diff --git a/src/regex_impl.cc b/src/regex_impl.cc index bb1f3537..11d0429a 100644 --- a/src/regex_impl.cc +++ b/src/regex_impl.cc @@ -1192,6 +1192,12 @@ auto test_regex = UnitTest{[]{ kak_assert(StringView{vm.captures()[0], vm.captures()[1]} == "boz"); } + { + TestVM vm{R"($)"}; + kak_assert(vm.exec("foo\nbar\nbaz\nqux", RegexExecFlags::Search | RegexExecFlags::NotEndOfLine)); + kak_assert(StringView{vm.captures()[0]} == "\nqux"); + } + { TestVM<> vm{R"(()*)"}; kak_assert(not vm.exec(" ")); diff --git a/src/regex_impl.hh b/src/regex_impl.hh index 6f2137ce..9a8efdd7 100644 --- a/src/regex_impl.hh +++ b/src/regex_impl.hh @@ -130,23 +130,28 @@ public: bool exec(Iterator begin, Iterator end, RegexExecFlags flags) { - const bool forward = direction == MatchDirection::Forward; + if (flags & RegexExecFlags::NotInitialNull and begin == end) + return false; + + constexpr bool forward = direction == MatchDirection::Forward; const bool prev_avail = flags & RegexExecFlags::PrevAvailable; + m_begin = Utf8It{utf8::iterator{forward ? begin : end, prev_avail ? begin-1 : begin, end}}; m_end = Utf8It{utf8::iterator{forward ? end : begin, prev_avail ? begin-1 : begin, end}}; - m_flags = flags; - - if (flags & RegexExecFlags::NotInitialNull and m_begin == m_end) - return false; + if (forward) + m_flags = flags; + else // Flip line begin/end flags as we flipped the instructions on compilation. + m_flags = (RegexExecFlags)(flags & ~(RegexExecFlags::NotEndOfLine | RegexExecFlags::NotBeginOfLine)) | + ((flags & RegexExecFlags::NotEndOfLine) ? RegexExecFlags::NotBeginOfLine : RegexExecFlags::None) | + ((flags & RegexExecFlags::NotBeginOfLine) ? RegexExecFlags::NotEndOfLine : RegexExecFlags::None); - const bool no_saves = (m_flags & RegexExecFlags::NoSaves); + const bool no_saves = (flags & RegexExecFlags::NoSaves); Utf8It start{m_begin}; const bool* start_chars = m_program.start_chars ? m_program.start_chars->map : nullptr; - if (flags & RegexExecFlags::Search) to_next_start(start, m_end, start_chars); diff --git a/src/selectors.cc b/src/selectors.cc index c7f237c2..0585c63c 100644 --- a/src/selectors.cc +++ b/src/selectors.cc @@ -881,7 +881,7 @@ Selection find_next_match(const Context& context, const Selection& sel, const Re wrapped = false; const bool found = (direction == MatchDirection::Forward) ? find_next(buffer, utf8::next(pos, buffer.end()), matches, regex, wrapped) - : find_prev(buffer, pos, matches, regex, wrapped); + : find_prev(buffer, utf8::previous(pos, buffer.begin()), matches, regex, wrapped); if (not found or matches[0].first == buffer.end()) throw runtime_error(format("'{}': no matches found", regex.str()));