Commit Graph

5515 Commits

Author SHA1 Message Date
Maxime Coste
2cbcdf2fb4 Merge remote-tracking branch 'krobelus/write-autoinfo2' 2022-10-19 20:23:18 +11:00
Maxime Coste
ae6ee02cb2 Refactor insert_output command to avoid intermediate vector
This is like a paste with a different source, so the same logic
should work. This means we now correctly fix overflowing selections.

Fixes #4750
2022-10-19 20:16:09 +11:00
Maxime Coste
d1ac4dbff3 Remove unused History MemoryDomain 2022-10-19 20:16:09 +11:00
Maxime Coste
287217b987 Fix splitting of display atoms accross multi-columns codepoint
Honor the split request by inserting an empty atom to make sure
client code can assume splitting does replace one atom with two

Fixes #4753
2022-10-17 17:48:39 +11:00
Johannes Altmanninger
91c43c0f67 Allow to put switches after :write's positional argument
After a failed

	:write file-that-already-exists

a user might want to type ":<up> -f<ret>" to force-overwrite.
This doesn't work because :write's switches must precede the filename.
It's dual :edit does not have this restriction.

Some commands require switches to precede positional arguments for a
good reason; for example because positional arguments might start with
"-" (like ":echo 1 - 1").

There seems to be no reason for the :write restriction, so remove
it. Same for :enter-user-mode.

