hook global BufCreate .*\.(cc|cpp|cxx|C|hh|hpp|hxx|H)$ %{ set-option buffer filetype cpp } hook global BufSetOption filetype=c\+\+ %{ hook -once buffer NormalIdle '' "set-option buffer filetype cpp" } hook global BufCreate .*\.c$ %{ set-option buffer filetype c } hook global BufCreate .*\.h$ %{ try %{ execute-keys -draft %{%s\b::\b|\btemplate\h*|\bclass\h+\w+|\b(typename|namespace)\b|\b(public|private|protected)\h*:} set-option buffer filetype cpp } catch %{ set-option buffer filetype c } } hook global BufCreate .*\.m %{ set-option buffer filetype objc } define-command -hidden c-family-trim-autoindent %{ # remove the line if it's empty when leaving the insert mode try %{ execute-keys -draft 1s^(\h+)$ d } } define-command -hidden c-family-indent-on-newline %< evaluate-commands -draft -itersel %< execute-keys \; try %< # if previous line is part of a comment, do nothing execute-keys -draft /\* ^\h*[^/*\h] > catch %< # else if previous line closed a paren, copy indent of the opening paren line execute-keys -draft k 1s(\))(\h+\w+)*\h*(\;\h*)?$ mJ 1 > catch %< # else indent new lines with the same level as the previous one execute-keys -draft K > # remove previous empty lines resulting from the automatic indent try %< execute-keys -draft k ^\h+$ Hd > # indent after an opening brace or parenthesis at end of line try %< execute-keys -draft k s[{(]\h*$ j > # indent after a label try %< execute-keys -draft k s[a-zA-Z0-9_-]+:\h*$ j > # indent after a statement not followed by an opening brace try %< execute-keys -draft k \b(if|else|for|while)\h*(\(.*?\)\h*)?$ j > # deindent after a single line statement end try %< execute-keys -draft K \;\h*$ K s\b(if|else|for|while)\h*(\(.*?\)\h*)?$|.\z 1 > # align to the opening parenthesis or opening brace (whichever is first) # on a previous line if its followed by text on the same line try %< evaluate-commands -draft %< # Go to opening parenthesis and opening brace, then select the most nested one try %< execute-keys [c [({],[)}] > # Validate selection and get first and last char execute-keys \A[{(](\h*\S+)+\n L # Remove eventual indent from new line try %< execute-keys -draft s\h+ d > # Now align that new line with the opening parenthesis/brace execute-keys & > > > > define-command -hidden c-family-indent-on-opening-curly-brace %[ # align indent with opening paren when { is entered on a new line after the closing paren try %[ execute-keys -draft -itersel h)M \A\(.*\)\h*\n\h*\{\z 1 ] ] define-command -hidden c-family-indent-on-closing-curly-brace %[ # align to opening curly brace when alone on a line try %[ execute-keys -itersel -draft ^\h+\}$hm1 ] ] define-command -hidden c-family-insert-on-closing-curly-brace %[ # add a semicolon after a closing brace if part of a class, union or struct definition try %[ execute-keys -itersel -draft hmB\A\h*(class|struct|union|enum) ';i;' ] ] define-command -hidden c-family-insert-on-newline %[ evaluate-commands -itersel -draft %[ execute-keys \; try %[ evaluate-commands -draft -save-regs '/"' %[ # copy the commenting prefix execute-keys -save-regs '' k 1s^\h*(//+\h*) y try %[ # if the previous comment isn't empty, create a new one execute-keys ^\h*//+\h*$ js^\h*P ] catch %[ # if there is no text in the previous comment, remove it completely execute-keys d ] ] ] try %[ # if the previous line isn't within a comment scope, break execute-keys -draft k ^(\h*/\*|\h+\*(?!/)) # find comment opening, validate it was not closed, and check its using star prefixes execute-keys -draft /\* \*/ \A\h*/\*([^\n]*\n\h*\*)*[^\n]*\n\h*.\z try %[ # if the previous line is opening the comment, insert star preceeded by space execute-keys -draft k^\h*/\* execute-keys -draft i* ] catch %[ try %[ # if the next line is a comment line insert a star execute-keys -draft j^\h+\* execute-keys -draft i* ] catch %[ try %[ # if the previous line is an empty comment line, close the comment scope execute-keys -draft k^\h+\*\h+$ 1s\*(\h*)c/ ] catch %[ # if the previous line is a non-empty comment line, add a star execute-keys -draft i* ] ] ] # trim trailing whitespace on the previous line try %[ execute-keys -draft s\h+$ d ] # align the new star with the previous one execute-keys K1s^[^*]*(\*)& ] ] ] # Regions definition are the same between c++ and objective-c evaluate-commands %sh{ for ft in c cpp objc; do if [ "${ft}" = "objc" ]; then maybe_at='@?' else maybe_at='' fi printf %s\\n ' add-highlighter shared/FT regions add-highlighter shared/FT/code default-region group add-highlighter shared/FT/string region %{MAYBEAT(?%ggxs\.c_A_INCLUDEDggxyppI#ifndefjI#definejI#endif//O' ;; pragma) echo 'execute-keys ggi#pragmaonce' ;; *);; esac } } hook -group c-family-insert global BufNewFile .*\.(h|hh|hpp|hxx|H) c-family-insert-include-guards declare-option -docstring "colon separated list of path in which header files will be looked for" \ str-list alt_dirs '.' '..' define-command c-family-alternative-file -docstring "Jump to the alternate file (header/implementation)" %{ evaluate-commands %sh{ file="${kak_buffile##*/}" file_noext="${file%.*}" dir=$(dirname "${kak_buffile}") # Set $@ to alt_dirs eval "set -- ${kak_opt_alt_dirs}" case ${file} in *.c|*.cc|*.cpp|*.cxx|*.C|*.inl|*.m) for alt_dir in "$@"; do for ext in h hh hpp hxx H; do altname="${dir}/${alt_dir}/${file_noext}.${ext}" if [ -f ${altname} ]; then printf 'edit %%{%s}\n' "${altname}" exit fi done done ;; *.h|*.hh|*.hpp|*.hxx|*.H) for alt_dir in "$@"; do for ext in c cc cpp cxx C m; do altname="${dir}/${alt_dir}/${file_noext}.${ext}" if [ -f ${altname} ]; then printf 'edit %%{%s}\n' "${altname}" exit fi done done ;; *) echo "echo -markup '{Error}extension not recognized'" exit ;; esac echo "echo -markup '{Error}alternative file not found'" }}