![Frank LENORMAND](/assets/img/avatar_default.png)
This commit makes `:modeline-parse` grab all lines that look like modelines, and lets the parser deal with invalid formats. This allows actually printing an error on unsupported modelines formats, instead of ignoring them upfront.
116 lines
4.9 KiB
Plaintext
116 lines
4.9 KiB
Plaintext
##
|
|
## 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
|
|
|
|
declare-option -docstring "amount of lines that will be checked at the beginning and the end of the buffer" \
|
|
int modelines 5
|
|
|
|
define-command -hidden modeline-parse-impl %{
|
|
evaluate-commands %sh{
|
|
kakquote() { printf "%s" "$*" | sed "s/'/''/g; 1s/^/'/; \$s/\$/'/"; }
|
|
|
|
# Translate a vim option into the corresponding kakoune one
|
|
translate_opt_vim() {
|
|
readonly key="$1"
|
|
readonly value="$2"
|
|
tr=""
|
|
|
|
case "${key}" in
|
|
so|scrolloff) tr=$(kakquote scrolloff "${value},${kak_opt_scrolloff##*,}");;
|
|
siso|sidescrolloff) tr=$(kakquote scrolloff "${kak_opt_scrolloff%%,*},${value}");;
|
|
ts|tabstop) tr=$(kakquote tabstop "${value}");;
|
|
sw|shiftwidth) tr=$(kakquote indentwidth "${value}");;
|
|
tw|textwidth) tr=$(kakquote autowrap_column "${value}");;
|
|
ff|fileformat)
|
|
case "${value}" in
|
|
unix) tr="eolformat lf";;
|
|
dos) tr="eolformat crlf";;
|
|
*) printf 'echo -debug %s' "$(kakquote "Unsupported file format: ${value}")" \
|
|
| kak -p "${kak_session}";;
|
|
esac
|
|
;;
|
|
ft|filetype) tr=$(kakquote filetype "{value}");;
|
|
bomb) tr="BOM utf8";;
|
|
nobomb) tr="BOM none";;
|
|
spelllang|spl) tr=$(kakquote spell_lang "{value%%,*}");;
|
|
*) printf 'echo -debug %s' "$(kakquote "Unsupported vim variable: ${key}")" \
|
|
| kak -p "${kak_session}";;
|
|
esac
|
|
|
|
if [ -n "${tr}" ]; then
|
|
printf 'set-option buffer %s\n' "${tr}"
|
|
fi
|
|
}
|
|
|
|
# Pass a few whitelisted options to kakoune directly
|
|
translate_opt_kakoune() {
|
|
readonly key="$1"
|
|
readonly value="$2"
|
|
|
|
case "${key}" in
|
|
scrolloff|tabstop|indentwidth|autowrap_column|eolformat|filetype|BOM|spell_lang);;
|
|
*) printf 'echo -debug %s' "$(kakquote "Unsupported kakoune variable: ${key}")" \
|
|
| kak -p "${kak_session}"
|
|
return;;
|
|
esac
|
|
|
|
printf 'set-option buffer %s' "$(kakquote "${key}" "${value}")"
|
|
}
|
|
|
|
case "${kak_selection}" in
|
|
*vi:*|*vim:*) type_selection="vim";;
|
|
*kak:*|*kakoune:*) type_selection="kakoune";;
|
|
*) printf 'echo -debug %s' "$(kakquote "Unsupported modeline format: ${kak_selection}")" \
|
|
| kak -p "${kak_session}"; exit 1 ;;
|
|
esac
|
|
|
|
# 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
|
|
printf %s "${kak_selection}" | sed \
|
|
-e 's/^[^:]\{1,\}://' \
|
|
-e 's/[ \t]*set\{0,1\}[ \t]//' \
|
|
-e 's/:[^a-zA-Z0-9_=-]*$//' \
|
|
-e 's/:/ /g' \
|
|
| tr ' ' '\n' \
|
|
| while read -r option; do
|
|
name_option="${option%%=*}"
|
|
value_option="${option#*=}"
|
|
|
|
if [ -z "${option}" ]; then
|
|
continue
|
|
fi
|
|
|
|
case "${type_selection}" in
|
|
vim) tr=$(translate_opt_vim "${name_option}" "${value_option}");;
|
|
kakoune) tr=$(translate_opt_kakoune "${name_option}" "${value_option}");;
|
|
*) tr="";;
|
|
esac
|
|
|
|
if [ -n "${tr}" ]; then
|
|
printf %s\\n "${tr}"
|
|
fi
|
|
done
|
|
}
|
|
}
|
|
|
|
# Add the following function to a hook on BufOpenFile to automatically parse modelines
|
|
# Select the first and last `modelines` lines in the buffer, only keep modelines
|
|
# ref. options.txt (in vim `:help options`) : 2 forms of modelines:
|
|
# [text]{white}{vi:|vim:|ex:}[white]{options}
|
|
# [text]{white}{vi:|vim:|Vim:|ex:}[white]se[t] {options}:[text]
|
|
define-command modeline-parse -docstring "Read and interpret vi-format modelines at the beginning/end of the buffer" %{
|
|
try %{ evaluate-commands -draft %{
|
|
execute-keys <percent> "s(?S)\A(.+\n){,%opt{modelines}}|(.+\n){,%opt{modelines}}\z<ret>" \
|
|
s^\S*?\s+?\w+:\s?[^\n]+<ret> <a-x>
|
|
evaluate-commands -draft -itersel modeline-parse-impl
|
|
} }
|
|
}
|