" Last Change: 2013 May 13
" Download: http://vim.sourceforge.net/script.php?script_id=454
" For more details please use:
" :h sql.txt
"
" This file should only contain values that are common to all SQL languages
" Oracle, Microsoft SQL Server, Sybase ASA/ASE, MySQL, and so on
" If additional features are required create:
" vimfiles/after/ftplugin/sql.vim (Windows)
" .vim/after/ftplugin/sql.vim (Unix)
" to override and add any of your own settings.
" This file also creates a command, SQLSetType, which allows you to change
" SQL dialects on the fly. For example, if I open an Oracle SQL file, it
" is color highlighted appropriately. If I open an Informix SQL file, it
" will still be highlighted according to Oracles settings. By running:
" :SQLSetType sqlinformix
"
" All files called sqlinformix.vim will be loaded from the indent and syntax
" directories. This allows you to easily flip SQL dialects on a per file
" basis. NOTE: you can also use completion:
" :SQLSetType
"
" To change the default dialect, add the following to your vimrc:
" let g:sql_type_default = 'sqlanywhere'
"
" This file also creates a command, SQLGetType, which allows you to
" determine what the current dialect is in use.
" :SQLGetType
"
" History
"
" Version 11.0 (May 2013)
"
" NF: Updated to use SyntaxComplete's new regex support for syntax groups.
"
" Version 10.0 (Dec 2012)
"
" NF: Changed all maps to use noremap instead of must map
" NF: Changed all visual maps to use xnoremap instead of vnoremap as they
" should only be used in visual mode and not select mode.
" BF: Most of the maps were using doubled up backslashes before they were
" changed to using the search() function, which meant they no longer
" worked.
"
" Version 9.0
"
" NF: Completes 'b:undo_ftplugin'
" BF: Correctly set cpoptions when creating script
"
" Version 8.0
"
" NF: Improved the matchit plugin regex (Talek)
"
" Version 7.0
"
" NF: Calls the sqlcomplete#ResetCacheSyntax() function when calling
" SQLSetType.
"
" Version 6.0
"
" NF: Adds the command SQLGetType
"
" Version 5.0
"
" NF: Adds the ability to choose the keys to control SQL completion, just add
" the following to your .vimrc:
" let g:ftplugin_sql_omni_key = ''
" let g:ftplugin_sql_omni_key_right = ''
" let g:ftplugin_sql_omni_key_left = ''
"
" BF: format-options - Auto-wrap comments using textwidth was turned off
" by mistake.
" Only do this when not done yet for this buffer
if exists("b:did_ftplugin")
finish
endif
let s:save_cpo = &cpo
set cpo&vim
" Disable autowrapping for code, but enable for comments
" t Auto-wrap text using textwidth
" c Auto-wrap comments using textwidth, inserting the current comment
" leader automatically.
setlocal formatoptions-=t
setlocal formatoptions+=c
" Functions/Commands to allow the user to change SQL syntax dialects
" through the use of :SQLSetType for completion.
" This works with both Vim 6 and 7.
if !exists("*SQL_SetType")
" NOTE: You cannot use function! since this file can be
" sourced from within this function. That will result in
" an error reported by Vim.
function SQL_GetList(ArgLead, CmdLine, CursorPos)
if !exists('s:sql_list')
" Grab a list of files that contain "sql" in their names
let list_indent = globpath(&runtimepath, 'indent/*sql*')
let list_syntax = globpath(&runtimepath, 'syntax/*sql*')
let list_ftplugin = globpath(&runtimepath, 'ftplugin/*sql*')
let sqls = "\n".list_indent."\n".list_syntax."\n".list_ftplugin."\n"
" Strip out everything (path info) but the filename
" Regex
" From between two newline characters
" Non-greedily grab all characters
" Followed by a valid filename \w\+\.\w\+ (sql.vim)
" Followed by a newline, but do not include the newline
"
" Replace it with just the filename (get rid of PATH)
"
" Recursively, since there are many filenames that contain
" the word SQL in the indent, syntax and ftplugin directory
let sqls = substitute( sqls,
\ '[\n]\%(.\{-}\)\(\w\+\.\w\+\)\n\@=',
\ '\1\n',
\ 'g'
\ )
" Remove duplicates, since sqlanywhere.vim can exist in the
" sytax, indent and ftplugin directory, yet we only want
" to display the option once
let index = match(sqls, '.\{-}\ze\n')
while index > -1
" Get the first filename
let file = matchstr(sqls, '.\{-}\ze\n', index)
" Recursively replace any *other* occurrence of that
" filename with nothing (ie remove it)
let sqls = substitute(sqls, '\%>'.(index+strlen(file)).'c\<'.file.'\>\n', '', 'g')
" Move on to the next filename
let index = match(sqls, '.\{-}\ze\n', (index+strlen(file)+1))
endwhile
" Sort the list if using version 7
if v:version >= 700
let mylist = split(sqls, "\n")
let mylist = sort(mylist)
let sqls = join(mylist, "\n")
endif
let s:sql_list = sqls
endif
return s:sql_list
endfunction
function SQL_SetType(name)
" User has decided to override default SQL scripts and
" specify a vendor specific version
" (ie Oracle, Informix, SQL Anywhere, ...)
" So check for an remove any settings that prevent the
" scripts from being executed, and then source the
" appropriate Vim scripts.
if exists("b:did_ftplugin")
unlet b:did_ftplugin
endif
if exists("b:current_syntax")
" echomsg 'SQLSetType - clearing syntax'
syntax clear
endif
if exists("b:did_indent")
" echomsg 'SQLSetType - clearing indent'
unlet b:did_indent
" Set these values to their defaults
setlocal indentkeys&
setlocal indentexpr&
endif
" Ensure the name is in the correct format
let new_sql_type = substitute(a:name,
\ '\s*\([^\.]\+\)\(\.\w\+\)\?', '\L\1', '')
" Do not specify a buffer local variable if it is
" the default value
if new_sql_type == 'sql'
let new_sql_type = 'sqloracle'
endif
let b:sql_type_override = new_sql_type
" Remove any cached SQL since a new sytax will have different
" items and groups
if !exists('g:loaded_sql_completion') || g:loaded_sql_completion >= 100
call sqlcomplete#ResetCacheSyntax()
endif
" Vim will automatically source the correct files if we
" change the filetype. You cannot do this with setfiletype
" since that command will only execute if a filetype has
" not already been set. In this case we want to override
" the existing filetype.
let &filetype = 'sql'
if b:sql_compl_savefunc != ""
" We are changing the filetype to SQL from some other filetype
" which had OMNI completion defined. We need to activate the
" SQL completion plugin in order to cache some of the syntax items
" while the syntax rules for SQL are active.
call sqlcomplete#PreCacheSyntax()
endif
endfunction
command! -nargs=* -complete=custom,SQL_GetList SQLSetType :call SQL_SetType()
endif
" Functions/Commands to allow the user determine current SQL syntax dialect
" This works with both Vim 6 and 7.
if !exists("*SQL_GetType")
function SQL_GetType()
if exists('b:sql_type_override')
echomsg "Current SQL dialect in use:".b:sql_type_override
else
echomsg "Current SQL dialect in use:".g:sql_type_default
endif
endfunction
command! -nargs=0 SQLGetType :call SQL_GetType()
endif
if exists("b:sql_type_override")
" echo 'sourcing buffer ftplugin/'.b:sql_type_override.'.vim'
if globpath(&runtimepath, 'ftplugin/'.b:sql_type_override.'.vim') != ''
exec 'runtime ftplugin/'.b:sql_type_override.'.vim'
" else
" echomsg 'ftplugin/'.b:sql_type_override.' not exist, using default'
endif
elseif exists("g:sql_type_default")
" echo 'sourcing global ftplugin/'.g:sql_type_default.'.vim'
if globpath(&runtimepath, 'ftplugin/'.g:sql_type_default.'.vim') != ''
exec 'runtime ftplugin/'.g:sql_type_default.'.vim'
" else
" echomsg 'ftplugin/'.g:sql_type_default.'.vim not exist, using default'
endif
endif
" If the above runtime command succeeded, do not load the default settings
if exists("b:did_ftplugin")
finish
endif
let b:undo_ftplugin = "setl comments< formatoptions< define< omnifunc<" .
\ " | unlet! b:browsefilter b:match_words"
" Don't load another plugin for this buffer
let b:did_ftplugin = 1
let b:current_ftplugin = 'sql'
" Win32 can filter files in the browse dialog
if has("gui_win32") && !exists("b:browsefilter")
let b:browsefilter = "SQL Files (*.sql)\t*.sql\n" .
\ "All Files (*.*)\t*.*\n"
endif
" Some standard expressions for use with the matchit strings
let s:notend = '\%(\.*:'.
" For ColdFusion support
setlocal matchpairs+=<:>
let b:match_words = &matchpairs .
\ ',\:\\W*$,'.
\
\ s:notend . '\:'.
\ '\\|\\|\:'.
\ '\,'.
\
\ '\(^\s*\)\@<=\(\<\%(do\|for\|while\|loop\)\>.*\):'.
\ '\%(\\|\\|\\|\\):'.
\ '\%(\\|\%(\\)\)\),'.
\
\ '\%('. s:notend . '\\):'.
\ '\%('.s:when_no_matched_or_others.'\):'.
\ '\%(\\|\\),' .
\
\ '\:' .
\ '\:' .
\ '\,' .
\
\ '\%(\'
" \ '\\|\:'.
" \ '\\(;\)\?\s*$'
" \ '\:'.s:when_no_matched_or_others.
" \ ':\,'.
"
" \ '\%(\\|\%('. s:notend . '\\)\):'.
" \ '\%(\\|'.s:when_no_matched_or_others.'\):'.
" \ '\%(\%(\\)\|\\),' .
endif
" Define how to find the macro definition of a variable using the various
" [d, [D, [_CTRL_D and so on features
" Match these values ignoring case
" ie DECLARE varname INTEGER
let &l:define = '\c\<\(VARIABLE\|DECLARE\|IN\|OUT\|INOUT\)\>'
" Mappings to move to the next BEGIN ... END block
" \W - no characters or digits
nnoremap ]] :call search('\c^\s*begin\>', 'W' )
nnoremap [[ :call search('\c^\s*begin\>', 'bW' )
nnoremap ][ :call search('\c^\s*end\W*$', 'W' )
nnoremap [] :call search('\c^\s*end\W*$', 'bW' )
xnoremap ]] :exec "normal! gv"call search('\c^\s*begin\>', 'W' )
xnoremap [[ :exec "normal! gv"call search('\c^\s*begin\>', 'bW' )
xnoremap ][ :exec "normal! gv"call search('\c^\s*end\W*$', 'W' )
xnoremap [] :exec "normal! gv"call search('\c^\s*end\W*$', 'bW' )
" By default only look for CREATE statements, but allow
" the user to override
if !exists('g:ftplugin_sql_statements')
let g:ftplugin_sql_statements = 'create'
endif
" Predefined SQL objects what are used by the below mappings using
" the ]} style maps.
" This global variable allows the users to override it's value
" from within their vimrc.
" Note, you cannot use \?, since these patterns can be used to search
" backwards, you must use \{,1}
if !exists('g:ftplugin_sql_objects')
let g:ftplugin_sql_objects = 'function,procedure,event,' .
\ '\(existing\\|global\s\+temporary\s\+\)\{,1}' .
\ 'table,trigger' .
\ ',schema,service,publication,database,datatype,domain' .
\ ',index,subscription,synchronization,view,variable'
endif
" Key to trigger SQL completion
if !exists('g:ftplugin_sql_omni_key')
let g:ftplugin_sql_omni_key = ''
endif
" Key to trigger drill into column list
if !exists('g:ftplugin_sql_omni_key_right')
let g:ftplugin_sql_omni_key_right = ''
endif
" Key to trigger drill out of column list
if !exists('g:ftplugin_sql_omni_key_left')
let g:ftplugin_sql_omni_key_left = ''
endif
" Replace all ,'s with bars, except ones with numbers after them.
" This will most likely be a \{,1} string.
let s:ftplugin_sql_objects =
\ '\c^\s*' .
\ '\(\(' .
\ substitute(g:ftplugin_sql_statements, ',\d\@!', '\\\\|', 'g') .
\ '\)\s\+\(or\s\+replace\s\+\)\{,1}\)\{,1}' .
\ '\<\(' .
\ substitute(g:ftplugin_sql_objects, ',\d\@!', '\\\\|', 'g') .
\ '\)\>'
" Mappings to move to the next CREATE ... block
exec "nnoremap ]} :call search('".s:ftplugin_sql_objects."', 'W')"
exec "nnoremap [{ :call search('".s:ftplugin_sql_objects."', 'bW')"
" Could not figure out how to use a :call search() string in visual mode
" without it ending visual mode
" Unfortunately, this will add a entry to the search history
exec 'xnoremap ]} /'.s:ftplugin_sql_objects.''
exec 'xnoremap [{ ?'.s:ftplugin_sql_objects.''
" Mappings to move to the next COMMENT
"
" Had to double the \ for the \| separator since this has a special
" meaning on maps
let b:comment_leader = '\(--\\|\/\/\\|\*\\|\/\*\\|\*\/\)'
" Find the start of the next comment
let b:comment_start = '^\(\s*'.b:comment_leader.'.*\n\)\@ ]" :call search('."'".b:comment_start."'".', "W" )'
exec 'nnoremap [" :call search('."'".b:comment_end."'".', "W" )'
exec 'xnoremap ]" :exec "normal! gv"call search('."'".b:comment_start."'".', "W" )'
exec 'xnoremap [" :exec "normal! gv"call search('."'".b:comment_end."'".', "W" )'
" Comments can be of the form:
" /*
" *
" */
" or
" --
" or
" //
setlocal comments=s1:/*,mb:*,ex:*/,:--,://
" Set completion with CTRL-X CTRL-O to autoloaded function.
if exists('&omnifunc')
" Since the SQL completion plugin can be used in conjunction
" with other completion filetypes it must record the previous
" OMNI function prior to setting up the SQL OMNI function
let b:sql_compl_savefunc = &omnifunc
" Source it to determine it's version
runtime autoload/sqlcomplete.vim
" This is used by the sqlcomplete.vim plugin
" Source it for it's global functions
runtime autoload/syntaxcomplete.vim
setlocal omnifunc=sqlcomplete#Complete
" Prevent the intellisense plugin from loading
let b:sql_vis = 1
if !exists('g:omni_sql_no_default_maps')
let regex_extra = ''
if exists('g:loaded_syntax_completion') && exists('g:loaded_sql_completion')
if g:loaded_syntax_completion > 120 && g:loaded_sql_completion > 140
let regex_extra = '\\w*'
endif
endif
" Static maps which use populate the completion list
" using Vim's syntax highlighting rules
exec 'inoremap '.g:ftplugin_sql_omni_key.'a :call sqlcomplete#Map("syntax")'
exec 'inoremap '.g:ftplugin_sql_omni_key.'k :call sqlcomplete#Map("sqlKeyword'.regex_extra.'")'
exec 'inoremap '.g:ftplugin_sql_omni_key.'f :call sqlcomplete#Map("sqlFunction'.regex_extra.'")'
exec 'inoremap '.g:ftplugin_sql_omni_key.'o :call sqlcomplete#Map("sqlOption'.regex_extra.'")'
exec 'inoremap '.g:ftplugin_sql_omni_key.'T :call sqlcomplete#Map("sqlType'.regex_extra.'")'
exec 'inoremap '.g:ftplugin_sql_omni_key.'s :call sqlcomplete#Map("sqlStatement'.regex_extra.'")'
" Dynamic maps which use populate the completion list
" using the dbext.vim plugin
exec 'inoremap '.g:ftplugin_sql_omni_key.'t :call sqlcomplete#Map("table")'
exec 'inoremap '.g:ftplugin_sql_omni_key.'p :call sqlcomplete#Map("procedure")'
exec 'inoremap '.g:ftplugin_sql_omni_key.'v :call sqlcomplete#Map("view")'
exec 'inoremap '.g:ftplugin_sql_omni_key.'c :call sqlcomplete#Map("column")'
exec 'inoremap '.g:ftplugin_sql_omni_key.'l :call sqlcomplete#Map("column_csv")'
" The next 3 maps are only to be used while the completion window is
" active due to the at the beginning of the map
exec 'inoremap '.g:ftplugin_sql_omni_key.'L :call sqlcomplete#Map("column_csv")'
" is not recognized on most Unix systems, so only create
" these additional maps on the Windows platform.
" If you would like to use these maps, choose a different key and make
" the same map in your vimrc.
" if has('win32')
exec 'inoremap '.g:ftplugin_sql_omni_key_right.' =sqlcomplete#DrillIntoTable()'
exec 'inoremap '.g:ftplugin_sql_omni_key_left.' =sqlcomplete#DrillOutOfColumns()'
" endif
" Remove any cached items useful for schema changes
exec 'inoremap '.g:ftplugin_sql_omni_key.'R :call sqlcomplete#Map("resetCache")'
endif
if b:sql_compl_savefunc != ""
" We are changing the filetype to SQL from some other filetype
" which had OMNI completion defined. We need to activate the
" SQL completion plugin in order to cache some of the syntax items
" while the syntax rules for SQL are active.
call sqlcomplete#ResetCacheSyntax()
call sqlcomplete#PreCacheSyntax()
endif
endif
let &cpo = s:save_cpo
unlet s:save_cpo
" vim:sw=4: