Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions doc/pages/changelog.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ released versions.

* `number-lines -full-relative` switch to keep a smaller line number gutter.

* Support the `\N` escape sequence in regex (like in PCRE, matches `[^\n]`).

== Kakoune 2025.06.03

* Expose env vars that are mentioned in the arguments passed to shell expansions
Expand Down
4 changes: 2 additions & 2 deletions doc/pages/faq.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -292,8 +292,8 @@ In most distributions, `/bin/sh` will end up being used.

Data in buffers is a stream of characters, and newlines do not receive special
treatment compared to other characters, with regards to regex matching. In
order to select data in a line without any trailing newline characters, one could
use the `[^\n]+` pattern, which is arguably a good compromise when
order to select data in a line without any trailing newline characters, one
could use the `\N+` pattern, which is arguably a good compromise when
balanced against the ability to select data over several lines.

You can instruct the regex engine to stop matching newline characters with
Expand Down
6 changes: 3 additions & 3 deletions doc/pages/highlighters.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,9 @@ highlighter is replaced with the new one.
This highlights C++ style comments in cyan, with an eventual 'TODO:'
in yellow on red background:

--------------------------------------------------------------------
add-highlighter window/ regex //\h*(TODO:)[^\n]* 0:cyan 1:yellow,red
--------------------------------------------------------------------
-----------------------------------------------------------------
add-highlighter window/ regex //\h*(TODO:)\N* 0:cyan 1:yellow,red
-----------------------------------------------------------------

capture_id can be either the capture number, or its name if a
named capture is used in the regex (See
Expand Down
4 changes: 3 additions & 1 deletion doc/pages/regex.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ is equivalent to `[\d]`.
`.` matches any character, including newlines, by default.
(see <<regex#modifiers,:doc regex modifiers>> on how to change it)

`\N` matches any character but newlines (not affected by modifiers).

== Groups

Regex atoms can be grouped using `(` and `)` or `(?:` and `)`. If `(` is
Expand Down Expand Up @@ -184,7 +186,7 @@ by <https://www.ecma-international.org/ecma-262/8.0/>; some divergence
exists for ease of use, or performance reasons:

* Lookarounds are not arbitrary, but lookbehind is supported.
* `\K`, `\Q..\E`, `\A`, `\h` and `\z` are added.
* `\K`, `\N`, `\Q..\E`, `\A`, `\h` and `\z` are added.
* Stricter handling of escaping, as we introduce additional escapes;
identity escapes like `\X` with `X` being a non-special character
are not accepted, to avoid confusions between `\h` meaning literal
Expand Down
1 change: 1 addition & 0 deletions src/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ struct {
"» {+b}%val\\{buffile}{} is now empty for scratch buffers\n"
"» {+b}FocusIn{}/{+b}FocusOut{} events on suspend\n"
"» {+u}number-lines -full-relative{} switch to keep a smaller line number gutter\n"
"» support the {+b}\\N{} escape sequence in regex (matches {+b}[^\\n]{})\n"
}, {
20250603,
"» kak_* appearing in shell arguments will be added to the environment\n"
Expand Down
9 changes: 9 additions & 0 deletions src/regex_vm.cc
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,9 @@ struct RegexParser
{
const Codepoint cp = *m_pos++;

if (cp == 'N')
return add_node(ParsedRegex::AnyCharExceptNewLine);

if (cp == 'Q')
{
auto escaped_sequence = add_node(ParsedRegex::Sequence);
Expand Down Expand Up @@ -1562,6 +1565,12 @@ auto test_regex = UnitTest{[]{
kak_assert(*vm.captures()[0] == 'f');
}

{
TestVM<> vm{R"(a(?<=\N)\N+(?=.\N)\s(?S)d.+(?!.)\s(?<!\N)g)"};
kak_assert(vm.exec("abc\ndef\ng"));
kak_assert(not vm.exec("abc\ndef g"));
}

{
TestVM<> vm{R"([d-ea-dcf-k]+)"};
kak_assert(vm.exec("abcde"));
Expand Down
Loading