mawww / kakoune

mawww's experiment for a better code editor
http://kakoune.org
The Unlicense
9.93k stars 714 forks source link

EditorConfig does not expandtab #3073

Closed benburk closed 5 years ago

benburk commented 5 years ago

Steps

.editorconfig:

indent_style = space
indent_size = 4

kakrc:

hook global WinCreate .* %{editorconfig-load}

Outcome

Pressing Tab inserts \t

Expected

Pressing Tab inserts 4 spaces

TeddyDD commented 5 years ago

@andreyorst any chance you would add support for this in https://github.com/andreyorst/smarttab.kak ?

andreyorst commented 5 years ago

@andreyorst any chance you would add support for this in https://github.com/andreyorst/smarttab.kak ?

I don't know. smarttab.kak provides, somewhat, rules for tab character insertion, which should be manipulated through filetype hooks. Though, I think we can infer settings from the indent_style options to automatically set correct mode, e.g. space => expandtab tab => expandtab. Also I don't know what to do with sofftabstop then.

But then it may conflict with user hooks, like hook global WinSetOption filetype=kak expandtab, if editorconfig is loaded first it will work, if expandtab is evaluated before editorconfig-load than user will have a long debug session on why the hook doesn't work.

benburk commented 5 years ago

I am currently using smarttab (great plugin!) to get the behaviour I want, but shouldn't editors that support .editorconfig have expandtab built in? Or is that not in the .editorconfig spec?

mawww commented 5 years ago

Hello,

I think this issue is incorrect, editorconfig support is doing the right thing here:

indent_style configures the indentwidth and aligntab options, controlling the indent (>) and align (&) normal mode commands to use tabs or not, and how much spaces an indent should take.

What you are asking for is for <tab> in insert mode to be treated as an indentation command, which is relatively common among editors, especially non-modal ones, but is not strictly what editorconfig is supposed to be doing.

I can understand that confusion, as users are used to <tab> being some kind of magical key in most editors, and thanks to smarttab.kak it is possible to get that behaviour in Kakoune. But I dont think editorconfig.kak should over-interpret the configuration in the .editorconfig file.

andreyorst commented 5 years ago

I guess I should include .editorconfig support to smarttab.kak

benburk commented 5 years ago

@mawww From https://editorconfig.org:

indent_style: set to tab or space to use hard tabs or soft tabs respectively.

My understanding is that soft vs hard tabs denotes what is inserted when the <tab> key is pressed, with soft tabs inserting spaces according to indent_size. I believe this is how it works in other programs. More info https://stackoverflow.com/a/26350798/9518712

mawww commented 5 years ago

@benburk To me, indent_style defines the indentation style, not the <tab> key behaviour, that would be for an eventual tab_behaviour entry. I understand indentation style as what is inserted to manage the indentation of a line (actual tab characters, spaces, a mixture of them with as much tabs as possible, tabs for nesting level then spaces for alignement...).

Most editor use the <tab> key for indentation because they are not modal. Kakoune already has a few indent command (<, >, and <a-...> version of those), I dont think editorconfig by itself should go further than configuring those command behaviour.

That said, I think it would make sense fo smarttab.kak to work well with editorconfig, so that you get the behaviour you expect. I merely object to the idea that its editorconfig.kak responsibility to do so.

benburk commented 5 years ago

Thanks for your perspective @mawww. It sounds like you have given it quite a bit of thought.

To me, indent_style defines the indentation style, not the key behaviour

To me, indent_style and <tab> are very much related. When you indent code, you do so most often using the <tab> key. I think it's unintuitive for kakoune to respect indent_style for many indent commands (<, >, etc.), except the most popular one: <tab>.

I think the majority of new users would expect the behaviour I describe, since that is how most other programs implement it, and it is a reasonable interpretation of the .editorconfig documentation.

Additionally, indenting with spaces is extremely popular and having to download a plugin to achieve the functionality they are familiar with could be frustrating to new users. I think it would be great to have as a default setting. I may be wrong though and am open to having my mind changed.

Screwtapello commented 5 years ago

When you indent code, you do so most often using the <tab> key.

In most editors, sure.

