Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bug: tabSize affects indentation #10339

Closed
cblp opened this issue Aug 9, 2016 · 36 comments
Closed

bug: tabSize affects indentation #10339

cblp opened this issue Aug 9, 2016 · 36 comments
Assignees
Labels
editor-core Editor basic functionality editor-rendering Editor rendering issues feature-request Request for new features or functionality on-testplan
Milestone

Comments

@cblp
Copy link

cblp commented Aug 9, 2016

  • VSCode Version: Code 1.4.0 (6276dcb, 2016-08-04T16:49:32.489Z)
  • OS Version: Linux x64 4.4.0-34-generic

tabSize setting has two independent functions:

  1. Size of tabulation character.
  2. Size of indentation.

The latter is really useful. But its connectedness with the former makes it unusable. In one file tabulation character size may be 8 and indentation size may be 4. How can I control these two values with one setting?

@rmunn
Copy link
Contributor

rmunn commented Aug 17, 2016

In one file tabulation character size may be 8 and indentation size may be 4. How can I control these two values with one setting?

@cblp Have you tried the EditorConfig plugin? It's written for exactly this scenario. See http://editorconfig.org/ for more details.

@cblp
Copy link
Author

cblp commented Aug 17, 2016

Yet another plugin and yet another configuration file for a single option? Okay :(

@cblp
Copy link
Author

cblp commented Aug 17, 2016

No, EditorConfig doesn't fix the issue. When I configure it to

[*]
indent_size = 2
tab_width = 8

it changes both indentation size and tab size to 2.

I think, EditorConfig can't work properly because of this issue.

@alexdima alexdima added feature-request Request for new features or functionality polish Cleanup and polish issue labels Aug 18, 2016
@alexdima alexdima added this to the Backlog milestone Aug 18, 2016
@alexdima alexdima added editor-core Editor basic functionality bug Issue identified by VS Code Team member as probable bug labels Aug 18, 2016
@gcp
Copy link

gcp commented Jan 10, 2017

This bug also makes proper handling of mode lines an issue, see for example ctlajoie/vscode-modelines#1.

@rebornix rebornix added the editor-autoindent Editor auto indentation issues label May 1, 2017
@rebornix rebornix self-assigned this May 1, 2017
@marktucker
Copy link

This issue makes it impossible for me to use VS Code as an editor on our existing library of code (which uses vim soft tabs of 4 spaces to indent, but a tab size of 8). With this fixed I could replace all my terminal windows, Vim, and Visual Studio with VS Code... Pretty please?

@greggman
Copy link
Contributor

Another vote hoping this gets some TLC. I've been using tab stops of 4 but indenting of 2 spaces for many many years.

@alexdima alexdima added editor-rendering Editor rendering issues and removed bug Issue identified by VS Code Team member as probable bug editor-autoindent Editor auto indentation issues labels Jan 30, 2018
@alexdima alexdima removed their assignment Jan 30, 2018
@jochumdev
Copy link

I also realy would welcome this to be fixed.

alexdima pushed a commit to dlech/vscode that referenced this issue Feb 18, 2019
This is an attempt to address issue microsoft#10339.

Background:

Currently, the `editor.tabSize` option does two things - it specifies the width of the tab character and it specifies how many columns to advance when the tab key is pressed. However, there is code in the wild that has a mix of spaces and tabs that expects these two values to be different.

These generally use and indent size of 2 or 4 and spaces are used for indentation until the indent becomes >= 8. The tab character size is excpected to be 8 and groups of 8 spaces are replaced with a tab character. Indent levels end up looking like 2 spaces, 4 spaces, 6 spaces, 1 tab, 1 tab + 2 spaces, and so on.

Implementation:

In the editor options, a new option, `editor.indentSize` is added. This, in conjunction with `editor.tabSize` has the same semantics as `indent_size` and `tab_width` in the well known [EditorConfig specification][1].

> indent_size: a whole number defining the number of columns used for each indentation level and the width of soft tabs (when supported). When set to "tab", the value of tab_width (if specified) will be used.
>
> tab_width: a whole number defining the number of columns used to represent a tab character. This defaults to the value of indent_size and doesn't usually need to be specified.

[1]: editorconfig.org

The new `indentSize` option takes a numeric value or "tab" just as EditorConfig's `indent_size`. The default value is set to "tab" so that current default behavior of VS Code does not change and existing user settings will not break.

When getting the new `indentSize` option programatically, it always returns a numeric value (just as `tabSize` does when set to the deprecated "auto" value).

In the text editor model, a new property is added for `indentSize`. Unlike the configuration options where the value of one property influences the other, In this code `tabSize` now should only mean "the width of the tab character" and `indentSize` should only mean "how may columns is one indent".

The cursor operations and shift command are updated to reflect these new semantics.
@alexdima alexdima assigned alexdima and unassigned rebornix Feb 18, 2019
@alexdima alexdima modified the milestones: Backlog, February 2019 Feb 18, 2019
@Wintaru
Copy link

Wintaru commented Mar 9, 2020

I'd like to vote for this to be fixed as well. I tried the EditorConfig extension, and when I reload the window it indeed "fixes" the issue (shows tabs with the correct spaces I put in .editorconfig, 8) but as soon as I click on another file and then back to the original, Code resets the tab width back to 4 (which weirdly, is not what I have in Code's default configuration for Editor:Tab Size, I put 8 there too).

