slackline: implement ctrl+w and ctrl+l - lchat - A line oriented chat front end… | |
git clone git://git.suckless.org/lchat | |
Log | |
Files | |
Refs | |
README | |
--- | |
commit aa7afafc6710c68811bbc33d8b781edfa8c17109 | |
parent 0c1a66c482d9ffa4e0e3f8fdb60aa1a02755da37 | |
Author: Tom Schwindl <[email protected]> | |
Date: Fri, 9 Sep 2022 21:40:55 +0200 | |
slackline: implement ctrl+w and ctrl+l | |
ctrl+w is part of the canonical line disciplines on most systems, thus | |
it is convenient to implement it. | |
ctrl+l is part of the emacs-mode, but generic and useful enough to be | |
implemented regardless of the current mode. | |
Additionally, we now check for control key combinations. This makes it | |
possible to ignore "invalid" key combinations. It also helps with the | |
implementation of an emacs-mode. Previously, pressing something like ctrl+f | |
would insert invisible characters, which is very irritating. | |
Last, it isn't weird that ctrl+u emits a NAK, since ctrl key combinations | |
map the letters A-Z to the ASCII codes 1-26. "u" is the 21. character in | |
the alphabet and NAK has the ASCII code 21. | |
Diffstat: | |
M slackline.c | 63 +++++++++++++++++++++--------… | |
1 file changed, 43 insertions(+), 20 deletions(-) | |
--- | |
diff --git a/slackline.c b/slackline.c | |
@@ -14,7 +14,7 @@ | |
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
*/ | |
-#include <stdbool.h> | |
+#include <ctype.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
@@ -104,6 +104,30 @@ sl_postoptr(struct slackline *sl, size_t pos) | |
return ptr; | |
} | |
+static void | |
+sl_backspace(struct slackline *sl) | |
+{ | |
+ char *ncur; | |
+ | |
+ if (sl->rcur == 0) | |
+ return; | |
+ | |
+ ncur = sl_postoptr(sl, sl->rcur - 1); | |
+ | |
+ if (sl->rcur < sl->rlen) | |
+ memmove(ncur, sl->ptr, sl->last - sl->ptr); | |
+ | |
+ sl->rcur--; | |
+ sl->rlen--; | |
+ sl->bcur = sl_postobyte(sl, sl->rcur); | |
+ sl->blen = sl_postobyte(sl, sl->rlen); | |
+ | |
+ sl->last -= sl->ptr - ncur; | |
+ *sl->last = '\0'; | |
+ | |
+ sl->ptr = ncur; | |
+} | |
+ | |
int | |
sl_keystroke(struct slackline *sl, int key) | |
{ | |
@@ -192,6 +216,9 @@ sl_keystroke(struct slackline *sl, int key) | |
} | |
} | |
+ if (!iscntrl((unsigned char) key)) | |
+ goto compose; | |
+ | |
/* handle ctl keys */ | |
switch (key) { | |
case 27: /* Escape */ | |
@@ -199,30 +226,26 @@ sl_keystroke(struct slackline *sl, int key) | |
return 0; | |
case 127: /* backspace */ | |
case 8: /* backspace */ | |
- if (sl->rcur == 0) | |
- return 0; | |
- | |
- char *ncur = sl_postoptr(sl, sl->rcur - 1); | |
- | |
- if (sl->rcur < sl->rlen) | |
- memmove(ncur, sl->ptr, sl->last - sl->ptr); | |
- | |
- sl->rcur--; | |
- sl->rlen--; | |
- sl->bcur = sl_postobyte(sl, sl->rcur); | |
- sl->blen = sl_postobyte(sl, sl->rlen); | |
- | |
- sl->last -= sl->ptr - ncur; | |
- *sl->last = '\0'; | |
- | |
- sl->ptr = ncur; | |
- | |
+ sl_backspace(sl); | |
return 0; | |
- case 21: /* ctrl+u or clearline, weird that it's a NAK */ | |
+ case 21: /* ctrl+u -- clearline */ | |
sl_reset(sl); | |
return 0; | |
+ case 12: /* ctrl+l -- clear screen, same as clear(1) */ | |
+ printf("\x1b[2J\x1b[H"); | |
+ return 0; | |
+ case 23: /* ctrl+w -- erase previous word */ | |
+ while (sl->rcur != 0 && isspace((unsigned char) *(sl->ptr-1))) | |
+ sl_backspace(sl); | |
+ | |
+ while (sl->rcur != 0 && !isspace((unsigned char) *(sl->ptr-1))) | |
+ sl_backspace(sl); | |
+ return 0; | |
+ default: | |
+ return 0; | |
} | |
+compose: | |
/* byte-wise composing of UTF-8 runes */ | |
sl->ubuf[sl->ubuf_len++] = key; | |
if (fullrune(sl->ubuf, sl->ubuf_len) == 0) |