| Age | Commit message (Collapse) | Author |
|
|
|
- keywords removed: `async`, `noasync`, and `usingnamespace`
- builtins added: `memmove`
|
|
|
|
|
|
<memory> is a costly header we can avoid by just implementing
UniquePtr ourselves, which is a pretty straightforward in modern
C++, this saves around 10% of the compilation time here.
|
|
|
|
|
|
This helps the compiler realize that data cannot change and does
not need reloading, improving codegen slightly.
|
|
|
|
Instead of jumping into the general CharClass code, detect simple
[a-z] style ranges and use a specific op.
Also detect when a range can be converted to ignore case
|
|
decrement and post_increment do not get cmov optimised as expected,
we can avoid this altogether by taking advantage of the fact that
capacity is always a power-of-two and we can hence use a bitwise and
we can use a bitwise and to loop around capacity.
|
|
The `history_since_<id>` value expansion allows incremental parsing of a
buffer's history.
declare-option int my_last_history_id
define-command my-process-history ...
# process the initial buffer history
my-process-history %val{bufname} 0 %val{history}
set-option buffer my_last_history_id 0
# only process new history changes on idle
hook buffer NormalIdle %{
evaluate-commands %exp{
my-process-history \
%%val{bufname} \
%%opt{my_last_history_id} \
%%val{history_since_%opt{my_last_history_id}}
}
set-option buffer my_last_history_id %val{history_id}
}
|
|
Link to `:doc changelog` in the title and link to startup-info there
so that this information stays visible even if the changelog overflows
the info box.
Use format support for 0 padding instead of custom code
|
|
|
|
We have this information in the changelog and its unlikely users
will read past the third entry.
Fixes #5352
|
|
This fixes going from static to non-static linking by having
different output files, the final symlink will point to the
latest built config, as usual.
|
|
computing the indentation is surprisingly costly (close to 8% of the
whole test framework runtime), and having the full path to easily copy
paste is handy instead of recreating it from the printed tree.
|
|
|
|
Commit ba41928aa (Remove spurious newline when | replaces at buffer end,
2024-11-28) also tried to fix a "DiffOp::Add" code path. Unless I'm
misremembering, I had run into a crash and extracted this unit test.
When apply_diff() decides to erase the last line, and then insert something
at the end, buffer changes might look like:
{.type=Erase, .begin={2, 0}, .end={3, 0}}
{.type=Insert, .begin={1, 5}, .end={5, 0}}
The "{1, 5}" is caused by "pos = buffer.prev(pos);" added by the
aforementioned commit. It's problematic because it breaks the caller's
"ForwardChangesTracker" invariant: the previous Erase leaves the cursor at
{2, 0}, so the insert cannot start before that.
Additionally, the inserted range returned by apply_diff() would be
"{ {2, 0}, {4, 0} }" whose end position is weirdly different from the Insert's
end position. It questionable that we are passing on this weird state.
The "pos = buffer.prev(pos);" statement was added so we actually delete the
current final newline. We still leave "tried_to_erase_final_newline" set,
meaning we'll also delete the the final newline after we're done.
But deleting the "current final newline" the way we do it is confusing,
because we do it at every step DiffOp::Add step. This would blow up if
there are multiple successive contiguous DiffOp::Add events. I doubt this
ever happens but it's still confusing.
Remove this logic, and restore historical behavior in case we append at the
buffer end. This does not break the system test added by ba41928aa because
in that case, we
1. first delete the entire buffer, setting pos={0, 0}, but also restoring
the EOL invariant, so the end position would be {0, 1}.
2. then we insert at pos={0, 0}, and since "buffer.is_end(pos)" is false we
don't run into this bad code path.
While at it add an assertion to clarify that we already assume that the
diff algorithm never gives us empty DiffOp::Keep, and always monotonically
increasing positions, except for the very special case where we deleted
until buffer end, which should already be handled.
The unit test is not perfect because it depends on the current behavior of
the diff algorithm.
|
|
|
|
Those do not really need to get inlined and pull std::max which
really wants <algorithm> which is an expensive header.
|
|
|
|
|
|
|
|
This reverts commit 549a5d2c223d422390795741537b150b492a3935.
|
|
Consider atom boundaries as word boundaries, which should be correct
du to passes ordering.
Fixes #5350
|
|
|
|
|
|
|
|
|
|
|
|
I dedicate any and all copyright interest in this software to the
public domain. I make this dedication for the benefit of the public at
large and to the detriment of my heirs and successors. I intend this
dedication to be an overt act of relinquishment in perpetuity of all
present and future rights to this software under copyright law.
|
|
|
|
This was only used for std::min and std::equal, which can be replaced
with custom code and memcmp, this removes a costly header from the
often used string.hh and may improve compilation speed slightly
|
|
|
|
Fixes #5349
|
|
If the current buffer is locked, it means we are in the middle of
creating the client or already changing the buffer, error out in this
case instead of getting into an inconsistent state.
Fixes #5338
|
|
My
kak -e "exec %{%ca<ret>b<esc>%|printf '\n\n'<ret>}"
adds a spurious third line.
When we replace up to the end everything, we keep around a single
newline to uphold the buffer invariant, but that newline
Commit de1433d30 (Avoid the spurious newline insertion when replacing
at end of buffer, 2016-03-16) fixed an issue for most commands that
replace until the buffer end.
A similar issue exists for the "|" command. It triggers in fewer
cases because the replacement is implemented by applying edits
computed by the diff algorithm. It does trigger when "|" replaces
the entire buffer.
Fix that by erasing the spurious newline.
Alternatively, we could allow the diff steps of kind "remove" to
delete the entire buffer, and only restore the invariant after the
whole diff is applied. This should work because the one-past-end
position is valid for Buffer::insert() even if the buffer is empty. It
is not valid for Buffer::erase() or Buffer::advance() where count>0
but if we do that when we're already at the buffer end, that is
probably a bug in the diff. I tried this but ran into a assertion
in ForwardChangesTracker (kak_assert(change.begin >= cur_pos)).
Alternatively, we could change the diff algorithm to always insert
before deleting.
I encountered this issue when using ansi-enable on a fifo buffer.
Specifically, the first BufReadFifo hook would replace the entire
inserted text but leave around a spurious newline.
|
|
This test uses ui_out and ui_in to coordinate events.
This is brittle[1] because ui_out behavior depends on timing.
Since this test doesn't really care about intermediate UI state,
express the sequence using BufCloseFifo instead.
This hits another issue: inside git blame-jump's BufCloseFifo, we
run git blame, which runs another "edit -fifo .. *git*". A special
aspect of fifo buffers is that any existing *git* buffer will be
reused instead of being recreated[2]. After BufCloseFifo, the fifo
watcher destructor will reset the fifo flag, even if BufCloseFifo
has recreated the fifo buffer. This breaks invariants and causes
the next fifo watcher destructor do fail its assertion.
Let's not reset fifo flags in this case. This should be safe because
it's the very last thing the fifo watcher does, so it's okay if
another one is active now.
Alternatively we could reject this kind of recursion, or implement
it in a different way (using ScopedSetBool for the flags).
Reported-by: Nico Sonack <nsonack@herrhotzenplotz.de>
[1]: https://lists.sr.ht/~mawww/kakoune/%3C20241210100417.1150697-1-aclopte@gmail.com%3E
[2]: This removes the need to use delete-buffer which also ensures that
the buffer remains visible in any client it's already shown.
|
|
Returning an optional of the removed item is not very idiomatic and
we currently have no use case for this.
|
|
FifoWatcher::read_fifo() deletes the fifo watcher in
m_buffer.values().erase(fifo_watcher_id); // will delete this
which calls: HashMap::unordered_remove()
constexpr_swap(m_items[index], m_items.back());
destructor called here --> m_items.pop_back();
m_index.remove(hash, index);
So hash map invariants (of buffer.values()) are broken, when calling
~FifoWatcher which fires BufCloseFifo hooks. Things blow up if those
hooks access buffer.values() such as by accessing cached highlighters
to redraw the buffer. A shell call with a long sleep in the client
context seems to trigger this.
Fix this by destroying removed map items only at the end of
HashMap::remove(), when invariants are restored. Alternatively, we
could introduce a fifo_trash container; I haven't explored that.
|
|
|
|
Replaced ranges will count towards the wrapping column but will not
be split.
Fixes #4883
|
|
For WrapHighlighter to be able to take ReplaceRangesHighlighter
into account, it needs to run afterwards, moreover, moving
TabulationHighlighter to the replace pass means we should be able to
remove any tabulation specific handling from WrapHighlighter
Also move ShowWhitespaceHighlighter to this pass as it is designed
to replace TabulationHighlighter by running before (as builtin
highlighters run after non builtin ones for each passes)
|
|
Move the whole responsibility of making the cursor visible to the
window, removing cursor_pos from the display setup and resolving
the cursor location by finding it in the display buffer afterwards.
This simplifies hightlighters' do_compute_display_setup as they do
not need to compute the cursor location. Highlighting may run on
more lines than necessary after this change but this should be a
minor performance hit.
|
|
|
|
|
|
assert_eq got renamed to check_json_eq but the fact this was used by
tests in their script file was missed, renamed it back to assert_eq
as this function is not necessarily used for json.
|
|
|
|
If git is present we can rely on git-diff word support to get a much
easier to understand diff.
|