view runtime/indent/xml.vim @ 33566:e1e3805fcd96 v9.0.2028

patch 9.0.2028: confusing build dependencies Commit: https://github.com/vim/vim/commit/5d03525cdef5db1b1cedfa26c6f8a21aaa207ec0 Author: Yee Cheng Chin <ychin.git@gmail.com> Date: Sun Oct 15 09:50:53 2023 +0200 patch 9.0.2028: confusing build dependencies Problem: confusing build dependencies Solution: clean them up, make them parallelizable Separate vim binary and unittest dependencies, make them parallelizable Clean up make dependencies so Vim and unit test binaries only depend on the object files they need. This fixes an existing issue where after running unit tests, the Vim binary would be invalidated, which results in it having to be linked again when running script tests, even though Vim was already previously built. Make link.sh (script we use to link those binaries) generate namespaced temporary files for each app to avoid them colliding with each other. This allows `unittesttargets` to be built in parallel. These fixes are useful when using link-time-optimization as the link phase could now take minutes rather than a few seconds. closes: #13344 Signed-off-by: Christian Brabandt <cb@256bit.org> Co-authored-by: Yee Cheng Chin <ychin.git@gmail.com>
author Christian Brabandt <cb@256bit.org>
date Sun, 15 Oct 2023 10:00:03 +0200
parents f0d7cb510ce3
children
line wrap: on
line source

" Language: XML
" Maintainer: Christian Brabandt <cb@256bit.org>
" Repository: https://github.com/chrisbra/vim-xml-ftplugin
" Previous Maintainer: Johannes Zellner <johannes@zellner.org>
" Last Changed: 2020 Nov 4th
" Last Change:
" 20200529 - Handle empty closing tags correctly
" 20191202 - Handle docbk filetype
" 20190726 - Correctly handle non-tagged data
" 20190204 - correctly handle wrap tags
"            https://github.com/chrisbra/vim-xml-ftplugin/issues/5
" 20190128 - Make sure to find previous tag
"            https://github.com/chrisbra/vim-xml-ftplugin/issues/4
" 20181116 - Fix indentation when tags start with a colon or an underscore
"            https://github.com/vim/vim/pull/926
" 20181022 - Do not overwrite indentkeys setting
"            https://github.com/chrisbra/vim-xml-ftplugin/issues/1
" 20180724 - Correctly indent xml comments https://github.com/vim/vim/issues/3200
"
" Notes:
"   1) does not indent pure non-xml code (e.g. embedded scripts)
"       2) will be confused by unbalanced tags in comments
"       or CDATA sections.
"       2009-05-26 patch by Nikolai Weibull
" TODO:     implement pre-like tags, see xml_indent_open / xml_indent_close

" Only load this indent file when no other was loaded.
if exists("b:did_indent")
    finish
endif
let b:did_indent = 1
let s:keepcpo= &cpo
set cpo&vim

" [-- local settings (must come before aborting the script) --]
" Attention: Parameter use_syntax_check is used by the docbk.vim indent script
setlocal indentexpr=XmlIndentGet(v:lnum,1)
setlocal indentkeys=o,O,*<Return>,<>>,<<>,/,{,},!^F
" autoindent: used when the indentexpr returns -1
setlocal autoindent

let b:undo_indent = "setl ai< inde< indk<"

if !exists('b:xml_indent_open')
    let b:xml_indent_open = '.\{-}<[:A-Z_a-z]'
    " pre tag, e.g. <address>
    " let b:xml_indent_open = '.\{-}<[/]\@!\(address\)\@!'
endif

if !exists('b:xml_indent_close')
    let b:xml_indent_close = '.\{-}</\|/>.\{-}'
    " end pre tag, e.g. </address>
    " let b:xml_indent_close = '.\{-}</\(address\)\@!'
endif

if !exists('b:xml_indent_continuation_filetype')
    let b:xml_indent_continuation_filetype = 'xml'
endif

let &cpo = s:keepcpo
unlet s:keepcpo

" [-- finish, if the function already exists --]
if exists('*XmlIndentGet')
    finish
endif

let s:keepcpo= &cpo
set cpo&vim

fun! <SID>XmlIndentWithPattern(line, pat)
    let s = substitute('x'.a:line, a:pat, "\1", 'g')
    return strlen(substitute(s, "[^\1].*$", '', ''))
endfun

" [-- check if it's xml --]
fun! <SID>XmlIndentSynCheck(lnum)
    if &syntax != ''
        let syn1 = synIDattr(synID(a:lnum, 1, 1), 'name')
        let syn2 = synIDattr(synID(a:lnum, strlen(getline(a:lnum)) - 1, 1), 'name')
        if syn1 != '' && syn1 !~ 'xml' && syn2 != '' && syn2 !~ 'xml'
            " don't indent pure non-xml code
            return 0
        endif
    endif
    return 1
endfun

