14770d09aSBram Moolenaar" Vim completion script 24770d09aSBram Moolenaar" Language: All languages, uses existing syntax highlighting rules 36dfc28beSBram Moolenaar" Maintainer: David Fishburn <dfishburn dot vim at gmail dot com> 4*34feacbcSBram Moolenaar" Version: 11.0 5*34feacbcSBram Moolenaar" Last Change: 2012 Dec 04 697e8f356SBram Moolenaar" Usage: For detailed help, ":help ft-syntax-omni" 74770d09aSBram Moolenaar 86dfc28beSBram Moolenaar" History 940af4e39SBram Moolenaar" 10*34feacbcSBram Moolenaar" Version 11.0 11*34feacbcSBram Moolenaar" Corrected which characters required escaping during 12*34feacbcSBram Moolenaar" substitution calls. 13*34feacbcSBram Moolenaar" 1497d62497SBram Moolenaar" Version 10.0 1597d62497SBram Moolenaar" Cycle through all the character ranges specified in the 1697d62497SBram Moolenaar" iskeyword option and build a list of valid word separators. 1797d62497SBram Moolenaar" Prior to this change, only actual characters were used, 1897d62497SBram Moolenaar" where for example ASCII "45" == "-". If "45" were used 1997d62497SBram Moolenaar" in iskeyword the hyphen would not be picked up. 2097d62497SBram Moolenaar" This introduces a new option, since the character ranges 2197d62497SBram Moolenaar" specified could be multibyte: 2297d62497SBram Moolenaar" let g:omni_syntax_use_single_byte = 1 2397d62497SBram Moolenaar" This by default will only allow single byte ASCII 2497d62497SBram Moolenaar" characters to be added and an additional check to ensure 2597d62497SBram Moolenaar" the charater is printable (see documentation for isprint). 2697d62497SBram Moolenaar" 2797d62497SBram Moolenaar" Version 9.0 2897d62497SBram Moolenaar" Add the check for cpo. 2997d62497SBram Moolenaar" 30f1568ecaSBram Moolenaar" Version 8.0 31f1568ecaSBram Moolenaar" Updated SyntaxCSyntaxGroupItems() 32f1568ecaSBram Moolenaar" - Some additional syntax items were also allowed 33f1568ecaSBram Moolenaar" on nextgroup= lines which were ignored by default. 34f1568ecaSBram Moolenaar" Now these lines are processed independently. 35f1568ecaSBram Moolenaar" 3640af4e39SBram Moolenaar" Version 7.0 3740af4e39SBram Moolenaar" Updated syntaxcomplete#OmniSyntaxList() 3840af4e39SBram Moolenaar" - Looking up the syntax groups defined from a syntax file 3940af4e39SBram Moolenaar" looked for only 1 format of {filetype}GroupName, but some 4040af4e39SBram Moolenaar" syntax writers use this format as well: 4140af4e39SBram Moolenaar" {b:current_syntax}GroupName 4240af4e39SBram Moolenaar" OmniSyntaxList() will now check for both if the first 4340af4e39SBram Moolenaar" method does not find a match. 4440af4e39SBram Moolenaar" 4540af4e39SBram Moolenaar" Version 6.0 4640af4e39SBram Moolenaar" Added syntaxcomplete#OmniSyntaxList() 4740af4e39SBram Moolenaar" - Allows other plugins to use this for their own 4840af4e39SBram Moolenaar" purposes. 4940af4e39SBram Moolenaar" - It will return a List of all syntax items for the 5040af4e39SBram Moolenaar" syntax group name passed in. 5140af4e39SBram Moolenaar" - XPTemplate for SQL will use this function via the 5240af4e39SBram Moolenaar" sqlcomplete plugin to populate a Choose box. 5340af4e39SBram Moolenaar" 546dfc28beSBram Moolenaar" Version 5.0 5540af4e39SBram Moolenaar" Updated SyntaxCSyntaxGroupItems() 5640af4e39SBram Moolenaar" - When processing a list of syntax groups, the final group 576dfc28beSBram Moolenaar" was missed in function SyntaxCSyntaxGroupItems. 586dfc28beSBram Moolenaar" 594770d09aSBram Moolenaar" Set completion with CTRL-X CTRL-O to autoloaded function. 60c15ef30cSBram Moolenaar" This check is in place in case this script is 61c15ef30cSBram Moolenaar" sourced directly instead of using the autoload feature. 62c06ac340SBram Moolenaarif exists('+omnifunc') 63c15ef30cSBram Moolenaar " Do not set the option if already set since this 64c15ef30cSBram Moolenaar " results in an E117 warning. 65c15ef30cSBram Moolenaar if &omnifunc == "" 66c06ac340SBram Moolenaar setlocal omnifunc=syntaxcomplete#Complete 674770d09aSBram Moolenaar endif 68c15ef30cSBram Moolenaarendif 694770d09aSBram Moolenaar 704770d09aSBram Moolenaarif exists('g:loaded_syntax_completion') 714770d09aSBram Moolenaar finish 724770d09aSBram Moolenaarendif 73*34feacbcSBram Moolenaarlet g:loaded_syntax_completion = 110 7497d62497SBram Moolenaar 7597d62497SBram Moolenaar" Turn on support for line continuations when creating the script 7697d62497SBram Moolenaarlet s:cpo_save = &cpo 7797d62497SBram Moolenaarset cpo&vim 7897e8f356SBram Moolenaar 7997e8f356SBram Moolenaar" Set ignorecase to the ftplugin standard 809964e468SBram Moolenaar" This is the default setting, but if you define a buffer local 819964e468SBram Moolenaar" variable you can override this on a per filetype. 8297e8f356SBram Moolenaarif !exists('g:omni_syntax_ignorecase') 8397e8f356SBram Moolenaar let g:omni_syntax_ignorecase = &ignorecase 8497e8f356SBram Moolenaarendif 854770d09aSBram Moolenaar 869964e468SBram Moolenaar" Indicates whether we should use the iskeyword option to determine 879964e468SBram Moolenaar" how to split words. 889964e468SBram Moolenaar" This is the default setting, but if you define a buffer local 899964e468SBram Moolenaar" variable you can override this on a per filetype. 909964e468SBram Moolenaarif !exists('g:omni_syntax_use_iskeyword') 919964e468SBram Moolenaar let g:omni_syntax_use_iskeyword = 1 929964e468SBram Moolenaarendif 939964e468SBram Moolenaar 9497d62497SBram Moolenaar" When using iskeyword, this setting controls whether the characters 9597d62497SBram Moolenaar" should be limited to single byte characters. 9697d62497SBram Moolenaarif !exists('g:omni_syntax_use_single_byte') 9797d62497SBram Moolenaar let g:omni_syntax_use_single_byte = 1 9897d62497SBram Moolenaarendif 9997d62497SBram Moolenaar 10097d62497SBram Moolenaar" When using iskeyword, this setting controls whether the characters 10197d62497SBram Moolenaar" should be limited to single byte characters. 10297d62497SBram Moolenaarif !exists('g:omni_syntax_use_iskeyword_numeric') 10397d62497SBram Moolenaar let g:omni_syntax_use_iskeyword_numeric = 1 10497d62497SBram Moolenaarendif 10597d62497SBram Moolenaar 1069964e468SBram Moolenaar" Only display items in the completion window that are at least 1079964e468SBram Moolenaar" this many characters in length. 1089964e468SBram Moolenaar" This is the default setting, but if you define a buffer local 1099964e468SBram Moolenaar" variable you can override this on a per filetype. 1109964e468SBram Moolenaarif !exists('g:omni_syntax_minimum_length') 1119964e468SBram Moolenaar let g:omni_syntax_minimum_length = 0 1129964e468SBram Moolenaarendif 1139964e468SBram Moolenaar 1144770d09aSBram Moolenaar" This script will build a completion list based on the syntax 1154770d09aSBram Moolenaar" elements defined by the files in $VIMRUNTIME/syntax. 1164770d09aSBram Moolenaarlet s:syn_remove_words = 'match,matchgroup=,contains,'. 117f1568ecaSBram Moolenaar \ 'links to,start=,end=' 118f1568ecaSBram Moolenaar " \ 'links to,start=,end=,nextgroup=' 1194770d09aSBram Moolenaar 1204770d09aSBram Moolenaarlet s:cache_name = [] 1214770d09aSBram Moolenaarlet s:cache_list = [] 122c15ef30cSBram Moolenaarlet s:prepended = '' 1234770d09aSBram Moolenaar 1244770d09aSBram Moolenaar" This function is used for the 'omnifunc' option. 1254770d09aSBram Moolenaarfunction! syntaxcomplete#Complete(findstart, base) 1264770d09aSBram Moolenaar 1279964e468SBram Moolenaar " Only display items in the completion window that are at least 1289964e468SBram Moolenaar " this many characters in length 1299964e468SBram Moolenaar if !exists('b:omni_syntax_ignorecase') 1309964e468SBram Moolenaar if exists('g:omni_syntax_ignorecase') 1319964e468SBram Moolenaar let b:omni_syntax_ignorecase = g:omni_syntax_ignorecase 1329964e468SBram Moolenaar else 1339964e468SBram Moolenaar let b:omni_syntax_ignorecase = &ignorecase 1349964e468SBram Moolenaar endif 1359964e468SBram Moolenaar endif 1369964e468SBram Moolenaar 1374770d09aSBram Moolenaar if a:findstart 1384770d09aSBram Moolenaar " Locate the start of the item, including "." 1394770d09aSBram Moolenaar let line = getline('.') 1404770d09aSBram Moolenaar let start = col('.') - 1 1414770d09aSBram Moolenaar let lastword = -1 1424770d09aSBram Moolenaar while start > 0 1439964e468SBram Moolenaar " if line[start - 1] =~ '\S' 1449964e468SBram Moolenaar " let start -= 1 1459964e468SBram Moolenaar " elseif line[start - 1] =~ '\.' 1469964e468SBram Moolenaar if line[start - 1] =~ '\k' 1474770d09aSBram Moolenaar let start -= 1 1489964e468SBram Moolenaar let lastword = a:findstart 1494770d09aSBram Moolenaar else 1504770d09aSBram Moolenaar break 1514770d09aSBram Moolenaar endif 1524770d09aSBram Moolenaar endwhile 1534770d09aSBram Moolenaar 1544770d09aSBram Moolenaar " Return the column of the last word, which is going to be changed. 1554770d09aSBram Moolenaar " Remember the text that comes before it in s:prepended. 1564770d09aSBram Moolenaar if lastword == -1 1574770d09aSBram Moolenaar let s:prepended = '' 1584770d09aSBram Moolenaar return start 1594770d09aSBram Moolenaar endif 1609964e468SBram Moolenaar let s:prepended = strpart(line, start, (col('.') - 1) - start) 1619964e468SBram Moolenaar return start 1624770d09aSBram Moolenaar endif 1634770d09aSBram Moolenaar 1649964e468SBram Moolenaar " let base = s:prepended . a:base 1659964e468SBram Moolenaar let base = s:prepended 1664770d09aSBram Moolenaar 16797e8f356SBram Moolenaar let filetype = substitute(&filetype, '\.', '_', 'g') 16897e8f356SBram Moolenaar let list_idx = index(s:cache_name, filetype, 0, &ignorecase) 1694770d09aSBram Moolenaar if list_idx > -1 1704770d09aSBram Moolenaar let compl_list = s:cache_list[list_idx] 1714770d09aSBram Moolenaar else 172c06ac340SBram Moolenaar let compl_list = OmniSyntaxList() 17397e8f356SBram Moolenaar let s:cache_name = add( s:cache_name, filetype ) 1744770d09aSBram Moolenaar let s:cache_list = add( s:cache_list, compl_list ) 1754770d09aSBram Moolenaar endif 1764770d09aSBram Moolenaar 1774770d09aSBram Moolenaar " Return list of matches. 1784770d09aSBram Moolenaar 1799964e468SBram Moolenaar if base != '' 1809964e468SBram Moolenaar " let compstr = join(compl_list, ' ') 1819964e468SBram Moolenaar " let expr = (b:omni_syntax_ignorecase==0?'\C':'').'\<\%('.base.'\)\@!\w\+\s*' 1829964e468SBram Moolenaar " let compstr = substitute(compstr, expr, '', 'g') 1839964e468SBram Moolenaar " let compl_list = split(compstr, '\s\+') 1849964e468SBram Moolenaar 1859964e468SBram Moolenaar " Filter the list based on the first few characters the user 1869964e468SBram Moolenaar " entered 1879964e468SBram Moolenaar let expr = 'v:val '.(g:omni_syntax_ignorecase==1?'=~?':'=~#')." '^".escape(base, '\\/.*$^~[]').".*'" 1889964e468SBram Moolenaar let compl_list = filter(deepcopy(compl_list), expr) 1894770d09aSBram Moolenaar endif 1904770d09aSBram Moolenaar 1914770d09aSBram Moolenaar return compl_list 1924770d09aSBram Moolenaarendfunc 1934770d09aSBram Moolenaar 19440af4e39SBram Moolenaarfunction! syntaxcomplete#OmniSyntaxList(...) 19540af4e39SBram Moolenaar if a:0 > 0 19640af4e39SBram Moolenaar let parms = [] 19740af4e39SBram Moolenaar if 3 == type(a:1) 19840af4e39SBram Moolenaar let parms = a:1 19940af4e39SBram Moolenaar elseif 1 == type(a:1) 20040af4e39SBram Moolenaar let parms = split(a:1, ',') 20140af4e39SBram Moolenaar endif 20240af4e39SBram Moolenaar return OmniSyntaxList( parms ) 20340af4e39SBram Moolenaar else 20440af4e39SBram Moolenaar return OmniSyntaxList() 20540af4e39SBram Moolenaar endif 20640af4e39SBram Moolenaarendfunc 20740af4e39SBram Moolenaar 20840af4e39SBram Moolenaarfunction! OmniSyntaxList(...) 20940af4e39SBram Moolenaar let list_parms = [] 21040af4e39SBram Moolenaar if a:0 > 0 21140af4e39SBram Moolenaar if 3 == type(a:1) 21240af4e39SBram Moolenaar let list_parms = a:1 21340af4e39SBram Moolenaar elseif 1 == type(a:1) 21440af4e39SBram Moolenaar let list_parms = split(a:1, ',') 21540af4e39SBram Moolenaar endif 21640af4e39SBram Moolenaar endif 21740af4e39SBram Moolenaar 21897e8f356SBram Moolenaar " Default to returning a dictionary, if use_dictionary is set to 0 21997e8f356SBram Moolenaar " a list will be returned. 22097e8f356SBram Moolenaar " let use_dictionary = 1 22197e8f356SBram Moolenaar " if a:0 > 0 && a:1 != '' 22297e8f356SBram Moolenaar " let use_dictionary = a:1 22397e8f356SBram Moolenaar " endif 22497e8f356SBram Moolenaar 2259964e468SBram Moolenaar " Only display items in the completion window that are at least 2269964e468SBram Moolenaar " this many characters in length 2279964e468SBram Moolenaar if !exists('b:omni_syntax_use_iskeyword') 2289964e468SBram Moolenaar if exists('g:omni_syntax_use_iskeyword') 2299964e468SBram Moolenaar let b:omni_syntax_use_iskeyword = g:omni_syntax_use_iskeyword 2309964e468SBram Moolenaar else 2319964e468SBram Moolenaar let b:omni_syntax_use_iskeyword = 1 2329964e468SBram Moolenaar endif 2339964e468SBram Moolenaar endif 2349964e468SBram Moolenaar 2359964e468SBram Moolenaar " Only display items in the completion window that are at least 2369964e468SBram Moolenaar " this many characters in length 2379964e468SBram Moolenaar if !exists('b:omni_syntax_minimum_length') 2389964e468SBram Moolenaar if exists('g:omni_syntax_minimum_length') 2399964e468SBram Moolenaar let b:omni_syntax_minimum_length = g:omni_syntax_minimum_length 2409964e468SBram Moolenaar else 2419964e468SBram Moolenaar let b:omni_syntax_minimum_length = 0 2429964e468SBram Moolenaar endif 2439964e468SBram Moolenaar endif 2449964e468SBram Moolenaar 2454770d09aSBram Moolenaar let saveL = @l 24640af4e39SBram Moolenaar let filetype = substitute(&filetype, '\.', '_', 'g') 24740af4e39SBram Moolenaar 24840af4e39SBram Moolenaar if empty(list_parms) 24940af4e39SBram Moolenaar " Default the include group to include the requested syntax group 25040af4e39SBram Moolenaar let syntax_group_include_{filetype} = '' 25140af4e39SBram Moolenaar " Check if there are any overrides specified for this filetype 25240af4e39SBram Moolenaar if exists('g:omni_syntax_group_include_'.filetype) 25340af4e39SBram Moolenaar let syntax_group_include_{filetype} = 25440af4e39SBram Moolenaar \ substitute( g:omni_syntax_group_include_{filetype},'\s\+','','g') 25540af4e39SBram Moolenaar let list_parms = split(g:omni_syntax_group_include_{filetype}, ',') 25640af4e39SBram Moolenaar if syntax_group_include_{filetype} =~ '\w' 25740af4e39SBram Moolenaar let syntax_group_include_{filetype} = 25840af4e39SBram Moolenaar \ substitute( syntax_group_include_{filetype}, 25940af4e39SBram Moolenaar \ '\s*,\s*', '\\|', 'g' 26040af4e39SBram Moolenaar \ ) 26140af4e39SBram Moolenaar endif 26240af4e39SBram Moolenaar endif 26340af4e39SBram Moolenaar else 26440af4e39SBram Moolenaar " A specific list was provided, use it 26540af4e39SBram Moolenaar endif 2664770d09aSBram Moolenaar 2674770d09aSBram Moolenaar " Loop through all the syntax groupnames, and build a 2684770d09aSBram Moolenaar " syntax file which contains these names. This can 2694770d09aSBram Moolenaar " work generically for any filetype that does not already 2704770d09aSBram Moolenaar " have a plugin defined. 2714770d09aSBram Moolenaar " This ASSUMES the syntax groupname BEGINS with the name 272c06ac340SBram Moolenaar " of the filetype. From my casual viewing of the vim7\syntax 27340af4e39SBram Moolenaar " directory this is true for almost all syntax definitions. 27440af4e39SBram Moolenaar " As an example, the SQL syntax groups have this pattern: 27540af4e39SBram Moolenaar " sqlType 27640af4e39SBram Moolenaar " sqlOperators 27740af4e39SBram Moolenaar " sqlKeyword ... 2784770d09aSBram Moolenaar redir @l 27940af4e39SBram Moolenaar silent! exec 'syntax list '.join(list_parms) 2804770d09aSBram Moolenaar redir END 2814770d09aSBram Moolenaar 282c06ac340SBram Moolenaar let syntax_full = "\n".@l 2834770d09aSBram Moolenaar let @l = saveL 2844770d09aSBram Moolenaar 285c06ac340SBram Moolenaar if syntax_full =~ 'E28' 286c06ac340SBram Moolenaar \ || syntax_full =~ 'E411' 287c06ac340SBram Moolenaar \ || syntax_full =~ 'E415' 288c06ac340SBram Moolenaar \ || syntax_full =~ 'No Syntax items' 289c06ac340SBram Moolenaar return [] 2904770d09aSBram Moolenaar endif 2914770d09aSBram Moolenaar 29297e8f356SBram Moolenaar let filetype = substitute(&filetype, '\.', '_', 'g') 29397e8f356SBram Moolenaar 29440af4e39SBram Moolenaar let list_exclude_groups = [] 29540af4e39SBram Moolenaar if a:0 > 0 29640af4e39SBram Moolenaar " Do nothing since we have specific a specific list of groups 29740af4e39SBram Moolenaar else 298c06ac340SBram Moolenaar " Default the exclude group to nothing 29997e8f356SBram Moolenaar let syntax_group_exclude_{filetype} = '' 300c06ac340SBram Moolenaar " Check if there are any overrides specified for this filetype 30197e8f356SBram Moolenaar if exists('g:omni_syntax_group_exclude_'.filetype) 30297e8f356SBram Moolenaar let syntax_group_exclude_{filetype} = 30397e8f356SBram Moolenaar \ substitute( g:omni_syntax_group_exclude_{filetype},'\s\+','','g') 30440af4e39SBram Moolenaar let list_exclude_groups = split(g:omni_syntax_group_exclude_{filetype}, ',') 30597e8f356SBram Moolenaar if syntax_group_exclude_{filetype} =~ '\w' 30697e8f356SBram Moolenaar let syntax_group_exclude_{filetype} = 30797e8f356SBram Moolenaar \ substitute( syntax_group_exclude_{filetype}, 308c06ac340SBram Moolenaar \ '\s*,\s*', '\\|', 'g' 309c06ac340SBram Moolenaar \ ) 310c06ac340SBram Moolenaar endif 311c06ac340SBram Moolenaar endif 31240af4e39SBram Moolenaar endif 313c06ac340SBram Moolenaar 31497e8f356SBram Moolenaar " Sometimes filetypes can be composite names, like c.doxygen 31597e8f356SBram Moolenaar " Loop through each individual part looking for the syntax 31697e8f356SBram Moolenaar " items specific to each individual filetype. 31797e8f356SBram Moolenaar let syn_list = '' 31897e8f356SBram Moolenaar let ftindex = 0 31997e8f356SBram Moolenaar let ftindex = match(&filetype, '\w\+', ftindex) 32097e8f356SBram Moolenaar 32197e8f356SBram Moolenaar while ftindex > -1 32297e8f356SBram Moolenaar let ft_part_name = matchstr( &filetype, '\w\+', ftindex ) 32397e8f356SBram Moolenaar 324c06ac340SBram Moolenaar " Syntax rules can contain items for more than just the current 325c06ac340SBram Moolenaar " filetype. They can contain additional items added by the user 326c06ac340SBram Moolenaar " via autocmds or their vimrc. 327c06ac340SBram Moolenaar " Some syntax files can be combined (html, php, jsp). 328c06ac340SBram Moolenaar " We want only items that begin with the filetype we are interested in. 3294770d09aSBram Moolenaar let next_group_regex = '\n' . 33097e8f356SBram Moolenaar \ '\zs'.ft_part_name.'\w\+\ze'. 331c06ac340SBram Moolenaar \ '\s\+xxx\s\+' 3324770d09aSBram Moolenaar let index = 0 333c06ac340SBram Moolenaar let index = match(syntax_full, next_group_regex, index) 3344770d09aSBram Moolenaar 33540af4e39SBram Moolenaar if index == -1 && exists('b:current_syntax') && ft_part_name != b:current_syntax 33640af4e39SBram Moolenaar " There appears to be two standards when writing syntax files. 33740af4e39SBram Moolenaar " Either items begin as: 33840af4e39SBram Moolenaar " syn keyword {filetype}Keyword values ... 33940af4e39SBram Moolenaar " let b:current_syntax = "sql" 34040af4e39SBram Moolenaar " let b:current_syntax = "sqlanywhere" 34140af4e39SBram Moolenaar " Or 34240af4e39SBram Moolenaar " syn keyword {syntax_filename}Keyword values ... 34340af4e39SBram Moolenaar " let b:current_syntax = "mysql" 34440af4e39SBram Moolenaar " So, we will make the format of finding the syntax group names 34540af4e39SBram Moolenaar " a bit more flexible and look for both if the first fails to 34640af4e39SBram Moolenaar " find a match. 34740af4e39SBram Moolenaar let next_group_regex = '\n' . 34840af4e39SBram Moolenaar \ '\zs'.b:current_syntax.'\w\+\ze'. 34940af4e39SBram Moolenaar \ '\s\+xxx\s\+' 35040af4e39SBram Moolenaar let index = 0 35140af4e39SBram Moolenaar let index = match(syntax_full, next_group_regex, index) 35240af4e39SBram Moolenaar endif 35340af4e39SBram Moolenaar 35497e8f356SBram Moolenaar while index > -1 355c06ac340SBram Moolenaar let group_name = matchstr( syntax_full, '\w\+', index ) 3564770d09aSBram Moolenaar 357c06ac340SBram Moolenaar let get_syn_list = 1 35840af4e39SBram Moolenaar for exclude_group_name in list_exclude_groups 35940af4e39SBram Moolenaar if '\<'.exclude_group_name.'\>' =~ '\<'.group_name.'\>' 360c06ac340SBram Moolenaar let get_syn_list = 0 361c06ac340SBram Moolenaar endif 36240af4e39SBram Moolenaar endfor 363c06ac340SBram Moolenaar 36440af4e39SBram Moolenaar " This code is no longer needed in version 6.0 since we have 36540af4e39SBram Moolenaar " augmented the syntax list command to only retrieve the syntax 36640af4e39SBram Moolenaar " groups we are interested in. 36740af4e39SBram Moolenaar " 36840af4e39SBram Moolenaar " if get_syn_list == 1 36940af4e39SBram Moolenaar " if syntax_group_include_{filetype} != '' 37040af4e39SBram Moolenaar " if '\<'.syntax_group_include_{filetype}.'\>' !~ '\<'.group_name.'\>' 37140af4e39SBram Moolenaar " let get_syn_list = 0 37240af4e39SBram Moolenaar " endif 37340af4e39SBram Moolenaar " endif 37440af4e39SBram Moolenaar " endif 375c06ac340SBram Moolenaar 376c06ac340SBram Moolenaar if get_syn_list == 1 377c06ac340SBram Moolenaar " Pass in the full syntax listing, plus the group name we 378c06ac340SBram Moolenaar " are interested in. 379e2f98b95SBram Moolenaar let extra_syn_list = s:SyntaxCSyntaxGroupItems(group_name, syntax_full) 3804770d09aSBram Moolenaar let syn_list = syn_list . extra_syn_list . "\n" 381c06ac340SBram Moolenaar endif 3824770d09aSBram Moolenaar 3834770d09aSBram Moolenaar let index = index + strlen(group_name) 384c06ac340SBram Moolenaar let index = match(syntax_full, next_group_regex, index) 3854770d09aSBram Moolenaar endwhile 3864770d09aSBram Moolenaar 38797e8f356SBram Moolenaar let ftindex = ftindex + len(ft_part_name) 38897e8f356SBram Moolenaar let ftindex = match( &filetype, '\w\+', ftindex ) 38997e8f356SBram Moolenaar endwhile 39097e8f356SBram Moolenaar 391c06ac340SBram Moolenaar " Convert the string to a List and sort it. 392c06ac340SBram Moolenaar let compl_list = sort(split(syn_list)) 393c06ac340SBram Moolenaar 394c06ac340SBram Moolenaar if &filetype == 'vim' 395c06ac340SBram Moolenaar let short_compl_list = [] 396c06ac340SBram Moolenaar for i in range(len(compl_list)) 397c06ac340SBram Moolenaar if i == len(compl_list)-1 398c06ac340SBram Moolenaar let next = i 399c06ac340SBram Moolenaar else 400c06ac340SBram Moolenaar let next = i + 1 401c06ac340SBram Moolenaar endif 402c06ac340SBram Moolenaar if compl_list[next] !~ '^'.compl_list[i].'.$' 403c06ac340SBram Moolenaar let short_compl_list += [compl_list[i]] 404c06ac340SBram Moolenaar endif 405c06ac340SBram Moolenaar endfor 406c06ac340SBram Moolenaar 407c06ac340SBram Moolenaar return short_compl_list 408c06ac340SBram Moolenaar else 409c06ac340SBram Moolenaar return compl_list 410c06ac340SBram Moolenaar endif 4114770d09aSBram Moolenaarendfunction 4124770d09aSBram Moolenaar 413e2f98b95SBram Moolenaarfunction! s:SyntaxCSyntaxGroupItems( group_name, syntax_full ) 4144770d09aSBram Moolenaar 415c06ac340SBram Moolenaar let syn_list = "" 4164770d09aSBram Moolenaar 417c06ac340SBram Moolenaar " From the full syntax listing, strip out the portion for the 418c06ac340SBram Moolenaar " request group. 419c06ac340SBram Moolenaar " Query: 420c06ac340SBram Moolenaar " \n - must begin with a newline 421c06ac340SBram Moolenaar " a:group_name - the group name we are interested in 422c06ac340SBram Moolenaar " \s\+xxx\s\+ - group names are always followed by xxx 423c06ac340SBram Moolenaar " \zs - start the match 424c06ac340SBram Moolenaar " .\{-} - everything ... 425c06ac340SBram Moolenaar " \ze - end the match 4266dfc28beSBram Moolenaar " \( - start a group or 2 potential matches 427c06ac340SBram Moolenaar " \n\w - at the first newline starting with a character 4286dfc28beSBram Moolenaar " \| - 2nd potential match 4296dfc28beSBram Moolenaar " \%$ - matches end of the file or string 4306dfc28beSBram Moolenaar " \) - end a group 431c06ac340SBram Moolenaar let syntax_group = matchstr(a:syntax_full, 4326dfc28beSBram Moolenaar \ "\n".a:group_name.'\s\+xxx\s\+\zs.\{-}\ze\(\n\w\|\%$\)' 433c06ac340SBram Moolenaar \ ) 434c06ac340SBram Moolenaar 435c06ac340SBram Moolenaar if syntax_group != "" 4364770d09aSBram Moolenaar " let syn_list = substitute( @l, '^.*xxx\s*\%(contained\s*\)\?', "", '' ) 437c06ac340SBram Moolenaar " let syn_list = substitute( @l, '^.*xxx\s*', "", '' ) 4384770d09aSBram Moolenaar 4394770d09aSBram Moolenaar " We only want the words for the lines begining with 4404770d09aSBram Moolenaar " containedin, but there could be other items. 4414770d09aSBram Moolenaar 4424770d09aSBram Moolenaar " Tried to remove all lines that do not begin with contained 4434770d09aSBram Moolenaar " but this does not work in all cases since you can have 4444770d09aSBram Moolenaar " contained nextgroup=... 4454770d09aSBram Moolenaar " So this will strip off the ending of lines with known 4464770d09aSBram Moolenaar " keywords. 44797e8f356SBram Moolenaar let syn_list = substitute( 44897e8f356SBram Moolenaar \ syntax_group, '\<\('. 4494770d09aSBram Moolenaar \ substitute( 4504770d09aSBram Moolenaar \ escape(s:syn_remove_words, '\\/.*$^~[]') 45197e8f356SBram Moolenaar \ , ',', '\\|', 'g' 45297e8f356SBram Moolenaar \ ). 4534770d09aSBram Moolenaar \ '\).\{-}\%($\|'."\n".'\)' 45497e8f356SBram Moolenaar \ , "\n", 'g' 45597e8f356SBram Moolenaar \ ) 4564770d09aSBram Moolenaar 457f1568ecaSBram Moolenaar " Now strip off the newline + blank space + contained. 458f1568ecaSBram Moolenaar " Also include lines with nextgroup=@someName skip_key_words syntax_element 45997e8f356SBram Moolenaar let syn_list = substitute( 460f1568ecaSBram Moolenaar \ syn_list, '\%(^\|\n\)\@<=\s*\<\(contained\|nextgroup=\)' 461f1568ecaSBram Moolenaar \ , "", 'g' 462f1568ecaSBram Moolenaar \ ) 463f1568ecaSBram Moolenaar 464f1568ecaSBram Moolenaar " This can leave lines like this 465f1568ecaSBram Moolenaar " =@vimMenuList skipwhite onoremenu 466f1568ecaSBram Moolenaar " Strip the special option keywords first 467f1568ecaSBram Moolenaar " :h :syn-skipwhite* 468f1568ecaSBram Moolenaar let syn_list = substitute( 469f1568ecaSBram Moolenaar \ syn_list, '\<\(skipwhite\|skipnl\|skipempty\)\>' 470f1568ecaSBram Moolenaar \ , "", 'g' 471f1568ecaSBram Moolenaar \ ) 472f1568ecaSBram Moolenaar 473f1568ecaSBram Moolenaar " Now remove the remainder of the nextgroup=@someName lines 474f1568ecaSBram Moolenaar let syn_list = substitute( 475f1568ecaSBram Moolenaar \ syn_list, '\%(^\|\n\)\@<=\s*\(@\w\+\)' 47697e8f356SBram Moolenaar \ , "", 'g' 47797e8f356SBram Moolenaar \ ) 4784770d09aSBram Moolenaar 4799964e468SBram Moolenaar if b:omni_syntax_use_iskeyword == 0 4804770d09aSBram Moolenaar " There are a number of items which have non-word characters in 4814770d09aSBram Moolenaar " them, *'T_F1'*. vim.vim is one such file. 4824770d09aSBram Moolenaar " This will replace non-word characters with spaces. 4834770d09aSBram Moolenaar let syn_list = substitute( syn_list, '[^0-9A-Za-z_ ]', ' ', 'g' ) 4844770d09aSBram Moolenaar else 48597d62497SBram Moolenaar if g:omni_syntax_use_iskeyword_numeric == 1 48697d62497SBram Moolenaar " iskeyword can contain value like this 48797d62497SBram Moolenaar " 38,42,43,45,47-58,60-62,64-90,97-122,_,+,-,*,/,%,<,=,>,:,$,?,!,@-@,94 48897d62497SBram Moolenaar " Numeric values convert to their ASCII equivalent using the 48997d62497SBram Moolenaar " nr2char() function. 49097d62497SBram Moolenaar " & 38 49197d62497SBram Moolenaar " * 42 49297d62497SBram Moolenaar " + 43 49397d62497SBram Moolenaar " - 45 49497d62497SBram Moolenaar " ^ 94 49597d62497SBram Moolenaar " Iterate through all numeric specifications and convert those 49697d62497SBram Moolenaar " to their ascii equivalent ensuring the character is printable. 49797d62497SBram Moolenaar " If so, add it to the list. 49897d62497SBram Moolenaar let accepted_chars = '' 49997d62497SBram Moolenaar for item in split(&iskeyword, ',') 50097d62497SBram Moolenaar if item =~ '-' 50197d62497SBram Moolenaar " This is a character range (ie 47-58), 50297d62497SBram Moolenaar " cycle through each character within the range 50397d62497SBram Moolenaar let [b:start, b:end] = split(item, '-') 50497d62497SBram Moolenaar for range_item in range( b:start, b:end ) 50597d62497SBram Moolenaar if range_item <= 127 || g:omni_syntax_use_single_byte == 0 50697d62497SBram Moolenaar if nr2char(range_item) =~ '\p' 50797d62497SBram Moolenaar let accepted_chars = accepted_chars . nr2char(range_item) 50897d62497SBram Moolenaar endif 50997d62497SBram Moolenaar endif 51097d62497SBram Moolenaar endfor 51197d62497SBram Moolenaar elseif item =~ '^\d\+$' 51297d62497SBram Moolenaar " Only numeric, translate to a character 51397d62497SBram Moolenaar if item < 127 || g:omni_syntax_use_single_byte == 0 51497d62497SBram Moolenaar if nr2char(item) =~ '\p' 51597d62497SBram Moolenaar let accepted_chars = accepted_chars . nr2char(item) 51697d62497SBram Moolenaar endif 51797d62497SBram Moolenaar endif 51897d62497SBram Moolenaar else 51997d62497SBram Moolenaar if char2nr(item) < 127 || g:omni_syntax_use_single_byte == 0 52097d62497SBram Moolenaar if item =~ '\p' 52197d62497SBram Moolenaar let accepted_chars = accepted_chars . item 52297d62497SBram Moolenaar endif 52397d62497SBram Moolenaar endif 52497d62497SBram Moolenaar endif 52597d62497SBram Moolenaar endfor 52697d62497SBram Moolenaar " Escape special regex characters 527*34feacbcSBram Moolenaar " Looks like the wrong chars are escaped. In a collection, 528*34feacbcSBram Moolenaar " :h /[] 529*34feacbcSBram Moolenaar " only `]', `\', `-' and `^' are special: 530*34feacbcSBram Moolenaar " let accepted_chars = escape(accepted_chars, '\\/.*$^~[]' ) 531*34feacbcSBram Moolenaar let accepted_chars = escape(accepted_chars, ']\-^' ) 53297d62497SBram Moolenaar " Remove all characters that are not acceptable 53397d62497SBram Moolenaar let syn_list = substitute( syn_list, '[^A-Za-z'.accepted_chars.']', ' ', 'g' ) 53497d62497SBram Moolenaar else 5359964e468SBram Moolenaar let accept_chars = ','.&iskeyword.',' 5369964e468SBram Moolenaar " Remove all character ranges 5373577c6faSBram Moolenaar " let accept_chars = substitute(accept_chars, ',[^,]\+-[^,]\+,', ',', 'g') 5383577c6faSBram Moolenaar let accept_chars = substitute(accept_chars, ',\@<=[^,]\+-[^,]\+,', '', 'g') 5399964e468SBram Moolenaar " Remove all numeric specifications 5403577c6faSBram Moolenaar " let accept_chars = substitute(accept_chars, ',\d\{-},', ',', 'g') 5413577c6faSBram Moolenaar let accept_chars = substitute(accept_chars, ',\@<=\d\{-},', '', 'g') 5429964e468SBram Moolenaar " Remove all commas 5439964e468SBram Moolenaar let accept_chars = substitute(accept_chars, ',', '', 'g') 5449964e468SBram Moolenaar " Escape special regex characters 545*34feacbcSBram Moolenaar " Looks like the wrong chars are escaped. In a collection, 546*34feacbcSBram Moolenaar " :h /[] 547*34feacbcSBram Moolenaar " only `]', `\', `-' and `^' are special: 548*34feacbcSBram Moolenaar " let accept_chars = escape(accept_chars, '\\/.*$^~[]' ) 549*34feacbcSBram Moolenaar let accept_chars = escape(accept_chars, ']\-^' ) 5509964e468SBram Moolenaar " Remove all characters that are not acceptable 5519964e468SBram Moolenaar let syn_list = substitute( syn_list, '[^0-9A-Za-z_'.accept_chars.']', ' ', 'g' ) 5529964e468SBram Moolenaar endif 55397d62497SBram Moolenaar endif 5549964e468SBram Moolenaar 5559964e468SBram Moolenaar if b:omni_syntax_minimum_length > 0 5569964e468SBram Moolenaar " If the user specified a minimum length, enforce it 5579964e468SBram Moolenaar let syn_list = substitute(' '.syn_list.' ', ' \S\{,'.b:omni_syntax_minimum_length.'}\ze ', ' ', 'g') 5589964e468SBram Moolenaar endif 5599964e468SBram Moolenaar else 5604770d09aSBram Moolenaar let syn_list = '' 5614770d09aSBram Moolenaar endif 5624770d09aSBram Moolenaar 5634770d09aSBram Moolenaar return syn_list 5644770d09aSBram Moolenaarendfunction 56597d62497SBram Moolenaar 56697d62497SBram Moolenaarfunction! OmniSyntaxShowChars(spec) 56797d62497SBram Moolenaar let result = [] 56897d62497SBram Moolenaar for item in split(a:spec, ',') 56997d62497SBram Moolenaar if len(item) > 1 57097d62497SBram Moolenaar if item == '@-@' 57197d62497SBram Moolenaar call add(result, char2nr(item)) 57297d62497SBram Moolenaar else 57397d62497SBram Moolenaar call extend(result, call('range', split(item, '-'))) 57497d62497SBram Moolenaar endif 57597d62497SBram Moolenaar else 57697d62497SBram Moolenaar if item == '@' " assume this is [A-Za-z] 57797d62497SBram Moolenaar for [c1, c2] in [['A', 'Z'], ['a', 'z']] 57897d62497SBram Moolenaar call extend(result, range(char2nr(c1), char2nr(c2))) 57997d62497SBram Moolenaar endfor 58097d62497SBram Moolenaar else 58197d62497SBram Moolenaar call add(result, char2nr(item)) 58297d62497SBram Moolenaar endif 58397d62497SBram Moolenaar endif 58497d62497SBram Moolenaar endfor 58597d62497SBram Moolenaar return join(map(result, 'nr2char(v:val)'), ', ') 58697d62497SBram Moolenaarendfunction 58797d62497SBram Moolenaarlet &cpo = s:cpo_save 58897d62497SBram Moolenaarunlet s:cpo_save 589