neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

bitbake.vim (3097B)


      1 " Support for bitbake indenting, see runtime/indent/bitbake.vim
      2 
      3 function s:is_bb_python_func_def(lnum)
      4    let stack = synstack(a:lnum, 1)
      5    if len(stack) == 0
      6        return 0
      7    endif
      8 
      9    return synIDattr(stack[0], "name") == "bbPyFuncDef"
     10 endfunction
     11 
     12 function bitbake#Indent(lnum)
     13    if !has('syntax_items')
     14        return -1
     15    endif
     16 
     17    let stack = synstack(a:lnum, 1)
     18    if len(stack) == 0
     19        return -1
     20    endif
     21 
     22    let name = synIDattr(stack[0], "name")
     23 
     24    " TODO: support different styles of indentation for assignments. For now,
     25    " we only support like this:
     26    " VAR = " \
     27    "     value1 \
     28    "     value2 \
     29    " "
     30    "
     31    " i.e. each value indented by shiftwidth(), with the final quote " completely unindented.
     32    if name == "bbVarValue"
     33        " Quote handling is tricky. kernel.bbclass has this line for instance:
     34        "     EXTRA_OEMAKE = " HOSTCC="${BUILD_CC} ${BUILD_CFLAGS} ${BUILD_LDFLAGS}" " HOSTCPP="${BUILD_CPP}""
     35        " Instead of trying to handle crazy cases like that, just assume that a
     36        " double-quote on a line by itself (following an assignment) means the
     37        " user is closing the assignment, and de-dent.
     38        if getline(a:lnum) =~ '^\s*"$'
     39            return 0
     40        endif
     41 
     42        let prevstack = synstack(a:lnum - 1, 1)
     43        if len(prevstack) == 0
     44            return -1
     45        endif
     46 
     47        let prevname = synIDattr(prevstack[0], "name")
     48 
     49        " Only indent if there was actually a continuation character on
     50        " the previous line, to avoid misleading indentation.
     51        let prevlinelastchar = synIDattr(synID(a:lnum - 1, col([a:lnum - 1, "$"]) - 1, 1), "name")
     52        let prev_continued = prevlinelastchar == "bbContinue"
     53 
     54        " Did the previous line introduce an assignment?
     55        if index(["bbVarDef", "bbVarFlagDef"], prevname) != -1
     56            if prev_continued
     57                return shiftwidth()
     58            endif
     59        endif
     60 
     61        if !prev_continued
     62            return 0
     63        endif
     64 
     65        " Autoindent can take it from here
     66        return -1
     67    endif
     68 
     69    if index(["bbPyDefRegion", "bbPyFuncRegion"], name) != -1
     70        let ret = python#GetIndent(a:lnum, function('s:is_bb_python_func_def'))
     71        " Should normally always be indented by at least one shiftwidth; but allow
     72        " return of -1 (defer to autoindent) or -2 (force indent to 0)
     73        if ret == 0
     74            return shiftwidth()
     75        elseif ret == -2
     76            return 0
     77        endif
     78        return ret
     79    endif
     80 
     81    " TODO: GetShIndent doesn't detect tasks prepended with 'fakeroot'
     82    " Need to submit a patch upstream to Vim to provide an extension point.
     83    " Unlike the Python indenter, the Sh indenter is way too large to copy and
     84    " modify here.
     85    if name == "bbShFuncRegion"
     86        return GetShIndent()
     87    endif
     88 
     89    " TODO:
     90    "   + heuristics for de-denting out of a bbPyDefRegion? e.g. when the user
     91    "       types an obvious BB keyword like addhandler or addtask, or starts
     92    "       writing a shell task. Maybe too hard to implement...
     93 
     94    return -1
     95 endfunction