Bram Moolenaar | b529cfb | 2022-07-25 15:42:07 +0100 | [diff] [blame] | 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 |