10fd9289dSBram Moolenaar" Vim indent file 20fd9289dSBram Moolenaar" Language: SQL 334feacbcSBram Moolenaar" Maintainer: David Fishburn <dfishburn dot vim at gmail dot com> 4*2286304cSBram Moolenaar" Last Change: 2021 Oct 11 5*2286304cSBram Moolenaar" Version: 4.0 60fd9289dSBram Moolenaar" Download: http://vim.sourceforge.net/script.php?script_id=495 70fd9289dSBram Moolenaar 80fd9289dSBram Moolenaar" Notes: 90fd9289dSBram Moolenaar" Indenting keywords are based on Oracle and Sybase Adaptive Server 100fd9289dSBram Moolenaar" Anywhere (ASA). Test indenting was done with ASA stored procedures and 116c391a74SBram Moolenaar" functions and Oracle packages which contain stored procedures and 120fd9289dSBram Moolenaar" functions. 130fd9289dSBram Moolenaar" This has not been tested against Microsoft SQL Server or 140fd9289dSBram Moolenaar" Sybase Adaptive Server Enterprise (ASE) which use the Transact-SQL 150fd9289dSBram Moolenaar" syntax. That syntax does not have end tags for IF's, which makes 160fd9289dSBram Moolenaar" indenting more difficult. 170fd9289dSBram Moolenaar" 180fd9289dSBram Moolenaar" Known Issues: 190fd9289dSBram Moolenaar" The Oracle MERGE statement does not have an end tag associated with 200fd9289dSBram Moolenaar" it, this can leave the indent hanging to the right one too many. 2134feacbcSBram Moolenaar" 2234feacbcSBram Moolenaar" History: 23*2286304cSBram Moolenaar" 4.0 (Oct 2021) 24*2286304cSBram Moolenaar" Added b:undo_indent 25*2286304cSBram Moolenaar" 2634feacbcSBram Moolenaar" 3.0 (Dec 2012) 2734feacbcSBram Moolenaar" Added cpo check 2834feacbcSBram Moolenaar" 2934feacbcSBram Moolenaar" 2.0 3034feacbcSBram Moolenaar" Added the FOR keyword to SQLBlockStart to handle (Alec Tica): 3134feacbcSBram Moolenaar" for i in 1..100 loop 3234feacbcSBram Moolenaar" |<-- I expect to have indentation here 3334feacbcSBram Moolenaar" end loop; 3434feacbcSBram Moolenaar" 350fd9289dSBram Moolenaar 360fd9289dSBram Moolenaar" Only load this indent file when no other was loaded. 370fd9289dSBram Moolenaarif exists("b:did_indent") 380fd9289dSBram Moolenaar finish 390fd9289dSBram Moolenaarendif 400fd9289dSBram Moolenaarlet b:did_indent = 1 410fd9289dSBram Moolenaarlet b:current_indent = "sqlanywhere" 420fd9289dSBram Moolenaar 430fd9289dSBram Moolenaarsetlocal indentkeys-=0{ 440fd9289dSBram Moolenaarsetlocal indentkeys-=0} 450fd9289dSBram Moolenaarsetlocal indentkeys-=: 460fd9289dSBram Moolenaarsetlocal indentkeys-=0# 470fd9289dSBram Moolenaarsetlocal indentkeys-=e 480fd9289dSBram Moolenaar 490fd9289dSBram Moolenaar" This indicates formatting should take place when one of these 500fd9289dSBram Moolenaar" expressions is used. These expressions would normally be something 510fd9289dSBram Moolenaar" you would type at the BEGINNING of a line 520fd9289dSBram Moolenaar" SQL is generally case insensitive, so this files assumes that 530fd9289dSBram Moolenaar" These keywords are something that would trigger an indent LEFT, not 540fd9289dSBram Moolenaar" an indent right, since the SQLBlockStart is used for those keywords 550fd9289dSBram Moolenaarsetlocal indentkeys+==~end,=~else,=~elseif,=~elsif,0=~when,0=) 560fd9289dSBram Moolenaar 570fd9289dSBram Moolenaar" GetSQLIndent is executed whenever one of the expressions 580fd9289dSBram Moolenaar" in the indentkeys is typed 590fd9289dSBram Moolenaarsetlocal indentexpr=GetSQLIndent() 600fd9289dSBram Moolenaar 61*2286304cSBram Moolenaarlet b:undo_indent = "setl indentexpr< indentkeys<" 62*2286304cSBram Moolenaar 63a3e6bc93SBram Moolenaar" Only define the functions once. 64a3e6bc93SBram Moolenaarif exists("*GetSQLIndent") 65a3e6bc93SBram Moolenaar finish 66a3e6bc93SBram Moolenaarendif 67*2286304cSBram Moolenaar 68a3e6bc93SBram Moolenaarlet s:keepcpo= &cpo 69a3e6bc93SBram Moolenaarset cpo&vim 70a3e6bc93SBram Moolenaar 710fd9289dSBram Moolenaar" List of all the statements that start a new block. 720fd9289dSBram Moolenaar" These are typically words that start a line. 730fd9289dSBram Moolenaar" IS is excluded, since it is difficult to determine when the 740fd9289dSBram Moolenaar" ending block is (especially for procedures/functions). 750fd9289dSBram Moolenaarlet s:SQLBlockStart = '^\s*\%('. 76*2286304cSBram Moolenaar \ 'if\|else\|elseif\|elsif\|'. 77*2286304cSBram Moolenaar \ 'while\|loop\|do\|for\|'. 78*2286304cSBram Moolenaar \ 'begin\|'. 790fd9289dSBram Moolenaar \ 'case\|when\|merge\|exception'. 800fd9289dSBram Moolenaar \ '\)\>' 810fd9289dSBram Moolenaarlet s:SQLBlockEnd = '^\s*\(end\)\>' 820fd9289dSBram Moolenaar 83acc22406SBram Moolenaar" The indent level is also based on unmatched parentheses 840fd9289dSBram Moolenaar" If a line has an extra "(" increase the indent 850fd9289dSBram Moolenaar" If a line has an extra ")" decrease the indent 86acc22406SBram Moolenaarfunction! s:CountUnbalancedParen( line, paren_to_check ) 870fd9289dSBram Moolenaar let l = a:line 880fd9289dSBram Moolenaar let lp = substitute(l, '[^(]', '', 'g') 890fd9289dSBram Moolenaar let l = a:line 900fd9289dSBram Moolenaar let rp = substitute(l, '[^)]', '', 'g') 910fd9289dSBram Moolenaar 92acc22406SBram Moolenaar if a:paren_to_check =~ ')' 93acc22406SBram Moolenaar " echom 'CountUnbalancedParen ) returning: ' . 940fd9289dSBram Moolenaar " \ (strlen(rp) - strlen(lp)) 950fd9289dSBram Moolenaar return (strlen(rp) - strlen(lp)) 96acc22406SBram Moolenaar elseif a:paren_to_check =~ '(' 97acc22406SBram Moolenaar " echom 'CountUnbalancedParen ( returning: ' . 980fd9289dSBram Moolenaar " \ (strlen(lp) - strlen(rp)) 990fd9289dSBram Moolenaar return (strlen(lp) - strlen(rp)) 1000fd9289dSBram Moolenaar else 101acc22406SBram Moolenaar " echom 'CountUnbalancedParen unknown paren to check: ' . 102acc22406SBram Moolenaar " \ a:paren_to_check 1030fd9289dSBram Moolenaar return 0 1040fd9289dSBram Moolenaar endif 1050fd9289dSBram Moolenaarendfunction 1060fd9289dSBram Moolenaar 1070fd9289dSBram Moolenaar" Unindent commands based on previous indent level 108acc22406SBram Moolenaarfunction! s:CheckToIgnoreRightParen( prev_lnum, num_levels ) 1090fd9289dSBram Moolenaar let lnum = a:prev_lnum 1100fd9289dSBram Moolenaar let line = getline(lnum) 1110fd9289dSBram Moolenaar let ends = 0 112acc22406SBram Moolenaar let num_right_paren = a:num_levels 113acc22406SBram Moolenaar let ignore_paren = 0 1140fd9289dSBram Moolenaar let vircol = 1 1150fd9289dSBram Moolenaar 116acc22406SBram Moolenaar while num_right_paren > 0 1170fd9289dSBram Moolenaar silent! exec 'norm! '.lnum."G\<bar>".vircol."\<bar>" 118acc22406SBram Moolenaar let right_paren = search( ')', 'W' ) 119acc22406SBram Moolenaar if right_paren != lnum 1200fd9289dSBram Moolenaar " This should not happen since there should be at least 121acc22406SBram Moolenaar " num_right_paren matches for this line 1220fd9289dSBram Moolenaar break 1230fd9289dSBram Moolenaar endif 1240fd9289dSBram Moolenaar let vircol = virtcol(".") 1250fd9289dSBram Moolenaar 1260fd9289dSBram Moolenaar " if getline(".") =~ '^)' 127acc22406SBram Moolenaar let matching_paren = searchpair('(', '', ')', 'bW', 128a7241f5fSBram Moolenaar \ 's:IsColComment(line("."), col("."))') 1290fd9289dSBram Moolenaar 130acc22406SBram Moolenaar if matching_paren < 1 1310fd9289dSBram Moolenaar " No match found 1320fd9289dSBram Moolenaar " echom 'CTIRP - no match found, ignoring' 1330fd9289dSBram Moolenaar break 1340fd9289dSBram Moolenaar endif 1350fd9289dSBram Moolenaar 136acc22406SBram Moolenaar if matching_paren == lnum 137acc22406SBram Moolenaar " This was not an unmatched parentheses, start the search again 1380fd9289dSBram Moolenaar " again after this column 1390fd9289dSBram Moolenaar " echom 'CTIRP - same line match, ignoring' 1400fd9289dSBram Moolenaar continue 1410fd9289dSBram Moolenaar endif 1420fd9289dSBram Moolenaar 1430fd9289dSBram Moolenaar " echom 'CTIRP - match: ' . line(".") . ' ' . getline(".") 1440fd9289dSBram Moolenaar 145acc22406SBram Moolenaar if getline(matching_paren) =~? '\(if\|while\)\>' 1460fd9289dSBram Moolenaar " echom 'CTIRP - if/while ignored: ' . line(".") . ' ' . getline(".") 147acc22406SBram Moolenaar let ignore_paren = ignore_paren + 1 1480fd9289dSBram Moolenaar endif 1490fd9289dSBram Moolenaar 1500fd9289dSBram Moolenaar " One match found, decrease and check for further matches 151acc22406SBram Moolenaar let num_right_paren = num_right_paren - 1 1520fd9289dSBram Moolenaar 1530fd9289dSBram Moolenaar endwhile 1540fd9289dSBram Moolenaar 1550fd9289dSBram Moolenaar " Fallback - just move back one 1563ec574f2SBram Moolenaar " return a:prev_indent - shiftwidth() 157acc22406SBram Moolenaar return ignore_paren 1580fd9289dSBram Moolenaarendfunction 1590fd9289dSBram Moolenaar 1600fd9289dSBram Moolenaar" Based on the keyword provided, loop through previous non empty 161acc22406SBram Moolenaar" non comment lines to find the statement that initiated the keyword. 1620fd9289dSBram Moolenaar" Return its indent level 1630fd9289dSBram Moolenaar" CASE .. 1640fd9289dSBram Moolenaar" WHEN ... 1650fd9289dSBram Moolenaar" Should return indent level of CASE 1660fd9289dSBram Moolenaar" EXCEPTION .. 1670fd9289dSBram Moolenaar" WHEN ... 1680fd9289dSBram Moolenaar" something; 1690fd9289dSBram Moolenaar" WHEN ... 1700fd9289dSBram Moolenaar" Should return indent level of exception. 17134feacbcSBram Moolenaarfunction! s:GetStmtStarterIndent( keyword, curr_lnum ) 1720fd9289dSBram Moolenaar let lnum = a:curr_lnum 1730fd9289dSBram Moolenaar 1740fd9289dSBram Moolenaar " Default - reduce indent by 1 1753ec574f2SBram Moolenaar let ind = indent(a:curr_lnum) - shiftwidth() 1760fd9289dSBram Moolenaar 1770fd9289dSBram Moolenaar if a:keyword =~? 'end' 1780fd9289dSBram Moolenaar exec 'normal! ^' 1790fd9289dSBram Moolenaar let stmts = '^\s*\%('. 1800fd9289dSBram Moolenaar \ '\<begin\>\|' . 1810fd9289dSBram Moolenaar \ '\%(\%(\<end\s\+\)\@<!\<loop\>\)\|' . 1820fd9289dSBram Moolenaar \ '\%(\%(\<end\s\+\)\@<!\<case\>\)\|' . 1830fd9289dSBram Moolenaar \ '\%(\%(\<end\s\+\)\@<!\<for\>\)\|' . 1840fd9289dSBram Moolenaar \ '\%(\%(\<end\s\+\)\@<!\<if\>\)'. 1850fd9289dSBram Moolenaar \ '\)' 1860fd9289dSBram Moolenaar let matching_lnum = searchpair(stmts, '', '\<end\>\zs', 'bW', 187a7241f5fSBram Moolenaar \ 's:IsColComment(line("."), col(".")) == 1') 1880fd9289dSBram Moolenaar exec 'normal! $' 1890fd9289dSBram Moolenaar if matching_lnum > 0 && matching_lnum < a:curr_lnum 1900fd9289dSBram Moolenaar let ind = indent(matching_lnum) 1910fd9289dSBram Moolenaar endif 1920fd9289dSBram Moolenaar elseif a:keyword =~? 'when' 1930fd9289dSBram Moolenaar exec 'normal! ^' 1940fd9289dSBram Moolenaar let matching_lnum = searchpair( 1950fd9289dSBram Moolenaar \ '\%(\<end\s\+\)\@<!\<case\>\|\<exception\>\|\<merge\>', 1960fd9289dSBram Moolenaar \ '', 1970fd9289dSBram Moolenaar \ '\%(\%(\<when\s\+others\>\)\|\%(\<end\s\+case\>\)\)', 1980fd9289dSBram Moolenaar \ 'bW', 199a7241f5fSBram Moolenaar \ 's:IsColComment(line("."), col(".")) == 1') 2000fd9289dSBram Moolenaar exec 'normal! $' 2010fd9289dSBram Moolenaar if matching_lnum > 0 && matching_lnum < a:curr_lnum 2020fd9289dSBram Moolenaar let ind = indent(matching_lnum) 2030fd9289dSBram Moolenaar else 2040fd9289dSBram Moolenaar let ind = indent(a:curr_lnum) 2050fd9289dSBram Moolenaar endif 2060fd9289dSBram Moolenaar endif 2070fd9289dSBram Moolenaar 2080fd9289dSBram Moolenaar return ind 2090fd9289dSBram Moolenaarendfunction 2100fd9289dSBram Moolenaar 2110fd9289dSBram Moolenaar 2120fd9289dSBram Moolenaar" Check if the line is a comment 21334feacbcSBram Moolenaarfunction! s:IsLineComment(lnum) 2140fd9289dSBram Moolenaar let rc = synIDattr( 2150fd9289dSBram Moolenaar \ synID(a:lnum, 2160fd9289dSBram Moolenaar \ match(getline(a:lnum), '\S')+1, 0) 2170fd9289dSBram Moolenaar \ , "name") 2180fd9289dSBram Moolenaar \ =~? "comment" 2190fd9289dSBram Moolenaar 2200fd9289dSBram Moolenaar return rc 2210fd9289dSBram Moolenaarendfunction 2220fd9289dSBram Moolenaar 2230fd9289dSBram Moolenaar 2240fd9289dSBram Moolenaar" Check if the column is a comment 22534feacbcSBram Moolenaarfunction! s:IsColComment(lnum, cnum) 2260fd9289dSBram Moolenaar let rc = synIDattr(synID(a:lnum, a:cnum, 0), "name") 2270fd9289dSBram Moolenaar \ =~? "comment" 2280fd9289dSBram Moolenaar 2290fd9289dSBram Moolenaar return rc 2300fd9289dSBram Moolenaarendfunction 2310fd9289dSBram Moolenaar 2320fd9289dSBram Moolenaar 233a7241f5fSBram Moolenaar" Instead of returning a column position, return 234a7241f5fSBram Moolenaar" an appropriate value as a factor of shiftwidth. 23534feacbcSBram Moolenaarfunction! s:ModuloIndent(ind) 2360fd9289dSBram Moolenaar let ind = a:ind 2370fd9289dSBram Moolenaar 2380fd9289dSBram Moolenaar if ind > 0 2393ec574f2SBram Moolenaar let modulo = ind % shiftwidth() 2400fd9289dSBram Moolenaar 2410fd9289dSBram Moolenaar if modulo > 0 2420fd9289dSBram Moolenaar let ind = ind - modulo 2430fd9289dSBram Moolenaar endif 2440fd9289dSBram Moolenaar endif 2450fd9289dSBram Moolenaar 2460fd9289dSBram Moolenaar return ind 2470fd9289dSBram Moolenaarendfunction 2480fd9289dSBram Moolenaar 2490fd9289dSBram Moolenaar 2500fd9289dSBram Moolenaar" Find correct indent of a new line based upon the previous line 25134feacbcSBram Moolenaarfunction! GetSQLIndent() 2520fd9289dSBram Moolenaar let lnum = v:lnum 2530fd9289dSBram Moolenaar let ind = indent(lnum) 2540fd9289dSBram Moolenaar 2550fd9289dSBram Moolenaar " If the current line is a comment, leave the indent as is 2560fd9289dSBram Moolenaar " Comment out this additional check since it affects the 2570fd9289dSBram Moolenaar " indenting of =, and will not reindent comments as it should 258a7241f5fSBram Moolenaar " if s:IsLineComment(lnum) == 1 2590fd9289dSBram Moolenaar " return ind 2600fd9289dSBram Moolenaar " endif 2610fd9289dSBram Moolenaar 2620fd9289dSBram Moolenaar " Get previous non-blank line 2630fd9289dSBram Moolenaar let prevlnum = prevnonblank(lnum - 1) 2640fd9289dSBram Moolenaar if prevlnum <= 0 2650fd9289dSBram Moolenaar return ind 2660fd9289dSBram Moolenaar endif 2670fd9289dSBram Moolenaar 268a7241f5fSBram Moolenaar if s:IsLineComment(prevlnum) == 1 2690fd9289dSBram Moolenaar if getline(v:lnum) =~ '^\s*\*' 270a7241f5fSBram Moolenaar let ind = s:ModuloIndent(indent(prevlnum)) 2710fd9289dSBram Moolenaar return ind + 1 2720fd9289dSBram Moolenaar endif 2730fd9289dSBram Moolenaar " If the previous line is a comment, then return -1 2740fd9289dSBram Moolenaar " to tell Vim to use the formatoptions setting to determine 2750fd9289dSBram Moolenaar " the indent to use 2760fd9289dSBram Moolenaar " But only if the next line is blank. This would be true if 2770fd9289dSBram Moolenaar " the user is typing, but it would not be true if the user 2780fd9289dSBram Moolenaar " is reindenting the file 2790fd9289dSBram Moolenaar if getline(v:lnum) =~ '^\s*$' 2800fd9289dSBram Moolenaar return -1 2810fd9289dSBram Moolenaar endif 2820fd9289dSBram Moolenaar endif 2830fd9289dSBram Moolenaar 2840fd9289dSBram Moolenaar " echom 'PREVIOUS INDENT: ' . indent(prevlnum) . ' LINE: ' . getline(prevlnum) 2850fd9289dSBram Moolenaar 2860fd9289dSBram Moolenaar " This is the line you just hit return on, it is not the current line 2870fd9289dSBram Moolenaar " which is new and empty 2880fd9289dSBram Moolenaar " Based on this line, we can determine how much to indent the new 2890fd9289dSBram Moolenaar " line 2900fd9289dSBram Moolenaar 2910fd9289dSBram Moolenaar " Get default indent (from prev. line) 2920fd9289dSBram Moolenaar let ind = indent(prevlnum) 2930fd9289dSBram Moolenaar let prevline = getline(prevlnum) 2940fd9289dSBram Moolenaar 2950fd9289dSBram Moolenaar " Now check what's on the previous line to determine if the indent 2960fd9289dSBram Moolenaar " should be changed, for example IF, BEGIN, should increase the indent 2970fd9289dSBram Moolenaar " where END IF, END, should decrease the indent. 2980fd9289dSBram Moolenaar if prevline =~? s:SQLBlockStart 2990fd9289dSBram Moolenaar " Move indent in 3003ec574f2SBram Moolenaar let ind = ind + shiftwidth() 3010fd9289dSBram Moolenaar " echom 'prevl - SQLBlockStart - indent ' . ind . ' line: ' . prevline 3020fd9289dSBram Moolenaar elseif prevline =~ '[()]' 3030fd9289dSBram Moolenaar if prevline =~ '(' 304acc22406SBram Moolenaar let num_unmatched_left = s:CountUnbalancedParen( prevline, '(' ) 3050fd9289dSBram Moolenaar else 3060fd9289dSBram Moolenaar let num_unmatched_left = 0 3070fd9289dSBram Moolenaar endif 3080fd9289dSBram Moolenaar if prevline =~ ')' 309acc22406SBram Moolenaar let num_unmatched_right = s:CountUnbalancedParen( prevline, ')' ) 3100fd9289dSBram Moolenaar else 3110fd9289dSBram Moolenaar let num_unmatched_right = 0 312acc22406SBram Moolenaar " let num_unmatched_right = s:CountUnbalancedParen( prevline, ')' ) 3130fd9289dSBram Moolenaar endif 3140fd9289dSBram Moolenaar if num_unmatched_left > 0 315acc22406SBram Moolenaar " There is a open left parenthesis 3160fd9289dSBram Moolenaar " increase indent 3173ec574f2SBram Moolenaar let ind = ind + ( shiftwidth() * num_unmatched_left ) 3180fd9289dSBram Moolenaar elseif num_unmatched_right > 0 319acc22406SBram Moolenaar " if it is an unbalanced parenthesis only unindent if 3200fd9289dSBram Moolenaar " it was part of a command (ie create table(..) ) 3210fd9289dSBram Moolenaar " instead of part of an if (ie if (....) then) which should 3220fd9289dSBram Moolenaar " maintain the indent level 323acc22406SBram Moolenaar let ignore = s:CheckToIgnoreRightParen( prevlnum, num_unmatched_right ) 3240fd9289dSBram Moolenaar " echom 'prevl - ) unbalanced - CTIRP - ignore: ' . ignore 3250fd9289dSBram Moolenaar 3260fd9289dSBram Moolenaar if prevline =~ '^\s*)' 3270fd9289dSBram Moolenaar let ignore = ignore + 1 3280fd9289dSBram Moolenaar " echom 'prevl - begins ) unbalanced ignore: ' . ignore 3290fd9289dSBram Moolenaar endif 3300fd9289dSBram Moolenaar 3310fd9289dSBram Moolenaar if (num_unmatched_right - ignore) > 0 3323ec574f2SBram Moolenaar let ind = ind - ( shiftwidth() * (num_unmatched_right - ignore) ) 3330fd9289dSBram Moolenaar endif 3340fd9289dSBram Moolenaar 3350fd9289dSBram Moolenaar endif 3360fd9289dSBram Moolenaar endif 3370fd9289dSBram Moolenaar 3380fd9289dSBram Moolenaar 3390fd9289dSBram Moolenaar " echom 'CURRENT INDENT: ' . ind . ' LINE: ' . getline(v:lnum) 3400fd9289dSBram Moolenaar 3410fd9289dSBram Moolenaar " This is a new blank line since we just typed a carriage return 3420fd9289dSBram Moolenaar " Check current line; search for simplistic matching start-of-block 3430fd9289dSBram Moolenaar let line = getline(v:lnum) 3440fd9289dSBram Moolenaar 3450fd9289dSBram Moolenaar if line =~? '^\s*els' 3460fd9289dSBram Moolenaar " Any line when you type else will automatically back up one 3470fd9289dSBram Moolenaar " ident level (ie else, elseif, elsif) 3483ec574f2SBram Moolenaar let ind = ind - shiftwidth() 3490fd9289dSBram Moolenaar " echom 'curr - else - indent ' . ind 3500fd9289dSBram Moolenaar elseif line =~? '^\s*end\>' 3510fd9289dSBram Moolenaar let ind = s:GetStmtStarterIndent('end', v:lnum) 3520fd9289dSBram Moolenaar " General case for end 3533ec574f2SBram Moolenaar " let ind = ind - shiftwidth() 3540fd9289dSBram Moolenaar " echom 'curr - end - indent ' . ind 3550fd9289dSBram Moolenaar elseif line =~? '^\s*when\>' 3560fd9289dSBram Moolenaar let ind = s:GetStmtStarterIndent('when', v:lnum) 3570fd9289dSBram Moolenaar " If the WHEN clause is used with a MERGE or EXCEPTION 3580fd9289dSBram Moolenaar " clause, do not change the indent level, since these 3590fd9289dSBram Moolenaar " statements do not have a corresponding END statement. 3600fd9289dSBram Moolenaar " if stmt_starter =~? 'case' 3613ec574f2SBram Moolenaar " let ind = ind - shiftwidth() 3620fd9289dSBram Moolenaar " endif 3630fd9289dSBram Moolenaar " elseif line =~ '^\s*)\s*;\?\s*$' 3640fd9289dSBram Moolenaar " elseif line =~ '^\s*)' 3650fd9289dSBram Moolenaar elseif line =~ '^\s*)' 366acc22406SBram Moolenaar let num_unmatched_right = s:CountUnbalancedParen( line, ')' ) 367acc22406SBram Moolenaar let ignore = s:CheckToIgnoreRightParen( v:lnum, num_unmatched_right ) 3680fd9289dSBram Moolenaar " If the line ends in a ), then reduce the indent 3690fd9289dSBram Moolenaar " This catches items like: 3700fd9289dSBram Moolenaar " CREATE TABLE T1( 3710fd9289dSBram Moolenaar " c1 int, 3720fd9289dSBram Moolenaar " c2 int 3730fd9289dSBram Moolenaar " ); 3740fd9289dSBram Moolenaar " But we do not want to unindent a line like: 3750fd9289dSBram Moolenaar " IF ( c1 = 1 3760fd9289dSBram Moolenaar " AND c2 = 3 ) THEN 377acc22406SBram Moolenaar " let num_unmatched_right = s:CountUnbalancedParen( line, ')' ) 3780fd9289dSBram Moolenaar " if num_unmatched_right > 0 3790fd9289dSBram Moolenaar " elseif strpart( line, strlen(line)-1, 1 ) =~ ')' 3803ec574f2SBram Moolenaar " let ind = ind - shiftwidth() 3810fd9289dSBram Moolenaar if line =~ '^\s*)' 3820fd9289dSBram Moolenaar " let ignore = ignore + 1 3830fd9289dSBram Moolenaar " echom 'curr - begins ) unbalanced ignore: ' . ignore 3840fd9289dSBram Moolenaar endif 3850fd9289dSBram Moolenaar 3860fd9289dSBram Moolenaar if (num_unmatched_right - ignore) > 0 3873ec574f2SBram Moolenaar let ind = ind - ( shiftwidth() * (num_unmatched_right - ignore) ) 3880fd9289dSBram Moolenaar endif 3890fd9289dSBram Moolenaar " endif 3900fd9289dSBram Moolenaar endif 3910fd9289dSBram Moolenaar 3920fd9289dSBram Moolenaar " echom 'final - indent ' . ind 393a7241f5fSBram Moolenaar return s:ModuloIndent(ind) 3940fd9289dSBram Moolenaarendfunction 3950fd9289dSBram Moolenaar 39634feacbcSBram Moolenaar" Restore: 3978e52a593SBram Moolenaarlet &cpo= s:keepcpo 3988e52a593SBram Moolenaarunlet s:keepcpo 39934feacbcSBram Moolenaar" vim: ts=4 fdm=marker sw=4 400