0

Consider, for instance, the colorcolumn option.

(Interestingly, the manual linked above refers to colorcolumn as a window-local option, but :setg colorcolumn=80 works as you would expect of a global-local option; does it mean that the man is wrong or am I misunderstanding the mechanics of global-local options?)

I'm trying to write some code that (intelligently) sets up a default colorcolumn for each new or resized window. However, I'd like to disable this automatic handling if colorcolumn is set manually, for example in a FileType autocommand.


Is it possible to somehow detect if colorcolumn was ever set locally for a given window, even if to the same value as the global one?

E.g. given this vimrc:

augroup filetypesettings
au!
au FileType help setlocal colorcolumn=
augroup END

I want to be able to distinguish a ft=help buffer/window where this autocommand has executed from any other buffer/window where the default is used (even if the default is also empty). Is it possible?

2
  • Does it really matter if the local value and the gloabl value are the same?
    – romainl
    Commented Jun 27 at 14:52
  • @romainl I want to ergonomically distinguish the "default" from "override".
    – intelfx
    Commented Jun 28 at 1:44

2 Answers 2

1

colorcolumn is called "local option", not a global-local one.

Nonetheless, "global" colorcolumn instance also exists. In fact, all such globals always exist. Sometimes, they are used as default values, sometimes, they do nothing. But they exist, just take it.

Unlike global-locals, pure local options cannot be set "to follow the global". They always have some "private" value set (it may be equal to Vim's default but it doesn't really matter). So you cannot distinguish between locally "set" and "unset" states. If you believe you need this then just create a dedicated buffer-local variable to trace such changes yourself.

3
  • Okay, so I did misunderstand the mechanics. Thanks for clarification. Re: creating a dedicated buffer-local variable, I'm not sure I understand the idea. Could you clarify how I can do this?
    – intelfx
    Commented Jun 28 at 1:45
  • @intelfx :h window-variable. Maybe even :h OptionSet if you really need this.
    – Matt
    Commented Jun 28 at 2:16
  • Yes, I've already consulted the manual. Sorry, but this is being unhelpful. What I meant with my question is, how exactly do you suggest to use {buffer,window}-local variables to achieve the goal in the OP?
    – intelfx
    Commented Jun 28 at 18:25
0

In my vim library, I have the following:

" Function: lh#option#is_set_locally(option_name, [bufid='%']) {{{3
" @return whether a vim option is already set locally, which requires to use
" `let &l:`  or `setlocal`
" TODO: Complete the list of equivalence
let s:k_option_fullname = {
      \ 'ai': 'autoindent',
      \ 'bs': 'backspace',
      \ 'efm': 'errorformat',
      \ 'et': 'expandtab',
      \ 'ft': 'filetype',
      \ 'isk': 'iskeyword',
      \ 'rtp': 'runtimepath',
      \ 'sw': 'shiftwidth',
      \ 'ts': 'tabstop',
      \ 'tw': 'textwidth'
      \ }
function! lh#option#is_set_locally(option_name, ...) abort
  let bufid = get(a:, 1, '%')
  if a:option_name =~ '^&\(\([lg]:\)\@!.\)*$'
    " options with no explicit scope
    let options = getbufvar(bufid, '&')
    " Before 7.4.434, getbufvar() returns an empty string instead of an
    " empty dict when nothing is found
    " Also, older version of vim don't return local options with
    " getbufvar(bid, '&')
    " In global-local options case, an empty local option is an option that
    " hasn't been overriden
    let option_name = get(s:k_option_fullname, a:option_name[1:], a:option_name[1:])
    if !empty(options) && has_key(options, option_name)
      if type(options[option_name]) == type('')
        return !empty(getbufvar(bufid, '&l:'.option_name))
      else
        return getbufvar(bufid, '&l:'.a:option_name[1:]) != getbufvar(bufid, '&g:'.option_name)
      endif
    endif
  endif
  return 0
endfunction

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.