Edit: fwiw detect indentation is off too. I have no idea where Code is getting this tab size now, or if it just defaults to 4 for some reason?

@trusktr
Copy link

trusktr commented Jun 2, 2020

If I understand correctly and am in the right place, this is important for develop experience. For example, some people really like to view code with indentation being at the width of four spaces. Regardless if the underlying code is actually using 2-space indentation, the developer wants to view it with 4-space indentation (equivalent of tab characters set to 4 spaces wide) to make the development experience better. However, VS Code does not allow this, instead, VS Code always modifies the underlying code to match the developers viewing preference, which is undersirable when collaborating with other people who may rely on the 2-space indentation.

Basically what we need is to control how the code is actually formatted, and to control how we view the code, such that if we open the code in a simple plain text editor we would see 2-space indentation, but in VS Code (with appropriate settings) we would see it as 4-space-tab-like only for developer convenience.

Is this what people are asking for?

@marktucker
Copy link

I don't want to speak for anyone else, but what I want is much simpler than this, I think. Actual "space" characters should be sacrosanct, not considered part of some "indentation" that the editor tries to interpret. All I want is that a tab character be allowed to move to the next columne that is a multiple of 8, which at the same time have my "indent size" for automatic code formatting set to 4 spaces (real space characters, no tab characters).

For me, the use case is dealing with an old code base filled with a mix of tabs characters and space characters (but with a consistent indent step size of 4 columns, populated as either space characters or size-8 tab characters) looks right in the editor. And I can edit these files without reformatting/editing every single line (automatically or not) without polluting my version control system with useless edits to the code spacing.

@Wintaru
Copy link

Wintaru commented Jun 3, 2020

What @marktucker said. I would like to be able to set tab characters to 8 spaces but when I hit the tab key want it to indent 4 spaces. My use case is the same as his.

Before anyone says "well fix the code base" 1) 30+ people work in this and it is millions of lines. 2) VIM, Emacs, and Eclipse can all do what we are asking for here, I am one of two people that use VS Code and making a huge whitespace commit for just us is not feasible when 3) some of our developers have not and seemingly will not configure their editors to use spaces instead of tabs so the whitespace commit would be ruined as soon as one of them pushed something.

@scigor
Copy link

scigor commented Jun 19, 2020

Same usecase here as @marktucker and @Wintaru. I hope this gets higher priority, because this is the reason vscode does not get higher adoption at the company i am working at.

@cblp cblp changed the title tabSize affects indentation bug: tabSize affects indentation Jun 19, 2020
@Timmmm
Copy link
Contributor

Timmmm commented Sep 20, 2020

It's a bit confusing that both settings still exist internally in the VSCode. If I'm adding a new feature do I just use tabSize for everything or should I try and do things "correctly" using indentSize and tabSize?

I think having two settings is overkill and I haven't heard a compelling reason to have tab size different to indent size. Legacy code can easily be fixed with sed or an automatic formatter (even if it is a million lines @Wintaru), and I don't think VSCode should greatly complicate itself just to support really really unusual code styles.

@Wintaru
Copy link

Wintaru commented Sep 20, 2020

It's a bit confusing that both settings still exist internally in the VSCode. If I'm adding a new feature do I just use tabSize for everything or should I try and do things "correctly" using indentSize and tabSize?

I think having two settings is overkill and I haven't heard a compelling reason to have tab size different to indent size. Legacy code can easily be fixed with sed or an automatic formatter (even if it is a million lines @Wintaru), and I don't think VSCode should greatly complicate itself just to support really really unusual code styles.

I’m sorry you think this is confusing but Vim, Emacs, Eclipse, and other major editors support this. If it is already an internal setting why can’t we expose this to settings and let us set both? Your excuse doesn’t fly with me, sorry.

@marktucker
Copy link

Automated updating of a huge, old code base isn't impossible because the scripts are hard to write, but becuase running those scripts and committing the results erases, or at least obscures and greatly complicates access to 25 years of svn blame history as in one commit 90% of the lines in the code based are changed by these scripts. That is a price I cannot pay just to be able to use VSCode.

@Timmmm
Copy link
Contributor

