Commit Graph

10389 Commits

Author SHA1 Message Date
Johannes Altmanninger
f786fceb73 Fix flaky blame-jump-message test
This test fails occasionally[1] because the order of events and the
number of events varies across runs.

We should always call draw_status exactly 3 times:

                        [*git*][fifo]
                        [*git*]
    Commit subject etc. [*git*]

Let's check it this way.
This seems to work; this time I took the time to run it a couple
hundred times and in Cirrus CI.

[1] https://builds.sr.ht/~mawww/job/1151239
2024-02-18 15:45:03 +11:00
Johannes Altmanninger
5f0729f155 rc tools git: fix initial position of blame of deleted line
When running git blame in a "git show" buffer, we annotate the youngest
version of the file that has the line referenced by the diff line
at cursor.
In case the cursor is on an added or context line, we simply show
the version from the surrounding commit.

When the cursor is on a deleted line, we show the parent commit,
which still has the deleted line.  However there is a bug: we use
the line number in the new version of the file. Fix that.
2024-02-18 10:15:03 +11:00
Johannes Altmanninger
22b1d4ec4a Try to fix crash due to fifo read regression
I saw a crash when running

	git log --oneline %arg{@}
	hook -once buffer NormalIdle .* %{
		execute-keys -draft \
		%{gk!} \
		%{git diff --quiet || echo "Unstaged changes";} \
		%{git diff --quiet --cached || echo "Staged changes";} \
		<ret>
	}

Backtrace (I still have GDB attached):

    #4  0x00006502c740b13f in Kakoune::operator- (rhs=..., lhs=...) at /home/johannes/git/kakoune/src/units.hh:33
    33	   { return RealType(lhs.m_value - rhs.m_value); }
    (gdb) up
    #5  Kakoune::Buffer::next (coord=..., this=0x6502c90d7ff0) at /home/johannes/git/kakoune/src/buffer.inl.hh:18
    18	   if (coord.column < m_lines[coord.line].length() - 1)
    (gdb) up
    #6  FifoWatcher::read_fifo (this=0x6502c90d9e48) at buffer_utils.cc:252
    252	                           m_buffer.erase(pos, m_buffer.next(pos));

This was introduced in 582c3c56b (Do not add trailing newline to
non-scrolling fifo buffers, 2024-01-28).

The problem seems to be that we call "m_buffer.next()" on a position
that is past-end the buffer, so m_lines[coord.line] is out-of-bounds.
Fix it.
For some reason I have not managed to reproduce the crash, not even
with sanitize=address.

There might be another problem: m_had_trailing_newline is intentionally
uninitialized because it is supposed to be read only on the second
read() with a positive return value. Unfortunately I think it's
possible that e.g. a NormalIdle hook inserts some text before the
first positive read(). Then, this line

        const bool is_first = pos == BufferCoord{0,0};
        if (not m_scroll and (is_first or m_had_trailing_newline))
            pos = m_buffer.next(pos);

