diff options
Diffstat (limited to 'examples/dte/status.c')
| -rw-r--r-- | examples/dte/status.c | 337 |
1 files changed, 0 insertions, 337 deletions
diff --git a/examples/dte/status.c b/examples/dte/status.c deleted file mode 100644 index 228b1c6..0000000 --- a/examples/dte/status.c +++ /dev/null @@ -1,337 +0,0 @@ -#include <stdbool.h> -#include <stdint.h> -#include <string.h> -#include "status.h" -#include "search.h" -#include "selection.h" -#include "util/debug.h" -#include "util/macros.h" -#include "util/numtostr.h" -#include "util/utf8.h" -#include "util/xsnprintf.h" - -typedef struct { - char *buf; - size_t size; - size_t pos; - size_t separator; - const Window *window; - const GlobalOptions *opts; - InputMode input_mode; -} Formatter; - -typedef enum { - STATUS_INVALID = 0, - STATUS_ESCAPED_PERCENT, - STATUS_ENCODING, - STATUS_MISC, - STATUS_IS_CRLF, - STATUS_SEPARATOR_LONG, - STATUS_CURSOR_COL_BYTES, - STATUS_TOTAL_ROWS, - STATUS_BOM, - STATUS_FILENAME, - STATUS_MODIFIED, - STATUS_LINE_ENDING, - STATUS_OVERWRITE, - STATUS_SCROLL_POSITION, - STATUS_READONLY, - STATUS_SEPARATOR, - STATUS_FILETYPE, - STATUS_UNICODE, - STATUS_CURSOR_COL, - STATUS_CURSOR_ROW, -} FormatSpecifierType; - -static FormatSpecifierType lookup_format_specifier(unsigned char ch) -{ - switch (ch) { - case '%': return STATUS_ESCAPED_PERCENT; - case 'E': return STATUS_ENCODING; - case 'M': return STATUS_MISC; - case 'N': return STATUS_IS_CRLF; - case 'S': return STATUS_SEPARATOR_LONG; - case 'X': return STATUS_CURSOR_COL_BYTES; - case 'Y': return STATUS_TOTAL_ROWS; - case 'b': return STATUS_BOM; - case 'f': return STATUS_FILENAME; - case 'm': return STATUS_MODIFIED; - case 'n': return STATUS_LINE_ENDING; - case 'o': return STATUS_OVERWRITE; - case 'p': return STATUS_SCROLL_POSITION; - case 'r': return STATUS_READONLY; - case 's': return STATUS_SEPARATOR; - case 't': return STATUS_FILETYPE; - case 'u': return STATUS_UNICODE; - case 'x': return STATUS_CURSOR_COL; - case 'y': return STATUS_CURSOR_ROW; - } - return STATUS_INVALID; -} - -#define add_status_literal(f, s) add_status_bytes(f, s, STRLEN(s)) - -static void add_ch(Formatter *f, char ch) -{ - f->buf[f->pos++] = ch; -} - -static void add_separator(Formatter *f) -{ - while (f->separator && f->pos < f->size) { - add_ch(f, ' '); - f->separator--; - } -} - -static void add_status_str(Formatter *f, const char *str) -{ - BUG_ON(!str); - if (unlikely(!str[0])) { - return; - } - add_separator(f); - size_t idx = 0; - while (f->pos < f->size && str[idx]) { - u_set_char(f->buf, &f->pos, u_str_get_char(str, &idx)); - } -} - -static void add_status_bytes(Formatter *f, const char *str, size_t len) -{ - if (unlikely(len == 0)) { - return; - } - add_separator(f); - if (f->pos >= f->size) { - return; - } - const size_t avail = f->size - f->pos; - len = MIN(len, avail); - memcpy(f->buf + f->pos, str, len); - f->pos += len; -} - -PRINTF(2) -static void add_status_format(Formatter *f, const char *format, ...) -{ - char buf[1024]; - va_list ap; - va_start(ap, format); - size_t len = xvsnprintf(buf, sizeof(buf), format, ap); - va_end(ap); - add_status_bytes(f, buf, len); -} - -static void add_status_umax(Formatter *f, uintmax_t x) -{ - char buf[DECIMAL_STR_MAX(x)]; - size_t len = buf_umax_to_str(x, buf); - add_status_bytes(f, buf, len); -} - -static void add_status_pos(Formatter *f) -{ - size_t lines = f->window->view->buffer->nl; - int h = f->window->edit_h; - long pos = f->window->view->vy; - if (lines <= h) { - if (pos) { - add_status_literal(f, "Bot"); - } else { - add_status_literal(f, "All"); - } - } else if (pos == 0) { - add_status_literal(f, "Top"); - } else if (pos + h - 1 >= lines) { - add_status_literal(f, "Bot"); - } else { - unsigned int d = lines - (h - 1); - unsigned int percent = (pos * 100 + d / 2) / d; - BUG_ON(percent > 100); - char buf[4]; - size_t len = buf_uint_to_str(percent, buf); - buf[len++] = '%'; - add_status_bytes(f, buf, len); - } -} - -static void add_misc_status(Formatter *f) -{ - static const struct { - const char str[24]; - size_t len; - } css_strs[] = { - [CSS_FALSE] = {STRN("[case-sensitive = false]")}, - [CSS_TRUE] = {STRN("[case-sensitive = true]")}, - [CSS_AUTO] = {STRN("[case-sensitive = auto]")}, - }; - - if (f->input_mode == INPUT_SEARCH) { - SearchCaseSensitivity css = f->opts->case_sensitive_search; - BUG_ON(css >= ARRAYLEN(css_strs)); - add_status_bytes(f, css_strs[css].str, css_strs[css].len); - return; - } - - const View *view = f->window->view; - if (view->selection == SELECT_NONE) { - return; - } - - SelectionInfo si; - init_selection(view, &si); - bool is_lines = (view->selection == SELECT_LINES); - size_t n = is_lines ? get_nr_selected_lines(&si) : get_nr_selected_chars(&si); - const char *unit = is_lines ? "line" : "char"; - const char *plural = unlikely(n == 1) ? "" : "s"; - add_status_format(f, "[%zu %s%s]", n, unit, plural); -} - -void sf_format ( - const Window *window, - const GlobalOptions *opts, - InputMode mode, - char *buf, // NOLINT(readability-non-const-parameter) - size_t size, - const char *format -) { - BUG_ON(size < 16); - Formatter f = { - .window = window, - .opts = opts, - .input_mode = mode, - .buf = buf, - .size = size - 5, // Max length of char and terminating NUL - }; - - const View *view = window->view; - const Buffer *buffer = view->buffer; - CodePoint u; - - while (f.pos < f.size && *format) { - unsigned char ch = *format++; - if (ch != '%') { - add_separator(&f); - add_ch(&f, ch); - continue; - } - - switch (lookup_format_specifier(*format++)) { - case STATUS_BOM: - if (buffer->bom) { - add_status_literal(&f, "BOM"); - } - break; - case STATUS_FILENAME: - add_status_str(&f, buffer_filename(buffer)); - break; - case STATUS_MODIFIED: - if (buffer_modified(buffer)) { - add_separator(&f); - add_ch(&f, '*'); - } - break; - case STATUS_READONLY: - if (buffer->readonly) { - add_status_literal(&f, "RO"); - } else if (buffer->temporary) { - add_status_literal(&f, "TMP"); - } - break; - case STATUS_CURSOR_ROW: - add_status_umax(&f, view->cy + 1); - break; - case STATUS_TOTAL_ROWS: - add_status_umax(&f, buffer->nl); - break; - case STATUS_CURSOR_COL: - add_status_umax(&f, view->cx_display + 1); - break; - case STATUS_CURSOR_COL_BYTES: - add_status_umax(&f, view->cx_char + 1); - if (view->cx_display != view->cx_char) { - add_ch(&f, '-'); - add_status_umax(&f, view->cx_display + 1); - } - break; - case STATUS_SCROLL_POSITION: - add_status_pos(&f); - break; - case STATUS_ENCODING: - add_status_str(&f, buffer->encoding.name); - break; - case STATUS_MISC: - add_misc_status(&f); - break; - case STATUS_IS_CRLF: - if (buffer->crlf_newlines) { - add_status_literal(&f, "CRLF"); - } - break; - case STATUS_LINE_ENDING: - if (buffer->crlf_newlines) { - add_status_literal(&f, "CRLF"); - } else { - add_status_literal(&f, "LF"); - } - break; - case STATUS_OVERWRITE: - if (buffer->options.overwrite) { - add_status_literal(&f, "OVR"); - } else { - add_status_literal(&f, "INS"); - } - break; - case STATUS_SEPARATOR_LONG: - f.separator = 3; - break; - case STATUS_SEPARATOR: - f.separator = 1; - break; - case STATUS_FILETYPE: - add_status_str(&f, buffer->options.filetype); - break; - case STATUS_UNICODE: - if (unlikely(!block_iter_get_char(&view->cursor, &u))) { - break; - } - if (u_is_unicode(u)) { - char str[STRLEN("U+10FFFF") + 1]; - str[0] = 'U'; - str[1] = '+'; - size_t ndigits = buf_umax_to_hex_str(u, str + 2, 4); - add_status_bytes(&f, str, 2 + ndigits); - } else { - add_status_literal(&f, "Invalid"); - } - break; - case STATUS_ESCAPED_PERCENT: - add_separator(&f); - add_ch(&f, '%'); - break; - case STATUS_INVALID: - default: - BUG("should be unreachable, due to validate_statusline_format()"); - } - } - - f.buf[f.pos] = '\0'; -} - -// Returns the offset of the first invalid format specifier, or 0 if -// the whole format string is valid. It's safe to use 0 to indicate -// "no errors", since it's not possible for there to be an error at -// the very start of the string. -size_t statusline_format_find_error(const char *str) -{ - for (size_t i = 0; str[i]; ) { - if (str[i++] != '%') { - continue; - } - if (lookup_format_specifier(str[i++]) == STATUS_INVALID) { - return i - 1; - } - } - return 0; -} |
