blob: e3ea0e2d81b2de816d27f3f972eb936671307009 [file] [log] [blame]
Bram Moolenaar4770d092006-01-12 23:22:24 +00001" Vim completion script
2" Language: All languages, uses existing syntax highlighting rules
Bram Moolenaar6dfc28b2010-02-11 14:19:15 +01003" Maintainer: David Fishburn <dfishburn dot vim at gmail dot com>
Bram Moolenaar34feacb2012-12-05 19:01:43 +01004" Version: 11.0
5" Last Change: 2012 Dec 04
6" Usage: For detailed help, ":help ft-syntax-omni"
Bram Moolenaar4770d092006-01-12 23:22:24 +00007
Bram Moolenaar6dfc28b2010-02-11 14:19:15 +01008" History
Bram Moolenaar40af4e32010-07-29 22:33:18 +02009"
Bram Moolenaar34feacb2012-12-05 19:01:43 +010010" Version 11.0
11" Corrected which characters required escaping during
12" substitution calls.
13"
Bram Moolenaar97d62492012-11-15 21:28:22 +010014" Version 10.0
15" Cycle through all the character ranges specified in the
16" iskeyword option and build a list of valid word separators.
Bram Moolenaar34feacb2012-12-05 19:01:43 +010017" Prior to this change, only actual characters were used,
18" where for example ASCII "45" == "-". If "45" were used
19" in iskeyword the hyphen would not be picked up.
Bram Moolenaar97d62492012-11-15 21:28:22 +010020" This introduces a new option, since the character ranges
21" specified could be multibyte:
22" let g:omni_syntax_use_single_byte = 1
Bram Moolenaar34feacb2012-12-05 19:01:43 +010023" This by default will only allow single byte ASCII
Bram Moolenaar97d62492012-11-15 21:28:22 +010024" characters to be added and an additional check to ensure
25" the charater is printable (see documentation for isprint).
26"
27" Version 9.0
28" Add the check for cpo.
29"
Bram Moolenaarf1568ec2011-12-14 21:17:39 +010030" Version 8.0
31" Updated SyntaxCSyntaxGroupItems()
32" - Some additional syntax items were also allowed
33" on nextgroup= lines which were ignored by default.
34" Now these lines are processed independently.
35"
Bram Moolenaar40af4e32010-07-29 22:33:18 +020036" Version 7.0
37" Updated syntaxcomplete#OmniSyntaxList()
38" - Looking up the syntax groups defined from a syntax file
Bram Moolenaar34feacb2012-12-05 19:01:43 +010039" looked for only 1 format of {filetype}GroupName, but some
Bram Moolenaar40af4e32010-07-29 22:33:18 +020040" syntax writers use this format as well:
41" {b:current_syntax}GroupName
42" OmniSyntaxList() will now check for both if the first
43" method does not find a match.
44"
45" Version 6.0
46" Added syntaxcomplete#OmniSyntaxList()
Bram Moolenaar34feacb2012-12-05 19:01:43 +010047" - Allows other plugins to use this for their own
Bram Moolenaar40af4e32010-07-29 22:33:18 +020048" purposes.
49" - It will return a List of all syntax items for the
Bram Moolenaar34feacb2012-12-05 19:01:43 +010050" syntax group name passed in.
51" - XPTemplate for SQL will use this function via the
Bram Moolenaar40af4e32010-07-29 22:33:18 +020052" sqlcomplete plugin to populate a Choose box.
53"
Bram Moolenaar6dfc28b2010-02-11 14:19:15 +010054" Version 5.0
Bram Moolenaar40af4e32010-07-29 22:33:18 +020055" Updated SyntaxCSyntaxGroupItems()
56" - When processing a list of syntax groups, the final group
57" was missed in function SyntaxCSyntaxGroupItems.
Bram Moolenaar6dfc28b2010-02-11 14:19:15 +010058"
Bram Moolenaar4770d092006-01-12 23:22:24 +000059" Set completion with CTRL-X CTRL-O to autoloaded function.
Bram Moolenaarc15ef302006-03-19 22:11:16 +000060" This check is in place in case this script is
Bram Moolenaar34feacb2012-12-05 19:01:43 +010061" sourced directly instead of using the autoload feature.
Bram Moolenaarc06ac342006-03-02 22:43:39 +000062if exists('+omnifunc')
Bram Moolenaarc15ef302006-03-19 22:11:16 +000063 " Do not set the option if already set since this
64 " results in an E117 warning.
65 if &omnifunc == ""
66 setlocal omnifunc=syntaxcomplete#Complete
67 endif
Bram Moolenaar4770d092006-01-12 23:22:24 +000068endif
69
70if exists('g:loaded_syntax_completion')
Bram Moolenaar34feacb2012-12-05 19:01:43 +010071 finish
Bram Moolenaar4770d092006-01-12 23:22:24 +000072endif
Bram Moolenaar34feacb2012-12-05 19:01:43 +010073let g:loaded_syntax_completion = 110
Bram Moolenaar97d62492012-11-15 21:28:22 +010074
75" Turn on support for line continuations when creating the script
76let s:cpo_save = &cpo
77set cpo&vim
Bram Moolenaar97e8f352006-05-06 21:40:45 +000078
79" Set ignorecase to the ftplugin standard
Bram Moolenaar9964e462007-05-05 17:54:07 +000080" This is the default setting, but if you define a buffer local
81" variable you can override this on a per filetype.
Bram Moolenaar97e8f352006-05-06 21:40:45 +000082if !exists('g:omni_syntax_ignorecase')
83 let g:omni_syntax_ignorecase = &ignorecase
84endif
Bram Moolenaar4770d092006-01-12 23:22:24 +000085
Bram Moolenaar9964e462007-05-05 17:54:07 +000086" Indicates whether we should use the iskeyword option to determine
87" how to split words.
88" This is the default setting, but if you define a buffer local
89" variable you can override this on a per filetype.
90if !exists('g:omni_syntax_use_iskeyword')
91 let g:omni_syntax_use_iskeyword = 1
92endif
93
Bram Moolenaar97d62492012-11-15 21:28:22 +010094" When using iskeyword, this setting controls whether the characters
95" should be limited to single byte characters.
96if !exists('g:omni_syntax_use_single_byte')
97 let g:omni_syntax_use_single_byte = 1
98endif
99
100" When using iskeyword, this setting controls whether the characters
101" should be limited to single byte characters.
102if !exists('g:omni_syntax_use_iskeyword_numeric')
103 let g:omni_syntax_use_iskeyword_numeric = 1
104endif
105
Bram Moolenaar9964e462007-05-05 17:54:07 +0000106" Only display items in the completion window that are at least
107" this many characters in length.
108" This is the default setting, but if you define a buffer local
109" variable you can override this on a per filetype.
110if !exists('g:omni_syntax_minimum_length')
111 let g:omni_syntax_minimum_length = 0
112endif
113
Bram Moolenaar4770d092006-01-12 23:22:24 +0000114" This script will build a completion list based on the syntax
115" elements defined by the files in $VIMRUNTIME/syntax.
Bram Moolenaar4770d092006-01-12 23:22:24 +0000116let s:syn_remove_words = 'match,matchgroup=,contains,'.
Bram Moolenaarf1568ec2011-12-14 21:17:39 +0100117 \ 'links to,start=,end='
118 " \ 'links to,start=,end=,nextgroup='
Bram Moolenaar4770d092006-01-12 23:22:24 +0000119
120let s:cache_name = []
121let s:cache_list = []
Bram Moolenaarc15ef302006-03-19 22:11:16 +0000122let s:prepended = ''
Bram Moolenaar4770d092006-01-12 23:22:24 +0000123
124" This function is used for the 'omnifunc' option.
125function! syntaxcomplete#Complete(findstart, base)
126
Bram Moolenaar9964e462007-05-05 17:54:07 +0000127 " Only display items in the completion window that are at least
128 " this many characters in length
129 if !exists('b:omni_syntax_ignorecase')
130 if exists('g:omni_syntax_ignorecase')
131 let b:omni_syntax_ignorecase = g:omni_syntax_ignorecase
132 else
133 let b:omni_syntax_ignorecase = &ignorecase
134 endif
135 endif
136
Bram Moolenaar4770d092006-01-12 23:22:24 +0000137 if a:findstart
138 " Locate the start of the item, including "."
139 let line = getline('.')
140 let start = col('.') - 1
141 let lastword = -1
142 while start > 0
Bram Moolenaar9964e462007-05-05 17:54:07 +0000143 " if line[start - 1] =~ '\S'
144 " let start -= 1
145 " elseif line[start - 1] =~ '\.'
146 if line[start - 1] =~ '\k'
Bram Moolenaar4770d092006-01-12 23:22:24 +0000147 let start -= 1
Bram Moolenaar9964e462007-05-05 17:54:07 +0000148 let lastword = a:findstart
Bram Moolenaar4770d092006-01-12 23:22:24 +0000149 else
150 break
151 endif
152 endwhile
153
154 " Return the column of the last word, which is going to be changed.
155 " Remember the text that comes before it in s:prepended.
156 if lastword == -1
157 let s:prepended = ''
158 return start
159 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +0000160 let s:prepended = strpart(line, start, (col('.') - 1) - start)
161 return start
Bram Moolenaar4770d092006-01-12 23:22:24 +0000162 endif
163
Bram Moolenaar9964e462007-05-05 17:54:07 +0000164 " let base = s:prepended . a:base
165 let base = s:prepended
Bram Moolenaar4770d092006-01-12 23:22:24 +0000166
Bram Moolenaar97e8f352006-05-06 21:40:45 +0000167 let filetype = substitute(&filetype, '\.', '_', 'g')
168 let list_idx = index(s:cache_name, filetype, 0, &ignorecase)
Bram Moolenaar4770d092006-01-12 23:22:24 +0000169 if list_idx > -1
170 let compl_list = s:cache_list[list_idx]
171 else
Bram Moolenaar97e8f352006-05-06 21:40:45 +0000172 let compl_list = OmniSyntaxList()
173 let s:cache_name = add( s:cache_name, filetype )
174 let s:cache_list = add( s:cache_list, compl_list )
Bram Moolenaar4770d092006-01-12 23:22:24 +0000175 endif
176
177 " Return list of matches.
178
Bram Moolenaar9964e462007-05-05 17:54:07 +0000179 if base != ''
180 " let compstr = join(compl_list, ' ')
181 " let expr = (b:omni_syntax_ignorecase==0?'\C':'').'\<\%('.base.'\)\@!\w\+\s*'
182 " let compstr = substitute(compstr, expr, '', 'g')
183 " let compl_list = split(compstr, '\s\+')
184
185 " Filter the list based on the first few characters the user
186 " entered
187 let expr = 'v:val '.(g:omni_syntax_ignorecase==1?'=~?':'=~#')." '^".escape(base, '\\/.*$^~[]').".*'"
188 let compl_list = filter(deepcopy(compl_list), expr)
Bram Moolenaar4770d092006-01-12 23:22:24 +0000189 endif
190
191 return compl_list
192endfunc
193
Bram Moolenaar40af4e32010-07-29 22:33:18 +0200194function! syntaxcomplete#OmniSyntaxList(...)
195 if a:0 > 0
196 let parms = []
Bram Moolenaar34feacb2012-12-05 19:01:43 +0100197 if 3 == type(a:1)
Bram Moolenaar40af4e32010-07-29 22:33:18 +0200198 let parms = a:1
199 elseif 1 == type(a:1)
200 let parms = split(a:1, ',')
201 endif
202 return OmniSyntaxList( parms )
203 else
204 return OmniSyntaxList()
205 endif
206endfunc
207
208function! OmniSyntaxList(...)
209 let list_parms = []
210 if a:0 > 0
Bram Moolenaar34feacb2012-12-05 19:01:43 +0100211 if 3 == type(a:1)
Bram Moolenaar40af4e32010-07-29 22:33:18 +0200212 let list_parms = a:1
213 elseif 1 == type(a:1)
214 let list_parms = split(a:1, ',')
215 endif
216 endif
217
Bram Moolenaar97e8f352006-05-06 21:40:45 +0000218 " Default to returning a dictionary, if use_dictionary is set to 0
219 " a list will be returned.
220 " let use_dictionary = 1
221 " if a:0 > 0 && a:1 != ''
222 " let use_dictionary = a:1
223 " endif
224
Bram Moolenaar9964e462007-05-05 17:54:07 +0000225 " Only display items in the completion window that are at least
226 " this many characters in length
227 if !exists('b:omni_syntax_use_iskeyword')
228 if exists('g:omni_syntax_use_iskeyword')
229 let b:omni_syntax_use_iskeyword = g:omni_syntax_use_iskeyword
230 else
231 let b:omni_syntax_use_iskeyword = 1
232 endif
233 endif
234
235 " Only display items in the completion window that are at least
236 " this many characters in length
237 if !exists('b:omni_syntax_minimum_length')
238 if exists('g:omni_syntax_minimum_length')
239 let b:omni_syntax_minimum_length = g:omni_syntax_minimum_length
240 else
241 let b:omni_syntax_minimum_length = 0
242 endif
243 endif
244
Bram Moolenaar4770d092006-01-12 23:22:24 +0000245 let saveL = @l
Bram Moolenaar40af4e32010-07-29 22:33:18 +0200246 let filetype = substitute(&filetype, '\.', '_', 'g')
Bram Moolenaar34feacb2012-12-05 19:01:43 +0100247
Bram Moolenaar40af4e32010-07-29 22:33:18 +0200248 if empty(list_parms)
249 " Default the include group to include the requested syntax group
250 let syntax_group_include_{filetype} = ''
251 " Check if there are any overrides specified for this filetype
252 if exists('g:omni_syntax_group_include_'.filetype)
253 let syntax_group_include_{filetype} =
Bram Moolenaar34feacb2012-12-05 19:01:43 +0100254 \ substitute( g:omni_syntax_group_include_{filetype},'\s\+','','g')
Bram Moolenaar40af4e32010-07-29 22:33:18 +0200255 let list_parms = split(g:omni_syntax_group_include_{filetype}, ',')
256 if syntax_group_include_{filetype} =~ '\w'
Bram Moolenaar34feacb2012-12-05 19:01:43 +0100257 let syntax_group_include_{filetype} =
258 \ substitute( syntax_group_include_{filetype},
Bram Moolenaar40af4e32010-07-29 22:33:18 +0200259 \ '\s*,\s*', '\\|', 'g'
260 \ )
261 endif
262 endif
263 else
264 " A specific list was provided, use it
265 endif
266
Bram Moolenaar4770d092006-01-12 23:22:24 +0000267 " Loop through all the syntax groupnames, and build a
Bram Moolenaar34feacb2012-12-05 19:01:43 +0100268 " syntax file which contains these names. This can
Bram Moolenaar4770d092006-01-12 23:22:24 +0000269 " work generically for any filetype that does not already
270 " have a plugin defined.
271 " This ASSUMES the syntax groupname BEGINS with the name
Bram Moolenaar34feacb2012-12-05 19:01:43 +0100272 " of the filetype. From my casual viewing of the vim7\syntax
Bram Moolenaar40af4e32010-07-29 22:33:18 +0200273 " directory this is true for almost all syntax definitions.
274 " As an example, the SQL syntax groups have this pattern:
275 " sqlType
276 " sqlOperators
277 " sqlKeyword ...
Bram Moolenaar4770d092006-01-12 23:22:24 +0000278 redir @l
Bram Moolenaar40af4e32010-07-29 22:33:18 +0200279 silent! exec 'syntax list '.join(list_parms)
Bram Moolenaar4770d092006-01-12 23:22:24 +0000280 redir END
281
Bram Moolenaarc06ac342006-03-02 22:43:39 +0000282 let syntax_full = "\n".@l
Bram Moolenaar4770d092006-01-12 23:22:24 +0000283 let @l = saveL
284
Bram Moolenaar34feacb2012-12-05 19:01:43 +0100285 if syntax_full =~ 'E28'
Bram Moolenaarc06ac342006-03-02 22:43:39 +0000286 \ || syntax_full =~ 'E411'
287 \ || syntax_full =~ 'E415'
288 \ || syntax_full =~ 'No Syntax items'
289 return []
Bram Moolenaar4770d092006-01-12 23:22:24 +0000290 endif
291
Bram Moolenaar97e8f352006-05-06 21:40:45 +0000292 let filetype = substitute(&filetype, '\.', '_', 'g')
293
Bram Moolenaar40af4e32010-07-29 22:33:18 +0200294 let list_exclude_groups = []
Bram Moolenaar34feacb2012-12-05 19:01:43 +0100295 if a:0 > 0
Bram Moolenaar40af4e32010-07-29 22:33:18 +0200296 " Do nothing since we have specific a specific list of groups
297 else
298 " Default the exclude group to nothing
299 let syntax_group_exclude_{filetype} = ''
300 " Check if there are any overrides specified for this filetype
301 if exists('g:omni_syntax_group_exclude_'.filetype)
302 let syntax_group_exclude_{filetype} =
Bram Moolenaar34feacb2012-12-05 19:01:43 +0100303 \ substitute( g:omni_syntax_group_exclude_{filetype},'\s\+','','g')
Bram Moolenaar40af4e32010-07-29 22:33:18 +0200304 let list_exclude_groups = split(g:omni_syntax_group_exclude_{filetype}, ',')
Bram Moolenaar34feacb2012-12-05 19:01:43 +0100305 if syntax_group_exclude_{filetype} =~ '\w'
306 let syntax_group_exclude_{filetype} =
307 \ substitute( syntax_group_exclude_{filetype},
Bram Moolenaar40af4e32010-07-29 22:33:18 +0200308 \ '\s*,\s*', '\\|', 'g'
309 \ )
310 endif
Bram Moolenaarc06ac342006-03-02 22:43:39 +0000311 endif
312 endif
313
Bram Moolenaar97e8f352006-05-06 21:40:45 +0000314 " Sometimes filetypes can be composite names, like c.doxygen
315 " Loop through each individual part looking for the syntax
316 " items specific to each individual filetype.
Bram Moolenaar4770d092006-01-12 23:22:24 +0000317 let syn_list = ''
Bram Moolenaar97e8f352006-05-06 21:40:45 +0000318 let ftindex = 0
319 let ftindex = match(&filetype, '\w\+', ftindex)
Bram Moolenaar4770d092006-01-12 23:22:24 +0000320
Bram Moolenaar97e8f352006-05-06 21:40:45 +0000321 while ftindex > -1
322 let ft_part_name = matchstr( &filetype, '\w\+', ftindex )
Bram Moolenaar4770d092006-01-12 23:22:24 +0000323
Bram Moolenaar34feacb2012-12-05 19:01:43 +0100324 " Syntax rules can contain items for more than just the current
Bram Moolenaar97e8f352006-05-06 21:40:45 +0000325 " filetype. They can contain additional items added by the user
326 " via autocmds or their vimrc.
327 " Some syntax files can be combined (html, php, jsp).
328 " We want only items that begin with the filetype we are interested in.
329 let next_group_regex = '\n' .
330 \ '\zs'.ft_part_name.'\w\+\ze'.
Bram Moolenaar34feacb2012-12-05 19:01:43 +0100331 \ '\s\+xxx\s\+'
Bram Moolenaar97e8f352006-05-06 21:40:45 +0000332 let index = 0
333 let index = match(syntax_full, next_group_regex, index)
334
Bram Moolenaar40af4e32010-07-29 22:33:18 +0200335 if index == -1 && exists('b:current_syntax') && ft_part_name != b:current_syntax
336 " There appears to be two standards when writing syntax files.
337 " Either items begin as:
338 " syn keyword {filetype}Keyword values ...
339 " let b:current_syntax = "sql"
340 " let b:current_syntax = "sqlanywhere"
341 " Or
342 " syn keyword {syntax_filename}Keyword values ...
343 " let b:current_syntax = "mysql"
344 " So, we will make the format of finding the syntax group names
Bram Moolenaar34feacb2012-12-05 19:01:43 +0100345 " a bit more flexible and look for both if the first fails to
Bram Moolenaar40af4e32010-07-29 22:33:18 +0200346 " find a match.
347 let next_group_regex = '\n' .
348 \ '\zs'.b:current_syntax.'\w\+\ze'.
Bram Moolenaar34feacb2012-12-05 19:01:43 +0100349 \ '\s\+xxx\s\+'
Bram Moolenaar40af4e32010-07-29 22:33:18 +0200350 let index = 0
351 let index = match(syntax_full, next_group_regex, index)
352 endif
353
Bram Moolenaar97e8f352006-05-06 21:40:45 +0000354 while index > -1
355 let group_name = matchstr( syntax_full, '\w\+', index )
356
357 let get_syn_list = 1
Bram Moolenaar40af4e32010-07-29 22:33:18 +0200358 for exclude_group_name in list_exclude_groups
359 if '\<'.exclude_group_name.'\>' =~ '\<'.group_name.'\>'
360 let get_syn_list = 0
361 endif
362 endfor
Bram Moolenaar34feacb2012-12-05 19:01:43 +0100363
Bram Moolenaar40af4e32010-07-29 22:33:18 +0200364 " This code is no longer needed in version 6.0 since we have
Bram Moolenaar34feacb2012-12-05 19:01:43 +0100365 " augmented the syntax list command to only retrieve the syntax
Bram Moolenaar40af4e32010-07-29 22:33:18 +0200366 " groups we are interested in.
367 "
368 " if get_syn_list == 1
369 " if syntax_group_include_{filetype} != ''
370 " if '\<'.syntax_group_include_{filetype}.'\>' !~ '\<'.group_name.'\>'
Bram Moolenaar97e8f352006-05-06 21:40:45 +0000371 " let get_syn_list = 0
372 " endif
373 " endif
Bram Moolenaar97e8f352006-05-06 21:40:45 +0000374 " endif
Bram Moolenaar4770d092006-01-12 23:22:24 +0000375
Bram Moolenaar97e8f352006-05-06 21:40:45 +0000376 if get_syn_list == 1
Bram Moolenaar34feacb2012-12-05 19:01:43 +0100377 " Pass in the full syntax listing, plus the group name we
Bram Moolenaar97e8f352006-05-06 21:40:45 +0000378 " are interested in.
379 let extra_syn_list = s:SyntaxCSyntaxGroupItems(group_name, syntax_full)
Bram Moolenaar97e8f352006-05-06 21:40:45 +0000380 let syn_list = syn_list . extra_syn_list . "\n"
381 endif
382
383 let index = index + strlen(group_name)
384 let index = match(syntax_full, next_group_regex, index)
385 endwhile
386
387 let ftindex = ftindex + len(ft_part_name)
388 let ftindex = match( &filetype, '\w\+', ftindex )
Bram Moolenaar4770d092006-01-12 23:22:24 +0000389 endwhile
390
Bram Moolenaarc06ac342006-03-02 22:43:39 +0000391 " Convert the string to a List and sort it.
392 let compl_list = sort(split(syn_list))
393
394 if &filetype == 'vim'
395 let short_compl_list = []
396 for i in range(len(compl_list))
397 if i == len(compl_list)-1
398 let next = i
399 else
400 let next = i + 1
401 endif
402 if compl_list[next] !~ '^'.compl_list[i].'.$'
403 let short_compl_list += [compl_list[i]]
404 endif
405 endfor
406
407 return short_compl_list
408 else
409 return compl_list
410 endif
Bram Moolenaar4770d092006-01-12 23:22:24 +0000411endfunction
412
Bram Moolenaare2f98b92006-03-29 21:18:24 +0000413function! s:SyntaxCSyntaxGroupItems( group_name, syntax_full )
Bram Moolenaar4770d092006-01-12 23:22:24 +0000414
Bram Moolenaarc06ac342006-03-02 22:43:39 +0000415 let syn_list = ""
416
417 " From the full syntax listing, strip out the portion for the
418 " request group.
419 " Query:
420 " \n - must begin with a newline
421 " a:group_name - the group name we are interested in
422 " \s\+xxx\s\+ - group names are always followed by xxx
423 " \zs - start the match
424 " .\{-} - everything ...
425 " \ze - end the match
Bram Moolenaar6dfc28b2010-02-11 14:19:15 +0100426 " \( - start a group or 2 potential matches
Bram Moolenaarc06ac342006-03-02 22:43:39 +0000427 " \n\w - at the first newline starting with a character
Bram Moolenaar6dfc28b2010-02-11 14:19:15 +0100428 " \| - 2nd potential match
429 " \%$ - matches end of the file or string
430 " \) - end a group
Bram Moolenaar34feacb2012-12-05 19:01:43 +0100431 let syntax_group = matchstr(a:syntax_full,
Bram Moolenaar6dfc28b2010-02-11 14:19:15 +0100432 \ "\n".a:group_name.'\s\+xxx\s\+\zs.\{-}\ze\(\n\w\|\%$\)'
Bram Moolenaar97e8f352006-05-06 21:40:45 +0000433 \ )
Bram Moolenaarc06ac342006-03-02 22:43:39 +0000434
435 if syntax_group != ""
Bram Moolenaar4770d092006-01-12 23:22:24 +0000436 " let syn_list = substitute( @l, '^.*xxx\s*\%(contained\s*\)\?', "", '' )
Bram Moolenaarc06ac342006-03-02 22:43:39 +0000437 " let syn_list = substitute( @l, '^.*xxx\s*', "", '' )
Bram Moolenaar4770d092006-01-12 23:22:24 +0000438
439 " We only want the words for the lines begining with
440 " containedin, but there could be other items.
Bram Moolenaar34feacb2012-12-05 19:01:43 +0100441
Bram Moolenaar4770d092006-01-12 23:22:24 +0000442 " Tried to remove all lines that do not begin with contained
443 " but this does not work in all cases since you can have
444 " contained nextgroup=...
445 " So this will strip off the ending of lines with known
446 " keywords.
Bram Moolenaar34feacb2012-12-05 19:01:43 +0100447 let syn_list = substitute(
Bram Moolenaar97e8f352006-05-06 21:40:45 +0000448 \ syntax_group, '\<\('.
449 \ substitute(
450 \ escape(s:syn_remove_words, '\\/.*$^~[]')
451 \ , ',', '\\|', 'g'
452 \ ).
453 \ '\).\{-}\%($\|'."\n".'\)'
Bram Moolenaar34feacb2012-12-05 19:01:43 +0100454 \ , "\n", 'g'
Bram Moolenaar97e8f352006-05-06 21:40:45 +0000455 \ )
Bram Moolenaar4770d092006-01-12 23:22:24 +0000456
Bram Moolenaarf1568ec2011-12-14 21:17:39 +0100457 " Now strip off the newline + blank space + contained.
458 " Also include lines with nextgroup=@someName skip_key_words syntax_element
Bram Moolenaar34feacb2012-12-05 19:01:43 +0100459 let syn_list = substitute(
Bram Moolenaarf1568ec2011-12-14 21:17:39 +0100460 \ syn_list, '\%(^\|\n\)\@<=\s*\<\(contained\|nextgroup=\)'
Bram Moolenaar34feacb2012-12-05 19:01:43 +0100461 \ , "", 'g'
Bram Moolenaarf1568ec2011-12-14 21:17:39 +0100462 \ )
463
464 " This can leave lines like this
465 " =@vimMenuList skipwhite onoremenu
466 " Strip the special option keywords first
467 " :h :syn-skipwhite*
Bram Moolenaar34feacb2012-12-05 19:01:43 +0100468 let syn_list = substitute(
Bram Moolenaarf1568ec2011-12-14 21:17:39 +0100469 \ syn_list, '\<\(skipwhite\|skipnl\|skipempty\)\>'
Bram Moolenaar34feacb2012-12-05 19:01:43 +0100470 \ , "", 'g'
Bram Moolenaarf1568ec2011-12-14 21:17:39 +0100471 \ )
472
473 " Now remove the remainder of the nextgroup=@someName lines
Bram Moolenaar34feacb2012-12-05 19:01:43 +0100474 let syn_list = substitute(
Bram Moolenaarf1568ec2011-12-14 21:17:39 +0100475 \ syn_list, '\%(^\|\n\)\@<=\s*\(@\w\+\)'
Bram Moolenaar34feacb2012-12-05 19:01:43 +0100476 \ , "", 'g'
Bram Moolenaar97e8f352006-05-06 21:40:45 +0000477 \ )
Bram Moolenaar4770d092006-01-12 23:22:24 +0000478
Bram Moolenaar9964e462007-05-05 17:54:07 +0000479 if b:omni_syntax_use_iskeyword == 0
480 " There are a number of items which have non-word characters in
481 " them, *'T_F1'*. vim.vim is one such file.
482 " This will replace non-word characters with spaces.
483 let syn_list = substitute( syn_list, '[^0-9A-Za-z_ ]', ' ', 'g' )
484 else
Bram Moolenaar97d62492012-11-15 21:28:22 +0100485 if g:omni_syntax_use_iskeyword_numeric == 1
486 " iskeyword can contain value like this
487 " 38,42,43,45,47-58,60-62,64-90,97-122,_,+,-,*,/,%,<,=,>,:,$,?,!,@-@,94
488 " Numeric values convert to their ASCII equivalent using the
489 " nr2char() function.
490 " & 38
Bram Moolenaar34feacb2012-12-05 19:01:43 +0100491 " * 42
Bram Moolenaar97d62492012-11-15 21:28:22 +0100492 " + 43
Bram Moolenaar34feacb2012-12-05 19:01:43 +0100493 " - 45
Bram Moolenaar97d62492012-11-15 21:28:22 +0100494 " ^ 94
Bram Moolenaar34feacb2012-12-05 19:01:43 +0100495 " Iterate through all numeric specifications and convert those
Bram Moolenaar97d62492012-11-15 21:28:22 +0100496 " to their ascii equivalent ensuring the character is printable.
497 " If so, add it to the list.
498 let accepted_chars = ''
499 for item in split(&iskeyword, ',')
500 if item =~ '-'
Bram Moolenaar34feacb2012-12-05 19:01:43 +0100501 " This is a character range (ie 47-58),
Bram Moolenaar97d62492012-11-15 21:28:22 +0100502 " cycle through each character within the range
503 let [b:start, b:end] = split(item, '-')
504 for range_item in range( b:start, b:end )
505 if range_item <= 127 || g:omni_syntax_use_single_byte == 0
506 if nr2char(range_item) =~ '\p'
507 let accepted_chars = accepted_chars . nr2char(range_item)
508 endif
509 endif
510 endfor
511 elseif item =~ '^\d\+$'
512 " Only numeric, translate to a character
513 if item < 127 || g:omni_syntax_use_single_byte == 0
514 if nr2char(item) =~ '\p'
515 let accepted_chars = accepted_chars . nr2char(item)
516 endif
517 endif
518 else
519 if char2nr(item) < 127 || g:omni_syntax_use_single_byte == 0
520 if item =~ '\p'
521 let accepted_chars = accepted_chars . item
522 endif
523 endif
524 endif
525 endfor
526 " Escape special regex characters
Bram Moolenaar34feacb2012-12-05 19:01:43 +0100527 " Looks like the wrong chars are escaped. In a collection,
528 " :h /[]
529 " only `]', `\', `-' and `^' are special:
530 " let accepted_chars = escape(accepted_chars, '\\/.*$^~[]' )
531 let accepted_chars = escape(accepted_chars, ']\-^' )
Bram Moolenaar97d62492012-11-15 21:28:22 +0100532 " Remove all characters that are not acceptable
533 let syn_list = substitute( syn_list, '[^A-Za-z'.accepted_chars.']', ' ', 'g' )
534 else
535 let accept_chars = ','.&iskeyword.','
536 " Remove all character ranges
537 " let accept_chars = substitute(accept_chars, ',[^,]\+-[^,]\+,', ',', 'g')
538 let accept_chars = substitute(accept_chars, ',\@<=[^,]\+-[^,]\+,', '', 'g')
539 " Remove all numeric specifications
540 " let accept_chars = substitute(accept_chars, ',\d\{-},', ',', 'g')
541 let accept_chars = substitute(accept_chars, ',\@<=\d\{-},', '', 'g')
542 " Remove all commas
543 let accept_chars = substitute(accept_chars, ',', '', 'g')
544 " Escape special regex characters
Bram Moolenaar34feacb2012-12-05 19:01:43 +0100545 " Looks like the wrong chars are escaped. In a collection,
546 " :h /[]
547 " only `]', `\', `-' and `^' are special:
548 " let accept_chars = escape(accept_chars, '\\/.*$^~[]' )
549 let accept_chars = escape(accept_chars, ']\-^' )
Bram Moolenaar97d62492012-11-15 21:28:22 +0100550 " Remove all characters that are not acceptable
551 let syn_list = substitute( syn_list, '[^0-9A-Za-z_'.accept_chars.']', ' ', 'g' )
552 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +0000553 endif
554
555 if b:omni_syntax_minimum_length > 0
556 " If the user specified a minimum length, enforce it
557 let syn_list = substitute(' '.syn_list.' ', ' \S\{,'.b:omni_syntax_minimum_length.'}\ze ', ' ', 'g')
558 endif
Bram Moolenaar4770d092006-01-12 23:22:24 +0000559 else
560 let syn_list = ''
561 endif
562
Bram Moolenaar4770d092006-01-12 23:22:24 +0000563 return syn_list
564endfunction
Bram Moolenaar97d62492012-11-15 21:28:22 +0100565
566function! OmniSyntaxShowChars(spec)
567 let result = []
568 for item in split(a:spec, ',')
569 if len(item) > 1
570 if item == '@-@'
571 call add(result, char2nr(item))
572 else
573 call extend(result, call('range', split(item, '-')))
574 endif
575 else
576 if item == '@' " assume this is [A-Za-z]
577 for [c1, c2] in [['A', 'Z'], ['a', 'z']]
578 call extend(result, range(char2nr(c1), char2nr(c2)))
579 endfor
580 else
581 call add(result, char2nr(item))
582 endif
583 endif
584 endfor
585 return join(map(result, 'nr2char(v:val)'), ', ')
586endfunction
587let &cpo = s:cpo_save
588unlet s:cpo_save