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*4c295027SBram Moolenaar" Version: 15.0 5*4c295027SBram Moolenaar" Last Change: 2021 Apr 27 697e8f356SBram Moolenaar" Usage: For detailed help, ":help ft-syntax-omni" 74770d09aSBram Moolenaar 86dfc28beSBram Moolenaar" History 940af4e39SBram Moolenaar" 10*4c295027SBram Moolenaar" Version 15.0 11*4c295027SBram Moolenaar" - SyntaxComplete ignored all buffer specific overrides, always used global 12*4c295027SBram Moolenaar" https://github.com/vim/vim/issues/8153 13*4c295027SBram Moolenaar" 149faec4e3SBram Moolenaar" Version 14.0 159faec4e3SBram Moolenaar" - Fixed issue with single quotes and is_keyword 169faec4e3SBram Moolenaar" https://github.com/vim/vim/issues/7463 179faec4e3SBram Moolenaar" 18ad3b366cSBram Moolenaar" Version 13.0 19ad3b366cSBram Moolenaar" - Extended the option omni_syntax_group_include_{filetype} 20ad3b366cSBram Moolenaar" to accept a comma separated list of regex's rather than 21ad3b366cSBram Moolenaar" string. For example, for the javascript filetype you could 22ad3b366cSBram Moolenaar" use: 23ad3b366cSBram Moolenaar" let g:omni_syntax_group_include_javascript = 'javascript\w\+,jquery\w\+' 24ad3b366cSBram Moolenaar" - Some syntax files (perl.vim) use the match // syntax as a mechanism 25ad3b366cSBram Moolenaar" to identify keywords. This update attempts to parse the 26ad3b366cSBram Moolenaar" match syntax and pull out syntax items which are at least 27ad3b366cSBram Moolenaar" 3 words or more. 28ad3b366cSBram Moolenaar" 29ad3b366cSBram Moolenaar" Version 12.0 30ad3b366cSBram Moolenaar" - It is possible to have '-' as part of iskeyword, when 31ad3b366cSBram Moolenaar" checking for character ranges, tighten up the regex. 32ad3b366cSBram Moolenaar" E688: More targets than List items. 33ad3b366cSBram Moolenaar" 3434feacbcSBram Moolenaar" Version 11.0 35ad3b366cSBram Moolenaar" - Corrected which characters required escaping during 3634feacbcSBram Moolenaar" substitution calls. 3734feacbcSBram Moolenaar" 3897d62497SBram Moolenaar" Version 10.0 39ad3b366cSBram Moolenaar" - Cycle through all the character ranges specified in the 4097d62497SBram Moolenaar" iskeyword option and build a list of valid word separators. 4197d62497SBram Moolenaar" Prior to this change, only actual characters were used, 4297d62497SBram Moolenaar" where for example ASCII "45" == "-". If "45" were used 4397d62497SBram Moolenaar" in iskeyword the hyphen would not be picked up. 4497d62497SBram Moolenaar" This introduces a new option, since the character ranges 4597d62497SBram Moolenaar" specified could be multibyte: 4697d62497SBram Moolenaar" let g:omni_syntax_use_single_byte = 1 47ad3b366cSBram Moolenaar" - This by default will only allow single byte ASCII 4897d62497SBram Moolenaar" characters to be added and an additional check to ensure 49*4c295027SBram Moolenaar" the character is printable (see documentation for isprint). 5097d62497SBram Moolenaar" 5197d62497SBram Moolenaar" Version 9.0 52ad3b366cSBram Moolenaar" - Add the check for cpo. 5397d62497SBram Moolenaar" 54f1568ecaSBram Moolenaar" Version 8.0 55ad3b366cSBram Moolenaar" - Updated SyntaxCSyntaxGroupItems() 56f1568ecaSBram Moolenaar" - Some additional syntax items were also allowed 57f1568ecaSBram Moolenaar" on nextgroup= lines which were ignored by default. 58f1568ecaSBram Moolenaar" Now these lines are processed independently. 59f1568ecaSBram Moolenaar" 6040af4e39SBram Moolenaar" Version 7.0 61ad3b366cSBram Moolenaar" - Updated syntaxcomplete#OmniSyntaxList() 6240af4e39SBram Moolenaar" - Looking up the syntax groups defined from a syntax file 6340af4e39SBram Moolenaar" looked for only 1 format of {filetype}GroupName, but some 6440af4e39SBram Moolenaar" syntax writers use this format as well: 6540af4e39SBram Moolenaar" {b:current_syntax}GroupName 66ad3b366cSBram Moolenaar" - OmniSyntaxList() will now check for both if the first 6740af4e39SBram Moolenaar" method does not find a match. 6840af4e39SBram Moolenaar" 6940af4e39SBram Moolenaar" Version 6.0 70ad3b366cSBram Moolenaar" - Added syntaxcomplete#OmniSyntaxList() 7140af4e39SBram Moolenaar" - Allows other plugins to use this for their own 7240af4e39SBram Moolenaar" purposes. 7340af4e39SBram Moolenaar" - It will return a List of all syntax items for the 7440af4e39SBram Moolenaar" syntax group name passed in. 7540af4e39SBram Moolenaar" - XPTemplate for SQL will use this function via the 7640af4e39SBram Moolenaar" sqlcomplete plugin to populate a Choose box. 7740af4e39SBram Moolenaar" 786dfc28beSBram Moolenaar" Version 5.0 79ad3b366cSBram Moolenaar" - Updated SyntaxCSyntaxGroupItems() 8040af4e39SBram Moolenaar" - When processing a list of syntax groups, the final group 816dfc28beSBram Moolenaar" was missed in function SyntaxCSyntaxGroupItems. 826dfc28beSBram Moolenaar" 834770d09aSBram Moolenaar" Set completion with CTRL-X CTRL-O to autoloaded function. 84c15ef30cSBram Moolenaar" This check is in place in case this script is 85c15ef30cSBram Moolenaar" sourced directly instead of using the autoload feature. 86c06ac340SBram Moolenaarif exists('+omnifunc') 87c15ef30cSBram Moolenaar " Do not set the option if already set since this 88c15ef30cSBram Moolenaar " results in an E117 warning. 89c15ef30cSBram Moolenaar if &omnifunc == "" 90c06ac340SBram Moolenaar setlocal omnifunc=syntaxcomplete#Complete 914770d09aSBram Moolenaar endif 92c15ef30cSBram Moolenaarendif 934770d09aSBram Moolenaar 944770d09aSBram Moolenaarif exists('g:loaded_syntax_completion') 954770d09aSBram Moolenaar finish 964770d09aSBram Moolenaarendif 97*4c295027SBram Moolenaarlet g:loaded_syntax_completion = 150 9897d62497SBram Moolenaar 9997d62497SBram Moolenaar" Turn on support for line continuations when creating the script 10097d62497SBram Moolenaarlet s:cpo_save = &cpo 10197d62497SBram Moolenaarset cpo&vim 10297e8f356SBram Moolenaar 10397e8f356SBram Moolenaar" Set ignorecase to the ftplugin standard 1049964e468SBram Moolenaar" This is the default setting, but if you define a buffer local 1059964e468SBram Moolenaar" variable you can override this on a per filetype. 10697e8f356SBram Moolenaarif !exists('g:omni_syntax_ignorecase') 10797e8f356SBram Moolenaar let g:omni_syntax_ignorecase = &ignorecase 10897e8f356SBram Moolenaarendif 1094770d09aSBram Moolenaar 1109964e468SBram Moolenaar" Indicates whether we should use the iskeyword option to determine 1119964e468SBram Moolenaar" how to split words. 1129964e468SBram Moolenaar" This is the default setting, but if you define a buffer local 1139964e468SBram Moolenaar" variable you can override this on a per filetype. 1149964e468SBram Moolenaarif !exists('g:omni_syntax_use_iskeyword') 1159964e468SBram Moolenaar let g:omni_syntax_use_iskeyword = 1 1169964e468SBram Moolenaarendif 1179964e468SBram Moolenaar 11897d62497SBram Moolenaar" When using iskeyword, this setting controls whether the characters 11997d62497SBram Moolenaar" should be limited to single byte characters. 12097d62497SBram Moolenaarif !exists('g:omni_syntax_use_single_byte') 12197d62497SBram Moolenaar let g:omni_syntax_use_single_byte = 1 12297d62497SBram Moolenaarendif 12397d62497SBram Moolenaar 12497d62497SBram Moolenaar" When using iskeyword, this setting controls whether the characters 12597d62497SBram Moolenaar" should be limited to single byte characters. 12697d62497SBram Moolenaarif !exists('g:omni_syntax_use_iskeyword_numeric') 12797d62497SBram Moolenaar let g:omni_syntax_use_iskeyword_numeric = 1 12897d62497SBram Moolenaarendif 12997d62497SBram Moolenaar 1309964e468SBram Moolenaar" Only display items in the completion window that are at least 1319964e468SBram Moolenaar" this many characters in length. 1329964e468SBram Moolenaar" This is the default setting, but if you define a buffer local 1339964e468SBram Moolenaar" variable you can override this on a per filetype. 1349964e468SBram Moolenaarif !exists('g:omni_syntax_minimum_length') 1359964e468SBram Moolenaar let g:omni_syntax_minimum_length = 0 1369964e468SBram Moolenaarendif 1379964e468SBram Moolenaar 1384770d09aSBram Moolenaar" This script will build a completion list based on the syntax 1394770d09aSBram Moolenaar" elements defined by the files in $VIMRUNTIME/syntax. 140ad3b366cSBram Moolenaar" let s:syn_remove_words = 'match,matchgroup=,contains,'. 141ad3b366cSBram Moolenaarlet s:syn_remove_words = 'matchgroup=,contains,'. 142f1568ecaSBram Moolenaar \ 'links to,start=,end=' 143f1568ecaSBram Moolenaar " \ 'links to,start=,end=,nextgroup=' 1444770d09aSBram Moolenaar 1454770d09aSBram Moolenaarlet s:cache_name = [] 1464770d09aSBram Moolenaarlet s:cache_list = [] 147c15ef30cSBram Moolenaarlet s:prepended = '' 1484770d09aSBram Moolenaar 1494770d09aSBram Moolenaar" This function is used for the 'omnifunc' option. 1504770d09aSBram Moolenaarfunction! syntaxcomplete#Complete(findstart, base) 1514770d09aSBram Moolenaar 152*4c295027SBram Moolenaar " Allow user to override ignorecase per buffer 153*4c295027SBram Moolenaar let l:omni_syntax_ignorecase = g:omni_syntax_ignorecase 154*4c295027SBram Moolenaar if exists('b:omni_syntax_ignorecase') 155*4c295027SBram Moolenaar let l:omni_syntax_ignorecase = b:omni_syntax_ignorecase 1569964e468SBram Moolenaar endif 1579964e468SBram Moolenaar 1584770d09aSBram Moolenaar if a:findstart 1594770d09aSBram Moolenaar " Locate the start of the item, including "." 1604770d09aSBram Moolenaar let line = getline('.') 1614770d09aSBram Moolenaar let start = col('.') - 1 1624770d09aSBram Moolenaar let lastword = -1 1634770d09aSBram Moolenaar while start > 0 1649964e468SBram Moolenaar " if line[start - 1] =~ '\S' 1659964e468SBram Moolenaar " let start -= 1 1669964e468SBram Moolenaar " elseif line[start - 1] =~ '\.' 1679964e468SBram Moolenaar if line[start - 1] =~ '\k' 1684770d09aSBram Moolenaar let start -= 1 1699964e468SBram Moolenaar let lastword = a:findstart 1704770d09aSBram Moolenaar else 1714770d09aSBram Moolenaar break 1724770d09aSBram Moolenaar endif 1734770d09aSBram Moolenaar endwhile 1744770d09aSBram Moolenaar 1754770d09aSBram Moolenaar " Return the column of the last word, which is going to be changed. 1764770d09aSBram Moolenaar " Remember the text that comes before it in s:prepended. 1774770d09aSBram Moolenaar if lastword == -1 1784770d09aSBram Moolenaar let s:prepended = '' 1794770d09aSBram Moolenaar return start 1804770d09aSBram Moolenaar endif 1819964e468SBram Moolenaar let s:prepended = strpart(line, start, (col('.') - 1) - start) 1829964e468SBram Moolenaar return start 1834770d09aSBram Moolenaar endif 1844770d09aSBram Moolenaar 1859964e468SBram Moolenaar " let base = s:prepended . a:base 1869faec4e3SBram Moolenaar let base = substitute(s:prepended, "'", "''", 'g') 1874770d09aSBram Moolenaar 18897e8f356SBram Moolenaar let filetype = substitute(&filetype, '\.', '_', 'g') 18997e8f356SBram Moolenaar let list_idx = index(s:cache_name, filetype, 0, &ignorecase) 1904770d09aSBram Moolenaar if list_idx > -1 1914770d09aSBram Moolenaar let compl_list = s:cache_list[list_idx] 1924770d09aSBram Moolenaar else 193c06ac340SBram Moolenaar let compl_list = OmniSyntaxList() 19497e8f356SBram Moolenaar let s:cache_name = add( s:cache_name, filetype ) 1954770d09aSBram Moolenaar let s:cache_list = add( s:cache_list, compl_list ) 1964770d09aSBram Moolenaar endif 1974770d09aSBram Moolenaar 1984770d09aSBram Moolenaar " Return list of matches. 1994770d09aSBram Moolenaar 2009964e468SBram Moolenaar if base != '' 2019964e468SBram Moolenaar " let compstr = join(compl_list, ' ') 202*4c295027SBram Moolenaar " let expr = (l:omni_syntax_ignorecase==0?'\C':'').'\<\%('.base.'\)\@!\w\+\s*' 2039964e468SBram Moolenaar " let compstr = substitute(compstr, expr, '', 'g') 2049964e468SBram Moolenaar " let compl_list = split(compstr, '\s\+') 2059964e468SBram Moolenaar 2069964e468SBram Moolenaar " Filter the list based on the first few characters the user 2079964e468SBram Moolenaar " entered 208*4c295027SBram Moolenaar let expr = 'v:val '.(l:omni_syntax_ignorecase==1?'=~?':'=~#')." '^".escape(base, '\\/.*$^~[]').".*'" 2099964e468SBram Moolenaar let compl_list = filter(deepcopy(compl_list), expr) 2104770d09aSBram Moolenaar endif 2114770d09aSBram Moolenaar 2124770d09aSBram Moolenaar return compl_list 2134770d09aSBram Moolenaarendfunc 2144770d09aSBram Moolenaar 21540af4e39SBram Moolenaarfunction! syntaxcomplete#OmniSyntaxList(...) 21640af4e39SBram Moolenaar if a:0 > 0 21740af4e39SBram Moolenaar let parms = [] 21840af4e39SBram Moolenaar if 3 == type(a:1) 21940af4e39SBram Moolenaar let parms = a:1 22040af4e39SBram Moolenaar elseif 1 == type(a:1) 22140af4e39SBram Moolenaar let parms = split(a:1, ',') 22240af4e39SBram Moolenaar endif 22340af4e39SBram Moolenaar return OmniSyntaxList( parms ) 22440af4e39SBram Moolenaar else 22540af4e39SBram Moolenaar return OmniSyntaxList() 22640af4e39SBram Moolenaar endif 22740af4e39SBram Moolenaarendfunc 22840af4e39SBram Moolenaar 229*4c295027SBram Moolenaarfunction! syntaxcomplete#OmniSyntaxClearCache() 230*4c295027SBram Moolenaar let s:cache_name = [] 231*4c295027SBram Moolenaar let s:cache_list = [] 232*4c295027SBram Moolenaarendfunction 233*4c295027SBram Moolenaar 234*4c295027SBram Moolenaar" To retrieve all syntax items regardless of syntax group: 235*4c295027SBram Moolenaar" echo OmniSyntaxList( [] ) 236*4c295027SBram Moolenaar" 237*4c295027SBram Moolenaar" To retrieve only the syntax items for the sqlOperator syntax group: 238*4c295027SBram Moolenaar" echo OmniSyntaxList( ['sqlOperator'] ) 239*4c295027SBram Moolenaar" 240*4c295027SBram Moolenaar" To retrieve all syntax items for both the sqlOperator and sqlType groups: 241*4c295027SBram Moolenaar" echo OmniSyntaxList( ['sqlOperator', 'sqlType'] ) 242*4c295027SBram Moolenaar" 243*4c295027SBram Moolenaar" A regular expression can also be used: 244*4c295027SBram Moolenaar" echo OmniSyntaxList( ['sql\w\+'] ) 245*4c295027SBram Moolenaar" 246*4c295027SBram Moolenaar" From within a plugin, you would typically assign the output to a List: > 247*4c295027SBram Moolenaar" let myKeywords = [] 248*4c295027SBram Moolenaar" let myKeywords = OmniSyntaxList( ['sqlKeyword'] ) 24940af4e39SBram Moolenaarfunction! OmniSyntaxList(...) 25040af4e39SBram Moolenaar let list_parms = [] 25140af4e39SBram Moolenaar if a:0 > 0 25240af4e39SBram Moolenaar if 3 == type(a:1) 25340af4e39SBram Moolenaar let list_parms = a:1 25440af4e39SBram Moolenaar elseif 1 == type(a:1) 25540af4e39SBram Moolenaar let list_parms = split(a:1, ',') 25640af4e39SBram Moolenaar endif 25740af4e39SBram Moolenaar endif 25840af4e39SBram Moolenaar 25997e8f356SBram Moolenaar " Default to returning a dictionary, if use_dictionary is set to 0 26097e8f356SBram Moolenaar " a list will be returned. 26197e8f356SBram Moolenaar " let use_dictionary = 1 26297e8f356SBram Moolenaar " if a:0 > 0 && a:1 != '' 26397e8f356SBram Moolenaar " let use_dictionary = a:1 26497e8f356SBram Moolenaar " endif 26597e8f356SBram Moolenaar 2664770d09aSBram Moolenaar let saveL = @l 26740af4e39SBram Moolenaar let filetype = substitute(&filetype, '\.', '_', 'g') 26840af4e39SBram Moolenaar 26940af4e39SBram Moolenaar if empty(list_parms) 270*4c295027SBram Moolenaar " Allow user to override per buffer 271*4c295027SBram Moolenaar if exists('g:omni_syntax_group_include_'.filetype) 272*4c295027SBram Moolenaar let l:omni_syntax_group_include_{filetype} = g:omni_syntax_group_include_{filetype} 273*4c295027SBram Moolenaar endif 274*4c295027SBram Moolenaar if exists('b:omni_syntax_group_include_'.filetype) 275*4c295027SBram Moolenaar let l:omni_syntax_group_include_{filetype} = b:omni_syntax_group_include_{filetype} 276*4c295027SBram Moolenaar endif 277*4c295027SBram Moolenaar 27840af4e39SBram Moolenaar " Default the include group to include the requested syntax group 27940af4e39SBram Moolenaar let syntax_group_include_{filetype} = '' 28040af4e39SBram Moolenaar " Check if there are any overrides specified for this filetype 281*4c295027SBram Moolenaar if exists('l:omni_syntax_group_include_'.filetype) 28240af4e39SBram Moolenaar let syntax_group_include_{filetype} = 283*4c295027SBram Moolenaar \ substitute( l:omni_syntax_group_include_{filetype},'\s\+','','g') 284*4c295027SBram Moolenaar let list_parms = split(l:omni_syntax_group_include_{filetype}, ',') 28540af4e39SBram Moolenaar if syntax_group_include_{filetype} =~ '\w' 28640af4e39SBram Moolenaar let syntax_group_include_{filetype} = 28740af4e39SBram Moolenaar \ substitute( syntax_group_include_{filetype}, 28840af4e39SBram Moolenaar \ '\s*,\s*', '\\|', 'g' 28940af4e39SBram Moolenaar \ ) 29040af4e39SBram Moolenaar endif 29140af4e39SBram Moolenaar endif 29240af4e39SBram Moolenaar else 29340af4e39SBram Moolenaar " A specific list was provided, use it 29440af4e39SBram Moolenaar endif 2954770d09aSBram Moolenaar 2964770d09aSBram Moolenaar " Loop through all the syntax groupnames, and build a 2974770d09aSBram Moolenaar " syntax file which contains these names. This can 2984770d09aSBram Moolenaar " work generically for any filetype that does not already 2994770d09aSBram Moolenaar " have a plugin defined. 3004770d09aSBram Moolenaar " This ASSUMES the syntax groupname BEGINS with the name 301c06ac340SBram Moolenaar " of the filetype. From my casual viewing of the vim7\syntax 30240af4e39SBram Moolenaar " directory this is true for almost all syntax definitions. 30340af4e39SBram Moolenaar " As an example, the SQL syntax groups have this pattern: 30440af4e39SBram Moolenaar " sqlType 30540af4e39SBram Moolenaar " sqlOperators 30640af4e39SBram Moolenaar " sqlKeyword ... 307ad3b366cSBram Moolenaar if !empty(list_parms) && empty(substitute(join(list_parms), '[a-zA-Z ]', '', 'g')) 308ad3b366cSBram Moolenaar " If list_parms only includes word characters, use it to limit 309ad3b366cSBram Moolenaar " the syntax elements. 310ad3b366cSBram Moolenaar " If using regex syntax list will fail to find those items, so 311ad3b366cSBram Moolenaar " simply grab the who syntax list. 3124770d09aSBram Moolenaar redir @l 31340af4e39SBram Moolenaar silent! exec 'syntax list '.join(list_parms) 3144770d09aSBram Moolenaar redir END 315ad3b366cSBram Moolenaar else 316ad3b366cSBram Moolenaar redir @l 317ad3b366cSBram Moolenaar silent! exec 'syntax list' 318ad3b366cSBram Moolenaar redir END 319ad3b366cSBram Moolenaar endif 3204770d09aSBram Moolenaar 321c06ac340SBram Moolenaar let syntax_full = "\n".@l 3224770d09aSBram Moolenaar let @l = saveL 3234770d09aSBram Moolenaar 324c06ac340SBram Moolenaar if syntax_full =~ 'E28' 325c06ac340SBram Moolenaar \ || syntax_full =~ 'E411' 326c06ac340SBram Moolenaar \ || syntax_full =~ 'E415' 327c06ac340SBram Moolenaar \ || syntax_full =~ 'No Syntax items' 328c06ac340SBram Moolenaar return [] 3294770d09aSBram Moolenaar endif 3304770d09aSBram Moolenaar 33197e8f356SBram Moolenaar let filetype = substitute(&filetype, '\.', '_', 'g') 33297e8f356SBram Moolenaar 33340af4e39SBram Moolenaar let list_exclude_groups = [] 33440af4e39SBram Moolenaar if a:0 > 0 33540af4e39SBram Moolenaar " Do nothing since we have specific a specific list of groups 33640af4e39SBram Moolenaar else 337c06ac340SBram Moolenaar " Default the exclude group to nothing 33897e8f356SBram Moolenaar let syntax_group_exclude_{filetype} = '' 339*4c295027SBram Moolenaar 340*4c295027SBram Moolenaar " Allow user to override per buffer 34197e8f356SBram Moolenaar if exists('g:omni_syntax_group_exclude_'.filetype) 342*4c295027SBram Moolenaar let l:omni_syntax_group_exclude_{filetype} = g:omni_syntax_group_exclude_{filetype} 343*4c295027SBram Moolenaar endif 344*4c295027SBram Moolenaar if exists('b:omni_syntax_group_exclude_'.filetype) 345*4c295027SBram Moolenaar let l:omni_syntax_group_exclude_{filetype} = b:omni_syntax_group_exclude_{filetype} 346*4c295027SBram Moolenaar endif 347*4c295027SBram Moolenaar 348*4c295027SBram Moolenaar " Check if there are any overrides specified for this filetype 349*4c295027SBram Moolenaar if exists('l:omni_syntax_group_exclude_'.filetype) 35097e8f356SBram Moolenaar let syntax_group_exclude_{filetype} = 351*4c295027SBram Moolenaar \ substitute( l:omni_syntax_group_exclude_{filetype},'\s\+','','g') 352*4c295027SBram Moolenaar let list_exclude_groups = split(l:omni_syntax_group_exclude_{filetype}, ',') 35397e8f356SBram Moolenaar if syntax_group_exclude_{filetype} =~ '\w' 35497e8f356SBram Moolenaar let syntax_group_exclude_{filetype} = 35597e8f356SBram Moolenaar \ substitute( syntax_group_exclude_{filetype}, 356c06ac340SBram Moolenaar \ '\s*,\s*', '\\|', 'g' 357c06ac340SBram Moolenaar \ ) 358c06ac340SBram Moolenaar endif 359c06ac340SBram Moolenaar endif 36040af4e39SBram Moolenaar endif 361c06ac340SBram Moolenaar 362ad3b366cSBram Moolenaar if empty(list_parms) 363ad3b366cSBram Moolenaar let list_parms = [&filetype.'\w\+'] 364ad3b366cSBram Moolenaar endif 365ad3b366cSBram Moolenaar 366ad3b366cSBram Moolenaar let syn_list = '' 367ad3b366cSBram Moolenaar let index = 0 368ad3b366cSBram Moolenaar for group_regex in list_parms 36997e8f356SBram Moolenaar " Sometimes filetypes can be composite names, like c.doxygen 37097e8f356SBram Moolenaar " Loop through each individual part looking for the syntax 37197e8f356SBram Moolenaar " items specific to each individual filetype. 372ad3b366cSBram Moolenaar " let ftindex = 0 373ad3b366cSBram Moolenaar " let ftindex = match(syntax_full, group_regex, ftindex) 37497e8f356SBram Moolenaar 375ad3b366cSBram Moolenaar " while ftindex > -1 376ad3b366cSBram Moolenaar " let ft_part_name = matchstr( syntax_full, '\w\+', ftindex ) 37797e8f356SBram Moolenaar 378c06ac340SBram Moolenaar " Syntax rules can contain items for more than just the current 379c06ac340SBram Moolenaar " filetype. They can contain additional items added by the user 380c06ac340SBram Moolenaar " via autocmds or their vimrc. 381c06ac340SBram Moolenaar " Some syntax files can be combined (html, php, jsp). 382c06ac340SBram Moolenaar " We want only items that begin with the filetype we are interested in. 3834770d09aSBram Moolenaar let next_group_regex = '\n' . 384ad3b366cSBram Moolenaar \ '\zs'.group_regex.'\ze'. 385c06ac340SBram Moolenaar \ '\s\+xxx\s\+' 386c06ac340SBram Moolenaar let index = match(syntax_full, next_group_regex, index) 3874770d09aSBram Moolenaar 388ad3b366cSBram Moolenaar " For the matched group name, strip off any of the regex special 389ad3b366cSBram Moolenaar " characters and see if we get a match with the current syntax 390ad3b366cSBram Moolenaar if index == -1 && exists('b:current_syntax') && substitute(group_regex, '[^a-zA-Z ]\+.*', '', 'g') !~ '^'.b:current_syntax 39140af4e39SBram Moolenaar " There appears to be two standards when writing syntax files. 39240af4e39SBram Moolenaar " Either items begin as: 39340af4e39SBram Moolenaar " syn keyword {filetype}Keyword values ... 39440af4e39SBram Moolenaar " let b:current_syntax = "sql" 39540af4e39SBram Moolenaar " let b:current_syntax = "sqlanywhere" 39640af4e39SBram Moolenaar " Or 39740af4e39SBram Moolenaar " syn keyword {syntax_filename}Keyword values ... 39840af4e39SBram Moolenaar " let b:current_syntax = "mysql" 39940af4e39SBram Moolenaar " So, we will make the format of finding the syntax group names 40040af4e39SBram Moolenaar " a bit more flexible and look for both if the first fails to 40140af4e39SBram Moolenaar " find a match. 40240af4e39SBram Moolenaar let next_group_regex = '\n' . 40340af4e39SBram Moolenaar \ '\zs'.b:current_syntax.'\w\+\ze'. 40440af4e39SBram Moolenaar \ '\s\+xxx\s\+' 40540af4e39SBram Moolenaar let index = 0 40640af4e39SBram Moolenaar let index = match(syntax_full, next_group_regex, index) 40740af4e39SBram Moolenaar endif 40840af4e39SBram Moolenaar 40997e8f356SBram Moolenaar while index > -1 410c06ac340SBram Moolenaar let group_name = matchstr( syntax_full, '\w\+', index ) 4114770d09aSBram Moolenaar 412c06ac340SBram Moolenaar let get_syn_list = 1 41340af4e39SBram Moolenaar for exclude_group_name in list_exclude_groups 41440af4e39SBram Moolenaar if '\<'.exclude_group_name.'\>' =~ '\<'.group_name.'\>' 415c06ac340SBram Moolenaar let get_syn_list = 0 416c06ac340SBram Moolenaar endif 41740af4e39SBram Moolenaar endfor 418c06ac340SBram Moolenaar 41940af4e39SBram Moolenaar " This code is no longer needed in version 6.0 since we have 42040af4e39SBram Moolenaar " augmented the syntax list command to only retrieve the syntax 42140af4e39SBram Moolenaar " groups we are interested in. 42240af4e39SBram Moolenaar " 42340af4e39SBram Moolenaar " if get_syn_list == 1 42440af4e39SBram Moolenaar " if syntax_group_include_{filetype} != '' 42540af4e39SBram Moolenaar " if '\<'.syntax_group_include_{filetype}.'\>' !~ '\<'.group_name.'\>' 42640af4e39SBram Moolenaar " let get_syn_list = 0 42740af4e39SBram Moolenaar " endif 42840af4e39SBram Moolenaar " endif 42940af4e39SBram Moolenaar " endif 430c06ac340SBram Moolenaar 431c06ac340SBram Moolenaar if get_syn_list == 1 432c06ac340SBram Moolenaar " Pass in the full syntax listing, plus the group name we 433c06ac340SBram Moolenaar " are interested in. 434e2f98b95SBram Moolenaar let extra_syn_list = s:SyntaxCSyntaxGroupItems(group_name, syntax_full) 4354770d09aSBram Moolenaar let syn_list = syn_list . extra_syn_list . "\n" 436c06ac340SBram Moolenaar endif 4374770d09aSBram Moolenaar 4384770d09aSBram Moolenaar let index = index + strlen(group_name) 439c06ac340SBram Moolenaar let index = match(syntax_full, next_group_regex, index) 4404770d09aSBram Moolenaar endwhile 4414770d09aSBram Moolenaar 442ad3b366cSBram Moolenaar " let ftindex = ftindex + len(ft_part_name) 443ad3b366cSBram Moolenaar " let ftindex = match( syntax_full, group_regex, ftindex ) 444ad3b366cSBram Moolenaar " endwhile 445ad3b366cSBram Moolenaar endfor 446ad3b366cSBram Moolenaar 447ad3b366cSBram Moolenaar" " Sometimes filetypes can be composite names, like c.doxygen 448ad3b366cSBram Moolenaar" " Loop through each individual part looking for the syntax 449ad3b366cSBram Moolenaar" " items specific to each individual filetype. 450ad3b366cSBram Moolenaar" let syn_list = '' 451ad3b366cSBram Moolenaar" let ftindex = 0 452ad3b366cSBram Moolenaar" let ftindex = match(&filetype, '\w\+', ftindex) 453ad3b366cSBram Moolenaar 454ad3b366cSBram Moolenaar" while ftindex > -1 455ad3b366cSBram Moolenaar" let ft_part_name = matchstr( &filetype, '\w\+', ftindex ) 456ad3b366cSBram Moolenaar 457ad3b366cSBram Moolenaar" " Syntax rules can contain items for more than just the current 458ad3b366cSBram Moolenaar" " filetype. They can contain additional items added by the user 459ad3b366cSBram Moolenaar" " via autocmds or their vimrc. 460ad3b366cSBram Moolenaar" " Some syntax files can be combined (html, php, jsp). 461ad3b366cSBram Moolenaar" " We want only items that begin with the filetype we are interested in. 462ad3b366cSBram Moolenaar" let next_group_regex = '\n' . 463ad3b366cSBram Moolenaar" \ '\zs'.ft_part_name.'\w\+\ze'. 464ad3b366cSBram Moolenaar" \ '\s\+xxx\s\+' 465ad3b366cSBram Moolenaar" let index = 0 466ad3b366cSBram Moolenaar" let index = match(syntax_full, next_group_regex, index) 467ad3b366cSBram Moolenaar 468ad3b366cSBram Moolenaar" if index == -1 && exists('b:current_syntax') && ft_part_name != b:current_syntax 469ad3b366cSBram Moolenaar" " There appears to be two standards when writing syntax files. 470ad3b366cSBram Moolenaar" " Either items begin as: 471ad3b366cSBram Moolenaar" " syn keyword {filetype}Keyword values ... 472ad3b366cSBram Moolenaar" " let b:current_syntax = "sql" 473ad3b366cSBram Moolenaar" " let b:current_syntax = "sqlanywhere" 474ad3b366cSBram Moolenaar" " Or 475ad3b366cSBram Moolenaar" " syn keyword {syntax_filename}Keyword values ... 476ad3b366cSBram Moolenaar" " let b:current_syntax = "mysql" 477ad3b366cSBram Moolenaar" " So, we will make the format of finding the syntax group names 478ad3b366cSBram Moolenaar" " a bit more flexible and look for both if the first fails to 479ad3b366cSBram Moolenaar" " find a match. 480ad3b366cSBram Moolenaar" let next_group_regex = '\n' . 481ad3b366cSBram Moolenaar" \ '\zs'.b:current_syntax.'\w\+\ze'. 482ad3b366cSBram Moolenaar" \ '\s\+xxx\s\+' 483ad3b366cSBram Moolenaar" let index = 0 484ad3b366cSBram Moolenaar" let index = match(syntax_full, next_group_regex, index) 485ad3b366cSBram Moolenaar" endif 486ad3b366cSBram Moolenaar 487ad3b366cSBram Moolenaar" while index > -1 488ad3b366cSBram Moolenaar" let group_name = matchstr( syntax_full, '\w\+', index ) 489ad3b366cSBram Moolenaar 490ad3b366cSBram Moolenaar" let get_syn_list = 1 491ad3b366cSBram Moolenaar" for exclude_group_name in list_exclude_groups 492ad3b366cSBram Moolenaar" if '\<'.exclude_group_name.'\>' =~ '\<'.group_name.'\>' 493ad3b366cSBram Moolenaar" let get_syn_list = 0 494ad3b366cSBram Moolenaar" endif 495ad3b366cSBram Moolenaar" endfor 496ad3b366cSBram Moolenaar 497ad3b366cSBram Moolenaar" " This code is no longer needed in version 6.0 since we have 498ad3b366cSBram Moolenaar" " augmented the syntax list command to only retrieve the syntax 499ad3b366cSBram Moolenaar" " groups we are interested in. 500ad3b366cSBram Moolenaar" " 501ad3b366cSBram Moolenaar" " if get_syn_list == 1 502ad3b366cSBram Moolenaar" " if syntax_group_include_{filetype} != '' 503ad3b366cSBram Moolenaar" " if '\<'.syntax_group_include_{filetype}.'\>' !~ '\<'.group_name.'\>' 504ad3b366cSBram Moolenaar" " let get_syn_list = 0 505ad3b366cSBram Moolenaar" " endif 506ad3b366cSBram Moolenaar" " endif 507ad3b366cSBram Moolenaar" " endif 508ad3b366cSBram Moolenaar 509ad3b366cSBram Moolenaar" if get_syn_list == 1 510ad3b366cSBram Moolenaar" " Pass in the full syntax listing, plus the group name we 511ad3b366cSBram Moolenaar" " are interested in. 512ad3b366cSBram Moolenaar" let extra_syn_list = s:SyntaxCSyntaxGroupItems(group_name, syntax_full) 513ad3b366cSBram Moolenaar" let syn_list = syn_list . extra_syn_list . "\n" 514ad3b366cSBram Moolenaar" endif 515ad3b366cSBram Moolenaar 516ad3b366cSBram Moolenaar" let index = index + strlen(group_name) 517ad3b366cSBram Moolenaar" let index = match(syntax_full, next_group_regex, index) 518ad3b366cSBram Moolenaar" endwhile 519ad3b366cSBram Moolenaar 520ad3b366cSBram Moolenaar" let ftindex = ftindex + len(ft_part_name) 521ad3b366cSBram Moolenaar" let ftindex = match( &filetype, '\w\+', ftindex ) 522ad3b366cSBram Moolenaar" endwhile 52397e8f356SBram Moolenaar 524c06ac340SBram Moolenaar " Convert the string to a List and sort it. 525c06ac340SBram Moolenaar let compl_list = sort(split(syn_list)) 526c06ac340SBram Moolenaar 527c06ac340SBram Moolenaar if &filetype == 'vim' 528c06ac340SBram Moolenaar let short_compl_list = [] 529c06ac340SBram Moolenaar for i in range(len(compl_list)) 530c06ac340SBram Moolenaar if i == len(compl_list)-1 531c06ac340SBram Moolenaar let next = i 532c06ac340SBram Moolenaar else 533c06ac340SBram Moolenaar let next = i + 1 534c06ac340SBram Moolenaar endif 535c06ac340SBram Moolenaar if compl_list[next] !~ '^'.compl_list[i].'.$' 536c06ac340SBram Moolenaar let short_compl_list += [compl_list[i]] 537c06ac340SBram Moolenaar endif 538c06ac340SBram Moolenaar endfor 539c06ac340SBram Moolenaar 540c06ac340SBram Moolenaar return short_compl_list 541c06ac340SBram Moolenaar else 542c06ac340SBram Moolenaar return compl_list 543c06ac340SBram Moolenaar endif 5444770d09aSBram Moolenaarendfunction 5454770d09aSBram Moolenaar 546e2f98b95SBram Moolenaarfunction! s:SyntaxCSyntaxGroupItems( group_name, syntax_full ) 5474770d09aSBram Moolenaar 548*4c295027SBram Moolenaar " Allow user to override iskeyword per buffer 549*4c295027SBram Moolenaar let l:omni_syntax_use_iskeyword = g:omni_syntax_use_iskeyword 550*4c295027SBram Moolenaar if exists('b:omni_syntax_use_iskeyword') 551*4c295027SBram Moolenaar let l:omni_syntax_use_iskeyword = b:omni_syntax_use_iskeyword 552*4c295027SBram Moolenaar endif 553*4c295027SBram Moolenaar 554*4c295027SBram Moolenaar " Allow user to override iskeyword_numeric per buffer 555*4c295027SBram Moolenaar let l:omni_syntax_use_iskeyword_numeric = g:omni_syntax_use_iskeyword_numeric 556*4c295027SBram Moolenaar if exists('b:omni_syntax_use_iskeyword_numeric') 557*4c295027SBram Moolenaar let l:omni_syntax_use_iskeyword_numeric = b:omni_syntax_use_iskeyword_numeric 558*4c295027SBram Moolenaar endif 559*4c295027SBram Moolenaar 560*4c295027SBram Moolenaar " Allow user to override iskeyword_numeric per buffer 561*4c295027SBram Moolenaar let l:omni_syntax_use_single_byte = g:omni_syntax_use_single_byte 562*4c295027SBram Moolenaar if exists('b:omni_syntax_use_single_byte') 563*4c295027SBram Moolenaar let l:omni_syntax_use_single_byte = b:omni_syntax_use_single_byte 564*4c295027SBram Moolenaar endif 565*4c295027SBram Moolenaar 566*4c295027SBram Moolenaar " Allow user to override minimum_length per buffer 567*4c295027SBram Moolenaar let l:omni_syntax_minimum_length = g:omni_syntax_minimum_length 568*4c295027SBram Moolenaar if exists('b:omni_syntax_minimum_length') 569*4c295027SBram Moolenaar let l:omni_syntax_minimum_length = b:omni_syntax_minimum_length 570*4c295027SBram Moolenaar endif 571*4c295027SBram Moolenaar 572c06ac340SBram Moolenaar let syn_list = "" 5734770d09aSBram Moolenaar 574c06ac340SBram Moolenaar " From the full syntax listing, strip out the portion for the 575c06ac340SBram Moolenaar " request group. 576c06ac340SBram Moolenaar " Query: 577c06ac340SBram Moolenaar " \n - must begin with a newline 578c06ac340SBram Moolenaar " a:group_name - the group name we are interested in 579c06ac340SBram Moolenaar " \s\+xxx\s\+ - group names are always followed by xxx 580c06ac340SBram Moolenaar " \zs - start the match 581c06ac340SBram Moolenaar " .\{-} - everything ... 582c06ac340SBram Moolenaar " \ze - end the match 5836dfc28beSBram Moolenaar " \( - start a group or 2 potential matches 584c06ac340SBram Moolenaar " \n\w - at the first newline starting with a character 5856dfc28beSBram Moolenaar " \| - 2nd potential match 5866dfc28beSBram Moolenaar " \%$ - matches end of the file or string 5876dfc28beSBram Moolenaar " \) - end a group 588c06ac340SBram Moolenaar let syntax_group = matchstr(a:syntax_full, 5896dfc28beSBram Moolenaar \ "\n".a:group_name.'\s\+xxx\s\+\zs.\{-}\ze\(\n\w\|\%$\)' 590c06ac340SBram Moolenaar \ ) 591c06ac340SBram Moolenaar 592c06ac340SBram Moolenaar if syntax_group != "" 5934770d09aSBram Moolenaar " let syn_list = substitute( @l, '^.*xxx\s*\%(contained\s*\)\?', "", '' ) 594c06ac340SBram Moolenaar " let syn_list = substitute( @l, '^.*xxx\s*', "", '' ) 5954770d09aSBram Moolenaar 5969faec4e3SBram Moolenaar " We only want the words for the lines beginning with 5974770d09aSBram Moolenaar " containedin, but there could be other items. 5984770d09aSBram Moolenaar 5994770d09aSBram Moolenaar " Tried to remove all lines that do not begin with contained 6004770d09aSBram Moolenaar " but this does not work in all cases since you can have 6014770d09aSBram Moolenaar " contained nextgroup=... 6024770d09aSBram Moolenaar " So this will strip off the ending of lines with known 6034770d09aSBram Moolenaar " keywords. 60497e8f356SBram Moolenaar let syn_list = substitute( 60597e8f356SBram Moolenaar \ syntax_group, '\<\('. 6064770d09aSBram Moolenaar \ substitute( 6074770d09aSBram Moolenaar \ escape(s:syn_remove_words, '\\/.*$^~[]') 60897e8f356SBram Moolenaar \ , ',', '\\|', 'g' 60997e8f356SBram Moolenaar \ ). 6104770d09aSBram Moolenaar \ '\).\{-}\%($\|'."\n".'\)' 61197e8f356SBram Moolenaar \ , "\n", 'g' 61297e8f356SBram Moolenaar \ ) 6134770d09aSBram Moolenaar 614ad3b366cSBram Moolenaar " Attempt to deal with lines using the match syntax 615ad3b366cSBram Moolenaar " javaScriptDocTags xxx match /@\(param\|argument\|requires\|file\)\>/ 616ad3b366cSBram Moolenaar " Though it can use any types of regex, so this plugin will attempt 617ad3b366cSBram Moolenaar " to restrict it 618ad3b366cSBram Moolenaar " 1. Only use \( or \%( constructs remove all else 619ad3b366cSBram Moolenaar " 2 Remove and []s 620ad3b366cSBram Moolenaar " 3. Account for match //constructs 621ad3b366cSBram Moolenaar " \%(\%(ms\|me\|hs\|he\|rs\|re\|lc\)\S\+\)\? 622ad3b366cSBram Moolenaar " 4. Hope for the best 623ad3b366cSBram Moolenaar " 624ad3b366cSBram Moolenaar " 625ad3b366cSBram Moolenaar let syn_list_old = syn_list 626ad3b366cSBram Moolenaar while syn_list =~ '\<match\>\s\+\/' 627ad3b366cSBram Moolenaar if syn_list =~ 'perlElseIfError' 628ad3b366cSBram Moolenaar let syn_list = syn_list 629ad3b366cSBram Moolenaar endif 630ad3b366cSBram Moolenaar " Check if the match has words at least 3 characters long 631ad3b366cSBram Moolenaar if syn_list =~ '\<match \/\zs.\{-}\<\w\{3,}\>.\{-}\ze\\\@<!\/\%(\%(ms\|me\|hs\|he\|rs\|re\|lc\)\S\+\)\?\s\+' 632ad3b366cSBram Moolenaar " Remove everything after / and before the first \( 633ad3b366cSBram Moolenaar let syn_list = substitute( syn_list, '\<match \/\zs.\{-}\ze\\%\?(.\{-}\\\@<!\/\%(\%(ms\|me\|hs\|he\|rs\|re\|lc\)\S\+\)\?\s\+', '', 'g' ) 634ad3b366cSBram Moolenaar " Remove everything after \) and up to the ending / 635ad3b366cSBram Moolenaar let syn_list = substitute( syn_list, '\<match \/.\{-}\\)\zs.\{-}\ze\/\%(\%(ms\|me\|hs\|he\|rs\|re\|lc\)\S\+\)\?\s\+', '', 'g' ) 636ad3b366cSBram Moolenaar 637ad3b366cSBram Moolenaar " Remove any character classes 638ad3b366cSBram Moolenaar " let syn_list = substitute( syn_list, '\<match /\zs.\{-}\[[^]]*\].\{-}\ze\/ ', '', 'g' ) 639ad3b366cSBram Moolenaar let syn_list = substitute( syn_list, '\%(\<match \/[^/]\{-}\)\@<=\[[^]]*\]\ze.\{-}\\\@<!\/\%(\%(ms\|me\|hs\|he\|rs\|re\|lc\)\S\+\)\?', '', 'g' ) 640ad3b366cSBram Moolenaar " Remove any words < 3 characters 641ad3b366cSBram Moolenaar let syn_list = substitute( syn_list, '\%(\<match \/[^/]\{-}\)\@<=\<\w\{1,2}\>\ze.\{-}\\\@<!\/\%(\%(ms\|me\|hs\|he\|rs\|re\|lc\)\S\+\)\?\s\+', '', 'g' ) 642ad3b366cSBram Moolenaar " Remove all non-word characters 643ad3b366cSBram Moolenaar " let syn_list = substitute( syn_list, '\<match /\zs.\{-}\<\W\+\>.\{-}\ze\/ ', "", 'g' ) 644ad3b366cSBram Moolenaar " let syn_list = substitute( syn_list, '\%(\<match \/[^/]\{-}\)\@<=\W\+\ze.\{-}\/ ', ' ', 'g' ) 64556c860c3SBram Moolenaar " Do this by using the outer substitute() call to gather all 646ad3b366cSBram Moolenaar " text between the match /.../ tags. 647ad3b366cSBram Moolenaar " The inner substitute() call operates on the text selected 648ad3b366cSBram Moolenaar " and replaces all non-word characters. 649ad3b366cSBram Moolenaar let syn_list = substitute( syn_list, '\<match \/\zs\(.\{-}\)\ze\\\@<!\/\%(\%(ms\|me\|hs\|he\|rs\|re\|lc\)\S\+\)\?\s\+' 650ad3b366cSBram Moolenaar \ , '\=substitute(submatch(1), "\\W\\+", " ", "g")' 651ad3b366cSBram Moolenaar \ , 'g' ) 652ad3b366cSBram Moolenaar " Remove the match / / syntax 653ad3b366cSBram Moolenaar let syn_list = substitute( syn_list, '\<match \/\(.\{-}\)\/\%(\%(ms\|me\|hs\|he\|rs\|re\|lc\)\S\+\)\?\s\+', '\1', 'g' ) 654ad3b366cSBram Moolenaar else 655ad3b366cSBram Moolenaar " No words long enough, remove the match 656ad3b366cSBram Moolenaar " Remove the match syntax 657ad3b366cSBram Moolenaar " let syn_list = substitute( syn_list, '\<match \/[^\/]*\/\%(\%(ms\|me\|hs\|he\|rs\|re\|lc\)\S\+\)\?\s\+', '', 'g' ) 658ad3b366cSBram Moolenaar let syn_list = substitute( syn_list, '\<match \/\%(.\{-}\)\?\/\%(\%(ms\|me\|hs\|he\|rs\|re\|lc\)\S\+\)\?\s\+', '', 'g' ) 659ad3b366cSBram Moolenaar endif 660ad3b366cSBram Moolenaar if syn_list =~ '\<match\>\s\+\/' 661ad3b366cSBram Moolenaar " Problem removing the match / / tags 662ad3b366cSBram Moolenaar let syn_list = '' 663ad3b366cSBram Moolenaar endif 664ad3b366cSBram Moolenaar endwhile 665ad3b366cSBram Moolenaar 666ad3b366cSBram Moolenaar 667f1568ecaSBram Moolenaar " Now strip off the newline + blank space + contained. 668f1568ecaSBram Moolenaar " Also include lines with nextgroup=@someName skip_key_words syntax_element 669ad3b366cSBram Moolenaar " \ syn_list, '\%(^\|\n\)\@<=\s*\<\(contained\|nextgroup=\)' 670ad3b366cSBram Moolenaar " \ syn_list, '\%(^\|\n\)\@<=\s*\<\(contained\|nextgroup=[@a-zA-Z,]*\)' 67197e8f356SBram Moolenaar let syn_list = substitute( 672ad3b366cSBram Moolenaar \ syn_list, '\<\(contained\|nextgroup=[@a-zA-Z,]*\)' 673f1568ecaSBram Moolenaar \ , "", 'g' 674f1568ecaSBram Moolenaar \ ) 675f1568ecaSBram Moolenaar 676f1568ecaSBram Moolenaar " This can leave lines like this 677f1568ecaSBram Moolenaar " =@vimMenuList skipwhite onoremenu 678f1568ecaSBram Moolenaar " Strip the special option keywords first 679f1568ecaSBram Moolenaar " :h :syn-skipwhite* 680f1568ecaSBram Moolenaar let syn_list = substitute( 681f1568ecaSBram Moolenaar \ syn_list, '\<\(skipwhite\|skipnl\|skipempty\)\>' 682f1568ecaSBram Moolenaar \ , "", 'g' 683f1568ecaSBram Moolenaar \ ) 684f1568ecaSBram Moolenaar 685f1568ecaSBram Moolenaar " Now remove the remainder of the nextgroup=@someName lines 686f1568ecaSBram Moolenaar let syn_list = substitute( 687f1568ecaSBram Moolenaar \ syn_list, '\%(^\|\n\)\@<=\s*\(@\w\+\)' 68897e8f356SBram Moolenaar \ , "", 'g' 68997e8f356SBram Moolenaar \ ) 6904770d09aSBram Moolenaar 691*4c295027SBram Moolenaar if l:omni_syntax_use_iskeyword == 0 6924770d09aSBram Moolenaar " There are a number of items which have non-word characters in 6934770d09aSBram Moolenaar " them, *'T_F1'*. vim.vim is one such file. 6944770d09aSBram Moolenaar " This will replace non-word characters with spaces. 695*4c295027SBram Moolenaar " setlocal filetype=forth 696*4c295027SBram Moolenaar " let g:omni_syntax_use_iskeyword = 1 697*4c295027SBram Moolenaar " let g:omni_syntax_use_iskeyword_numeric = 1 698*4c295027SBram Moolenaar " You will see entries like 699*4c295027SBram Moolenaar " #>> 700*4c295027SBram Moolenaar " (.local) 701*4c295027SBram Moolenaar " These were found doing a grep in vim82\syntax 702*4c295027SBram Moolenaar " grep iskeyword * 703*4c295027SBram Moolenaar " forth.vim:setlocal iskeyword=!,@,33-35,%,$,38-64,A-Z,91-96,a-z,123-126,128-255 7044770d09aSBram Moolenaar let syn_list = substitute( syn_list, '[^0-9A-Za-z_ ]', ' ', 'g' ) 7054770d09aSBram Moolenaar else 706*4c295027SBram Moolenaar if l:omni_syntax_use_iskeyword_numeric == 1 70797d62497SBram Moolenaar " iskeyword can contain value like this 70897d62497SBram Moolenaar " 38,42,43,45,47-58,60-62,64-90,97-122,_,+,-,*,/,%,<,=,>,:,$,?,!,@-@,94 70997d62497SBram Moolenaar " Numeric values convert to their ASCII equivalent using the 71097d62497SBram Moolenaar " nr2char() function. 71197d62497SBram Moolenaar " & 38 71297d62497SBram Moolenaar " * 42 71397d62497SBram Moolenaar " + 43 71497d62497SBram Moolenaar " - 45 71597d62497SBram Moolenaar " ^ 94 71697d62497SBram Moolenaar " Iterate through all numeric specifications and convert those 71797d62497SBram Moolenaar " to their ascii equivalent ensuring the character is printable. 71897d62497SBram Moolenaar " If so, add it to the list. 71997d62497SBram Moolenaar let accepted_chars = '' 72097d62497SBram Moolenaar for item in split(&iskeyword, ',') 721ad3b366cSBram Moolenaar if item =~ '\d-\d' 72297d62497SBram Moolenaar " This is a character range (ie 47-58), 72397d62497SBram Moolenaar " cycle through each character within the range 72497d62497SBram Moolenaar let [b:start, b:end] = split(item, '-') 72597d62497SBram Moolenaar for range_item in range( b:start, b:end ) 726*4c295027SBram Moolenaar if range_item <= 127 || l:omni_syntax_use_single_byte == 0 72797d62497SBram Moolenaar if nr2char(range_item) =~ '\p' 72897d62497SBram Moolenaar let accepted_chars = accepted_chars . nr2char(range_item) 72997d62497SBram Moolenaar endif 73097d62497SBram Moolenaar endif 73197d62497SBram Moolenaar endfor 73297d62497SBram Moolenaar elseif item =~ '^\d\+$' 73397d62497SBram Moolenaar " Only numeric, translate to a character 734*4c295027SBram Moolenaar if item < 127 || l:omni_syntax_use_single_byte == 0 73597d62497SBram Moolenaar if nr2char(item) =~ '\p' 73697d62497SBram Moolenaar let accepted_chars = accepted_chars . nr2char(item) 73797d62497SBram Moolenaar endif 73897d62497SBram Moolenaar endif 73997d62497SBram Moolenaar else 740*4c295027SBram Moolenaar if char2nr(item) < 127 || l:omni_syntax_use_single_byte == 0 74197d62497SBram Moolenaar if item =~ '\p' 74297d62497SBram Moolenaar let accepted_chars = accepted_chars . item 74397d62497SBram Moolenaar endif 74497d62497SBram Moolenaar endif 74597d62497SBram Moolenaar endif 74697d62497SBram Moolenaar endfor 74797d62497SBram Moolenaar " Escape special regex characters 74834feacbcSBram Moolenaar " Looks like the wrong chars are escaped. In a collection, 74934feacbcSBram Moolenaar " :h /[] 75034feacbcSBram Moolenaar " only `]', `\', `-' and `^' are special: 75134feacbcSBram Moolenaar " let accepted_chars = escape(accepted_chars, '\\/.*$^~[]' ) 75234feacbcSBram Moolenaar let accepted_chars = escape(accepted_chars, ']\-^' ) 75397d62497SBram Moolenaar " Remove all characters that are not acceptable 75497d62497SBram Moolenaar let syn_list = substitute( syn_list, '[^A-Za-z'.accepted_chars.']', ' ', 'g' ) 75597d62497SBram Moolenaar else 7569964e468SBram Moolenaar let accept_chars = ','.&iskeyword.',' 7579964e468SBram Moolenaar " Remove all character ranges 7583577c6faSBram Moolenaar " let accept_chars = substitute(accept_chars, ',[^,]\+-[^,]\+,', ',', 'g') 7593577c6faSBram Moolenaar let accept_chars = substitute(accept_chars, ',\@<=[^,]\+-[^,]\+,', '', 'g') 7609964e468SBram Moolenaar " Remove all numeric specifications 7613577c6faSBram Moolenaar " let accept_chars = substitute(accept_chars, ',\d\{-},', ',', 'g') 7623577c6faSBram Moolenaar let accept_chars = substitute(accept_chars, ',\@<=\d\{-},', '', 'g') 7639964e468SBram Moolenaar " Remove all commas 7649964e468SBram Moolenaar let accept_chars = substitute(accept_chars, ',', '', 'g') 7659964e468SBram Moolenaar " Escape special regex characters 76634feacbcSBram Moolenaar " Looks like the wrong chars are escaped. In a collection, 76734feacbcSBram Moolenaar " :h /[] 76834feacbcSBram Moolenaar " only `]', `\', `-' and `^' are special: 76934feacbcSBram Moolenaar " let accept_chars = escape(accept_chars, '\\/.*$^~[]' ) 77034feacbcSBram Moolenaar let accept_chars = escape(accept_chars, ']\-^' ) 7719964e468SBram Moolenaar " Remove all characters that are not acceptable 7729964e468SBram Moolenaar let syn_list = substitute( syn_list, '[^0-9A-Za-z_'.accept_chars.']', ' ', 'g' ) 7739964e468SBram Moolenaar endif 77497d62497SBram Moolenaar endif 7759964e468SBram Moolenaar 776*4c295027SBram Moolenaar if l:omni_syntax_minimum_length > 0 7779964e468SBram Moolenaar " If the user specified a minimum length, enforce it 778*4c295027SBram Moolenaar let syn_list = substitute(' '.syn_list.' ', ' \S\{,'.l:omni_syntax_minimum_length.'}\ze ', ' ', 'g') 7799964e468SBram Moolenaar endif 7809964e468SBram Moolenaar else 7814770d09aSBram Moolenaar let syn_list = '' 7824770d09aSBram Moolenaar endif 7834770d09aSBram Moolenaar 7844770d09aSBram Moolenaar return syn_list 7854770d09aSBram Moolenaarendfunction 78697d62497SBram Moolenaar 78797d62497SBram Moolenaarfunction! OmniSyntaxShowChars(spec) 78897d62497SBram Moolenaar let result = [] 78997d62497SBram Moolenaar for item in split(a:spec, ',') 79097d62497SBram Moolenaar if len(item) > 1 79197d62497SBram Moolenaar if item == '@-@' 79297d62497SBram Moolenaar call add(result, char2nr(item)) 79397d62497SBram Moolenaar else 79497d62497SBram Moolenaar call extend(result, call('range', split(item, '-'))) 79597d62497SBram Moolenaar endif 79697d62497SBram Moolenaar else 79797d62497SBram Moolenaar if item == '@' " assume this is [A-Za-z] 79897d62497SBram Moolenaar for [c1, c2] in [['A', 'Z'], ['a', 'z']] 79997d62497SBram Moolenaar call extend(result, range(char2nr(c1), char2nr(c2))) 80097d62497SBram Moolenaar endfor 80197d62497SBram Moolenaar else 80297d62497SBram Moolenaar call add(result, char2nr(item)) 80397d62497SBram Moolenaar endif 80497d62497SBram Moolenaar endif 80597d62497SBram Moolenaar endfor 80697d62497SBram Moolenaar return join(map(result, 'nr2char(v:val)'), ', ') 80797d62497SBram Moolenaarendfunction 808*4c295027SBram Moolenaar 80997d62497SBram Moolenaarlet &cpo = s:cpo_save 81097d62497SBram Moolenaarunlet s:cpo_save 811