microsoft / vscode

Visual Studio Code
https://code.visualstudio.com
MIT License
160.84k stars 28.21k forks source link

Indent using tabs by default #156304

Closed BenjaminAster closed 1 year ago

BenjaminAster commented 1 year ago

Prettier is considering making tabs the default indentation (as opposed to spaces) in version 3.0. The issue has recently risen in popularity after @Rich-Harris (the creator of the popular JavaScript framework Svelte) tweeted about it.

In this issue, I want to elaborate why Visual Studio Code should do the same thing. This would mean setting "editor.insertSpaces" to false by default.

The arguments below are mostly based on this Reddit post, the conversation on the Prettier issue and the following excellent blog posts. If you want to dive even deeper into why tabs are superior to spaces, you may want to consider reading them all:


Customization

Different people prefer different indentations for their code. Some like a width of two spaces, others like a width of four spaces, and even different people want their code indentation to have a width of three spaces (like me!). If a codebase uses tabs as its indentation, everyone can configure their editor to display tabs with a width of their personal preference. With spaces on the other hand, one single indentation width is forced onto all contributors. The choice is taken away from the individual people.

Accessibility

Blind people often use screen readers to "read" the text from their screen. In this case, it is much more meaningful if the screen reader announces e.g. three tabs instead of twelve spaces. Some blind people also use refreshable braille displays to read text using their fingers. A tab character occupies a single character cell on the braille display while multiple spaces occupy multiple cells. So spaces as indentation waste a lot of space there and are impractical for the person to read. Additionally, these braille displays are very expensive devices, so the more actually meaningful characters you can display on e.g. a 40 character display, the better. (An indentation of five levels using four spaces each would result in 20 whitespace characters – which would be half of the whole 40 character braille display.)

But accessibility is not just about blind people. There are other types of impairments, like low vision. People with low vision often increase font sizes in order to read text. Because the text is then already so big, they tend to use a narrow code indentation with a width of two or even just one spaces. A fixed indentation of e.g. four spaces would make their lives harder and waste a lot of valuable screen space.

Additionally, people with dyslexia and/or ADHD often prefer large indentation widths (like a width of eight spaces) to better keep track of the current indentation level.

File size

One tab character has a size of one byte. Multiple space characters have a size of multiple bytes. In large codebases, an indentation using spaces can make file sizes unnecessarily large. If all of your projects (and node_modules!) would use tabs for indentation, that would make a not insignificant difference to your hard drive. Also, not everyone uses build tools in webdevelopment to minify the HTML, CSS and JavaScript sent to the client. If that's the case, lower file sizes would not just benefit developers, but also end users.

Readability & keyboard navigation

Personally, I want my whitespaces to be displayed in my editor because I like to have an overview of what's actually going on in my code files. (You can enable this in VSCode by setting "editor.renderWhitespace": "all"). This is what the code looks like with tabs as indentation:

code snippet with visible tabs as indentation:
for (let i = 0; i < 8; i++) {
for (let j = 0; j < 8; j++) {
if ((i + j) % 2 === 0) {
console.log({ i, j });
}
}
}

And this is how it looks like with spaces as indentation:

code snippet with visible spaces (three each) as indentation:
for (let i = 0; i < 8; i++) {
for (let j = 0; j < 8; j++) {
if ((i + j) % 2 === 0) {
console.log({ i, j });
}
}
}

In this case, tabs provide a much better overview of the code's indentation. Also, when using the keyboard to navigate through your code, tabs allow you to easily skip one indentation level forwards/backwards by pressing e.g. the right/left arrow keys.

Semantics

Historically, the tab key was specifically invented to "advance the carriage to the next tabular stop". And when computers became a thing, the horizontal tabluation ASCII character was created do exactly such things as code indentation. The tab character has a semantic meaning of "this should be indented" while spaces are just spaces. Using spaces for indentation is nothing more and nothing less than a silly hack.


Conclusion

Visual Studio Code is by far the most popular code editor worldwide, so the defaults of VSCode will automatically be the defaults for most developers. As long as VSCode ships with spaces as the default indentation, people will keep using spaces. Changing the default behavior of VSCode would make a huge difference in the developer community worldwide.

Dear Microsoft, if you care about your users and if you care about accessibility, you should care about making tabs the default in Visual Studio Code.

I'd like to end this issue with a quote by @LeaVerou:

Using spaces is like saying “I don’t give a rat’s ass about how you feel more comfortable reading code. I will force you to use my preferences because it’s my code”.

trezy commented 1 year ago

One very important issue here is that there are many significant whitespace languages that require spaces for indentation. Python can use tabs in place of spaces, but YAML will hork every time.

I fully support this proposal, but it's also important to note the scenarios in which this would cause significant problems.

BenjaminAster commented 1 year ago