will read uninitialized "m_had_trailing_newline".  Fix that too, to
be on the safe side. Sadly I don't have a test for this one either
so I'm not sure.
2024-02-18 10:14:17 +11:00
Johannes Altmanninger
a85b81e08a test tools patch: disable when perl is missing
This failed on freebsd_gcc task in
Cirrus because Perl is not installed, see
https://github.com/mawww/kakoune/pull/5101/checks?check_run_id=21604156722
2024-02-18 10:05:55 +11:00
Johannes Altmanninger
7a86602ff8 Fix edit-fifo-noscroll test on BSD
This has been failing on FreeBSD sourcehut CI, for example
https://builds.sr.ht/~mawww/job/1151241
2024-02-18 09:58:53 +11:00
Yukai Huang
d987dadda0
Yukai Huang Copyright Waiver
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.
2024-02-15 18:23:55 +08:00
Yukai Huang
97a50a2352
pass pane-id to wezterm cli 2024-02-15 18:22:10 +08:00
Johannes Altmanninger
e1fd2351e0 rc git.kak: fix blame-jump for commits with special characters
Commit 53d9b9b67 (Escaping tweak in git.kak, 2024-02-06) broke
blame-jump when the commit subject contains a single quote.
(Also on unbalanced "{" which is a rare edge case but we already have
it in our Git history.)
git.kak assumes that filenames don't contain ' or unbalanced {,
but we can't really make that assumption about people's names or
commit subjects.

Unfortunately the escaping here is very messy. We need to pass
arbitrary text to callbacks; maybe we should have closures that can
capture private temporary registers.
2024-02-13 19:24:24 +11:00
Johannes Altmanninger
b838d58e1a rc tools git: quote $kak_buffile for add/rm
Our "git add" and "git rm" default to the current file.  The shell
interprets globs in the filename, which can lead to surprising results,
for example if it's accidentally used on a scratch buffer like *git*.
2024-02-12 19:57:45 +11:00
Maxime Coste
4101e18144 Early reject regex instructions that were already scheduled this step 2024-02-12 08:08:16 +11:00
Maxime Coste
e0c7a34bc1 Use unicode is_word/to_{lower/upper} function in ranked match 2024-02-12 07:50:04 +11:00
Maxime Coste
bd91a255e4 Do not decode utf8 while looking for next regex match start candidate
If the first byte in the multi-byte utf8 sequence does not match,
it means the "other" character is not set, so none of the sequence
byte will match (as they are all with the MSB set). This tightens
the critical loop which ends up running faster in most cases.
2024-02-11 12:17:21 +11:00
Maxime Coste
8d60e19484 Merge remote-tracking branch 'arachsys/balance' 2024-02-10 21:59:38 +11:00
Maxime Coste
cf95043b14 Merge remote-tracking branch 'krobelus/changelog' 2024-02-10 21:55:09 +11:00
Maxime Coste
dbefadeb0f Merge remote-tracking branch '4hnme/master' 2024-02-10 21:53:17 +11:00
Maxime Coste
857760ae60 Merge branch 'functionbeforemeta' of https://github.com/chriselrod/kakoune 2024-02-10 21:52:19 +11:00
Chris Elrod
ed9ecf9abc
Move function before meta so meta applies after function for @foo(ex) pattern, and add Cvoid to types 2024-02-08 17:46:35 -05:00
Maxime Coste
3ef68188b4 Avoid iswlower, iswupper, towlower and towupper for ascii codepoints
Avoid the costly shared object function call when most codepoints
will be ascii.

The regex benchmark gets a nice speedup:

Regex                                   Before     After
--------------------------------------+----------+---------
'Twain'                               |    25 ms | 15 ms
'(?i)Twain'                           |    74 ms | 57 ms
'[a-z]shing'                          |   323 ms | 303 ms
'Huck[a-zA-Z]+|Saw[a-zA-Z]+'          |    26 ms | 17 ms
'\b\w+nn\b'                           |   424 ms | 393 ms
'[a-q][^u-z]{13}x'                    |   869 ms | 815 ms
'Tom|Sawyer|Huckleberry|Finn'         |    33 ms | 24 ms
'(?i)Tom|Sawyer|Huckleberry|Finn'     |   319 ms | 281 ms
'.{0,2}(Tom|Sawyer|Huckleberry|Finn)' |  1294 ms | 1293 ms
'.{2,4}(Tom|Sawyer|Huckleberry|Finn)' |  1470 ms | 1429 ms
'Tom.{10,25}river|river.{10,25}Tom'   |    69 ms | 61 ms
'[a-zA-Z]+ing'                        |   447 ms | 408 ms
'\s[a-zA-Z]{0,12}ing\s'               |   539 ms | 543 ms
'([A-Za-z]awyer|[A-Za-z]inn)\s'       |   588 ms | 552 ms
'["'][^"']{0,30}[?!\.]["']'           |    92 ms | 81 ms
2024-02-06 22:16:08 +11:00
Maxime Coste
04a96b059f Use different hash algorithms for strings and file hashing
For hash map, using fnv1a is faster as it is a much simpler algorithm
we can afford to inline. For files murmur3 should win as it processes
bytes 4 by 4.
2024-02-06 21:57:17 +11:00
Maxime Coste
53d9b9b676 Escaping tweak in git.kak 2024-02-06 20:50:14 +11:00
Maxime Coste
707904a91b Avoid calling iswalnum for ascii characters
iswalnum can be pretty expensive as its a shared library call.
2024-02-06 20:47:59 +11:00
Johannes Altmanninger
c97add7f5a rc tools git: blame-jump to handle buffer modifications since blame
If I run

    git blame
    execute-keys 10o<esc>,j
    git blame-jump

that'll jump to the wrong commit.

Use a flag-lines option to tell if a line still has blame information
cached.

Closes #5084
2024-02-05 21:42:02 +11:00
Johannes Altmanninger
7cea09d327 Changelog entries for new blame features 2024-02-05 21:42:02 +11:00
Johannes Altmanninger
4e13fbef0a rc tools git: support blame in git-diff and git-log buffers
Today we can recursively search history with "git blame-jump". However
that command has some drawbacks, mainly that it's blocking. Making
it async without any progress indicator might be confusing. Better
to run plain "git blame"[1] and press Enter.

Also it might be nice to enable recursive searches using only "git
blame" and `<ret>` (since that is bound to "git blame-jump" while
blame annotations are displayed).

