5

I want to be able to delete indenting spaces one at a time.

If I set shiftwidth to 4, it deletes 4 spaces at a time if vim counts them as indentation. Setting shiftwidth to 1 fixes the problem, but makes vim autoindents using 1 space instead of a tab and inserts 1 space when I try to insert a tab.

Is it possible to delete spaces counted as indentation one at a time while keeping shiftwidth equal to 4?

1

4 Answers 4

3

I think some of your confusion comes down to terminology. There are two separate characters, space " " and tab "\t". Tabs are a single character, but get displayed as several blank columns. This can be configured with "shiftwidth". If you do :set shiftwidth=4 this means

When I press tab, insert a tab character, and display it as 4 blank columns (or as 4 spaces).

When you hit backspace, it deletes a single tab character that looks like 4 spaces. Now, if you want a tab character to insert 4 actual space characters, you should use expandtab. If you :set expandtab, it means:

When I press tab, enter tabstop spaces instead of a tab character.

So, if you :set tabstop=4, the tab key will insert 4 spaces, and backspace will delete one of them at a time. For reference, here are the relevant lines in my .vimrc:

"Indent settings
set autoindent
set expandtab
set tabstop=4
set shiftwidth=4

I also have:

filetype plugin on
2

Figured out the answer. Set softtabstop to 0. Wasn't working with my version of neovim, but it works when tested with original vim.

EDIT: Per options.txt#softtabstop in Vim's help, setting softtabstop to 0 disables the softtabstop feature. The reason this allows for deleting "tab-like" sequences of spaces in a space-by-space way is presumably because softtabstop controls the "number of spaces that a <Tab> counts for while performing editing operations, like…using <BS>," per the manual. It's a bit strange to me in light of this that the documentation for tabstop says that it controls the "number of spaces that a <Tab> counts for," full stop, but I suppose you're meant to infer that tabstop is about the file's "appearance," e.g. in normal mode, whereas softtabstop is about "editing," e.g. in insert mode. You would be wrong in practice if you did that though, because tabstop does control how many spaces you end up inserting in place of a tab if you have expandtab on. The whole "appearance vs. reality" thing kind of makes less sense with spaces than it does with tabs, I guess.

To those who doubt the usefulness of doing this, I use it in plaintext files meant for human consumption, because I like to indent things out to arbitrary distances in that context. It works nicely there to set a big tabstop like 8, set softtabstop to 0, and enable expandtab, because you can use the tab key to indent something about as far out as you want and then delete a few spaces to get it just right. I also have <s-Tab> (i.e. <Shift>-<Tab>) mapped to 4 spaces if I wanted to add a few spaces instead of delete a few.

1

Since you actually want indentation to be four spaces, I assume that this is a once-in-a-while thing you want to do. You could always use dh in normal mode. In the worst case, you'd be typing dh three times. Any more than three and you might as well be pressing the backspace key. To be a little bit more efficient with these four spaces, you could type dh, then start mashing . to repeat the deletion.

Given that you're only dealing with four spaces, the math is simple enough to use a count such as d2h without needing to think hard about it. Again, d2h is repeatable with . so you can delete 2 spaces at a time.

3
  • Wouldn't x be better than dh? (One less keypress, and deletes the character under the cursor instead of the one to the left.)
    – Rich
    Jul 30, 2022 at 23:39
  • @Rich dh is like <bs> moving left, while x is like <del> moving right. The issue is pressing <bs> in insert mode deletes expanded indentation in a leftward direction. Pressing dh gets around this in one "action". x will work, but is done in two "actions" via hx to move in the same direction. The difference is clearer when adding a count: d2h vs 2h2x. What makes the number of actions significant is your ability to use it from insert mode: <c-o>dh vs <c-o>hx. Given this quality, it could be mapped to keep you in insert mode: inoremap <m-bs> <c-o>dh.
    – Tommy A
    Oct 4, 2022 at 16:45
  • Yeah I've got no idea where I was coming from with that comment. I know that I wasn't suggesting pressing hx, but using x by itself obviously requires the cursor to be in a different place before you do it.
    – Rich
    Oct 4, 2022 at 19:50
1

A simple solution would be pressing x in normal mode. This will delete spaces one by one, no matter what are your settings.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.