@trezy Hmmm... My idea here would be to change the accepted values of the "editor.insertSpaces" setting from true | false to "always" | "whenRequired" | "never". "always" would be equivalent to the current true, "never" would be equivalent to the current false, and "whenRequired" would insert spaces only in languages that require it (like YAML). "whenRequired" would then be the new default for this setting. Also, the true and false values should still be supported for backwards compatibility.

aMediocreDad commented 1 year ago

I want to add another consideration for using tabs by default.

A lot of beginners are taught to indent code using the tab-key (no source) on their keyboard. There is a cognitive disconnect that happens with the current default setting. The first vscode setting I learned about was this one, exactly because of this disconnect where you press tab, but two spaces are inserted instead. This subverts expectation.

Additionally, to a beginner, navigating space-indentation is often difficult because you are not familiar with conventions (2 spaces / 4 spaces for indentation).

I would argue that these two concerns fall under accessibility as they effect the experience of newcomers, forcing an unnecessary learning curve.

With tabs being default you help new developers by making the tool work just a tiny bit more like you would expect from the outset.

jbreckmckye commented 1 year ago

I posted in that linked thread about a week ago, again after Rich Harris' tweet.

I'm not necessarily opposed to this, but I do want to add some caveats to what's been said: after speaking to several partially sighted users, and considering my own (more limited) experience using assistive technology (AT), I think - though I could be wrong - that the accessibility gains of tabs to low-sighted users are possibly overstated.

Most of the AT users I've spoken with don't express much concern about whether code is indented with tabs or spaces. Screen readers are highly configurable and a common pattern is to not have the reader announce individual punctuation. Another pattern is to use tone to announce indentation rather than reading out tab stops.

So for instance, this argument

Blind people often use screen readers to "read" the text from their screen. In this case, it is much more meaningful if the screen reader announces e.g. three tabs instead of twelve spaces.

May not actually be true. And in my own testing, I can't recall an instance where a screen reader, out of the box, would not collapse consecutive whitespace anyway (making tabs and spaces indistinguishable). Screen readers "read" text, they don't dictate characters verbatim.

Some AT users do use Braille displays but not quite in the way described here. For instance, one person I spoke to on Twitter used a screen reader to navigate code at a high level, then would examine sections of code using a smaller braille display. The idea of a braille display that completely replaces an entire terminal output may not be exactly the common use case.

And that's not to raise the other issues with tabs, namely how certain clients render them inconsistently or without customisation.

Again, this is not a "vote against" this consideration, but the key point I want to underline is that a campaign for accessibility should be driven by disabled users and based on the things they say are priorities. My concern is that this community does not seem very concerned about spaces vs tabs.

For an example of some of the conversations I've had - which don't comprise a systematic survey of any kind! - see this recent Twitter thread: https://mobile.twitter.com/jbreckmckye/status/1551306055942127617

Again, that's not to detract from other possible benefits. It's just to emphasise that there needs to be some validation of the AT argument, preferably with real AT users.

pgfearo commented 1 year ago

(aside) As well as using tab or space characters, attempts have been made to support character-free indentation: See video

Such a 'virtual' formatting provider would simply be able to return an array of integers representing indent-level instead of an array of text edits for each line. CSS in Monaco could handle the indentation.

xsrvmy commented 1 year ago

There is a problem with tabs instead of spaces that no one is really considering IMO: what happens if your document has a multiline string that needs to be tab aligned so tabwidth needs to be 8? I have code that actually uses tab alignment (although I do believe I use tab indent for that because typing a tab in vscode is annoying when indenting by spaces)

nickmccurdy commented 1 year ago

Tabs are for indentation, not alignment. You're using them incorrectly. You should use 8 spaces instead.

xsrvmy commented 1 year ago

I'm talking about cases where you want to use the tab-stop feature of tabs, eg. tables, goto labels, command line programs that use tab. After all, tables are the namesake of the tab character. I would support moving to tabs if elastic tab stops find wide-spread usage though.

VSCodeTriageBot commented 1 year ago

We closed this issue because we don't plan to address it in the foreseeable future. If you disagree and feel that this issue is crucial: we are happy to listen and to reconsider.

If you wonder what we are up to, please see our roadmap and issue reporting guidelines.

Thanks for your understanding, and happy coding!

nickmccurdy commented 1 year ago

Can this still be reopened if it gets more comments or upvotes?

GrabbenD commented 2 months ago

Hope this decision can be re-considered! https://github.com/microsoft/vscode/issues/211836

GrabbenD commented 1 month ago

This feature request is now a candidate for our backlog. The community has 60 days to upvote the issue. If it receives 20 upvotes we will move it to our backlog. If not, we will close it. To learn more about how we handle feature requests, please see our documentation.

Consider supporting this ticket with a 👍 if you want to see this change -->

https://github.com/microsoft/vscode/issues/211836