2

I am working on a plugin that could potentially define more than 120 different signs. The vim / neovim documentation specifies that you can define about 120 signs (not sure why this number and why so ambigous). From :he sign-define

:sign define {name} {argument}...
        Define a new sign or set attributes for an existing sign.
        The {name} can either be a number (all digits) or a name
        starting with a non-digit.  Leading zeros are ignored, thus
        "0012", "012" and "12" are considered the same name.
        About 120 different signs can be defined.

The thing is I have already tried to define well over 500 signs and place them as well and I did not see any issues on my system in both vim and neovim. I was wondering if there are any dangers in doing this, or any performance issues.

If anyone is curios how to add so many signs:

" permutations of 2 with repetition
function! Permutations(lst, counter, res)
  if a:counter == len(a:lst)
    return a:res
  endif
  let l:res = copy(a:res) + map(copy(a:lst),
        \ { idx, val -> a:lst[a:counter] . val })
  let l:counter = a:counter + 1
  return Permutations(a:lst, l:counter, l:res)
endfunction

" ['aa', 'ab', 'ac', ..., 'zy', 'zz']
function! DefineSigns()
  let l:signs = Permutations(
        \ map(range(97, 97 + 25), 'nr2char(v:val)'), 0, [])
  for i in l:signs
    call sign_define(
          \ 'signs' . i,
          \ {'text': len(i) == 1 ? ' ' . i : i, 'texthl': 'MoreMsg'})
  endfor
endfunction
:call DefineSigns() | echo len(sign_getdefined())
676
3

I'm going to guess that the documentation is outdated with respect to that limit. I'm looking at the code for alloc_new_sign()...

    // Check that next_sign_typenr is not already being used.
    // This only happens after wrapping around.  Hopefully
    // another one got deleted and we can use its number.
...
    if (lp->sn_typenr == next_sign_typenr)
    {
        ++next_sign_typenr;
        if (next_sign_typenr == MAX_TYPENR)
...
        if (next_sign_typenr == start)
        {
            vim_free(sp);
            emsg(_("E612: Too many signs defined"));

MAX_TYPENR is defined as 65535 in my build. Perhaps in the past it was assigned to a smaller type (unsigned char? Does C have those? I can't remember.) and thus was limited to a smaller number. Or it was limited due to some condition that no longer applies.

Regardless, looks like you can add as many signs as you need...unless you're doing something absolutely crazy. ;)

11
  • Thanks! I was assuming the documentation is outdated but had no idea how to check. – skamsie Dec 20 '20 at 16:21
  • @B Layer How did you get the value of this MAX_TYPENR ? – skamsie Dec 20 '20 at 16:22
  • 2
    When syntax highlighting was disabled at compile time, the block of code in vim.h used to define unsigned char sattr_T and MAX_TYPENR 255, so 120 signs is a rule-of-thumb as this limit is used by other things. However, with syntax highlighting, the limit was (almost) always 65535. – Mass Dec 20 '20 at 16:23
  • 1
    @skamsie ag MAX_TYPENR in the vim source tree (it's in vim.h). :) – B Layer Dec 20 '20 at 16:23
  • 1
    Yeah, N *+syntax* Syntax highlighting |syntax|; if you build vim in "tiny" or "small" configurations, the +syntax (highlighting) feature is disabled, so less "attributes" are required. The reason, of course is memory savings, which today is less important than maintenance concerns, so this distinction (general sign limit) was dropped. – Mass Dec 20 '20 at 16:38

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.