These actions complete the current command line with the last token of
the previous/next command in history. They are bound to "Alt+." and
"Alt+>"/"Alt+" (which is "Alt+Shift+." on QWERTY/QWERTZ).
Example:
% echo "hello world"
% folder=/tmp/folder
% mkdir $folder
% cd $folder
% mv ~/Downloads/x .
% echo folder=$folder
% echo [Alt+.]
On pressing "Alt+." multiple times, the current command line will be
completed to
% echo folder=$folder
% echo .
% echo $folder
% echo hello world
The duplicate $folder token will be skipped. "folder=/tmp/folder" will
be skipped as well (because there are no arguments). "hello world" will be
considered one token (using made::split_sh).
Possible TODO's:
- "hello world" it is inserted without quotes. made::sh_escape could be
used to escape the space but this would also escape the "$" in
"$folder". Maybe made::split_sh can be modified to optionally return
tokens including surrounding quotes.
- IMO, these actions should iterate over all arguments not only the last
one of every command. This would require to modify made::split_sh to
optionally return a token with a requested index.
---
made/actions.ha | 47 +++++++++++++++++++++++++++++++++++++++++++++++made/hist.ha | 1 +made/line.ha | 4 ++++made/types.ha | 1 +
4 files changed, 53 insertions(+)
diff --git a/made/actions.ha b/made/actions.ha
index 10f8021..dea1b2f 100644
--- a/made/actions.ha+++ b/made/actions.ha
@@ -2,6 +2,7 @@ use bufio;
use io;
use strings;
use sort;
+use crypto;// Pull new lines from other madeline instances into the in-memory history
fn update_hist(s: *state) (void | error) = {
@@ -53,6 +54,52 @@ fn histdown(s: *state) (void | error) = {
};
};
+fn histtokenup(s: *state) (void | error) = {+ update_hist(s)?;+ let h = &s.ctx.hist;+ if (s.mode == mode::NORMAL) {+ if (len(h.our_hist) == 0) return;+ h.htokidx = len(h.our_hist);+ s.buftyped = s.buf;+ };+ if (s.mode == mode::SEARCH) return;+ s.mode = mode::HIST;+ for (h.htokidx > 0) {+ h.htokidx -= 1;+ let (token, count) = s.ctx.split.split(h.our_hist[h.htokidx]);+ if (count == 0) continue; // command only, no arguments+ let tempbuf = strings::concat(strings::fromutf8(s.buftyped)!, token);+ defer free(tempbuf);+ let newbufutf8 = strings::toutf8(strings::dup(tempbuf));+ if (crypto::compare(s.buf, newbufutf8)) continue;+ s.buf = newbufutf8;+ s.pos = len(s.buf);+ break;+ };+};++fn histtokendown(s: *state) (void | error) = {+ if (s.mode != mode::HIST) return;+ update_hist(s)?;+ let h = &s.ctx.hist;+ for (h.htokidx < len(h.our_hist) - 1) {+ h.htokidx += 1;+ let (token, count) = s.ctx.split.split(h.our_hist[h.htokidx]);+ if (count == 0) continue; // command only, no arguments+ let tempbuf = strings::concat(strings::fromutf8(s.buftyped)!, token);+ defer free(tempbuf);+ let newbufutf8 = strings::toutf8(strings::dup(tempbuf));+ if (crypto::compare(s.buf, newbufutf8)) continue;+ // update command line with new token+ s.buf = newbufutf8;+ s.pos = len(s.buf);+ return;+ };+ s.buf = s.buftyped;+ s.pos = len(s.buf);+ s.mode = mode::NORMAL;+};+fn complete(s: *state) void = {
freecompletions(s);
s.completions = s.ctx.complete(s.ctx, s.buf, s.pos);
diff --git a/made/hist.ha b/made/hist.ha
index 7f867bd..04ddaf4 100644
--- a/made/hist.ha+++ b/made/hist.ha
@@ -13,6 +13,7 @@ export type history = struct {
hist: []str,
our_hist: []str,
hidx: size,
+ htokidx: size,};
// Stores [[history]] in memory without a backing handle.
diff --git a/made/line.ha b/made/line.ha
index a66600d..ebbfebd 100644
--- a/made/line.ha+++ b/made/line.ha
@@ -138,6 +138,10 @@ export fn line(ctx: *context) (str | void | io::EOF | error) = {
kill(&s, &prevword, false);
case 'y' => // alt+y
unkill(&s, false);
+ case '.' => // alt+.+ histtokenup(&s)?;+ case '>', ':' => // alt+shift+.+ histtokendown(&s)?; case '\x0a', '\x0d' => // alt+enter
appendstr(&s, "\n");
case => void;
diff --git a/made/types.ha b/made/types.ha
index 8359903..15cad42 100644
--- a/made/types.ha+++ b/made/types.ha
@@ -20,6 +20,7 @@ type state = struct {
in: io::file,
out: io::handle,
buf: []u8,
+ buftyped: []u8, // typed manually, without token completion pos: size,
mode: mode,
completions: (str, [](str, str)),
--
2.42.0