The description of the Kakoune repo is "mawww's experiment for a better code editor", and part of that experiment is seeing how far it can get with super-minimalist internals and a lot of scripting on top. For example, one example of that minimalism is "in insert mode, keys are inserted into the buffer, but in normal mode they operate on the selection". This is a bit fuzzy, since pressing Esc in insert mode does not insert a 0x1B byte into the buffer, but it's true for regular typable characters like A and } and Space and Tab. Those are all characters one might reasonably expect to find in a source-code file, and in insert mode, they all insert themselves as-is.

That said, brutal minimalism is uncomfortable for actual humans, and Kakoune ships with a a bunch of scripts to make things more comfortable. For example, many of Kakoune's file-type-support scripts, as well as adding syntax highlighting, teach Enter to copy the indent from the previous line as well as inserting a new one. There's definitely drawbacks to that strategy (not every file-type supports it, and some of them are inconsistent), but there's also advantages (file-formats or users with unusual requirements can be special without having to modify Kakoune's core).

If Kakoune were all about making the most polished, easy-to-use editor, then sure, making a magic Tab key would absolutely be the right move. But instead, Kakoune is trying to balance comfort against simplicity and minimalism.

One thing that has changed since these conventions were established is that Kakoune now has a module system so scripts can depend on one another. I wonder if it would be reasonable to ship some tab-magic.kak in the standard library with helper commands like setup-window-expandtabs, and update all the file-type plugins to use it. That way, users can still write their own hooks if they need something really custom, or use the helper commands if they want something generic.

benburk commented 5 years ago

Regardless of the design philosophy of Kakoune, it purports to implement the .editorconfig standard but indent_style isn't implemented according to the specification. It seems like more of a bug than a design issue.

In addition to those reasons, I believe it is inconvenient and perhaps uninviting requiring new users to resort to plugins for such a basic feature used by ~half of programmers when they should be focusing on learning the editing model. I think Kakoune has done a great job setting itself up as a minimalist editor but I'm not convinced this is where to draw the line.

benburk commented 5 years ago

@mawww Just wondering if this affects your view at all. If not I can close the issue.

mawww commented 5 years ago

Hello,

