Bram,
this patch fies an issue reported by David Fishburn about a misbehaving 
searchpairpos(). I traced it back to syntax.c and I think what happens 
is, that Vim gets confused about the current syntax stack. I added a 
newstyle test, that lets the problem reproduce, given the plugin from 
David. I hope it is okay, to include some plugins for the tests.

I have fixed that behaviour for David back in October and haven't heard 
from him back since then. I think, this patch should be included for a 
possible vim 7.5.
CC'ing David for his opinion.

Best,
Christian
-- 
Jeder Erfolg, den man erzielt, schafft uns einen Feind. Man muß
mittelmäßig sein, wenn man beliebt sein will.
                -- Oscar Wilde

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.
diff --git a/src/syntax.c b/src/syntax.c
index badb226..3edf98b 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -6474,6 +6474,10 @@ syn_get_id(wp, lnum, col, trans, spellp, keep_state)
 	    || lnum != current_lnum
 	    || col < current_col)
 	syntax_start(wp, lnum);
+    else if (wp->w_buffer == syn_buf
+           && lnum == current_lnum
+           && col > current_col)
+       next_match_idx = -1;   /* just in case */
 
     (void)get_syntax_attr(col, spellp, keep_state);
 
diff --git a/src/testdir/Make_all.mak b/src/testdir/Make_all.mak
index f392451..4993964 100644
--- a/src/testdir/Make_all.mak
+++ b/src/testdir/Make_all.mak
@@ -175,6 +175,7 @@ NEW_TESTS = test_assert.res \
 	    test_cdo.res \
 	    test_increment.res \
 	    test_quickfix.res \
+	    test_searchpair.res \
 	    test_viml.res \
 	    test_alot.res
 
