11" Vim OMNI completion script for SQL
22" Language: SQL
33" Maintainer: David Fishburn <dfishburn dot vim at gmail dot com>
4- " Version: 12.0
5- " Last Change: 2012 Feb 08
4+ " Version: 14.0
5+ " Last Change: 2012 Dec 04
6+ " Homepage: http://www.vim.org/scripts/script.php?script_id=1572
67" Usage: For detailed help
78" ":help sql.txt"
89" or ":help ft-sql-omni"
910" or read $VIMRUNTIME/doc/sql.txt
1011
1112" History
12- " Version 12.0
13+ "
14+ " Version 14.0 (Dec 2012)
15+ " - BF: Added check for cpo
16+ "
17+ " Version 13.0 (Dec 2012)
18+ " - NF: When completing column lists or drilling into a table
19+ " and g:omni_sql_include_owner is enabled, the
20+ " only the table name would be replaced with the column
21+ " list instead of the table name and owner (if specified).
22+ " - NF: When completing column lists using table aliases
23+ " and g:omni_sql_include_owner is enabled, account
24+ " for the owner name when looking up the table
25+ " list instead of the table name and owner (if specified).
26+ " - BF: When completing column lists or drilling into a table
27+ " and g:omni_sql_include_owner is enabled, the
28+ " column list could often not be found for the table.
29+ " - BF: When OMNI popped up, possibly the wrong word
30+ " would be replaced for column and column list options.
31+ "
32+ " Version 12.0 (Feb 2012)
1333" - Partial column name completion did not work when a table
1434" name or table alias was provided (Jonas Enberg).
1535" - Improved the handling of column completion. First we match any
1636" columns from a previous completion. If not matches are found, we
17- " consider the partial name to be a table or table alias for the
37+ " consider the partial name to be a table or table alias for the
1838" query and attempt to match on it.
1939"
20- " Version 11.0
40+ " Version 11.0 (Jan 2012)
2141" Added g:omni_sql_default_compl_type variable
2242" - You can specify which type of completion to default to
2343" when pressing <C-X><C-O>. The entire list of available
4060" - Prepends error message with SQLComplete so you know who issued
4161" the error.
4262"
43- " Version 9.0
63+ " Version 9.0 (May 2010)
4464" This change removes some of the support for tables with spaces in their
4565" names in order to simplify the regexes used to pull out query table
4666" aliases for more robust table name and column name code completion.
5171" Incorrectly re-executed the g:ftplugin_sql_omni_key_right and g:ftplugin_sql_omni_key_left
5272" when drilling in and out of a column list for a table.
5373"
54- " Version 7.0
74+ " Version 7.0 (Jan 2010)
5575" Better handling of object names
5676"
57- " Version 6.0
77+ " Version 6.0 (Apr 2008)
5878" Supports object names with spaces "my table name"
5979"
6080" Set completion with CTRL-X CTRL-O to autoloaded function.
7191if exists (' g:loaded_sql_completion' )
7292 finish
7393endif
74- let g: loaded_sql_completion = 120
94+ let g: loaded_sql_completion = 130
95+ let s: keepcpo= &cpo
96+ set cpo &vim
7597
7698" Maintains filename of dictionary
7799let s: sql_file_table = " "
@@ -137,6 +159,13 @@ if !exists('g:omni_sql_default_compl_type')
137159endif
138160
139161" This function is used for the 'omnifunc' option.
162+ " It is called twice by omni and it is responsible
163+ " for returning the completion list of items.
164+ " But it must also determine context of what to complete
165+ " and what to "replace" with the completion.
166+ " The a:base, is replaced directly with what the user
167+ " chooses from the choices.
168+ " The s:prepend provides context for the completion.
140169function ! sqlcomplete#Complete (findstart, base)
141170
142171 " Default to table name completion
@@ -145,6 +174,7 @@ function! sqlcomplete#Complete(findstart, base)
145174 if exists (' b:sql_compl_type' )
146175 let compl_type = b: sql_compl_type
147176 endif
177+ let begindot = 0
148178
149179 " First pass through this function determines how much of the line should
150180 " be replaced by whatever is chosen from the completion list
@@ -153,7 +183,6 @@ function! sqlcomplete#Complete(findstart, base)
153183 let line = getline (' .' )
154184 let start = col (' .' ) - 1
155185 let lastword = -1
156- let begindot = 0
157186 " Check if the first character is a ".", for column completion
158187 if line [start - 1 ] == ' .'
159188 let begindot = 1
@@ -179,7 +208,10 @@ function! sqlcomplete#Complete(findstart, base)
179208 " If lastword has already been set for column completion
180209 " break from the loop, since we do not also want to pickup
181210 " a table name if it was also supplied.
211+ " Unless g:omni_sql_include_owner == 1, then we can
212+ " include the ownername.
182213 if lastword != -1 && compl_type == ' column'
214+ \ && g: omni_sql_include_owner == 0
183215 break
184216 endif
185217 " If column completion was specified stop at the "." if
@@ -191,7 +223,7 @@ function! sqlcomplete#Complete(findstart, base)
191223 " If omni_sql_include_owner = 0, do not include the table
192224 " name as part of the substitution, so break here
193225 if lastword == -1 &&
194- \ compl_type = ~ ' table\|view\|procedure\column_csv' &&
226+ \ compl_type = ~ ' \<\( table\|view\|procedure\|column\| column_csv\)\> ' &&
195227 \ g: omni_sql_include_owner == 0
196228 let lastword = start
197229 break
@@ -288,6 +320,12 @@ function! sqlcomplete#Complete(findstart, base)
288320 let table = matchstr ( base, ' ^\(.*\.\)\?\zs.*\ze\..*' )
289321 let column = matchstr ( base, ' .*\.\zs.*' )
290322
323+ if g: omni_sql_include_owner == 1 && owner == ' ' && table != ' ' && column != ' '
324+ let owner = table
325+ let table = column
326+ let column = ' '
327+ endif
328+
291329 " It is pretty well impossible to determine if the user
292330 " has entered:
293331 " owner.table
@@ -370,7 +408,16 @@ function! sqlcomplete#Complete(findstart, base)
370408 let list_type = ' csv'
371409 endif
372410
373- let compl_list = s: SQLCGetColumns (table, list_type)
411+ " If we are including the OWNER for the objects, then for
412+ " table completion, if we have it, it should be included
413+ " as there can be the same table names in a database yet
414+ " with different owner names.
415+ if g: omni_sql_include_owner == 1 && owner != ' ' && table != ' '
416+ let compl_list = s: SQLCGetColumns (owner.' .' .table, list_type)
417+ else
418+ let compl_list = s: SQLCGetColumns (table, list_type)
419+ endif
420+
374421 if column != ' '
375422 " If no column prefix has been provided and the table
376423 " name was provided, append it to each of the items
@@ -393,11 +440,14 @@ function! sqlcomplete#Complete(findstart, base)
393440 endif
394441 elseif compl_type == ' resetCache'
395442 " Reset all cached items
396- let s: tbl_name = []
397- let s: tbl_alias = []
398- let s: tbl_cols = []
399- let s: syn_list = []
400- let s: syn_value = []
443+ let s: tbl_name = []
444+ let s: tbl_alias = []
445+ let s: tbl_cols = []
446+ let s: syn_list = []
447+ let s: syn_value = []
448+ let s: sql_file_table = " "
449+ let s: sql_file_procedure = " "
450+ let s: sql_file_view = " "
401451
402452 let msg = " All SQL cached items have been removed."
403453 call s: SQLCWarningMsg (msg)
@@ -423,12 +473,27 @@ function! sqlcomplete#Complete(findstart, base)
423473 " let expr = 'v:val '.(g:omni_sql_ignorecase==1?'=~?':'=~#').' "\\(^'.base.'\\|\\(\\.\\)\\?'.base.'\\)"'
424474 " let expr = 'v:val '.(g:omni_sql_ignorecase==1?'=~?':'=~#').' "\\(^'.base.'\\|\\([^.]*\\)\\?'.base.'\\)"'
425475 let compl_list = filter (deepcopy (compl_list), expr )
476+
477+ if empty (compl_list) && compl_type == ' table' && base = ~ ' \.$'
478+ " It is possible we could be looking for column name completion
479+ " and the user simply hit C-X C-O to lets try it as well
480+ " since we had no hits with the tables.
481+ " If the base ends with a . it is hard to know if we are
482+ " completing table names or column names.
483+ let list_type = ' '
484+
485+ let compl_list = s: SQLCGetColumns (base, list_type)
486+ endif
426487 endif
427488
428489 if exists (' b:sql_compl_savefunc' ) && b: sql_compl_savefunc != " "
429490 let &omnifunc = b: sql_compl_savefunc
430491 endif
431492
493+ if empty (compl_list)
494+ call s: SQLCWarningMsg ( ' Could not find type[' .compl_type.' ] using prepend[.' .s: prepended .' ] base[' .a: base .' ]' )
495+ endif
496+
432497 return compl_list
433498endfunc
434499
@@ -664,8 +729,26 @@ function! s:SQLCGetObjectOwner(object)
664729endfunction
665730
666731function ! s: SQLCGetColumns (table_name, list_type)
732+ if a: table_name = ~ ' \.'
733+ " Check if the owner/creator has been specified
734+ let owner = matchstr ( a: table_name , ' ^\zs.*\ze\..*\..*' )
735+ let table = matchstr ( a: table_name , ' ^\(.*\.\)\?\zs.*\ze\..*' )
736+ let column = matchstr ( a: table_name , ' .*\.\zs.*' )
737+
738+ if g: omni_sql_include_owner == 1 && owner == ' ' && table != ' ' && column != ' '
739+ let owner = table
740+ let table = column
741+ let column = ' '
742+ endif
743+ else
744+ let owner = ' '
745+ let table = matchstr (a: table_name , ' ^["\[\]a-zA-Z0-9_ ]\+\ze\.\?' )
746+ let column = ' '
747+ endif
748+
667749 " Check if the table name was provided as part of the column name
668- let table_name = matchstr (a: table_name , ' ^["\[\]a-zA-Z0-9_ ]\+\ze\.\?' )
750+ " let table_name = matchstr(a:table_name, '^["\[\]a-zA-Z0-9_ ]\+\ze\.\?')
751+ let table_name = table
669752 let table_cols = []
670753 let table_alias = ' '
671754 let move_to_top = 1
@@ -786,7 +869,12 @@ function! s:SQLCGetColumns(table_name, list_type)
786869
787870 if table_name_new != ' '
788871 let table_alias = table_name
789- let table_name = matchstr ( table_name_new, ' ^\(.*\.\)\?\zs.*\ze' )
872+ if g: omni_sql_include_owner == 1
873+ let table_name = matchstr ( table_name_new, ' ^\zs\(.\{-}\.\)\?\(.\{-}\.\)\?.*\ze' )
874+ else
875+ " let table_name = matchstr( table_name_new, '^\(.*\.\)\?\zs.*\ze' )
876+ let table_name = matchstr ( table_name_new, ' ^\(.\{-}\.\)\?\zs\(.\{-}\.\)\?.*\ze' )
877+ endif
790878
791879 let list_idx = index (s: tbl_name , table_name, 0 , &ignorecase )
792880 if list_idx > -1
@@ -828,7 +916,8 @@ function! s:SQLCGetColumns(table_name, list_type)
828916 if empty (table_cols)
829917 " Specify silent mode, no messages to the user (tbl, 1)
830918 " Specify do not comma separate (tbl, 1, 1)
831- let table_cols_str = DB_getListColumn (table_name, 1 , 1 )
919+ " let table_cols_str = DB_getListColumn(table_name, 1, 1)
920+ let table_cols_str = DB_getListColumn ((owner!= ' ' ?owner.' .' :' ' ).table_name, 1 , 1 )
832921
833922 if table_cols_str != " "
834923 let s: tbl_name = add ( s: tbl_name , table_name )
@@ -854,3 +943,7 @@ function! s:SQLCGetColumns(table_name, list_type)
854943
855944 return table_cols
856945endfunction
946+ " Restore:
947+ let &cpo = s: keepcpo
948+ unlet s: keepcpo
949+ " vim: ts = 4 fdm = marker
0 commit comments