Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package kakoune for openSUSE:Factory checked in at 2021-12-05 22:45:49 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/kakoune (Old) and /work/SRC/openSUSE:Factory/.kakoune.new.31177 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "kakoune" Sun Dec 5 22:45:49 2021 rev:21 rq:935566 version:2021.11.08 Changes: -------- --- /work/SRC/openSUSE:Factory/kakoune/kakoune.changes 2021-11-03 17:27:18.809371600 +0100 +++ /work/SRC/openSUSE:Factory/.kakoune.new.31177/kakoune.changes 2021-12-05 22:46:13.957618395 +0100 @@ -1,0 +2,8 @@ +Fri Dec 3 18:25:50 UTC 2021 - Michael Vetter <mvet...@suse.com> + +- Update to 2021.11.08: + * Support for curly and separately colored underlines + * Fixes for terminal flickering + * Fixes for command and response fifo corner cases + +------------------------------------------------------------------- Old: ---- kakoune-2021.10.28.tar.bz2 New: ---- kakoune-2021.11.08.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ kakoune.spec ++++++ --- /var/tmp/diff_new_pack.o810dq/_old 2021-12-05 22:46:15.613612999 +0100 +++ /var/tmp/diff_new_pack.o810dq/_new 2021-12-05 22:46:15.613612999 +0100 @@ -17,7 +17,7 @@ Name: kakoune -Version: 2021.10.28 +Version: 2021.11.08 Release: 0 Summary: A code editor heavily inspired by Vim License: Unlicense ++++++ kakoune-2021.10.28.tar.bz2 -> kakoune-2021.11.08.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kakoune-2021.10.28/doc/pages/changelog.asciidoc new/kakoune-2021.11.08/doc/pages/changelog.asciidoc --- old/kakoune-2021.10.28/doc/pages/changelog.asciidoc 2021-10-28 00:13:34.000000000 +0200 +++ new/kakoune-2021.11.08/doc/pages/changelog.asciidoc 2021-11-07 06:51:39.000000000 +0100 @@ -3,6 +3,14 @@ This changelog contains major and/or breaking changes to Kakoune between released versions. +== Kakoune 2021.11.07 + +* Support for curly and separately colored underlines (undocumented in 2021.10.28) + +* Fixes for terminal flickering + +* Fixes for command and response fifo corner cases + == Kakoune 2021.10.28 * `g` and `v` do not auto lower case the next key, so `GL` needs to be diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kakoune-2021.10.28/doc/pages/highlighters.asciidoc new/kakoune-2021.11.08/doc/pages/highlighters.asciidoc --- old/kakoune-2021.10.28/doc/pages/highlighters.asciidoc 2021-10-28 00:13:34.000000000 +0200 +++ new/kakoune-2021.11.08/doc/pages/highlighters.asciidoc 2021-11-07 06:51:39.000000000 +0100 @@ -65,6 +65,10 @@ specify a string to separate the line numbers column from the rest of the buffer (default is '|') + *-cursor-separator* <separator text>::: + identical to *-separator* but applies only to the line of the cursor + (default is the same value passed to *-separator*) + *-min-digits* <num>::: always reserve room for at least *num* digits, so text doesn't jump around as lines are added or removed diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kakoune-2021.10.28/doc/pages/regex.asciidoc new/kakoune-2021.11.08/doc/pages/regex.asciidoc --- old/kakoune-2021.10.28/doc/pages/regex.asciidoc 2021-10-28 00:13:34.000000000 +0200 +++ new/kakoune-2021.11.08/doc/pages/regex.asciidoc 2021-11-07 06:51:39.000000000 +0100 @@ -2,7 +2,7 @@ == Regex syntax -Kakoune regex syntax is based on ECMAScript syntax, as defined by the +Kakoune's regex syntax is inspired by ECMAScript, as defined by the ECMA-262 standard (see <<regex#compatibility,:doc regex compatibility>>). Kakoune's regex always runs on Unicode codepoint sequences, not on bytes. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kakoune-2021.10.28/rc/tools/make.kak new/kakoune-2021.11.08/rc/tools/make.kak --- old/kakoune-2021.10.28/rc/tools/make.kak 2021-10-28 00:13:34.000000000 +0200 +++ new/kakoune-2021.11.08/rc/tools/make.kak 2021-11-07 06:51:39.000000000 +0100 @@ -14,7 +14,7 @@ } make %{ evaluate-commands %sh{ output=$(mktemp -d "${TMPDIR:-/tmp}"/kak-make.XXXXXXXX)/fifo mkfifo ${output} - ( eval ${kak_opt_makecmd} "$@" > ${output} 2>&1 & ) > /dev/null 2>&1 < /dev/null + ( eval "${kak_opt_makecmd}" "$@" > ${output} 2>&1 & ) > /dev/null 2>&1 < /dev/null printf %s\\n "evaluate-commands -try-client '$kak_opt_toolsclient' %{ edit! -fifo ${output} -scroll *make* diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kakoune-2021.10.28/rc/tools/man.kak new/kakoune-2021.11.08/rc/tools/man.kak --- old/kakoune-2021.10.28/rc/tools/man.kak 2021-10-28 00:13:34.000000000 +0200 +++ new/kakoune-2021.11.08/rc/tools/man.kak 2021-11-07 06:51:39.000000000 +0100 @@ -108,8 +108,12 @@ # Define a useful command sequence for searching a given regex # and a given sequence of search keys. define-command man-search -params 2 %{ - set-register / %arg[1] - execute-keys %arg[2] + set-register / %arg[1] + try %{ + execute-keys %arg[2] + } catch %{ + fail "Could not find man page link" + } } define-command -docstring 'Go to next man page link' \ @@ -135,13 +139,9 @@ } # Suggested keymaps for a user mode -declare-user-mode man-mode +declare-user-mode man -define-command man-mode-map -params 3 %{ - map global man-mode %arg[1] %arg[2] -docstring %arg[3] -} -hidden - -man-mode-map 'g' ': man-jump<ret>' 'Jump to a man page using selected man page link' -man-mode-map 'j' ': try %{ man-link-next }<ret>' 'Go to next man page link' -man-mode-map 'k' ': try %{ man-link-prev }<ret>' 'Go to previous man page link' -man-mode-map 'm' ': man<space>' 'Look up a man page' +map global man 'g' -docstring 'Jump to a man page using selected man page link' ': man-jump<ret>' +map global man 'j' -docstring 'Go to next man page link' ': man-link-next<ret>' +map global man 'k' -docstring 'Go to previous man page link' ': man-link-prev<ret>' +map global man 'm' -docstring 'Look up a man page' ':man<space>' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kakoune-2021.10.28/src/.version new/kakoune-2021.11.08/src/.version --- old/kakoune-2021.10.28/src/.version 2021-10-28 00:14:38.000000000 +0200 +++ new/kakoune-2021.11.08/src/.version 2021-11-07 06:52:16.000000000 +0100 @@ -1 +1 @@ -v2021.10.28 +v2021.11.08 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kakoune-2021.10.28/src/commands.cc new/kakoune-2021.11.08/src/commands.cc --- old/kakoune-2021.10.28/src/commands.cc 2021-10-28 00:13:34.000000000 +0200 +++ new/kakoune-2021.11.08/src/commands.cc 2021-11-07 06:51:39.000000000 +0100 @@ -206,6 +206,14 @@ context, prefix.substr(0, cursor_pos)); } +static Completions complete_alias_name(const Context& context, CompletionFlags, + const String& prefix, ByteCount cursor_pos) +{ + return { 0_byte, cursor_pos, complete(prefix, cursor_pos, + context.aliases().flatten_aliases() + | transform(&HashItem<String, String>::key)) }; +} + struct ShellScriptCompleter { ShellScriptCompleter(String shell_script, @@ -979,7 +987,19 @@ HighlighterRegistry& registry = HighlighterRegistry::instance(); auto it = registry.find(params[1]); if (it != registry.end()) - return format("{}:\n{}", params[1], indent(it->value.docstring)); + { + auto docstring = it->value.description->docstring; + auto desc_params = generate_switches_doc(it->value.description->params.switches); + + if (desc_params.empty()) + return format("{}:\n{}", params[1], indent(docstring)); + else + { + auto desc_indent = Vector<String>{docstring, "Switches:", indent(desc_params)} + | transform([](auto& s) { return indent(s); }); + return format("{}:\n{}", params[1], join(desc_indent, "\n")); + } + } } return ""; }, @@ -1297,7 +1317,7 @@ ParameterDesc{{}, ParameterDesc::Flags::None, 3, 3}, CommandFlags::None, CommandHelper{}, - make_completer(complete_scope, complete_nothing, complete_command_name), + make_completer(complete_scope, complete_alias_name, complete_command_name), [](const ParametersParser& parser, Context& context, const ShellContext&) { if (not CommandManager::instance().command_defined(parser[2])) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kakoune-2021.10.28/src/highlighter.hh new/kakoune-2021.11.08/src/highlighter.hh --- old/kakoune-2021.10.28/src/highlighter.hh 2021-10-28 00:13:34.000000000 +0200 +++ new/kakoune-2021.11.08/src/highlighter.hh 2021-11-07 06:51:39.000000000 +0100 @@ -10,6 +10,7 @@ #include "array_view.hh" #include "string.hh" #include "utils.hh" +#include "parameters_parser.hh" #include <memory> @@ -86,13 +87,19 @@ using HighlighterParameters = ConstArrayView<String>; using HighlighterFactory = std::unique_ptr<Highlighter> (*)(HighlighterParameters params, Highlighter* parent); -struct HighlighterFactoryAndDocstring +struct HighlighterDesc +{ + const char* docstring; + ParameterDesc params; +}; + +struct HighlighterFactoryAndDescription { HighlighterFactory factory; - String docstring; + const HighlighterDesc* description; }; -struct HighlighterRegistry : HashMap<String, HighlighterFactoryAndDocstring, MemoryDomain::Highlight>, +struct HighlighterRegistry : HashMap<String, HighlighterFactoryAndDescription, MemoryDomain::Highlight>, Singleton<HighlighterRegistry> {}; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kakoune-2021.10.28/src/highlighters.cc new/kakoune-2021.11.08/src/highlighters.cc --- old/kakoune-2021.10.28/src/highlighters.cc 2021-10-28 00:13:34.000000000 +0200 +++ new/kakoune-2021.11.08/src/highlighters.cc 2021-11-07 06:51:39.000000000 +0100 @@ -221,6 +221,10 @@ }; }; +const HighlighterDesc fill_desc = { + "Fill the whole highlighted range with the given face", + {} +}; static std::unique_ptr<Highlighter> create_fill_highlighter(HighlighterParameters params, Highlighter*) { if (params.size() != 1) @@ -253,6 +257,11 @@ using FacesSpec = Vector<std::pair<size_t, String>, MemoryDomain::Highlight>; +const HighlighterDesc regex_desc = { + "Parameters: <regex> <capture num>:<face> <capture num>:<face>...\n" + "Highlights the matches for captures from the regex with the given faces", + {} +}; class RegexHighlighter : public Highlighter { public: @@ -479,6 +488,11 @@ RegexHighlighter m_highlighter; }; +const HighlighterDesc dynamic_regex_desc = { + "Parameters: <expr> <capture num>:<face> <capture num>:<face>...\n" + "Evaluate expression at every redraw to gather a regex", + {} +}; std::unique_ptr<Highlighter> create_dynamic_regex_highlighter(HighlighterParameters params, Highlighter*) { if (params.size() < 2) @@ -544,6 +558,11 @@ return make_hl(get_regex, get_face); } +const HighlighterDesc line_desc = { + "Parameters: <value string> <face>\n" + "Highlight the line given by evaluating <value string> with <face>", + {} +}; std::unique_ptr<Highlighter> create_line_highlighter(HighlighterParameters params, Highlighter*) { if (params.size() != 2) @@ -591,6 +610,11 @@ return make_highlighter(std::move(func)); } +const HighlighterDesc column_desc = { + "Parameters: <value string> <face>\n" + "Highlight the column given by evaluating <value string> with <face>", + {} +}; std::unique_ptr<Highlighter> create_column_highlighter(HighlighterParameters params, Highlighter*) { if (params.size() != 2) @@ -651,6 +675,17 @@ return make_highlighter(std::move(func)); } +const HighlighterDesc wrap_desc = { + "Parameters: [-word] [-indent] [-width <max_width>] [-marker <marker_text>]\n" + "Wrap lines to window width", + { { + { "word", { false, "wrap at word boundaries instead of codepoint boundaries" } }, + { "indent", { false, "preserve line indentation of the wrapped line" } }, + { "width", { true, "wrap at the given column instead of the window's width" } }, + { "marker", { true, "insert the given text at the beginning of the wrapped line" } }, }, + ParameterDesc::Flags::None, 0, 0 + } +}; struct WrapHighlighter : Highlighter { WrapHighlighter(ColumnCount max_width, bool word_wrap, bool preserve_indent, String marker) @@ -915,14 +950,7 @@ static std::unique_ptr<Highlighter> create(HighlighterParameters params, Highlighter*) { - static const ParameterDesc param_desc{ - { { "word", { false, "" } }, - { "indent", { false, "" } }, - { "width", { true, "" } }, - { "marker", { true, "" } } }, - ParameterDesc::Flags::None, 0, 0 - }; - ParametersParser parser(params, param_desc); + ParametersParser parser(params, wrap_desc.params); ColumnCount max_width = parser.get_switch("width").map(str_to_int) .value_or(std::numeric_limits<int>::max()); @@ -998,6 +1026,18 @@ } }; +const HighlighterDesc show_whitespace_desc = { + "Parameters: [-tab <separator>] [-tabpad <separator>] [-lf <separator>] [-spc <separator>] [-nbsp <separator>]\n" + "Display whitespaces using symbols", + { { + { "tab", { true, "replace tabulations with the given character" } }, + { "tabpad", { true, "append as many of the given character as is necessary to honor `tabstop`" } }, + { "spc", { true, "replace spaces with the given character" } }, + { "lf", { true, "replace line feeds with the given character" } }, + { "nbsp", { true, "replace non-breakable spaces with the given character" } } }, + ParameterDesc::Flags::None, 0, 0 + } +}; struct ShowWhitespacesHighlighter : Highlighter { ShowWhitespacesHighlighter(String tab, String tabpad, String spc, String lf, String nbsp) @@ -1007,15 +1047,7 @@ static std::unique_ptr<Highlighter> create(HighlighterParameters params, Highlighter*) { - static const ParameterDesc param_desc{ - { { "tab", { true, "" } }, - { "tabpad", { true, "" } }, - { "spc", { true, "" } }, - { "lf", { true, "" } }, - { "nbsp", { true, "" } } }, - ParameterDesc::Flags::None, 0, 0 - }; - ParametersParser parser(params, param_desc); + ParametersParser parser(params, show_whitespace_desc.params); auto get_param = [&](StringView param, StringView fallback) { StringView value = parser.get_switch(param).value_or(fallback); @@ -1080,6 +1112,18 @@ const String m_tab, m_tabpad, m_spc, m_lf, m_nbsp; }; +const HighlighterDesc line_numbers_desc = { + "Parameters: [-relative] [-hlcursor] [-separators <separator|separator:cursor|cursor:up:down>] [-min-digits <cols>]\n" + "Display line numbers", + { { + { "relative", { false, "show line numbers relative to the main cursor line" } }, + { "separator", { true, "string to separate the line numbers column from the rest of the buffer (default '|')" } }, + { "cursor-separator", { true, "identical to -separator but applies only to the line of the cursor (default is the same value passed to -separator)" } }, + { "min-digits", { true, "use at least the given number of columns to display line numbers (default 2)" } }, + { "hlcursor", { false, "highlight the cursor line with a separate face" } } }, + ParameterDesc::Flags::None, 0, 0 + } +}; struct LineNumbersHighlighter : Highlighter { LineNumbersHighlighter(bool relative, bool hl_cursor_line, String separator, String cursor_separator, int min_digits) @@ -1092,15 +1136,7 @@ static std::unique_ptr<Highlighter> create(HighlighterParameters params, Highlighter*) { - static const ParameterDesc param_desc{ - { { "relative", { false, "" } }, - { "separator", { true, "" } }, - { "cursor-separator", { true, "" } }, - { "min-digits", { true, "" } }, - { "hlcursor", { false, "" } } }, - ParameterDesc::Flags::None, 0, 0 - }; - ParametersParser parser(params, param_desc); + ParametersParser parser(params, line_numbers_desc.params); StringView separator = parser.get_switch("separator").value_or("???"); StringView cursor_separator = parser.get_switch("cursor-separator").value_or(separator); @@ -1192,6 +1228,10 @@ constexpr StringView LineNumbersHighlighter::ms_id; +const HighlighterDesc show_matching_desc = { + "Apply the MatchingChar face to the char matching the one under the cursor", + {} +}; void show_matching_char(HighlightContext context, DisplayBuffer& display_buffer, BufferRange) { const Face face = context.context.faces()["MatchingChar"]; @@ -1364,6 +1404,11 @@ { return std::get<0>(lhs) < std::get<0>(rhs); }); } +const HighlighterDesc flag_lines_desc = { + "Parameters: <face> <option name>\n" + "Display flags specified in the line-spec option <option name> with <face>", + {} +}; struct FlagLinesHighlighter : Highlighter { FlagLinesHighlighter(String option_name, String default_face) @@ -1565,6 +1610,12 @@ return true; } +const HighlighterDesc ranges_desc = { + "Parameters: <option name>\n" + "Use the range-specs option given as parameter to highlight buffer\n" + "each spec is interpreted as a face to apply to the range", + {} +}; struct RangesHighlighter : OptionBasedHighlighter<RangeAndStringList, RangesHighlighter> { using RangesHighlighter::OptionBasedHighlighter::OptionBasedHighlighter; @@ -1589,6 +1640,12 @@ } }; +const HighlighterDesc replace_ranges_desc = { + "Parameters: <option name>\n" + "Use the range-specs option given as parameter to highlight buffer\n" + "each spec is interpreted as a display line to display in place of the range", + {} +}; struct ReplaceRangesHighlighter : OptionBasedHighlighter<RangeAndStringList, ReplaceRangesHighlighter, HighlightPass::Move> { using ReplaceRangesHighlighter::OptionBasedHighlighter::OptionBasedHighlighter; @@ -1682,18 +1739,34 @@ return passes; } +const HighlighterDesc higlighter_group_desc = { + "Parameters: [-passes <passes>]\n" + "Creates a group that can contain other highlighters", + { { + { "passes", { true, "flags(colorize|move|wrap) " + "kind of highlighters can be put in the group " + "(default colorize)" } } }, + ParameterDesc::Flags::SwitchesOnlyAtStart, 0, 0 + } +}; std::unique_ptr<Highlighter> create_highlighter_group(HighlighterParameters params, Highlighter*) { - static const ParameterDesc param_desc{ - { { "passes", { true, "" } } }, - ParameterDesc::Flags::SwitchesOnlyAtStart, 0, 0 - }; - ParametersParser parser{params, param_desc}; + ParametersParser parser{params, higlighter_group_desc.params}; HighlightPass passes = parse_passes(parser.get_switch("passes").value_or("colorize")); return std::make_unique<HighlighterGroup>(passes); } +const HighlighterDesc ref_desc = { + "Parameters: [-passes <passes>] <path>\n" + "Reference the highlighter at <path> in shared highlighters", + { { + { "passes", { true, "flags(colorize|move|wrap) " + "kind of highlighters that can be referenced " + "(default colorize)" } } }, + ParameterDesc::Flags::SwitchesOnlyAtStart, 1, 1 + } +}; struct ReferenceHighlighter : Highlighter { ReferenceHighlighter(HighlightPass passes, String name) @@ -1701,11 +1774,7 @@ static std::unique_ptr<Highlighter> create(HighlighterParameters params, Highlighter*) { - static const ParameterDesc param_desc{ - { { "passes", { true, "" } } }, - ParameterDesc::Flags::SwitchesOnlyAtStart, 1, 1 - }; - ParametersParser parser{params, param_desc}; + ParametersParser parser{params, ref_desc.params}; HighlightPass passes = parse_passes(parser.get_switch("passes").value_or("colorize")); return std::make_unique<ReferenceHighlighter>(passes, parser[0]); } @@ -1881,6 +1950,30 @@ } }; +const HighlighterDesc default_region_desc = { + "Parameters: <delegate_type> <delegate_params>...\n" + "Define the default region of a regions highlighter", + {} +}; +const HighlighterDesc region_desc = { + "Parameters: [-match-capture] [-recurse <recurse>] <opening> <closing> <type> <params>...\n" + "Define a region for a regions highlighter, and apply the given delegate\n" + "highlighter as defined by <type> and eventual <params>...\n" + "The region starts at <begin> match and ends at the first <end>", + { { + { "match-capture", { false, "only consider region ending/recurse delimiters whose first capture group match the region beginning delimiter" } }, + { "recurse", { true, "make the region end on the first ending delimiter that does not close the given parameter" } } }, + ParameterDesc::Flags::SwitchesOnlyAtStart | ParameterDesc::Flags::IgnoreUnknownSwitches, + 3 + } +}; +const HighlighterDesc regions_desc = { + "Holds child region highlighters and segments the buffer in ranges based on those regions\n" + "definitions. The regions highlighter finds the next region to start by finding which\n" + "of its child region has the leftmost starting point from current position. In between\n" + "regions, the default-region child highlighter is applied (if such a child exists)", + {} +}; struct RegionsHighlighter : public Highlighter { public: @@ -2015,13 +2108,7 @@ if (not is_regions(parent)) throw runtime_error{"region highlighter can only be added to a regions parent"}; - static const ParameterDesc param_desc{ - { { "match-capture", { false, "" } }, { "recurse", { true, "" } } }, - ParameterDesc::Flags::SwitchesOnlyAtStart | ParameterDesc::Flags::IgnoreUnknownSwitches, - 3 - }; - - ParametersParser parser{params, param_desc}; + ParametersParser parser{params, region_desc.params}; const bool match_capture = (bool)parser.get_switch("match-capture"); if (parser[0].empty() or parser[1].empty()) @@ -2281,106 +2368,56 @@ HighlighterRegistry& registry = HighlighterRegistry::instance(); registry.insert({ - "number-lines", - { LineNumbersHighlighter::create, - "Display line numbers \n" - "Parameters: -relative, -hlcursor, -separator <separator text>, -cursor-separator <separator text>, -min-digits <cols>\n" } }); + "column", + { create_column_highlighter, &column_desc } }); registry.insert({ - "show-matching", - { create_matching_char_highlighter, - "Apply the MatchingChar face to the char matching the one under the cursor" } }); + "default-region", + { RegionsHighlighter::create_default_region, &default_region_desc } }); registry.insert({ - "show-whitespaces", - { ShowWhitespacesHighlighter::create, - "Display whitespaces using symbols \n" - "Parameters: -tab <separator> -tabpad <separator> -lf <separator> -spc <separator> -nbsp <separator>\n" } }); + "dynregex", + { create_dynamic_regex_highlighter, &dynamic_regex_desc } }); registry.insert({ "fill", - { create_fill_highlighter, - "Fill the whole highlighted range with the given face" } }); - registry.insert({ - "regex", - { RegexHighlighter::create, - "Parameters: <regex> <capture num>:<face> <capture num>:<face>...\n" - "Highlights the matches for captures from the regex with the given faces" } }); + { create_fill_highlighter, &fill_desc } }); registry.insert({ - "dynregex", - { create_dynamic_regex_highlighter, - "Parameters: <expr> <capture num>:<face> <capture num>:<face>...\n" - "Evaluate expression at every redraw to gather a regex" } }); + "flag-lines", + { FlagLinesHighlighter::create, &flag_lines_desc } }); registry.insert({ "group", - { create_highlighter_group, - "Parameters: [-passes <passes>]\n" - "Creates a group that can contain other highlighters,\n" - "<passes> is a flags(colorize|move|wrap) defaulting to colorize\n" - "which specify what kind of highlighters can be put in the group" } }); + { create_highlighter_group, &higlighter_group_desc } }); registry.insert({ - "flag-lines", - { FlagLinesHighlighter::create, - "Parameters: <face> <option name>\n" - "Display flags specified in the line-spec option <option name> with <face>"} }); + "line", + { create_line_highlighter, &line_desc } }); + registry.insert({ + "number-lines", + { LineNumbersHighlighter::create, &line_numbers_desc } }); registry.insert({ "ranges", - { RangesHighlighter::create, - "Parameters: <option name>\n" - "Use the range-specs option given as parameter to highlight buffer\n" - "each spec is interpreted as a face to apply to the range\n" } }); + { RangesHighlighter::create, &ranges_desc } }); registry.insert({ - "replace-ranges", - { ReplaceRangesHighlighter::create, - "Parameters: <option name>\n" - "Use the range-specs option given as parameter to highlight buffer\n" - "each spec is interpreted as a display line to display in place of the range\n" } }); + "ref", + { ReferenceHighlighter::create, &ref_desc } }); registry.insert({ - "line", - { create_line_highlighter, - "Parameters: <value string> <face>\n" - "Highlight the line given by evaluating <value string> with <face>" } }); + "regex", + { RegexHighlighter::create, ®ex_desc } }); registry.insert({ - "column", - { create_column_highlighter, - "Parameters: <value string> <face>\n" - "Highlight the column given by evaluating <value string> with <face>" } }); + "region", + { RegionsHighlighter::create_region, ®ion_desc } }); registry.insert({ - "wrap", - { WrapHighlighter::create, - "Parameters: [-word] [-indent] [-width <max_width>] [-marker <marker_text>]\n" - "Wrap lines to window width, or max_width if given and window is wider,\n" - "wrap at word boundaries instead of codepoint boundaries if -word is given\n" - "insert marker_text at start of wrapped lines if given\n" - "preserve line indent in wrapped parts if -indent is given\n"} }); + "regions", + { RegionsHighlighter::create, ®ions_desc } }); registry.insert({ - "ref", - { ReferenceHighlighter::create, - "Parameters: [-passes <passes>] <path>\n" - "Reference the highlighter at <path> in shared highlighters\n" - "<passes> is a flags(colorize|move|wrap) defaulting to colorize\n" - "which specify what kind of highlighters can be referenced" } }); + "replace-ranges", + { ReplaceRangesHighlighter::create, &replace_ranges_desc } }); registry.insert({ - "regions", - { RegionsHighlighter::create, - "Parameters: None\n" - "Holds child region highlighters and segments the buffer in ranges based on those regions\n" - "definitions. The regions highlighter finds the next region to start by finding which\n" - "of its child region has the leftmost starting point from current position. In between\n" - "regions, the default-region child highlighter is applied (if such a child exists)" } }); + "show-matching", + { create_matching_char_highlighter, &show_matching_desc } }); registry.insert({ - "region", - { RegionsHighlighter::create_region, - "Parameters: [-match-capture] [-recurse <recurse>] <opening> <closing> <type> <params>...\n" - "Define a region for a regions highlighter, and apply the given delegate\n" - "highlighter as defined by <type> and eventual <params>...\n" - "The region starts at <begin> match and ends at the first <end>\n" - "If -recurse is specified, then the region ends at the first <end> that\n" - "does not close a <recurse> match.\n" - "If -match-capture is specified, then regions end/recurse matches must have\n" - "the same \\1 capture content as the begin match to be considered"} }); + "show-whitespaces", + { ShowWhitespacesHighlighter::create, &show_whitespace_desc } }); registry.insert({ - "default-region", - { RegionsHighlighter::create_default_region, - "Parameters: <delegate_type> <delegate_params>...\n" - "Define the default region of a regions highlighter" } }); + "wrap", + { WrapHighlighter::create, &wrap_desc } }); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kakoune-2021.10.28/src/main.cc new/kakoune-2021.11.08/src/main.cc --- old/kakoune-2021.10.28/src/main.cc 2021-10-28 00:13:34.000000000 +0200 +++ new/kakoune-2021.11.08/src/main.cc 2021-11-07 06:51:39.000000000 +0100 @@ -44,6 +44,9 @@ unsigned int version; StringView notes; } constexpr version_notes[] = { { + 20211107, + "?? colored and curly underlines support (undocumented in 20210828)\n" + }, { 20211028, "?? {+b}g{} and {+b}v{} do not auto-convert to lowercase anymore\n" }, { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kakoune-2021.10.28/src/normal.cc new/kakoune-2021.11.08/src/normal.cc --- old/kakoune-2021.10.28/src/normal.cc 2021-10-28 00:13:34.000000000 +0200 +++ new/kakoune-2021.11.08/src/normal.cc 2021-11-07 06:51:39.000000000 +0100 @@ -720,6 +720,9 @@ offsets.push_back(all.length()); } + if (offsets.empty()) + throw runtime_error("nothing to paste"); + Buffer& buffer = context.buffer(); Vector<Selection> result; auto& selections = context.selections(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kakoune-2021.10.28/src/shell_manager.cc new/kakoune-2021.11.08/src/shell_manager.cc --- old/kakoune-2021.10.28/src/shell_manager.cc 2021-10-28 00:13:34.000000000 +0200 +++ new/kakoune-2021.11.08/src/shell_manager.cc 2021-11-07 06:51:39.000000000 +0100 @@ -172,15 +172,19 @@ FDWatcher make_reader(int fd, String& contents, OnClose&& on_close) { return {fd, FdEvents::Read, EventMode::Urgent, - [fd, &contents, on_close](FDWatcher& watcher, FdEvents, EventMode) { + [&contents, on_close](FDWatcher& watcher, FdEvents, EventMode) { + const int fd = watcher.fd(); char buffer[1024]; while (fd_readable(fd)) { - size_t size = ::read(fd, buffer, sizeof(buffer)); + ssize_t size = ::read(fd, buffer, sizeof(buffer)); if (size <= 0) { + if (size < 0 and errno == EAGAIN) + continue; // try again + watcher.disable(); - on_close(); + on_close(size == 0); return; } contents += StringView{buffer, buffer+size}; @@ -225,11 +229,15 @@ mkfifo(command_fifo_path().c_str(), 0600); mkfifo(response_fifo_path().c_str(), 0600); int fd = open(command_fifo_path().c_str(), O_RDONLY | O_NONBLOCK); - return make_reader(fd, command, [&, fd] { - close(fd); + return make_reader(fd, command, [&, fd](bool graceful) { + if (not graceful) + { + write_to_debug_buffer(format("error reading from command fifo '{}'", strerror(errno))); + return; + } CommandManager::instance().execute(command, context, shell_context); command.clear(); - command_watcher.reset_fd(open(command_fifo_path().c_str(), O_RDONLY | O_NONBLOCK)); + command_watcher.reset_fd(fd); }); }()) { @@ -310,8 +318,8 @@ auto wait_time = Clock::now(); String stdout_contents, stderr_contents; - auto stdout_reader = make_reader(child_stdout.read_fd(), stdout_contents, [&]{ child_stdout.close_read_fd(); }); - auto stderr_reader = make_reader(child_stderr.read_fd(), stderr_contents, [&]{ child_stderr.close_read_fd(); }); + auto stdout_reader = make_reader(child_stdout.read_fd(), stdout_contents, [&](bool){ child_stdout.close_read_fd(); }); + auto stderr_reader = make_reader(child_stderr.read_fd(), stderr_contents, [&](bool){ child_stderr.close_read_fd(); }); auto stdin_writer = make_pipe_writer(child_stdin, input); // block SIGCHLD to make sure we wont receive it before diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kakoune-2021.10.28/src/terminal_ui.cc new/kakoune-2021.11.08/src/terminal_ui.cc --- old/kakoune-2021.10.28/src/terminal_ui.cc 2021-10-28 00:13:34.000000000 +0200 +++ new/kakoune-2021.11.08/src/terminal_ui.cc 2021-11-07 06:51:39.000000000 +0100 @@ -247,7 +247,7 @@ if (face.attributes & (Attribute)(1 << i)) format_with(writer, ";{}", attr_table[i]); } - m_active_face = Face{{}, {}, face.attributes}; + m_active_face.fg = m_active_face.bg = Color::Default; join = true; } if (m_active_face.fg != face.fg) @@ -754,7 +754,7 @@ auto parse_csi = [this, &convert, &parse_mask]() -> Optional<Key> { auto next_char = [] { return get_char().value_or((unsigned char)0xff); }; - int params[16] = {}; + int params[16][4] = {}; auto c = next_char(); char private_mode = 0; if (c == '?' or c == '<' or c == '=' or c == '>') @@ -762,12 +762,17 @@ private_mode = c; c = next_char(); } - for (int count = 0; count < 16 and c >= 0x30 && c <= 0x3f; c = next_char()) + for (int count = 0, subcount = 0; count < 16 and c >= 0x30 && c <= 0x3f; c = next_char()) { if (isdigit(c)) - params[count] = params[count] * 10 + c - '0'; + params[count][subcount] = params[count][subcount] * 10 + c - '0'; + else if (c == ':' && subcount < 3) + ++subcount; else if (c == ';') + { ++count; + subcount = 0; + } else return {}; } @@ -794,13 +799,13 @@ (Codepoint)((down ? 1 : -1) * m_wheel_scroll_amount)}; }; - auto masked_key = [&](Codepoint key) { - int mask = std::max(params[1] - 1, 0); + auto masked_key = [&](Codepoint key, Codepoint shifted_key = 0) { + int mask = std::max(params[1][0] - 1, 0); Key::Modifiers modifiers = parse_mask(mask); - if (is_basic_alpha(key) and (modifiers & Key::Modifiers::Shift)) + if (shifted_key != 0 and (modifiers & Key::Modifiers::Shift)) { modifiers &= ~Key::Modifiers::Shift; - key = to_upper(key); + key = shifted_key; } return Key{modifiers, key}; }; @@ -810,14 +815,14 @@ case '$': if (private_mode == '?' and next_char() == 'y') // DECRPM { - if (params[0] == 2026) - m_synchronized.supported = (params[0] != 0); + if (params[0][0] == 2026) + m_synchronized.supported = (params[1][0] == 1 or params[1][0] == 2); return {Key::Invalid}; } - switch (params[0]) + switch (params[0][0]) { case 23: case 24: - return Key{Key::Modifiers::Shift, Key::F11 + params[0] - 23}; // rxvt style + return Key{Key::Modifiers::Shift, Key::F11 + params[0][0] - 23}; // rxvt style } return {}; case 'A': return masked_key(Key::Up); @@ -832,7 +837,7 @@ case 'R': return masked_key(Key::F3); case 'S': return masked_key(Key::F4); case '~': - switch (params[0]) + switch (params[0][0]) { case 1: return masked_key(Key::Home); // VT220/tmux style case 2: return masked_key(Key::Insert); @@ -843,23 +848,24 @@ case 7: return masked_key(Key::Home); // rxvt style case 8: return masked_key(Key::End); // rxvt style case 11: case 12: case 13: case 14: case 15: - return masked_key(Key::F1 + params[0] - 11); + return masked_key(Key::F1 + params[0][0] - 11); case 17: case 18: case 19: case 20: case 21: - return masked_key(Key::F6 + params[0] - 17); + return masked_key(Key::F6 + params[0][0] - 17); case 23: case 24: - return masked_key(Key::F11 + params[0] - 23); + return masked_key(Key::F11 + params[0][0] - 23); case 25: case 26: - return Key{Key::Modifiers::Shift, Key::F3 + params[0] - 25}; // rxvt style + return Key{Key::Modifiers::Shift, Key::F3 + params[0][0] - 25}; // rxvt style case 28: case 29: - return Key{Key::Modifiers::Shift, Key::F5 + params[0] - 28}; // rxvt style + return Key{Key::Modifiers::Shift, Key::F5 + params[0][0] - 28}; // rxvt style case 31: case 32: - return Key{Key::Modifiers::Shift, Key::F7 + params[0] - 31}; // rxvt style + return Key{Key::Modifiers::Shift, Key::F7 + params[0][0] - 31}; // rxvt style case 33: case 34: - return Key{Key::Modifiers::Shift, Key::F9 + params[0] - 33}; // rxvt style + return Key{Key::Modifiers::Shift, Key::F9 + params[0][0] - 33}; // rxvt style } return {}; case 'u': - return masked_key(convert(static_cast<Codepoint>(params[0]))); + return masked_key(convert(static_cast<Codepoint>(params[0][0])), + convert(static_cast<Codepoint>(params[0][1]))); case 'Z': return shift(Key::Tab); case 'I': return {Key::FocusIn}; case 'O': return {Key::FocusOut}; @@ -868,9 +874,9 @@ if (not sgr and c != 'M') return {}; - const Codepoint b = sgr ? params[0] : next_char() - 32; - const int x = (sgr ? params[1] : next_char() - 32) - 1; - const int y = (sgr ? params[2] : next_char() - 32) - 1; + const Codepoint b = sgr ? params[0][0] : next_char() - 32; + const int x = (sgr ? params[1][0] : next_char() - 32) - 1; + const int y = (sgr ? params[2][0] : next_char() - 32) - 1; auto coord = encode_coord({y - content_line_offset(), x}); Key::Modifiers mod = parse_mask((b >> 2) & 0x7); switch (const int code = b & 0x43; code) @@ -1404,6 +1410,7 @@ "\033[?1049h" // enable alternative screen buffer "\033[?1004h" // enable focus notify "\033[>4;1m" // request CSI u style key reporting + "\033[>5u" // kitty progressive enhancement - report shifted key codes "\033[22t" // save the current window title "\033[?25l" // hide cursor "\033=" // set application keypad mode, so the keypad keys send unique codes @@ -1417,6 +1424,7 @@ "\033>" "\033[?25h" "\033[23t" + "\033[<u" "\033[>4;0m" "\033[?1004l" "\033[?1049l" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kakoune-2021.10.28/test/highlight/replace-only-fully-selected-ranges/.kak_history new/kakoune-2021.11.08/test/highlight/replace-only-fully-selected-ranges/.kak_history --- old/kakoune-2021.10.28/test/highlight/replace-only-fully-selected-ranges/.kak_history 2021-10-28 00:13:34.000000000 +0200 +++ new/kakoune-2021.11.08/test/highlight/replace-only-fully-selected-ranges/.kak_history 1970-01-01 01:00:00.000000000 +0100 @@ -1 +0,0 @@ -'reg' ':' '' 'wq' \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kakoune-2021.10.28/test/regression/4414-crash-on-paste-all/cmd new/kakoune-2021.11.08/test/regression/4414-crash-on-paste-all/cmd --- old/kakoune-2021.10.28/test/regression/4414-crash-on-paste-all/cmd 1970-01-01 01:00:00.000000000 +0100 +++ new/kakoune-2021.11.08/test/regression/4414-crash-on-paste-all/cmd 2021-11-07 06:51:39.000000000 +0100 @@ -0,0 +1 @@ +<a-p> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kakoune-2021.10.28/test/regression/4414-crash-on-paste-all/in new/kakoune-2021.11.08/test/regression/4414-crash-on-paste-all/in --- old/kakoune-2021.10.28/test/regression/4414-crash-on-paste-all/in 1970-01-01 01:00:00.000000000 +0100 +++ new/kakoune-2021.11.08/test/regression/4414-crash-on-paste-all/in 2021-11-07 06:51:39.000000000 +0100 @@ -0,0 +1 @@ + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kakoune-2021.10.28/test/regression/4414-crash-on-paste-all/out new/kakoune-2021.11.08/test/regression/4414-crash-on-paste-all/out --- old/kakoune-2021.10.28/test/regression/4414-crash-on-paste-all/out 1970-01-01 01:00:00.000000000 +0100 +++ new/kakoune-2021.11.08/test/regression/4414-crash-on-paste-all/out 2021-11-07 06:51:39.000000000 +0100 @@ -0,0 +1 @@ +