From 94674b63e0e0a5cbf071c2767dc7669ea482f70d Mon Sep 17 00:00:00 2001 From: Frank LENORMAND Date: Tue, 26 Jan 2016 09:55:23 +0200 Subject: [PATCH 1/2] Add a modeline support script (vim + kakoune options) --- rc/modeline.kak | 126 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 rc/modeline.kak diff --git a/rc/modeline.kak b/rc/modeline.kak new file mode 100644 index 00000000..baecea73 --- /dev/null +++ b/rc/modeline.kak @@ -0,0 +1,126 @@ +## +## modeline.kak by lenormf +## + +## Currently supported modeline format: vim +## Also supports kakoune options with a 'kak' or 'kakoune' prefix +## Only a few options are supported, in order to prevent the +## buffers from poking around the configuration too much + +# Set to 'true' to parse modelines in buffers +decl bool modeline "true" +# Amount of lines that will be checked at the beginning and the end of the buffer +decl int modelines 5 + +def -hidden _modeline-parse %{ + %sh{ + # Translate a vim option into the corresponding kakoune one + function translate_opt_vim { + readonly key="$1" + readonly value="$2" + local tr="" + + case "${key}" in + so) ;& + scrolloff) tr="scrolloff ${value},${kak_opt_scrolloff##*,}";; + siso) ;& + sidescrolloff) tr="scrolloff ${kak_opt_scrolloff%%,*},${value}";; + ts) ;& + tabstop) tr="tabstop ${value}";; + sw) ;& + shiftwidth) tr="indentwidth ${value}";; + tw) ;& + textwidth) tr="autowrap_column ${value}";; + ff) ;& + fileformat) + case "${value}" in + unix) tr="eolformat lf";; + dos) tr="eolformat crlf";; + *) echo "Unsupported file format: ${value}" >&2;; + esac + ;; + ft) ;& + filetype) tr="filetype ${value}";; + bomb) tr="BOM utf8";; + nobomb) tr="BOM none";; + *) echo "Unsupported vim variable: ${key}" >&2;; + esac + + [ -n "${tr}" ] && echo "set buffer ${tr}" + } + + # Pass a few whitelisted options to kakoune directly + function translate_opt_kakoune { + readonly key="$1" + readonly value="$2" + readonly OPTS_ALLOWED=( + scrolloff + tabstop + indentwidth + autowrap_column + eolformat + filetype + mimetype + BOM + ) + + grep -qw "${key}" <<< "${OPTS_ALLOWED[@]}" || { + echo "Unsupported kakoune variable: ${key}" >&2; + return; + } + + echo "set buffer ${key} ${value}" + } + + # The following subshell will keep the actual options of the modeline, and strip: + # - the text that leads the first option, according to the official vim modeline format + # - the trailing text after the last option, and an optional ':' sign before it + # It will also convert the ':' seperators beween the option=value pairs + # More info: http://vimdoc.sourceforge.net/htmldoc/options.html#modeline + options=( + $(sed -r -e 's/^(.+\s\w+:\s?(set?)?\s)//' \ + -e 's/:?\s[^a-zA-Z0-9_=-]+$//' \ + -e 's/:/ /g' <<< "${kak_selection}") + ) + + case "${kak_selection}" in + *vi:*) ;& + *vim:*) type_selection="vim";; + *kak:*) ;& + *kakoune:*) type_selection="kakoune";; + *) echo "echo -debug Unsupported modeline format";; + esac + [ -n "${type_selection}" ] || exit 1 + + for option in "${options[@]}"; do + name_option="${option%%=*}" + value_option="${option#*=}" + + case "${type_selection}" in + vim) tr=$(translate_opt_vim "${name_option}" "${value_option}");; + kakoune) tr=$(translate_opt_kakoune "${name_option}" "${value_option}");; + esac + + [ -n "${tr}" ] && echo "${tr}" + done + } +} + +# Select the first and last `modelines` lines in the buffer, only keep modelines +def -hidden _modeline-crunch %{ + try %{ + exec -draft "\% +s(\`(^[^\n]*\n?){%opt{modelines}})|((^[^\n]*\n?){%opt{modelines}}\') +s^[^\s]+?\s(vim?|kak(oune)?):\s?[^\n]+ + +:eval -draft -itersel _modeline-parse" + } +} + +hook global BufOpen .* %{ + %sh{ + if [ "${kak_opt_modeline}" = true ]; then + echo "eval _modeline-crunch" + fi + } +} From 507ed69dda9d8c2787488cfb1348a2ccb861bddc Mon Sep 17 00:00:00 2001 From: Frank LENORMAND Date: Mon, 8 Feb 2016 11:30:37 +0200 Subject: [PATCH 2/2] Get rid of the `modeline` option to let users set hooks manually --- rc/modeline.kak | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/rc/modeline.kak b/rc/modeline.kak index baecea73..cb93b337 100644 --- a/rc/modeline.kak +++ b/rc/modeline.kak @@ -7,8 +7,6 @@ ## Only a few options are supported, in order to prevent the ## buffers from poking around the configuration too much -# Set to 'true' to parse modelines in buffers -decl bool modeline "true" # Amount of lines that will be checked at the beginning and the end of the buffer decl int modelines 5 @@ -106,8 +104,9 @@ def -hidden _modeline-parse %{ } } +# Add the following function to a hook on BufOpen to automatically parse modelines # Select the first and last `modelines` lines in the buffer, only keep modelines -def -hidden _modeline-crunch %{ +def modeline-parse %{ try %{ exec -draft "\% s(\`(^[^\n]*\n?){%opt{modelines}})|((^[^\n]*\n?){%opt{modelines}}\') @@ -116,11 +115,3 @@ s^[^\s]+?\s(vim?|kak(oune)?):\s?[^\n]+ :eval -draft -itersel _modeline-parse" } } - -hook global BufOpen .* %{ - %sh{ - if [ "${kak_opt_modeline}" = true ]; then - echo "eval _modeline-crunch" - fi - } -}