Make "git blame" in git-diff/git-log buffers run "git show
$commit:$file" for the commit and file at cursor, and decorate this
blob view with blame annotations. The latter allows to use `<ret>`
and repeat.

Unfortunately this relies on a hidden option "git_blob" to keep the
commit ID and filename. Maybe we can put this metadata somewhere
else like the buffer name or contents, ideally in a way that survives
serialization.

I'd still keep "git blame-jump" because it seems faster for the common
case of tracking down a single line.

[1]: In my testing, "git blame --incremental" is not any slower than
"git blame -L123,123" at finding that line.
2024-02-05 21:42:02 +11:00
Johannes Altmanninger
24bf123503 rc tools git: while blame annotations are shown, map <ret> to "git blame-jump"
Running git blame signals intent to view the blamed commit.  Let's make
`<ret>` to go to that commit+line as long as blame info is shown.

In diff buffers we already use `<ret>` for "diff-jump".

Like blame annotations, the blame-jump mapping lives in window scope.
This means it will not collide with "diff-jump" which is mapped in
buffer scope.

Add the mapping synchronously (unlike the rest of the git-blame code)
to perhaps allow the user to override the mapping:

    git blame; map window normal <ret> ...
2024-02-05 21:42:02 +11:00
Johannes Altmanninger
86d940c225 rc tools git: command for easy recursive blaming
Our ":git blame" annotates each line with the most recent commit.
However often a line has been modified by several commits.

Introduce ":git blame-jump" which shows the commit that added the
line at cursor. Crucially, it works also in Git diff buffers, so it
can be used recursively to find the full history of a line.

To do the recursive blame from a diff, I need to navigate to the
old (deleted) version of a line. Since old and new line are usually
neighbors. Speed up the common scenario of finding the old version
by making ":git blame-jump" jump to the new version. This means the
initial diff view might not include the commit message etc. Compensate
this by showing the commit's date+author+subject in the status line.

Here are some test cases.
- run blame-jump after "git blame"
- create an uncommitted or unsaved line, run "git blame" and
  "blame-jump" on the uncommitted line
- run blame-jump without running "git blame"
- run blame-jump in "git show"
- run blame-jump in "git diff HEAD"
- run blame-jump in "git diff --cached"
- run blame-jump in "git diff" (YMMV if there are cached changes,
  could fix that)

Naming: there are some similar commands in the wild [1];
they are usually called "show-blamed" or similar, but they
don't jump to the corresponding line.  Also our list of git
commands is getting a bit messy (especially the undocumented
show-diff/hide-diff/next-hunk/prev-hunk; subject first naming seems
better).

[1]: f6e78ec4c0/kakrc (L423)

Future work: to go back to the previously-blamed commit we need to
have had the foresight to use "rename-buffer". Perhaps we want to
add some kind of buffer stack (like Magit does for example).
2024-02-05 21:42:02 +11:00
Johannes Altmanninger
36efbf4cbf rc filetype diff: extract diff parsing from diff-jump
Most diff consumers we've written only care about the "final" state
after parsing through a diff. Let's extract the diff parsing part,
for reuse in several new commands.

