From e83ad2a2a4c78e6c1b753664942f2ddf744a85f3 Mon Sep 17 00:00:00 2001 From: Frank LENORMAND Date: Mon, 9 Mar 2020 14:22:34 +0300 Subject: [PATCH] rc spell: Re-implement message processing in Awk Plain shell takes too long on large files. Fixes #3399 --- rc/tools/spell.kak | 69 ++++++++++++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 27 deletions(-) diff --git a/rc/tools/spell.kak b/rc/tools/spell.kak index 0eeaceb57..a39c22040 100644 --- a/rc/tools/spell.kak +++ b/rc/tools/spell.kak @@ -37,33 +37,48 @@ define-command -params ..1 -docstring %{ fi { - sed 's/^/^/' "$kak_opt_spell_tmp_file" | eval "aspell --byte-offsets -a $options" 2>&1 | { - line_num=1 - regions=$kak_timestamp - while read -r line; do - case "$line" in - @\(\#\)*) - # drop the identification message - ;; - [\#\&]*) - if expr "$line" : '^&' >/dev/null; then - pos=$(printf %s\\n "$line" | cut -d ' ' -f 4 | sed 's/:$//') - else - pos=$(printf %s\\n "$line" | cut -d ' ' -f 3) - fi - word=$(printf %s\\n "$line" | cut -d ' ' -f 2) - # trim whitespace to make `wc` output consistent across implementations - len=$(($(printf %s "$word" | wc -c))) - regions="$regions $line_num.$pos+${len}|Error" - ;; - '') line_num=$((line_num + 1));; - \*) ;; - *) printf 'fail %s\n' "${line}" | kak -p "${kak_session}";; - esac - done - printf 'set-option "buffer=%s" spell_regions %s' "${kak_bufname}" "${regions}" \ - | kak -p "${kak_session}" - } + sed 's/^/^/' "$kak_opt_spell_tmp_file" | eval "aspell --byte-offsets -a $options" 2>&1 | awk ' + BEGIN { + line_num = 1 + regions = ENVIRON["kak_timestamp"] + server_command = sprintf("kak -p \"%s\"", ENVIRON["kak_session"]) + } + + { + if (/^@\(#\)/) { + /* drop the identification message */ + } + + else if (/^\*/) { + /* nothing */ + } + + else if (/^$/) { + line_num++ + } + + else if (/^[#&]/) { + word_len = length($2) + word_pos = substr($0, 1, 1) == "&" ? substr($4, 1, length($4) - 1) : $3; + regions = regions " " line_num "." word_pos "+" word_len "|Error" + } + + else { + line = $0 + gsub(/"/, "&&", line) + command = "fail \"" line "\"" + exit + } + } + + END { + if (!length(command)) + command = "set-option \"buffer=" ENVIRON["kak_bufname"] "\" spell_regions " regions + + print command | server_command + close(server_command) + } + ' rm -rf $(dirname "$kak_opt_spell_tmp_file") } /dev/null 2>&1 & }