codekingpro/portable-devtools
115k
1" SQL filetype plugin file2" Language: SQL (Common for Oracle, Microsoft SQL Server, Sybase)3" Version: 12.04" Maintainer: David Fishburn <dfishburn dot vim at gmail dot com>5" Last Change: 2017 Mar 076" 2024 Jan 14 by Vim Project: browsefilter7" 2024 May 18 by Vim Project: set comment options8" 2024 Aug 14 by Vim Project: remove redundant code9" Download: http://vim.sourceforge.net/script.php?script_id=45410 11" For more details please use:12" :h sql.txt13"14" This file should only contain values that are common to all SQL languages15" Oracle, Microsoft SQL Server, Sybase ASA/ASE, MySQL, and so on16" If additional features are required create:17" vimfiles/after/ftplugin/sql.vim (Windows)18" .vim/after/ftplugin/sql.vim (Unix)19" to override and add any of your own settings.20 21 22" This file also creates a command, SQLSetType, which allows you to change23" SQL dialects on the fly. For example, if I open an Oracle SQL file, it24" is color highlighted appropriately. If I open an Informix SQL file, it25" will still be highlighted according to Oracles settings. By running:26" :SQLSetType sqlinformix27"28" All files called sqlinformix.vim will be loaded from the indent and syntax29" directories. This allows you to easily flip SQL dialects on a per file30" basis. NOTE: you can also use completion:31" :SQLSetType <tab>32"33" To change the default dialect, add the following to your vimrc:34" let g:sql_type_default = 'sqlanywhere'35"36" This file also creates a command, SQLGetType, which allows you to37" determine what the current dialect is in use.38" :SQLGetType39"40" History41"42" Version 12.0 (April 2013)43"44" NF: Added support for "BEGIN TRY ... END TRY ... BEGIN CATCH ... END CATCH45" BF: This plugin is designed to be used with other plugins to enable the 46" SQL completion with Perl, Python, Java, ... The loading mechanism 47" was not checking if the SQL objects were created, which can lead to 48" the plugin not loading the SQL support.49"50" Version 11.0 (May 2013)51"52" NF: Updated to use SyntaxComplete's new regex support for syntax groups.53"54" Version 10.0 (Dec 2012)55"56" NF: Changed all maps to use noremap instead of must map57" NF: Changed all visual maps to use xnoremap instead of vnoremap as they58" should only be used in visual mode and not select mode.59" BF: Most of the maps were using doubled up backslashes before they were60" changed to using the search() function, which meant they no longer61" worked.62"63" Version 9.064"65" NF: Completes 'b:undo_ftplugin'66" BF: Correctly set cpoptions when creating script67"68" Version 8.069"70" NF: Improved the matchit plugin regex (Talek)71"72" Version 7.073"74" NF: Calls the sqlcomplete#ResetCacheSyntax() function when calling75" SQLSetType.76"77" Version 6.078"79" NF: Adds the command SQLGetType80"81" Version 5.082"83" NF: Adds the ability to choose the keys to control SQL completion, just add84" the following to your .vimrc:85" let g:ftplugin_sql_omni_key = '<C-C>'86" let g:ftplugin_sql_omni_key_right = '<Right>'87" let g:ftplugin_sql_omni_key_left = '<Left>'88"89" BF: format-options - Auto-wrap comments using textwidth was turned off90" by mistake.91 92 93" Only do this when not done yet for this buffer94" This ftplugin can be used with other ftplugins. So ensure loading95" happens if all elements of this plugin have not yet loaded.96if exists("b:did_ftplugin")97 finish98endif99 100" Don't load another plugin for this buffer101let b:did_ftplugin = 1102 103let s:save_cpo = &cpo104set cpo&vim105 106let b:undo_ftplugin = "setl comments< commentstring< formatoptions< define< omnifunc<" .107 \ " | unlet! b:browsefilter b:match_words"108 109" Disable autowrapping for code, but enable for comments110" t Auto-wrap text using textwidth111" c Auto-wrap comments using textwidth, inserting the current comment112" leader automatically.113setlocal formatoptions-=t114setlocal formatoptions+=c115 116setlocal comments=:-- commentstring=--\ %s117 118" Functions/Commands to allow the user to change SQL syntax dialects119" through the use of :SQLSetType <tab> for completion.120" This works with both Vim 6 and 7.121 122if !exists("*SQL_SetType")123 " NOTE: You cannot use function! since this file can be124 " sourced from within this function. That will result in125 " an error reported by Vim.126 function SQL_GetList(ArgLead, CmdLine, CursorPos)127 128 if !exists('s:sql_list')129 " Grab a list of files that contain "sql" in their names130 let list_indent = globpath(&runtimepath, 'indent/*sql*')131 let list_syntax = globpath(&runtimepath, 'syntax/*sql*')132 let list_ftplugin = globpath(&runtimepath, 'ftplugin/*sql*')133 134 let sqls = "\n".list_indent."\n".list_syntax."\n".list_ftplugin."\n"135 136 " Strip out everything (path info) but the filename137 " Regex138 " From between two newline characters139 " Non-greedily grab all characters140 " Followed by a valid filename \w\+\.\w\+ (sql.vim)141 " Followed by a newline, but do not include the newline142 "143 " Replace it with just the filename (get rid of PATH)144 "145 " Recursively, since there are many filenames that contain146 " the word SQL in the indent, syntax and ftplugin directory147 let sqls = substitute( sqls,148 \ '[\n]\%(.\{-}\)\(\w\+\.\w\+\)\n\@=',149 \ '\1\n',150 \ 'g'151 \ )152 153 " Remove duplicates, since sqlanywhere.vim can exist in the154 " syntax, indent and ftplugin directory, yet we only want155 " to display the option once156 let index = match(sqls, '.\{-}\ze\n')157 while index > -1158 " Get the first filename159 let file = matchstr(sqls, '.\{-}\ze\n', index)160 " Recursively replace any *other* occurrence of that161 " filename with nothing (ie remove it)162 let sqls = substitute(sqls, '\%>'.(index+strlen(file)).'c\<'.file.'\>\n', '', 'g')163 " Move on to the next filename164 let index = match(sqls, '.\{-}\ze\n', (index+strlen(file)+1))165 endwhile166 167 " Sort the list if using version 7168 if v:version >= 700169 let mylist = split(sqls, "\n")170 let mylist = sort(mylist)171 let sqls = join(mylist, "\n")172 endif173 174 let s:sql_list = sqls175 endif176 177 return s:sql_list178 179 endfunction180 181 function SQL_SetType(name)182 183 " User has decided to override default SQL scripts and184 " specify a vendor specific version185 " (ie Oracle, Informix, SQL Anywhere, ...)186 " So check for an remove any settings that prevent the187 " scripts from being executed, and then source the188 " appropriate Vim scripts.189 if exists("b:did_ftplugin")190 unlet b:did_ftplugin191 endif192 if exists("b:current_syntax")193 " echomsg 'SQLSetType - clearing syntax'194 syntax clear195 if exists("b:current_syntax")196 unlet b:current_syntax197 endif198 endif199 if exists("b:did_indent")200 " echomsg 'SQLSetType - clearing indent'201 unlet b:did_indent202 " Set these values to their defaults203 setlocal indentkeys&204 setlocal indentexpr&205 endif206 207 " Ensure the name is in the correct format208 let new_sql_type = substitute(a:name,209 \ '\s*\([^\.]\+\)\(\.\w\+\)\?', '\L\1', '')210 211 " Do not specify a buffer local variable if it is212 " the default value213 if new_sql_type == 'sql'214 let new_sql_type = 'sqloracle'215 endif216 let b:sql_type_override = new_sql_type217 218 " Remove any cached SQL since a new syntax will have different219 " items and groups220 if !exists('g:loaded_sql_completion') || g:loaded_sql_completion >= 100221 call sqlcomplete#ResetCacheSyntax()222 endif223 224 " Vim will automatically source the correct files if we225 " change the filetype. You cannot do this with setfiletype226 " since that command will only execute if a filetype has227 " not already been set. In this case we want to override228 " the existing filetype.229 let &filetype = 'sql'230 231 if b:sql_compl_savefunc != ""232 " We are changing the filetype to SQL from some other filetype233 " which had OMNI completion defined. We need to activate the234 " SQL completion plugin in order to cache some of the syntax items235 " while the syntax rules for SQL are active.236 call sqlcomplete#PreCacheSyntax()237 endif238 endfunction239 command! -nargs=* -complete=custom,SQL_GetList SQLSetType :call SQL_SetType(<q-args>)240 241endif242 243" Functions/Commands to allow the user determine current SQL syntax dialect244" This works with both Vim 6 and 7.245 246if !exists("*SQL_GetType")247 function SQL_GetType()248 if exists('b:sql_type_override')249 echomsg "Current SQL dialect in use:".b:sql_type_override250 else251 echomsg "Current SQL dialect in use:".g:sql_type_default252 endif253 endfunction254 command! -nargs=0 SQLGetType :call SQL_GetType()255endif256 257if exists("b:sql_type_override")258 " echo 'sourcing buffer ftplugin/'.b:sql_type_override.'.vim'259 if globpath(&runtimepath, 'ftplugin/'.b:sql_type_override.'.vim') != ''260 exec 'runtime ftplugin/'.b:sql_type_override.'.vim'261 " else262 " echomsg 'ftplugin/'.b:sql_type_override.' not exist, using default'263 endif264elseif exists("g:sql_type_default")265 " echo 'sourcing global ftplugin/'.g:sql_type_default.'.vim'266 if globpath(&runtimepath, 'ftplugin/'.g:sql_type_default.'.vim') != ''267 exec 'runtime ftplugin/'.g:sql_type_default.'.vim'268 " else269 " echomsg 'ftplugin/'.g:sql_type_default.'.vim not exist, using default'270 endif271endif272 273" Win32 and GTK can filter files in the browse dialog274if (has("gui_win32") || has("gui_gtk")) && !exists("b:browsefilter")275 let b:browsefilter = "SQL Files (*.sql)\t*.sql\n"276 if has("win32")277 let b:browsefilter .= "All Files (*.*)\t*\n"278 else279 let b:browsefilter .= "All Files (*)\t*\n"280 endif281endif282 283" Some standard expressions for use with the matchit strings284let s:notend = '\%(\<end\s\+\)\@<!'285let s:when_no_matched_or_others = '\%(\<when\>\%(\s\+\%(\%(\<not\>\s\+\)\?<matched\>\)\|\<others\>\)\@!\)'286let s:or_replace = '\%(or\s\+replace\s\+\)\?'287 288" Define patterns for the matchit macro289if !exists("b:match_words")290 " SQL is generally case insensitive291 let b:match_ignorecase = 1292 293 " Handle the following:294 " if295 " elseif | elsif296 " else [if]297 " end if298 "299 " [while condition] loop300 " leave301 " break302 " continue303 " exit304 " end loop305 "306 " for307 " leave308 " break309 " continue310 " exit311 " end loop312 "313 " do314 " statements315 " doend316 "317 " case318 " when319 " when320 " default321 " end case322 "323 " merge324 " when not matched325 " when matched326 "327 " EXCEPTION328 " WHEN column_not_found THEN329 " WHEN OTHERS THEN330 "331 " begin try332 " end try333 " begin catch334 " end catch335 "336 " create[ or replace] procedure|function|event337 " \ '^\s*\<\%(do\|for\|while\|loop\)\>.*:'.338 339 " For ColdFusion support340 setlocal matchpairs+=<:>341 let b:match_words = &matchpairs .342 \ ',\%(\<begin\)\%(\s\+\%(try\|catch\)\>\)\@!:\<end\>\W*$,'.343 \344 \ '\<begin\s\+try\>:'.345 \ '\<end\s\+try\>:'.346 \ '\<begin\s\+catch\>:'.347 \ '\<end\s\+catch\>,'.348 \349 \ s:notend . '\<if\>:'.350 \ '\<elsif\>\|\<elseif\>\|\<else\>:'.351 \ '\<end\s\+if\>,'.352 \353 \ '\(^\s*\)\@<=\(\<\%(do\|for\|while\|loop\)\>.*\):'.354 \ '\%(\<exit\>\|\<leave\>\|\<break\>\|\<continue\>\):'.355 \ '\%(\<doend\>\|\%(\<end\s\+\%(for\|while\|loop\>\)\)\),'.356 \357 \ '\%('. s:notend . '\<case\>\):'.358 \ '\%('.s:when_no_matched_or_others.'\):'.359 \ '\%(\<when\s\+others\>\|\<end\s\+case\>\),' .360 \361 \ '\<merge\>:' .362 \ '\<when\s\+not\s\+matched\>:' .363 \ '\<when\s\+matched\>,' .364 \365 \ '\%(\<create\s\+' . s:or_replace . '\)\?'.366 \ '\%(function\|procedure\|event\):'.367 \ '\<returns\?\>'368 " \ '\<begin\>\|\<returns\?\>:'.369 " \ '\<end\>\(;\)\?\s*$'370 " \ '\<exception\>:'.s:when_no_matched_or_others.371 " \ ':\<when\s\+others\>,'.372 "373 " \ '\%(\<exception\>\|\%('. s:notend . '\<case\>\)\):'.374 " \ '\%(\<default\>\|'.s:when_no_matched_or_others.'\):'.375 " \ '\%(\%(\<when\s\+others\>\)\|\<end\s\+case\>\),' .376endif377 378" Define how to find the macro definition of a variable using the various379" [d, [D, [_CTRL_D and so on features380" Match these values ignoring case381" ie DECLARE varname INTEGER382let &l:define = '\c\<\(VARIABLE\|DECLARE\|IN\|OUT\|INOUT\)\>'383 384 385" Mappings to move to the next BEGIN ... END block386" \W - no characters or digits387nnoremap <buffer> <silent> ]] :call search('\c^\s*begin\>', 'W' )<CR>388nnoremap <buffer> <silent> [[ :call search('\c^\s*begin\>', 'bW' )<CR>389nnoremap <buffer> <silent> ][ :call search('\c^\s*end\W*$', 'W' )<CR>390nnoremap <buffer> <silent> [] :call search('\c^\s*end\W*$', 'bW' )<CR>391xnoremap <buffer> <silent> ]] :<C-U>exec "normal! gv"<Bar>call search('\c^\s*begin\>', 'W' )<CR>392xnoremap <buffer> <silent> [[ :<C-U>exec "normal! gv"<Bar>call search('\c^\s*begin\>', 'bW' )<CR>393xnoremap <buffer> <silent> ][ :<C-U>exec "normal! gv"<Bar>call search('\c^\s*end\W*$', 'W' )<CR>394xnoremap <buffer> <silent> [] :<C-U>exec "normal! gv"<Bar>call search('\c^\s*end\W*$', 'bW' )<CR>395 396 397" By default only look for CREATE statements, but allow398" the user to override399if !exists('g:ftplugin_sql_statements')400 let g:ftplugin_sql_statements = 'create'401endif402 403" Predefined SQL objects what are used by the below mappings using404" the ]} style maps.405" This global variable allows the users to override its value406" from within their vimrc.407" Note, you cannot use \?, since these patterns can be used to search408" backwards, you must use \{,1}409if !exists('g:ftplugin_sql_objects')410 let g:ftplugin_sql_objects = 'function,procedure,event,' .411 \ '\(existing\\|global\s\+temporary\s\+\)\{,1}' .412 \ 'table,trigger' .413 \ ',schema,service,publication,database,datatype,domain' .414 \ ',index,subscription,synchronization,view,variable'415endif416 417" Key to trigger SQL completion418if !exists('g:ftplugin_sql_omni_key')419 let g:ftplugin_sql_omni_key = '<C-C>'420endif421" Key to trigger drill into column list422if !exists('g:ftplugin_sql_omni_key_right')423 let g:ftplugin_sql_omni_key_right = '<Right>'424endif425" Key to trigger drill out of column list426if !exists('g:ftplugin_sql_omni_key_left')427 let g:ftplugin_sql_omni_key_left = '<Left>'428endif429 430" Replace all ,'s with bars, except ones with numbers after them.431" This will most likely be a \{,1} string.432let s:ftplugin_sql_objects =433 \ '\c^\s*' .434 \ '\(\(' .435 \ substitute(g:ftplugin_sql_statements, ',\d\@!', '\\\\|', 'g') .436 \ '\)\s\+\(or\s\+replace\s\+\)\{,1}\)\{,1}' .437 \ '\<\(' .438 \ substitute(g:ftplugin_sql_objects, ',\d\@!', '\\\\|', 'g') .439 \ '\)\>'440 441" Mappings to move to the next CREATE ... block442exec "nnoremap <buffer> <silent> ]} :call search('".s:ftplugin_sql_objects."', 'W')<CR>"443exec "nnoremap <buffer> <silent> [{ :call search('".s:ftplugin_sql_objects."', 'bW')<CR>"444" Could not figure out how to use a :call search() string in visual mode445" without it ending visual mode446" Unfortunately, this will add a entry to the search history447exec 'xnoremap <buffer> <silent> ]} /'.s:ftplugin_sql_objects.'<CR>'448exec 'xnoremap <buffer> <silent> [{ ?'.s:ftplugin_sql_objects.'<CR>'449 450" Mappings to move to the next COMMENT451"452" Had to double the \ for the \| separator since this has a special453" meaning on maps454let b:comment_leader = '\(--\\|\/\/\\|\*\\|\/\*\\|\*\/\)'455" Find the start of the next comment456let b:comment_start = '^\(\s*'.b:comment_leader.'.*\n\)\@<!'.457 \ '\(\s*'.b:comment_leader.'\)'458" Find the end of the previous comment459let b:comment_end = '\(^\s*'.b:comment_leader.'.*\n\)'.460 \ '\(^\s*'.b:comment_leader.'\)\@!'461" Skip over the comment462let b:comment_jump_over = "call search('".463 \ '^\(\s*'.b:comment_leader.'.*\n\)\@<!'.464 \ "', 'W')"465let b:comment_skip_back = "call search('".466 \ '^\(\s*'.b:comment_leader.'.*\n\)\@<!'.467 \ "', 'bW')"468" Move to the start and end of comments469exec 'nnoremap <silent><buffer> ]" :call search('."'".b:comment_start."'".', "W" )<CR>'470exec 'nnoremap <silent><buffer> [" :call search('."'".b:comment_end."'".', "W" )<CR>'471exec 'xnoremap <silent><buffer> ]" :<C-U>exec "normal! gv"<Bar>call search('."'".b:comment_start."'".', "W" )<CR>'472exec 'xnoremap <silent><buffer> [" :<C-U>exec "normal! gv"<Bar>call search('."'".b:comment_end."'".', "W" )<CR>'473 474" Comments can be of the form:475" /*476" *477" */478" or479" --480" or481" //482setlocal comments=s1:/*,mb:*,ex:*/,:--,://483 484" Set completion with CTRL-X CTRL-O to autoloaded function.485if exists('&omnifunc')486 " Since the SQL completion plugin can be used in conjunction487 " with other completion filetypes it must record the previous488 " OMNI function prior to setting up the SQL OMNI function489 let b:sql_compl_savefunc = &omnifunc490 491 " Source it to determine its version492 runtime autoload/sqlcomplete.vim493 " This is used by the sqlcomplete.vim plugin494 " Source it for its global functions495 runtime autoload/syntaxcomplete.vim496 497 setlocal omnifunc=sqlcomplete#Complete498 " Prevent the intellisense plugin from loading499 let b:sql_vis = 1500 if !exists('g:omni_sql_no_default_maps')501 let regex_extra = ''502 if exists('g:loaded_syntax_completion') && exists('g:loaded_sql_completion')503 if g:loaded_syntax_completion > 120 && g:loaded_sql_completion > 140504 let regex_extra = '\\w*'505 endif506 endif507 " Static maps which use populate the completion list508 " using Vim's syntax highlighting rules509 exec 'inoremap <buffer> '.g:ftplugin_sql_omni_key.'a <C-\><C-O>:call sqlcomplete#Map("syntax")<CR><C-X><C-O>'510 exec 'inoremap <buffer> '.g:ftplugin_sql_omni_key.'k <C-\><C-O>:call sqlcomplete#Map("sqlKeyword'.regex_extra.'")<CR><C-X><C-O>'511 exec 'inoremap <buffer> '.g:ftplugin_sql_omni_key.'f <C-\><C-O>:call sqlcomplete#Map("sqlFunction'.regex_extra.'")<CR><C-X><C-O>'512 exec 'inoremap <buffer> '.g:ftplugin_sql_omni_key.'o <C-\><C-O>:call sqlcomplete#Map("sqlOption'.regex_extra.'")<CR><C-X><C-O>'513 exec 'inoremap <buffer> '.g:ftplugin_sql_omni_key.'T <C-\><C-O>:call sqlcomplete#Map("sqlType'.regex_extra.'")<CR><C-X><C-O>'514 exec 'inoremap <buffer> '.g:ftplugin_sql_omni_key.'s <C-\><C-O>:call sqlcomplete#Map("sqlStatement'.regex_extra.'")<CR><C-X><C-O>'515 " Dynamic maps which use populate the completion list516 " using the dbext.vim plugin517 exec 'inoremap <buffer> '.g:ftplugin_sql_omni_key.'t <C-\><C-O>:call sqlcomplete#Map("table")<CR><C-X><C-O>'518 exec 'inoremap <buffer> '.g:ftplugin_sql_omni_key.'p <C-\><C-O>:call sqlcomplete#Map("procedure")<CR><C-X><C-O>'519 exec 'inoremap <buffer> '.g:ftplugin_sql_omni_key.'v <C-\><C-O>:call sqlcomplete#Map("view")<CR><C-X><C-O>'520 exec 'inoremap <buffer> '.g:ftplugin_sql_omni_key.'c <C-\><C-O>:call sqlcomplete#Map("column")<CR><C-X><C-O>'521 exec 'inoremap <buffer> '.g:ftplugin_sql_omni_key.'l <C-\><C-O>:call sqlcomplete#Map("column_csv")<CR><C-X><C-O>'522 " The next 3 maps are only to be used while the completion window is523 " active due to the <CR> at the beginning of the map524 exec 'inoremap <buffer> '.g:ftplugin_sql_omni_key.'L <C-Y><C-\><C-O>:call sqlcomplete#Map("column_csv")<CR><C-X><C-O>'525 " <C-Right> is not recognized on most Unix systems, so only create526 " these additional maps on the Windows platform.527 " If you would like to use these maps, choose a different key and make528 " the same map in your vimrc.529 " if has('win32')530 exec 'inoremap <buffer> '.g:ftplugin_sql_omni_key_right.' <C-R>=sqlcomplete#DrillIntoTable()<CR>'531 exec 'inoremap <buffer> '.g:ftplugin_sql_omni_key_left.' <C-R>=sqlcomplete#DrillOutOfColumns()<CR>'532 " endif533 " Remove any cached items useful for schema changes534 exec 'inoremap <buffer> '.g:ftplugin_sql_omni_key.'R <C-\><C-O>:call sqlcomplete#Map("resetCache")<CR><C-X><C-O>'535 endif536 537 if b:sql_compl_savefunc != ""538 " We are changing the filetype to SQL from some other filetype539 " which had OMNI completion defined. We need to activate the540 " SQL completion plugin in order to cache some of the syntax items541 " while the syntax rules for SQL are active.542 call sqlcomplete#ResetCacheSyntax()543 call sqlcomplete#PreCacheSyntax()544 endif545endif546 547let &cpo = s:save_cpo548unlet s:save_cpo549 550" vim:sw=4:551 