I have two buffers in vim:

  1 %a   ".vimrc"                       line 1
  2 #h   "script.sh"                    line 1
Press ENTER or type command to continue

As seen above, I'm on the first buffer. Now if I execute the :set softtabstop=16 command, then I expect it to affect both buffers. However, this is not the case- while the sts value for first buffer is indeed changed and Tab key inserts four tab characters(ts=4), then for second buffer the sts value is still 4:

  1 #h + ".vimrc"                       line 1
  2 %a + "script.sh"                    line 1
Press ENTER or type command to continue

Why is that so? I thought that set affects all the buffers and setlocal affects only the active buffer..


Options can be global, window-local, or buffer-local.

When you :set a global option, the new value is global.

When you :setlocal a global option, the new value is local.

When you :set a local option, the new value is local.

softtabstop being a buffer-local option, changing its value only affects the current buffer.

The "scope" of an option is indicated in :help option:

'softtabstop' 'sts'    number    (default 0)
                       local to buffer
                       {not in Vi}
Number of spaces that a <Tab> counts[...]

:help local-options, :help :setlocal, and :help global-local explain all that in more details.

  • 3
    There's also a :setglobal. – Sato Katsura Sep 4 '16 at 7:13
  • 3
    Also, some options are global, no matter how you set them. E.g. 'encoding'. – Antony Sep 4 '16 at 20:45
  • Is there a way to set local function by buffer id and the option value with some a vimscript function call? – St.Antario Dec 2 '19 at 5:08
  • There is a function setbufvar which can be used to achieve that. Did not found it at first. – St.Antario Dec 2 '19 at 5:56

Not an expert, @Martin, but from reading :help set you would need to "unset" the local value of sts in each buffer to have that buffer pick up any new global value. setlocal sts= (or for boolean flags, setlocal flag<). Kinda makes sense, local settings initialized to current global values on open, then keep local values until told otherwise. If there is no local setting in play, it should pick up any new global values.

Again, not being an expert, I'd hazard a guess that that second buffer had an explicit local setting before the later set. More than 50/50 that my understanding is wrong, as I'm still unclear on what the difference between set and setglobal is.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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