summaryrefslogtreecommitdiff
path: root/examples/dte/screen-cmdline.c
diff options
context:
space:
mode:
Diffstat (limited to 'examples/dte/screen-cmdline.c')
-rw-r--r--examples/dte/screen-cmdline.c91
1 files changed, 91 insertions, 0 deletions
diff --git a/examples/dte/screen-cmdline.c b/examples/dte/screen-cmdline.c
new file mode 100644
index 0000000..58d04c4
--- /dev/null
+++ b/examples/dte/screen-cmdline.c
@@ -0,0 +1,91 @@
+#include "screen.h"
+#include "error.h"
+#include "search.h"
+
+static void print_message(Terminal *term, const ColorScheme *colors, const char *msg, bool is_error)
+{
+ BuiltinColorEnum c = BC_COMMANDLINE;
+ if (msg[0]) {
+ c = is_error ? BC_ERRORMSG : BC_INFOMSG;
+ }
+
+ TermOutputBuffer *obuf = &term->obuf;
+ set_builtin_color(term, colors, c);
+
+ for (size_t i = 0; msg[i]; ) {
+ CodePoint u = u_get_char(msg, i + 4, &i);
+ if (!term_put_char(obuf, u)) {
+ break;
+ }
+ }
+}
+
+void show_message(Terminal *term, const ColorScheme *colors, const char *msg, bool is_error)
+{
+ term_output_reset(term, 0, term->width, 0);
+ term_move_cursor(&term->obuf, 0, term->height - 1);
+ print_message(term, colors, msg, is_error);
+ term_clear_eol(term);
+}
+
+static size_t print_command(Terminal *term, const ColorScheme *colors, const CommandLine *cmdline, char prefix)
+{
+ const String *buf = &cmdline->buf;
+ TermOutputBuffer *obuf = &term->obuf;
+
+ // Width of characters up to and including cursor position
+ size_t w = 1; // ":" (prefix)
+
+ for (size_t i = 0; i <= cmdline->pos && i < buf->len; ) {
+ CodePoint u = u_get_char(buf->buffer, buf->len, &i);
+ w += u_char_width(u);
+ }
+ if (cmdline->pos == buf->len) {
+ w++;
+ }
+ if (w > term->width) {
+ obuf->scroll_x = w - term->width;
+ }
+
+ set_builtin_color(term, colors, BC_COMMANDLINE);
+ term_put_char(obuf, prefix);
+
+ size_t x = obuf->x - obuf->scroll_x;
+ for (size_t i = 0; i < buf->len; ) {
+ BUG_ON(obuf->x > obuf->scroll_x + obuf->width);
+ CodePoint u = u_get_char(buf->buffer, buf->len, &i);
+ if (!term_put_char(obuf, u)) {
+ break;
+ }
+ if (i <= cmdline->pos) {
+ x = obuf->x - obuf->scroll_x;
+ }
+ }
+
+ return x;
+}
+
+void update_command_line(EditorState *e)
+{
+ Terminal *term = &e->terminal;
+ char prefix = ':';
+ term_output_reset(term, 0, term->width, 0);
+ term_move_cursor(&term->obuf, 0, term->height - 1);
+ switch (e->input_mode) {
+ case INPUT_NORMAL: {
+ bool msg_is_error;
+ const char *msg = get_msg(&msg_is_error);
+ print_message(term, &e->colors, msg, msg_is_error);
+ break;
+ }
+ case INPUT_SEARCH:
+ prefix = e->search.reverse ? '?' : '/';
+ // Fallthrough
+ case INPUT_COMMAND:
+ e->cmdline_x = print_command(term, &e->colors, &e->cmdline, prefix);
+ break;
+ default:
+ BUG("unhandled input mode");
+ }
+ term_clear_eol(term);
+}