Thanks to alexherbo2 for reporting.
2022-10-16 19:49:43 +02:00
Maxime Coste
360a6847be Merge remote-tracking branch 'vsyl/c_description' 2022-10-11 20:39:10 +11:00
Jakub Wasilewski
69f4d1261b Correct and unify descriptions of normal mode C key behavior
Fixes #4747
2022-10-11 08:39:34 +02:00
Hampus Fröjdholm
18a84c6b3c Fix compilation failure with clang 12 and debug=yes
The pointer type alias was missing from FlattenedView::Iterator causing
std::iterator_traits to be an empty class.
2022-10-02 14:04:07 +02:00
Maxime Coste
24d6072353 Merge remote-tracking branch 'krobelus/faster-update-matches' 2022-09-17 20:16:14 +02:00
Johannes Altmanninger
803873c91c Fix quadratic runtime when updating region highlighter matches
Running %sYeti<ret>casdf on file
[example.journal.txt](https://github.com/mawww/kakoune/issues/4685#issuecomment-1193243588)
can cause noticeable lag.  This is because we insert text at 6000
selections, which means we need to update highlighters in those lines.
The runtime for updating range highlighters is quadratic in the
number of selections: for each selection, we call on_new_range(),
which calls add_matches(), which calls std::rotate(), which needs
needs linear time.

Fix the quadratic runtime by calling std::inplace_merge() once instead
of repeatedly calling std::rotate().  This is works because ranges
are already sorted.

I used this script to benchmark the improvements.
(In hindsight I could have just used "-ui json" instead of tmux).

	#!/bin/sh
	set -ex
	N=${1:-100}
	kak=${2:-./kak.opt}
	for i in $(seq "$N")
	do
		echo -n "\
	2022-02-06 * Earth
	    expense:electronics:audio    116.7 USD
	    liability:card              -116.7 USD

	2022-02-06 * Blue Yeti USB Microphone
	    expense:electronics:audio    116.7 USD
	    liability:card              -116.7 USD

	"
	done > big-journal.ledger
	echo > .empty-tmux.conf 'set -sg escape-time 5'
	test_tmux() {
		tmux -S .tmux-socket -f .empty-tmux.conf "$@"
	}
	test_tmux new-session -d "$kak" big-journal.ledger
	test_tmux send-keys '%sYeti' Enter c 1234567890
	sleep .2
	test_tmux send-keys Escape
	while ! test_tmux capture-pane -p | grep 123
	do
		sleep .1
	done
	test_tmux send-keys ':wq' Enter
	while test_tmux ls
	do
		sleep .1
	done
	rm -f .tmux-socket .empty-tmux.conf

This script's runtime used to grow super-linearly but now it grows
linearly:

	         kak.old  kak.new
	N=10000    1.142    0.897
	N=20000    2.879    1.400

Detailed results:

	$ hyperfine -w 1 './bench.sh 10000 ./kak.opt.'{old,new}
	Benchmark 1: ./bench.sh 10000 ./kak.opt.old
	  Time (mean ± σ):      1.142 s ±  0.072 s    [User: 0.252 s, System: 0.059 s]
	  Range (min … max):    1.060 s …  1.242 s    10 runs

	Benchmark 2: ./bench.sh 10000 ./kak.opt.new
	  Time (mean ± σ):     897.2 ms ±  19.3 ms    [User: 241.6 ms, System: 57.4 ms]
	  Range (min … max):   853.9 ms … 923.6 ms    10 runs

	Summary
	  './bench.sh 10000 ./kak.opt.new' ran
	    1.27 ± 0.09 times faster than './bench.sh 10000 ./kak.opt.old'
	$ hyperfine -w 1 './bench.sh 20000 ./kak.opt.'{old,new}
	Benchmark 1: ./bench.sh 20000 ./kak.opt.old
	  Time (mean ± σ):      2.879 s ±  0.065 s    [User: 0.553 s, System: 0.126 s]
	  Range (min … max):    2.768 s …  2.963 s    10 runs

	Benchmark 2: ./bench.sh 20000 ./kak.opt.new
	  Time (mean ± σ):      1.400 s ±  0.018 s    [User: 0.428 s, System: 0.083 s]
	  Range (min … max):    1.374 s …  1.429 s    10 runs

	Summary
	  './bench.sh 20000 ./kak.opt.new' ran
	    2.06 ± 0.05 times faster than '../repro.sh 20000 ./kak.opt.old'
2022-09-17 06:44:57 -05:00
Johannes Altmanninger
a33ec8dc80 Avoid potentially quadratic runtime when updating selections after modification
LineRangeSet::add_range() calls Vector::erase() in a loop over the
same vector. This could cause performance problems when there are many
selections. Fix this by only calling Vector::erase() once.  I didn't
measure anything because my benchmark is dominated by another issue
(see next commit).

LineRangeSet::remove_range() also has a suspicious call to erase()
but that one is only used in test code, so it doesn't matter.
2022-09-17 06:44:57 -05:00
Adrià Arrufat
f50ee5bb5a Fix crash when trying to display the menu in a tiny window 2022-09-17 00:51:34 +09:00
Maxime Coste
1a8f379a43 Merge remote-tracking branch 'krobelus/embrace-menu-3' 2022-09-09 17:10:53 +02:00
Maxime Coste
1831c4da4b Merge remote-tracking branch 'krobelus/to-string' 2022-09-09 17:03:59 +02:00
Maxime Coste
c428d3296d Merge remote-tracking branch 'krobelus/write-autoinfo' 2022-09-09 15:43:22 +02:00
Maxime Coste
1b4a6a03ee Merge remote-tracking branch 'krobelus/hashset-no-braces' 2022-09-09 15:40:08 +02:00
Maxime Coste
6828c9cb4d Merge remote-tracking branch 'krobelus/cleanup' 2022-09-09 15:37:48 +02:00
Johannes Altmanninger
1333fe21d0 Fix clang warning regarding useless braces when using HashSet
clang/clangd complain about the new HashSet type:

	hash_map.cc:98:20: warning: braces around scalar initializer [-Wbraced-scalar-init]
	        set.insert({10});
	                   ^~~~

The argument to HashSet<int>::insert is just an int, so we don't
need braces.  Only an actual HashMap would need braces to construct
a HashItem object.
2022-08-28 15:23:29 +02:00
Johannes Altmanninger
7ae31b6778 Show write -force parameter only for commands that support it
When passing a filename parameter to "write", the -force parameter
allows overwriting an existing file.
The "write!" variant (which allows writing files where the current
user does not have write permissions) already implies -force.
All other variants (like write-quit or write-all) do not take a
file parameter.
Hence -force is relevant only for "write".  Let's hide it from the
autoinfo of the other commands.

It's difficult to avoid duplication when constructing the constexpr
SwitchMap because String is not constexpr-enabled.  Today, all our
SwitchMap objects are known at compile time, so we could make SwitchMap
use StringView to work around this. In future we might want to allow
adding switches at runtime, which would need String again to avoid
lifetime issues.
2022-08-28 09:28:06 +02:00
Johannes Altmanninger
348b3f9d9d Fix synopsis of write-quit commands
Like other write commands, these support the -method switch, so
indicate that in the synopsis.
2022-08-24 22:21:06 +02:00
Maxime Coste
13a95b0ba0 Merge remote-tracking branch 'krobelus/set-remove-autoinfo' 2022-08-21 18:38:28 +02:00
Maxime Coste
d076c033e7 Avoid calling memcpy from empty string views
ubsan is unhappy when passing a nullptr as the source pointer to
memcpy even if the length is 0.

Fixes #4720
2022-08-21 17:52:51 +02:00
Maxime Coste
efa45f8bdd Bypass RegexIterator in RegionsHighlighter::add_matches 2022-08-21 10:25:51 +02:00
Maxime Coste
021da117cf Add support for field width and digit grouping in format 2022-08-20 11:03:03 +02:00
Maxime Coste
0c1d4808fa Slight code style tweak 2022-08-20 11:03:03 +02:00
Maxime Coste
21047db4a0 Remove unnecessary utf8 decoding when looking for EOL in regex 2022-08-20 11:03:03 +02:00
Maxime Coste
c8c8051bd0 Refactor RegionsHighlighter to share regexes
Instead of storing regexes in each regions, move them to the core
highlighter in a hash map so that shared regexes between different
regions are only applied once per update instead of once per region

Also change iteration logic to apply all regex together to each
changed lines to improve memory locality on big buffers.

For the big_markdown.md file described in #4685 this reduces
initial display time from 3.55s to 2.41s on my machine.
2022-08-20 11:02:59 +02:00
Johannes Altmanninger
d324e506e3 Use make_array to avoid specifying the array size
When I wrote this line I wanted to avoid adding the array size but
I didn't know about make_array().

I had unsuccessfully tried some alternatives, for example

	Array{"a", "b", "c"}

which doesn't work because we need StringView (c.f. git blame on
this line)

