frontend: add a line editor for shell input

This commit is contained in:
2024-11-18 09:53:55 +00:00
parent f44a3364b3
commit 4fc1a6ade8
22 changed files with 2137 additions and 0 deletions

View File

@@ -0,0 +1,131 @@
#include "highlight.h"
#include <ivy/lang/lex.h>
#include <stdlib.h>
#include <string.h>
#define LEX_SOURCE_TO_HIGHLIGHT(p) \
((struct highlight_hook *)((char *)p \
- offsetof(struct highlight_hook, hook_src)))
#define HOOK_TO_HIGHLIGHT(p) \
((struct highlight_hook *)((char *)p \
- offsetof(struct highlight_hook, hook_base)))
static enum ivy_status readline(
struct ivy_line_source *source, char *out, size_t max, size_t *read,
const char *scope_type)
{
struct highlight_hook *highlight = LEX_SOURCE_TO_HIGHLIGHT(source);
const char *bufp = highlight->hook_bufp;
size_t r = 0;
for (size_t i = 0; i < max; i++) {
char c = *bufp;
out[i] = c;
if (c == '\0') {
break;
}
r++;
bufp++;
if (c == '\n') {
break;
}
}
highlight->hook_bufp = bufp;
*read = r;
return r > 0 ? IVY_OK : IVY_ERR_EOF;
}
static void highlight_token(
struct line_ed *ed, struct ivy_token *tok, struct s_tty_vmode *vmode)
{
/* TODO re-enable this once tokens contain positional info */
#if 0
line_ed_put_highlight(
ed, tok->t_start_col - 1, tok->t_start_row - 1,
tok->t_end_col - 1, tok->t_end_row - 1, vmode);
#endif
}
static void buffer_modified(struct line_ed *ed, struct line_ed_hook *hook)
{
#if 0
struct highlight_hook *highlight = HOOK_TO_HIGHLIGHT(hook);
line_ed_clear_highlights(ed);
lex_reset(highlight->hook_lex);
highlight->hook_bufp = ed->l_buf;
struct s_tty_vmode vmode_number = MAKE_VMODE(
MAKE_COLOUR_16(TTY_COLOUR16_CYAN), MAKE_COLOUR_DEFAULT(),
TTY_ATTRIB_NORMAL);
struct s_tty_vmode vmode_keyword = MAKE_VMODE(
MAKE_COLOUR_16(TTY_COLOUR16_BRIGHT_YELLOW),
MAKE_COLOUR_DEFAULT(), TTY_ATTRIB_BOLD);
struct s_tty_vmode vmode_var = MAKE_VMODE(
MAKE_COLOUR_16(TTY_COLOUR16_MAGENTA), MAKE_COLOUR_DEFAULT(),
TTY_ATTRIB_ITALIC);
struct lex_token *tok;
while (1) {
tok = lex_advance(highlight->hook_lex);
if (!tok) {
break;
}
if (tok->t_start_col == 0) {
lex_token_destroy(tok);
continue;
}
switch (tok->t_type) {
case TOK_NUMBER:
highlight_token(ed, tok, &vmode_number);
break;
case TOK_KEYWORD:
highlight_token(ed, tok, &vmode_keyword);
break;
case TOK_VAR:
highlight_token(ed, tok, &vmode_var);
break;
default:
break;
}
lex_token_destroy(tok);
}
#endif
}
extern struct highlight_hook *highlight_hook_create(void)
{
#if 0
struct highlight_hook *out = malloc(sizeof *out);
if (!out) {
return NULL;
}
memset(out, 0x0, sizeof *out);
out->hook_lex = lex_create(LEX_MODE_SPECULATIVE);
out->hook_base.hook_buffer_modified = buffer_modified;
out->hook_src.s_readline = readline;
lex_set_source(out->hook_lex, &out->hook_src);
return out;
#endif
return NULL;
}
extern void highlight_hook_destroy(struct highlight_hook *hook)
{
#if 0
lex_destroy(hook->hook_lex);
free(hook);
#endif
}

View File

@@ -0,0 +1,20 @@
#ifndef LINE_ED_HOOKS_HIGHLIGHT_H_
#define LINE_ED_HOOKS_HIGHLIGHT_H_
#include "../line-ed.h"
#include <ivy/lang/lex.h>
struct lex;
struct highlight_hook {
struct line_ed_hook hook_base;
struct ivy_line_source hook_src;
const char *hook_bufp;
struct lex *hook_lex;
};
extern struct highlight_hook *highlight_hook_create(void);
extern void highlight_hook_destroy(struct highlight_hook *hook);
#endif