3

I'm wondering, if there's a way to move with % in CMakeLists.txt files between foreach and endforeach, if and endif, function and endfunction, …

googeling I only found plugins that allow calling cmake from within vim, but not for editing CMakeLists.txt files.

2 Answers 2

5

You can achieve this easily using either the plugin matchit (distributed with vim, just use packadd! matchit) or match-up (external plugin). The latter provides enhanced text objects and also enables highlighting of the words.

To define the matches for cmake, create a file .vim/after/ftplugin/cmake.vim containing:

if exists('loaded_matchit')
    let b:match_words = '\<if\>:\<elseif\>\|\<else\>:\<endif\>'
      \ . ',\<foreach\>\|\<while\>:\<break\>:\<endforeach\>\|\<endwhile\>'
      \ . ',\<macro\>:\<endmacro\>'
      \ . ',\<function\>:\<endfunction\>'
    let b:match_ignorecase = 1

    let b:undo_ftplugin .= "| unlet b:match_words"
endif

This should work with either plugin.

2

I didn't find an existing solution, but the way to implement that doesn't seem too hard. One needs the matchit plugin (cf https://vi.stackexchange.com/a/784/6044)

" in .vimrc
runtime macros/matchit.vim

And can then define b:match_words e.g. in .vim/ftplugin/cmake.vim

if exists("loaded_matchit")
  let b:match_words =  '^[^#]*\<if\>\s*(:^[^#]*\<else\>\s*(:^[^#]*\<elseif\>\s*(:^[^#]*\<endif\>\s*(\c'
  let b:match_words .= ',^[^#]*\<function\>\s*(:^[^#]*\<endfunction\>\s*(\c'
  let b:match_words .= ',^[^#]*\<foreach\>\s*(:^[^#]*\<endforeach\>\s*(\c'
  let b:match_words .= ',^[^#]*\<macro\>\s*(:^[^#]*\<endmacro\>\s*(\c'
  let b:match_words .= ',^[^#]*\<while\>\s*(:^[^#]*\<endwhile\>\s*(\c'
endif

to be honest I bodged this quickly and didn't go through the entire matchit documentation, but so far it seems to do the job.

1
  • 1
    I added an answer which is a bit more up to date and includes an alternative plugn. Note you should not need ^[^#]* because comments are already excluded (I'm also not totally sure if you need the \s*(). You can use b:match_ignorecase instead of \c. packadd! matchit is the new style of enabling matchit.
    – Mass
    Aug 29, 2018 at 16:40

Your Answer

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

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