also

	Array<StringView>{"a", "b", "c"}

doesn't work because it's missing a template argument.
2022-08-17 00:42:12 +02:00
Johannes Altmanninger
0eb4e68c40 Rename button_to_str() to the more idiomatic to_string()
Analogous to the parent commit.

This returns StringView, but it's immortal so it's even better
than String.
2022-08-17 00:38:58 +02:00
Johannes Altmanninger
01f3d7cbda Rename key_to_str() to the more idiomatic to_string()
This makes the function easier to find for newcomers because
to_string() is the obvious name. It enables format() to do the
conversion automatically which seems like good idea (since there is
no other obvious representation).

Of course this change makes it a bit harder to grep but that's not
a problem with clang tooling.

We need to cast the function in one place when calling transform()
but that's acceptable.
2022-08-17 00:38:58 +02:00
Johannes Altmanninger
08ea6d07e4 Remove stale comment about StaticRegister
Commit d470bd2cc (Make numeric registers setable, 2017-02-14) removed
the user-provided StaticRegister::operator= in favor of a set()
member function, so this comment is no longer valid.
2022-08-16 19:15:22 +02:00
Maxime Coste
ca71d8997d Reuse existing character classes when possible in regex 2022-08-05 20:31:39 +10:00
Maxime Coste
26d14d52bb uniquify selection contents before generating regex for '*'
Avoid generating regex with the same alternative repeated multiple
times.
2022-08-05 20:10:11 +10:00
Maxime Coste
89cd3c52eb Add HashSet implemented as HashMap with void value type 2022-08-05 20:06:34 +10:00
Maxime Coste
9fb7d90449 Change HashMap not to support multiple identical keys by default
We do not seem to have any uses for this remaining, and this is
better opt-in with MultiHashMap
2022-08-05 19:20:00 +10:00
Maxime Coste
31e9fc3cef Merge remote-tracking branch 'krobelus/history-in-mappings' 2022-08-03 20:37:44 +10:00
Maxime Coste
fa209a9a97 Merge remote-tracking branch 'krobelus/document-history-registers' 2022-08-03 19:51:22 +10:00
Johannes Altmanninger
e13b435783 Do not complete command switches after --
Recently, switch completion were given the menu behavior.
Unfortunately this breaks cases like

	:echo -- -mark<ret>

where the hypothetical user wanted to actually display "-mark", not
"-markup".

Simply bail if there is a double-dash. This is not fully correct,
for example it wrongly disables switch completion on

	echo -to-file -- -

but that's minor, we can fix it later.

In future, we should reuse the ParametersParser when computing completions,
which will obsolete this workaround.
2022-08-01 12:34:22 +02:00
Johannes Altmanninger
a36473f4bb Do not record prompt history when executing user mode mappings
Commit 217dd6a1d (Disable history when executing maps, 2015-11-10)
made it so with

	map global normal X %{:echo 123<ret>}

X does not add to prompt history (%reg{:}).

Unfortunately this behavior was not extended to mappings in the "user"
keymap, nor to mappings in custom user modes.
In my experience, not adding to history is almost always the expected
behavior for mappings. Most users achieve this by adding a leading space:

	map global user X %{: echo 123<ret>}

but that's awkward. We should have good defaults (no nnoremap)
and map should work the same way across all modes.

Fix this by also disabling history when executing user mappings. This
is a breaking change but I think it only breaks hypothetical scenarios.

I found some uses where user mappings add to history but none of them
looks intentional.

