How to make mouse selection and arrow keys ignore soft tabs


#1

In the editors I’m used to, the equivalent of “soft tabs” only causes tabs to insert 4 (or some other number) spaces, and backspace/delete to remove 4 spaces. It does nothing else.

Atom does more than that. Selection (whether by mouse or arrow keys) will treat the series of spaces as a unit; for example, hitting the left or right arrow keys once will move up or down a level of indentation, regardless of how many spaces that actually is.

While I can understand how it might be useful to have soft tabs be just as strict as hard tabs, I find it kind of disruptive. I click with the mouse, and my cursor doesn’t go where I expect it to. I use the arrow keys a couple of times, and suddenly I’m nowhere near the column I intended to be. Plus, the soft tab setting doesn’t affect old files, so it can be annoying to tell if a file is actually using soft or hard tabs.

How do I make Atom behave more like I’m used to?


#2

Disable the “Atomic Soft Tabs” setting.


#3

That’s closer to what I want, but still not exactly what I’d like. I still want backspace (and delete) to remove an indentation level’s worth of spaces.


#4

Hmm. That’s significantly harder and not something I’d think we’ll be exposing as a config option. Maybe someone will know how to do it in your init.coffee file though.


#5

After stumbling across TextEditor::backspace and TextEditor::delete, I managed to get it to work the way I like. There’s still a bit of weirdness when you use backspace and delete and aren’t aligned with the tabs, but it’s not something I’m particularly concerned about.

I added the following to my init.coffee:

atom.commands.add 'body', {
    'init:atomic-backspace': () ->
        editor = atom.workspace.getActiveTextEditor()
        ast = editor.displayLayer.atomicSoftTabs
        editor.displayLayer.atomicSoftTabs = true
        editor.backspace()
        editor.displayLayer.atomicSoftTabs = ast

    'init:atomic-delete': () ->
        editor = atom.workspace.getActiveTextEditor()
        ast = editor.displayLayer.atomicSoftTabs
        editor.displayLayer.atomicSoftTabs = true
        editor.delete()
        editor.displayLayer.atomicSoftTabs = ast
}

Edit: Wait, scratch that. That will cause an error (and not the backspace) in (e.g.) text selection in the settings menu.


#6

Make sure the active text editor isn’t null :wink:


#7

Oh, sorry, I forgot to mention I already added a test for null and it still doesn’t work. Without a test, you get an error when you backspace, and with a test, backspace does nothing in the settings menu.

The problem is that in (for example) package search, atom.workspace.getActiveTextEditor() returns null, so I can’t call editor.backspace() or editor.delete(). You can specifically test for null, but then pressing backspace or delete in the settings menu will silently do nothing.


#8

Then maybe try constraining your selector to atom-text-editor:not([mini]) instead of just body?