Timmmm commented Sep 20, 2020

I’m sorry you think this is confusing but Vim, Emacs, Eclipse, and other major editors support this.

You misunderstand. I meant it is confusing when developing VSCode itself that both settings exist internally in VSCode, but it actually only supports a single setting.

running those scripts and committing the results erases

Clearly not.

or at least obscures and greatly complicates access to 25 years of svn blame

Actually, just for converting all tabs to spaces you could avoid a big whitespace modification commit by rewriting history and running the script for every commit. Might take a while but git has built in support to do it automatically (filter-branch).

In any case, I still don't think it is worth the extra complication just to support the "I don't want to use git blame -w" use case.

@rmunn
Copy link
Contributor

rmunn commented Sep 21, 2020

I think having two settings is overkill and I haven't heard a compelling reason to have tab size different to indent size. Legacy code can easily be fixed with sed or an automatic formatter (even if it is a million lines @Wintaru), and I don't think VSCode should greatly complicate itself just to support really really unusual code styles.

The compelling reason, which may not feel compelling to you but is compelling to many people, is that many tools (including some languages) are hardcoded to treat Tab characters as being 8 spaces wide. For example, Python 2 and Python 3 both treat a Tab character as meaning "one to eight spaces such that the total number of characters up to and including the replacement is a multiple of eight (this is intended to be the same rule as used by Unix)". Note that Python 3 adds the rule "Indentation is rejected as inconsistent if a source file mixes tabs and spaces in a way that makes the meaning dependent on the worth of a tab in spaces; a TabError is raised in that case," which means that mixed tabs-and-spaces files will cause a syntax error in Python 3 until the codebase is fixed to be consistent. But for codebases using Python 2, where four-space indents are the norm but someone in the project has created a file containing tab characters (which is equivalent to eight spaces, i.e. two indentation levels), it's crucial that tabSize be left at 8 while indentSize needs to be 4 in order for the existing code to be displayed and edited correctly.

And the suggested "just rewrite history with git filter-branch" solution is a non-starter for many projects. That will change every commit hash, which would end up causing all sorts of links (GitHub PRs, mentions of commit IDs in Git history such as reverted commits) to go dead. That's far more costly than having two settings in an editor, one for tab size and one for indent size. Those two options should not be the same value in many projects, and a decent editor should be able to handle that use case.

@Timmmm
Copy link
Contributor

Timmmm commented Sep 21, 2020

Good point about links being invalidated. However I think Python's mad indentation rules are irrelevant. Nobody mixes tabs and spaces in Python code precisely because it is so hard to reason about.

@mcornella
Copy link

mcornella commented Oct 15, 2020

  1. The name. "visualTabSize" has been suggested. My personal opinion is that it would be nice to try to be consistent with other major editors. This isn't really possible because of the fact that the most important aspect of the existing "tabSize" setting is the indentation, so the meaning can't be the same as Visual Studio and Eclipse. However, I kind of like "tabstop" from vim since the visual width of a tab character could actually be less than 8 characters (or whatever the setting is set to).

I think using tabstop or tabWidth makes sense (for consistency with EditorConfig), but having two settings named tab* will be confusing, so I think you should also use indentSize and deprecate tabSize (and if indentSize isn't set, use tabSize instead). This requires a transition, which is harder to do, but I don't see tabstop and tabSize coexisting without significant user confusion.

@jednano
Copy link

jednano commented Nov 24, 2020

I haven't heard anyone yet make the distinction between indentation and alignment. Ideally, a document would only use tab characters for indentation and spaces for alignment.

tabs-vs-spaces

If I were building an editor from scratch, I would keep the word "tab" out of the setting name and start with something like the following:

interface EditorSettings {
  /**
   * Each indent is represented by either a single tab character or a specified number of spaces.
   */
  indent?: 'tab' | number;

  /**
   * Visual width for each level of indentation.
   * @default EditorSettings['indent']
   * @example an `indent` of `2` and an `indentWidth` of `4` would make each space in the
   * indent range appear as `2` spaces of width. Conversely, an `indent` of `4` with an
   * `indentWidth` of `2` would make each space character appear at half width.
   */
  indentWidth?: number;

  /**
   * In alignment regions, each Tab key press inserts a tab character.
   * @default false
   * @warning changing the indentation width will break the alignment if this is `true`.
   */
  alignViaTabs?: boolean;

  /**
   * If `alignViaTabs` is `false`, pressing the Tab key within alignment regions produces the
   * correct number of spaces to land on a column number that is divisible by this number.
   */
  tabStops?: number;
}

Related issues

@alexdima
Copy link
Member

Done via #155450

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
editor-core Editor basic functionality editor-rendering Editor rendering issues feature-request Request for new features or functionality on-testplan
Projects
None yet
Development

No branches or pull requests