" [-- return the sum of indents of a:lnum --]
fun! <SID>XmlIndentSum(line, style, add)
    if <SID>IsXMLContinuation(a:line) && a:style == 0 && !<SID>IsXMLEmptyClosingTag(a:line)
        " no complete tag, add one additional indent level
        " but only for the current line
        return a:add + shiftwidth()
    elseif <SID>HasNoTagEnd(a:line)
        " no complete tag, return initial indent
        return a:add
    endif
    if a:style == match(a:line, '^\s*</')
        return (shiftwidth() *
        \  (<SID>XmlIndentWithPattern(a:line, b:xml_indent_open)
        \ - <SID>XmlIndentWithPattern(a:line, b:xml_indent_close)
        \ - <SID>XmlIndentWithPattern(a:line, '.\{-}/>'))) + a:add
    else
        return a:add
    endif
endfun

" Main indent function
fun! XmlIndentGet(lnum, use_syntax_check)
    " Find a non-empty line above the current line.
    if prevnonblank(a:lnum - 1) == 0
        " Hit the start of the file, use zero indent.
        return 0
    endif
    " Find previous line with a tag (regardless whether open or closed,
    " but always restrict the match to a line before the current one
    " Note: xml declaration: <?xml version="1.0"?>
    "       won't be found, as it is not a legal tag name
    let ptag_pattern = '\%(.\{-}<[/:A-Z_a-z]\)'. '\%(\&\%<'. a:lnum .'l\)'
    let ptag = search(ptag_pattern, 'bnW')
    " no previous tag
    if ptag == 0
        return 0
    endif

    let pline = getline(ptag)
    let pind  = indent(ptag)

    let syn_name_start = '' " Syntax element at start of line (excluding whitespace)
    let syn_name_end = ''   " Syntax element at end of line
    let curline = getline(a:lnum)
    if a:use_syntax_check
        let check_lnum = <SID>XmlIndentSynCheck(ptag)
        let check_alnum = <SID>XmlIndentSynCheck(a:lnum)
        if check_lnum == 0 || check_alnum == 0
            return indent(a:lnum)
        endif
        let syn_name_end   = synIDattr(synID(a:lnum, strlen(curline) - 1, 1), 'name')
        let syn_name_start = synIDattr(synID(a:lnum, match(curline, '\S') + 1, 1), 'name')
        let prev_syn_name_end   = synIDattr(synID(ptag, strlen(pline) - 1, 1), 'name')
        " not needed (yet?)
        " let prev_syn_name_start = synIDattr(synID(ptag, match(pline, '\S') + 1, 1), 'name')
    endif

    if syn_name_end =~ 'Comment' && syn_name_start =~ 'Comment'
        return <SID>XmlIndentComment(a:lnum)
    elseif empty(syn_name_start) && empty(syn_name_end) && a:use_syntax_check
        " non-xml tag content: use indent from 'autoindent'
        if pline =~ b:xml_indent_close
            return pind
        elseif !empty(prev_syn_name_end)
            " only indent by an extra shiftwidth, if the previous line ends
            " with an XML like tag
           return pind + shiftwidth()
        else
            " no extra indent, looks like a text continuation line
           return pind
        endif
    endif

    " Get indent from previous tag line
    let ind = <SID>XmlIndentSum(pline, -1, pind)
    " Determine indent from current line
    let ind = <SID>XmlIndentSum(curline, 0, ind)
    return ind
endfun

func! <SID>IsXMLContinuation(line)
    " Checks, whether or not the line matches a start-of-tag
    return a:line !~ '^\s*<' && &ft =~# b:xml_indent_continuation_filetype
endfunc

func! <SID>HasNoTagEnd(line)
    " Checks whether or not the line matches '>' (so finishes a tag)
    return a:line !~ '>\s*$'
endfunc

func! <SID>IsXMLEmptyClosingTag(line)
    " Checks whether the line ends with an empty closing tag such as <lb/>
    return a:line =~? '<[^>]*/>\s*$'
endfunc

" return indent for a commented line,
" the middle part might be indented one additional level
func! <SID>XmlIndentComment(lnum)
    let ptagopen = search('.\{-}<[:A-Z_a-z]\_[^/]\{-}>.\{-}', 'bnW')
    let ptagclose = search(b:xml_indent_close, 'bnW')
    if getline(a:lnum) =~ '<!--'
        " if previous tag was a closing tag, do not add
        " one additional level of indent
        if ptagclose > ptagopen && a:lnum > ptagclose
            " If the previous tag was closed on the same line as it was
            " declared, we should indent with its indent level.
            if !<SID>IsXMLContinuation(getline(ptagclose))
                return indent(ptagclose)
            else
                return indent(ptagclose) - shiftwidth()
            endif
        elseif ptagclose == ptagopen
            return indent(ptagclose)
        else
            " start of comment, add one indentation level
            return indent(ptagopen) + shiftwidth()
        endif
    elseif getline(a:lnum) =~ '-->'
        " end of comment, same as start of comment
        return indent(search('<!--', 'bnW'))
    else
        " middle part of comment, add one additional level
        return indent(search('<!--', 'bnW')) + shiftwidth()
    endif
endfunc

let &cpo = s:keepcpo
unlet s:keepcpo

" vim:ts=4 et sts=-1 sw=0