frontend: add a line editor for shell input
This commit is contained in:
96
frontend/line-ed/line-ed.h
Normal file
96
frontend/line-ed/line-ed.h
Normal file
@@ -0,0 +1,96 @@
|
||||
#ifndef LINE_ED_H_
|
||||
#define LINE_ED_H_
|
||||
|
||||
#define LINE_MAX 4096
|
||||
|
||||
#include "tty.h"
|
||||
|
||||
#include <blue/core/queue.h>
|
||||
#include <blue/object/array.h>
|
||||
#include <ivy/line-source.h>
|
||||
#include <stddef.h>
|
||||
|
||||
struct s_tty_vmode;
|
||||
|
||||
struct line_ed;
|
||||
|
||||
struct line_ed_hook {
|
||||
void (*hook_keypress)(struct line_ed *, struct line_ed_hook *, s_keycode);
|
||||
void (*hook_buffer_modified)(struct line_ed *, struct line_ed_hook *);
|
||||
b_queue_entry hook_entry;
|
||||
};
|
||||
|
||||
enum line_ed_flags {
|
||||
/* always reprint an entire line when a character is added/deleted.
|
||||
* without this flag, only the modified character any subsequent
|
||||
* characters are reprinted. */
|
||||
LINE_ED_FULL_REPRINT = 0x01u,
|
||||
|
||||
/* keep line continuation (backslash-newline) tokens in the output
|
||||
* buffer (default behaviour) */
|
||||
LINE_ED_KEEP_CONTINUATIONS = 0x00u,
|
||||
/* convert line continuation tokens in the output buffer to simple
|
||||
* linefeeds. */
|
||||
LINE_ED_CONVERT_CONTINUATIONS = 0x02u,
|
||||
/* remove line continuation tokens from the output buffer, so that all
|
||||
* chars are on a single line */
|
||||
LINE_ED_REMOVE_CONTINUATIONS = 0x06u,
|
||||
};
|
||||
|
||||
struct line_ed {
|
||||
enum line_ed_flags l_flags;
|
||||
|
||||
/* array of basic prompt strings */
|
||||
const char *l_prompt[2];
|
||||
/* input buffer, pointer to the buffer cell that corresponds to
|
||||
* the current cursor position, and pointer to the byte AFTER the last
|
||||
* usable byte in the buffer */
|
||||
char *l_buf, *l_buf_ptr, *l_buf_end;
|
||||
/* pointer to the byte AFTER the last byte of the user's input */
|
||||
char *l_line_end;
|
||||
/* 2-dimensional coordinates of the current cursor position.
|
||||
* this does NOT include any prompts that are visible on the terminal */
|
||||
unsigned int l_cursor_x, l_cursor_y;
|
||||
/* the number of line continuations that have been inputted */
|
||||
unsigned int l_continuations;
|
||||
|
||||
struct ivy_line_source l_line_source;
|
||||
|
||||
/* the lexical scope that we are currently in.
|
||||
* this is provided by components further up the input pipeline,
|
||||
* for example, when we are inside a string or if-statement. */
|
||||
const char *l_scope_type;
|
||||
|
||||
/* array of previously entered commands */
|
||||
b_array *l_history;
|
||||
/* index of the currently selected history entry */
|
||||
unsigned int l_history_pos;
|
||||
|
||||
/* list of defined highlight ranges */
|
||||
b_queue l_hl_ranges;
|
||||
/* list of installed hooks */
|
||||
b_queue l_hooks;
|
||||
};
|
||||
|
||||
extern struct line_ed *line_ed_create(void);
|
||||
extern void line_ed_destroy(struct line_ed *ed);
|
||||
extern void line_ed_set_flags(struct line_ed *ed, enum line_ed_flags flags);
|
||||
extern void line_ed_set_scope_type(struct line_ed *ed, const char *scope_type);
|
||||
|
||||
extern void line_ed_put_highlight(
|
||||
struct line_ed *ed, unsigned long start_x, unsigned long start_y,
|
||||
unsigned long end_x, unsigned long end_y, const struct s_tty_vmode *vmode);
|
||||
extern void line_ed_clear_highlights(struct line_ed *ed);
|
||||
extern void line_ed_print_highlights(struct line_ed *ed);
|
||||
|
||||
extern void line_ed_add_hook(struct line_ed *ed, struct line_ed_hook *hook);
|
||||
extern void line_ed_remove_hook(struct line_ed *ed, struct line_ed_hook *hook);
|
||||
|
||||
extern long line_ed_readline(struct line_ed *ed, char *out, size_t max);
|
||||
|
||||
static inline struct ivy_line_source *line_ed_to_line_source(struct line_ed *ed)
|
||||
{
|
||||
return &ed->l_line_source;
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user