diff --git a/rc/filetype/R.kak b/rc/filetype/R.kak new file mode 100644 index 00000000..5f7100eb --- /dev/null +++ b/rc/filetype/R.kak @@ -0,0 +1,143 @@ +# http://kakoune.org +# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ + +# Detection +# ‾‾‾‾‾‾‾‾‾ + +hook global BufCreate (.*/)?(\.Rprofile|.*\.[rR]) %{ + set-option buffer filetype R +} + +# Highlighters & Completion +# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ + +add-highlighter shared/R regions +add-highlighter shared/R/code default-region group +add-highlighter shared/R/double_string region '"' (?])>|<=|>=|==|!=|!|&{1,2}|\|{1,2}|~|\?) 0:operator + + +# Commands +# ‾‾‾‾‾‾‾‾ + +define-command -hidden R-trim-indent %{ + # remove the line if it's empty when leaving the insert mode + try %{ execute-keys -draft 1s^(\h+)$ d } +} + +define-command -hidden R-indent-on-newline %< evaluate-commands -draft -itersel %< + execute-keys \; + try %< + # if previous line closed a paren (possibly followed by words and a comment), + # copy indent of the opening paren line + execute-keys -draft k 1s(\))(\h+\w+)*\h*(\;\h*)?(?:#[^\n]+)?\n\z 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 statement not followed by an opening brace + try %< execute-keys -draft k s\)\h*(?:#[^\n]+)?\n\z \ + mB \A\b(if|for|while)\b j > + try %< execute-keys -draft k s \belse\b\h*(?:#[^\n]+)?\n\z \ + j > + # deindent after a single line statement end + try %< execute-keys -draft K \;\h*(#[^\n]+)?$ \ + K s\)(\h+\w+)*\h*(#[^\n]+)?\n([^\n]*\n){2}\z \ + MB \A\b(if|for|while)\b 1 > + try %< execute-keys -draft K \;\h*(#[^\n]+)?$ \ + K s \belse\b\h*(?:#[^\n]+)?\n([^\n]*\n){2}\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 "(([^"]*"){2})* '(([^']*'){2})* L + # Remove possibly incorrect indent from new line which was copied from previous line + try %< execute-keys -draft s\h+ d > + # Now indent and align that new line with the opening parenthesis/brace + execute-keys 1 & + > > +> > + +define-command -hidden R-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 R-indent-on-closing-curly-brace %[ + # align to opening curly brace when alone on a line + try %[ + # in case open curly brace follows a closing paren, align indent with opening paren + execute-keys -itersel -draft ^\h+\}$hm )M \A\(.*\)\h\{.*\}\z 1 + ] catch %[ + # otherwise align with open curly brace + execute-keys -itersel -draft ^\h+\}$hm1 + ] catch %[] +] + +define-command -hidden R-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 + ] + ] + ] +] ] + +# Initialization +# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ + +hook -group R-highlight global WinSetOption filetype=R %{ + add-highlighter window/R ref R + hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/R } +} + +hook global WinSetOption filetype=R %~ + hook window ModeChange insert:.* R-trim-indent + hook window InsertChar \n R-insert-on-newline + hook window InsertChar \n R-indent-on-newline + hook window InsertChar \{ R-indent-on-opening-curly-brace + hook window InsertChar \} R-indent-on-closing-curly-brace + + hook -once -always window WinSetOption filetype=.* %{ remove-hooks window R-.+ } +~