aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--editor.h5
-rw-r--r--ui-curses.c42
-rw-r--r--ui.h11
-rw-r--r--vis.c29
4 files changed, 50 insertions, 37 deletions
diff --git a/editor.h b/editor.h
index 36f2829..edfa210 100644
--- a/editor.h
+++ b/editor.h
@@ -26,11 +26,6 @@ typedef union {
void (*f)(Editor*); /* generic editor commands */
} Arg;
-typedef struct {
- char str[6]; /* UTF8 character or terminal escape code */
- int code; /* curses KEY_* constant */
-} Key;
-
#define MAX_KEYS 2
typedef Key KeyCombo[MAX_KEYS];
diff --git a/ui-curses.c b/ui-curses.c
index 619524b..f2f6899 100644
--- a/ui-curses.c
+++ b/ui-curses.c
@@ -528,6 +528,46 @@ static void ui_suspend(Ui *ui) {
raise(SIGSTOP);
}
+static bool ui_haskey(Ui *ui) {
+ nodelay(stdscr, TRUE);
+ int c = getch();
+ if (c != ERR)
+ ungetch(c);
+ nodelay(stdscr, FALSE);
+ return c != ERR;
+}
+
+static Key ui_getkey(Ui *ui) {
+ Key key = { .str = "", .code = 0 };
+ int keycode = getch(), cur = 0;
+ if (keycode == ERR)
+ return key;
+
+ if (keycode >= KEY_MIN) {
+ key.code = keycode;
+ } else {
+ key.str[cur++] = keycode;
+ int len = 1;
+ unsigned char keychar = keycode;
+ if (ISASCII(keychar)) len = 1;
+ else if (keychar == 0x1B || keychar >= 0xFC) len = 6;
+ else if (keychar >= 0xF8) len = 5;
+ else if (keychar >= 0xF0) len = 4;
+ else if (keychar >= 0xE0) len = 3;
+ else if (keychar >= 0xC0) len = 2;
+ len = MIN(len, LENGTH(key.str));
+
+ if (cur < len) {
+ nodelay(stdscr, TRUE);
+ for (int t; cur < len && (t = getch()) != ERR; cur++)
+ key.str[cur] = t;
+ nodelay(stdscr, FALSE);
+ }
+ }
+
+ return key;
+}
+
Ui *ui_curses_new(void) {
setlocale(LC_CTYPE, "");
if (!getenv("ESCDELAY"))
@@ -571,6 +611,8 @@ Ui *ui_curses_new(void) {
.info = info,
.info_hide = info_hide,
.color_get = color_get,
+ .haskey = ui_haskey,
+ .getkey = ui_getkey,
};
struct sigaction sa;
diff --git a/ui.h b/ui.h
index 732c618..40e2ea7 100644
--- a/ui.h
+++ b/ui.h
@@ -15,6 +15,11 @@ enum UiOption {
UI_OPTION_LINE_NUMBERS_RELATIVE = 1 << 1,
};
+typedef struct {
+ char str[6]; /* UTF8 character or terminal escape code */
+ int code; /* curses KEY_* constant */
+} Key;
+
#include <stdbool.h>
#include <stdarg.h>
#include "text.h"
@@ -40,10 +45,8 @@ struct Ui {
void (*update)(Ui*);
void (*suspend)(Ui*);
void (*resume)(Ui*);
-/* TODO main loop integration, signal handling
- Key getkey(void);
- bool haskey(void);
-*/
+ Key (*getkey)(Ui*);
+ bool (*haskey)(Ui*);
};
struct UiWin {
diff --git a/vis.c b/vis.c
index ee6612b..f4f712a 100644
--- a/vis.c
+++ b/vis.c
@@ -2268,36 +2268,9 @@ static void keypress(Key *key) {
}
static Key getkey(void) {
- Key key = { .str = "", .code = 0 };
- int keycode = getch(), cur = 0;
- if (keycode == ERR)
- return key;
-
- if (keycode >= KEY_MIN) {
- key.code = keycode;
- } else {
- key.str[cur++] = keycode;
- int len = 1;
- unsigned char keychar = keycode;
- if (ISASCII(keychar)) len = 1;
- else if (keychar == 0x1B || keychar >= 0xFC) len = 6;
- else if (keychar >= 0xF8) len = 5;
- else if (keychar >= 0xF0) len = 4;
- else if (keychar >= 0xE0) len = 3;
- else if (keychar >= 0xC0) len = 2;
- len = MIN(len, LENGTH(key.str));
-
- if (cur < len) {
- nodelay(stdscr, TRUE);
- for (int t; cur < len && (t = getch()) != ERR; cur++)
- key.str[cur] = t;
- nodelay(stdscr, FALSE);
- }
- }
-
+ Key key = vis->ui->getkey(vis->ui);
if (config->keypress && !config->keypress(&key))
return (Key){ .str = "", .code = 0 };
-
return key;
}