├── README ├── autoload └── cmakecomplete.vim ├── doc └── cmakecomplete.txt └── plugin └── cmakecomplete.vim /README: -------------------------------------------------------------------------------- 1 | Vim plugin for CMake omnicompletion 2 | 3 | See doc/cmakecomplete.txt for more details. 4 | -------------------------------------------------------------------------------- /autoload/cmakecomplete.vim: -------------------------------------------------------------------------------- 1 | " Description: Omni completion for CMake 2 | " Maintainer: Richard Quirk richard.quirk at gmail.com 3 | " License: Apache License 2.0 4 | " 5 | " To install cmake completion, copy the contents of this file to 6 | " $HOME/.vim/autoload/cmakecomplete.vim 7 | " And the associated plugin file to: 8 | " $HOME/.vim/plugin/cmake.vim 9 | " Then in a CMakeLists.txt file, use C-X C-O to autocomplete cmake 10 | " keywords with the corresponding info shown in the info buffer. 11 | 12 | """ 13 | " Copyright 2009 Richard Quirk 14 | " 15 | " Licensed under the Apache License, Version 2.0 (the "License"); you may not 16 | " use this file except in compliance with the License. You may obtain a copy of 17 | " the License at http://www.apache.org/licenses/LICENSE-2.0 18 | " 19 | " Unless required by applicable law or agreed to in writing, software 20 | " distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 21 | " WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 22 | " License for the specific language governing permissions and limitations under 23 | " the License. 24 | """ 25 | if version < 700 26 | finish 27 | endif 28 | let s:keepcpo= &cpo 29 | set cpo&vim 30 | 31 | " this is the list of potential completions 32 | let s:cmake_commands = [] 33 | let s:cmake_properties = [] 34 | let s:cmake_modules = [] 35 | let s:cmake_variables = [] 36 | let s:cmake_command_examples = {} 37 | 38 | function s:createbuffer() 39 | let counter = 0 40 | let versionedName = 'cmake help (' . counter . ')' 41 | while buflisted(versionedName) 42 | let counter += 1 43 | let versionedName = 'cmake help (' . counter . ')' 44 | endwhile 45 | return versionedName 46 | endfunction 47 | 48 | function cmakecomplete#Help(...) 49 | " create a new buffer and show all of cmake's help there 50 | let output = "" 51 | if a:0 == 1 52 | let arg = tolower(a:1) 53 | let searchlist = [s:cmake_commands, s:cmake_properties, s:cmake_modules, s:cmake_variables] 54 | for sl in searchlist 55 | for m in sl 56 | if m['word'] == arg 57 | let output = m['info'] 58 | break 59 | endif 60 | endfor 61 | if output != "" 62 | break 63 | endif 64 | endfor 65 | else 66 | let output = system('cmake --help-full') 67 | endif 68 | if output == "" 69 | echoerr "No help found for that" 70 | return 71 | endif 72 | pc 73 | exec "above ". winheight(0) / 3 . " split" 74 | let bufferName=s:createbuffer() 75 | edit `=bufferName` 76 | setlocal buftype=nofile 77 | setlocal previewwindow 78 | setlocal readonly 79 | setlocal noswapfile 80 | setlocal bufhidden=delete 81 | silent 0put=output 82 | let &filetype = 'help' 83 | setlocal nomodifiable 84 | 0 85 | endfunction 86 | 87 | function cmakecomplete#AddWord(word, info, list, ignore_case) 88 | " strip the leading spaces, add the info 89 | call add(a:list, {'word': substitute(a:word, '^\W\+', '', 'g'), 90 | \ 'icase': a:ignore_case, 91 | \ 'info': a:info}) 92 | endfunction 93 | 94 | function cmakecomplete#PrintExamples() 95 | echo len(s:cmake_command_examples) 96 | echo s:cmake_command_examples 97 | endfunc 98 | 99 | function cmakecomplete#Version() 100 | let output = system('cmake --version') 101 | for c in split(output, '\n') 102 | if c =~ 'version' 103 | let components = split(c, ' ') 104 | return components[len(components) - 1] 105 | endif 106 | endfor 107 | endfunc 108 | 109 | function cmakecomplete#Init3(help, list, ignore_case) 110 | " parse the help to get completions 111 | let oldic = &ignorecase 112 | set noignorecase 113 | let output = system('cmake --help-' . a:help) 114 | let word = '' 115 | let info = [] 116 | let in_example = 0 117 | let last_line = '' 118 | for c in split(output, '\n') 119 | " CMake commands now have a line of dashes after them... 120 | if c =~ '^-\+$' 121 | if word != '' 122 | call cmakecomplete#AddWord(word, join(info[0:len(info) - 3], ''), a:list, a:ignore_case) 123 | endif 124 | let info = [last_line, "\n", c] 125 | let word = substitute(last_line, '^\s\+', '', 'g') 126 | let last_line = c 127 | else 128 | let last_line = c 129 | " if we have a command, then the rest is the help 130 | if word != '' 131 | " extract examples... 132 | if in_example == 0 && a:help == 'commands' && c =~ '^\s' . word 133 | let in_example = 1 134 | let example = substitute(c, '\W', ' ', 'g') 135 | elseif in_example == 1 136 | if c =~ '^\s*$' 137 | if !has_key(s:cmake_command_examples, word) 138 | let s:cmake_command_examples[word] = '' 139 | endif 140 | let s:cmake_command_examples[word] = s:cmake_command_examples[word] . ' ' . example 141 | let in_example = 0 142 | else 143 | let example = example . " " . substitute(c, '\W', ' ', 'g') 144 | endif 145 | endif 146 | let info += [c, "\n"] 147 | endif 148 | endif 149 | endfor 150 | " add the last command to the list 151 | if word != '' 152 | call cmakecomplete#AddWord(word, join(info[0: len(info) - 3], ''), a:list, a:ignore_case) 153 | endif 154 | let &ignorecase = oldic 155 | endfunction 156 | 157 | function cmakecomplete#Init(help, list, ignore_case) 158 | " parse the help to get completions 159 | let oldic = &ignorecase 160 | set noignorecase 161 | let output = system('cmake --help-' . a:help) 162 | let word = '' 163 | let info = '' 164 | let re = '^\W\W[a-zA-Z_]\+$' 165 | if !a:ignore_case 166 | let re = '^\W\W[A-Z_]\+$' 167 | endif 168 | let in_example = 0 169 | for c in split(output, '\n') 170 | " CMake commands start with 2 blanks and then a lowercase letter 171 | if c =~ re 172 | if word != '' 173 | call cmakecomplete#AddWord(word, info, a:list, a:ignore_case) 174 | endif 175 | let info = c . "\n" 176 | let word = substitute(c, '^\s\+', '', 'g') 177 | else 178 | " if we have a command, then the rest is the help 179 | if word != '' 180 | " extract examples... 181 | if in_example == 0 && a:help == 'commands' && c =~ '^\s\{9}' . word 182 | let in_example = 1 183 | let example = substitute(c, '\W', ' ', 'g') 184 | elseif in_example == 1 185 | if c =~ '^\s*$' 186 | if !has_key(s:cmake_command_examples, word) 187 | let s:cmake_command_examples[word] = '' 188 | endif 189 | let s:cmake_command_examples[word] = s:cmake_command_examples[word] . ' ' . example 190 | let in_example = 0 191 | else 192 | let example = example . " " . substitute(c, '\W', ' ', 'g') 193 | endif 194 | endif 195 | " End of the help is marked with line of dashes 196 | " But only after getting at least one command 197 | if c =~ '^-\+$' 198 | continue 199 | endif 200 | let info = info . c . "\n" 201 | endif 202 | endif 203 | endfor 204 | " add the last command to the list 205 | if word != '' 206 | call cmakecomplete#AddWord(word, info, a:list, a:ignore_case) 207 | endif 208 | let &ignorecase = oldic 209 | endfunction 210 | 211 | function! cmakecomplete#InComment() 212 | return match(synIDattr(synID(line("."), col(".")-1, 1), "name"), '\= 0 213 | endfunction 214 | 215 | function! cmakecomplete#InVariable() 216 | let here = line('.') 217 | let openb = search('${', 'bn', line("w0"), 500) 218 | if openb == 0 219 | return 0 220 | endif 221 | let closeb = search('}', 'bn', openb, 500) 222 | return closeb == 0 && openb <= here 223 | endfunction 224 | 225 | function! cmakecomplete#InFunction() 226 | let here = line('.') 227 | let openb = search('(', 'bn', line("w0"), 500) 228 | if openb == 0 229 | return 0 230 | endif 231 | let closeb = search(')', 'bn', openb, 500) 232 | return closeb == 0 && openb <= here 233 | endfunction 234 | 235 | function! cmakecomplete#InFunctionName() 236 | let here = line('.') 237 | let [openl, openc] = searchpos('[a-zA-Z_]\+\s*(', 'bn', line("w0"), 500) 238 | if openl == 0 239 | return "" 240 | endif 241 | let closeb = search(')', 'bn', openl, 500) 242 | if closeb == 0 && openl <= here 243 | return substitute(getline(openl)[(openc - 1):], '\s*(.*', '', 'g') 244 | endif 245 | return "" 246 | endfunction 247 | 248 | function! cmakecomplete#InInclude() 249 | let here = line('.') 250 | let openb = search('include(', 'bn', line("w0"), 500) 251 | if openb == 0 252 | return 0 253 | endif 254 | let closeb = search(')', 'bn', openb, 500) 255 | return closeb == 0 && openb <= here 256 | endfunction 257 | 258 | function! cmakecomplete#GetArguments(info) 259 | let oldic = &ignorecase 260 | set noignorecase 261 | let words = map(filter(split(s:cmake_command_examples[a:info]), 262 | \ 'v:val == toupper(v:val)'), 263 | \ "{'word': v:val, " . 264 | \ " 'icase ': 0 }") 265 | let &ignorecase = oldic 266 | return words 267 | endfunc 268 | 269 | function! cmakecomplete#PreviousWord() 270 | let here = line('.') 271 | let openb = search('(', 'bn', line("w0"), 500) 272 | if openb == 0 273 | return "" 274 | endif 275 | let closeb = search(')', 'bn', openb, 500) 276 | if closeb == 0 && openb <= here 277 | let propw = search('\', 'bn', openb, 500) 278 | if propw 279 | return "PROPERTIES" 280 | endif 281 | endif 282 | return "" 283 | endfunc 284 | 285 | function! cmakecomplete#Complete(findstart, base) 286 | if a:findstart == 1 287 | let s:cmakeNoComplete = 0 288 | " first time, wants to know where the word starts 289 | if cmakecomplete#InComment() 290 | let s:cmakeNoComplete = 1 291 | return -1 292 | endif 293 | let linestr = getline('.') 294 | let start = col('.') - 1 295 | while start > 0 && linestr[start - 1] =~ '[a-zA-Z_]' 296 | let start -= 1 297 | endwhile 298 | let s:compl_context = linestr[0:col('.')-2] 299 | return start 300 | endif 301 | if exists("s:compl_context") 302 | let linestr = s:compl_context 303 | unlet! s:compl_context 304 | else 305 | let linestr = a:base 306 | endif 307 | 308 | if s:cmakeNoComplete 309 | return [] 310 | endif 311 | 312 | let res = [] 313 | let list = s:cmake_commands 314 | let match = '^' . tolower(a:base) 315 | if cmakecomplete#InVariable() 316 | let match = '^' . a:base 317 | let list = s:cmake_variables 318 | elseif cmakecomplete#InInclude() 319 | " return modules 320 | let match = '^' . a:base 321 | let list = s:cmake_modules 322 | elseif cmakecomplete#InFunction() 323 | " return completion variables 324 | let match = '^' . a:base 325 | let fname = cmakecomplete#InFunctionName() 326 | if has_key(s:cmake_command_examples, fname) 327 | let list = cmakecomplete#GetArguments(fname) 328 | else 329 | let list = s:cmake_properties 330 | endif 331 | let prevword = cmakecomplete#PreviousWord() 332 | if prevword == "PROPERTIES" 333 | let list = s:cmake_properties 334 | endif 335 | endif 336 | " return the completion words 337 | for m in list 338 | if m['word'] =~ match 339 | call add(res, m) 340 | endif 341 | endfor 342 | " problem here: always returns lower case 343 | return res 344 | endfunction 345 | 346 | function cmakecomplete#HelpComplete(ArgLead, CmdLine, CursorPos) 347 | let result = [] 348 | let match = '^' . a:ArgLead 349 | for m in s:cmake_commands 350 | let w = m['word'] 351 | if w =~ match 352 | call add(result, w) 353 | endif 354 | endfor 355 | return result 356 | endfunction 357 | 358 | if cmakecomplete#Version() =~ "^2\." 359 | call cmakecomplete#Init('commands', s:cmake_commands, 1) 360 | call cmakecomplete#Init('properties', s:cmake_properties, 0) 361 | call cmakecomplete#Init('modules', s:cmake_modules, 1) 362 | call cmakecomplete#Init('variables', s:cmake_variables, 1) 363 | else 364 | call cmakecomplete#Init3('commands', s:cmake_commands, 1) 365 | call cmakecomplete#Init3('properties', s:cmake_properties, 0) 366 | call cmakecomplete#Init3('modules', s:cmake_modules, 1) 367 | call cmakecomplete#Init3('variables', s:cmake_variables, 1) 368 | endif 369 | 370 | let &cpo = s:keepcpo 371 | unlet s:keepcpo 372 | -------------------------------------------------------------------------------- /doc/cmakecomplete.txt: -------------------------------------------------------------------------------- 1 | *cmakecomplete.txt* Vim plugin for CMake omnicompletion 2 | *cmakecomplete* 3 | 4 | ============================================================================== 5 | 6 | 1. Overview |cmakecomplete-overview| 7 | 2. Installation |cmakecomplete-installation| 8 | 9 | ============================================================================== 10 | 1. Overview 11 | *cmakecomplete-overview* 12 | The purpose of this script is to provide an 'omnifunc' function for the CMake 13 | scripting language. In a CMake file you can use |i_CTRL-X_CTRL-O| to complete 14 | command names and attributes within commands. 15 | 16 | *g:cmake_map_keys* 17 | Also the |K| key is mapped to lookup the help on the current word under the 18 | cursor. This can be avoided by setting 'g:cmake_map_keys' 19 | 20 | ============================================================================== 21 | 22 | 2. Installation 23 | *cmakecomplete-installation* 24 | 2.1. Script installation 25 | 26 | Unzip the downloaded file in your personal |vimfiles| directory (~/.vim under 27 | unix or %HOMEPATH%\vimfiles under windows). The 'omnifunc' option will be 28 | automatically set for CMake files. 29 | 30 | You also have to enable plugins by adding these two lines in your|.vimrc|file: > 31 | 32 | set nocp 33 | filetype plugin on 34 | < 35 | Please see |cp| and |filetype-plugin-on| sections for more details. 36 | 37 | The script assumes the cmake binary is in your $PATH and will use it to 38 | generate the help. 39 | 40 | 2.2. Files 41 | 42 | After installation you should have these files: 43 | 44 | autoload/cmakecomplete.vim 45 | plugin/cmakecomplete.vim 46 | doc/cmakecomplete.txt 47 | 48 | ============================================================================== 49 | -------------------------------------------------------------------------------- /plugin/cmakecomplete.vim: -------------------------------------------------------------------------------- 1 | " Description: CMake bootstrap plugin 2 | " Maintainer: Richard Quirk richard.quirk at gmail.com 3 | " License: Apache License 2.0 4 | " 5 | " To install cmake completion, copy the contents of this file to 6 | " $HOME/.vim/plugin/cmakecomplete.vim 7 | " And the associated autoload file to: 8 | " $HOME/.vim/autoload/cmakecomplete.vim 9 | " 10 | " The CMakeHelp command shows full help, or can be filtered by command 11 | 12 | """ 13 | " Copyright 2009 Richard Quirk 14 | " 15 | " Licensed under the Apache License, Version 2.0 (the "License"); you may not 16 | " use this file except in compliance with the License. You may obtain a copy of 17 | " the License at http://www.apache.org/licenses/LICENSE-2.0 18 | " 19 | " Unless required by applicable law or agreed to in writing, software 20 | " distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 21 | " WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 22 | " License for the specific language governing permissions and limitations under 23 | " the License. 24 | """ 25 | if exists('did_cmakecomplete') || &cp || version < 700 26 | finish 27 | endif 28 | let did_cmakecomplete = 1 29 | command! -nargs=* -complete=customlist,cmakecomplete#HelpComplete CMakeHelp call cmakecomplete#Help() 30 | autocmd FileType cmake set omnifunc=cmakecomplete#Complete 31 | autocmd FileType cmake setlocal completeopt+=preview 32 | 33 | if !exists('g:cmake_map_keys') 34 | let g:cmake_map_keys = 1 35 | endif 36 | 37 | if g:cmake_map_keys 38 | autocmd FileType cmake nnoremap K :call cmakecomplete#Help(expand("")) 39 | endif 40 | --------------------------------------------------------------------------------