patches/klish: restore some common keybindings for line manipulation

This restores some of the original keybindings for line manipulation
that was part of the original CLISH.  They had been disabled upstream
during the UTF8 conversion and never got reimplemented.

From branch kkit on https://github.com/kernelkit/klish, the kkit branch
is based off of the 3.0.0 release.  The same patches are also available
on kkit-next, which is based on the latest upstream master.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
Joachim Wiberg
2023-08-08 16:35:18 +02:00
committed by Tobias Waldekranz
parent 30a28fe874
commit 142f33e89e
5 changed files with 520 additions and 0 deletions
@@ -0,0 +1,71 @@
From 8b95602d5111e736854447c0c75004a45b678812 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Wed, 12 Jul 2023 10:28:32 +0200
Subject: [PATCH 3/7] tinyrl: use std wint_t instead of unisigned long
Organization: Addiva Elektronik
This allows us to use wctype.h functions like iswspace() later.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
tinyrl/tinyrl/private.h | 3 ++-
tinyrl/tinyrl/utf8.c | 7 ++++---
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/tinyrl/tinyrl/private.h b/tinyrl/tinyrl/private.h
index 90bcff9..1a23ea7 100644
--- a/tinyrl/tinyrl/private.h
+++ b/tinyrl/tinyrl/private.h
@@ -1,4 +1,5 @@
#include <termios.h>
+#include <wctype.h>
#include <faux/faux.h>
@@ -8,7 +9,7 @@
// UTF-8 functions
-ssize_t utf8_to_wchar(const char *sp, unsigned long *sym_out);
+ssize_t utf8_to_wchar(const char *sp, wint_t *sym_out);
bool_t utf8_wchar_is_cjk(unsigned long sym);
off_t utf8_move_left(const char *line, off_t cur_pos);
off_t utf8_move_right(const char *line, off_t cur_pos);
diff --git a/tinyrl/tinyrl/utf8.c b/tinyrl/tinyrl/utf8.c
index daa5878..0543e48 100644
--- a/tinyrl/tinyrl/utf8.c
+++ b/tinyrl/tinyrl/utf8.c
@@ -9,6 +9,7 @@
#include <ctype.h>
#include <errno.h>
#include <unistd.h>
+#include <wctype.h>
#include <faux/str.h>
@@ -21,11 +22,11 @@
* @param [out] sym_out Resulting wchar.
* @return Number of bytes for current UTF-8 symbol.
*/
-ssize_t utf8_to_wchar(const char *sp, unsigned long *sym_out)
+ssize_t utf8_to_wchar(const char *sp, wint_t *sym_out)
{
int i = 0;
int octets = 0; // Number of 0x10xxxxxx UTF-8 sequence bytes
- unsigned long sym = 0;
+ wint_t sym = 0;
const unsigned char *p = (const unsigned char *)sp;
if (sym_out)
@@ -226,7 +227,7 @@ ssize_t utf8_nsyms(const char *str, size_t len)
return -1;
while ((pos < (str + len)) && (*pos != '\0')) {
- unsigned long sym = 0;
+ wint_t sym = 0;
// ASCII char
if ((UTF8_7BIT_MASK & *pos) == 0) {
--
2.34.1
@@ -0,0 +1,66 @@
From d91dccba60d6d3def03647f899e4b7ab03e42e50 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Wed, 12 Jul 2023 10:29:54 +0200
Subject: [PATCH 4/7] tinyrl: add UTF8 support for Ctrl-W (backword)
Organization: Addiva Elektronik
Introduce local helper function for walking backwards on a line, UTF8
safe, so that we can restore the Ctrl-W keybinding.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
tinyrl/tinyrl/keys.c | 32 ++++++++++++++++++--------------
1 file changed, 18 insertions(+), 14 deletions(-)
diff --git a/tinyrl/tinyrl/keys.c b/tinyrl/tinyrl/keys.c
index 21de784..a99173f 100644
--- a/tinyrl/tinyrl/keys.c
+++ b/tinyrl/tinyrl/keys.c
@@ -230,26 +230,30 @@ bool_t tinyrl_key_delete(tinyrl_t *tinyrl, unsigned char key)
return BOOL_TRUE;
}
+static int is_prev_space(tinyrl_t *tinyrl)
+{
+ if (tinyrl->utf8) {
+ off_t new_pos = utf8_move_left(tinyrl->line.str, tinyrl->line.pos);
+
+ return iswspace(tinyrl->line.str[new_pos]);
+ }
+
+ return isspace(tinyrl->line.str[tinyrl->line.pos - 1]);
+}
bool_t tinyrl_key_backword(tinyrl_t *tinyrl, unsigned char key)
{
- bool_t result = BOOL_FALSE;
-/*
- // remove current whitespace before cursor
- while (tinyrl->point > 0 && isspace(tinyrl->line[tinyrl->point - 1]))
- tinyrl_key_backspace(tinyrl, KEY_BS);
+ (void)key;
- // delete word before cusor
- while (tinyrl->point > 0 && !isspace(tinyrl->line[tinyrl->point - 1]))
- tinyrl_key_backspace(tinyrl, KEY_BS);
+ // remove current whitespace before cursor
+ while (tinyrl->line.pos > 0 && is_prev_space(tinyrl))
+ tinyrl_key_backspace(tinyrl, KEY_BS);
- result = BOOL_TRUE;
-*/
- // Happy compiler
- tinyrl = tinyrl;
- key = key;
+ // delete word before cusor
+ while (tinyrl->line.pos > 0 && !is_prev_space(tinyrl))
+ tinyrl_key_backspace(tinyrl, KEY_BS);
- return result;
+ return BOOL_TRUE;
}
--
2.34.1
@@ -0,0 +1,127 @@
From 4d4ab6a88e61ccdc3802e15bf0c4c5254addaf98 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Wed, 12 Jul 2023 10:30:30 +0200
Subject: [PATCH 5/7] tinyrl: add support for Ctrl-k and Ctrl-u (kill) and
Ctrl-y (yank)
Organization: Addiva Elektronik
Standard (fine legacy) line editing functions for cut and paste.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
tinyrl/tinyrl/keys.c | 55 ++++++++++++++++++------------------------
tinyrl/tinyrl/tinyrl.c | 1 +
2 files changed, 24 insertions(+), 32 deletions(-)
diff --git a/tinyrl/tinyrl/keys.c b/tinyrl/tinyrl/keys.c
index a99173f..d912233 100644
--- a/tinyrl/tinyrl/keys.c
+++ b/tinyrl/tinyrl/keys.c
@@ -67,19 +67,19 @@ bool_t tinyrl_key_end_of_line(tinyrl_t *tinyrl, unsigned char key)
bool_t tinyrl_key_kill(tinyrl_t *tinyrl, unsigned char key)
{
-/*
+ size_t len;
+
+ (void)key;
+
// release any old kill string
- lub_string_free(tinyrl->kill_string);
+ faux_free(tinyrl->kill_string);
// store the killed string
- tinyrl->kill_string = lub_string_dup(&tinyrl->buffer[tinyrl->point]);
+ tinyrl->kill_string = strdup(&tinyrl->line.str[tinyrl->line.pos]);
- // delete the text to the end of the line
- tinyrl_delete_text(tinyrl, tinyrl->point, tinyrl->end);
-*/
- // Happy compiler
- tinyrl = tinyrl;
- key = key;
+ // delete the text to the end of the line
+ len = strlen(&tinyrl->line.str[tinyrl->line.pos]);
+ tinyrl_line_delete(tinyrl, tinyrl->line.pos, len);
return BOOL_TRUE;
}
@@ -87,18 +87,14 @@ bool_t tinyrl_key_kill(tinyrl_t *tinyrl, unsigned char key)
bool_t tinyrl_key_yank(tinyrl_t *tinyrl, unsigned char key)
{
- bool_t result = BOOL_FALSE;
-/*
+ (void)key;
+
if (tinyrl->kill_string) {
// insert the kill string at the current insertion point
- result = tinyrl_insert_text(tinyrl, tinyrl->kill_string);
+ return tinyrl_line_insert(tinyrl, tinyrl->kill_string, strlen(tinyrl->kill_string));
}
-*/
- // Happy compiler
- tinyrl = tinyrl;
- key = key;
- return result;
+ return BOOL_TRUE;
}
@@ -271,30 +267,25 @@ bool_t tinyrl_key_clear_screen(tinyrl_t *tinyrl, unsigned char key)
bool_t tinyrl_key_erase_line(tinyrl_t *tinyrl, unsigned char key)
{
-/* unsigned int end;
+ size_t len;
+
+ (void)key;
// release any old kill string
- lub_string_free(tinyrl->kill_string);
+ faux_free(tinyrl->kill_string);
- if (!tinyrl->point) {
+ if (!tinyrl->line.pos) {
tinyrl->kill_string = NULL;
return BOOL_TRUE;
}
- end = tinyrl->point - 1;
-
- // store the killed string
- tinyrl->kill_string = malloc(tinyrl->point + 1);
- memcpy(tinyrl->kill_string, tinyrl->buffer, tinyrl->point);
- tinyrl->kill_string[tinyrl->point] = '\0';
+ // store the killed string
+ len = strlen(tinyrl->line.str) + 1;
+ tinyrl->kill_string = malloc(len);
+ memcpy(tinyrl->kill_string, tinyrl->line.str, len);
// delete the text from the start of the line
- tinyrl_delete_text(tinyrl, 0, end);
- tinyrl->point = 0;
-*/
- // Happy compiler
- tinyrl = tinyrl;
- key = key;
+ tinyrl_reset_line(tinyrl);
return BOOL_TRUE;
}
diff --git a/tinyrl/tinyrl/tinyrl.c b/tinyrl/tinyrl/tinyrl.c
index 61ba97d..de93b7c 100644
--- a/tinyrl/tinyrl/tinyrl.c
+++ b/tinyrl/tinyrl/tinyrl.c
@@ -108,6 +108,7 @@ void tinyrl_free(tinyrl_t *tinyrl)
faux_str_free(tinyrl->prompt);
tinyrl_reset_line_state(tinyrl); // It's really reset 'last' string
faux_str_free(tinyrl->line.str);
+ faux_str_free(tinyrl->kill_string);
faux_free(tinyrl);
}
--
2.34.1
@@ -0,0 +1,137 @@
From 6e44dc48f5d61a46d4d25730c85a964c95a4db16 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Wed, 12 Jul 2023 11:11:20 +0200
Subject: [PATCH 6/7] tinyrl: add support for Ctrl-left and Ctrl-right (move by
word)
Organization: Addiva Elektronik
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
tinyrl/tinyrl/keys.c | 44 +++++++++++++++++++++++++++++++++++++++++
tinyrl/tinyrl/private.h | 2 ++
tinyrl/tinyrl/tinyrl.c | 6 ++++++
tinyrl/vt100.h | 2 ++
tinyrl/vt100/vt100.c | 2 ++
5 files changed, 56 insertions(+)
diff --git a/tinyrl/tinyrl/keys.c b/tinyrl/tinyrl/keys.c
index d912233..10ea6a3 100644
--- a/tinyrl/tinyrl/keys.c
+++ b/tinyrl/tinyrl/keys.c
@@ -237,6 +237,17 @@ static int is_prev_space(tinyrl_t *tinyrl)
return isspace(tinyrl->line.str[tinyrl->line.pos - 1]);
}
+static int is_next_space(tinyrl_t *tinyrl)
+{
+ if (tinyrl->utf8) {
+ off_t new_pos = utf8_move_right(tinyrl->line.str, tinyrl->line.pos);
+
+ return iswspace(tinyrl->line.str[new_pos]);
+ }
+
+ return isspace(tinyrl->line.str[tinyrl->line.pos + 1]);
+}
+
bool_t tinyrl_key_backword(tinyrl_t *tinyrl, unsigned char key)
{
(void)key;
@@ -252,6 +263,39 @@ bool_t tinyrl_key_backword(tinyrl_t *tinyrl, unsigned char key)
return BOOL_TRUE;
}
+bool_t tinyrl_key_left_word(tinyrl_t *tinyrl, unsigned char key)
+{
+ (void)key;
+
+ while (tinyrl->line.pos > 0 && is_prev_space(tinyrl))
+ tinyrl_key_left(tinyrl, key);
+
+ while (tinyrl->line.pos > 0 && !is_prev_space(tinyrl))
+ tinyrl_key_left(tinyrl, key);
+
+ return BOOL_TRUE;
+}
+
+bool_t tinyrl_key_right_word(tinyrl_t *tinyrl, unsigned char key)
+{
+ int adjust = 0;
+
+ (void)key;
+
+ while (tinyrl->line.pos < tinyrl->line.len && !is_next_space(tinyrl))
+ tinyrl_key_right(tinyrl, key);
+
+ while (tinyrl->line.pos < tinyrl->line.len && is_next_space(tinyrl)) {
+ adjust = 1;
+ tinyrl_key_right(tinyrl, key);
+ }
+
+ if (adjust)
+ tinyrl_key_right(tinyrl, key);
+
+ return BOOL_TRUE;
+}
+
bool_t tinyrl_key_clear_screen(tinyrl_t *tinyrl, unsigned char key)
{
diff --git a/tinyrl/tinyrl/private.h b/tinyrl/tinyrl/private.h
index 1a23ea7..370f8a6 100644
--- a/tinyrl/tinyrl/private.h
+++ b/tinyrl/tinyrl/private.h
@@ -30,6 +30,8 @@ bool_t tinyrl_key_right(tinyrl_t *tinyrl, unsigned char key);
bool_t tinyrl_key_backspace(tinyrl_t *tinyrl, unsigned char key);
bool_t tinyrl_key_backword(tinyrl_t *tinyrl, unsigned char key);
bool_t tinyrl_key_delete(tinyrl_t *tinyrl, unsigned char key);
+bool_t tinyrl_key_left_word(tinyrl_t *tinyrl, unsigned char key);
+bool_t tinyrl_key_right_word(tinyrl_t *tinyrl, unsigned char key);
bool_t tinyrl_key_clear_screen(tinyrl_t *tinyrl, unsigned char key);
bool_t tinyrl_key_erase_line(tinyrl_t *tinyrl, unsigned char key);
bool_t tinyrl_key_tab(tinyrl_t *tinyrl, unsigned char key);
diff --git a/tinyrl/tinyrl/tinyrl.c b/tinyrl/tinyrl/tinyrl.c
index de93b7c..2c83106 100644
--- a/tinyrl/tinyrl/tinyrl.c
+++ b/tinyrl/tinyrl/tinyrl.c
@@ -506,6 +506,12 @@ bool_t tinyrl_esc_seq(tinyrl_t *tinyrl, const char *esc_seq)
case VT100_CURSOR_RIGHT:
result = tinyrl_key_right(tinyrl, 0);
break;
+ case VT100_CURSOR_FDWORD:
+ result = tinyrl_key_right_word(tinyrl, 0);
+ break;
+ case VT100_CURSOR_BKWORD:
+ result = tinyrl_key_left_word(tinyrl, 0);
+ break;
case VT100_HOME:
result = tinyrl_key_start_of_line(tinyrl, 0);
break;
diff --git a/tinyrl/vt100.h b/tinyrl/vt100.h
index 6864bb0..7eca40e 100644
--- a/tinyrl/vt100.h
+++ b/tinyrl/vt100.h
@@ -60,6 +60,8 @@ typedef enum {
VT100_CURSOR_DOWN, // Move the cursor down
VT100_CURSOR_LEFT, // Move the cursor left
VT100_CURSOR_RIGHT, // Move the cursor right
+ VT100_CURSOR_FDWORD, // Move the cursor right one word
+ VT100_CURSOR_BKWORD, // Move the cursor left one word
VT100_HOME, // Move the cursor to the beginning of the line
VT100_END, // Move the cursor to the end of the line
VT100_INSERT, // No action at the moment
diff --git a/tinyrl/vt100/vt100.c b/tinyrl/vt100/vt100.c
index 0c4f4aa..8dbf474 100644
--- a/tinyrl/vt100/vt100.c
+++ b/tinyrl/vt100/vt100.c
@@ -32,6 +32,8 @@ static vt100_decode_t esc_map[] = {
{"[D", VT100_CURSOR_LEFT},
{"[H", VT100_HOME},
{"[1~", VT100_HOME},
+ {"[1;5C", VT100_CURSOR_FDWORD},
+ {"[1;5D", VT100_CURSOR_BKWORD},
{"[F", VT100_END},
{"[4~", VT100_END},
{"[2~", VT100_INSERT},
--
2.34.1
@@ -0,0 +1,119 @@
From fde25d13a2b5b91fe807503cb264426371cf35fa Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Wed, 12 Jul 2023 12:44:08 +0200
Subject: [PATCH 7/7] tinyrl: add support for Meta-d and Meta-Backspace (delete
word)
Organization: Addiva Elektronik
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
tinyrl/tinyrl/keys.c | 23 +++++++++++++++++++++++
tinyrl/tinyrl/private.h | 1 +
tinyrl/tinyrl/tinyrl.c | 6 ++++++
tinyrl/vt100.h | 4 +++-
tinyrl/vt100/vt100.c | 4 ++++
5 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/tinyrl/tinyrl/keys.c b/tinyrl/tinyrl/keys.c
index 10ea6a3..ddbbfe3 100644
--- a/tinyrl/tinyrl/keys.c
+++ b/tinyrl/tinyrl/keys.c
@@ -226,6 +226,14 @@ bool_t tinyrl_key_delete(tinyrl_t *tinyrl, unsigned char key)
return BOOL_TRUE;
}
+static int is_space(tinyrl_t *tinyrl)
+{
+ if (tinyrl->utf8)
+ return iswspace(tinyrl->line.str[tinyrl->line.pos]);
+
+ return isspace(tinyrl->line.str[tinyrl->line.pos]);
+}
+
static int is_prev_space(tinyrl_t *tinyrl)
{
if (tinyrl->utf8) {
@@ -263,6 +271,21 @@ bool_t tinyrl_key_backword(tinyrl_t *tinyrl, unsigned char key)
return BOOL_TRUE;
}
+bool_t tinyrl_key_delword(tinyrl_t *tinyrl, unsigned char key)
+{
+ (void)key;
+
+ // remove current whitespace at cursor
+ while (tinyrl->line.pos < tinyrl->line.len && is_space(tinyrl))
+ tinyrl_key_delete(tinyrl, KEY_DEL);
+
+ // delete word at cusor
+ while (tinyrl->line.pos < tinyrl->line.len && !is_space(tinyrl))
+ tinyrl_key_delete(tinyrl, KEY_DEL);
+
+ return BOOL_TRUE;
+}
+
bool_t tinyrl_key_left_word(tinyrl_t *tinyrl, unsigned char key)
{
(void)key;
diff --git a/tinyrl/tinyrl/private.h b/tinyrl/tinyrl/private.h
index 370f8a6..a230939 100644
--- a/tinyrl/tinyrl/private.h
+++ b/tinyrl/tinyrl/private.h
@@ -29,6 +29,7 @@ bool_t tinyrl_key_left(tinyrl_t *tinyrl, unsigned char key);
bool_t tinyrl_key_right(tinyrl_t *tinyrl, unsigned char key);
bool_t tinyrl_key_backspace(tinyrl_t *tinyrl, unsigned char key);
bool_t tinyrl_key_backword(tinyrl_t *tinyrl, unsigned char key);
+bool_t tinyrl_key_delword(tinyrl_t *tinyrl, unsigned char key);
bool_t tinyrl_key_delete(tinyrl_t *tinyrl, unsigned char key);
bool_t tinyrl_key_left_word(tinyrl_t *tinyrl, unsigned char key);
bool_t tinyrl_key_right_word(tinyrl_t *tinyrl, unsigned char key);
diff --git a/tinyrl/tinyrl/tinyrl.c b/tinyrl/tinyrl/tinyrl.c
index 2c83106..96fa7a5 100644
--- a/tinyrl/tinyrl/tinyrl.c
+++ b/tinyrl/tinyrl/tinyrl.c
@@ -512,6 +512,12 @@ bool_t tinyrl_esc_seq(tinyrl_t *tinyrl, const char *esc_seq)
case VT100_CURSOR_BKWORD:
result = tinyrl_key_left_word(tinyrl, 0);
break;
+ case VT100_DEL_FDWORD:
+ result = tinyrl_key_delword(tinyrl, 0);
+ break;
+ case VT100_DEL_BKWORD:
+ result = tinyrl_key_backword(tinyrl, 0);
+ break;
case VT100_HOME:
result = tinyrl_key_start_of_line(tinyrl, 0);
break;
diff --git a/tinyrl/vt100.h b/tinyrl/vt100.h
index 7eca40e..7cb1c31 100644
--- a/tinyrl/vt100.h
+++ b/tinyrl/vt100.h
@@ -67,7 +67,9 @@ typedef enum {
VT100_INSERT, // No action at the moment
VT100_DELETE, // Delete character on the right
VT100_PGUP, // No action at the moment
- VT100_PGDOWN // No action at the moment
+ VT100_PGDOWN, // No action at the moment
+ VT100_DEL_BKWORD, // Delete word to the left
+ VT100_DEL_FDWORD, // Delete word to the right
} vt100_esc_e;
diff --git a/tinyrl/vt100/vt100.c b/tinyrl/vt100/vt100.c
index 8dbf474..229af7e 100644
--- a/tinyrl/vt100/vt100.c
+++ b/tinyrl/vt100/vt100.c
@@ -40,6 +40,10 @@ static vt100_decode_t esc_map[] = {
{"[3~", VT100_DELETE},
{"[5~", VT100_PGUP},
{"[6~", VT100_PGDOWN},
+ {"b", VT100_CURSOR_BKWORD},
+ {"f", VT100_CURSOR_FDWORD},
+ {"\177", VT100_DEL_BKWORD},
+ {"d", VT100_DEL_FDWORD},
};
--
2.34.1