In future we should try to use this (or better, a diff-parsing library)
for patch-range.pl. We'd add a callback argument that is invoked once
perl hunk (or line). Unfortunately I haven't found that library for
Perl yet.
2024-02-05 21:42:02 +11:00
Johannes Altmanninger
ce7ceb1cf0 rc tools git: detect filetype=git-diff for untracked diff buffers
On untracked diff buffers, it might be useful to make the upcoming
blame features work.

This is experimental, I might drop it.
2024-02-05 21:42:02 +11:00
Johannes Altmanninger
d6b75ac0bb rc tools git: change git diff filetype from diff to git-diff
Diff buffers created by ":git diff" differ from other filetype=diff
buffers in that they use "git rev-parse --show-toplevel" as root
directory for diff-jump. This makes sense because paths printed by
"git diff" are relative to that directory.

Today we handle the above difference by making ":git" override the
diff-jump mapping.  This doesn't work for buffers that were read from
a file.  Fix this by introducing a separate filetype, "git-diff",
which allows to move the mapping in the usual place.

This breaks existing filetype=diff hooks[1] which need to be adapted
to match git-diff (also git-log).

Another motivation for the separate filetype is that a following
patch wants to enable Git blame commands in git-diff buffers but
not in plain diff buffers -- those should keep being blamed like any
other file if tracked by Git.
Perhaps git-* buffers are for Git metadata, not files that are tracked
by Git.

The added hooks awkwardly include their hook parameter to work around
hook ordering issues when switching between filetypes. See also [2].

We could also use filetype=git-log instead of git-diff.
Our highlighting for "git log --graph" would have rare false positives.

Closes #5049

[1]: https://github.com/search?utf8=%E2%9C%93&q=filetype%3Ddiff+language%3Akakounescript+-repo%3Amawww%2Fkakoune+-is%3Afork&type=code
[2]: https://lists.sr.ht/~mawww/kakoune/%3C20240201091907.973508-1-aclopte@gmail.com%3E
2024-02-05 21:42:02 +11:00
Johannes Altmanninger
7a5bf7f649 rc tools git: remove unused dependency on diff from status/show-branch 2024-02-05 21:42:02 +11:00
Johannes Altmanninger
da1adc9b94 rc tools git: blame buffer contents, not on-disk file
When a buffer has unsaved deleted/added lines, then any blame
annotations below those lines may be off. Fix this by feeding the
latest buffer contents to Git.  Unfortunately there is no easy way
to distinguish between "Unsaved" and "Saved but not committed yet"
so let's keep using the umbrella term.
2024-02-05 21:42:02 +11:00
Johannes Altmanninger
c2c978907f rc tools patch: figure out path to patch-range.pl without double-parsing
We double-parse a command definition to figure out the location of
a support script at load time. This feels a bit dangerous and is not
really necessary, so use %val{runtime}/rc/tools/... instead.

Reference: https://lists.sr.ht/~mawww/kakoune/%3CZbOSCK2JjJvo-RTt@gmail.com%3E
2024-02-01 20:41:01 +11:00
Johannes Altmanninger
582c3c56b2 Do not add trailing newline to non-scrolling fifo buffers
Internally, all lines have a trailing "\n".
Buffers created empty (like fifo buffers) start with a single line.

When reading data into fifo buffers, we insert *before* the last line's
trailing newline ("last newline").  This enables autoscrolling (enabled
with "edit -scroll") as long as the cursor is on the last newline.

When autoscrolling is disabled, we have a special case to insert
*after* the last newline.  This means that a cursor on that newline
won't be moved.  Then we transplant the newline character from the
beginning to the end of the buffer. This special case happens only on
the very first fifo read; on subsequent reads, the cursor at position
1.1 will not be moved anway because insertions happen below 1.1.

Since we always insert (effectively) before the last newline, fifo
buffers have a trailing empty line.

For autoscrolling buffers this seems correct; it gives users an
obvious way to toggle autoscrolling.

For non-scrolling buffers the newline is redundant.  Remove it.
This requires keeping track of whether the last newline comes from
the fifo, or was added by us.  The shortest fix I could find
is to always append to the buffer if not scrolling, and then delete
the added newline character if applicable.

    m_buffer.insert(m_scroll ? pos : m_buffer.next(pos), StringView(data, data+count));
    if (not m_scroll and not m_had_trailing_newline)
        m_buffer.erase(pos, m_buffer.next(pos));