diff --git a/src/testdir/bundles/searchpair/autoload/SQLUtilities.vim b/src/testdir/bundles/searchpair/autoload/SQLUtilities.vim
new file mode 100644
index 0000000..a718321
--- /dev/null
+++ b/src/testdir/bundles/searchpair/autoload/SQLUtilities.vim
@@ -0,0 +1,2818 @@
+" SQLUtilities:   Variety of tools for writing SQL
+"   Author:	      David Fishburn <dfishburn dot vim at gmail dot com>
+"   Date:	      Nov 23, 2002
+"   Last Changed: 2015 Sep 25
+"   Version:	  7.0.0
+"   Script:	      http://www.vim.org/script.php?script_id=492
+"   License:      GPL (http://www.gnu.org/licenses/gpl.html)
+"
+"   Dependencies:
+"        Align.vim - Version 15 (as a minimum)
+"                  - Author: Charles E. Campbell, Jr.
+"                  - http://www.vim.org/script.php?script_id=294
+"   Documentation:
+"        :h SQLUtilities.txt 
+"
+
+" Prevent duplicate loading
+if exists("g:loaded_sqlutilities_auto")
+    finish
+endif
+if v:version < 700
+    echomsg "SQLUtilities: Version 2.0.0 or higher requires Vim7.  Version 1.4.1 can stil be used with Vim6."
+    finish
+endif
+let g:loaded_sqlutilities_auto = 700
+
+" Turn on support for line continuations when creating the script
+let s:cpo_save = &cpo
+set cpo&vim
+
+" SQLU_Formatter: align selected text based on alignment pattern(s)
+function! SQLUtilities#SQLU_Formatter(...) range
+    let mode = 'n'
+    if a:0 > 0
+        let mode = (a:1 == ''?'n':(a:1))
+    endif
+
+    " if ! exists( ':AlignCtrl' ) 
+    "     call s:SQLU_WarningMsg(
+    "                 \ 'SQLU_Formatter - The Align plugin cannot be found'
+    "                 \ )
+    "     return -1
+    " endif
+
+    call s:SQLU_WrapperStart( a:firstline, a:lastline, mode )
+    " Store pervious value of highlight search
+    let hlsearch = &hlsearch
+    let &hlsearch = 0
+
+    " Store pervious value of gdefault
+    let gdefault = &gdefault
+    let &gdefault = 0
+
+    " save previous search string
+    let saveSearch = @/ 
+
+    " save previous format options and turn off automatic formating
+    let saveFormatOptions = &formatoptions
+    silent execute 'setlocal formatoptions-=a'
+
+    " Use the mark locations instead of storing the line numbers
+    " since these values can changes based on the reformatting 
+    " of the lines
+    let ret = s:SQLU_ReformatStatement()
+    if ret > -1
+        if g:sqlutil_indent_nested_blocks == 1
+            let ret = s:SQLU_IndentNestedBlocks()
+        endif
+    endif
+
+    " Restore default value
+    " And restore cursor position
+    let &hlsearch = hlsearch
+    call s:SQLU_WrapperEnd(mode)
+
+    " restore previous format options 
+    let &formatoptions = saveFormatOptions 
+
+    " restore previous search string
+    let @/ = saveSearch
+    let &gdefault = gdefault
+    
+endfunction
+
+" SQLU_FormatStmts: 
+"    For a given range (default entire file), it find each SQL 
+"    statement an run SQLFormatter against it.
+"                 
+function! SQLUtilities#SQLU_FormatStmts(...) range
+    let mode = 'n'
+    if a:0 > 0
+        let mode = (a:1 == ''?'n':(a:1))
+    endif
+
+    let curline     = line(".")
+    let curcol      = virtcol(".")
+    let keepline_ms = line("'s")
+    let keepcol_ms  = virtcol("'s")
+    let keepline_me = line("'e")
+    let keepcol_me  = virtcol("'e")
+
+    silent! exec 'normal! '.a:lastline."G\<bar>0\<bar>"
+    " Add a new line to the bottom of the mark to be removed latter
+    put =''
+    silent! exec "ma e"
+    silent! exec 'normal! '.a:firstline."G\<bar>0\<bar>"
+    " Add a new line above the mark to be removed latter
+    put! = ''
+    silent! exec "ma s"
+    silent! exec "normal! 'sj"
+
+    " Store pervious value of highlight search
+    let hlsearch = &hlsearch
+    let &hlsearch = 0
+
+    " save previous search string
+    let saveSearch = @/ 
+
+    " save previous format options and turn off automatic formating
+    let saveFormatOptions = &formatoptions
+    silent execute 'setlocal formatoptions-=a'
+
+    " Must default the statements to query
+    let stmt_keywords = g:sqlutil_stmt_keywords
+
+    " Verify the string is in the correct format
+    " Strip off any trailing commas
+    let stmt_keywords =
+                \ substitute(stmt_keywords, ',$','','')
+    " Convert commas to regex ors
+    let stmt_keywords =
+                \ substitute(stmt_keywords, '\s*,\s*', '\\|', 'g')
+
+    let sql_commands = '\c\<\('.stmt_keywords.'\)\>'
+
+    " Find a line starting with SELECT|UPDATE|DELETE
+    "     .,-             - From that line backup one line due to :g
+    "     /;              - find the ending command delimiter
+    "     SQLUFormatter   - Use the SQLUtilities plugin to format it
+    let cmd = a:firstline.','.a:lastline.'g/^\s*\<\(' .
+                \ stmt_keywords . '\)\>/.,-/' .
+                \ g:sqlutil_cmd_terminator . '/SQLUFormatter'
+    exec cmd
+
+    " Restore default value
+    " And restore cursor position
+    let &hlsearch = hlsearch
+
+    " restore previous format options 
+    let &formatoptions = saveFormatOptions 
+
+    " restore previous search string
+    let @/ = saveSearch
+    
+    silent! exe 'normal! '.curline."G\<bar>".(curcol-1).
+				\ ((curcol-1)>0 ? 'l' : '' )
+
+    if (mode != 'n')
+        " Reselect the visual area, so the user can us gv
+        " to operate over the region again
+        exec 'normal! '.(line("'s")+1).'gg'.'|'.
+                    \ 'V'.(line("'e")-2-line("'s")).'j|'."\<Esc>"
+    endif
+
+    " Delete blanks lines added around the visually selected range
+    silent! exe "normal! 'sdd'edd"
+
+    silent! exe 'normal! '.curline."G\<bar>".(curcol-1).
+				\ ((curcol-1)>0 ? 'l' : '' )
+
+endfunction
+
+" This function will return a count of unmatched parenthesis
+" ie ( this ( funtion ) - will return 1 in this case
+function! s:SQLU_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 'SQLU_CountUnbalancedParan ) returning: ' 
+        " \ . (strlen(rp) - strlen(lp))
+        return (strlen(rp) - strlen(lp))
+    elseif a:paran_to_check =~ '('
+        " echom 'SQLU_CountUnbalancedParan ( returning: ' 
+        " \ . (strlen(lp) - strlen(rp))
+        return (strlen(lp) - strlen(rp))
+    else
+        " echom 'SQLU_CountUnbalancedParan unknown paran to check: ' . 
+        " \ a:paran_to_check
+        return 0
+    endif
+endfunction
+
+" WS: wrapper start (internal)   Creates guard lines,
+"     stores marks y and z, and saves search pattern
+function! s:SQLU_WrapperStart( beginline, endline, mode )
+    let b:curline     = line(".")
+    let b:curcol      = virtcol(".")
+    let b:keepsearch  = @/
+    let b:keepline_mr = line("'r")
+    let b:keepcol_mr  = virtcol("'r")
+    let b:keepline_my = line("'y")
+    let b:keepcol_my  = virtcol("'y")
+    let b:keepline_mz = line("'z")
+    let b:keepcol_mz  = virtcol("'z")
+
+    silent! exec 'normal! '.a:endline."G\<bar>0\<bar>"
+    " Add a new line to the bottom of the mark to be removed later
+    put =''
+    silent! exec "ma z"
+    silent! exec 'normal! '.a:beginline."G\<bar>0\<bar>"
+    " Add a new line above the mark to be removed later
+    put! = ''
+    silent! exec "ma y"
+    let b:cmdheight= &cmdheight
+    set cmdheight=2
+    silent! exec "normal! 'zk"
+endfunction
+
+" WE: wrapper end (internal)   Removes guard lines,
+"     restores marks y and z, and restores search pattern
+function! s:SQLU_WrapperEnd(mode)
+    if (a:mode != 'n')
+        " Reselect the visual area, so the user can us gv
+        " to operate over the region again
+        " exec 'normal! '.(line("'y+1").'gg'.'|'.
+        "             \ 'V'.(line("'z")-2-line("'y")).'j|'."\<Esc>"
+        exec 'normal! gv'."\<Esc>"
+    endif
+
+    " Delete blanks lines added around the visually selected range
+    silent! exe "normal! 'ydd'zdd"
+    silent! exe "set cmdheight=".b:cmdheight
+    unlet b:cmdheight
+    let @/= b:keepsearch
+
+    silent! exe 'normal! '.b:curline."G\<bar>".(b:curcol-1).
+				\ ((b:curcol-1)>0 ? 'l' : '' )
+
+    unlet b:keepline_mr b:keepcol_mr
+    unlet b:keepline_my b:keepcol_my
+    unlet b:keepline_mz b:keepcol_mz
+    unlet b:curline     b:curcol
+endfunction
+
+" Generic Search and Replace uses syntax ID {{{
+function! s:SQLU_SearchReplace(exp_find_str, before_rplc_str, after_rplc_str, exp_srch_rplc_str)
+    call cursor( line("'y"), 1 )
+
+    let keepline_mo = line("'o")
+    let keepcol_mo  = virtcol("'o")
+    let keepline_mp = line("'p")
+    let keepcol_mp  = virtcol("'p")
+
+    " Find the string index position of the first match
+    " 'c'	accept a match at the cursor position
+    " 'W'	don't wrap around the end of the file
+    let search_flags = 'cW'
+    let index = search(a:exp_find_str, search_flags, (line("'z")))
+    while index > 0
+        " Reset to default, as the bottom repeat searches 
+        " can change the default
+        let search_flags = 'cW'
+        " Verify the cursor is within the range
+        if index >= line("'y") && index <= line("'z")
+
+            " Useful debug statment to see where on the line 
+            " and which keyword you are working on
+            " echo line(".") strpart(getline("."), col(".")-1)
+
+            let syn_element_list = split(g:sqlutil_syntax_elements, ',')
+            
+            if !empty(syn_element_list)
+                let found_in_str = 0
+                for syn_element_name in syn_element_list
+                    " Determine the ID for the name in the CSV list
+                    let syn_element_id = hlID(syn_element_name)
+
+                    " Grab the current syntax ID of the match
+                    let childsynid  = synID(line("."),col("."),1)
+                    let parentsynid = synIDtrans(synID(line("."),col("."),1)) 
+
+                    if childsynid == syn_element_id || parentsynid == syn_element_id
+                        let found_in_str = 1
+                        break
+                    endif
+                endfor
+                if found_in_str == 1
+                    " Advance the cursor 1 position since we use 
+                    " 'c' in the flags
+                    call cursor( line("."), (col(".") + 1) )
+                    let index = search(a:exp_find_str, search_flags, (line("'z")))
+                    continue
+                endif
+            endif
+
+            " Mark the current position 
+            exec 'normal! mo'
+
+            " Find the string index position of the end of the match
+            " 'c'	accept a match at the cursor position
+            " 'e'	move to the End of the match
+            " 'W'	don't wrap around the end of the file
+            let search_flags = 'ceW'
+            let index = search(a:exp_find_str, search_flags, (line("'z")))
+
+            " Verify the cursor is within the range
+            if index >= line("'y") && index <= line("'z")
+                " Start a newline at the end of the match 
+                " and create the mark "p".  The mark needs to be
+                " on a newline since substitutions on a line
+                " with the mark looses the mark position which 
+                " prevents us from coming back to it after 
+                " our align first word option.
+                silent! exec "normal! a\<CR>\<Esc>mp"
+                " Return to the start of the match
+                exec 'normal! `o'
+                " Between the beginning mark "o" and the 
+                " ending mark "p" execute the regex expression 
+                " with the supplied substitution.
+                " For debugging:
+                "     echo line(".") col(".") index strpart(getline("."), col(".")-1, 5) getline(".")
+                try
+                    exec "s/\\%'o\\(".a:after_rplc_str."\\)\\%'p/" . a:before_rplc_str
+                catch /.*/
+                    call s:SQLU_WarningMsg(
+                                \ 'SQLU_SR: Match not found on line #:' . 
+                                \ line("'o") .
+                                \ ' Error:' .
+                                \ v:errmsg .
+                                \ ' Line:' .
+                                \ getline("'o")
+                                \ )
+                endtry
+                " Return to the beginning of the match
+                exec 'normal! `o'
+                " Execute last search and and replace based on 
+                " the beginning mark.
+                " For debugging:
+                "     echo line(".") col(".") index strpart(getline("."), col(".")-1, 5) getline(".")
+                try
+                    exec 's/' . a:exp_srch_rplc_str
+                catch /.*/
+                    call s:SQLU_WarningMsg(
+                                \ 'SQLU_SR: Match not found on line #:' . 
+                                \ line("'o") .
+                                \ ' Error:' .
+                                \ v:errmsg .
+                                \ ' Line:' .
+                                \ getline("'o")
+                                \ )
+                endtry
+                " Join the current line just substituted on
+                " and the line where we put the "p" mark.
+                " This effectively places the cursor at the end 
+                " of the initial match (regardless of align first word).
+                exec 'normal! J'
+                " Reset to default, as the bottom repeat searches 
+                " can change the default
+                let search_flags = 'cW'
+            else 
+                return
+            endif
+
+            let index = search(a:exp_find_str, search_flags, (line("'z")))
+        endif
+    endwhile
+    
+endfunction 
+
+" Generic Search and Replace uses syntax ID {{{
+function! s:SQLU_SearchReplaceOld(exp_find_str, before_rplc_str, after_rplc_str, exp_srch_rplc_str)
+    call cursor( line("'y"), 1 )
+
+    let keepline_mo = line("'o")
+    let keepcol_mo  = virtcol("'o")
+    let keepline_mp = line("'p")
+    let keepcol_mp  = virtcol("'p")
+
+    " Find the string index position of the first match
+    " 'c'	accept a match at the cursor position
+    " 'W'	don't wrap around the end of the file
+    let search_flags = 'cW'
+    let index = search(a:exp_find_str, search_flags, (line("'z")))
+    while index > 0
+        " Reset to default, as the bottom repeat searches 
+        " can change the default
+        let search_flags = 'cW'
+        " Verify the cursor is within the range
+        if index >= line("'y") && index <= line("'z")
+
+            " Useful debug statment to see where on the line 
+            " and which keyword you are working on
+            " echo line(".") strpart(getline("."), col(".")-1)
+
+            let syn_element_list = split(g:sqlutil_syntax_elements, ',')
+            
+            if !empty(syn_element_list)
+                let found_in_str = 0
+                for syn_element_name in syn_element_list
+                    " Determine the ID for the name in the CSV list
+                    let syn_element_id = hlID(syn_element_name)
+
+                    " Grab the current syntax ID of the match
+                    let childsynid  = synID(line("."),col("."),1)
+                    let parentsynid = synIDtrans(synID(line("."),col("."),1)) 
+
+                    if childsynid == syn_element_id || parentsynid == syn_element_id
+                        let found_in_str = 1
+                        break
+                    endif
+                endfor
+                if found_in_str == 1
+                    " Advance the cursor 1 position since we use 
+                    " 'c' in the flags
+                    call cursor( line("."), (col(".") + 1) )
+                    let index = search(a:exp_find_str, search_flags, (line("'z")))
+                    continue
+                endif
+            endif
+
+            " Mark the current position 
+            exec 'normal! mo'
+
+            " At the current cursor position \%#
+            exec 's/\%#/' . a:before_rplc_str
+
+            " Return to the start of the current match
+            exec 'normal! `o'
+
+            if a:after_rplc_str != ''
+                " Find the string index position of the end of the match
+                " 'c'	accept a match at the cursor position
+                " 'e'	move to the End of the match
+                " 'W'	don't wrap around the end of the file
+                let search_flags = 'ceW'
+                let index = search(a:exp_find_str, search_flags, (line("'z")))
+
+                " Verify the cursor is within the range
+                if index >= line("'y") && index <= line("'z")
+                    " Mark the current position 
+                    exec 'normal! mp'
+                    " Return to the start of the current match
+                    exec 'normal! ``'
+                    " At the current cursor position \%#
+                    exec 's/\%#/' . a:after_rplc_str
+                    " Remove the 'c' to find the next match
+                    let search_flags = 'W'
+                    " Advance to the end of the current match
+                    exec 'normal! `p'
+                    " Move ahead the size of the replace text
+                    exec 'normal! '.strlen(a:after_rplc_str).'l'
+                endif
+            elseif a:exp_srch_rplc_str != ''
+                " Find the string index position of the end of the match
+                " 'c'	accept a match at the cursor position
+                " 'e'	move to the End of the match
+                " 'W'	don't wrap around the end of the file
+                let search_flags = 'ceW'
+                let index = search(a:exp_find_str, search_flags, (line("'z")))
+
+                " Verify the cursor is within the range
+                if index >= line("'y") && index <= line("'z")
+                    " Mark the current position 
+                    exec 'normal! mp'
+                    " Return to the start of the current match
+                    exec 'normal! ``'
+                    " At the current cursor position \%#
+                    exec 's/\%#' . a:exp_srch_rplc_str
+                    " Remove the 'c' to find the next match
+                    let search_flags = 'W'
+                    " Advance to the end of the current match
+                    exec 'normal! `p'
+                endif
+            else
+                " Advance past the match
+                exec 'normal! w'
+            endif
+
+            let index = search(a:exp_find_str, search_flags, (line("'z")))
+        endif
+    endwhile
+    
+endfunction 
+" }}}
+
+
+" Reformats the statements 
+" 1. Keywords (FROM, WHERE, AND, ... ) " are on new lines
+" 2. Keywords are right justified
+" 3. CASE statements are setup for alignment.
+" 4. Operators are lined up
+" 
+function! s:SQLU_ReformatStatement()
+    if exists("b:current_syntax") == 0 || g:sqlutil_use_syntax_support == 0
+        " Remove any lines that have comments on them since the comments
+        " could spill onto new lines and no longer have comment markers
+        " which would result in syntax errors
+        " Comments could also contain keywords, which would be split
+        " on to new lines
+        call cursor( line("'y"), 0 )
+        " Find the string index position of the first match
+        " 'W'	don't wrap around the end of the file
+        " Check for standard SQL comment indicators
+        "    --
+        "    //
+        "    /*
+        "    */
+        let search_flags = 'W'
+        let index = search(g:sqlutil_comment_regex, search_flags, (line("'z")))
+       
+        if index > 0 
+            " Comments found, confirm with user to delete them
+            let choice = confirm( 
+                        \ 'SQLU: Comments found, without syntax support these must be ' .
+                        \ 'removed before formatting.  Is this Ok?'
+                        \ , "&No\n&Yes\n&Cancel"
+                        \ , 1
+                        \ )
+            if choice != 2
+                return -1
+            endif
+            if exists("b:current_syntax") == 0 || g:sqlutil_use_syntax_support == 0
+                " First remove only comment lines
+                silent! 'y+1,'z-1g/^\s*\(--\|\/\/\)/d
+                " Now remove comments from the end of lines
+                silent! 'y+1,'z-1s/\(--\|\/\/\).*$//ge
+            endif
+        endif
+    endif
+
+    " Check to see if multiple statements have been specified 
+    " by checking for ;.  If more than 1, show an error message.
+    call cursor( line("'y"), 0 )
+    " Find the string index position of the first match
+    " 'W'	don't wrap around the end of the file
+    let search_flags = 'W'
+    let index = search('\(;\|^go\>\)', search_flags, (line("'z")))
+    if index > 0 
+        let index = search('\(;\|^go\>\)', search_flags, (line("'z")))
+        if index > 0 
+            call s:SQLU_WarningMsg(
+                        \ 'SQLU: You can only reformat one statement at a time, found multiple ";" or "go" '
+                        \ )
+            return -1
+        endif
+    endif
+
+    " Removed in SQLUtilities 7.0
+    if exists("b:current_syntax") == 0 || g:sqlutil_use_syntax_support == 0
+        " Join block of text into 1 line
+        " All comments were removed earlier
+        silent! 'y+1,'z-1j
+    else
+        " If the line is only a comment, we leave it.
+        " If the comment is at the end of a line, we join
+        " as many lines as possible prior to it.
+        let only_comments = 1
+        let linenum = line("'y")+1
+        while linenum < line("'z")-1
+            if getline(linenum) !~ g:sqlutil_comment_regex
+                let only_comments = 0
+                exec 'silent! '.linenum.'j'
+            else
+                if only_comments == 1 && getline(linenum) =~ '^\s*\(--\|\/\/\)'
+                    silent! s/^\s*\zs--/-@-\(--\|\/\/\)/
+                elseif only_comments == 0 && getline(linenum) =~ '^\s*\(--\|\/\/\)'
+                    silent! s/^\s*\zs\(--\|\/\/\)/-@- \1/
+                endif
+                let linenum = linenum + 1
+            endif
+        endwhile
+    endif
+    " Reformat the commas, to remove any spaces before them
+    " As long as the line is not a comment
+    silent! 'y+1,'z-1v/^\s*\(--\|\/\/\)/s/\s*,/,/ge
+    " Change more than 1 space with just one except spaces at
+    " the beginning of the range
+    silent! 'y+1,'z-1v/^\s*\(--\|\/\/\)/s/\(\S\+\)\(\s\+\)/\1 /g
+    " Place a special marker at the start of the line
+    " of a comment for formatting purposes
+    " Don't do this as this will mess up the alignment 
+    " of comments.  Now, when we join the lines ignoring 
+    " comments, we will either put the marker in front 
+    " of the line, or the marker with a space following it 
+    " that will allow us to align properly.
+    " silent! 'y+1,'z-1s/^\s*\zs--/-@---/
+    " Go to the start of the block
+    silent! 'y+1
+
+    " Place an UPDATE on a newline, but not if it is preceeded by
+    " the existing statement.  Example:
+    "           INSERT INTO T1 (...)
+    "           ON EXISTING UPDATE
+    "           VALUES (...);
+    "           SELECT ...
+    "           FOR UPDATE
+    let sql_update_keywords = '' . 
+                \ '\%(\%(\<\%(for\|existing\)\s\+\)\@<!update\)'
+    " WINDOW clauses can be used in both the SELECT list
+    " and after the HAVING clause.
+    let sql_window_keywords = '' . 
+                \ 'over\|partition\s\+by\|' .
+                \ '\%(rows\|range\)\s\+' .
+                \ '\%(between\|unbounded\|current\|preceding\|following\)'
+    " INTO clause can be used in a SELECT statement as well 
+    " as an INSERT statement.  We do not want to place INTO
+    " on a newline if it is preceeded by INSERT
+    let sql_into_keywords = '' . 
+                \ '\%(\%(\<\%(insert\|merge\)\s\+\)\@<!into\)'
+    " Normally you would add put an AND statement on a new
+    " line.  But in the cases where you are dealing with
+    " a BETWEEN '1963-1-1' AND '1965-3-31', we no not want
+    " to put the AND on a new line
+    " Do not put AND on a new line if preceeded by
+    "      between<space><some text not including space><space>AND
+    let sql_and_between_keywords = '' . 
+                \ '\%(\%(\<between\s\+[^ ]\+\s\+\)\@<!and\)'
+    " For SQL Remote (ASA), this is valid syntax
+    "           SUBSCRIBE BY
+    "       OLD SUBSCRIBE BY
+    "       NEW SUBSCRIBE BY
+    let sql_subscribe_keywords = '' . 
+                \ '\%(\%(\<\%(old\|new\)\s\+\)\?subscribe\)'
+    " Oracle CONNECT BY statement
+    let sql_connect_by_keywords = '' . 
+                \ 'connect\s\+by\s\+\w\+'
+    " Oracle MERGE INTO statement
+    "      MERGE INTO ...
+    "      WHEN MATCHED THEN ...
+    "      WHEN NOT MATCHED THEN ....
+    " Match on the WHEN clause (with zero width) if it is followed
+    " by [not] matched
+    let sql_merge_keywords = '' . 
+                \ '\%(merge\s\+into\)\|\%(when\(\s\+\%(not\s\+\)\?matched\)\@=\)'
+    " Some additional Oracle keywords from the SQL Reference for SELECT
+    let sql_ora_keywords = '' .
+                \ '\%(dimension\s\+by\|' .
+                \ 'measures\s*(\|' .
+                \ 'iterate\s*(\|' .
+                \ 'within\s\+group\|' .
+                \ '\%(ignore\|keep\)\s\+nav\|' .
+                \ 'return\s\+\%(updated\|all\)\|' .
+                \ 'rules\s\+\%(upsert\|update\)\)'
+    " FROM clause can be used in a DELETE statement as well 
+    " as a SELECT statement.  We do not want to place FROM
+    " on a newline if it is preceeded by DELETE
+    let sql_from_keywords = '' . 
+                \ '\%(\%(\<delete\s\+\)\@<!from\)'
+    " Only place order on a newline if followed by "by"
+    " let sql_order_keywords = '' .  \ '\%(\%(\<order\s\+\)\@<!into\)'
+
+    " join type syntax from ASA help file
+    " INNER
+    " | LEFT [ OUTER ]
+    " | RIGHT [ OUTER ]
+    " | FULL [ OUTER ]
+    " LEFT, RIGHT, FULL can optional be followed by OUTER
+    " The entire expression is optional
+    let sql_join_type_keywords = '' . 
+                \ '\%(' .
+                \ '\%(inner\|' .
+                \ '\%(\%(\%(left\|right\|full\)\%(\s\+outer\)\?\s*\)\?\)' .
+                \ '\)\?\s*\)\?'
+    " Decho 'join types: ' . sql_join_type_keywords
+    " join operator syntax
+    " [ KEY | NATURAL ] [ join_type ] JOIN
+    " | CROSS JOIN
+    let sql_join_operator = '' .
+                \ '\%(' .
+                \ '\%(\%(\%(key\|natural\)\?\s*\)\?' .
+                \ sql_join_type_keywords .
+                \ 'join\)\|' .
+                \ '\%(\%(\%(cross\)\?\s*\)\?join\)' .
+                \ '\)'
+    " Decho 'join types: ' . sql_join_type_keywords
+    " join operator syntax
+    " [ KEY | NATURAL ] [ join_type ] JOIN
+    " | CROSS JOIN
+    " force each keyword onto a newline
+    let sql_keywords =  '\<\%(create\|drop\|call\|select\|set\|values\|declare\|cursor\|' .
+                \ sql_update_keywords . '\|' .
+                \ sql_into_keywords . '\|' .
+                \ sql_and_between_keywords . '\|' .
+                \ sql_from_keywords . '\|' .
+                \ sql_join_operator . '\|' .
+                \ sql_subscribe_keywords . '\|' .
+                \ sql_connect_by_keywords . '\|' .
+                \ sql_merge_keywords . '\|' .
+                \ sql_ora_keywords . '\|' .
+                \ 'on\|where\|or\|\%(order\|group\)\s\+\%(\w\+\s\+\)\?\<by\>\|'.
+                \ sql_window_keywords . '\|' .
+                \ 'having\|for\|insert\%(\s\+\|-@-\)into\|delete\%(\s\+\|-@-\)from\|using\|' .
+                \ 'intersect\|except\|window\|' .
+                \ '\%(union\%(\s\+all\)\?\)\|' .
+                \ 'start\s\+with\|' .
+                \ '\%(\%(\<start\s\+\)\@<!with\)\)\>'
+    " The user can specify whether to align the statements based on 
+    " the first word, or on the matching string.
+    "     let g:sqlutil_align_first_word = 0
+    "           select
+    "             from
+    "         union all
+    "     let g:sqlutil_align_first_word = 1
+    "           select
+    "             from
+    "            union all
+    let srch_exp = '\c\%(^\s*\)\?\zs\<\(' .
+                \ sql_keywords .
+                \ '\)\>\s*'
+
+    " Place all SQL keywords on a newline.
+    " The position of the -@- depends on the setting of 
+    " the g:sqlutil_align_first_word option.
+    " If 0, the -@- is at the start of the line.
+    " If 1, the -@- is after the first word.
+    if exists("b:current_syntax") == 0 || g:sqlutil_use_syntax_support == 0
+        let cmd = "'y+1,'z-1s/". srch_exp .
+                    \ '/\r\1' .
+                    \ ( g:sqlutil_align_first_word==0 ? '-@-' : ' ' ) .
+                    \ '/ge'
+        " Decho cmd
+        silent! exec cmd
+        " Ensure keywords at the beginning of a line have a space after them
+        " This will ensure the Align program lines them up correctly
+        silent! 'y+1,'z-1s/^\([a-zA-Z0-9_]*\)(/\1 (/e
+
+        if g:sqlutil_align_first_word == 1
+            silent! 'y+1,'z-1s/^\s*\zs\([a-zA-Z0-9_]\+\)\>\s*/\1-@-/
+        endif
+    else
+        " This uses Vim's syntax support to determine if
+        " a match is found within a string (or comment) or not.
+        " Therefore only do it if syntax support is on
+        " which can be tested checking for the existance
+        " of the buffer local variable b:current_syntax
+        "    call s:SQLU_SearchReplace(srch_exp
+        "                \ , '\r\1'
+        "                \ , (g:sqlutil_align_first_word==0 ? '-@-' : '')
+        "                \ , (g:sqlutil_align_first_word==1 ? '\(\w\+\)\s*/\1-@-' : '')
+        "                \ )
+        if g:sqlutil_align_first_word == 0
+            call s:SQLU_SearchReplace(srch_exp, '\1-@-', '.*\n.*', '\(^\s*\)\@<!\%'."'".'o/\r/e' )
+        else
+            call s:SQLU_SearchReplace(srch_exp, '\2-@-\3', '\(\w\+\)\(.*\n.*\)', '\(^\s*\)\@<!\%'."'".'o/\r/e' )
+        endif
+    endif
+
+    " Ensure CASE statements also start on new lines
+    " CASE statements can also be nested, but we want these to align
+    " with column lists, not keywords, so the -@- is placed BEFORE
+    " the CASE keywords, not after
+    "
+    " The CASE statement and the Oracle MERGE statement are very similar.
+    " I have changed the WHEN clause to check to see if it is followed
+    " by [NOT] MATCHED, if so, do not match the WHEN
+    let sql_case_keywords = '\(\<end\s\+\)\@<!case' .
+                \ '\|\<when\>\(\%(-@-\)\?\s*\%(not\s\+\)\?matched\)\@!' .
+                \ '\|else\|end\(\s\+case\)\?' 
+
+    " echom 'case: '.sql_case_keywords
+    " The case keywords must not be proceeded by a -@-
+    " silent! exec "'y+1,'z-1".'s/'.
+    "             \ '\%(-@-\)\@<!'.
+    "             \ '\<\('.
+    "             \ sql_case_keywords.
+    "             \ '\)\>/\r-@-\1/gei'
+    let srch_exp = '\c\%(-@-\)\@<!'.
+                \ '\<\('.
+                \ sql_case_keywords.
+                \ '\)\>'
+
+    " For all CASE keywords, place them on a new line followed by the 
+    " alignment marker
+    if exists("b:current_syntax") == 0 || g:sqlutil_use_syntax_support == 0
+        let cmd = "'y+1,'z-1s/". srch_exp .
+                    \ '/\r-@-\1' .
+                    \ '/ge'
+        " Decho cmd
+        silent! exec cmd
+    else
+        " This uses Vim's syntax support to determine if
+        " a match is found within a string or not.
+        " Therefore only do it if syntax support is on
+        " which can be tested checking for the existance
+        " of the buffer local variable b:current_syntax
+        " call s:SQLU_SearchReplace(srch_exp, '\r-@-\1', '.*', '' )
+        " call s:SQLU_SearchReplace(srch_exp, '\2-@-\3', '\(\w\+\)\(.*\n\)', '\(^\s*\)\@<!\%'."'".'o/\r/e' )
+        call s:SQLU_SearchReplace(srch_exp, '-@-\2', '\(.*\n.*\)', '\(^\s*\)\@<!\%'."'".'o/\r/e' )
+    endif
+
+    " If g:sqlutil_align_first_word == 0, then we need only add the -@-
+    " on the first word, else we need to do it to the first word
+    " on each line
+    " silent! exec "'y+1," .  
+    "             \ ( g:sqlutil_align_first_word==0 ? "'y+1" : "'z-1" ) .  
+    "             \ 's/^\s*\<\w\+\>\zs\s*/-@-'
+    silent! exec "'y+1,'z-1".'v/-@-/s/^\s*\zs/-@-'
+
+    " AlignPush
+
+    " Using the Align.vim plugin, reformat the lines
+    " so that the keywords are RIGHT justified
+    " AlignCtrl default
+
+    if g:sqlutil_align_comma == 1 
+        call s:SQLU_WrapAtCommas()
+    endif
+
+    if g:sqlutil_wrap_function_calls == 1 
+        call s:SQLU_WrapFunctionCalls()
+    endif
+
+    if g:sqlutil_split_unbalanced_paran == 1 
+        let ret = s:SQLU_SplitUnbalParan()
+        if ret < 0
+            " Undo any changes made so far since an error occurred
+            " silent! exec 'u'
+            return ret
+        endif
+    endif
+
+    if g:sqlutil_wrap_long_lines == 1
+        let ret = s:SQLU_WrapLongLines( '^'.sql_keywords )
+        if ret < 0
+            " Undo any changes made so far since an error occurred
+            " silent! exec 'u'
+            return ret
+        endif
+    endif
+
+    " Removed in SQLUtilities 7.0
+    if exists("b:current_syntax") == 1 || g:sqlutil_use_syntax_support == 1
+        " Comments before the first statement must be formatted 
+        " differently that comments within the SQL being formatted.
+        " To achieve this, any comment line beginning with -@--- 
+        " within a SQL statement should be changed to -@- --
+        " so that the formatting will change.  The fact the comment 
+        " is indented 1 additional space cannot be helped.
+        let only_comments = 1
+        let linenum = line("'y")+1
+        while linenum < line("'z")-1
+            if getline(linenum) !~ '^\s*-@-\(--\|\/\/\)'
+                let only_comments = 0
+            else
+                if only_comments == 0 && getline(linenum) =~ '^\s*-@-\(--\|\/\/\)'
+                    silent! exec linenum.','.linenum.'s/-@-\(--\|\/\/\)/-@- \1/'
+                endif
+            endif
+            let linenum = linenum + 1
+        endwhile
+    endif
+
+    " When formatting, ignore lines beginning with a comment
+    " AlignCtrl v ^\s*-@-\(--\|\/\/\)
+
+    " Align these based on the special charater
+    " and the column names are LEFT justified
+    " Ip0P0l
+    "   I : retain only the first line's initial white space and
+    "       re-use it for subsequent lines
+    " p0P0: put no spaces both before and after separators
+    "   l : left-justify fields between separators, cyclically. Ie. llllllll...
+    let align_ctrl = 'Ip0P0'.(g:sqlutil_align_keyword_right==1?'r':'l').'l:'
+    silent! exec 'AlignCtrl '.align_ctrl
+    " silent! 'y+1,'z-1Align -@-
+    silent! 'y+1,'z-1s/-@-/ /ge
+
+    " Now that we have removed the special alignment marker
+    " upper or lower case all the keywords only if the user
+    " has specified an override.
+    if g:sqlutil_keyword_case != ''
+        let cmd = "'y+1,'z-1".'s/\<\(' .
+                    \ sql_keywords .
+                    \ '\|' .
+                    \ sql_case_keywords .
+                    \ '\|' .
+                    \ sql_join_type_keywords .
+                    \ '\|' .
+                    \ substitute(g:sqlutil_non_line_break_keywords, ',', '\\|', 'g') .
+                    \ '\)\>/' .
+                    \ g:sqlutil_keyword_case .
+                    \ '\1/gei'
+        silent! exec cmd
+    endif
+
+    " Now align the operators 
+    " and the operators are CENTER justified
+    if g:sqlutil_align_where == 1
+        " If I may explain what you're doing with the commands you've given:
+        "     AlignCtrl default
+        "         This resets AlignCtrl to default settings
+        "     AlignCtrl g [!<>=]
+        "         This command says to only consider aligning lines containing
+        "         one of the characters matching [!<>=].  Lines without those
+        "         characters are ignored.
+        "     AlignCtrl Wp1P1l
+        "         W    : retain all selected lines' initial white space
+        "         p1P1 : put one space both before and after separators
+        "         l    : left-justify fields between separators, cyclically. Ie. llllllll...
+        " 
+        "     * The separators are  =  <  >  <>
+        "     * you only want the first separator to be active
+        " 
+        " So, to do this:
+        "     AlignCtrl default
+        "     AlignCtrl g [!<>=]
+        "     AlignCtrl Wp1P1l:
+        "     [range]Align =\|[!<>]\ze[^<>=]\|<>\|<=\|>=\|!>\|!<\|!=
+        " 
+        " I've added a ":" to the AlignCtrl field control pattern; this means
+        " that only one separator (ie. field - separator - field) is to be
+        " aligned.
+        " I've set up the separator pattern to recognize = < > and <> as
+        " separators.
+        " 
+        " This won't do the "< parameter >" conversion to "<parameter>"; it
+        " will preserve it whichever way its written.
+        " AlignCtrl default
+        " AlignCtrl g [!<>=]
+        " AlignCtrl Wp1P1l:
+
+        " Change this to only attempt to align the last WHERE clause
+        " and not the entire SQL statement
+        " Valid operators are: 
+        "      =, >, <, >=, <=, !=, !<, !>, <> 
+        if search('\c\%(\%>'.line("'y").'l\%<'.line("'z").'l\)\&\<WHERE\>')
+            " v17.00 
+            " silent! exec line(".").",'z-1".'Align [!<>=]\(<\|>\|=\)'
+            " v18.00
+            " silent! exec line(".").",'z-1".'Align =\|[!<>]\ze[^<>=]\|<>\|<=\|>=\|!>\|!<\|!='
+        endif
+    endif
+
+    " Reset back to defaults
+    " AlignCtrl default
+
+    " Reset the alignment to what it was prior to 
+    " this function
+    " AlignPop
+
+    " Remove any trailing spaces which can be added 
+    " after aligning.
+    silent! 'y+1,'z-1s/\s\+$//
+    " Delete any blank lines
+    silent! 'y+1,'z-1g/^$/d
+
+    return 1
+endfunction
+
+" Check through the selected text for open ( and
+" indent if necessary
+function! s:SQLU_IndentNestedBlocks()
+
+    let org_textwidth = &textwidth
+    if &textwidth == 0 
+        " Get the width of the window
+        let &textwidth = winwidth(winnr())
+    endif
+    
+    let sql_keywords = '\<\%(select\|set\|\%(insert\s\+\)\?into\|from\|values'.
+                \ '\|order\|group\|having\|return\|call\)\>'
+
+    " Indent nested blocks surrounded by ()s.
+    let linenum = line("'y")+1
+    while linenum <= line("'z")-1
+        let line = getline(linenum)
+        if line =~ '(\s*$'
+            let begin_paran = match( line, '(\s*$' )
+            if begin_paran > -1
+                let curline     = line(".")
+                let curcol      = begin_paran + 1
+                " echom 'begin_paran: '.begin_paran.
+                "             \ ' line: '.curline.
+                "             \ ' col: '.curcol
+                silent! exe 'normal! '.linenum."G\<bar>".curcol."l"
+                " v  - visual
+                " ib - inner block
+                " k  - backup on line
+                " >  - right shift
+                " .  - shift again
+                " silent! exe 'normal! vibk>.'
+                silent! exe 'normal! vib>'
+                
+                " If the following line begins with a keyword, 
+                " indent one additional time.  This is necessary since 
+                " keywords are right justified, so they need an extra
+                " indent
+                if getline(linenum+1) =~? '\c^\s*\('.sql_keywords.'\)'
+                    silent! exe 'normal! .'
+                endif
+                " echom 'SQLU_IndentNestedBlocks - from: '.line("'<").' to: ' .
+                "             \ line("'>") 
+                " echom 'SQLU_IndentNestedBlocks - no match: '.getline(linenum)
+            endif
+        endif
+
+        let linenum = linenum + 1
+    endwhile
+
+    let ret = linenum
+
+    "
+    " Indent nested CASE blocks
+    "
+    let linenum = line("'y")+1
+    " Search for the beginning of a CASE statement
+    let begin_case = '\<\(\<end\s\+\)\@<!case\>'
+
+    silent! exe 'normal! '.linenum."G\<bar>0\<bar>"
+
+    while( search( begin_case, 'W' ) > 0 )
+        " Check to see if the CASE statement is inside a string
+        if synID(line("."),col("."),1) > 0
+            continue
+        endif
+        let curline = line(".")
+        if( (curline < line("'y")+1)  || (curline > line("'z")-1) )
+            " echom 'No case statements, leaving loop'
+            silent! exe 'normal! '.(line("'y")+1)."G\<bar>0\<bar>"
+            break
+        endif
+        " echom 'begin CASE found at: '.curline
+        let curline = curline + 1
+        let end_of_case = s:SQLU_IndentNestedCase( begin_case, curline, 
+                    \ line("'z")-1 )
+        let end_of_case = end_of_case + 1
+        let ret = end_of_case
+        if( ret < 0 )
+            break
+        endif
+        silent! exe 'normal! '.end_of_case."G\<bar>0\<bar>"
+    endwhile
+
+    "
+    " Indent Oracle nested MERGE blocks
+    "
+    let linenum = line("'y")+1
+    " Search for the beginning of a CASE statement
+    let begin_merge = '\<merge\s\+into\>'
+
+    silent! exe 'normal! '.linenum."G\<bar>0\<bar>"
+
+    if( search( begin_merge, 'W' ) > 0 )
+        let curline = line(".")
+        if( (curline < line("'y")+1)  || (curline > line("'z")-1) )
+            " echom 'No case statements, leaving loop'
+            silent! exe 'normal! '.(line("'y")+1)."G\<bar>0\<bar>"
+        else
+            " echom 'begin CASE found at: '.curline
+            let curline = curline + 1
+
+            while 1==1
+                " Find the matching when statement
+                " let match_merge = searchpair('\<merge\s\+into\>', 
+                let match_merge = searchpair('\<merge\>', '',
+                            \ '\<\%(when\s\+\%(not\s\+\)\?matched\)', 
+                            \ 'W', '' )
+                if( (match_merge < curline) || (match_merge > line("'z-1")) )
+                    silent! exec curline . "," . line("'z-1") . ">>"
+                    break
+                else
+                    if match_merge > (curline+1)
+                        let savePos = 'normal! '.line(".").'G'.col(".")."\<bar>"
+                        silent! exec curline . "," . (match_merge-1) . ">>"
+                        silent! exec savePos
+                    endif
+                    let curline = match_merge + 1
+                endif
+            endwhile
+        endif
+    endif
+
+    let &textwidth = org_textwidth
+    return ret
+endfunction
+
+" Recursively indent nested case statements
+function! s:SQLU_IndentNestedCase( begin_case, start_line, end_line )
+
+    " Indent nested CASE blocks
+    let linenum = a:start_line
+
+    " Find the matching end case statement
+    let end_of_prev_case = searchpair(a:begin_case, '', 
+                \ '\<end\( case\)\?\>', 'W', '' )
+
+    if( (end_of_prev_case < a:start_line) || (end_of_prev_case > a:end_line) )
+        call s:SQLU_WarningMsg(
+                    \ 'SQLU_IndentNestedCase - No matching end case for: ' .
+                    \ getline((linenum-1))
+                    \ )
+        return -1
+    " else
+        " echom 'Matching END found at: '.end_of_prev_case
+    endif
+
+    silent! exe 'normal! '.linenum."G\<bar>0\<bar>"
+
+    if( search( a:begin_case, 'W' ) > 0 )
+        let curline = line(".")
+        if( (curline > a:start_line) && (curline < end_of_prev_case) )
+            let curline = curline + 1
+            let end_of_case = s:SQLU_IndentNestedCase( a:begin_case, curline, 
+                        \ line("'z-1") )
+            " echom 'SQLU_IndentNestedCase from: '.linenum.' to: '.end_of_case
+            silent! exec (curline-1) . "," . end_of_case . ">>"
+        " else
+        "     echom 'SQLU_IndentNestedCase No case statements, '.
+        "                 \ 'leaving SQLU_IndentNestedCase: '.linenum
+        endif
+    endif
+
+    return end_of_prev_case
+endfunction
+
+" For certain keyword lines (SELECT, ORDER BY, GROUP BY, ...)
+" Ensure the lines fit in the textwidth (or default 80), wrap
+" the lines where necessary and left justify the column names
+function! s:SQLU_WrapFunctionCalls()
+    " Check if this is a statement that can often be longer than 80 characters
+    " (select, set and so on), if so, ensure the column list is broken over as
+    " many lines as necessary and lined up with the other columns
+    let linenum = line("'y")+1
+
+    let org_textwidth = &textwidth
+    if org_textwidth == 0 
+        " Get the width of the window
+        let curr_textwidth = winwidth(winnr())
+    else
+        let curr_textwidth = org_textwidth
+    endif
+
+    let sql_keywords = '\<\%(select\|set\|\%(insert\(-@-\s*\)\?\)into' .
+                \ '\|from\|values'.
+                \ '\|order\|group\|having\|return\|with\)\>'
+
+    " Useful in the debugger
+    " echo linenum.' '.func_call.' '.virtcol(".").' 
+    " '.','.substitute(getline("."), '^ .*\(\%'.(func_call-1).'c...\).*', 
+    " '\1', '' ).', '.getline(linenum)
+
+    " call Decho(" Before column splitter 'y+1=".line("'<").
+    " \ ":".col("'<")."  'z-1=".line("'>").":".col("'>"))
+    while linenum <= line("'z")-1
+        let line = getline(linenum)
+
+        if strlen(line) < curr_textwidth
+            let linenum = linenum + 1
+            continue
+        endif
+
+        let get_func_nm = '[a-zA-Z_.]\+\s*('
+
+        " Use a special line textwidth, since if we split function calls
+        " any text within the parantheses will be indented 2 &shiftwidths
+        " so when calculating where to split, we must take that into
+        " account
+        let keyword_str = matchstr(
+                    \ getline(linenum), '\c^\s*\('.sql_keywords.'\)' )
+
+        let line_textwidth = curr_textwidth - strlen(keyword_str)
+        let func_call = 0
+        while( strlen(getline(linenum)) > line_textwidth )
+
+            " Find the column # of the start of the function name
+            let func_call = match( getline(linenum), get_func_nm, func_call )
+            if func_call < 0 
+                " If no functions found, move on to next line
+                break
+            endif
+
+            let prev_func_call = func_call
+
+            " Position cursor at func_call
+            silent! exe 'normal! '.linenum."G\<bar>".func_call."l"
+
+            if search('(', 'W') > linenum
+                call s:SQLU_WarningMsg(
+                            \ 'SQLU_WrapFunctionCalls - should have found a ('
+                            \ )
+                let linenum = linenum + 1
+                break
+            endif
+
+            " Check to ensure the paran is not part of a string
+            " Otherwise ignore and move on to the next paran
+            if synID(line("."),col("."),1) == 0
+                " let end_paran = searchpair( '(', '', ')', '' )
+                " Ignore parans that are inside of strings
+                let end_paran = searchpair( '(', '', ')', '',
+                            \ 'synID(line("."),col("."),1)>0' )
+                if end_paran < linenum || end_paran > linenum
+                    " call s:SQLU_WarningMsg(
+                    "             \ 'SQLU_WrapFunctionCalls - ' . 
+                    "             \ 'should have found a matching ) for :' .
+                    "             \ getline(linenum)
+                    "             \ )
+                    let linenum = linenum + 1
+                    break
+                endif
+
+                " If the matching ) is past the textwidth
+                if virtcol(".") > line_textwidth
+                    if (virtcol(".")-func_call) > line_textwidth
+                        " Place the closing brace on a new line only if
+                        " the entire length of the function call and 
+                        " parameters is longer than a line
+                        silent! exe "normal! i\r-@-\<esc>"
+                    endif
+                    " If the SQL keyword preceeds the function name don't
+                    " bother placing it on a new line
+                    let preceeded_by_keyword = 
+                                \ '\c^\s*' .
+                                \ '\(' .
+                                \ sql_keywords .
+                                \ '\|,' .
+                                \ '\)' .
+                                \ '\(-@-\)\?' .
+                                \ '\s*' .
+                                \ '\%'.(func_call+1).'c'
+                    " echom 'preceeded_by_keyword: '.preceeded_by_keyword
+                    " echom 'func_call:'.func_call.' Current 
+                    " character:"'.getline(linenum)[virtcol(func_call)].'"  - 
+                    " '.getline(linenum)
+                    if getline(linenum) !~? preceeded_by_keyword
+                        " Place the function name on a new line
+                        silent! exe linenum.'s/\%'.(func_call+1).'c/\r-@-'
+                        let linenum = linenum + 1
+                        " These lines will be indented since they are wrapped
+                        " in parantheses.  Decrease the line_textwidth by
+                        " that amount to determine where to split nested 
+                        " function calls
+                        let line_textwidth = line_textwidth - (2 * &shiftwidth)
+                        let func_call = 0
+                        " Get the new offset of this function from the start
+                        " of the newline it is on
+                        let prev_func_call = match(
+                                    \ getline(linenum),get_func_nm,func_call)
+                    endif
+                endif
+            endif
+
+            " Get the name of the previous function
+            let prev_func_call_str = matchstr(
+                        \ getline(linenum), get_func_nm, prev_func_call )
+            " Advance the column by its length to find the next function
+            let func_call = prev_func_call +
+                        \ strlen(prev_func_call_str) 
+
+        endwhile
+
+        let linenum = linenum + 1
+    endwhile
+
+    let &textwidth = org_textwidth
+    return linenum
+endfunction
+
+" For certain keyword lines (SELECT, SET, INTO, FROM, VALUES)
+" put each comma on a new line and align it with the keyword 
+"     SELECT c1
+"          , c2
+"          , c3
+function! s:SQLU_WrapAtCommas()
+    let linenum    = line("'y")+1
+    let paran_done = 0
+
+    " These keywords typically have column lists:
+    " SELECT c1, c2, c3 
+    " SET c1 = 1, c2 = 2
+    " INTO var1, var2 
+    " FROM t1, t2
+    " VALUES( var1, var2 )
+    " INSERT INTO T1 (c1, c2)
+    " , - If we have already broken the line up
+    let sql_keywords = '\c^\s*\<\%(select\|set\|into\|from\|values\|insert\|,\)\>'
+
+    " call Decho(" Before column splitter 'y+1=".line("'<").
+    " \ ":".col("'<")."  'z-1=".line("'>").":".col("'>"))
+    while linenum <= line("'z-1")
+        let line = getline(linenum)
+        if line =~? '\w'
+            silent! exec linenum 
+            " Mark the start of the line
+            silent! exec "normal! mb"
+            " echom "line b - ".getline("'b")
+            " Mark the next line
+            silent! exec "normal! jmek"
+
+            let saved_linenum = linenum
+            " let index = match(getline(linenum), '[,(]')
+            " Find the first , or (
+            let index = match(getline(linenum), (g:sqlutil_align_comma==1?'[,(]':'[,]'))
+            while index > -1
+                " Go to the , or (
+                call cursor(linenum, (index+1))
+
+                " Assuming syntax is on, check to ensure the , or (
+                " is not a string
+                if getline(linenum)[col(".")-1] == '(' 
+                    if synID(line("."),col("."),1) == 0
+                        " When paran_done was set, it was for a particular keyword 
+                        " as we move through the lines, the ending ) for that 
+                        " keyword should reset the value for future keywords.
+                        " Classic case is:
+                        "     INSERT INTO T1 () <-- reset on closing )
+                        "     VALUES ()
+                        if line('"r') <= linenum
+                            let paran_done = 0
+                        endif
+
+                        " Only do this once and only in the special cases of 
+                        "    1.  INSERT INTO [owner].t1 (
+                        "    2.  VALUES (
+                        " If the opening ( is found after these cases, ignore
+                        " the special processing of them
+                        "     Starting at this linenum 
+                        "     Look for the VALUES or INSERT patterns 
+                        "     Followed by the ( at the exact column position
+                        " Flags - Do not move cursor
+                        if search( '\c^\%'.linenum.'l\s*\<\%(values\%(\s*\|-@-\)\|insert\%(\s\+\|-@-\)into\s\+\S\+\s*\)\%'.(index+1).'v(', 'n' ) == 0
+                            let paran_done = 1
+                        endif
+
+                        " The paran is not part of a string.
+                        " There can be 2 cases now.
+                        "    1.  It is part of a statement (INSERT)
+                        "    2.  It is the start of a function()
+
+                        " Case 1
+                        " Check if we are at a point where we expect commas
+                        if paran_done == 0 && line =~? sql_keywords
+                            " In case 1, we want to move to the matched 
+                            " closing paran and place it on a newline so that 
+                            " it will align with the commas.
+                            if searchpair( '(', '', ')', '',
+                                        \ 'synID(line("."),col("."),1)>0' ) > 0
+                                let matched_linenum = line(".")
+                                let matched_index   = col(".")
+
+                                " But only do this if there is at least 1 comma 
+                                " between these matched ()s.
+                                " The pattern uses :h \%l
+                                if search('\%(\%(\%'.linenum.'l\%>'.(index+1).'v\)\|\%(\%'.matched_linenum.'l\%<'.(matched_index+1).'v\)\)\&,')
+                                    " Found a comma between these ()s,
+                                    " therefore at the closing paran, move it 
+                                    " on to a separate line
+                                    silent! exec matched_linenum . ',' . matched_linenum . 
+                                                \ 's/\%' . (matched_index) . 'c)\s*' .
+                                                \ '/\r' .
+                                                \ ')-@- '
+                                                " \ (g:sqlutil_align_keyword_right == 1 ? ')-@-' : '-@-) ')
+                                    let paran_done = 1
+                                    silent! exec (matched_linenum+1).','.(matched_linenum+1).'mark r'
+                                endif
+                            endif
+
+                            " Now that we have moved to the end of the matched 
+                            " paranthesis, check again for our comma or paran
+                            let index = index + 1
+                            let index = match( getline(linenum), '[,(]', index )
+
+                            continue
+                        endif
+
+                        " Case 2
+                        " If part of a function skip to the end 
+                        " of the paranthesis
+
+                        " if searchpair( '(', '', ')', '' ) > 0
+                        " Ignore parans that are inside of strings
+                        if searchpair( '(', '', ')', '',
+                                    \ 'synID(line("."),col("."),1)>0' ) > 0
+                            let linenum = line(".")
+                            let index   = col(".")
+
+                            " Now that we have moved to the end of the matched 
+                            " paranthesis, check again for our comma or paran
+                            let index = match( getline(linenum), '[,(]', index )
+
+                            continue
+                        endif
+                    else
+                        " The ( found was within a comment, so advance
+                        " the match, and find the next match
+                        let index = index + 1
+                        let index = match( getline(linenum), '[,(]', index )
+
+                        continue
+                    endif
+                elseif getline(linenum)[col(".")-1] == ','
+                    if synID(line("."),col("."),1) != 0
+                        " If the , is within a comment or string
+                        let index = index + 1
+                        let index = match( getline(linenum), '[,(]', index )
+                        continue
+                    endif
+                endif
+
+                " Only do this if the comma at this offset
+                " is not already at the start of the line
+                if match(getline(linenum), '\S') != index
+                    " Given the current cursor position, replace
+                    " the , and any following whitespace
+                    " with a newline and the special -@- character
+                    " for Align
+                    silent! exec linenum . ',' . linenum . 
+                                \ 's/\%' . (index + 1) . 'c,\s*' .
+                                \ '/\r' .
+                                \ (g:sqlutil_align_keyword_right == 1 ? ',-@-' : '-@-, ')
+                    let linenum = linenum + 1
+
+                    let index = 0
+                    if g:sqlutil_align_keyword_right == 0
+                        " If aligning the commas with the left justified 
+                        " column names, we must skip ahead the index
+                        " to be infront of the -@-
+                        let index = 3
+                    endif
+                endif
+                " Find the index of the first non-white space
+                " which should be the , we just put on the 
+                " newline
+                let index = match(getline(linenum), '\S', index)
+                let index = index + 1
+
+                " then continue on for the remainder of the line
+                " looking for the next , or (
+                "
+                " Must figure out what index value to start from
+                let index = match( getline(linenum), '[,(]', index )
+            endwhile
+            let linenum = saved_linenum 
+
+            " Go to the end of the new lines
+            silent! exec "'e-" 
+            let linenum = line("'e")-1
+        endif
+
+        let linenum = linenum + 1
+    endwhile
+
+    return linenum
+endfunction
+
+" For certain keyword lines (SELECT, SET, INTO, FROM, VALUES)
+" put each comma on a new line and align it with the keyword 
+"     SELECT c1
+"          , c2
+"          , c3
+function! s:SQLU_WrapLongLines( sql_keywords )
+    let linenum           = line("'y")+1
+    let paran_done        = 0
+    let restart_main_loop = 0
+    let max_width         = g:sqlutil_wrap_width
+    let comma_pattern     = '\c\(,\|(\|--\|\/\/\|\<\%(END\s\+\)\@<!CASE\>\|\<\%(END\s\+\)\@<!IF\>\)'
+
+    " These keywords typically have column lists:
+    " SELECT c1, c2, c3 
+    " SET c1 = 1, c2 = 2
+    " INTO var1, var2 
+    " FROM t1, t2
+    " VALUES( var1, var2 )
+    " INSERT INTO T1 (c1, c2)
+    " , - If we have already broken the line up
+    let sql_keywords = a:sql_keywords
+
+    " call Decho(" Before column splitter 'y+1=".line("'<").
+    " \ ":".col("'<")."  'z-1=".line("'>").":".col("'>"))
+    while linenum <= line("'z-1")
+        let line = getline(linenum)
+        if strlen(getline(linenum)) < max_width
+            let linenum = linenum + 1
+            continue
+        endif
+        
+        " If the line does not start with a keyword it is a good 
+        " candidate to wrap.
+        " Experimentation with wrapping using Vim's qp results 
+        " in ugly code which is as bad as unformatted code.
+        " So instead, we are going to look for various special
+        " markers (, (, CASE, IF) and split the lines there.  
+        " But in this case, we will 
+        " leave the commas on the end of the lines as there 
+        " is a special option to put those at the start of the line.
+        silent! exec linenum 
+        " Mark the start of the line
+        silent! exec "normal! mb"
+        " echom "line b - ".getline("'b")
+        " Mark the next line
+        silent! exec "normal! jmek"
+
+        let saved_linenum = linenum
+        " Find the first , 
+        let index = match(getline(linenum), comma_pattern)
+        " Check to see if there is another , closer to 
+        " the max_width
+        while index > -1
+            let prev_match = line[index]
+            let prev_index = index 
+
+            " Check next match if current match is a ,
+            " Since a match on a ( can easily find a closing ) 
+            " on or near the end of the line
+            if getline(linenum)[index] != ','
+                break
+            endif
+
+            let index = match(getline(linenum), comma_pattern, (index+1))
+            if index > -1
+                let curr_match = line[index]
+
+                if synID(getline(linenum),index,1) != 0
+                    " If within a comment, skip this match
+                    let index = prev_index 
+                    break
+                endif
+
+                if prev_match != curr_match
+                    " If the match between a ( and , changes
+                    " go back to the previous match
+                    let index = prev_index 
+                    break
+                endif
+                if index > max_width
+                    " Use first match as this one is beyond 
+                    " screen size
+                    let index = prev_index 
+                    break
+                else
+                    continue
+                endif
+            else 
+                " Use previous match as no more are found
+                let index = prev_index
+                break 
+            endif
+        endwhile
+
+        while index > -1
+            " Go to the , or (
+            call cursor(linenum, (index+1))
+
+            " Assuming syntax is on, check to ensure the , or (
+            " is not a string
+            if getline(linenum)[col(".")-1] == '(' 
+                if synID(line("."),col("."),1) == 0
+                    " Find closing paran
+                    if searchpair( '(', '', ')', '',
+                                \ 'synID(line("."),col("."),1)>0' ) > 0
+                        let matched_linenum = line(".")
+                        let matched_index   = col(".")
+
+                        if matched_index > max_width
+                            " But only do this if there is at least 1 comma 
+                            " between these matched ()s.
+                            " The pattern uses :h \%l
+                            if search('\%(\%(\%'.linenum.'l\%>'.(index+1).'v\)\|\%(\%'.matched_linenum.'l\%<'.(matched_index+1).'v\)\)\&,')
+                                " Found a comma between these ()s,
+                                " therefore at the closing paran, move it 
+                                " on to a separate line
+                                silent! exec matched_linenum . ',' . matched_linenum . 
+                                            \ 's/\%' . (matched_index) . 'c)\s*' .
+                                            \ '/\r' .
+                                            \ ')-@- '
+                                            " \ (g:sqlutil_align_keyword_right == 1 ? ')-@-' : '-@-) ')
+                                let paran_done = 1
+                                silent! exec (matched_linenum+1).','.(matched_linenum+1).'mark r'
+                            endif
+                        else 
+                            " We are at the closing ) 
+                            " And we still have not exceeded line
+                            " length 
+                            " So continue searching from this point forward
+                            " only if we are stil on the same line
+                            if linenum == line(".")
+                                let index = matched_index
+                            endif
+                        endif
+                    endif
+
+                    " Now that we have moved to the end of the matched 
+                    " paranthesis, check again for our comma or paran
+                    let index = index + 1
+                    let index = match( getline(linenum), comma_pattern, index )
+
+                    continue
+                else
+                    " The ( found was within a comment, so advance
+                    " the match, and find the next match
+                    let index = index + 1
+                    let index = match( getline(linenum), comma_pattern, index )
+
+                    continue
+                endif
+            elseif matchstr(getline(linenum), '\%'.(index+1).'v.\{4}') =~? '^CASE' 
+                " Moved to the CASE keywords to newlines
+                silent! exec linenum . ',' . linenum . 
+                            \ 's/\<\(\%(END\s\+\)\@<!CASE\|WHEN\|ELSE\|END\%(\s\+CASE\)\?\)\>/\r-@-&/gi'
+
+                let index = index + 1
+                let index = match( getline(linenum), comma_pattern, index )
+                continue
+            elseif matchstr(getline(linenum), '\%'.(index+1).'v.\{4}') =~? '^IF' 
+                " Moved to the CASE keywords to newlines
+                silent! exec linenum . ',' . linenum . 
+                            \ 's/\<\%(END\s\+\)\@<!IF\|ELSEIF\|ELSIF\|ELSE\|END\%(IF\|\s\+IF\)\>/\r-@-&/gi'
+
+                let index = index + 1
+                let index = match( getline(linenum), comma_pattern, index )
+                continue
+            elseif matchstr(getline(linenum), '\%'.(index+1).'v.\{4}') =~? '^\(--\|\/\/\)' 
+                " Start of a comment, ignore rest of line and move on
+                " to the next match
+                let index = match( getline(linenum), comma_pattern, index )
+                let linenum = linenum + 1
+                break
+            endif
+
+            " Only do this if the comma at this offset
+            " is not already at the start of the line
+            if match(getline(linenum), '\S') != index
+                " Given the current cursor position, replace
+                " the , and any following whitespace
+                " with a newline and the special -@- character
+                " for Align
+                silent! exec linenum . ',' . linenum . 
+                            \ 's/\%' . (index + 1) . 'c,\s*' .
+                            \ '/,\r' .
+                            \ '-@-'
+                let linenum = linenum + 1
+
+                " If the newline is no longer long, kick
+                " out of the loop and work on the next line
+                if strlen(getline(linenum)) < max_width
+                    let linenum = linenum + 1
+                    break
+                else
+                    let index = 0
+                    let index = match( getline(linenum), comma_pattern, index )
+
+                    if matchstr(getline(linenum), '\%'.(index+1).'v.\{1}') =~? '^,' 
+                        " If our match is another comma, break out of this
+                        " loop and perform the check to determine which comma
+                        " to split the line on
+                        let restart_main_loop = 1
+                        break
+                    endif
+                endif
+            else
+                let linenum = linenum + 1
+                let index = match( getline(linenum), comma_pattern, index )
+            endif
+            "          " Find the index of the first non-white space
+            "          " which should the substitute we just made
+            "          " newline
+            "          let index = match(getline(linenum), '\S', index)
+            "          let index = index + 1
+
+            "          " then continue on for the remainder of the line
+            "          " looking for the next , or (
+            "          "
+            "          " Must figure out what index value to start from
+            "          let index = match( getline(linenum), comma_pattern, index )
+            "          " Check to see if there is another , closer to 
+            "          " the max_width
+            "          while index > -1
+            "              let prev_index = index 
+            "              " Check next match
+            "              let index = match(getline(linenum), comma_pattern, (index+1))
+            "              if index > -1
+            "                  if index > max_width
+            "                      " Use first match as this one is beyond 
+            "                      " screen size
+            "                      let index = prev_index 
+            "                      break
+            "                  else
+            "                      continue
+            "                  endif
+            "              else 
+            "                  " Use previous match as no more are found
+            "                  let index = prev_index
+            "                  break 
+            "              endif
+            "          endwhile
+        endwhile
+
+        if restart_main_loop == 1
+            let restart_main_loop = 0
+            continue
+        endif
+
+        let linenum = saved_linenum 
+
+        " Go to the end of the new lines
+        silent! exec "'e-" 
+        let linenum = line("'e")-1
+
+        let linenum = linenum + 1
+    endwhile
+
+    return linenum
+endfunction
+
+" For certain keyword lines (SELECT, ORDER BY, GROUP BY, ...)
+" Ensure the lines fit in the textwidth (or default 80), wrap
+" the lines where necessary and left justify the column names
+function! s:SQLU_WrapExpressions()
+    " Check if this is a statement that can often by longer than 80 characters
+    " (select, set and so on), if so, ensure the column list is broken over as
+    " many lines as necessary and lined up with the other columns
+    let linenum = line("'y")+1
+
+    return 
+
+    let sql_keywords = '\<\%(select\)\>'
+    let sql_expression_operator = '' .
+                \ '\<\%(' .
+                \ '\%(end\s\+\)\@<!if\|else\%(if\)\?\|endif\|case\|when\|end' .
+                \ '\)\>'
+
+    " call Decho(" Before column splitter 'y+1=".line("'<").
+    " \ ":".col("'<")."  'z-1=".line("'>").":".col("'>"))
+    while linenum <= line("'z-1")
+        let line = getline(linenum)
+        if line =~? '\w'
+            " Decho 'linenum: ' . linenum . ' strlen: ' .
+            " \ strlen(line) . ' textwidth: ' . &textwidth .
+            " \ '  line: ' . line
+            " go to the current line
+            silent! exec linenum 
+            " Mark the start of the wide line
+            silent! exec "normal! mb"
+            let markb = linenum
+            " echom "line b - ".getline("'b")
+            " Mark the next line
+            silent! exec "normal! jmek"
+            " echom "line e - ".getline("'e")
+
+
+            if line =~? '\('.sql_expression_operator.'\)'
+                silent! exec linenum . ',' . linenum . 
+                            \ 's/\c^\s*\('.sql_keywords.'\)\s*'.
+                            \ '/\1-@-'
+                " Create a special marker for Align.vim
+                " to line up the columns with
+                silent! exec linenum . ',' . linenum . 
+                            \ 's/\c'.sql_expression_operator.'/'.
+                            \ '\r-@-&'
+
+            endif
+
+            " echom "end_line_nbr - ".end_line_nbr
+            " echom "normal! end_line_nbr - ".line(end_line_nbr)
+
+            " Append the special marker to the beginning of the line
+            " for Align.vim
+            " silent! exec "'b+," .end_line_nbr. 's/\s*\(.*\)/-@-\1'
+            " silent! exec "'b+," .end_line_nbr. 's/^\s*/-@-'
+            silent! exec ''.(markb+1)."," .end_line_nbr. 's/^\s*/-@-/g'
+            " silent! exec "'b+,'e-" . 's/\s*\(.*\)/-@-\1'
+            AlignCtrl Ip0P0rl:
+            " silent! 'b,'e-Align -@-
+            " silent! exec "'b,".end_line_nbr.'Align -@-'
+            silent! exec markb.",'e".'Align -@-'
+            " silent! 'b,'e-s/-@-/ /
+            silent! exec markb.",'e".'s/-@-/ /ge'
+            AlignCtrl default
+
+            " Advance the linenum to the end of the range
+            let linenum = line("'e") 
+        endif
+
+        let linenum = linenum + 1
+    endwhile
+
+    return linenum
+endfunction
+
+
+" For certain keyword lines (SELECT, ORDER BY, GROUP BY, ...)
+" Ensure the lines fit in the textwidth (or default 80), wrap
+" the lines where necessary and left justify the column names
+function! s:SQLU_WrapLongLinesQPP()
+    " Check if this is a statement that can often by longer than 80 characters
+    " (select, set and so on), if so, ensure the column list is broken over as
+    " many lines as necessary and lined up with the other columns
+    let linenum = line("'y")+1
+
+    " return
+
+    let org_textwidth = &textwidth
+    if &textwidth == 0 
+        " Get the width of the window
+        let &textwidth = winwidth(winnr())
+    endif
+
+    let sql_keywords = '\<\%(select\|set\|into\|from\|values'.
+                \ '\|order\|group\|having\|call\|with\)\>'
+
+    " call Decho(" Before column splitter 'y+1=".line("'<").
+    " \ ":".col("'<")."  'z-1=".line("'>").":".col("'>"))
+    while linenum <= line("'z-1")
+        let line = getline(linenum)
+        if line =~? '\w'
+            " Set the textwidth to current value
+            " minus an adjustment for select and set
+            " minus any indent value this may have
+            " echo 'tw: '.&textwidth.'  indent: '.indent(line)
+            " Decho 'line: '.line
+            " Decho 'tw: '.&textwidth.'  match at: '.
+            "             \ matchend(line, sql_keywords )
+            " let &textwidth = &textwidth - 10 - indent(line)
+            if line =~? '^\s*\('.sql_keywords.'\)'
+                let &textwidth = &textwidth - matchend(line, sql_keywords ) - 2
+                let line_length = strlen(line) - matchend(line, sql_keywords )
+            else
+                let line_length = strlen(line)
+            endif
+
+            if( line_length > &textwidth )
+                " Decho 'linenum: ' . linenum . ' strlen: ' .
+                " \ strlen(line) . ' textwidth: ' . &textwidth .
+                " \ '  line: ' . line
+                " go to the current line
+                silent! exec linenum 
+                " Mark the start of the wide line
+                silent! exec "normal! mb"
+                let markb = linenum
+                " echom "line b - ".getline("'b")
+                " Mark the next line
+                silent! exec "normal! jmek"
+                " echom "line e - ".getline("'e")
+                " echom "line length- ".strlen(getline(".")).
+                " \ "  tw=".&textwidth
+
+
+                if line =~? '^\s*\('.sql_keywords.'\)'
+                    " Create a special marker for Align.vim
+                    " to line up the columns with
+                    silent! exec linenum . ',' . linenum . 's/\(\w\) /\1-@-'
+
+                    " If the line begins with SET then force each
+                    " column on a newline, instead of breaking them apart
+                    " this will ensure that the col_name = ... is on the
+                    " same line
+                    if line =~? '^\s*\<set\>'
+                        silent! 'b,'e-1s/,/,\r/ge
+                    endif
+                else
+                    " Place the special marker that the first non-whitespace
+                    " characeter
+                    if g:sqlutil_align_comma == 1  && line =~ '^\s*,'
+                        " silent! exec linenum . ',' . linenum .
+                        "             \ 's/^\s*\zs,\s*/,  -@-'
+                        if g:sqlutil_align_keyword_right == 1 
+                            silent! exec linenum . ',' . linenum .
+                                        \ 's/^\s*\zs,\s*/,  -@-'
+                        else
+                            silent! exec linenum . ',' . linenum .
+                                        \ 's/^\s*\zs,\s*/-@-, '
+                        endif
+                    else
+                        if line !~ '-@-'
+                            " If there is not a special marker on the line 
+                            " yet, then add one
+                            silent! exec linenum . ',' . linenum . 's/\S/-@-&'
+                        endif
+                    endif
+                endif
+
+                silent! exec linenum
+                " Reformat the line based on the textwidth
+                silent! exec "normal! gqq"
+
+                " echom "normal! mb - ".line("'b")
+                " echom "normal! me - ".line("'e")
+                " Sometimes reformatting does not change the line
+                " so we need to double check the end range to 
+                " ensure it does go backwards
+                let begin_line_nbr = (line("'b") + 1)
+                let begin_line_nbr = (markb + 1)
+                let end_line_nbr = (line("'e") - 1)
+                " echom "b- ".begin_line_nbr."  e- ".end_line_nbr
+                if end_line_nbr < begin_line_nbr
+                    let end_line_nbr = end_line_nbr + 1
+                    " echom "end_line_nbr adding 1 "
+                endif
+                " echom "end_line_nbr - ".end_line_nbr
+                " echom "normal! end_line_nbr - ".line(end_line_nbr)
+
+                " Reformat the commas
+                " silent! 'b,'e-s/\s*,/,/ge
+                " silent! exec "'b,".end_line_nbr.'s/\s*,/,/ge'
+                " Add a space after the comma
+                " silent! 'b,'e-s/,\(\w\)/, \1/ge
+                " silent! exec "'b,".end_line_nbr.'s/,\(\w\)/, \1/ge'
+                silent! exec markb.",".end_line_nbr.'s/,\(\w\)/, \1/ge'
+
+                " Append the special marker to the beginning of the line
+                " for Align.vim
+                " silent! exec "'b+," .end_line_nbr. 's/\s*\(.*\)/-@-\1'
+                " silent! exec "'b+," .end_line_nbr. 's/^\s*/-@-'
+                silent! exec ''.(markb+1)."," .end_line_nbr. 's/^\s*/-@-'
+                " silent! exec "'b+,'e-" . 's/\s*\(.*\)/-@-\1'
+                AlignCtrl Ip0P0rl:
+                " silent! 'b,'e-Align -@-
+                " silent! exec "'b,".end_line_nbr.'Align -@-'
+                silent! exec markb.",".end_line_nbr.'Align -@-'
+                " silent! 'b,'e-s/-@-/ /
+                if line =~? '^\s*\('.sql_keywords.'\)'
+                    silent! exec markb.",".end_line_nbr.'s/-@-/ /ge'
+                else
+                    silent! exec markb.",".end_line_nbr.'s/-@-/'.(g:sqlutil_align_comma == 1 ? ' ' : '' ).'/ge'
+                endif
+                AlignCtrl default
+
+                " Dont move to the end of the reformatted text
+                " since we also want to check for CASE statemtns
+                " let linenum = line("'e") - 1
+                " let linenum = line("'e")
+            endif
+        endif
+
+        let &textwidth = org_textwidth
+        if &textwidth == 0 
+            " Get the width of the window
+            let &textwidth = winwidth(winnr())
+        endif
+        let linenum = linenum + 1
+    endwhile
+
+    let &textwidth = org_textwidth
+    return linenum
+endfunction
+
+" Finds unbalanced paranthesis and put each one on a new line
+function! s:SQLU_SplitUnbalParan()
+    let linenum = line("'y")+1
+    while linenum <= line("'z")-1
+        let line = getline(linenum)
+        " echom 'SQLU_SplitUnbalParan: l: ' . linenum . ' t: '. getline(linenum)
+        if line !~ '('
+            " echom 'SQLU_SplitUnbalParan: no (s: '.linenum.'  : '.
+            " \ getline(linenum)
+            let linenum = linenum + 1
+            continue
+        endif
+            
+        " echom 'SQLU_SplitUnbalParan: start line: '.linenum.' : '.line
+
+        let begin_paran = match( line, "(" )
+        while begin_paran > -1
+            " Check if the paran is inside a string
+            if synID(linenum,(begin_paran+1),1) > 0
+                " If it is, skip to the next paran
+                let begin_paran = match( getline(linenum), "(", (begin_paran+1) )
+                continue
+            endif
+
+            let curcol      = begin_paran
+
+            " Place the cursor on the (
+            call cursor(linenum,(curcol+1))
+
+            echomsg 'Pre searchpair' line('.') col('.') getline('.')[col('.')-1] getline('.')
+            " Find the matching closing )
+            " Ignore parans that have syntax elements (most likely a comment)
+            let indent_to = searchpair( '(', '', ')', 'W', 'synID(line("."),col("."),1)>0' )
+
+            echomsg 'Post searchpair' line('.') col('.') indent_to getline('.')[col('.')-1] getline('.')
+            " If the match is outside of the range, this is an unmatched (
+            if indent_to < 1 || indent_to > line("'z-1")
+                " Return to previous location
+                " echom 'Unmatched parentheses on line: ' . getline(linenum)
+                call s:SQLU_WarningMsg(
+                            \ 'SQLU_SplitUnbalParan: Unmatched parentheses' .
+                            \ ' at line/col: (' . (linenum-1).','.(curcol+1). 
+                            \ ') on line: ' . 
+                            \ getline(linenum)
+                            \ )
+                "call cursor(linenum,(curcol+1))
+                return -1
+            endif
+             
+            let matchline     = line(".")
+            let matchcol      = virtcol(".")
+
+            " If the match is on a DIFFERENT line
+            if indent_to != linenum
+                " If there are any characters before the matching ) place it on a newline
+                let index = match(getline(indent_to), '\S')
+                if index == -1 || index < col('.') 
+                    " Place the paranethesis on a new line
+                    silent! exec "normal! i\n\<Esc>"
+                    let indent_to = indent_to + 1
+                endif
+                " Remove leading spaces
+                " echom "Removing leading spaces"
+                silent! exec 's/^\s*//e'."\n"
+                
+                " Place a marker at the beginning of the line so
+                " it can be Aligned with its matching paranthesis
+                if getline(".") !~ '^\s*-@-'
+                    silent! exec "normal! i-@-\<Esc>"
+                endif
+
+                " Return to the original line
+                " Check if the line with the ( needs splitting as well
+                " Since the closing ) is on a different line, make sure
+                " this ( is the last character on the line, this is 
+                " necessary so that the blocks are correctly indented
+                " .\{8} - match any characters up to the 8th column
+                " \zs   - start the search in column 9
+                " \s*$  - If the line only has whitespace dont split
+
+                if getline(linenum) !~ '^.\{'.(curcol+1).'}\zs\s*$'     
+                    " Return to previous location"
+                    call cursor(linenum,(curcol+1))
+
+                    " Place the paranethesis on a new line
+                    " with the marker at the beginning so
+                    " it can be Aligned with its matching paranthesis
+                    silent! exec "normal! a\n-@-\<Esc>"
+
+                    " Add 1 to the linenum since the remainder of this 
+                    " line has been moved 
+                    let linenum = linenum + 1
+                    " Reset begin_paran since we are on a new line
+                    let begin_paran = -1
+                endif
+            endif
+
+            " We have potentially changed the line we are on
+            " so get a new copy of the row to perform the match
+            " Add one to the curcol to look for the next (
+            let begin_paran = match( getline(linenum), "(", (begin_paran+1) )
+
+        endwhile
+
+        let linenum = linenum + 1
+    endwhile
+
+    " Never found matching close parenthesis
+    " or end of range
+    return linenum
+endfunction
+
+" If a comment is found, skip it
+function! SQLUtilities#SQLU_AlignSkip( lineno, indx )
+    if getline(a:lineno) =~ '^\s*\(--\|\/\/\)'
+        return 1
+    endif
+    return 0
+
+    let synid   = synID(a:lineno,a:indx+1,1)
+    let synname = synIDattr(synIDtrans(synid),"name")
+    let ret= (synname == "String")? 1 : 0
+    return ret
+endfunction
+
+" Puts a command separate list of columns given a table name
+" Will search through the file looking for the create table command
+" It assumes that each column is on a separate line
+" It places the column list in unnamed buffer
+function! SQLUtilities#SQLU_CreateColumnList(...)
+
+    " Mark the current line to return to
+    let curline     = line(".")
+    let curcol      = virtcol(".")
+    let curbuf      = bufnr(expand("<abuf>"))
+    let found       = 0
+
+    if(a:0 > 0) 
+        let table_name  = a:1
+    else
+        let table_name  = expand("<cword>")
+    endif
+
+    if(a:0 > 1) 
+        let only_primary_key = 1
+    else
+        let only_primary_key = 0
+    endif
+
+    let add_alias = ''
+    if(a:0 > 2) 
+        let add_alias = a:2
+    else
+        if 'da' =~? g:sqlutil_use_tbl_alias
+            if table_name =~ '_'
+                " Treat _ as separators since people often use these
+                " for word separators
+                let save_keyword = &iskeyword
+                setlocal iskeyword-=_
+
+                " Get the first letter of each word
+                " [[:alpha:]] is used instead of \w 
+                " to catch extended accented characters
+                "
+                let initials = substitute( 
+                            \ table_name, 
+                            \ '\<[[:alpha:]]\+\>_\?', 
+                            \ '\=strpart(submatch(0), 0, 1)', 
+                            \ 'g'
+                            \ )
+                " Restore original value
+                let &iskeyword = save_keyword
+            elseif table_name =~ '\u\U'
+                let initials = substitute(
+                            \ table_name, '\(\u\)\U*', '\1', 'g')
+            else
+                let initials = strpart(table_name, 0, 1)
+            endif
+
+            if 'a' =~? g:sqlutil_use_tbl_alias
+                let add_alias = inputdialog("Enter table alias:", initials)
+            else
+                let add_alias = initials
+            endif
+        endif
+    endif
+    " Following a word character, make sure there is a . and no spaces
+    let add_alias = substitute(add_alias, '\w\zs\.\?\s*$', '.', '')
+
+    " save previous search string
+    let saveSearch = @/
+    let saveZ      = @z
+    let columns    = ""
+    " Prevent the alternate buffer (<C-^>) from being set to this
+    " temporary file
+    let l:old_cpoptions = &cpoptions
+    setlocal cpo-=a
+    
+    " ignore case
+    if( only_primary_key == 0 )
+        let srch_table = '\c^[ \t]*create.*table.*\<'.table_name.'\>'
+    else
+        " Regular expression breakdown
+        " Ingore case and spaces
+        " line begins with either create or alter
+        " followed by table and table_name (on the same line)
+        " Could be other lines inbetween these
+        " Look for the primary key clause (must be one)
+        " Start the match after the open paran
+        " The column list could span multiple lines
+        " End the match on the closing paran
+        " Could be other lines in between these
+        " Remove any newline characters for the command
+        " terminator (ie "\ngo" )
+        " Besides a CREATE TABLE statement, this expression
+        " should find statements like:
+        "     ALTER TABLE SSD.D_CENTR_ALLOWABLE_DAYS
+        "         ADD PRIMARY KEY (CUST_NBR, CAL_NBR, GRP_NBR,
+        "              EVENT_NBR, ALLOW_REVIS_NBR, ROW_REVIS_NBR);
+        let srch_table = '\c^[ \t]*' . 
+                    \ '\(create\|alter\)' . 
+                    \ '.*table.*' . 
+                    \ table_name .                
+                    \ '\_.\{-}' .    
+                    \ '\%(primary key\)\{-1,}' . 
+                    \ '\s*(\zs' . 
+                    \ '\_.\{-}' . 
+                    \ '\ze)' . 
+                    \ '\_.\{-}' . 
+                    \ substitute( g:sqlutil_cmd_terminator,
+                            \ "[\n]", '', "g" )
+    endif
+
+    " Loop through all currenly open buffers to look for the 
+    " CREATE TABLE statement, if found build the column list
+    " or display a message saying the table wasn't found
+    " I am assuming a create table statement is of this format
+    " CREATE TABLE "cons"."sync_params" (
+    "   "id"                            integer NOT NULL,
+    "   "last_sync"                     timestamp NULL,
+    "   "sync_required"                 char(1) NOT NULL DEFAULT 'N',
+    "   "retries"                       smallint NOT NULL ,
+    "   PRIMARY KEY ("id")
+    " );
+    while( 1==1 )
+        " Mark the current line to return to
+        let buf_curline     = line(".")
+        let buf_curcol      = virtcol(".")
+        " From the top of the file
+        silent! exe "normal! 1G\<bar>0\<bar>"
+        if( search( srch_table, "W" ) ) > 0
+            if( only_primary_key == 0 )
+                " Find the create table statement
+                " let cmd = '/'.srch_create_table."\n"
+                " Find the opening ( that starts the column list
+                let cmd = 'normal! /('."\n".'Vib'."\<ESC>"
+                silent! exe cmd
+                " Decho 'end: '.getline(line("'>"))
+                let start_line = line("'<")
+                let end_line = line("'>")
+                silent! exe 'noh'
+                let found = 1
+                
+                " Visually select until the following keyword are the beginning
+                " of the line, this should be at the bottom of the column list
+                " Start visually selecting columns
+                " let cmd = 'silent! normal! V'."\n"
+                let find_end_of_cols = 
+                            \ '\(' .
+                            \ g:sqlutil_cmd_terminator .
+                            \ '\|' .
+                            \ substitute(
+                            \ g:sqlutil_col_list_terminators,
+                            \ ',', '\\|\1', 'g' ) .
+                            \ '\)' 
+                    
+                let separator = ""
+                let columns = ""
+
+                " Build comma separated list of input parameters
+                while start_line <= end_line
+                    let line = getline(start_line)
+
+                    " If the line has no words on it, skip it
+                    if line !~ '\w' || line =~ '^\s*$'
+                        let start_line = start_line + 1
+                        continue
+                    endif
+
+
+                    " if any of the find_end_of_cols is found, leave this loop.
+                    " This test is case insensitive.
+                    if line =~? '^\s*\w\+\s\+\w\+\s\+'.find_end_of_cols
+                        " Special case, the column name definition
+                        " is part of the line
+                    elseif line =~? find_end_of_cols
+                        let end_line = start_line - 1
+                        break
+                    endif
+
+                    let column_name = substitute( line, 
+                                \ '[ \t"]*\(\<\w\+\>\).*', '\1', "g" )
+                    let column_def = SQLU_GetColumnDatatype( line, 1 )
+
+                    let columns = columns . separator . add_alias . column_name
+                    let separator  = ", "
+                    let start_line = start_line + 1
+                endwhile
+
+            else
+                " Find the primary key statement
+                " Visually select all the text until the 
+                " closing paranthesis
+                silent! exe 'silent! normal! v/)/e-1'."\n".'"zy'
+                let columns = @z
+                " Strip newlines characters
+                let columns = substitute( columns, 
+                            \ "[\n]", '', "g" )
+                " Strip everything but the column list
+                let columns = substitute( columns, 
+                            \ '\s*\(.*\)\s*', '\1', "g" )
+                " Remove double quotes
+                let columns = substitute( columns, '"', '', "g" )
+                let columns = substitute( columns, ',\s*', ', ', "g" )
+                let columns = substitute( columns, '^\s*', '', "g" )
+                let columns = substitute( columns, '\s*$', '', "g" )
+                let found = 1
+                silent! exe 'noh'
+            endif
+
+        endif
+
+        " Return to previous location
+        silent! exe 'normal! '.buf_curline."G\<bar>".buf_curcol."l"
+
+        if found == 1
+            break
+        endif
+        
+        if &hidden == 0
+            call s:SQLU_WarningMsg(
+                        \ "Cannot search other buffers with set nohidden"
+                        \ )
+            break
+        endif
+
+        " Switch buffers to check to see if the create table
+        " statement exists
+        silent! exec "bnext"
+        if bufnr(expand("<abuf>")) == curbuf
+            break
+        endif
+    endwhile
+    
+    silent! exec "buffer " . curbuf
+
+    " Return to previous location
+    silent! exe 'normal! '.curline."G\<bar>".(curcol-1).(((curcol-1) > 0)?"l":'')
+    silent! exe 'noh'
+
+    " restore previous search
+    let @/ = saveSearch
+    let @z = saveZ
+
+    " Restore previous cpoptions
+    let &cpoptions = l:old_cpoptions
+
+
+    redraw
+
+    if found == 0
+        let @@ = ""
+        if( only_primary_key == 0 )
+            call s:SQLU_WarningMsg(
+                        \ "SQLU_CreateColumnList - Table: " .
+                        \ table_name . 
+                        \ " was not found"
+                        \ )
+        else
+            call s:SQLU_WarningMsg(
+                        \ "SQLU_CreateColumnList - Table: " .
+                        \ table_name . 
+                        \ " does not have a primary key"
+                        \ )
+        endif
+        return ""
+    endif 
+
+    " If clipboard is pointing to the windows clipboard
+    " copy the results there.
+    if &clipboard == 'unnamed'
+        let @* = columns 
+    else
+        let @@ = columns 
+    endif
+
+    echo "Paste register: " . columns
+
+    return columns
+
+endfunction
+
+
+" Strip the datatype from a column definition line
+function! SQLUtilities#SQLU_GetColumnDatatype( line, need_type )
+
+    let pattern = '\c^\s*'  " case insensitve, white space at start of line
+    let pattern = pattern . '\S\+\w\+[ "\t]\+' " non white space (name with 
+                                               " quotes)
+
+    if a:need_type == 1
+        let pattern = pattern . '\zs'    " Start matching the datatype
+        let pattern = pattern . '.\{-}'  " include anything
+        let pattern = pattern . '\ze\s*'    " Stop matching when ...
+        let pattern = pattern . '\(NOT\|NULL\|DEFAULT\|'
+        let pattern = pattern . '\(\s*,\s*$\)' " Line ends with a comma 
+        let pattern = pattern . '\)' 
+    else
+        let pattern = pattern . '\zs'   " Start matching the datatype
+        let pattern = pattern . '.\{-}' " include anything
+        let pattern = pattern . '\ze'   " Stop matching when ...
+        let pattern = pattern . '\s*,\s*$' " Line ends with a comma 
+    endif
+
+    let datatype = matchstr( a:line, pattern )
+
+    return datatype
+endfunction
+
+
+" Puts a comma separated list of columns given a table name
+" Will search through the file looking for the create table command
+" It assumes that each column is on a separate line
+" It places the column list in unnamed buffer
+function! SQLUtilities#SQLU_GetColumnDef( ... )
+
+    " Mark the current line to return to
+    let curline     = line(".")
+    let curcol      = virtcol(".")
+    let curbuf      = bufnr(expand("<abuf>"))
+    let found       = 0
+    
+    if(a:0 > 0) 
+        let col_name  = a:1
+    else
+        let col_name  = expand("<cword>")
+    endif
+
+    if(a:0 > 1) 
+        let need_type = a:2
+    else
+        let need_type = 0
+    endif
+
+    let srch_column_name = '^[ \t]*["]\?\<' . col_name . '\>["]\?\s\+\<\w\+\>'
+    let column_def = ""
+
+    " Loop through all currenly open buffers to look for the 
+    " CREATE TABLE statement, if found build the column list
+    " or display a message saying the table wasn't found
+    " I am assuming a create table statement is of this format
+    " CREATE TABLE "cons"."sync_params" (
+    "   "id"                            integer NOT NULL,
+    "   "last_sync"                     timestamp NULL,
+    "   "sync_required"                 char(1) NOT NULL DEFAULT 'N',
+    "   "retries"                       smallint NOT NULL ,
+    "   PRIMARY KEY ("id")
+    " );
+    while( 1==1 )
+        " Mark the current line to return to
+        let buf_curline     = line(".")
+        let buf_curcol      = virtcol(".")
+
+        " From the top of the file
+        silent! exe "normal! 1G\<bar>0\<bar>"
+
+        if( search( srch_column_name, "w" ) ) > 0
+            silent! exe 'noh'
+            let found = 1
+            let column_def = SQLU_GetColumnDatatype( getline("."), need_type )
+        endif
+
+        " Return to previous location
+        silent! exe 'normal! '.buf_curline."G\<bar>".buf_curcol."l"
+
+        if found == 1
+            break
+        endif
+        
+        if &hidden == 0
+            call s:SQLU_WarningMsg(
+                        \ "Cannot search other buffers with set nohidden"
+                        \ )
+            break
+        endif
+
+        " Switch buffers to check to see if the create table
+        " statement exists
+        silent! exec "bnext"
+        if bufnr(expand("<abuf>")) == curbuf
+            break
+        endif
+    endwhile
+    
+    silent! exec "buffer " . curbuf
+
+    " Return to previous location
+    silent! exe 'normal! '.curline."G\<bar>".curcol."l"
+
+    if found == 0
+        let @@ = ""
+        echo "Column: " . col_name . " was not found"
+        return ""
+    endif 
+
+    if &clipboard == 'unnamed'
+        let @* = column_def 
+    else
+        let @@ = column_def 
+    endif
+
+    " If a parameter has been passed, this means replace the 
+    " current word, with the column list
+    " if (a:0 > 0) && (found == 1)
+        " exec "silent! normal! viwp"
+        " if &clipboard == 'unnamed'
+            " let @* = col_name 
+        " else
+            " let @@ = col_name 
+        " endif
+        " echo "Paste register: " . col_name
+    " else
+        echo "Paste register: " . column_def
+    " endif
+
+    return column_def
+
+endfunction
+
+
+
+" Creates a procedure defintion into the unnamed buffer for the 
+" table that the cursor is currently under.
+function! SQLUtilities#SQLU_CreateProcedure(...)
+
+    " Mark the current line to return to
+    let curline     = line(".")
+    let curcol      = virtcol(".")
+    let curbuf      = bufnr(expand("<abuf>"))
+    let found       = 0
+    " save previous search string
+    let saveSearch=@/ 
+    " Prevent the alternate buffer (<C-^>) from being set to this
+    " temporary file
+    let l:old_cpoptions   = &cpoptions
+    let l:old_eventignore = &eventignore
+    setlocal cpo-=A
+    setlocal eventignore=BufRead,BufReadPre,BufEnter,BufNewFile
+
+    
+
+    if(a:0 > 0) 
+        let table_name  = a:1
+    else
+        let table_name  = expand("<cword>")
+    endif
+
+    let i = 0
+    let indent_spaces = ''
+    while( i < &shiftwidth )
+        let indent_spaces = indent_spaces . ' '
+        let i = i + 1
+    endwhile
+    
+    " ignore case
+    " let srch_create_table = '\c^[ \t]*create.*table.*\<' . table_name . '\>'
+    let srch_create_table = '\c^[ \t]*create.*table.*\<' . 
+                \ table_name . 
+                \ '\>'
+    let procedure_def = "CREATE PROCEDURE sp_" . table_name . "(\n"
+
+    " Loop through all currenly open buffers to look for the 
+    " CREATE TABLE statement, if found build the column list
+    " or display a message saying the table wasn't found
+    " I am assuming a create table statement is of this format
+    " CREATE TABLE "cons"."sync_params" (
+    "   "id"                            integer NOT NULL,
+    "   "last_sync"                     timestamp NULL,
+    "   "sync_required"                 char(1) NOT NULL DEFAULT 'N',
+    "   "retries"                       smallint NOT NULL,
+    "   PRIMARY KEY ("id")
+    " );
+    while( 1==1 )
+        " Mark the current line to return to
+        let buf_curline     = line(".")
+        let buf_curcol      = virtcol(".")
+
+        " From the top of the file
+        silent! exe "normal! 1G\<bar>0\<bar>"
+
+        if( search( srch_create_table, "w" ) ) > 0
+            " Find the create table statement
+            " let cmd = '/'.srch_create_table."\n"
+            " Find the opening ( that starts the column list
+            let cmd = 'normal! /('."\n".'Vib'."\<ESC>"
+            silent! exe cmd
+            " Decho 'end: '.getline(line("'>"))
+            let start_line = line("'<")
+            let end_line = line("'>")
+            silent! exe 'noh'
+            let found = 1
+            
+            " Visually select until the following keyword are the beginning
+            " of the line, this should be at the bottom of the column list
+            " Start visually selecting columns
+            " let cmd = 'silent! normal! V'."\n"
+            let find_end_of_cols = 
+                        \ '\(' .
+                        \ g:sqlutil_cmd_terminator .
+                        \ '\|' .
+                        \ substitute(
+                        \ g:sqlutil_col_list_terminators,
+                        \ ',', '\\|\1', 'g' ) .
+                        \ '\)' 
+                
+            let separator = " "
+            let column_list = ""
+
+            " Build comma separated list of input parameters
+            while start_line <= end_line
+                let line = getline(start_line)
+
+                " If the line has no words on it, skip it
+                if line !~ '\w' || line =~ '^\s*$'
+                    let start_line = start_line + 1
+                    continue
+                endif
+
+                " if any of the find_end_of_cols is found, leave this loop.
+                " This test is case insensitive.
+                if line =~? find_end_of_cols
+                    let end_line = start_line - 1
+                    break
+                endif
+
+                let column_name = substitute( line, 
+                            \ '[ \t"]*\(\<\w\+\>\).*', '\1', "g" )
+                let column_def = SQLU_GetColumnDatatype( line, 1 )
+
+                let column_list = column_list . separator . column_name
+                let procedure_def = procedure_def . 
+                            \ indent_spaces .
+                            \ separator .
+                            \ "IN @" . column_name .
+                            \ ' ' . column_def . "\n"
+
+                let separator  = ","
+                let start_line = start_line + 1
+            endwhile
+
+            let procedure_def = procedure_def .  ")\n"
+            let procedure_def = procedure_def . "RESULT(\n" 
+
+            let start_line = line("'<")
+            let separator  = " "
+            
+            " Build comma separated list of datatypes
+            while start_line <= end_line
+                let line = getline(start_line)
+                
+                " If the line has no words on it, skip it
+                if line !~ '\w' || line =~ '^\s*$'
+                    let start_line = start_line + 1
+                    continue
+                endif
+
+                let column_def = SQLU_GetColumnDatatype( line, 1 )
+                
+                let procedure_def = procedure_def .
+                            \ indent_spaces .
+                            \ separator . 
+                            \ column_def .
+                            \ "\n"
+
+                let separator  = ","
+                let start_line = start_line + 1
+            endwhile
+
+            let procedure_def = procedure_def .  ")\n"
+            " Strip off any spaces
+            let column_list = substitute( column_list, ' ', '', 'g' )
+            " Ensure there is one space after each ,
+            let column_list = substitute( column_list, ',', ', ', 'g' )
+            let save_tbl_alias = g:sqlutil_use_tbl_alias
+            " Disable the prompt for the table alias
+            let g:sqlutil_use_tbl_alias = 'n'
+            let pk_column_list = SQLU_CreateColumnList(
+                        \ table_name, 'primary_keys')
+            let g:sqlutil_use_tbl_alias = save_tbl_alias  
+
+            let procedure_def = procedure_def . "BEGIN\n\n" 
+            
+            " Create a sample SELECT statement
+            let procedure_def = procedure_def . 
+                        \ indent_spaces .
+                        \ "SELECT " . column_list . "\n" .
+                        \ indent_spaces .
+                        \ "  FROM " . table_name . "\n"
+            let where_clause = indent_spaces . 
+                        \ substitute( column_list, 
+                        \ '^\(\<\w\+\>\)\(.*\)', " WHERE \\1 = \@\\1\\2", "g" )
+            let where_clause = 
+                        \ substitute( where_clause, 
+                        \ ', \(\<\w\+\>\)', 
+                        \ "\n" . indent_spaces . "   AND \\1 = @\\1", "g" )
+            let procedure_def = procedure_def . where_clause . ";\n\n"
+
+            " Create a sample INSERT statement
+            let procedure_def = procedure_def . 
+                        \ indent_spaces . 
+                        \ "INSERT INTO " . table_name . "( " .
+                        \ column_list .
+                        \ " )\n"
+            let procedure_def = procedure_def . 
+                        \ indent_spaces .
+                        \ "VALUES( " .
+                        \ substitute( column_list, '\(\<\w\+\>\)', '@\1', "g" ).
+                        \ " );\n\n"
+
+            " Create a sample UPDATE statement
+            let procedure_def = procedure_def . 
+                        \ indent_spaces .
+                        \ "UPDATE " . table_name . "\n" 
+
+            " Now we must remove each of the columns in the pk_column_list
+            " from the column_list, to create the no_pk_column_list.  This is
+            " used by the UPDATE statement, since we do not SET columns in the
+            " primary key.
+            " The order of the columns in the pk_column_list is not guaranteed
+            " to be in the same order as the table list in the CREATE TABLE
+            " statement.  So we must remove each word one at a time.
+            let no_pk_column_list = SQLU_RemoveMatchingColumns(
+                        \ column_list, pk_column_list )
+
+            " Check for the special case where there is no 
+            " primary key for the table (ie ,\? \? )
+            let set_clause = 
+                        \ indent_spaces .
+                        \ substitute( no_pk_column_list, 
+                        \ ',\? \?\(\<\w\+\>\)', 
+                        \ '   SET \1 = @\1', '' )
+            let set_clause = 
+                        \ substitute( set_clause, 
+                        \ ', \(\<\w\+\>\)', 
+                        \ ",\n" . indent_spaces . '       \1 = @\1', "g" )
+
+            " Check for the special case where there is no 
+            " primary key for the table
+            if strlen(pk_column_list) > 0
+                let where_clause = 
+                            \ indent_spaces .
+                            \ substitute( pk_column_list, 
+                            \ '^\(\<\w\+\>\)', ' WHERE \1 = @\1', "" ) 
+                let where_clause = 
+                            \ substitute( where_clause, 
+                            \ ', \(\<\w\+\>\)', 
+                            \ "\n" . indent_spaces . '   AND \1 = @\1', "g" )
+            else
+                " If there is no primary key for the table place
+                " all columns in the WHERE clause
+                let where_clause = 
+                            \ indent_spaces .
+                            \ substitute( column_list, 
+                            \ '^\(\<\w\+\>\)', ' WHERE \1 = @\1', "" ) 
+                let where_clause = 
+                            \ substitute( where_clause, 
+                            \ ', \(\<\w\+\>\)', 
+                            \ "\n" . indent_spaces . '   AND \1 = @\1', "g" )
+            endif
+            let procedure_def = procedure_def . set_clause . "\n" 
+            let procedure_def = procedure_def . where_clause .  ";\n\n"
+
+            " Create a sample DELETE statement
+            let procedure_def = procedure_def . 
+                        \ indent_spaces .
+                        \ "DELETE FROM " . table_name . "\n" 
+            let procedure_def = procedure_def . where_clause . ";\n\n"
+
+            let procedure_def = procedure_def . "END;\n\n" 
+            
+        endif
+
+        " Return to previous location
+        silent! exe 'normal! '.buf_curline."G\<bar>".buf_curcol."l"
+
+        if found == 1
+            break
+        endif
+        
+        if &hidden == 0
+            call s:SQLU_WarningMsg(
+                        \ "Cannot search other buffers with set nohidden"
+                        \ )
+            break
+        endif
+
+        " Switch buffers to check to see if the create table
+        " statement exists
+        silent! exec "bnext"
+        if bufnr(expand("<abuf>")) == curbuf
+            break
+        endif
+    endwhile
+    
+    silent! exec "buffer " . curbuf
+
+    " restore previous search string
+    let @/ = saveSearch
+    " Restore previous cpoptions
+    let &cpoptions   = l:old_cpoptions
+    let &eventignore = l:old_eventignore
+
+    
+    " Return to previous location
+    silent! exe 'normal! '.curline."G\<bar>".curcol."l"
+
+    if found == 0
+        let @@ = ""
+        echo "Table: " . table_name . " was not found"
+        return ""
+    endif 
+
+    echo 'Procedure: sp_' . table_name . ' in unnamed buffer'
+    if &clipboard == 'unnamed'
+        let @* = procedure_def 
+    else
+        let @@ = procedure_def 
+    endif
+
+    return ""
+
+endfunction
+
+
+
+" Compares two strings, and will remove all names from the first 
+" parameter, if the same name exists in the second column name.
+" The 2 parameters take comma separated lists
+function! SQLUtilities#SQLU_RemoveMatchingColumns( full_col_list, dup_col_list )
+
+    let stripped_col_list = a:full_col_list
+    let pos = 0
+    " Find the string index position of the first match
+    let index = match( a:dup_col_list, '\w\+' )
+    while index > -1
+        " Get name of column
+        let dup_col_name = matchstr( a:dup_col_list, '\w\+', index )
+        let stripped_col_list = substitute( stripped_col_list,
+                    \ dup_col_name.'[, ]*', '', 'g' )
+        " Advance the search after the word we just found and look for
+        " others.  
+        let index = match( a:dup_col_list, '\w\+', 
+                    \ index + strlen(dup_col_name) )
+    endwhile
+
+    return stripped_col_list
+
+endfunction
+
+function! s:SQLU_WarningMsg(msg) "{{{
+    echohl WarningMsg
+    echomsg a:msg
+    echohl None
+endfunction "}}}
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
+
+" vim:fdm=marker:nowrap:ts=4:expandtab:ff=unix:
diff --git a/src/testdir/bundles/searchpair/plugin/SQLUtilities.vim b/src/testdir/bundles/searchpair/plugin/SQLUtilities.vim
new file mode 100644
index 0000000..5a63d8d
--- /dev/null
+++ b/src/testdir/bundles/searchpair/plugin/SQLUtilities.vim
@@ -0,0 +1,416 @@
+" SQLUtilities:   Variety of tools for writing SQL
+"   Author:	      David Fishburn <dfishburn dot vim at gmail dot com>
+"   Date:	      Nov 23, 2002
+"   Last Changed: 2015 Jul 27
+"   Version:	  7.0.0
+"   Script:	      http://www.vim.org/script.php?script_id=492
+"   License:      GPL (http://www.gnu.org/licenses/gpl.html)
+"
+"   Dependencies:
+"        Align.vim - Version 15 (as a minimum)
+"                  - Author: Charles E. Campbell, Jr.
+"                  - http://www.vim.org/script.php?script_id=294
+"   Documentation:
+"        :h SQLUtilities.txt 
+"
+
+" Prevent duplicate loading
+if exists("g:loaded_sqlutilities")
+    finish
+endif
+let g:loaded_sqlutilities = 700
+
+" Turn on support for line continuations when creating the script
+let s:cpo_save = &cpo
+set cpo&vim
+
+if !exists('g:sqlutil_align_where')
+    let g:sqlutil_align_where = 1
+endif
+
+if !exists('g:sqlutil_align_comma')
+    let g:sqlutil_align_comma = 0
+endif
+
+if !exists('g:sqlutil_align_first_word')
+    let g:sqlutil_align_first_word = 1
+endif
+
+if !exists('g:sqlutil_align_keyword_right')
+    let g:sqlutil_align_keyword_right = 1
+endif
+
+if !exists('g:sqlutil_indent_nested_blocks')
+    let g:sqlutil_indent_nested_blocks = 1
+endif
+
+if !exists('g:sqlutil_wrap_long_lines')
+    let g:sqlutil_wrap_long_lines = 1
+endif
+
+if !exists('g:sqlutil_wrap_function_calls')
+    let g:sqlutil_wrap_function_calls = 1
+endif
+
+if !exists('g:sqlutil_wrap_width')
+    let g:sqlutil_wrap_width = (&textwidth > 0 ? &textwidth : 76)
+endif
+
+if !exists('g:sqlutil_split_unbalanced_paran')
+    let g:sqlutil_split_unbalanced_paran = 1
+endif
+
+if !exists('g:sqlutil_cmd_terminator')
+    let g:sqlutil_cmd_terminator = ';'
+endif
+
+if !exists('g:sqlutil_stmt_keywords')
+    let g:sqlutil_stmt_keywords = 'select,insert,update,delete,with,merge'
+endif
+
+if !exists('g:sqlutil_comment_regex')
+    let g:sqlutil_comment_regex = '\(--\|\/\/\|\/\*\|\*\/\)'
+endif
+
+if !exists('g:sqlutil_keyword_case')
+    " This controls whether keywords should be made
+    " upper or lower case.
+    " The default is to leave them in current case.
+    let g:sqlutil_keyword_case = ''
+endif
+
+if !exists('g:sqlutil_use_tbl_alias')
+    " If this is set to 1, when you run SQLU_CreateColumnList
+    " and you do not specify a 3rd parameter, you will be
+    " prompted for the alias name to append to the column list.
+    "
+    " The default for the alias are the initials for the table:
+    "     some_thing_with_under_bars -> stwub
+    "     somethingwithout           -> s
+    "
+    " The default is no asking
+    "   d - use by default
+    "   a - ask (prompt)
+    "   n - no
+    let g:sqlutil_use_tbl_alias = 'a'
+endif
+
+if !exists('g:sqlutil_col_list_terminators')
+    " You can override which keywords will determine
+    " when a column list finishes:
+    "        CREATE TABLE customer (
+    "        	id	INT DEFAULT AUTOINCREMENT,
+    "        	last_modified TIMESTAMP NULL,
+    "        	first_name     	VARCHAR(30) NOT NULL,
+    "        	last_name	VARCHAR(60) NOT NULL,
+    "        	balance	        NUMERIC(10,2),
+    "        	PRIMARY KEY( id )
+    "        );
+    " So in the above example, when "primary" is reached, we
+    " know the column list is complete.
+    "     PRIMARY KEY
+    "     foreign keys
+    "     indicies
+    "     check contraints
+    "     table contraints
+    "     foreign keys
+    " 
+    let g:sqlutil_col_list_terminators = 
+                \ 'primary\s\+key.*(' .
+                \ ',references' .
+                \ ',match' .
+                \ ',unique' .
+                \ ',check' .
+                \ ',constraint' .
+                \ ',\%(not\s\+null\s\+\)\?foreign'
+endif
+
+if !exists('g:sqlutil_use_syntax_support')
+    " This controls whether search and replace
+    " of various keywords as part of the formatting 
+    " of sql statements should use Vim's built in
+    " syntax support.
+    " The default to use the syntax id to help
+    " determine if keywords are within strings
+    " and therefore not aligning them.
+    let g:sqlutil_use_syntax_support = 1
+else
+    if exists('g:syntax_on') 
+        let g:sqlutil_use_syntax_support = 1
+    else
+        let g:sqlutil_use_syntax_support = 0
+    endif
+endif
+
+if !exists('g:sqlutil_syntax_elements')
+    " This controls how SQLUtilities determines if
+    " the keyword found is within a string or not.
+    " This is a comma separated list of values.
+    " Items within these syntax groups will 
+    " typically be ignored.
+    " The default is Constant,sqlString,sqlComment,Comment.
+    let g:sqlutil_syntax_elements = 'Constant,sqlString,sqlComment,Comment'
+endif
+
+if !exists('g:sqlutil_non_line_break_keywords')
+    " These keywords will be affected by the sqlutil_keyword_case
+    " option.
+    let g:sqlutil_non_line_break_keywords = 'is,as,in,to,of,at,all,first,top,start,limit,offset,recursive,local,temporary,table,read,only,window,over,like,desc,asc,then,not,exists,between,null,any,distinct,similar,contains,only,true,false,unknown'
+endif
+
+" Determines which menu items will be recreated
+let s:sqlutil_menus_created = 0
+
+" Public Interface:
+command! -range=% -nargs=* SQLUFormatStmts <line1>,<line2> 
+            \ call SQLUtilities#SQLU_FormatStmts(<q-args>)
+command! -range -nargs=* SQLUFormatter <line1>,<line2> 
+            \ call SQLUtilities#SQLU_Formatter(<q-args>)
+command!        -nargs=* SQLUCreateColumnList  
+            \ call SQLU_CreateColumnList(<f-args>)
+command!        -nargs=* SQLUGetColumnDef 
+            \ call SQLU_GetColumnDef(<f-args>)
+command!        -nargs=* SQLUGetColumnDataType 
+            \ call SQLU_GetColumnDef(expand("<cword>"), 1)
+command!        -nargs=* SQLUCreateProcedure 
+            \ call SQLU_CreateProcedure(<f-args>)
+command!        -nargs=* SQLUToggleValue 
+            \ call SQLU_ToggleValue(<f-args>)
+
+if !exists("g:sqlutil_load_default_maps")
+    let g:sqlutil_load_default_maps = 1
+endif 
+
+if(g:sqlutil_load_default_maps == 1)
+    if !hasmapto('<Plug>SQLUFormatStmts')
+        nmap <unique> <Leader>sfr <Plug>SQLUFormatStmts
+        vmap <unique> <Leader>sfr <Plug>SQLUFormatStmts
+    endif 
+    if !hasmapto('<Plug>SQLUFormatter')
+        nmap <unique> <Leader>sfs <Plug>SQLUFormatter
+        vmap <unique> <Leader>sfs <Plug>SQLUFormatter
+        nmap <unique> <Leader>sf <Plug>SQLUFormatter
+        vmap <unique> <Leader>sf <Plug>SQLUFormatter
+    endif 
+    if !hasmapto('<Plug>SQLUCreateColumnList')
+        nmap <unique> <Leader>scl <Plug>SQLUCreateColumnList
+    endif 
+    if !hasmapto('<Plug>SQLUGetColumnDef')
+        nmap <unique> <Leader>scd <Plug>SQLUGetColumnDef
+    endif 
+    if !hasmapto('<Plug>SQLUGetColumnDataType')
+        nmap <unique> <Leader>scdt <Plug>SQLUGetColumnDataType
+    endif 
+    if !hasmapto('<Plug>SQLUCreateProcedure')
+        nmap <unique> <Leader>scp <Plug>SQLUCreateProcedure
+    endif 
+endif 
+
+if exists("g:loaded_sqlutilities_global_maps")
+    vunmap <unique> <script> <Plug>SQLUFormatStmts
+    nunmap <unique> <script> <Plug>SQLUFormatStmts
+    vunmap <unique> <script> <Plug>SQLUFormatter
+    nunmap <unique> <script> <Plug>SQLUFormatter
+    nunmap <unique> <script> <Plug>SQLUCreateColumnList
+    nunmap <unique> <script> <Plug>SQLUGetColumnDef
+    nunmap <unique> <script> <Plug>SQLUGetColumnDataType
+    nunmap <unique> <script> <Plug>SQLUCreateProcedure
+endif
+
+" Global Maps:
+vmap <unique> <script> <Plug>SQLUFormatStmts       :SQLUFormatStmts v<CR>
+nmap <unique> <script> <Plug>SQLUFormatStmts       :SQLUFormatStmts n<CR>
+vmap <unique> <script> <Plug>SQLUFormatter         :SQLUFormatter v<CR>
+nmap <unique> <script> <Plug>SQLUFormatter         :SQLUFormatter n<CR>
+nmap <unique> <script> <Plug>SQLUCreateColumnList  :SQLUCreateColumnList<CR>
+nmap <unique> <script> <Plug>SQLUGetColumnDef      :SQLUGetColumnDef<CR>
+nmap <unique> <script> <Plug>SQLUGetColumnDataType :SQLUGetColumnDataType<CR>
+nmap <unique> <script> <Plug>SQLUCreateProcedure   :SQLUCreateProcedure<CR>
+let g:loaded_sqlutilities_global_maps = 1
+
+if !exists('g:sqlutil_default_menu_mode')
+    let g:sqlutil_default_menu_mode = 3
+endif
+
+function! SQLU_Menu()
+    if has("menu") && g:sqlutil_default_menu_mode != 0
+        if g:sqlutil_default_menu_mode == 1
+            let menuRoot     = 'SQLUtil'
+            let menuPriority = exists("g:sqlutil_menu_priority") ? g:sqlutil_menu_priority : ''
+        elseif g:sqlutil_default_menu_mode == 2
+            let menuRoot     = '&SQLUtil'
+            let menuPriority = exists("g:sqlutil_menu_priority") ? g:sqlutil_menu_priority : ''
+        elseif g:sqlutil_default_menu_mode == 3
+            let menuRoot     = exists("g:sqlutil_menu_root") ? g:sqlutil_menu_root : '&Plugin.&SQLUtil'
+            let menuPriority = exists("g:sqlutil_menu_priority") ? g:sqlutil_menu_priority : ''
+        else
+            let menuRoot     = '&Plugin.&SQLUtil'
+            let menuPriority = exists("g:sqlutil_menu_priority") ? g:sqlutil_menu_priority : ''
+        endif
+
+        let leader = '\'
+        if exists('g:mapleader')
+            let leader = g:mapleader
+        endif
+        let leader = escape(leader, '\')
+
+        if s:sqlutil_menus_created == 0 
+            exec 'vnoremenu <script> '.menuPriority.' '.menuRoot.'.Format\ Range\ Stmts<TAB>'.leader.'sfr :SQLUFormatStmts<CR>'
+            exec 'noremenu  <script> '.menuPriority.' '.menuRoot.'.Format\ Range\ Stmts<TAB>'.leader.'sfr :SQLUFormatStmts<CR>'
+            exec 'vnoremenu <script> '.menuPriority.' '.menuRoot.'.Format\ Statement<TAB>'.leader.'sfs :SQLUFormatter<CR>'
+            exec 'noremenu  <script> '.menuPriority.' '.menuRoot.'.Format\ Statement<TAB>'.leader.'sfs :SQLUFormatter<CR>'
+            exec 'noremenu  <script> '.menuPriority.' '.menuRoot.'.Create\ Procedure<TAB>'.leader.'scp :SQLUCreateProcedure<CR>'
+            exec 'inoremenu <script> '.menuPriority.' '.menuRoot.'.Create\ Procedure<TAB>'.leader.'scp  
+                        \ <C-O>:SQLUCreateProcedure<CR>'
+            exec 'noremenu  <script> '.menuPriority.' '.menuRoot.'.Create\ Column\ List<TAB>'.leader.'sl   
+                        \ :SQLUCreateColumnList<CR>'
+            exec 'inoremenu <script> '.menuPriority.' '.menuRoot.'.Create\ Column\ List<TAB>'.leader.'sl 
+                        \ <C-O>:SQLUCreateColumnList<CR>'
+            exec 'noremenu  <script> '.menuPriority.' '.menuRoot.'.Column\ Definition<TAB>'.leader.'scd 
+                        \ :SQLUGetColumnDef<CR>'
+            exec 'inoremenu <script> '.menuPriority.' '.menuRoot.'.Column\ Definition<TAB>'.leader.'scd 
+                        \ <C-O>:SQLUGetColumnDef<CR>'
+            exec 'noremenu  <script> '.menuPriority.' '.menuRoot.'.Column\ Datatype<TAB>'.leader.'scdt
+                        \ :SQLUGetColumnDataType<CR>'
+            exec 'inoremenu <script> '.menuPriority.' '.menuRoot.'.Column\ Datatype<TAB>'.leader.'scdt
+                        \ <C-O>:SQLUGetColumnDataType<CR>'
+
+            let s:sqlutil_menus_created = 1
+        endif
+        silent! exec 'aunmenu  <script> '.menuPriority.' '.menuRoot.'.Toggle\ Align\ Where'
+        exec 'noremenu  <script> '.menuPriority.' '.menuRoot.'.Toggle\ Align\ Where'.
+                    \ (g:sqlutil_align_where==1?'<TAB>(on) ':'<TAB>(off) ').
+                    \ ':SQLUToggleValue g:sqlutil_align_where<CR>'
+        silent! exec 'aunmenu '.menuPriority.' '.menuRoot.'.Toggle\ Align\ Comma'
+        exec 'noremenu  <script> '.menuPriority.' '.menuRoot.'.Toggle\ Align\ Comma'.
+                    \ (g:sqlutil_align_comma==1?'<TAB>(on) ':'<TAB>(off) ').
+                    \ ':SQLUToggleValue g:sqlutil_align_comma<CR>'
+        silent! exec 'aunmenu '.menuPriority.' '.menuRoot.'.Toggle\ Align\ First\ Word'
+        exec 'noremenu  <script> '.menuPriority.' '.menuRoot.'.Toggle\ Align\ First\ Word'.
+                    \ (g:sqlutil_align_first_word==1?'<TAB>(on) ':'<TAB>(off) ').
+                    \ ':SQLUToggleValue g:sqlutil_align_first_word<CR>'
+        silent! exec 'aunmenu '.menuPriority.' '.menuRoot.'.Toggle\ Right\ Align\ Keywords'
+        exec 'noremenu  <script> '.menuPriority.' '.menuRoot.'.Toggle\ Right\ Align\ Keywords'.
+                    \ (g:sqlutil_align_keyword_right=='1'?'<TAB>(on) ':'<TAB>(off) ').
+                    \ ':SQLUToggleValue g:sqlutil_align_keyword_right<CR>'
+        silent! exec 'aunmenu '.menuPriority.' '.menuRoot.'.Uppercase\ Keywords'
+        exec 'noremenu  <script> '.menuPriority.' '.menuRoot.'.Uppercase\ Keywords'.
+                    \ (g:sqlutil_keyword_case=='\U'?'<TAB>(on) ':' ').
+                    \ ':SQLUToggleValue g:sqlutil_keyword_case \U<CR>'
+        silent! exec 'aunmenu '.menuPriority.' '.menuRoot.'.Lowercase\ Keywords'
+        exec 'noremenu  <script> '.menuPriority.' '.menuRoot.'.Lowercase\ Keywords'.
+                    \ (g:sqlutil_keyword_case=='\L'?'<TAB>(on) ':' ').
+                    \ ':SQLUToggleValue g:sqlutil_keyword_case \L<CR>'
+        silent! exec 'aunmenu '.menuPriority.' '.menuRoot.'.Default\ Case\ Keywords'
+        exec 'noremenu  <script> '.menuPriority.' '.menuRoot.'.Default\ Case\ Keywords'.
+                    \ (g:sqlutil_keyword_case==''?'<TAB>(on) ':' ').
+                    \ ':SQLUToggleValue g:sqlutil_keyword_case default<CR>'
+        silent! exec 'aunmenu '.menuPriority.' '.menuRoot.'.-Debug-'
+        exec 'noremenu  <script> '.menuPriority.' '.menuRoot.'.-Debug- :'
+        silent! exec 'aunmenu '.menuPriority.' '.menuRoot.'.Toggle\ Indent\ Nested\ Blocks'
+        exec 'noremenu  <script> '.menuPriority.' '.menuRoot.'.Toggle\ Indent\ Nested\ Blocks'.
+                    \ (g:sqlutil_indent_nested_blocks=='1'?'<TAB>(on) ':'<TAB>(off) ').
+                    \ ':SQLUToggleValue g:sqlutil_indent_nested_blocks<CR>'
+        silent! exec 'aunmenu '.menuPriority.' '.menuRoot.'.Toggle\ Wrap\ Long\ Lines'
+        exec 'noremenu  <script> '.menuPriority.' '.menuRoot.'.Toggle\ Wrap\ Long\ Lines'.
+                    \ (g:sqlutil_wrap_long_lines=='1'?'<TAB>(on) ':'<TAB>(off) ').
+                    \ ':SQLUToggleValue g:sqlutil_wrap_long_lines<CR>'
+        silent! exec 'aunmenu '.menuPriority.' '.menuRoot.'.Toggle\ Wrap\ Function\ Calls'
+        exec 'noremenu  <script> '.menuPriority.' '.menuRoot.'.Toggle\ Wrap\ Function\ Calls'.
+                    \ (g:sqlutil_wrap_function_calls=='1'?'<TAB>(on) ':'<TAB>(off) ').
+                    \ ':SQLUToggleValue g:sqlutil_wrap_function_calls<CR>'
+        silent! exec 'aunmenu '.menuPriority.' '.menuRoot.'.Toggle\ Split\ Unbalanced\ Paranthesis'
+        exec 'noremenu  <script> '.menuPriority.' '.menuRoot.'.Toggle\ Split\ Unbalanced\ Paranthesis'.
+                    \ (g:sqlutil_split_unbalanced_paran=='1'?'<TAB>(on) ':'<TAB>(off) ').
+                    \ ':SQLUToggleValue g:sqlutil_split_unbalanced_paran<CR>'
+    endif
+endfunction
+
+" Puts a command separate list of columns given a table name
+" Will search through the file looking for the create table command
+" It assumes that each column is on a separate line
+" It places the column list in unnamed buffer
+function! SQLU_CreateColumnList(...)
+    if(a:0 > 1) 
+        call SQLUtilities#SQLU_CreateColumnList(a:1, a:2)
+    elseif(a:0 > 0) 
+        call SQLUtilities#SQLU_CreateColumnList(a:1)
+    else
+        call SQLUtilities#SQLU_CreateColumnList()
+    endif
+endfunction
+
+
+" Strip the datatype from a column definition line
+function! SQLU_GetColumnDatatype( line, need_type )
+    return SQLUtilities#SQLU_GetColumnDatatype(a:line, a:need_type)
+endfunction
+
+
+" Puts a comma separated list of columns given a table name
+" Will search through the file looking for the create table command
+" It assumes that each column is on a separate line
+" It places the column list in unnamed buffer
+function! SQLU_GetColumnDef( ... )
+    if(a:0 > 1) 
+        return SQLUtilities#SQLU_GetColumnDef(a:1, a:2)
+    elseif(a:0 > 0) 
+        return SQLUtilities#SQLU_GetColumnDef(a:1)
+    else
+        return SQLUtilities#SQLU_GetColumnDef()
+    endif
+endfunction
+
+
+
+" Creates a procedure defintion into the unnamed buffer for the 
+" table that the cursor is currently under.
+function! SQLU_CreateProcedure(...)
+    if(a:0 > 0) 
+        return SQLUtilities#SQLU_CreateProcedure(a:1)
+    else
+        return SQLUtilities#SQLU_CreateProcedure()
+    endif
+endfunction
+
+
+
+" Compares two strings, and will remove all names from the first 
+" parameter, if the same name exists in the second column name.
+" The 2 parameters take comma separated lists
+function! SQLU_RemoveMatchingColumns( full_col_list, dup_col_list )
+    return SQLUtilities#SQLU_RemoveMatchingColumns( a:full_col_list, a:dup_col_list )
+endfunction
+
+
+
+" Toggles the value of some configuration parameters.
+" Mainly used by the menu.
+function! SQLU_ToggleValue( ... )
+    if (a:0 == 0)
+        echohl WarningMsg
+        echomsg "SQLUToggle value requires at least 1 parameter"
+        echohl None
+    elseif (a:0 == 1)
+        if exists('{a:1}') 
+            let {a:1} = (({a:1} == 0)?1:0)
+        endif
+    else
+        if exists('{a:1}') 
+            " Use defaults as the default for this function
+            if a:2 == 'default'
+                let {a:1} = ''
+            else
+                let {a:1} = a:2
+            endif
+        endif
+    endif
+    call SQLU_Menu()
+endfunction
+
+call SQLU_Menu()
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
+
+" vim:fdm=marker:nowrap:ts=4:expandtab:ff=unix:
diff --git a/src/testdir/bundles/searchpair/searchpair.sql b/src/testdir/bundles/searchpair/searchpair.sql
new file mode 100644
index 0000000..8057192
--- /dev/null
+++ b/src/testdir/bundles/searchpair/searchpair.sql
@@ -0,0 +1,2 @@
+    SELECT ( CASE 
+             END CASE) AS 'POTYP', COALESCE( OLTXT.LTXT, '' ) AS LTXT FROM O_PO_HDR po
diff --git a/src/testdir/test_searchpair.vim b/src/testdir/test_searchpair.vim
new file mode 100644
index 0000000..4f87e8a
--- /dev/null
+++ b/src/testdir/test_searchpair.vim
@@ -0,0 +1,27 @@
+" Tests for searchpair() function
+
+func SetUp()
+	set rtp+=./bundles/searchpair
+	set nocp selectmode=
+	behave xterm
+	syntax on
+	filetype plugin indent on
+	cd .
+	source ./bundles/searchpair/plugin/SQLUtilities.vim
+	source ./bundles/searchpair/autoload/SQLUtilities.vim
+	new 
+	edit ./bundles/searchpair/searchpair.sql
+endfu
+
+func Test_searchpair()
+	":%SQLUFormatter
+	1,2call SQLUtilities#SQLU_Formatter('')
+	call assert_equal(['    SELECT  (', '	 CASE', '	 END CASE', ' ) AS ''POTYP'', COALESCE( OLTXT.LTXT, '''' ) AS LTXT', 'FROM  O_PO_HDR po'], getline(1,'$'))
+endfu
+
+func TearDown()
+	bw!
+endfu
+
+
+" vim: tabstop=2 shiftwidth=0 expandtab

Raspunde prin e-mail lui