The acro package introduces LaTeX macros like \ac{abc}, \acs{abc}, \acl{abc}, \acp{abc}, \acpl{abc}, \Ac{abc}, etc. Here, abc is the label for an acronym.

I manually extract the acronym labels from the acronym file and add them to my local en.utf-8.add file. The latter is specific to each report. It is not an ideal process because both the acronym file and en.utf-8.add are constantly changing.

Can someone suggest a more efficient way to have the spell checker ignore acronym labels?

  • Loop over uses of the macro and run zg?
    – D. Ben Knoble
    Jan 19 '21 at 19:26
  • It's possible. I'm not great with the Vim command language, so I'd capture normal-mode movements/searches/edits into a register for invocation via @, modify the register content to invoke itself at the end, then run the infinite loop until it stops when it can't find the acronym command (or one of its many variations ala regular expression). It's hazardous, though. There could be unintended side-effects which I wouldn't see except when the report is reviewed (by others).
    – user36800
    Jan 19 '21 at 20:09
  • It seems less risky to use Vim to filter and wrangle the acronym file, paste/add the entries into the spell's word list file, then submit the latter to a unix sort and uniquification command. There's also no chance of issuing zg or zG on a mistyped acronym label. I was hoping there was a way to make Vim ignore labels within curly braces, like it does for \cite{}, \label{}, and variations of \ref{}.
    – user36800
    Jan 19 '21 at 20:12
  • It's not enough to update the .add file; you also have to update the .spl file (which zg does automatically). Either way, you could use something like %s/\v\\(ac|acs|acl|acp|acpl|Ac)\{\zs[^}]*\ze\}/\=/ if you can fit it into a single-expression; otherwise I think you'll have to write a while-loop with search(). That's fair re: the hazard though. You might be able to tell syntax to ignore spelling (:help :syn-spell)
    – D. Ben Knoble
    Jan 19 '21 at 20:12
  • Thanks, D. Ben Knoble. I browsed around that file. I think I will need a lot more research to figure out how spell and syntax interacts, and the kinds of data object they use.
    – user36800
    Jan 19 '21 at 20:27

Spellchecking is permitted only on syntax elements that accept sub-token of type @Spell. I don't remember the exact details. The syntax files have been patched ages ago now.

I wouldn't be surprised that \cite{} and other commands introduce an new syntax kind for the token within braces, and that token doesn't include the @Spell syntax cluster.

If you add a syntax match for acronyms, it should get ignored by spell checking as well. You can have a look at {rtp}/syntax/tex.vim. This should be the most efficient approach.


" Dirty hack: we should define new texAcronymGroup and texAcronymZone instead
syn region texRefZone       matchgroup=texStatement start="\\[Aa]c[lp*]*{"  end="}\|%stopzone\>"    contains=@texRefGroup
  • Hi, Luc. I took a look at tex.vim, and I recall trying plumb the documentation on syntax in the past. I don't think that I'll be able to crack that nut in the near future. Thanks anyway. Mar 4 '21 at 3:58
  • 1
    If you search the part on \cite{}, you should be able to duplicate a simplified version for acronyms and drop it into your $HOME/.vim/syntax Mar 4 '21 at 4:09
  • 1
    The only matching line in /usr/share/vim/vim82/syntax/tex.vim is syn match texRefZone '\\ac\%([tp]\*\=\)\=\>' nextgroup=texRefOption,texCite. I copied it to /usr/share/vim/vimfiles/syntax/tex.vim and replaced cite with ac. I then issued that command in the buffer containing the *.tex file of interest. It worked! I just have to repeat that command for all variations of the \ac command. Thanks! Unfortunately, it doesn't work for (say) \Acs*{acme}, even if I escape the * with backslash. Mar 4 '21 at 5:23
  • Indeed. Something else is conflicting when starting with a capital A, but I don't know what. But it seems it doesn't work either with \citet*{} Mar 4 '21 at 11:15
  • syn region texRefZone matchgroup=texStatement start="\\[Aa]c[lp*]*{" end="}\|%stopzone\>" contains=@texRefGroup seems to do it though. You should be able to add it in an after/syntax/tex.vim file Mar 4 '21 at 11:21

If I'm reading the acro manual correctly, you have to define all acronyms in the preamble with \DeclareAcronym{abc}{properties}; if that's not correct you can adapt the code below to use \ac{} and others). Therefore, you could adopt the following strategy which will work independent of folding status, unlike using a macro:

  1. Write a function that reads your tex file and extracts all of the acronynm ids. Then add these to the internal word list which won't pollute your spellfile.
  2. Use an autocmd to execute this, I would suggest on BufEnter and BufWritePost is probably sufficient).

For example, in ftplugin/tex.vim:

function! SpellAddAcronyms()
    let l:lines = getline(1, "$")
    call filter(l:lines, {_, v -> match(v, '\\DeclareAcronym{') > -1})
    call map(l:lines, {_, v -> matchstr(v, '\\DeclareAcronym{[^}]*}')[16:-2]})
    for l:id in l:lines
        silent execute ":spellgood! " . l:id

augroup SpellAddAcronyms
    autocmd! * <buffer>
    autocmd BufEnter,BufWritePost <buffer> call SpellAddAcronyms()
augroup END

I use this strategy to add citekeys to the internal word list which otherwise get flagged as spelling errors.

  • Thanks, Andrew Ho-Lee. I'm surprised to see that your cite keys get flagged. Mine don't, and I assume it is because of syn match texRefZone '\\cite\%([tp]\*\=\)\=\>' nextgroup=texRefOption,texCite in /usr/share/vim/vim82/syntax/tex.vim. I'm going to keep your approach as a possible solution for tough cases in the future. I appreciate you sharing it. Mar 4 '21 at 13:28
  • I hadn't realised that \cite{} was excluded from spell checking by that. I use biblatex with \autocite{} which is probably why they are flagged as \autocite{} isn't in vim's syntax/tex.vim. Maybe I can replace my autocmd with an adapted form that syn match! Mar 4 '21 at 14:01
  • I haven't experimented, but I suspect that you need a lot of the code logic from /usr/share/vim/vim82/syntax/tex.vim (or wherever that file sits in your installation), which I don't fully understand. That code probably accompanies all installations of vim 8.2 and above (and maybe even below), however, and is independent of the specific LaTeX tool flow that individuals may be using. Mar 4 '21 at 14:49

I created a normal-mode macro, stored in register a, that searches the *.tex source file for acronym tags and performs a normal-mode zG on them: /\<[Aa]c[sl]\?p\?\*\?{\zs\i\+\ze}^MzG@a. The ^M is a carriage return, captured by preceding it with Ctrl+V.

I invoke the macro by 1G@a. The macro runs in a loop to capture all the acronym tags into the "internal word list...used for all buffers where 'spell' is set". Spell check then ceases to flag the tags as errors. I found that all folds have to be opened in order for the macro to catch all acronym tags.

I remove the tags from the internal word list by setting the encoding option. Since I don't actually want to change that option's setting, D. Ben Knoble suggested :let &l:encoding = &l:encoding, which works. The acronym tags become flagged again by spell check.

Note that setl encoding=&encoding does not work. It doesn't re-enable flagging of the acronym tags by spell check.

  • 1
    I'm surprised setlocal encoding=&encoding doesn't change the encoding, but maybe that's a syntax I'm not familiar with. I would have done let &l:encoding = &l:encoding
    – D. Ben Knoble
    Mar 3 '21 at 20:53
  • @D. Ben Knoble: Thanks! I will update the answer, as your suggestion works! Mar 3 '21 at 20:58

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.