maybe that's the best fix overall; but erasing at the end seems better
than erasing in the middle, so do that whenever possible.

Reported in https://lists.sr.ht/~mawww/kakoune/%3CZbTK7qit9nzvrMkx@gmail.com%3E
2024-01-30 08:24:27 +11:00
Johannes Altmanninger
fdbad4d9b2 Test to demonstrate fifo buffer blank line inconsistency
When "edit -fifo" reads data without a trailing newline, the fifo
buffer will not have a trailing blank line. But if there is a trailing
newline, we will get a trailing blank line. This is weird because the
trailing blank line exists for scrolling, it should not be determined
by the data read.

Add a test case to demonstrates the inconsistency which is fixed by
the next patch.
2024-01-30 08:23:59 +11:00
Maxime Coste
c124c8f517 Support -after switch for flag-lines highlighter 2024-01-30 08:20:13 +11:00
4hnme
68ab2f2e7f 4hnme Copyright Waiver
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.
2024-01-27 17:08:41 +06:00
4hnme
8d30efb109 Ocaml filetype handling improvements
Manage indentation when creating a new line in Ocaml files
2024-01-26 23:51:20 +06:00
Johannes Altmanninger
2c944f6415 rc patch.kak: fix quoting
I learned that

    $ foo="'1

    2'"
    $ echo $foo
    '1 2'

Quote some variables to avoid this double unescaping.
2024-01-26 10:05:55 +11:00
Johannes Altmanninger
11e7e2964c rc tools patch: skip patch message signature, fixing diff application
Patches as produced by "git format-patch" have a trailing signature
that is separated from the body by a line with "-- " on it.  By default
it contains the Git version.  We erroneously include this signature
in the diff we pipe to patch, which fails to apply as a result.

Add a targeted fix to suppress these signatures.
2024-01-26 09:55:52 +11:00
Johannes Altmanninger
c7eeb0ead5 rc tools git: suggest -3/--3way argument to git apply
Sometimes a patch that fails to apply will apply cleanly after
adding -3.  Also sometimes we do want to apply with conflict markers.
So this is another somewhat common option.
2024-01-26 09:52:01 +11:00
Johannes Altmanninger
6eb3d1baf5 rc tools git: fix regression hiding blame in large files
Sorry I did not test my earlier patch in production.  It passes
blame flags via the environment.  On a 5000 line file this results in
"execve failed: Argument list too long" errors.

Use a different way of checking whether blame info is shown.
2024-01-23 08:16:16 +11:00
Johannes Altmanninger
52bf8d343b README.asciidoc: fix markup for sourcehut builds banner
Fixes the rendering on github.
2024-01-23 08:15:07 +11:00
Maxime Coste
1194aa861e Merge remote-tracking branch 'krobelus/patch-context-only-filediff' 2024-01-22 20:23:52 +11:00
Maxime Coste
a500d27ef1 Merge remote-tracking branch 'krobelus/git-blame-toggle' 2024-01-22 20:23:49 +11:00
Maxime Coste
f535c37aae Build README for Sourcehut 2024-01-22 20:23:45 +11:00
Johannes Altmanninger
1276e67ef7 rc tools patch: skip spurious diff header for files with no changes
Since :patch transforms its inputs into context-only lines, we can
easily get into a state where a file diff has only context lines.
git apply does not accept a "diff" without any hunk, so let's skip
that.
2024-01-22 07:02:31 +01:00
Johannes Altmanninger
462bf9ff6a rc tools git: blame to hide blame if already shown
This simplifies the UI (no need to add multiple mappings) and might
obsolete hide-blame.
2024-01-21 13:01:28 +01:00
Johannes Altmanninger
6b03f4dc4f rc tools git: remove redundant try
These commands must never fail.
2024-01-21 13:01:28 +01:00
Maxime Coste
869e89b3e5 Add builds.sr.ht configurations
Build and test (using both clang and gcc) on Debian stable x86_64,
FreeBSD and Debian unstable arm64.
2024-01-21 16:04:37 +11:00
Maxime Coste
5ea5c99c58 Fix using invalid strings for undo content strings
The code was wrongly using the write_it instead of the read_it to
access the removed lines content.

Fixes #5088
2024-01-21 10:24:08 +11:00