f702a641d1/.config/kak/kakrc (L169)
604ef1c1c2/kakrc (L96)
d22e7d6f68/kak/kakrc (L71)
https://grep.app/search?q=map%20%28global%7Cbuffer%7Cwindow%29%20user%20.%2A%5B%21%3A/%5D%5B%5E%20%5D.%2A%3Cret%3E&regexp=true
2022-08-01 07:37:02 +02:00
Johannes Altmanninger
253b13281e Show the default values for -save-regs in autoinfo of exec/eval
They are documented in ":doc execeval" but it seems like a good idea
to make this info more prominent.
2022-08-01 07:15:08 +02:00
Johannes Altmanninger
d999a00b0c Fix typo in eval/exec code
Will touch similar code
2022-08-01 07:15:08 +02:00
Johannes Altmanninger
031de6d28c Use menu behavior for completing builtins where appropriate
This allows to select completions without pressing Tab.

There are two different obvious ways to add the menu bit.
1. When creating the "Completions" object, pass the
   Completions::Flags::Menu parameter.
2. If there is a completer function like "complete_scope", wrap
   it, e.g. "menu(complete_scope)".

I have settled on always using 2 if there is a completer function
and 1 otherwise.
The advantage of 2 over 1 is that it allows to use the completer
function in a context where we don't want the menu behavior
(e.g. "complete-command").

---

Now the only* completion type where we usually don't use menu behavior
is file completion. Unfortunately, menu behavior has poor interaction
with directories' trailing slashes. Consider this (contrived) example:

	define-command ls -docstring "list directory contents" -params .. %{
		echo -- %sh{ls "$@"}
	}
	complete-command -menu ls file

Run ":ls kakoun<ret>".  The prompt expands to ":ls kakoune/"
before executing. Next, run ":<c-p>".  This recalls ":ls kakoune/"
and immediately selects the first completion, so on validation,
the command will be ":ls kakoune/colors/", which is weird.

[*] Also, expansions like %val{bufname} also don't use menu
behavior.  It wouldn't add value since validation doesn't add a
closing delimiter. I have an experimental patch that adds closing
delimiters automatically but I'm not sure if that's the right
direction.
2022-07-30 22:17:32 +02:00
Johannes Altmanninger
69053d9623 Use menu behavior when completing change-directory
This makes "cd<space><ret>" change to the first completion,
not to $HOME.  This might be surprising but it should make sense.
I don't have a concrete motivation but this should save a Tab press
in some scenarios.
2022-07-28 15:10:28 +02:00
Johannes Altmanninger
a1715a0c41 Use menu behavior when completing scope arguments
We allow to abbreviate scopes ("set g" means the same thing as "set
global") but that feature is a bit obscure.  Users might figure out the
menu completion behavior faster, so let's maybe use it here as well?
2022-07-28 15:10:28 +02:00
Johannes Altmanninger
5aa0241124 Use and extract functions for completing scope arguments
Not really attached to this but it enables the next commit to use
menu() for completing scopes.

This refactoring is possible because we always have

	params[token_to_complete].length() == pos_in_token

---

Instead of three separate functions, I originally tried to add
template arguments to complete_scope().  That worked fine with g++
12.1 but clang 14.0 complained when wrapping a menu() around a
complete_scope() that relied on defaulted template arguments:

	commands.cc:1087:20: error: no matching function for call to 'menu'
	    make_completer(menu(complete_scope), menu(complete_hooks), complete_nothing,
	                   ^~~~
	commands.cc:116:6: note: candidate template ignored: couldn't infer template argument 'Completer'
	auto menu(Completer completer)
	     ^
2022-07-28 15:10:28 +02:00
Johannes Altmanninger
23fcf77160 Fix autoinfo for "set-option -remove" not showing option-specific info
On a command prompt like

	"set-option -remove buffer aligntab "

we fail to show the aligntab-specific info . Fix this by skipping a
leading -remove, just like we skip -add.

Add an explicit specialization of contains() because otherwise I'd
need to write something like

	contains(Array{"-add", "remove"}, param)
2022-07-28 15:02:20 +02:00
Johannes Altmanninger
4b6abfaedf Remove redundant handling of "-add" from set-option completer
Switches are removed before invoking a command's completer (look for
"std::not_fn(is_switch)". Remove completer code that attempts to
handle switches.
2022-07-28 14:02:20 +02:00
Maxime Coste
e83dbdcd2c Merge remote-tracking branch 'krobelus/embrace-menu-2' 2022-07-28 21:34:31 +10:00
Maxime Coste
79ff3c29e5 Merge remote-tracking branch 'krobelus/support-prompt-menu' 2022-07-28 21:33:07 +10:00
Maxime Coste
99874a1e25 Merge remote-tracking branch 'krobelus/prompt-completion-cut-at-cursor' 2022-07-28 21:29:21 +10:00