summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2006-03-09 22:27:48 +0000
committerBram Moolenaar <Bram@vim.org>2006-03-09 22:27:48 +0000
commit0fd9289de3079583cd19c88425277b99b5a15253 (patch)
tree065beae578d42ca17b8e9f96807d3cc06fff8a85
parenta3227e2b15600b2303e3aac070803021e76ed6d5 (diff)
updated for version 7.0219
-rw-r--r--runtime/autoload/README.txt12
-rw-r--r--runtime/autoload/paste.vim39
-rw-r--r--runtime/doc/Makefile2
-rw-r--r--runtime/doc/netbeans.txt22
-rw-r--r--runtime/ftplugin/sql.vim248
-rw-r--r--runtime/indent/sql.vim39
-rw-r--r--runtime/indent/sqlanywhere.vim384
-rw-r--r--runtime/macmap.vim83
-rw-r--r--runtime/plugin/netrwPlugin.vim5
-rw-r--r--src/netbeans.c163
-rw-r--r--src/normal.c2
-rw-r--r--src/os_mac.h114
-rw-r--r--src/spell.c1
-rw-r--r--src/vim.h6
14 files changed, 885 insertions, 235 deletions
diff --git a/runtime/autoload/README.txt b/runtime/autoload/README.txt
index 2038fa224e..dcefbf033d 100644
--- a/runtime/autoload/README.txt
+++ b/runtime/autoload/README.txt
@@ -4,12 +4,18 @@ These are functions used by plugins and for general use. They will be loaded
automatically when the function is invoked. See ":help autoload".
gzip.vim for editing compressed files
-netrw.vim browsing (remote) directories and editing remote files
+netrw*.vim browsing (remote) directories and editing remote files
tar.vim browsing tar files
zip.vim browsing zip files
+paste.vim common code for mswin.vim, menu.vim and macmap.vim
+spellfile.vim downloading of a missing spell file
-Occult completion files:
+Omni completion files:
ccomplete.vim C
csscomplete.vim HTML / CSS
htmlcomplete.vim HTML
-
+javascriptcomplete.vim Javascript
+phpcomplete.vim PHP
+pycomplete.vim Python
+syntaxcomplete.vim from syntax highlighting
+xmlcomplete.vim XML (uses files in the xml directory)
diff --git a/runtime/autoload/paste.vim b/runtime/autoload/paste.vim
new file mode 100644
index 0000000000..435c5e6235
--- /dev/null
+++ b/runtime/autoload/paste.vim
@@ -0,0 +1,39 @@
+" Vim support file to help with paste mappings and menus
+" Maintainer: Bram Moolenaar <Bram@vim.org>
+" Last Change: 2006 Mar 09
+
+" Define the string to use for items that are present both in Edit, Popup and
+" Toolbar menu. Also used in mswin.vim and macmap.vim.
+
+" Pasting blockwise and linewise selections is not possible in Insert and
+" Visual mode without the +virtualedit feature. They are pasted as if they
+" were characterwise instead. Add to that some tricks to leave the cursor in
+" the right position, also for "gi".
+if has("virtualedit")
+ let paste#paste_cmd = {'n': ":call paste#Paste()<CR>"}
+ let paste#paste_cmd['v'] = '"-c<Esc>' . paste#paste_cmd['n']
+ let paste#paste_cmd['i'] = '<Esc>' . paste#paste_cmd['n'] . 'gi'
+
+ func! paste#Paste()
+ let ove = &ve
+ set ve=all
+ normal! `^
+ if @+ != ''
+ normal! "+gP
+ endif
+ let c = col(".")
+ normal! i
+ if col(".") < c " compensate for i<ESC> moving the cursor left
+ normal! l
+ endif
+ let &ve = ove
+ endfunc
+else
+ let paste#paste_cmd = {'n': "\"=@+.'xy'<CR>gPFx\"_2x"}
+ let paste#paste_cmd['v'] = '"-c<Esc>gix<Esc>' . paste#paste_cmd['n'] . '"_x'
+ let paste#paste_cmd['i'] = 'x<Esc>' . paste#paste_cmd['n'] . '"_s'
+endif
+
+if has("virtualedit")
+else
+endif
diff --git a/runtime/doc/Makefile b/runtime/doc/Makefile
index 70cb7a8a11..9ebce3c7e1 100644
--- a/runtime/doc/Makefile
+++ b/runtime/doc/Makefile
@@ -89,6 +89,7 @@ DOCS = \
sponsor.txt \
starting.txt \
spell.txt \
+ sql.txt \
syntax.txt \
tabpage.txt \
tagsrch.txt \
@@ -213,6 +214,7 @@ HTMLS = \
sponsor.html \
starting.html \
spell.html \
+ sql.html \
syntax.html \
tabpage.html \
tagsrch.html \
diff --git a/runtime/doc/netbeans.txt b/runtime/doc/netbeans.txt
index 71f8f8e170..9d851cce29 100644
--- a/runtime/doc/netbeans.txt
+++ b/runtime/doc/netbeans.txt
@@ -1,4 +1,4 @@
-*netbeans.txt* For Vim version 7.0aa. Last change: 2006 Feb 05
+*netbeans.txt* For Vim version 7.0aa. Last change: 2006 Mar 09
VIM REFERENCE MANUAL by Gordon Prieur
@@ -259,10 +259,19 @@ problems and has been fixed in 2.2. To decrease the likelihood of this
confusion happening again, netbeans_saved() has been renamed to
netbeans_save_buffer().
+We are now at version 2.3. For the differences between 2.2 and 2.3 search for
+"2.3" below.
+
The messages are currently sent over a socket. Since the messages are in
plain UTF-8 text this protocol could also be used with any other communication
mechanism.
+To see an example implementation look at the gvim tool in Agide. Currently
+found here:
+ http://cvs.sf.net/viewcvs.py/a-a-p/Agide/Tools/GvimTool.py?view=markup
+
+
+
10.1 Kinds of messages |nb-messages|
10.2 Terms |nb-terms|
10.3 Commands |nb-commands|
@@ -612,11 +621,22 @@ getText Return the contents of the buffer as a string.
insert off text
Insert "text" before position "off". "text" is a string
argument, "off" a number.
+ "off" should have a "\n" (newline) at the end of each line.
+ Or "\r\n" when 'fileformat' is "dos". When using "insert" in
+ an empty buffer Vim will set 'fileformat' accordingly.
+ When "off" points to the start of a line the text is inserted
+ above this line. Thus when "off" is zero lines are inserted
+ before the first line.
+ When "off" points after the start of a line, possibly on the
+ NUL at the end of a line, the first line of text is appended
+ to this line. Further lines come below it.
Possible replies:
123 no problem
123 !message failed
Note that the message in the reply is not quoted.
Also sets the current buffer, if necessary.
+ Does not move the cursor to the changed text.
+ Resets undo information.
remove off length
Delete "length" bytes of text at position "off". Both
diff --git a/runtime/ftplugin/sql.vim b/runtime/ftplugin/sql.vim
index efccebdf16..d2e6ee5217 100644
--- a/runtime/ftplugin/sql.vim
+++ b/runtime/ftplugin/sql.vim
@@ -1,10 +1,13 @@
" SQL filetype plugin file
" Language: SQL (Common for Oracle, Microsoft SQL Server, Sybase)
-" Version: 0.08
+" Version: 1.0
" Maintainer: David Fishburn <fishburn at ianywhere dot com>
-" Last Change: Mon Feb 21 2005 7:27:36 AM
+" Last Change: Wed Jan 11 2006 10:04:55 AM
" 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:
@@ -12,6 +15,22 @@
" .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 <tab>
+"
+" To change the default dialect, add the following to your vimrc:
+" let g:sql_type_default = 'sqlanywhere'
+
+
" Only do this when not done yet for this buffer
if exists("b:did_ftplugin")
finish
@@ -20,8 +39,146 @@ endif
let s:save_cpo = &cpo
set cpo=
+" Functions/Commands to allow the user to change SQL syntax dialects
+" through the use of :SQLSetType <tab> 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
+
+ " 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'
+ endfunction
+ command! -nargs=* -complete=custom,SQL_GetList SQLSetType :call SQL_SetType(<q-args>)
+
+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<"
+
" Don't load another plugin for this buffer
-let b:did_ftplugin = 1
+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 = '\%(\<end\s\+\)\@<!'
@@ -112,69 +269,78 @@ endif
" [d, [D, [_CTRL_D and so on features
" Match these values ignoring case
" ie DECLARE varname INTEGER
-let &l:define = '\c\(DECLARE\|IN\|OUT\|INOUT\)\s*'
+let &l:define = '\c\<\(VARIABLE\|DECLARE\|IN\|OUT\|INOUT\)\>'
" Mappings to move to the next BEGIN ... END block
" \W - no characters or digits
-nmap <buffer> <silent> ]] :call search('\c^\s*begin\>', 'W' )<CR>
-nmap <buffer> <silent> [[ :call search('\c^\s*begin\>', 'bW' )<CR>
-nmap <buffer> <silent> ][ :call search('\c^\s*end\W*$', 'W' )<CR>
-nmap <buffer> <silent> [] :call search('\c^\s*end\W*$', 'bW' )<CR>
-vmap <buffer> <silent> ]] /\c^\s*begin\><CR>
-vmap <buffer> <silent> [[ ?\c^\s*begin<CR>
-vmap <buffer> <silent> ][ /\c^\s*end\W*$<CR>
-vmap <buffer> <silent> [] ?\c^\s*end\W*$<CR>
+nmap <buffer> <silent> ]] :call search('\\c^\\s*begin\\>', 'W' )<CR>
+nmap <buffer> <silent> [[ :call search('\\c^\\s*begin\\>', 'bW' )<CR>
+nmap <buffer> <silent> ][ :call search('\\c^\\s*end\\W*$', 'W' )<CR>
+nmap <buffer> <silent> [] :call search('\\c^\\s*end\\W*$', 'bW' )<CR>
+vmap <buffer> <silent> ]] /\\c^\\s*begin\\><CR>
+vmap <buffer> <silent> [[ ?\\c^\\s*begin\\><CR>
+vmap <buffer> <silent> ][ /\\c^\\s*end\\W*$<CR>
+vmap <buffer> <silent> [] ?\\c^\\s*end\\W*$<CR>
+
+" 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\+\)\?table,trigger' .
+ \ '\\(existing\\\\|global\\s\\+temporary\\s\\+\\)\\\{,1}' .
+ \ 'table,trigger' .
\ ',schema,service,publication,database,datatype,domain' .
\ ',index,subscription,synchronization,view,variable'
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*' .
- \ '\(create\s\+\(or\s\+replace\s\+\)\?\)\?' .
- \ '\<\(' .
- \ substitute(g:ftplugin_sql_objects, ',', '\\\\|', 'g') .
- \ '\)\>'
+ \ '\\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
-" map <buffer> <silent> ]} :call search(g:ftplugin_sql_objects, 'W' )<CR>
-" nmap <buffer> <silent> [{ :call search('\c^\s*\(create\s\+\(or\s\+replace\s\+\)\?\)\?\<\(function\\|procedure\\|event\\|table\\|trigger\\|schema\)\>', 'bW' )<CR>
-" exec 'nmap <buffer> <silent> ]} /'.s:ftplugin_sql_objects.'<CR>'
exec "nmap <buffer> <silent> ]} :call search('".s:ftplugin_sql_objects."', 'W')<CR>"
exec "nmap <buffer> <silent> [{ :call search('".s:ftplugin_sql_objects."', 'bW')<CR>"
" 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 'vmap <buffer> <silent> ]} /'.s:ftplugin_sql_objects.'<CR>'
exec 'vmap <buffer> <silent> [{ ?'.s:ftplugin_sql_objects.'<CR>'
-" vmap <buffer> <silent> ]} /\c^\s*\(create\s\+\(or\s\+replace\s\+\)\?\)\?\<\(function\\|procedure\\|event\\|table\\|trigger\\|schema\)\><CR>
-" vmap <buffer> <silent> [{ ?\c^\s*\(create\s\+\(or\s\+replace\s\+\)\?\)\?\<\(function\\|procedure\\|event\\|table\\|trigger\\|schema\)\><CR>
" 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 = '\(--\\|\/\/\\|\*\\|\/\*\\|\*\/\)'
+let b:comment_leader = '\\(--\\\|\\/\\/\\\|\\*\\\|\\/\\*\\\|\\*\\/\\)'
" Find the start of the next comment
-let b:comment_start = '^\(\s*'.b:comment_leader.'.*\n\)\@<!'.
- \ '\(\s*'.b:comment_leader.'\)'
+let b:comment_start = '^\\(\\s*'.b:comment_leader.'.*\\n\\)\\@<!'.
+ \ '\\(\\s*'.b:comment_leader.'\\)'
" Find the end of the previous comment
-let b:comment_end = '\(^\s*'.b:comment_leader.'.*\n\)'.
- \ '\(^\s*'.b:comment_leader.'\)\@!'
+let b:comment_end = '\\(^\\s*'.b:comment_leader.'.*\\n\\)'.
+ \ '\\(^\\s*'.b:comment_leader.'\\)\\@!'
" Skip over the comment
let b:comment_jump_over = "call search('".
- \ '^\(\s*'.b:comment_leader.'.*\n\)\@<!'.
+ \ '^\\(\\s*'.b:comment_leader.'.*\\n\\)\\@<!'.
\ "', 'W')"
let b:comment_skip_back = "call search('".
- \ '^\(\s*'.b:comment_leader.'.*\n\)\@<!'.
+ \ '^\\(\\s*'.b:comment_leader.'.*\\n\\)\\@<!'.
\ "', 'bW')"
" Move to the start and end of comments
exec 'nnoremap <silent><buffer> ]" /'.b:comment_start.'<CR>'
@@ -187,11 +353,29 @@ exec 'vnoremap <silent><buffer> [" /'.b:comment_end.'<CR>'
" *
" */
" or
-" //
-" or
" --
+" or
+" //
setlocal comments=s1:/*,mb:*,ex:*/,:--,://
+" Set completion with CTRL-X CTRL-O to autoloaded function.
+if exists('&omnifunc')
+ " 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
+ imap <buffer> <c-space>t <C-O>:let b:sql_compl_type='table'<CR><C-X><C-O>
+ imap <buffer> <c-space>p <C-O>:let b:sql_compl_type='procedure'<CR><C-X><C-O>
+ imap <buffer> <c-space>v <C-O>:let b:sql_compl_type='view'<CR><C-X><C-O>
+ imap <buffer> <c-space>c <C-O>:let b:sql_compl_type='column'<CR><C-X><C-O>
+ imap <buffer> <c-space>f <C-O>:let b:sql_compl_type='function'<CR><C-X><C-O>
+ imap <buffer> <c-space>o <C-O>:let b:sql_compl_type='option'<CR><C-X><C-O>
+ imap <buffer> <c-right> <C-O>:let b:sql_compl_type='column'<CR><C-X><C-O>
+endif
+
let &cpo = s:save_cpo
" vim:sw=4:ff=unix:
diff --git a/runtime/indent/sql.vim b/runtime/indent/sql.vim
new file mode 100644
index 0000000000..490d652ae1
--- /dev/null
+++ b/runtime/indent/sql.vim
@@ -0,0 +1,39 @@
+" Vim indent file loader
+" Language: SQL
+" Maintainer: David Fishburn <fishburn at ianywhere dot com>
+" Last Change: Thu Sep 15 2005 10:27:51 AM
+" Version: 1.0
+" Download: http://vim.sourceforge.net/script.php?script_id=495
+
+" Description: Checks for a:
+" buffer local variable,
+" global variable,
+" If the above exist, it will source the type specified.
+" If none exist, it will source the default sqlanywhere.vim file.
+
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+ finish
+endif
+
+" Default to the standard Vim distribution file
+let filename = 'sqlanywhere'
+
+" Check for overrides. Buffer variables have the highest priority.
+if exists("b:sql_type_override")
+ " Check the runtimepath to see if the file exists
+ if globpath(&runtimepath, 'indent/'.b:sql_type_override.'.vim') != ''
+ let filename = b:sql_type_override
+ endif
+elseif exists("g:sql_type_default")
+ if globpath(&runtimepath, 'indent/'.g:sql_type_default.'.vim') != ''
+ let filename = g:sql_type_default
+ endif
+endif
+
+" Source the appropriate file
+exec 'runtime indent/'.filename.'.vim'
+
+
+" vim:sw=4:ff=unix:
diff --git a/runtime/indent/sqlanywhere.vim b/runtime/indent/sqlanywhere.vim
new file mode 100644
index 0000000000..65d711383a
--- /dev/null
+++ b/runtime/indent/sqlanywhere.vim
@@ -0,0 +1,384 @@
+" Vim indent file
+" Language: SQL
+" Maintainer: David Fishburn <fishburn at ianywhere dot com>
+" Last Change: Wed Sep 14 2005 10:21:15 PM
+" Version: 1.4
+" Download: http://vim.sourceforge.net/script.php?script_id=495
+
+" Notes:
+" Indenting keywords are based on Oracle and Sybase Adaptive Server
+" Anywhere (ASA). Test indenting was done with ASA stored procedures and
+" fuctions and Oracle packages which contain stored procedures and
+" functions.
+" This has not been tested against Microsoft SQL Server or
+" Sybase Adaptive Server Enterprise (ASE) which use the Transact-SQL
+" syntax. That syntax does not have end tags for IF's, which makes
+" indenting more difficult.
+"
+" Known Issues:
+" The Oracle MERGE statement does not have an end tag associated with
+" it, this can leave the indent hanging to the right one too many.
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+ finish
+endif
+let b:did_indent = 1
+let b:current_indent = "sqlanywhere"
+
+setlocal indentkeys-=0{
+setlocal indentkeys-=0}
+setlocal indentkeys-=:
+setlocal indentkeys-=0#
+setlocal indentkeys-=e
+
+" This indicates formatting should take place when one of these
+" expressions is used. These expressions would normally be something
+" you would type at the BEGINNING of a line
+" SQL is generally case insensitive, so this files assumes that
+" These keywords are something that would trigger an indent LEFT, not
+" an indent right, since the SQLBlockStart is used for those keywords
+setlocal indentkeys+==~end,=~else,=~elseif,=~elsif,0=~when,0=)
+
+" GetSQLIndent is executed whenever one of the expressions
+" in the indentkeys is typed
+setlocal indentexpr=GetSQLIndent()
+
+" Only define the functions once.
+if exists("*GetSQLIndent")
+ finish
+endif
+
+" List of all the statements that start a new block.
+" These are typically words that start a line.
+" IS is excluded, since it is difficult to determine when the
+" ending block is (especially for procedures/functions).
+let s:SQLBlockStart = '^\s*\%('.
+ \ 'if\|else\|elseif\|elsif\|'.
+ \ 'while\|loop\|do\|'.
+ \ 'begin\|'.
+ \ 'case\|when\|merge\|exception'.
+ \ '\)\>'
+let s:SQLBlockEnd = '^\s*\(end\)\>'
+
+" The indent level is also based on unmatched paranethesis
+" If a line has an extra "(" increase the indent
+" If a line has an extra ")" decrease the indent
+function s:CountUnbalancedParan( line, paran_to_check )
+ let l = a:line
+ let lp = substitute(l, '[^(]', '', 'g')
+ let l = a:line
+ let rp = substitute(l, '[^)]', '', 'g')
+
+ if a:paran_to_check =~ ')'
+ " echom 'CountUnbalancedParan ) returning: ' .
+ " \ (strlen(rp) - strlen(lp))
+ return (strlen(rp) - strlen(lp))
+ elseif a:paran_to_check =~ '('
+ " echom 'CountUnbalancedParan ( returning: ' .
+ " \ (strlen(lp) - strlen(rp))
+ return (strlen(lp) - strlen(rp))
+ else
+ " echom 'CountUnbalancedParan unknown paran to check: ' .
+ " \ a:paran_to_check
+ return 0
+ endif
+endfunction
+
+" Unindent commands based on previous indent level
+function s:CheckToIgnoreRightParan( prev_lnum, num_levels )
+ let lnum = a:prev_lnum
+ let line = getline(lnum)
+ let ends = 0
+ let num_right_paran = a:num_levels
+ let ignore_paran = 0
+ let vircol = 1
+
+ while num_right_paran > 0
+ silent! exec 'norm! '.lnum."G\<bar>".vircol."\<bar>"
+ let right_paran = search( ')', 'W' )
+ if right_paran != lnum
+ " This should not happen since there should be at least
+ " num_right_paran matches for this line
+ break
+ endif
+ let vircol = virtcol(".")
+
+ " if getline(".") =~ '^)'
+ let matching_paran = searchpair('(', '', ')', 'bW',
+ \ 'IsColComment(line("."), col("."))')
+
+ if matching_paran < 1
+ " No match found
+ " echom 'CTIRP - no match found, ignoring'
+ break
+ endif
+
+ if matching_paran == lnum
+ " This was not an unmatched parantenses, start the search again
+ " again after this column
+ " echom 'CTIRP - same line match, ignoring'
+ continue
+ endif
+
+ " echom 'CTIRP - match: ' . line(".") . ' ' . getline(".")
+
+ if getline(matching_paran) =~? '\(if\|while\)\>'
+ " echom 'CTIRP - if/while ignored: ' . line(".") . ' ' . getline(".")
+ let ignore_paran = ignore_paran + 1
+ endif
+
+ " One match found, decrease and check for further matches
+ let num_right_paran = num_right_paran - 1
+
+ endwhile
+
+ " Fallback - just move back one
+ " return a:prev_indent - &sw
+ return ignore_paran
+endfunction
+
+" Based on the keyword provided, loop through previous non empty
+" non comment lines to find the statement that initated the keyword.
+" Return its indent level
+" CASE ..
+" WHEN ...
+" Should return indent level of CASE
+" EXCEPTION ..
+" WHEN ...
+" something;
+" WHEN ...
+" Should return indent level of exception.
+function s:GetStmtStarterIndent( keyword, curr_lnum )
+ let lnum = a:curr_lnum
+
+ " Default - reduce indent by 1
+ let ind = indent(a:curr_lnum) - &sw
+
+ if a:keyword =~? 'end'
+ exec 'normal! ^'
+ let stmts = '^\s*\%('.
+ \ '\<begin\>\|' .
+ \ '\%(\%(\<end\s\+\)\@<!\<loop\>\)\|' .
+ \ '\%(\%(\<end\s\+\)\@<!\<case\>\)\|' .
+ \ '\%(\%(\<end\s\+\)\@<!\<for\>\)\|' .
+ \ '\%(\%(\<end\s\+\)\@<!\<if\>\)'.
+ \ '\)'
+ let matching_lnum = searchpair(stmts, '', '\<end\>\zs', 'bW',
+ \ 'IsColComment(line("."), col(".")) == 1')
+ exec 'normal! $'
+ if matching_lnum > 0 && matching_lnum < a:curr_lnum
+ let ind = indent(matching_lnum)
+ endif
+ elseif a:keyword =~? 'when'
+ exec 'normal! ^'
+ let matching_lnum = searchpair(
+ \ '\%(\<end\s\+\)\@<!\<case\>\|\<exception\>\|\<merge\>',
+ \ '',
+ \ '\%(\%(\<when\s\+others\>\)\|\%(\<end\s\+case\>\)\)',
+ \ 'bW',
+ \ 'IsColComment(line("."), col(".")) == 1')
+ exec 'normal! $'
+ if matching_lnum > 0 && matching_lnum < a:curr_lnum
+ let ind = indent(matching_lnum)
+ else
+ let ind = indent(a:curr_lnum)
+ endif
+ endif
+
+ return ind
+endfunction
+
+
+" Check if the line is a comment
+function IsLineComment(lnum)
+ let rc = synIDattr(
+ \ synID(a:lnum,
+ \ match(getline(a:lnum), '\S')+1, 0)
+ \ , "name")
+ \ =~? "comment"
+
+ return rc
+endfunction
+
+
+" Check if the column is a comment
+function IsColComment(lnum, cnum)
+ let rc = synIDattr(synID(a:lnum, a:cnum, 0), "name")
+ \ =~? "comment"
+
+ return rc
+endfunction
+
+
+" Check if the column is a comment
+function ModuloIndent(ind)
+ let ind = a:ind
+
+ if ind > 0
+ let modulo = ind % &shiftwidth
+
+ if modulo > 0
+ let ind = ind - modulo
+ endif
+ endif
+
+ return ind
+endfunction
+
+
+" Find correct indent of a new line based upon the previous line
+function GetSQLIndent()
+ let lnum = v:lnum
+ let ind = indent(lnum)
+
+ " If the current line is a comment, leave the indent as is
+ " Comment out this additional check since it affects the
+ " indenting of =, and will not reindent comments as it should
+ " if IsLineComment(lnum) == 1
+ " return ind
+ " endif
+
+ " while 1
+ " Get previous non-blank line
+ let prevlnum = prevnonblank(lnum - 1)
+ if prevlnum <= 0
+ return ind
+ endif
+
+ if IsLineComment(prevlnum) == 1
+ if getline(v:lnum) =~ '^\s*\*'
+ let ind = ModuloIndent(indent(prevlnum))
+ return ind + 1
+ endif
+ " If the previous line is a comment, then return -1
+ " to tell Vim to use the formatoptions setting to determine
+ " the indent to use
+ " But only if the next line is blank. This would be true if
+ " the user is typing, but it would not be true if the user
+ " is reindenting the file
+ if getline(v:lnum) =~ '^\s*$'
+ return -1
+ endif
+ endif
+
+ " let prevline = getline(prevlnum)
+ " if prevline !~ '^\s*$'
+ " " echom 'previous non blank - break: ' . prevline
+ " break
+ " endif
+ " endwhile
+
+ " echom 'PREVIOUS INDENT: ' . indent(prevlnum) . ' LINE: ' . getline(prevlnum)
+
+ " This is the line you just hit return on, it is not the current line
+ " which is new and empty
+ " Based on this line, we can determine how much to indent the new
+ " line
+
+ " Get default indent (from prev. line)
+ let ind = indent(prevlnum)
+ let prevline = getline(prevlnum)
+
+ " Now check what's on the previous line to determine if the indent
+ " should be changed, for example IF, BEGIN, should increase the indent
+ " where END IF, END, should decrease the indent.
+ if prevline =~? s:SQLBlockStart
+ " Move indent in
+ let ind = ind + &sw
+ " echom 'prevl - SQLBlockStart - indent ' . ind . ' line: ' . prevline
+ elseif prevline =~ '[()]'
+ if prevline =~ '('
+ let num_unmatched_left = s:CountUnbalancedParan( prevline, '(' )
+ else
+ let num_unmatched_left = 0
+ endif
+ if prevline =~ ')'
+ let num_unmatched_right = s:CountUnbalancedParan( prevline, ')' )
+ else
+ let num_unmatched_right = 0
+ " let num_unmatched_right = s:CountUnbalancedParan( prevline, ')' )
+ endif
+ if num_unmatched_left > 0
+ " There is a open left paranethesis
+ " increase indent
+ let ind = ind + ( &sw * num_unmatched_left )
+ elseif num_unmatched_right > 0
+ " if it is an unbalanced paranethesis only unindent if
+ " it was part of a command (ie create table(..) )
+ " instead of part of an if (ie if (....) then) which should
+ " maintain the indent level
+ let ignore = s:CheckToIgnoreRightParan( prevlnum, num_unmatched_right )
+ " echom 'prevl - ) unbalanced - CTIRP - ignore: ' . ignore
+
+ if prevline =~ '^\s*)'
+ let ignore = ignore + 1
+ " echom 'prevl - begins ) unbalanced ignore: ' . ignore
+ endif
+
+ if (num_unmatched_right - ignore) > 0
+ let ind = ind - ( &sw * (num_unmatched_right - ignore) )
+ endif
+
+ endif
+ endif
+
+
+ " echom 'CURRENT INDENT: ' . ind . ' LINE: ' . getline(v:lnum)
+
+ " This is a new blank line since we just typed a carriage return
+ " Check current line; search for simplistic matching start-of-block
+ let line = getline(v:lnum)
+
+ if line =~? '^\s*els'
+ " Any line when you type else will automatically back up one
+ " ident level (ie else, elseif, elsif)
+ let ind = ind - &sw
+ " echom 'curr - else - indent ' . ind
+ elseif line =~? '^\s*end\>'
+ let ind = s:GetStmtStarterIndent('end', v:lnum)
+ " General case for end
+ " let ind = ind - &sw
+ " echom 'curr - end - indent ' . ind
+ elseif line =~? '^\s*when\>'
+ let ind = s:GetStmtStarterIndent('when', v:lnum)
+ " If the WHEN clause is used with a MERGE or EXCEPTION
+ " clause, do not change the indent level, since these
+ " statements do not have a corresponding END statement.
+ " if stmt_starter =~? 'case'
+ " let ind = ind - &sw
+ " endif
+ " elseif line =~ '^\s*)\s*;\?\s*$'
+ " elseif line =~ '^\s*)'
+ elseif line =~ '^\s*)'
+ let num_unmatched_right = s:CountUnbalancedParan( line, ')' )
+ let ignore = s:CheckToIgnoreRightParan( v:lnum, num_unmatched_right )
+ " If the line ends in a ), then reduce the indent
+ " This catches items like:
+ " CREATE TABLE T1(
+ " c1 int,
+ " c2 int
+ " );
+ " But we do not want to unindent a line like:
+ " IF ( c1 = 1
+ " AND c2 = 3 ) THEN
+ " let num_unmatched_right = s:CountUnbalancedParan( line, ')' )
+ " if num_unmatched_right > 0
+ " elseif strpart( line, strlen(line)-1, 1 ) =~ ')'