Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
sqlanywhere.vim400 linesDownload Raw Back to indent
1" Vim indent file2" Language:    SQL3" Maintainer:  David Fishburn <dfishburn dot vim at gmail dot com>4" Last Change: 2021 Oct 115" Version:     4.06" Download:    http://vim.sourceforge.net/script.php?script_id=4957 8" Notes:9"    Indenting keywords are based on Oracle and Sybase Adaptive Server10"    Anywhere (ASA).  Test indenting was done with ASA stored procedures and11"    functions and Oracle packages which contain stored procedures and12"    functions.13"    This has not been tested against Microsoft SQL Server or14"    Sybase Adaptive Server Enterprise (ASE) which use the Transact-SQL15"    syntax.  That syntax does not have end tags for IF's, which makes16"    indenting more difficult.17"18" Known Issues:19"    The Oracle MERGE statement does not have an end tag associated with20"    it, this can leave the indent hanging to the right one too many.21"22" History:23"    4.0 (Oct 2021)24"        Added b:undo_indent25"26"    3.0 (Dec 2012)27"        Added cpo check28"29"    2.030"        Added the FOR keyword to SQLBlockStart to handle (Alec Tica):31"            for i in 1..100 loop32"              |<-- I expect to have indentation here33"            end loop;34"35 36" Only load this indent file when no other was loaded.37if exists("b:did_indent")38    finish39endif40let b:did_indent     = 141let b:current_indent = "sqlanywhere"42 43setlocal indentkeys-=0{44setlocal indentkeys-=0}45setlocal indentkeys-=:46setlocal indentkeys-=0#47setlocal indentkeys-=e48 49" This indicates formatting should take place when one of these50" expressions is used.  These expressions would normally be something51" you would type at the BEGINNING of a line52" SQL is generally case insensitive, so this files assumes that53" These keywords are something that would trigger an indent LEFT, not54" an indent right, since the SQLBlockStart is used for those keywords55setlocal indentkeys+==~end,=~else,=~elseif,=~elsif,0=~when,0=)56 57" GetSQLIndent is executed whenever one of the expressions58" in the indentkeys is typed59setlocal indentexpr=GetSQLIndent()60 61let b:undo_indent = "setl indentexpr< indentkeys<"62 63" Only define the functions once.64if exists("*GetSQLIndent")65    finish66endif67 68let s:keepcpo= &cpo69set cpo&vim70 71" List of all the statements that start a new block.72" These are typically words that start a line.73" IS is excluded, since it is difficult to determine when the74" ending block is (especially for procedures/functions).75let s:SQLBlockStart = '^\s*\%('.76                \ 'if\|else\|elseif\|elsif\|'.77                \ 'while\|loop\|do\|for\|'.78                \ 'begin\|'.79                \ 'case\|when\|merge\|exception'.80                \ '\)\>'81let s:SQLBlockEnd = '^\s*\(end\)\>'82 83" The indent level is also based on unmatched parentheses84" If a line has an extra "(" increase the indent85" If a line has an extra ")" decrease the indent86function! s:CountUnbalancedParen( line, paren_to_check )87    let l = a:line88    let lp = substitute(l, '[^(]', '', 'g')89    let l = a:line90    let rp = substitute(l, '[^)]', '', 'g')91 92    if a:paren_to_check =~ ')'93        " echom 'CountUnbalancedParen ) returning: ' .94        " \ (strlen(rp) - strlen(lp))95        return (strlen(rp) - strlen(lp))96    elseif a:paren_to_check =~ '('97        " echom 'CountUnbalancedParen ( returning: ' .98        " \ (strlen(lp) - strlen(rp))99        return (strlen(lp) - strlen(rp))100    else101        " echom 'CountUnbalancedParen unknown paren to check: ' .102        " \ a:paren_to_check103        return 0104    endif105endfunction106 107" Unindent commands based on previous indent level108function! s:CheckToIgnoreRightParen( prev_lnum, num_levels )109    let lnum = a:prev_lnum110    let line = getline(lnum)111    let ends = 0112    let num_right_paren = a:num_levels113    let ignore_paren = 0114    let vircol = 1115 116    while num_right_paren > 0117        silent! exec 'norm! '.lnum."G\<bar>".vircol."\<bar>"118        let right_paren = search( ')', 'W' )119        if right_paren != lnum120            " This should not happen since there should be at least121            " num_right_paren matches for this line122            break123        endif124        let vircol      = virtcol(".")125 126        " if getline(".") =~ '^)'127        let matching_paren = searchpair('(', '', ')', 'bW',128                    \ 's:IsColComment(line("."), col("."))')129 130        if matching_paren < 1131            " No match found132            " echom 'CTIRP - no match found, ignoring'133            break134        endif135 136        if matching_paren == lnum137            " This was not an unmatched parentheses, start the search again138            " again after this column139            " echom 'CTIRP - same line match, ignoring'140            continue141        endif142 143        " echom 'CTIRP - match: ' . line(".") . '  ' . getline(".")144 145        if getline(matching_paren) =~? '\(if\|while\)\>'146            " echom 'CTIRP - if/while ignored: ' . line(".") . '  ' . getline(".")147            let ignore_paren = ignore_paren + 1148        endif149 150        " One match found, decrease and check for further matches151        let num_right_paren = num_right_paren - 1152 153    endwhile154 155    " Fallback - just move back one156    " return a:prev_indent - shiftwidth()157    return ignore_paren158endfunction159 160" Based on the keyword provided, loop through previous non empty161" non comment lines to find the statement that initiated the keyword.162" Return its indent level163"    CASE ..164"    WHEN ...165" Should return indent level of CASE166"    EXCEPTION ..167"    WHEN ...168"         something;169"    WHEN ...170" Should return indent level of exception.171function! s:GetStmtStarterIndent( keyword, curr_lnum )172    let lnum  = a:curr_lnum173 174    " Default - reduce indent by 1175    let ind = indent(a:curr_lnum) - shiftwidth()176 177    if a:keyword =~? 'end'178        exec 'normal! ^'179        let stmts = '^\s*\%('.180                    \ '\<begin\>\|' .181                    \ '\%(\%(\<end\s\+\)\@<!\<loop\>\)\|' .182                    \ '\%(\%(\<end\s\+\)\@<!\<case\>\)\|' .183                    \ '\%(\%(\<end\s\+\)\@<!\<for\>\)\|' .184                    \ '\%(\%(\<end\s\+\)\@<!\<if\>\)'.185                    \ '\)'186        let matching_lnum = searchpair(stmts, '', '\<end\>\zs', 'bW',187                    \ 's:IsColComment(line("."), col(".")) == 1')188        exec 'normal! $'189        if matching_lnum > 0 && matching_lnum < a:curr_lnum190            let ind = indent(matching_lnum)191        endif192    elseif a:keyword =~? 'when'193        exec 'normal! ^'194        let matching_lnum = searchpair(195                    \ '\%(\<end\s\+\)\@<!\<case\>\|\<exception\>\|\<merge\>',196                    \ '',197                    \ '\%(\%(\<when\s\+others\>\)\|\%(\<end\s\+case\>\)\)',198                    \ 'bW',199                    \ 's:IsColComment(line("."), col(".")) == 1')200        exec 'normal! $'201        if matching_lnum > 0 && matching_lnum < a:curr_lnum202            let ind = indent(matching_lnum)203        else204            let ind = indent(a:curr_lnum)205        endif206    endif207 208    return ind209endfunction210 211 212" Check if the line is a comment213function! s:IsLineComment(lnum)214    let rc = synIDattr(215                \ synID(a:lnum,216                \     match(getline(a:lnum), '\S')+1, 0)217                \ , "name")218                \ =~? "comment"219 220    return rc221endfunction222 223 224" Check if the column is a comment225function! s:IsColComment(lnum, cnum)226    let rc = synIDattr(synID(a:lnum, a:cnum, 0), "name")227                \           =~? "comment"228 229    return rc230endfunction231 232 233" Instead of returning a column position, return234" an appropriate value as a factor of shiftwidth.235function! s:ModuloIndent(ind)236    let ind = a:ind237 238    if ind > 0239        let modulo = ind % shiftwidth()240 241        if modulo > 0242            let ind = ind - modulo243        endif244    endif245 246    return ind247endfunction248 249 250" Find correct indent of a new line based upon the previous line251function! GetSQLIndent()252    let lnum = v:lnum253    let ind = indent(lnum)254 255    " If the current line is a comment, leave the indent as is256    " Comment out this additional check since it affects the257    " indenting of =, and will not reindent comments as it should258    " if s:IsLineComment(lnum) == 1259    "     return ind260    " endif261 262    " Get previous non-blank line263    let prevlnum = prevnonblank(lnum - 1)264    if prevlnum <= 0265        return ind266    endif267 268    if s:IsLineComment(prevlnum) == 1269        if getline(v:lnum) =~ '^\s*\*'270            let ind = s:ModuloIndent(indent(prevlnum))271            return ind + 1272        endif273        " If the previous line is a comment, then return -1274        " to tell Vim to use the formatoptions setting to determine275        " the indent to use276        " But only if the next line is blank.  This would be true if277        " the user is typing, but it would not be true if the user278        " is reindenting the file279        if getline(v:lnum) =~ '^\s*$'280            return -1281        endif282    endif283 284    " echom 'PREVIOUS INDENT: ' . indent(prevlnum) . '  LINE: ' . getline(prevlnum)285 286    " This is the line you just hit return on, it is not the current line287    " which is new and empty288    " Based on this line, we can determine how much to indent the new289    " line290 291    " Get default indent (from prev. line)292    let ind      = indent(prevlnum)293    let prevline = getline(prevlnum)294 295    " Now check what's on the previous line to determine if the indent296    " should be changed, for example IF, BEGIN, should increase the indent297    " where END IF, END, should decrease the indent.298    if prevline =~? s:SQLBlockStart299        " Move indent in300        let ind = ind + shiftwidth()301        " echom 'prevl - SQLBlockStart - indent ' . ind . '  line: ' . prevline302    elseif prevline =~ '[()]'303        if prevline =~ '('304            let num_unmatched_left = s:CountUnbalancedParen( prevline, '(' )305        else306            let num_unmatched_left = 0307        endif308        if prevline =~ ')'309            let num_unmatched_right  = s:CountUnbalancedParen( prevline, ')' )310        else311            let num_unmatched_right  = 0312            " let num_unmatched_right  = s:CountUnbalancedParen( prevline, ')' )313        endif314        if num_unmatched_left > 0315            " There is a open left parenthesis316            " increase indent317            let ind = ind + ( shiftwidth() * num_unmatched_left )318        elseif num_unmatched_right > 0319            " if it is an unbalanced parenthesis only unindent if320            " it was part of a command (ie create table(..)  )321            " instead of part of an if (ie if (....) then) which should322            " maintain the indent level323            let ignore = s:CheckToIgnoreRightParen( prevlnum, num_unmatched_right )324            " echom 'prevl - ) unbalanced - CTIRP - ignore: ' . ignore325 326            if prevline =~ '^\s*)'327                let ignore = ignore + 1328                " echom 'prevl - begins ) unbalanced ignore: ' . ignore329            endif330 331            if (num_unmatched_right - ignore) > 0332                let ind = ind - ( shiftwidth() * (num_unmatched_right - ignore) )333            endif334 335        endif336    endif337 338 339    " echom 'CURRENT INDENT: ' . ind . '  LINE: '  . getline(v:lnum)340 341    " This is a new blank line since we just typed a carriage return342    " Check current line; search for simplistic matching start-of-block343    let line = getline(v:lnum)344 345    if line =~? '^\s*els'346        " Any line when you type else will automatically back up one347        " ident level  (ie else, elseif, elsif)348        let ind = ind - shiftwidth()349        " echom 'curr - else - indent ' . ind350    elseif line =~? '^\s*end\>'351        let ind = s:GetStmtStarterIndent('end', v:lnum)352        " General case for end353        " let ind = ind - shiftwidth()354        " echom 'curr - end - indent ' . ind355    elseif line =~? '^\s*when\>'356        let ind = s:GetStmtStarterIndent('when', v:lnum)357        " If the WHEN clause is used with a MERGE or EXCEPTION358        " clause, do not change the indent level, since these359        " statements do not have a corresponding END statement.360        " if stmt_starter =~? 'case'361        "    let ind = ind - shiftwidth()362        " endif363        " elseif line =~ '^\s*)\s*;\?\s*$'364        " elseif line =~ '^\s*)'365    elseif line =~ '^\s*)'366        let num_unmatched_right  = s:CountUnbalancedParen( line, ')' )367        let ignore = s:CheckToIgnoreRightParen( v:lnum, num_unmatched_right )368        " If the line ends in a ), then reduce the indent369        " This catches items like:370        " CREATE TABLE T1(371        "    c1 int,372        "    c2 int373        "    );374        " But we do not want to unindent a line like:375        " IF ( c1 = 1376        " AND  c2 = 3 ) THEN377        " let num_unmatched_right  = s:CountUnbalancedParen( line, ')' )378        " if num_unmatched_right > 0379        " elseif strpart( line, strlen(line)-1, 1 ) =~ ')'380        " let ind = ind - shiftwidth()381        if line =~ '^\s*)'382            " let ignore = ignore + 1383            " echom 'curr - begins ) unbalanced ignore: ' . ignore384        endif385 386        if (num_unmatched_right - ignore) > 0387            let ind = ind - ( shiftwidth() * (num_unmatched_right - ignore) )388        endif389        " endif390    endif391 392    " echom 'final - indent ' . ind393    return s:ModuloIndent(ind)394endfunction395 396"  Restore:397let &cpo= s:keepcpo398unlet s:keepcpo399" vim: ts=4 fdm=marker sw=4400 
codekingpro/portable-devtools · Team Ai