I agree that from the wording at editorconfig.org, interpreting indent_style as intending to configure the tab key behaviour is reasonable. I do not think this is strong enough to mandate a behaviour change here. Vim has a less strong separation of responsibility between insert and normal mode than Kakoune has (as vim's <c-w> or <c-u> bindings and expandtab option show), and most other editors, being non-modal use <tab> because they have no other reasonable choice.

Editorconfig hence used a wording that made sense to 99% of text editor users, but that does not mean Kakoune has to embrace it blindly. I think it makes sense to have an interpretation of editorconfig that matches both its general intent, and Kakoune design principles, in the case of indent_style that means interpreting it as controlling the indentation style, instead of controlling the <tab> key behaviour.

etoombs-encircle commented 5 years ago

What you are asking for is for <tab> in insert mode to be treated as an indentation command, which is relatively common among editors, especially non-modal ones, but is not strictly what editorconfig is supposed to be doing.

<tab> as an indentation command is far more useful by default than <tab> as a means of inserting literal tab characters. If that is what you want, just escape with ^V. The cases where this doesn't save keystrokes are massively outweighed by those where it does. Unless actually indenting with tab characters, which is not kak's default, almost everybody using kak's defaults would hardly ever use the tab key in insert mode. That is bad use of keyboard real estate.

Though I realise this is a separate issue, which I've made here: #3136.

valpackett commented 4 years ago

Here's how I configured indentation:

define-command auto-setup-indent %{
    # … other ways of inferring indentwidth …
    editorconfig-load
    modeline-parse
    evaluate-commands %sh{
        if [ $kak_opt_indentwidth -eq 0 ]; then
            printf "smarttab\n" # from smarttab plugin
        else
            printf "expandtab\n" # also from there
        fi;
    }
}
hook global BufOpenFile .* auto-setup-indent
hook global BufNewFile .* auto-setup-indent

(full version also configures smarttab's softtabstop)

It's honestly silly that the scripts shipped out of the box don't include all of smarttab and parts of something like this. Making the tab key "magic" should be done in a couple lines of config, not a whole screen of config.

hamoid commented 4 years ago

Hi! I think it would help to have a page linked at https://github.com/mawww/kakoune/blob/master/README.asciidoc dedicated to the behavior of the tab key and how it can be tweaked.

I've been trying Kakoune for a few weeks and tabs were biting me few times with a language in which indentation changes scope. The code looked right to me, but to the compiler it meant something I didn't expect, giving me hard to debug errors (because tabs were mixed with spaces).

andreyorst commented 4 years ago

Hi! I think it would help to have a page linked at https://github.com/mawww/kakoune/blob/master/README.asciidoc dedicated to the behavior of the tab key and how it can be tweaked.

Like this https://github.com/mawww/kakoune/wiki/Indentation-and-Tabulation?

hamoid commented 4 years ago

@andreyorst yes, like that for example. There's no link to that page in the main documentation page I linked.

But then, that page about Indentation-and-Tabulation does not mention interesting facts that are in this thread, for example, that every key pressed in insert mode is inserted into the document, which may be different from other editors, and why is it so.

It is also very brief, with no explanations or reasoning. For example "Indentation and Tab handling — Through a mapping" - what is that for? and what is the purpose of "Indentation and Tab handling — Through hooks" ?

It seems like what I'm looking for is at the bottom: expandtab. Before finding this thread I was convinced I can have no tabs by setting some flag, but now I understand I need your plugin. Thanks for sharing :)

andreyorst commented 4 years ago

@mawww, it was mentioned several times in this thread, and I've also thought about the fact that there are some languages1 which directly expect spaces to be used for indenation, either because of language parser implementation, or because language standard strongly suggests it. Isn't this good enough reason to include smarttab.kak to the core and handle Tab and > keys through it for better programming experience? This issue has popped up several times, and majority of users expect this thing to be builtin. (Again, it is presented in 99% of editors).

Smarttab.kak has barely changed since I've wrote it, and had served me well, as well as other users. I'm fine with it being a plugin, but I still think that this is a first-class feature of any code editor. I know that one of the reasons not to ship it is this, but I think we have better ways to teach users write hooks.

1: Such languages would be all Lisps, Python, Rust.

tmccombs commented 4 years ago

Like this https://github.com/mawww/kakoune/wiki/Indentation-and-Tabulation?

That doesn't have any instructions on how to set it up with editorconfig.

Also, is it really that common to have have softtabs for indentation, but want to insert literal tab characters in the file? I don't really understand the argument that you shouldn't use to indent, because you can use <alt-;> instead. (and same with vs <alt-;>)

askreet commented 3 years ago

New user here. Came here to figure out what I was doing wrong because I'd set up editorconfig and it configured the size of a tab but not the behavior of the tab key. Turns out I'm not doing anything wrong and these defaults are deeply surprising.

I'm curious who benefits by having the behavior of the tab key be inserting literal tabs regardless of editorconfig? Seems like something anyone working on a spaces-only codebase would immediately be hung up on.

Screwtapello commented 3 years ago

I'm curious who benefits by having the behavior of the tab key be inserting literal tabs regardless of editorconfig?

In theory, everybody benefits from a simpler, more flexible editor core, as I wrote above: https://github.com/mawww/kakoune/issues/3073#issuecomment-535339862

If a project has indent_style = space, do people expect <tab> to insert exactly $indent_size spaces, or enough spaces to reach the next tab stop? Should backspace delete one space, $indent_size spaces, or to the previous tab-stop? Does this change if we're talking about indent at the beginning of the line, or spaces in the middle of the line? Should <tab> always indent the line the cursor is on, no matter where the cursor is? What if the user wants to use <tab> to navigate the completion menu while it's visible, but for indenting otherwise?

If there were one simple, obvious implementation that would make everybody happy, Kakoune would probably do that. In practice, people have different ideas of how things should work, and different levels of willingness to deal with behaviour that isn't quite what they expected. As a general rule, if there's more than one sensible way to do something, Kakoune will not pick one, or try to build a system that provides every option. Instead, Kakoune will do nothing, but will give you the tools to build whatever you want.

askreet commented 3 years ago

If there were one simple, obvious implementation that would make everybody happy, Kakoune would probably do that.

Perhaps what I'm suggesting, at least, isn't that Kakoune change it's core behavior, but that the implementation of the editorconfig do the expected thing with indent_style = space. I think most people would expect tab to insert spaces up to $indent_size, aligned with tabstops, when that is set.

At any rate, I've started using smarttab.kak and it works "fine", I only wanted to add a +1 to the idea that with built-in editorconfig support, I felt like I must be doing something wrong with tab continuing to insert the literal tab character. Perhaps this is just something new users will have to grapple with, and that's OK.