From e3c5bfd457614773508feefdc12dbc60073030ed Mon Sep 17 00:00:00 2001 From: Charlie Gordon Date: Sun, 1 Dec 2024 23:34:00 +0100 Subject: [PATCH] Remove references to global `qe_state` (#45) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Remove references to global `qe_state` Add `QEmacsState *qs` field in context and object structures: - `QEditScreen`, `EditState` (renamed from `qe_state`), `QuitState` - `WinWindow` (win32.c), `X11State` (x11.c), `QEArgs` (cmd line arguments) - `CmdLineOptionDef::func_arg()`, `QEModeData` - move `QEKeyContext` to `QEmacsState` Pass `QEmacsState *qs` to configuration and state functions: - all `module_xxx_init` and static `xxx_init` functions - `QEDisplay::dpy_init()`, `qe_register_display()`, `screen_init()̀` - `load_input_methods()`, `unload_input_methods()` - `register_input_method()`, `find_input_method()` - `find_resource_file()`, `open_resource_file()` - `qe_find_current_binding()`, `qe_list_bindings()` - `qe_register_mode()`, `qe_find_mode()`, `qe_find_mode_filename()` - `qe_register_cmd_line_options()`, `set_user_option()`, `set_tty_charset()` - `qe_register_commands()`, `qe_register_bindings()`, `qe_find_cmd()` - `qe_register_completion()`, `qe_register_variables()` - `eb_register_data_type()`, `parse_command_line()` - `eb_trace_bytes()`, `qe_toggle_control_h()` (split from `do_toggle_control_h()`) - `unget_key()`, `qe_grab_keys()`, `qe_ungrab_keys()`, `qe_key_process()` - `eb_new()`, `eb_find()`, `eb_find_new()`, `eb_scratch()`, `eb_find_file()` - `new_shell_buffer()` `macro_add_key()`, `clear_macro(), `stop_macro()` - `check_window()`, `check_buffer()`, `qe_kill_buffer()`, `qe_get_history()` - `qe_register_charset()`, `find_charset()` Add error message handlers: - add `QEDisplay::dpy_error()` method - add `qe_cfg_error()`, use for all expression parsing errors - pass opaque pointer to `css_error()` - add `qe_put_error()` and `qe_dpy_error()` Add context argument: - always pass a non-null window pointer to `do_refresh()`, `new_help_buffer()` Rename functions: - `find_resource_file` -> `qe_find_resource_file` - `open_resource_file` -> `qe_open_resource_file` - `input_methods_init` -> `qe_input_methods_init` - `load_input_methods` -> `qe_load_input_methods` - `unload_input_methods` -> `qe_unload_input_methods` - `find_input_methods` -> `qe_find_input_methods` - `register_input_method` -> `qe_register_input_method` - `parse_command_line` -> `qe_parse_command_line` - `eb_trace_bytes` -> `qe_trace_bytes` - `eb_init` -> `qe_data_init` - `eb_count_buffers` -> `qe_count_buffers` - `eb_get_buffer_from_index` -> `qe_get_buffer_from_index` - `init_all_modules` -> `qe_init_all_modules` - `exit_all_modules` -> `qe_exit_all_modules` - `load_all_modules` -> `qe_load_all_modules` - `maybe_set_mark` -> `do_maybe_set_mark` - `unget_key` -> `qe_unget_key` - `minibuffer_init` -> `qe_minibuffer_init` - `edit_display` -> `qe_display` - `new_yank_buffer` -> `qe_new_yank_buffer` - `new_shell_buffer` -> `qe_new_shell_buffer` - `shell_find_mode` -> `qe_shell_find_mode` - `save_selection` -> `qe_save_selection` - `register_emulation_bindings` -> `qe_register_emulation_bindings` - `macro_add_key` -> `qe_macro_add_key` - `clear_macro` -> `qe_clear_macro` - `stop_macro` -> `qe_stop_macro` - `eb_format_message` -> `qe_format_message` - `screen_init` -> `qe_screen_init` - `charset_jis_init` -> `qe_charset_jis_init` - `charset_more_init` -> `qe_charset_more_init` - `check_window` -> `qe_check_window` - `check_buffer` -> `qe_check_buffer` - `eb_find_file` -> `qe_find_buffer_file` - `eb_find` -> `qe_find_buffer_name` - `eb_new` -> `qe_new_buffer` - `eb_find_new` -> `qe_new_buffer` with `BC_REUSE` - `eb_scratch` -> `qe_new_buffer` with `BC_REUSE | BC_CLEAR` - `find_charset` -> `qe_find_charset` Add asan, msan and ubsan targets Fix `qe_encode64` buffer length computation. Add `qe_new_shell_buffer` flags `SF_REUSE_BUFFER` and `SF_ERASE_BUFFER` Bumped version to 6.3.3 fix redundant typedef fix compilation errors --- .gitignore | 4 + Makefile | 65 ++- TODO.md | 5 +- VERSION | 2 +- buffer.c | 140 ++++--- charset.c | 26 +- charset.h | 10 +- charsetjis.c | 10 +- charsetmore.c | 82 ++-- cutils.h | 2 +- display.c | 14 +- display.h | 13 +- extras.c | 125 +++--- haiku.cpp | 7 +- html2png.c | 27 +- input.c | 18 +- kmap.c | 8 +- lang/ada.c | 2 +- lang/agena.c | 3 +- lang/arm.c | 6 +- lang/asm.c | 3 +- lang/ats.c | 3 +- lang/basic.c | 3 +- lang/clang.c | 138 +++---- lang/cobol.c | 3 +- lang/coffee.c | 3 +- lang/crystal.c | 2 +- lang/csv.c | 2 +- lang/ebnf.c | 5 +- lang/elixir.c | 3 +- lang/elm.c | 3 +- lang/emf.c | 3 +- lang/erlang.c | 3 +- lang/falcon.c | 3 +- lang/forth.c | 2 +- lang/fortran.c | 3 +- lang/groovy.c | 3 +- lang/haskell.c | 3 +- lang/htmlsrc.c | 5 +- lang/icon.c | 3 +- lang/inifile.c | 3 +- lang/jai.c | 5 +- lang/julia.c | 3 +- lang/lisp.c | 14 +- lang/lua.c | 3 +- lang/magpie.c | 3 +- lang/makemode.c | 4 +- lang/nanorc.c | 3 +- lang/nim.c | 3 +- lang/ocaml.c | 5 +- lang/pascal.c | 3 +- lang/perl.c | 3 +- lang/postscript.c | 3 +- lang/python.c | 7 +- lang/rebol.c | 3 +- lang/rlang.c | 3 +- lang/ruby.c | 3 +- lang/rust.c | 3 +- lang/rye.c | 2 +- lang/scad.c | 3 +- lang/script.c | 13 +- lang/sharp.c | 3 +- lang/smalltalk.c | 3 +- lang/sql.c | 3 +- lang/swift.c | 3 +- lang/tiger.c | 3 +- lang/txl.c | 3 +- lang/vimscript.c | 3 +- lang/virgil.c | 3 +- lang/wolfram.c | 3 +- lang/xml.c | 3 +- libqhtml/Makefile | 26 +- libqhtml/css.c | 1 - libqhtml/css.h | 19 +- libqhtml/cssparse.c | 7 +- libqhtml/xmlparse.c | 15 +- modes/archive.c | 35 +- modes/bufed.c | 51 +-- modes/dired.c | 46 ++- modes/docbook.c | 4 +- modes/fractal.c | 23 +- modes/hex.c | 10 +- modes/html.c | 23 +- modes/image.c | 10 +- modes/latex-mode.c | 34 +- modes/markdown.c | 25 +- modes/mpeg.c | 2 +- modes/orgmode.c | 13 +- modes/shell.c | 160 ++++---- modes/stb.c | 6 +- modes/unihex.c | 4 +- modes/video.c | 14 +- plugins/my_plugin.c | 2 +- qe.c | 933 +++++++++++++++++++++++--------------------- qe.h | 163 ++++---- qescript.c | 109 +++--- search.c | 63 +-- tools/cptoqe.c | 10 +- tools/jistoqe.c | 4 +- tty.c | 36 +- unix.c | 7 +- util.c | 14 +- variables.c | 41 +- variables.h | 2 +- win32.c | 12 +- x11.c | 34 +- 106 files changed, 1500 insertions(+), 1345 deletions(-) diff --git a/.gitignore b/.gitignore index b5de52f..2e840cf 100644 --- a/.gitignore +++ b/.gitignore @@ -14,12 +14,16 @@ bin *.dSYM *_g *_debug +*_asan +*_msan +*_ubsan html2png qe tqe tqe1 xqe # temp-directories +copilot doc junk patches diff --git a/Makefile b/Makefile index 444835b..e3e2a15 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # QEmacs, tiny but powerful multimode editor # # Copyright (c) 2000-2002 Fabrice Bellard. -# Copyright (c) 2000-2023 Charlie Gordon. +# Copyright (c) 2000-2024 Charlie Gordon. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -79,13 +79,42 @@ DEFINES=-DHAVE_QE_CONFIG_H ######################################################## # do not modify after this +ifeq ($(CC),clang) +SANITIZE_CFLAGS := -fno-sanitize-recover=all -fno-omit-frame-pointer +else +SANITIZE_CFLAGS := -fno-omit-frame-pointer +endif +DEBUG_SUFFIX:= ifdef DEBUG +$(info Building with debug info) DEBUG_SUFFIX:=_debug ECHO_CFLAGS += -DCONFIG_DEBUG CFLAGS += -g -O0 LDFLAGS += -g -O0 -else -DEBUG_SUFFIX:= +endif +ifdef ASAN +$(info Building with ASan) +DEBUG_SUFFIX:=_asan +ECHO_CFLAGS += -DCONFIG_ASAN +CFLAGS += -D__ASAN__ +CFLAGS += -fsanitize=address $(SANITIZE_CFLAGS) +LDFLAGS += -fsanitize=address $(SANITIZE_CFLAGS) +endif +ifdef MSAN +$(info Building with MSan) +DEBUG_SUFFIX:=_msan +ECHO_CFLAGS += -DCONFIG_MSAN +CFLAGS += -D__MSAN__ +CFLAGS += -fsanitize=memory $(SANITIZE_CFLAGS) +LDFLAGS += -fsanitize=memory $(SANITIZE_CFLAGS) +endif +ifdef UBSAN +$(info Building with UBSan) +DEBUG_SUFFIX:=_ubsan +ECHO_CFLAGS += -DCONFIG_UBSAN +CFLAGS += -D__UBSAN__ +CFLAGS += -fsanitize=undefined $(SANITIZE_CFLAGS) +LDFLAGS += -fsanitize=undefined $(SANITIZE_CFLAGS) endif TARGETLIBS:= @@ -269,7 +298,7 @@ endif libqhtml: force $(MAKE) -C libqhtml all -ifdef DEBUG +ifneq (,$(DEBUG_SUFFIX)) $(TARGET)$(DEBUG_SUFFIX)$(EXE): $(OBJS) $(DEP_LIBS) $(echo) LD $@ $(cmd) $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) @@ -290,13 +319,15 @@ endif ifeq (1,$(TOP)) # targets that require recursion -xqe: force; $(MAKE) TARGET=xqe TARGET_OBJ=qe TARGET_X11=1 -tqe: force; $(MAKE) TARGET=tqe TARGET_TINY=1 -debug: force; $(MAKE) TARGET=qe DEBUG=1 -qe_debug: force; $(MAKE) TARGET=qe DEBUG=1 -xqe_debug: force; $(MAKE) TARGET=xqe TARGET_OBJ=qe TARGET_X11=1 DEBUG=1 -tqe_debug: force; $(MAKE) TARGET=tqe TARGET_TINY=1 DEBUG=1 -tqe1: force; $(MAKE) TARGET=tqe TARGET_TINY=1 tqe1$(EXE) +xqe: force; $(MAKE) TARGET=xqe TARGET_OBJ=qe TARGET_X11=1 +tqe: force; $(MAKE) TARGET=tqe TARGET_TINY=1 +tqe1: force; $(MAKE) TARGET=tqe TARGET_TINY=1 tqe1$(EXE) +asan qe_asan: force; $(MAKE) TARGET=qe ASAN=1 +msan qe_msan: force; $(MAKE) TARGET=qe MSAN=1 +ubsan qe_ubsan: force; $(MAKE) TARGET=qe UBSAN=1 +debug qe_debug: force; $(MAKE) TARGET=qe DEBUG=1 +xqe_debug: force; $(MAKE) TARGET=xqe TARGET_OBJ=qe TARGET_X11=1 DEBUG=1 +tqe_debug: force; $(MAKE) TARGET=tqe TARGET_TINY=1 DEBUG=1 else @@ -333,20 +364,20 @@ $(OBJS_DIR)/$(TARGET)_modules.c: $(SRCS) Makefile config.mak @echo '/* This file was generated automatically */' > $@ @echo '#include "qe.h"' >> $@ @echo '#undef qe_module_init' >> $@ - @echo '#define qe_module_init(fn) extern int module_##fn(void)' >> $@ + @echo '#define qe_module_init(fn) extern int qe_module_##fn(QEmacsState *qs)' >> $@ -@grep -h ^qe_module_init $(SRCS) >> $@ @echo '#undef qe_module_init' >> $@ - @echo 'void init_all_modules(QEmacsState *qs) {' >> $@ - @echo '#define qe_module_init(fn) module_##fn()' >> $@ + @echo 'void qe_init_all_modules(QEmacsState *qs) {' >> $@ + @echo '#define qe_module_init(fn) qe_module_##fn(qs)' >> $@ -@grep -h ^qe_module_init $(SRCS) >> $@ @echo '#undef qe_module_init' >> $@ @echo '}' >> $@ @echo '#undef qe_module_exit' >> $@ - @echo '#define qe_module_exit(fn) extern void module_##fn(QEmacsState *qs)' >> $@ + @echo '#define qe_module_exit(fn) extern void qe_module_##fn(QEmacsState *qs)' >> $@ -@grep -h ^qe_module_exit $(SRCS) >> $@ @echo '#undef qe_module_exit' >> $@ - @echo 'void exit_all_modules(QEmacsState *qs) {' >> $@ - @echo '#define qe_module_exit(fn) module_##fn(qs)' >> $@ + @echo 'void qe_exit_all_modules(QEmacsState *qs) {' >> $@ + @echo '#define qe_module_exit(fn) qe_module_##fn(qs)' >> $@ -@grep -h ^qe_module_exit $(SRCS) >> $@ @echo '#undef qe_module_exit' >> $@ @echo '}' >> $@ diff --git a/TODO.md b/TODO.md index 58e7ce6..0ae47ce 100644 --- a/TODO.md +++ b/TODO.md @@ -12,11 +12,9 @@ * drag out of window should generate **autorepeat** scrolling requests * prevent mouse focus to window if searching * prevent mouse focus to window if minibuf active -* get clipboard contents at startup or only at yank time? * only get tty clipboard contents on yank * only set tty clipboard contents if kill buffer changed during focus time * add script variable for clipboard support -* handle double/triple click to select word and line * add command line options for terminal features: backspace * add command line options for tracing * add command line options for color support @@ -39,6 +37,7 @@ * DEC SET 1036 ESC or Alt keys * stb: add magic number detection * shell integration: easily navigate to previous shell prompts with `M-S-up` and `M-S-down`. + use buffer properties for this * timestamp shell commands * remanent annotations on files and buffers * autoblame source code @@ -54,7 +53,7 @@ when inserting a character before an accented space, replace * fix markdown command bindings * toggle long listing and column listing in dired buffers -* keep a count of windows in `EditBuffer` +* keep a list of windows in `EditBuffer` * keep the last active window when detaching a buffer, just make it invisible. - easy if deleting the last window that shows the buffer - if changing the buffer for a window, if the new buffer has a pending window, use that diff --git a/VERSION b/VERSION index 91e4a9f..7849b73 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -6.3.2 +6.3.3 diff --git a/buffer.c b/buffer.c index 98162a6..757d9aa 100644 --- a/buffer.c +++ b/buffer.c @@ -546,22 +546,24 @@ int eb_delete(EditBuffer *b, int offset, int size) /* Verify that window still exists, return argument or NULL, * update handle if window is invalid. */ -EditBuffer *check_buffer(EditBuffer **sp) +EditBuffer *qe_check_buffer(QEmacsState *qs, EditBuffer **sp) { - QEmacsState *qs = &qe_state; + EditBuffer *b0 = *sp; EditBuffer *b; + if (b0 == NULL) + return NULL; + for (b = qs->first_buffer; b != NULL; b = b->next) { - if (b == *sp) + if (b == b0) return b; } return *sp = NULL; } #ifdef CONFIG_TINY -EditBuffer *eb_find(const char *name) +EditBuffer *qe_find_buffer_name(QEmacsState *qs, const char *name) { - QEmacsState *qs = &qe_state; EditBuffer *b; b = qs->first_buffer; @@ -597,7 +599,7 @@ static int eb_cache_locate(EditBuffer **cache, int len, const char *name) static int eb_cache_remove(EditBuffer *b) { - QEmacsState *qs = &qe_state; + QEmacsState *qs = b->qs; EditBuffer **cache = qs->buffer_cache; int len = qs->buffer_cache_len; int pos = eb_cache_locate(cache, len, b->name); @@ -616,7 +618,7 @@ static int eb_cache_remove(EditBuffer *b) static int eb_cache_insert(EditBuffer *b) { - QEmacsState *qs = &qe_state; + QEmacsState *qs = b->qs; EditBuffer **cache = qs->buffer_cache; int len = qs->buffer_cache_len; int pos = eb_cache_locate(cache, len, b->name); @@ -639,9 +641,8 @@ static int eb_cache_insert(EditBuffer *b) return 0; } -EditBuffer *eb_find(const char *name) +EditBuffer *qe_find_buffer_name(QEmacsState *qs, const char *name) { - QEmacsState *qs = &qe_state; EditBuffer **cache = qs->buffer_cache; int len = qs->buffer_cache_len; int pos = eb_cache_locate(cache, len, name); @@ -681,7 +682,7 @@ int eb_set_buffer_name(EditBuffer *b, const char *name1) } n = 0; /* do not allow an empty name */ - while ((b1 = eb_find(name)) != NULL || *name == '\0') { + while ((b1 = qe_find_buffer_name(b->qs, name)) != NULL || *name == '\0') { if (b == b1) return 0; n++; @@ -694,22 +695,25 @@ int eb_set_buffer_name(EditBuffer *b, const char *name1) return eb_cache_insert(b); } -EditBuffer *eb_new(const char *name, int flags) +EditBuffer *qe_new_buffer(QEmacsState *qs, const char *name, int flags) { - QEmacsState *qs = &qe_state; EditBuffer *b; EditBuffer **pb; + if (flags & BC_REUSE) { + b = qe_find_buffer_name(qs, name); + if (b != NULL) { + if (flags & BC_CLEAR) + eb_clear(b); + return b; + } + } + flags &= ~(BC_REUSE | BC_CLEAR); + b = qe_mallocz(EditBuffer); if (!b) return NULL; - /* set the buffer name to a unique name */ - if (eb_set_buffer_name(b, name)) { - qe_free(&b); - return NULL; - } - b->qs = qs; b->flags = flags & ~BF_STYLES; @@ -724,6 +728,15 @@ EditBuffer *eb_new(const char *name, int flags) b->fill_column = qs->default_fill_column; b->eol_type = qs->default_eol_type; + /* set the buffer name to a unique name */ + // XXX: `b` is not in the buffer list nor in the buffer cache + // `eb_set_buffer_name` will insert it into the cache. + // This is somewhat sloppy. + if (eb_set_buffer_name(b, name)) { + qe_free(&b); + return NULL; + } + /* add buffer in global buffer list (at end for system buffers) */ pb = &qs->first_buffer; if (*b->name == '*') { @@ -753,18 +766,6 @@ EditBuffer *eb_new(const char *name, int flags) return b; } -/* Return an empty scratch buffer, create one if necessary */ -EditBuffer *eb_scratch(const char *name, int flags) -{ - EditBuffer *b; - - b = eb_find_new(name, flags); - if (b != NULL) - eb_clear(b); - - return b; -} - void eb_clear(EditBuffer *b) { b->flags &= ~BF_READONLY; @@ -794,7 +795,7 @@ void eb_free(EditBuffer **bp) { if (*bp) { EditBuffer *b = *bp; - QEmacsState *qs = &qe_state; + QEmacsState *qs = b->qs; EditBuffer **pb; EditBuffer *b1; @@ -844,27 +845,14 @@ void eb_free(EditBuffer **bp) } } -EditBuffer *eb_find_new(const char *name, int flags) +EditBuffer *qe_find_buffer_file(QEmacsState *qs, const char *filename) { EditBuffer *b; - b = eb_find(name); - if (!b) - b = eb_new(name, flags); - return b; -} - -EditBuffer *eb_find_file(const char *filename) -{ - QEmacsState *qs = &qe_state; - EditBuffer *b; - - b = qs->first_buffer; - while (b != NULL) { + for (b = qs->first_buffer; b != NULL; b = b->next) { /* XXX: should also use stat to ensure this is same file */ if (strequal(b->filename, filename)) return b; - b = b->next; } return NULL; } @@ -872,19 +860,20 @@ EditBuffer *eb_find_file(const char *filename) /* Find a window attached to a given buffer, different from s */ EditState *eb_find_window(EditBuffer *b, EditState *s) { - QEmacsState *qs = &qe_state; EditState *e; - for (e = qs->first_window; e != NULL; e = e->next_window) { + if (!b) + return NULL; + + for (e = b->qs->first_window; e != NULL; e = e->next_window) { if (e != s && e->b == b) break; } return e; } -void eb_trace_bytes(const void *buf, int size, int state) +void qe_trace_bytes(QEmacsState *qs, const void *buf, int size, int state) { - QEmacsState *qs = &qe_state; EditBuffer *b = qs->trace_buffer; EditState *e; const char *str = NULL; @@ -1038,7 +1027,9 @@ int eb_create_style_buffer(EditBuffer *b, int flags) } else { char name[MAX_BUFFERNAME_SIZE]; snprintf(name, sizeof(name), "*S<%.*s>", MAX_BUFFERNAME_SIZE - 5, b->name); - b->b_styles = eb_new(name, BF_SYSTEM | BF_IS_STYLE | BF_RAW); + b->b_styles = qe_new_buffer(b->qs, name, BF_SYSTEM | BF_IS_STYLE | BF_RAW); + if (!b->b_styles) + return -1; b->flags |= flags & BF_STYLES; b->style_shift = (((unsigned)flags & BF_STYLES) / BF_STYLE1) - 1; b->style_bytes = 1 << b->style_shift; @@ -1154,7 +1145,7 @@ static void eb_addlog(EditBuffer *b, enum LogOperation op, * referenced by name. */ snprintf(buf, sizeof(buf), "*L<%.*s>", MAX_BUFFERNAME_SIZE - 5, b->name); - b->log_buffer = eb_new(buf, BF_SYSTEM | BF_IS_LOG | BF_RAW); + b->log_buffer = qe_new_buffer(b->qs, buf, BF_SYSTEM | BF_IS_LOG | BF_RAW); if (!b->log_buffer) return; b->log_new_index = 0; @@ -1229,7 +1220,7 @@ static void eb_addlog(EditBuffer *b, enum LogOperation op, void do_undo(EditState *s) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; EditBuffer *b = s->b; int log_index, size_trailer; LogBuffer lb; @@ -1244,8 +1235,8 @@ void do_undo(EditState *s) s->multi_cursor_active = 0; /* Should actually keep undo state current until new logs are added */ - if (s->qe_state->last_cmd_func != (CmdFunc)do_undo - && s->qe_state->last_cmd_func != (CmdFunc)do_redo) { + if (qs->last_cmd_func != (CmdFunc)do_undo + && qs->last_cmd_func != (CmdFunc)do_redo) { b->log_current = 0; } @@ -1328,8 +1319,8 @@ void do_redo(EditState *s) s->region_style = 0; /* Should actually keep undo state current until new logs are added */ - if (s->qe_state->last_cmd_func != (CmdFunc)do_undo - && s->qe_state->last_cmd_func != (CmdFunc)do_redo) { + if (s->qs->last_cmd_func != (CmdFunc)do_undo + && s->qs->last_cmd_func != (CmdFunc)do_redo) { b->log_current = 0; } @@ -1720,6 +1711,8 @@ int eb_goto_pos(EditBuffer *b, int line1, int col1) offset = 0; p = b->page_table; + if (!p) + return 0; p_end = b->page_table + b->nb_pages; while (p < p_end) { if (!(p->flags & PG_VALID_POS)) { @@ -1764,6 +1757,8 @@ int eb_get_pos(EditBuffer *b, int *line_ptr, int *col_ptr, int offset) line = 0; col = 0; p = b->page_table; + if (!p) + goto the_end; p_end = p + b->nb_pages; for (;;) { if (p >= p_end) @@ -2024,7 +2019,7 @@ int eb_raw_buffer_load1(EditBuffer *b, FILE *f, int offset) unsigned char buf[IOBUF_SIZE]; int len, size, inserted; - //put_status(NULL, "loading %s", filename); + //put_status(b->qs->active_window, "loading %s", filename); size = inserted = 0; for (;;) { len = fread(buf, 1, IOBUF_SIZE, f); @@ -2037,7 +2032,7 @@ int eb_raw_buffer_load1(EditBuffer *b, FILE *f, int offset) offset += len; size += len; } - //put_status(NULL, ""); + //put_status(b->qs->active_window, ""); return size; } @@ -2063,7 +2058,7 @@ int eb_mmap_buffer(EditBuffer *b, const char *filename) if (fd < 0) return -1; file_size = lseek(fd, 0, SEEK_END); - //put_status(NULL, "mapping %s", filename); + //put_status(b->qs->active_window, "mapping %s", filename); file_ptr = mmap(NULL, file_size, PROT_READ, MAP_SHARED, fd, 0); if ((void*)file_ptr == MAP_FAILED) { close(fd); @@ -2096,14 +2091,13 @@ int eb_mmap_buffer(EditBuffer *b, const char *filename) } // XXX: not needed b->map_handle = fd; - //put_status(NULL, ""); + //put_status(b->qs->active_window, ""); return 0; } #endif static int raw_buffer_load(EditBuffer *b, FILE *f) { - QEmacsState *qs = &qe_state; struct stat st; /* TODO: Should produce error messages */ @@ -2112,12 +2106,12 @@ static int raw_buffer_load(EditBuffer *b, FILE *f) return -1; #ifdef CONFIG_MMAP - if (st.st_size >= qs->mmap_threshold) { + if (st.st_size >= b->qs->mmap_threshold) { if (!eb_mmap_buffer(b, b->filename)) return 0; } #endif - if (st.st_size <= qs->max_load_size) { + if (st.st_size <= b->qs->max_load_size) { return eb_raw_buffer_load1(b, f, 0); } return -1; @@ -2136,7 +2130,7 @@ static int raw_buffer_save(EditBuffer *b, int start, int end, if (fd < 0) return -1; - //put_status(NULL, "writing %s", filename); + //put_status(b->qs->active_window, "writing %s", filename); if (end < start) { int tmp = start; start = end; @@ -2163,7 +2157,7 @@ static int raw_buffer_save(EditBuffer *b, int start, int end, size -= len; } close(fd); - //put_status(NULL, ""); + //put_status(b->qs->active_window, ""); return written; } @@ -2480,7 +2474,9 @@ int eb_insert_buffer_convert(EditBuffer *dest, int dest_offset, b = dest; if (!styles_flags && ((b->flags & BF_SAVELOG) || dest_offset != b->total_size)) { - b = eb_new("*tmp*", BF_SYSTEM); + b = qe_new_buffer(b->qs, "*tmp*", BF_SYSTEM); + if (!b) + return 0; eb_set_charset(b, dest->charset, dest->eol_type); offset1 = 0; } @@ -2812,9 +2808,8 @@ void eb_delete_properties(EditBuffer *b, int offset, int offset2) { /* buffer data type handling */ -void eb_register_data_type(EditBufferDataType *bdt) +void qe_register_data_type(QEmacsState *qs, EditBufferDataType *bdt) { - QEmacsState *qs = &qe_state; EditBufferDataType **lp; lp = &qs->first_buffer_data_type; @@ -2840,7 +2835,6 @@ int eb_write_buffer(EditBuffer *b, int start, int end, const char *filename) */ int eb_save_buffer(EditBuffer *b) { - QEmacsState *qs = &qe_state; int ret, st_mode; char buf1[MAX_FILENAME_SIZE]; const char *filename; @@ -2855,7 +2849,7 @@ int eb_save_buffer(EditBuffer *b) if (stat(filename, &st) == 0) st_mode = st.st_mode & 0777; - if (!qs->backup_inhibited + if (!b->qs->backup_inhibited && strlen(filename) < MAX_FILENAME_SIZE - 1) { /* backup old file if present */ if (snprintf(buf1, sizeof(buf1), "%s~", filename) < ssizeof(buf1)) { @@ -2898,7 +2892,7 @@ EditBufferDataType raw_data_type = { }; /* init buffer handling */ -void eb_init(QEmacsState *qs) +void qe_data_init(QEmacsState *qs) { - eb_register_data_type(&raw_data_type); + qe_register_data_type(qs, &raw_data_type); } diff --git a/charset.c b/charset.c index f174953..11067db 100644 --- a/charset.c +++ b/charset.c @@ -2,7 +2,7 @@ * Basic Charset functions for QEmacs * * Copyright (c) 2000-2002 Fabrice Bellard. - * Copyright (c) 2002-2023 Charlie Gordon. + * Copyright (c) 2002-2024 Charlie Gordon. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -974,7 +974,7 @@ struct QECharset charset_ucs4be = { /********************************************************/ /* generic charset functions */ -void qe_register_charset(struct QECharset *charset) +void qe_register_charset(struct QEmacsState *qs, struct QECharset *charset) { struct QECharset **pp; @@ -1010,7 +1010,7 @@ void charset_complete(CompleteState *cp, CompleteFunc enumerate) { } } -QECharset *find_charset(const char *name) +QECharset *qe_find_charset(struct QEmacsState *qs, const char *name) { QECharset *charset; @@ -1610,14 +1610,14 @@ int charset_goto_char_8bit(CharsetDecodeState *s, /********************************************************/ void charset_init(struct QEmacsState *qs) { - qe_register_charset(&charset_raw); - qe_register_charset(&charset_8859_1); - qe_register_charset(&charset_vt100); - qe_register_charset(&charset_7bit); - qe_register_charset(&charset_utf8); - qe_register_charset(&charset_utf8x); - qe_register_charset(&charset_ucs2le); - qe_register_charset(&charset_ucs2be); - qe_register_charset(&charset_ucs4le); - qe_register_charset(&charset_ucs4be); + qe_register_charset(qs, &charset_raw); + qe_register_charset(qs, &charset_8859_1); + qe_register_charset(qs, &charset_vt100); + qe_register_charset(qs, &charset_7bit); + qe_register_charset(qs, &charset_utf8); + qe_register_charset(qs, &charset_utf8x); + qe_register_charset(qs, &charset_ucs2le); + qe_register_charset(qs, &charset_ucs2be); + qe_register_charset(qs, &charset_ucs4le); + qe_register_charset(qs, &charset_ucs4be); } diff --git a/charset.h b/charset.h index aaa62c7..40822c5 100644 --- a/charset.h +++ b/charset.h @@ -2,7 +2,7 @@ * Charset definitions and functions for QEmacs * * Copyright (c) 2000-2001 Fabrice Bellard. - * Copyright (c) 2000-2023 Charlie Gordon. + * Copyright (c) 2000-2024 Charlie Gordon. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -103,13 +103,13 @@ struct CharsetDecodeState { struct QEmacsState; void charset_init(struct QEmacsState *qs); -int charset_more_init(struct QEmacsState *qs); -int charset_jis_init(struct QEmacsState *qs); +int qe_charset_more_init(struct QEmacsState *qs); +int qe_charset_jis_init(struct QEmacsState *qs); -void qe_register_charset(struct QECharset *charset); +void qe_register_charset(struct QEmacsState *qs, struct QECharset *charset); void charset_complete(CompleteState *cp, CompleteFunc enumerate); -QECharset *find_charset(const char *str); +QECharset *qe_find_charset(struct QEmacsState *qs, const char *str); void charset_decode_init(CharsetDecodeState *s, QECharset *charset, EOLType eol_type); void charset_decode_close(CharsetDecodeState *s); diff --git a/charsetjis.c b/charsetjis.c index 5db86a8..d9172d6 100644 --- a/charsetjis.c +++ b/charsetjis.c @@ -2,7 +2,7 @@ * JIS Charset handling for QEmacs * * Copyright (c) 2002 Fabrice Bellard. - * Copyright (c) 2002-2023 Charlie Gordon. + * Copyright (c) 2002-2024 Charlie Gordon. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -243,12 +243,12 @@ static struct QECharset charset_sjis = { .eol_char = 10, }; -int charset_jis_init(QEmacsState *qs) +int qe_charset_jis_init(QEmacsState *qs) { - qe_register_charset(&charset_sjis); - qe_register_charset(&charset_euc_jp); + qe_register_charset(qs, &charset_sjis); + qe_register_charset(qs, &charset_euc_jp); return 0; } -qe_module_init(charset_jis_init); +qe_module_init(qe_charset_jis_init); diff --git a/charsetmore.c b/charsetmore.c index a7d4db4..80375ec 100644 --- a/charsetmore.c +++ b/charsetmore.c @@ -4,7 +4,7 @@ * More Charsets and Tables for QEmacs * * Copyright (c) 2002 Fabrice Bellard. - * Copyright (c) 2002-2023 Charlie Gordon. + * Copyright (c) 2002-2024 Charlie Gordon. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -1838,48 +1838,48 @@ static struct QECharset charset_atarist = { .private_table = table_atarist, }; -int charset_more_init(QEmacsState *qs) +int qe_charset_more_init(QEmacsState *qs) { - qe_register_charset(&charset_8859_2); - qe_register_charset(&charset_8859_3); - qe_register_charset(&charset_8859_4); - qe_register_charset(&charset_8859_5); - qe_register_charset(&charset_8859_6); - qe_register_charset(&charset_8859_7); - qe_register_charset(&charset_8859_8); - qe_register_charset(&charset_8859_9); - qe_register_charset(&charset_8859_10); - qe_register_charset(&charset_8859_11); - qe_register_charset(&charset_8859_13); - qe_register_charset(&charset_8859_14); - qe_register_charset(&charset_8859_15); - qe_register_charset(&charset_8859_16); - qe_register_charset(&charset_cp437); - qe_register_charset(&charset_cp737); - qe_register_charset(&charset_cp850); - qe_register_charset(&charset_cp852); - qe_register_charset(&charset_cp866); - qe_register_charset(&charset_cp1125); - qe_register_charset(&charset_cp1250); - qe_register_charset(&charset_cp1251); - qe_register_charset(&charset_cp1252); - qe_register_charset(&charset_cp1256); - qe_register_charset(&charset_cp1257); - qe_register_charset(&charset_mac_latin2); - qe_register_charset(&charset_mac_roman); - qe_register_charset(&charset_kamen); - qe_register_charset(&charset_koi8_r); - qe_register_charset(&charset_koi8_u); - qe_register_charset(&charset_tcvn); - qe_register_charset(&charset_viscii); - qe_register_charset(&charset_cp037); - qe_register_charset(&charset_cp424); - qe_register_charset(&charset_cp500); - qe_register_charset(&charset_cp875); - qe_register_charset(&charset_cp1026); - qe_register_charset(&charset_atarist); + qe_register_charset(qs, &charset_8859_2); + qe_register_charset(qs, &charset_8859_3); + qe_register_charset(qs, &charset_8859_4); + qe_register_charset(qs, &charset_8859_5); + qe_register_charset(qs, &charset_8859_6); + qe_register_charset(qs, &charset_8859_7); + qe_register_charset(qs, &charset_8859_8); + qe_register_charset(qs, &charset_8859_9); + qe_register_charset(qs, &charset_8859_10); + qe_register_charset(qs, &charset_8859_11); + qe_register_charset(qs, &charset_8859_13); + qe_register_charset(qs, &charset_8859_14); + qe_register_charset(qs, &charset_8859_15); + qe_register_charset(qs, &charset_8859_16); + qe_register_charset(qs, &charset_cp437); + qe_register_charset(qs, &charset_cp737); + qe_register_charset(qs, &charset_cp850); + qe_register_charset(qs, &charset_cp852); + qe_register_charset(qs, &charset_cp866); + qe_register_charset(qs, &charset_cp1125); + qe_register_charset(qs, &charset_cp1250); + qe_register_charset(qs, &charset_cp1251); + qe_register_charset(qs, &charset_cp1252); + qe_register_charset(qs, &charset_cp1256); + qe_register_charset(qs, &charset_cp1257); + qe_register_charset(qs, &charset_mac_latin2); + qe_register_charset(qs, &charset_mac_roman); + qe_register_charset(qs, &charset_kamen); + qe_register_charset(qs, &charset_koi8_r); + qe_register_charset(qs, &charset_koi8_u); + qe_register_charset(qs, &charset_tcvn); + qe_register_charset(qs, &charset_viscii); + qe_register_charset(qs, &charset_cp037); + qe_register_charset(qs, &charset_cp424); + qe_register_charset(qs, &charset_cp500); + qe_register_charset(qs, &charset_cp875); + qe_register_charset(qs, &charset_cp1026); + qe_register_charset(qs, &charset_atarist); return 0; } -qe_module_init(charset_more_init); +qe_module_init(qe_charset_more_init); diff --git a/cutils.h b/cutils.h index e70ffba..da81e15 100644 --- a/cutils.h +++ b/cutils.h @@ -38,7 +38,7 @@ #define qe__attr_printf(a, b) #endif -#if defined(__GNUC__) && __GNUC__ > 2 +#if (defined(__GNUC__) && __GNUC__ > 2) || (defined(__clang__) && __clang_major__ >= 12) #define qe__attr_nonnull(l) __attribute__((nonnull l)) #define qe__unused__ __attribute__((unused)) #define likely(x) __builtin_expect(!!(x), 1) diff --git a/display.c b/display.c index 898cd9c..e1e8828 100644 --- a/display.c +++ b/display.c @@ -29,8 +29,9 @@ static QEDisplay *first_dpy; /* dummy display driver for initialization time */ -static int dummy_dpy_init(QEditScreen *s, qe__unused__ int w, qe__unused__ int h) +static int dummy_dpy_init(QEditScreen *s, QEmacsState *qs, qe__unused__ int w, qe__unused__ int h) { + s->qs = qs; s->charset = &charset_8859_1; return 0; @@ -129,6 +130,7 @@ static QEDisplay const dummy_dpy = { NULL, /* dpy_describe */ NULL, /* dpy_sound_bell */ NULL, /* dpy_suspend */ + NULL, /* dpy_error */ NULL, /* next */ }; @@ -237,7 +239,7 @@ void push_clip_rectangle(QEditScreen *s, CSSRect *r0, CSSRect *r) s->dpy.dpy_set_clip(s, x1, y1, x2 - x1, y2 - y1); } -int qe_register_display(QEDisplay *dpy) +int qe_register_display(QEmacsState *qs, QEDisplay *dpy) { QEDisplay **pp; @@ -268,10 +270,10 @@ QEDisplay *probe_display(void) return dpy; } -int screen_init(QEditScreen *s, QEDisplay *dpy, int w, int h) +int qe_screen_init(QEmacsState *qs, QEditScreen *s, QEDisplay *dpy, int w, int h) { s->dpy = dpy ? *dpy : dummy_dpy; - return s->dpy.dpy_init(s, w, h); + return s->dpy.dpy_init(s, qs, w, h); } /* simple font cache */ @@ -313,7 +315,7 @@ QEFont *select_font(QEditScreen *s, int style, int size) } /* not found : open new font */ if (min_index < 0) { - put_error(NULL, "Font cache full"); + dpy_error(s, "Font cache full"); goto fail; } if (font_cache[min_index]) { @@ -324,7 +326,7 @@ QEFont *select_font(QEditScreen *s, int style, int size) if (style & QE_FONT_FAMILY_FALLBACK_MASK) return NULL; - put_error(NULL, "open_font: cannot open style=%X size=%d", + dpy_error(s, "open_font: cannot open style=%X size=%d", style, size); goto fail; } diff --git a/display.h b/display.h index e2b640f..d2178d2 100644 --- a/display.h +++ b/display.h @@ -71,6 +71,7 @@ typedef struct QEPicture { int tcolor; } QEPicture; +struct QEmacsState; typedef struct QEditScreen QEditScreen; typedef struct QEDisplay QEDisplay; struct EditBuffer; @@ -80,7 +81,7 @@ struct QEDisplay { const char *name; int xfactor, yfactor; int (*dpy_probe)(void); - int (*dpy_init)(QEditScreen *s, int w, int h); + int (*dpy_init)(QEditScreen *s, struct QEmacsState *qs, int w, int h); void (*dpy_close)(QEditScreen *s); void (*dpy_flush)(QEditScreen *s); int (*dpy_is_user_input_pending)(QEditScreen *s); @@ -123,15 +124,17 @@ struct QEDisplay { void (*dpy_describe)(QEditScreen *s, struct EditBuffer *b); void (*dpy_sound_bell)(QEditScreen *s); void (*dpy_suspend)(QEditScreen *s); + void (*dpy_error)(QEditScreen *s, const char *fmt, ...); QEDisplay *next; }; struct QEditScreen { QEDisplay dpy; + struct QEmacsState *qs; FILE *STDIN, *STDOUT; int width, height; const struct QECharset *charset; /* the charset of the TTY, XXX: suppress that, - use a system in fonts instead */ + use a system in fonts instead */ int unicode_version; int media; /* media type (see CSS_MEDIA_xxx) */ QEBitmapFormat bitmap_format; /* supported bitmap format */ @@ -142,10 +145,10 @@ struct QEditScreen { void *priv_data; }; -int qe_register_display(QEDisplay *dpy); +int qe_register_display(struct QEmacsState *qs, QEDisplay *dpy); QEDisplay *probe_display(void); -int screen_init(QEditScreen *s, QEDisplay *dpy, int w, int h); +int qe_screen_init(struct QEmacsState *qs, QEditScreen *s, QEDisplay *dpy, int w, int h); static inline void dpy_close(QEditScreen *s) { @@ -243,6 +246,8 @@ static inline void dpy_sound_bell(QEditScreen *s) s->dpy.dpy_sound_bell(s); } +#define dpy_error(ds, ...) do { if ((ds)->dpy.dpy_error) ((ds)->dpy.dpy_error)(ds, __VA_ARGS__); } while (0) + /* XXX: only needed for backward compatibility */ static inline int glyph_width(QEditScreen *s, QEFont *font, char32_t ch) { char32_t buf[1]; diff --git a/extras.c b/extras.c index d7a888d..8afdf46 100644 --- a/extras.c +++ b/extras.c @@ -51,7 +51,7 @@ void delete_equivalent(Equivalent *ep) { static void do_define_equivalent(EditState *s, const char *str1, const char *str2) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; Equivalent **epp; /* append the definition, ignore duplicates */ @@ -65,7 +65,7 @@ static void do_define_equivalent(EditState *s, const char *str1, const char *str static void do_delete_equivalent(EditState *s, const char *str) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; Equivalent **epp; for (epp = &qs->first_equivalent; *epp; epp = &(*epp)->next) { @@ -79,11 +79,11 @@ static void do_delete_equivalent(EditState *s, const char *str) static void do_list_equivalents(EditState *s, int argval) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; EditBuffer *b; Equivalent *ep; - b = new_help_buffer(); + b = new_help_buffer(s); if (!b) return; @@ -94,7 +94,7 @@ static void do_list_equivalents(EditState *s, int argval) show_popup(s, b, "Equivalents"); } -static void qs_free_equivalent(QEmacsState *qs) { +static void qe_free_equivalent(QEmacsState *qs) { while (qs->first_equivalent) { Equivalent *ep = qs->first_equivalent; qs->first_equivalent = ep->next; @@ -106,7 +106,7 @@ static int qe_skip_equivalent(EditState *s, EditBuffer *b1, int offset1, int *offset1p, EditBuffer *b2, int offset2, int *offset2p) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; Equivalent *ep; int end1, end2; @@ -227,7 +227,7 @@ static char *utf8_char32_to_string(char *buf, char32_t c) { void do_compare_windows(EditState *s, int argval) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; EditState *s1; EditState *s2; int offset1, offset2, size1, size2; @@ -417,7 +417,7 @@ void do_compare_files(EditState *s, const char *filename, int bflags) do_delete_other_windows(s, 0); e = qe_split_window(s, SW_STACKED, 50); if (e) { - s->qe_state->active_window = e; + s->qs->active_window = e; do_find_file(e, buf, bflags); } } @@ -429,7 +429,7 @@ void do_compare_files(EditState *s, const char *filename, int bflags) static void do_adjust_window(EditState *s, int argval, int flags) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; EditState *e; int delta, x = -1, y = -1; @@ -745,7 +745,7 @@ static void do_indent_rigidly(EditState *s, int start, int end, int argval) { if (argval == NO_ARG) { /* enter interactive mode */ - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; if (!qs->first_transient_key) { s->region_style = QE_STYLE_REGION_HILITE; put_status(s, "indent the region interactively with TAB, left, right, S-left, S-right"); @@ -767,7 +767,7 @@ static void do_indent_region(EditState *s, int start, int end, int argval) s->region_style = 0; if (argval < 0 || !s->mode->indent_func - || s->qe_state->last_cmd_func == (CmdFunc)do_indent_region) { + || s->qs->last_cmd_func == (CmdFunc)do_indent_region) { do_indent_rigidly_to_tab_stop(s, start, end, argval); return; } @@ -1054,7 +1054,7 @@ static void do_kill_block(EditState *s, int n) void do_transpose(EditState *s, int cmd) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; int offset0, offset1, offset2, offset3; int start_offset, end_offset; int size0, size1, size2; @@ -1158,6 +1158,7 @@ void do_transpose(EditState *s, int cmd) size1 = offset2 - offset1; size2 = offset3 - offset2; + // XXX: should have a way to move buffer contents if (!b->b_styles && size0 + size1 + size2 <= 1024) { u8 buf[1024]; /* Use fast method and generate single undo record */ @@ -1166,8 +1167,9 @@ void do_transpose(EditState *s, int cmd) eb_read(b, offset0, buf + size2 + size1, size0); eb_write(b, offset0, buf, size0 + size1 + size2); } else { - EditBuffer *b1 = eb_new("*tmp*", BF_SYSTEM | (b->flags & BF_STYLES)); - + EditBuffer *b1 = qe_new_buffer(qs, "*tmp*", BF_SYSTEM | (b->flags & BF_STYLES)); + if (!b1) + return; eb_set_charset(b1, b->charset, b->eol_type); /* Use eb_insert_buffer_convert to copy styles. * This conversion should not change sizes */ @@ -1184,19 +1186,19 @@ void do_transpose(EditState *s, int cmd) /*---------------- help ----------------*/ -int qe_list_bindings(const CmdDef *d, ModeDef *mode, int inherit, char *buf, int size) +int qe_list_bindings(QEmacsState *qs, const CmdDef *d, ModeDef *mode, int inherit, char *buf, int size) { buf_t outbuf, *out; ModeDef *mode0 = mode; out = buf_init(&outbuf, buf, size); for (;;) { - KeyDef *kd = mode ? mode->first_key : qe_state.first_key; + KeyDef *kd = mode ? mode->first_key : qs->first_key; for (; kd != NULL; kd = kd->next) { /* do not list overridden bindings */ if (kd->cmd == d - && qe_find_current_binding(kd->keys, kd->nb_keys, mode0, 1) == kd) { + && qe_find_current_binding(qs, kd->keys, kd->nb_keys, mode0, 1) == kd) { if (out->len > 0) buf_puts(out, ", "); @@ -1214,13 +1216,14 @@ int qe_list_bindings(const CmdDef *d, ModeDef *mode, int inherit, char *buf, int void do_show_bindings(EditState *s, const char *cmd_name) { char buf[256]; + QEmacsState *qs = s->qs; const CmdDef *d; - if ((d = qe_find_cmd(cmd_name)) == NULL) { + if ((d = qe_find_cmd(qs, cmd_name)) == NULL) { put_status(s, "No command %s", cmd_name); return; } - if (qe_list_bindings(d, s->mode, 1, buf, sizeof(buf))) { + if (qe_list_bindings(qs, d, s->mode, 1, buf, sizeof(buf))) { put_status(s, "%s is bound to %s", cmd_name, buf); } else { put_status(s, "%s is not bound to any key", cmd_name); @@ -1232,11 +1235,11 @@ static void do_describe_function(EditState *s, const char *cmd_name) { const CmdDef *d; const char *desc; - if ((d = qe_find_cmd(cmd_name)) == NULL) { + if ((d = qe_find_cmd(s->qs, cmd_name)) == NULL) { put_status(s, "No command %s", cmd_name); return; } - b = new_help_buffer(); + b = new_help_buffer(s); if (!b) return; @@ -1266,7 +1269,7 @@ static int eb_sort_span(EditBuffer *b, int *pp1, int *pp2, int cur_offset, int f static void print_bindings(EditBuffer *b, ModeDef *mode) { - struct QEmacsState *qs = &qe_state; + struct QEmacsState *qs = b->qs; char buf[256]; const CmdDef *d; int gfound, start, stop, i, j; @@ -1275,7 +1278,7 @@ static void print_bindings(EditBuffer *b, ModeDef *mode) gfound = 0; for (i = 0; i < qs->cmd_array_count; i++) { for (j = qs->cmd_array[i].count, d = qs->cmd_array[i].array; j-- > 0; d++) { - if (qe_list_bindings(d, mode, 0, buf, sizeof(buf))) { + if (qe_list_bindings(qs, d, mode, 0, buf, sizeof(buf))) { if (!gfound) { if (mode) { eb_printf(b, "\n%s mode bindings:\n\n", mode->name); @@ -1299,7 +1302,7 @@ void do_describe_bindings(EditState *s, int argval) { EditBuffer *b; - b = new_help_buffer(); + b = new_help_buffer(s); if (!b) return; @@ -1311,14 +1314,14 @@ void do_describe_bindings(EditState *s, int argval) void do_apropos(EditState *s, const char *str) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; char buf[256]; EditBuffer *b; const CmdDef *d; VarDef *vp; int start, stop, i, j, extra; - b = new_help_buffer(); + b = new_help_buffer(s); if (!b) return; @@ -1381,14 +1384,17 @@ extern char **environ; static void do_about_qemacs(EditState *s) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; char buf[256]; EditBuffer *b; ModeDef *m; const CmdDef *d; int start, stop, i, j; - b = eb_scratch("*About QEmacs*", BF_UTF8); + b = qe_new_buffer(qs, "*About QEmacs*", BC_REUSE | BC_CLEAR | BF_UTF8); + if (!b) + return; + eb_printf(b, "\n %s\n\n%s\n", str_version, str_credits); /* list current bindings */ @@ -1593,7 +1599,7 @@ static void do_set_style_color(EditState *e, const char *stylestr, const char *v return; } } - e->qe_state->complete_refresh = 1; + e->qs->complete_refresh = 1; } static void do_set_region_color(EditState *s, const char *str) @@ -1685,7 +1691,7 @@ static void do_describe_buffer(EditState *s, int argval) EditBuffer *b = s->b; EditBuffer *b1; - b1 = new_help_buffer(); + b1 = new_help_buffer(s); if (!b1) return; @@ -1864,7 +1870,7 @@ static void do_describe_window(EditState *s, int argval) EditBuffer *b1; int w; - b1 = new_help_buffer(); + b1 = new_help_buffer(s); if (!b1) return; @@ -1956,7 +1962,7 @@ static void do_describe_screen(EditState *e, int argval) EditBuffer *b1; int w; - b1 = new_help_buffer(); + b1 = new_help_buffer(e); if (!b1) return; @@ -2016,8 +2022,8 @@ static int chunk_cmp(void *vp0, const void *vp1, const void *vp2) { int pos1, pos2; if ((++cp->ncmp & 8191) == 8191) { - QEmacsState *qs = &qe_state; - put_status(NULL, "Sorting: %d%%", (int)((cp->ncmp * 90LL) / cp->total_cmp)); + QEmacsState *qs = cp->b->qs; + put_status(qs->active_window, "Sorting: %d%%", (int)((cp->ncmp * 90LL) / cp->total_cmp)); dpy_flush(qs->screen); } if (cp->flags & SF_REVERSE) { @@ -2199,7 +2205,9 @@ static int eb_sort_span(EditBuffer *b, int *pp1, int *pp2, int cur_offset, int f } qe_qsort_r(chunk_array, lines, sizeof(*chunk_array), &ctx, chunk_cmp); - b1 = eb_new("*sorted*", BF_SYSTEM | (b->flags & BF_STYLES)); + b1 = qe_new_buffer(b->qs, "*sorted*", BF_SYSTEM | (b->flags & BF_STYLES)); + if (!b1) + return -1; eb_set_charset(b1, b->charset, b->eol_type); for (i = 0; i < lines; i++) { @@ -2209,9 +2217,8 @@ static int eb_sort_span(EditBuffer *b, int *pp1, int *pp2, int cur_offset, int f // XXX: style issue. Should include newline from source buffer eb_putc(b1, '\n'); if ((i & 8191) == 8191 && !(flags & SF_SILENT)) { - QEmacsState *qs = &qe_state; - put_status(NULL, "Sorting: %d%%", (int)(90 + i * 10LL / lines)); - dpy_flush(qs->screen); + put_status(b->qs->active_window, "Sorting: %d%%", (int)(90 + i * 10LL / lines)); + dpy_flush(b->qs->screen); } } eb_delete_range(b, p1, p2); @@ -2221,7 +2228,7 @@ static int eb_sort_span(EditBuffer *b, int *pp1, int *pp2, int cur_offset, int f qe_free(&chunk_array); done: if (!(flags & SF_SILENT)) - put_status(NULL, "%d lines sorted", lines); + put_status(b->qs->active_window, "%d lines sorted", lines); return 0; } @@ -2308,7 +2315,7 @@ static int tag_get_entry(EditState *s, char *dest, int size, int offset) } static void do_find_tag(EditState *s, const char *str) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; QEProperty *p; int offset = -1; @@ -2360,7 +2367,7 @@ static void do_list_tags(EditState *s, int argval) { QEProperty *p; EditState *e1; - b = new_help_buffer(); + b = new_help_buffer(s); if (!b) return; @@ -2395,12 +2402,13 @@ static CompletionDef tag_completion = { static void charname_complete(CompleteState *cp, CompleteFunc enumerate) { char buf[256]; char entry[264]; // silence compiler warning on snprintf calls below + QEmacsState *qs = cp->s->qs; FILE *fp; /* enumerate Unicode character names from Unicode consortium data */ - if ((fp = open_resource_file("DerivedName-15.0.0.txt")) != NULL - || (fp = open_resource_file("DerivedName.txt")) != NULL - || (fp = open_resource_file("extracted/DerivedName.txt")) != NULL) { + if ((fp = qe_open_resource_file(qs, "DerivedName-15.0.0.txt")) != NULL + || (fp = qe_open_resource_file(qs, "DerivedName.txt")) != NULL + || (fp = qe_open_resource_file(qs, "extracted/DerivedName.txt")) != NULL) { while (fgets(buf, sizeof buf, fp)) { char *p1, *p2, *p3; if ((p1 = strchr(buf, ';')) != NULL @@ -2419,8 +2427,8 @@ static void charname_complete(CompleteState *cp, CompleteFunc enumerate) { } fclose(fp); } else - if ((fp = open_resource_file("UnicodeData-15.0.0.txt")) != NULL - || (fp = open_resource_file("UnicodeData.txt")) != NULL) { + if ((fp = qe_open_resource_file(qs, "UnicodeData-15.0.0.txt")) != NULL + || (fp = qe_open_resource_file(qs, "UnicodeData.txt")) != NULL) { while (fgets(buf, sizeof buf, fp)) { char *p1, *p2; if ((p1 = strchr(buf, ';')) != NULL @@ -2439,17 +2447,18 @@ static void charname_complete(CompleteState *cp, CompleteFunc enumerate) { } } -static long charname_convert_entry(const char *str, const char **endp) { +static long charname_convert_entry(EditState *s, const char *str, const char **endp) { char buf[256]; + QEmacsState *qs = s->qs; FILE *fp; long code = strtol_c(str, endp, 0); if (**endp == '\0') return code; /* enumerate Unicode character names from Unicode consortium data */ - if ((fp = open_resource_file("DerivedName-15.0.0.txt")) != NULL - || (fp = open_resource_file("DerivedName.txt")) != NULL - || (fp = open_resource_file("extracted/DerivedName.txt")) != NULL) { + if ((fp = qe_open_resource_file(qs, "DerivedName-15.0.0.txt")) != NULL + || (fp = qe_open_resource_file(qs, "DerivedName.txt")) != NULL + || (fp = qe_open_resource_file(qs, "extracted/DerivedName.txt")) != NULL) { while (fgets(buf, sizeof buf, fp)) { char *p1, *p2; if ((p1 = strchr(buf, ';')) != NULL @@ -2465,8 +2474,8 @@ static long charname_convert_entry(const char *str, const char **endp) { } fclose(fp); } else - if ((fp = open_resource_file("UnicodeData-15.0.0.txt")) != NULL - || (fp = open_resource_file("UnicodeData.txt")) != NULL) { + if ((fp = qe_open_resource_file(qs, "UnicodeData-15.0.0.txt")) != NULL + || (fp = qe_open_resource_file(qs, "UnicodeData.txt")) != NULL) { while (fgets(buf, sizeof buf, fp)) { char *p1, *p2; if ((p1 = strchr(buf, ';')) != NULL @@ -2695,7 +2704,7 @@ int eb_skip_paragraphs(EditBuffer *b, int offset, int n) { } void do_forward_paragraph(EditState *s, int n) { - maybe_set_mark(s); + do_maybe_set_mark(s); s->offset = eb_skip_paragraphs(s->b, s->offset, n); } @@ -3006,7 +3015,7 @@ int eb_skip_sentences(EditBuffer *b, int offset, int n) { } void do_forward_sentence(EditState *s, int n) { - maybe_set_mark(s); + do_maybe_set_mark(s); s->offset = eb_skip_sentences(s->b, s->offset, n); } @@ -3341,15 +3350,15 @@ static const CmdDef extra_commands[] = { }; static int extras_init(QEmacsState *qs) { - qe_register_commands(NULL, extra_commands, countof(extra_commands)); - qe_register_completion(&tag_completion); - qe_register_completion(&charname_completion); + qe_register_commands(qs, NULL, extra_commands, countof(extra_commands)); + qe_register_completion(qs, &tag_completion); + qe_register_completion(qs, &charname_completion); return 0; } static void extras_exit(QEmacsState *qs) { - qs_free_equivalent(qs); + qe_free_equivalent(qs); } qe_module_init(extras_init); diff --git a/haiku.cpp b/haiku.cpp index 76254c7..194f354 100644 --- a/haiku.cpp +++ b/haiku.cpp @@ -362,7 +362,7 @@ extern int32 atomic_get_and_set(int32 *p, int32 v); static void haiku_handle_event(void *opaque) { QEditScreen *s = (QEditScreen *)opaque; - QEmacsState *qs = &qe_state; + QEmacsState *qs = s->qs; WindowState *ctx = (WindowState *)s->priv_data; bigtime_t timestamp_ms; BMessage *event; @@ -895,13 +895,12 @@ static QEDisplay haiku_dpy = { NULL, /* dpy_describe */ NULL, /* dpy_sound_bell */ NULL, /* dpy_suspend */ + qe_dpy_error, /* dpy_error */ NULL, /* next */ }; static int haiku_module_init(QEmacsState *qs) { - QEmacsState *qs = &qe_state; - /* override default res path, to find config file at native location */ BPath path; BString old(":"); @@ -916,7 +915,7 @@ static int haiku_module_init(QEmacsState *qs) if (force_tty) return 0; - return qe_register_display(&haiku_dpy); + return qe_register_display(qs, &haiku_dpy); } qe_module_init(haiku_module_init); diff --git a/html2png.c b/html2png.c index 1f9fb2b..a09b28e 100644 --- a/html2png.c +++ b/html2png.c @@ -76,13 +76,14 @@ void css_close(CSSFile **f2) /* error display */ -void css_error(const char *filename, int line_num, +void css_error(void *error_opaque, const char *filename, int line_num, const char *msg) { fprintf(stderr, "%s:%d: %s\n", filename, line_num, msg); } -void put_error(qe__unused__ EditState *s, const char *fmt, ...) +static void ppm_error(QEditScreen *s, const char *fmt, ...) qe__attr_printf(2,3); +static void ppm_error(qe__unused__ QEditScreen *s, const char *fmt, ...) { va_list ap; @@ -92,7 +93,6 @@ void put_error(qe__unused__ EditState *s, const char *fmt, ...) putc('\n', stderr); } - /* dummy functions */ char32_t eb_nextc(qe__unused__ EditBuffer *b, qe__unused__ int offset, qe__unused__ int *next_ptr) @@ -102,15 +102,16 @@ char32_t eb_nextc(qe__unused__ EditBuffer *b, /* display driver based on cfb driver */ -static int ppm_init(QEditScreen *s, int w, int h); +static int ppm_init(QEditScreen *s, QEmacsState *qs, int w, int h); static void ppm_close(QEditScreen *s); +static void ppm_flush(QEditScreen *s) {} static QEDisplay ppm_dpy = { "ppm", 1, 1, NULL, ppm_init, ppm_close, - NULL, /* dpy_flush */ + ppm_flush, /* dpy_flush */ NULL, /* dpy_is_user_input_pending */ NULL, /* dpy_fill_rectangle */ NULL, /* dpy_xor_rectangle */ @@ -133,6 +134,7 @@ static QEDisplay ppm_dpy = { NULL, /* dpy_describe */ NULL, /* dpy_sound_bell */ NULL, /* dpy_suspend */ + ppm_error, /* dpy_error */ NULL, /* next */ }; @@ -157,7 +159,7 @@ static int ppm_resize(QEditScreen *s, int w, int h) return 0; } -static int ppm_init(QEditScreen *s, int w, int h) +static int ppm_init(QEditScreen *s, QEmacsState *qs, int w, int h) { CFBContext *cfb; @@ -165,6 +167,7 @@ static int ppm_init(QEditScreen *s, int w, int h) if (!cfb) return -1; + s->qs = qs; s->priv_data = cfb; s->media = CSS_MEDIA_SCREEN; @@ -353,7 +356,7 @@ static int draw_html(QEditScreen *scr, /* prepare default style sheet */ s->style_sheet = css_new_style_sheet(); - css_parse_style_sheet_str(s->style_sheet, html_style, flags); + css_parse_style_sheet_str(s->style_sheet, scr->qs, html_style, flags); /* default colors */ s->selection_bgcolor = QERGB(0x00, 0x00, 0xff); @@ -366,7 +369,7 @@ static int draw_html(QEditScreen *scr, if (!f) goto fail; - xml = xml_begin(s->style_sheet, flags, html_test_abort, NULL, filename, charset); + xml = xml_begin(s->style_sheet, flags, html_test_abort, NULL, scr->qs, filename, charset); for (;;) { len = css_read(f, buf, IO_BUF_SIZE); @@ -439,8 +442,8 @@ int main(int argc, char **argv) qs = memset(&state, 0, sizeof state); charset_init(qs); - charset_more_init(qs); - charset_jis_init(qs); + qe_charset_more_init(qs); + qe_charset_jis_init(qs); css_init(); page_width = DEFAULT_WIDTH; @@ -464,7 +467,7 @@ int main(int argc, char **argv) outfilename = optarg; break; case 'f': - charset = find_charset(optarg); + charset = qe_find_charset(qs, optarg); if (!charset) { QECharset *p; fprintf(stderr, "Unknown charset '%s'\n", optarg); @@ -487,7 +490,7 @@ int main(int argc, char **argv) infilename = argv[optind]; /* init display driver with dummy height */ - if (screen_init(screen, &ppm_dpy, page_width, 1) < 0) { + if (qe_screen_init(qs, screen, &ppm_dpy, page_width, 1) < 0) { fprintf(stderr, "Could not init display driver\n"); exit(1); } diff --git a/input.c b/input.c index e23b603..0f17233 100644 --- a/input.c +++ b/input.c @@ -71,9 +71,8 @@ static InputMethod unicode_input_method = { "unicode", unicode_input, NULL, NULL, }; -void register_input_method(InputMethod *m) +void qe_register_input_method(QEmacsState *qs, InputMethod *m) { - QEmacsState *qs = &qe_state; InputMethod **p; p = &qs->input_methods; @@ -85,7 +84,7 @@ void register_input_method(InputMethod *m) } static void input_complete(CompleteState *cp, CompleteFunc enumerate) { - QEmacsState *qs = cp->s->qe_state; + QEmacsState *qs = cp->s->qs; InputMethod *m; for (m = qs->input_methods; m != NULL; m = m->next) { @@ -93,9 +92,8 @@ static void input_complete(CompleteState *cp, CompleteFunc enumerate) { } } -static InputMethod *find_input_method(const char *name) +static InputMethod *qe_find_input_method(QEmacsState *qs, const char *name) { - QEmacsState *qs = &qe_state; InputMethod *m; for (m = qs->input_methods; m != NULL; m = m->next) { @@ -107,7 +105,7 @@ static InputMethod *find_input_method(const char *name) void do_set_input_method(EditState *s, const char *name) { - InputMethod *m = find_input_method(name); + InputMethod *m = qe_find_input_method(s->qs, name); if (m) { s->input_method = m; @@ -130,9 +128,9 @@ static CompletionDef input_completion = { .enumerate = input_complete, }; -void input_methods_init(QEmacsState *qs) +void qe_input_methods_init(QEmacsState *qs) { - register_input_method(&default_input_method); - register_input_method(&unicode_input_method); - qe_register_completion(&input_completion); + qe_register_input_method(qs, &default_input_method); + qe_register_input_method(qs, &unicode_input_method); + qe_register_completion(qs, &input_completion); } diff --git a/kmap.c b/kmap.c index e41cdbb..3e17e54 100644 --- a/kmap.c +++ b/kmap.c @@ -172,7 +172,7 @@ static size_t input_method_size; #endif static void *input_method_ptr; -int load_input_methods(const char *filename) +int qe_load_input_methods(QEmacsState *qs, const char *filename) { ssize_t file_size; int fd, offset; @@ -220,19 +220,19 @@ int load_input_methods(const char *filename) m->data = file_ptr + offset; m->input_match = kmap_input; m->name = (const char*)p; - register_input_method(m); + qe_register_input_method(qs, m); } p += strlen((const char *)p) + 1; } return 0; fail: - unload_input_methods(); + qe_unload_input_methods(qs); close(fd); return -1; } -void unload_input_methods(void) +void qe_unload_input_methods(QEmacsState *qs) { /* Should unregister input methods, but this is only called upon exit */ #ifdef CONFIG_MMAP diff --git a/lang/ada.c b/lang/ada.c index d4ef0a5..5460793 100644 --- a/lang/ada.c +++ b/lang/ada.c @@ -199,7 +199,7 @@ static ModeDef ada_mode = { }; static int ada_init(QEmacsState *qs) { - qe_register_mode(&ada_mode, MODEF_SYNTAX); + qe_register_mode(qs, &ada_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/agena.c b/lang/agena.c index 3a4033c..02dc250 100644 --- a/lang/agena.c +++ b/lang/agena.c @@ -199,8 +199,7 @@ static ModeDef agena_mode = { static int agena_init(QEmacsState *qs) { - qe_register_mode(&agena_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &agena_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/arm.c b/lang/arm.c index 64a4be3..42ee8b1 100644 --- a/lang/arm.c +++ b/lang/arm.c @@ -175,7 +175,7 @@ static ModeDef arm_asm_mode = { static int arm_asm_init(QEmacsState *qs) { - qe_register_mode(&arm_asm_mode, MODEF_SYNTAX); + qe_register_mode(qs, &arm_asm_mode, MODEF_SYNTAX); return 0; } @@ -302,7 +302,7 @@ static ModeDef arm_lst_mode = { static int arm_lst_init(QEmacsState *qs) { - qe_register_mode(&arm_lst_mode, MODEF_SYNTAX); + qe_register_mode(qs, &arm_lst_mode, MODEF_SYNTAX); return 0; } @@ -371,7 +371,7 @@ static ModeDef intel_hex_mode = { static int intel_hex_init(QEmacsState *qs) { - qe_register_mode(&intel_hex_mode, MODEF_SYNTAX); + qe_register_mode(qs, &intel_hex_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/asm.c b/lang/asm.c index 26dbe5a..db5c1d9 100644 --- a/lang/asm.c +++ b/lang/asm.c @@ -166,8 +166,7 @@ static ModeDef asm_mode = { static int asm_init(QEmacsState *qs) { - qe_register_mode(&asm_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &asm_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/ats.c b/lang/ats.c index e8ff6c5..2317360 100644 --- a/lang/ats.c +++ b/lang/ats.c @@ -228,8 +228,7 @@ static ModeDef ats_mode = { static int ats_init(QEmacsState *qs) { - qe_register_mode(&ats_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &ats_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/basic.c b/lang/basic.c index 889ab00..0cbd6b9 100644 --- a/lang/basic.c +++ b/lang/basic.c @@ -129,8 +129,7 @@ static ModeDef basic_mode = { static int basic_init(QEmacsState *qs) { - qe_register_mode(&basic_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &basic_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/clang.c b/lang/clang.c index 98aca0f..9c9e73d 100644 --- a/lang/clang.c +++ b/lang/clang.c @@ -223,9 +223,15 @@ static void c_colorize_line(QEColorizeContext *cp, switch (c) { case '*': + /* lone star at the beginning of a line in a shell buffer + * is treated as a comment start. This improves colorization + * of diff and git output. + */ if (start == indent && cp->partial_file - && (i == n || str[i] == ' ' || str[i] == '/')) + && (i == n || str[i] == ' ' || str[i] == '/')) { + i--; goto parse_comment2; + } goto normal; case '/': if (str[i] == '*') { @@ -826,7 +832,7 @@ void c_indent_line(EditState *s, int offset0) if (pos1 == len || cp->sbuf[0] == C_STYLE_PREPROCESS) continue; if (c_line_has_label(s, cp->buf, len, cp->sbuf)) { - pos1 = pos1 - s->qe_state->c_label_indent + s->indent_width; + pos1 = pos1 - s->qs->c_label_indent + s->indent_width; } /* scan the line from end to start */ for (off = len; off-- > 0;) { @@ -1042,7 +1048,7 @@ void c_indent_line(EditState *s, int offset0) break; } if (c_line_has_label(s, cp->buf + i, len - i, cp->sbuf + i)) { - pos -= s->indent_width + s->qe_state->c_label_indent; + pos -= s->indent_width + s->qs->c_label_indent; break; } break; @@ -1124,7 +1130,7 @@ done: static void do_c_indent(EditState *s) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; if (!s->region_style && !(s->b->flags & BF_PREVIEW) @@ -1253,7 +1259,7 @@ static void do_c_list_conditionals(EditState *s) int offset, offset1; EditBuffer *b; - b = eb_scratch("Preprocessor conditionals", BF_UTF8); + b = qe_new_buffer(s->qs, "Preprocessor conditionals", BC_REUSE | BC_CLEAR | BF_UTF8); if (!b) return; @@ -4305,68 +4311,68 @@ static ModeDef jakt_mode = { static int c_init(QEmacsState *qs) { - qe_register_mode(&c_mode, MODEF_SYNTAX); - qe_register_commands(&c_mode, c_commands, countof(c_commands)); - qe_register_mode(&cpp_mode, MODEF_SYNTAX); - qe_register_mode(&js_mode, MODEF_SYNTAX); - qe_register_mode(&v8_mode, MODEF_SYNTAX); - qe_register_mode(&bee_mode, MODEF_SYNTAX); - qe_register_mode(&java_mode, MODEF_SYNTAX); - qe_register_mode(&php_mode, MODEF_SYNTAX); - qe_register_mode(&go_mode, MODEF_SYNTAX); - qe_register_mode(&yacc_mode, MODEF_SYNTAX); - qe_register_mode(&lex_mode, MODEF_SYNTAX); + qe_register_mode(qs, &c_mode, MODEF_SYNTAX); + qe_register_commands(qs, &c_mode, c_commands, countof(c_commands)); + qe_register_mode(qs, &cpp_mode, MODEF_SYNTAX); + qe_register_mode(qs, &js_mode, MODEF_SYNTAX); + qe_register_mode(qs, &v8_mode, MODEF_SYNTAX); + qe_register_mode(qs, &bee_mode, MODEF_SYNTAX); + qe_register_mode(qs, &java_mode, MODEF_SYNTAX); + qe_register_mode(qs, &php_mode, MODEF_SYNTAX); + qe_register_mode(qs, &go_mode, MODEF_SYNTAX); + qe_register_mode(qs, &yacc_mode, MODEF_SYNTAX); + qe_register_mode(qs, &lex_mode, MODEF_SYNTAX); #ifndef CONFIG_TINY - qe_register_mode(&idl_mode, MODEF_SYNTAX); - qe_register_mode(&carbon_mode, MODEF_SYNTAX); - qe_register_mode(&c2_mode, MODEF_SYNTAX); - qe_register_mode(&objc_mode, MODEF_SYNTAX); - qe_register_mode(&csharp_mode, MODEF_SYNTAX); - qe_register_mode(&awk_mode, MODEF_SYNTAX); - qe_register_mode(&css_mode, MODEF_SYNTAX); - qe_register_mode(&less_mode, MODEF_SYNTAX); - qe_register_mode(&json_mode, MODEF_SYNTAX); - qe_register_mode(&ts_mode, MODEF_SYNTAX); - qe_register_mode(&jspp_mode, MODEF_SYNTAX); - qe_register_mode(&koka_mode, MODEF_SYNTAX); - qe_register_mode(&as_mode, MODEF_SYNTAX); - qe_register_mode(&scala_mode, MODEF_SYNTAX); - qe_register_mode(&d_mode, MODEF_SYNTAX); - qe_register_mode(&limbo_mode, MODEF_SYNTAX); - qe_register_mode(&cyclone_mode, MODEF_SYNTAX); - qe_register_mode(&ch_mode, MODEF_SYNTAX); - qe_register_mode(&squirrel_mode, MODEF_SYNTAX); - qe_register_mode(&ici_mode, MODEF_SYNTAX); - qe_register_mode(&jsx_mode, MODEF_SYNTAX); - qe_register_mode(&haxe_mode, MODEF_SYNTAX); - qe_register_mode(&dart_mode, MODEF_SYNTAX); - qe_register_mode(&pike_mode, MODEF_SYNTAX); - qe_register_mode(&idl_mode, MODEF_SYNTAX); - qe_register_mode(&calc_mode, MODEF_SYNTAX); - qe_register_mode(&enscript_mode, MODEF_SYNTAX); - qe_register_mode(&qscript_mode, MODEF_SYNTAX); - qe_register_mode(&ec_mode, MODEF_SYNTAX); - qe_register_mode(&sl_mode, MODEF_SYNTAX); - qe_register_mode(&csl_mode, MODEF_SYNTAX); - qe_register_mode(&neko_mode, MODEF_SYNTAX); - qe_register_mode(&nml_mode, MODEF_SYNTAX); - qe_register_mode(&alloy_mode, MODEF_SYNTAX); - qe_register_mode(&scilab_mode, MODEF_SYNTAX); - qe_register_mode(&kotlin_mode, MODEF_SYNTAX); - qe_register_mode(&cbang_mode, MODEF_SYNTAX); - qe_register_mode(&vala_mode, MODEF_SYNTAX); - qe_register_mode(&pawn_mode, MODEF_SYNTAX); - qe_register_mode(&cminus_mode, MODEF_SYNTAX); - qe_register_mode(&gmscript_mode, MODEF_SYNTAX); - qe_register_mode(&wren_mode, MODEF_SYNTAX); - qe_register_mode(&jack_mode, MODEF_SYNTAX); - qe_register_mode(&smac_mode, MODEF_SYNTAX); - qe_register_mode(&v_mode, MODEF_SYNTAX); - qe_register_mode(&protobuf_mode, MODEF_SYNTAX); - qe_register_mode(&odin_mode, MODEF_SYNTAX); - qe_register_mode(&salmon_mode, MODEF_SYNTAX); - qe_register_mode(&ppl_mode, MODEF_SYNTAX); - qe_register_mode(&jakt_mode, MODEF_SYNTAX); + qe_register_mode(qs, &idl_mode, MODEF_SYNTAX); + qe_register_mode(qs, &carbon_mode, MODEF_SYNTAX); + qe_register_mode(qs, &c2_mode, MODEF_SYNTAX); + qe_register_mode(qs, &objc_mode, MODEF_SYNTAX); + qe_register_mode(qs, &csharp_mode, MODEF_SYNTAX); + qe_register_mode(qs, &awk_mode, MODEF_SYNTAX); + qe_register_mode(qs, &css_mode, MODEF_SYNTAX); + qe_register_mode(qs, &less_mode, MODEF_SYNTAX); + qe_register_mode(qs, &json_mode, MODEF_SYNTAX); + qe_register_mode(qs, &ts_mode, MODEF_SYNTAX); + qe_register_mode(qs, &jspp_mode, MODEF_SYNTAX); + qe_register_mode(qs, &koka_mode, MODEF_SYNTAX); + qe_register_mode(qs, &as_mode, MODEF_SYNTAX); + qe_register_mode(qs, &scala_mode, MODEF_SYNTAX); + qe_register_mode(qs, &d_mode, MODEF_SYNTAX); + qe_register_mode(qs, &limbo_mode, MODEF_SYNTAX); + qe_register_mode(qs, &cyclone_mode, MODEF_SYNTAX); + qe_register_mode(qs, &ch_mode, MODEF_SYNTAX); + qe_register_mode(qs, &squirrel_mode, MODEF_SYNTAX); + qe_register_mode(qs, &ici_mode, MODEF_SYNTAX); + qe_register_mode(qs, &jsx_mode, MODEF_SYNTAX); + qe_register_mode(qs, &haxe_mode, MODEF_SYNTAX); + qe_register_mode(qs, &dart_mode, MODEF_SYNTAX); + qe_register_mode(qs, &pike_mode, MODEF_SYNTAX); + qe_register_mode(qs, &idl_mode, MODEF_SYNTAX); + qe_register_mode(qs, &calc_mode, MODEF_SYNTAX); + qe_register_mode(qs, &enscript_mode, MODEF_SYNTAX); + qe_register_mode(qs, &qscript_mode, MODEF_SYNTAX); + qe_register_mode(qs, &ec_mode, MODEF_SYNTAX); + qe_register_mode(qs, &sl_mode, MODEF_SYNTAX); + qe_register_mode(qs, &csl_mode, MODEF_SYNTAX); + qe_register_mode(qs, &neko_mode, MODEF_SYNTAX); + qe_register_mode(qs, &nml_mode, MODEF_SYNTAX); + qe_register_mode(qs, &alloy_mode, MODEF_SYNTAX); + qe_register_mode(qs, &scilab_mode, MODEF_SYNTAX); + qe_register_mode(qs, &kotlin_mode, MODEF_SYNTAX); + qe_register_mode(qs, &cbang_mode, MODEF_SYNTAX); + qe_register_mode(qs, &vala_mode, MODEF_SYNTAX); + qe_register_mode(qs, &pawn_mode, MODEF_SYNTAX); + qe_register_mode(qs, &cminus_mode, MODEF_SYNTAX); + qe_register_mode(qs, &gmscript_mode, MODEF_SYNTAX); + qe_register_mode(qs, &wren_mode, MODEF_SYNTAX); + qe_register_mode(qs, &jack_mode, MODEF_SYNTAX); + qe_register_mode(qs, &smac_mode, MODEF_SYNTAX); + qe_register_mode(qs, &v_mode, MODEF_SYNTAX); + qe_register_mode(qs, &protobuf_mode, MODEF_SYNTAX); + qe_register_mode(qs, &odin_mode, MODEF_SYNTAX); + qe_register_mode(qs, &salmon_mode, MODEF_SYNTAX); + qe_register_mode(qs, &ppl_mode, MODEF_SYNTAX); + qe_register_mode(qs, &jakt_mode, MODEF_SYNTAX); #endif return 0; } diff --git a/lang/cobol.c b/lang/cobol.c index 205cc23..dbad265 100644 --- a/lang/cobol.c +++ b/lang/cobol.c @@ -253,8 +253,7 @@ static ModeDef cobol_mode = { static int cobol_init(QEmacsState *qs) { - qe_register_mode(&cobol_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &cobol_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/coffee.c b/lang/coffee.c index 52157e0..536290f 100644 --- a/lang/coffee.c +++ b/lang/coffee.c @@ -377,8 +377,7 @@ static ModeDef coffee_mode = { static int coffee_init(QEmacsState *qs) { - qe_register_mode(&coffee_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &coffee_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/crystal.c b/lang/crystal.c index efc3c3f..bbf01f1 100644 --- a/lang/crystal.c +++ b/lang/crystal.c @@ -504,7 +504,7 @@ static ModeDef crystal_mode = { static int crystal_init(QEmacsState *qs) { - qe_register_mode(&crystal_mode, MODEF_SYNTAX); + qe_register_mode(qs, &crystal_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/csv.c b/lang/csv.c index 7769739..7af3d26 100644 --- a/lang/csv.c +++ b/lang/csv.c @@ -257,7 +257,7 @@ static ModeDef csv_mode = { static int csv_init(QEmacsState *qs) { - qe_register_mode(&csv_mode, MODEF_SYNTAX); + qe_register_mode(qs, &csv_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/ebnf.c b/lang/ebnf.c index 1362544..9b84dd6 100644 --- a/lang/ebnf.c +++ b/lang/ebnf.c @@ -209,9 +209,8 @@ static ModeDef antlr_mode = { static int ebnf_init(QEmacsState *qs) { - qe_register_mode(&antlr_mode, MODEF_SYNTAX); - qe_register_mode(&ebnf_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &antlr_mode, MODEF_SYNTAX); + qe_register_mode(qs, &ebnf_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/elixir.c b/lang/elixir.c index 168540b..3e04439 100644 --- a/lang/elixir.c +++ b/lang/elixir.c @@ -294,8 +294,7 @@ static ModeDef elixir_mode = { static int elixir_init(QEmacsState *qs) { - qe_register_mode(&elixir_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &elixir_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/elm.c b/lang/elm.c index 5173c3b..dd6c03f 100644 --- a/lang/elm.c +++ b/lang/elm.c @@ -265,8 +265,7 @@ static ModeDef elm_mode = { static int elm_init(QEmacsState *qs) { - qe_register_mode(&elm_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &elm_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/emf.c b/lang/emf.c index a6091d3..0936fea 100644 --- a/lang/emf.c +++ b/lang/emf.c @@ -134,8 +134,7 @@ static ModeDef emf_mode = { static int emf_init(QEmacsState *qs) { - qe_register_mode(&emf_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &emf_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/erlang.c b/lang/erlang.c index 94f0766..123bc22 100644 --- a/lang/erlang.c +++ b/lang/erlang.c @@ -267,8 +267,7 @@ static ModeDef erlang_mode = { static int erlang_init(QEmacsState *qs) { - qe_register_mode(&erlang_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &erlang_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/falcon.c b/lang/falcon.c index 4b3fbbf..3b22b65 100644 --- a/lang/falcon.c +++ b/lang/falcon.c @@ -226,8 +226,7 @@ static ModeDef falcon_mode = { static int falcon_init(QEmacsState *qs) { - qe_register_mode(&falcon_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &falcon_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/forth.c b/lang/forth.c index 7b19f73..644ab03 100644 --- a/lang/forth.c +++ b/lang/forth.c @@ -332,7 +332,7 @@ static ModeDef ff_mode = { static int ff_init(QEmacsState *qs) { - qe_register_mode(&ff_mode, MODEF_SYNTAX); + qe_register_mode(qs, &ff_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/fortran.c b/lang/fortran.c index 5e0831c..63413a1 100644 --- a/lang/fortran.c +++ b/lang/fortran.c @@ -171,8 +171,7 @@ static ModeDef fortran_mode = { static int fortran_init(QEmacsState *qs) { - qe_register_mode(&fortran_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &fortran_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/groovy.c b/lang/groovy.c index cf011be..3b4bab5 100644 --- a/lang/groovy.c +++ b/lang/groovy.c @@ -463,8 +463,7 @@ static ModeDef groovy_mode = { static int groovy_init(QEmacsState *qs) { - qe_register_mode(&groovy_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &groovy_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/haskell.c b/lang/haskell.c index b6eeaf8..0ea0af8 100644 --- a/lang/haskell.c +++ b/lang/haskell.c @@ -254,8 +254,7 @@ static ModeDef haskell_mode = { static int haskell_init(QEmacsState *qs) { - qe_register_mode(&haskell_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &haskell_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/htmlsrc.c b/lang/htmlsrc.c index 23c3e12..ed9848a 100644 --- a/lang/htmlsrc.c +++ b/lang/htmlsrc.c @@ -400,9 +400,8 @@ ModeDef htmlsrc_mode = { static int htmlsrc_init(QEmacsState *qs) { - qe_register_mode(&htmlsrc_mode, MODEF_SYNTAX); - //qe_register_commands(&htmlsrc_mode, htmlsrc_commands, countof(htmlsrc_commands)); - + qe_register_mode(qs, &htmlsrc_mode, MODEF_SYNTAX); + //qe_register_commands(qs, &htmlsrc_mode, htmlsrc_commands, countof(htmlsrc_commands)); return 0; } diff --git a/lang/icon.c b/lang/icon.c index dcec517..37c38f7 100644 --- a/lang/icon.c +++ b/lang/icon.c @@ -207,8 +207,7 @@ static ModeDef icon_mode = { static int icon_init(QEmacsState *qs) { - qe_register_mode(&icon_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &icon_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/inifile.c b/lang/inifile.c index 42c3de6..cf94d39 100644 --- a/lang/inifile.c +++ b/lang/inifile.c @@ -154,8 +154,7 @@ static ModeDef ini_mode = { static int ini_init(QEmacsState *qs) { - qe_register_mode(&ini_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &ini_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/jai.c b/lang/jai.c index 81f2074..c1de4ac 100644 --- a/lang/jai.c +++ b/lang/jai.c @@ -269,9 +269,8 @@ static ModeDef vale_mode = { static int jai_init(QEmacsState *qs) { - qe_register_mode(&jai_mode, MODEF_SYNTAX); - qe_register_mode(&vale_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &jai_mode, MODEF_SYNTAX); + qe_register_mode(qs, &vale_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/julia.c b/lang/julia.c index 2ab9a80..82b6097 100644 --- a/lang/julia.c +++ b/lang/julia.c @@ -288,8 +288,7 @@ static ModeDef julia_mode = { static int julia_init(QEmacsState *qs) { - qe_register_mode(&julia_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &julia_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/lisp.c b/lang/lisp.c index 4428186..38d1db2 100644 --- a/lang/lisp.c +++ b/lang/lisp.c @@ -540,13 +540,13 @@ static ModeDef xaos_mode = { static int lisp_init(QEmacsState *qs) { - qe_register_mode(&lisp_mode, MODEF_SYNTAX); - qe_register_mode(&elisp_mode, MODEF_SYNTAX); - qe_register_mode(&scheme_mode, MODEF_SYNTAX); - qe_register_mode(&racket_mode, MODEF_SYNTAX); - qe_register_mode(&clojure_mode, MODEF_SYNTAX); - qe_register_mode(&sandbox_mode, MODEF_SYNTAX); - qe_register_mode(&xaos_mode, MODEF_SYNTAX); + qe_register_mode(qs, &lisp_mode, MODEF_SYNTAX); + qe_register_mode(qs, &elisp_mode, MODEF_SYNTAX); + qe_register_mode(qs, &scheme_mode, MODEF_SYNTAX); + qe_register_mode(qs, &racket_mode, MODEF_SYNTAX); + qe_register_mode(qs, &clojure_mode, MODEF_SYNTAX); + qe_register_mode(qs, &sandbox_mode, MODEF_SYNTAX); + qe_register_mode(qs, &xaos_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/lua.c b/lang/lua.c index dc43919..c235474 100644 --- a/lang/lua.c +++ b/lang/lua.c @@ -200,8 +200,7 @@ static ModeDef lua_mode = { static int lua_init(QEmacsState *qs) { - qe_register_mode(&lua_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &lua_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/magpie.c b/lang/magpie.c index 4ff9896..458f8b4 100644 --- a/lang/magpie.c +++ b/lang/magpie.c @@ -208,8 +208,7 @@ static ModeDef magpie_mode = { static int magpie_init(QEmacsState *qs) { - qe_register_mode(&magpie_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &magpie_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/makemode.c b/lang/makemode.c index 0a50bd0..5385bb8 100644 --- a/lang/makemode.c +++ b/lang/makemode.c @@ -262,8 +262,8 @@ static ModeDef cmake_mode = { static int makefile_init(QEmacsState *qs) { - qe_register_mode(&makefile_mode, MODEF_SYNTAX); - qe_register_mode(&cmake_mode, MODEF_SYNTAX); + qe_register_mode(qs, &makefile_mode, MODEF_SYNTAX); + qe_register_mode(qs, &cmake_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/nanorc.c b/lang/nanorc.c index e686740..15254e4 100644 --- a/lang/nanorc.c +++ b/lang/nanorc.c @@ -189,8 +189,7 @@ static ModeDef nanorc_mode = { static int nanorc_init(QEmacsState *qs) { - qe_register_mode(&nanorc_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &nanorc_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/nim.c b/lang/nim.c index 2993595..6cb951c 100644 --- a/lang/nim.c +++ b/lang/nim.c @@ -331,8 +331,7 @@ static ModeDef nim_mode = { static int nim_init(QEmacsState *qs) { - qe_register_mode(&nim_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &nim_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/ocaml.c b/lang/ocaml.c index 285c54a..2bd1b79 100644 --- a/lang/ocaml.c +++ b/lang/ocaml.c @@ -274,9 +274,8 @@ static ModeDef eff_mode = { static int ocaml_init(QEmacsState *qs) { - qe_register_mode(&ocaml_mode, MODEF_SYNTAX); - qe_register_mode(&eff_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &ocaml_mode, MODEF_SYNTAX); + qe_register_mode(qs, &eff_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/pascal.c b/lang/pascal.c index 440ce7b..8d1670f 100644 --- a/lang/pascal.c +++ b/lang/pascal.c @@ -197,8 +197,7 @@ static ModeDef pascal_mode = { static int pascal_init(QEmacsState *qs) { - qe_register_mode(&pascal_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &pascal_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/perl.c b/lang/perl.c index 3710f19..5538d72 100644 --- a/lang/perl.c +++ b/lang/perl.c @@ -402,8 +402,7 @@ static ModeDef perl_mode = { static int perl_init(QEmacsState *qs) { - qe_register_mode(&perl_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &perl_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/postscript.c b/lang/postscript.c index c8c3dc1..15612de 100644 --- a/lang/postscript.c +++ b/lang/postscript.c @@ -143,8 +143,7 @@ static ModeDef ps_mode = { static int ps_init(QEmacsState *qs) { - qe_register_mode(&ps_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &ps_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/python.c b/lang/python.c index 9f61110..e8179ec 100644 --- a/lang/python.c +++ b/lang/python.c @@ -359,10 +359,9 @@ static ModeDef bazel_mode = { static int python_init(QEmacsState *qs) { - qe_register_mode(&python_mode, MODEF_SYNTAX); - qe_register_mode(&rapydscript_mode, MODEF_SYNTAX); - qe_register_mode(&bazel_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &python_mode, MODEF_SYNTAX); + qe_register_mode(qs, &rapydscript_mode, MODEF_SYNTAX); + qe_register_mode(qs, &bazel_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/rebol.c b/lang/rebol.c index 1f81f87..eca669a 100644 --- a/lang/rebol.c +++ b/lang/rebol.c @@ -308,8 +308,7 @@ static ModeDef rebol_mode = { static int rebol_init(QEmacsState *qs) { - qe_register_mode(&rebol_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &rebol_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/rlang.c b/lang/rlang.c index 09a3531..3ba0d5f 100644 --- a/lang/rlang.c +++ b/lang/rlang.c @@ -211,8 +211,7 @@ static ModeDef r_mode = { static int r_init(QEmacsState *qs) { - qe_register_mode(&r_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &r_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/ruby.c b/lang/ruby.c index 3aae735..35969e6 100644 --- a/lang/ruby.c +++ b/lang/ruby.c @@ -508,8 +508,7 @@ static ModeDef ruby_mode = { static int ruby_init(QEmacsState *qs) { - qe_register_mode(&ruby_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &ruby_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/rust.c b/lang/rust.c index 5300932..7f39238 100644 --- a/lang/rust.c +++ b/lang/rust.c @@ -282,8 +282,7 @@ static ModeDef rust_mode = { static int rust_init(QEmacsState *qs) { - qe_register_mode(&rust_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &rust_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/rye.c b/lang/rye.c index 2c589f2..97012ba 100644 --- a/lang/rye.c +++ b/lang/rye.c @@ -270,7 +270,7 @@ static ModeDef rye_mode = { }; static int rye_init(QEmacsState *qs) { - qe_register_mode(&rye_mode, MODEF_SYNTAX); + qe_register_mode(qs, &rye_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/scad.c b/lang/scad.c index 4c2832e..6ca228e 100644 --- a/lang/scad.c +++ b/lang/scad.c @@ -198,8 +198,7 @@ static ModeDef scad_mode = { static int scad_init(QEmacsState *qs) { - qe_register_mode(&scad_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &scad_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/script.c b/lang/script.c index 8e057d8..9f498ef 100644 --- a/lang/script.c +++ b/lang/script.c @@ -351,13 +351,12 @@ static ModeDef tcsh_mode = { static int shell_script_init(QEmacsState *qs) { - qe_register_mode(&sh_mode, MODEF_SYNTAX); - qe_register_mode(&bash_mode, MODEF_SYNTAX); - qe_register_mode(&csh_mode, MODEF_SYNTAX); - qe_register_mode(&ksh_mode, MODEF_SYNTAX); - qe_register_mode(&zsh_mode, MODEF_SYNTAX); - qe_register_mode(&tcsh_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &sh_mode, MODEF_SYNTAX); + qe_register_mode(qs, &bash_mode, MODEF_SYNTAX); + qe_register_mode(qs, &csh_mode, MODEF_SYNTAX); + qe_register_mode(qs, &ksh_mode, MODEF_SYNTAX); + qe_register_mode(qs, &zsh_mode, MODEF_SYNTAX); + qe_register_mode(qs, &tcsh_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/sharp.c b/lang/sharp.c index 49cf7b6..335bf63 100644 --- a/lang/sharp.c +++ b/lang/sharp.c @@ -78,8 +78,7 @@ static ModeDef sharp_mode = { static int sharp_init(QEmacsState *qs) { - qe_register_mode(&sharp_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &sharp_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/smalltalk.c b/lang/smalltalk.c index ff4bcf5..928679d 100644 --- a/lang/smalltalk.c +++ b/lang/smalltalk.c @@ -196,8 +196,7 @@ static ModeDef smalltalk_mode = { static int smalltalk_init(QEmacsState *qs) { - qe_register_mode(&smalltalk_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &smalltalk_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/sql.c b/lang/sql.c index 44a2197..c720ac1 100644 --- a/lang/sql.c +++ b/lang/sql.c @@ -207,8 +207,7 @@ static ModeDef sql_mode = { static int sql_init(QEmacsState *qs) { - qe_register_mode(&sql_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &sql_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/swift.c b/lang/swift.c index fea21ad..57a73f6 100644 --- a/lang/swift.c +++ b/lang/swift.c @@ -359,8 +359,7 @@ static ModeDef swift_mode = { static int swift_init(QEmacsState *qs) { - qe_register_mode(&swift_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &swift_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/tiger.c b/lang/tiger.c index 0968263..99e1623 100644 --- a/lang/tiger.c +++ b/lang/tiger.c @@ -184,8 +184,7 @@ static ModeDef tiger_mode = { static int tiger_init(QEmacsState *qs) { - qe_register_mode(&tiger_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &tiger_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/txl.c b/lang/txl.c index 79466ba..971dbef 100644 --- a/lang/txl.c +++ b/lang/txl.c @@ -164,8 +164,7 @@ static ModeDef txl_mode = { static int txl_init(QEmacsState *qs) { - qe_register_mode(&txl_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &txl_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/vimscript.c b/lang/vimscript.c index 397d0a6..f4faeba 100644 --- a/lang/vimscript.c +++ b/lang/vimscript.c @@ -268,8 +268,7 @@ static ModeDef vim_mode = { static int vim_init(QEmacsState *qs) { - qe_register_mode(&vim_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &vim_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/virgil.c b/lang/virgil.c index 92a9c8c..84830d7 100644 --- a/lang/virgil.c +++ b/lang/virgil.c @@ -463,8 +463,7 @@ static ModeDef virgil_mode = { static int virgil_init(QEmacsState *qs) { - qe_register_mode(&virgil_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &virgil_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/wolfram.c b/lang/wolfram.c index e4c6a54..ce65a84 100644 --- a/lang/wolfram.c +++ b/lang/wolfram.c @@ -242,8 +242,7 @@ static ModeDef wolfram_mode = { static int wolfram_init(QEmacsState *qs) { - qe_register_mode(&wolfram_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &wolfram_mode, MODEF_SYNTAX); return 0; } diff --git a/lang/xml.c b/lang/xml.c index 6548391..d3bb3c3 100644 --- a/lang/xml.c +++ b/lang/xml.c @@ -200,8 +200,7 @@ ModeDef xml_mode = { static int xml_init(QEmacsState *qs) { - qe_register_mode(&xml_mode, MODEF_SYNTAX); - + qe_register_mode(qs, &xml_mode, MODEF_SYNTAX); return 0; } diff --git a/libqhtml/Makefile b/libqhtml/Makefile index ed82631..fe0746b 100644 --- a/libqhtml/Makefile +++ b/libqhtml/Makefile @@ -1,7 +1,7 @@ # Libqhtml tiny HTML/CSS rendering library for QEmacs # # Copyright (c) 2000-2002 Fabrice Bellard. -# Copyright (c) 2000-2023 Charlie Gordon. +# Copyright (c) 2000-2024 Charlie Gordon. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -68,13 +68,33 @@ CFLAGS+=-I$(DEPTH) HOST_CFLAGS:=$(CFLAGS) +DEBUG_SUFFIX:= ifdef DEBUG DEBUG_SUFFIX:=_debug ECHO_CFLAGS += -DCONFIG_DEBUG CFLAGS += -g -O0 LDFLAGS += -g -O0 -else -DEBUG_SUFFIX:= +endif +ifdef ASAN +DEBUG_SUFFIX:=_asan +ECHO_CFLAGS += -DCONFIG_ASAN +CFLAGS += -D__ASAN__ +CFLAGS += -fsanitize=address -fno-sanitize-recover=all -fno-omit-frame-pointer +LDFLAGS += -fsanitize=address -fno-sanitize-recover=all -fno-omit-frame-pointer +endif +ifdef MSAN +DEBUG_SUFFIX:=_msan +ECHO_CFLAGS += -DCONFIG_MSAN +CFLAGS += -D__MSAN__ +CFLAGS += -fsanitize=memory -fno-sanitize-recover=all -fno-omit-frame-pointer +LDFLAGS += -fsanitize=memory -fno-sanitize-recover=all -fno-omit-frame-pointer +endif +ifdef UBSAN +DEBUG_SUFFIX:=_ubsan +ECHO_CFLAGS += -DCONFIG_UBSAN +CFLAGS += -D__UBSAN__ +CFLAGS += -fsanitize=undefined -fno-sanitize-recover=all -fno-omit-frame-pointer +LDFLAGS += -fsanitize=undefined -fno-sanitize-recover=all -fno-omit-frame-pointer endif LIB= $(DEPTH)/.objs/$(TARGET_OS)-$(TARGET_ARCH)-$(CC)/libqhtml$(DEBUG_SUFFIX).a diff --git a/libqhtml/css.c b/libqhtml/css.c index a031f70..8376272 100644 --- a/libqhtml/css.c +++ b/libqhtml/css.c @@ -30,7 +30,6 @@ #include "css.h" // XXX: need fix for this: should use read function with opaque argument -struct EditBuffer; char32_t eb_nextc(struct EditBuffer *b, int offset, int *next_ptr); //#define DEBUG diff --git a/libqhtml/css.h b/libqhtml/css.h index a349ab7..fef245c 100644 --- a/libqhtml/css.h +++ b/libqhtml/css.h @@ -2,7 +2,7 @@ * CSS core for qemacs. * * Copyright (c) 2000-2002 Fabrice Bellard. - * Copyright (c) 2007-2023 Charlie Gordon. + * Copyright (c) 2007-2024 Charlie Gordon. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -532,15 +532,16 @@ typedef struct CSSStyleSheet { CSSStyleSheetEntry *tag_hash[CSS_TAG_HASH_SIZE]; } CSSStyleSheet; -typedef struct { +typedef struct CSSParseState { + void *error_opaque; const char *ptr; - int line_num; const char *filename; + int line_num; int ignore_case; /* true if case must be ignored (convert to lower case) */ } CSSParseState; CSSStyleSheet *css_new_style_sheet(void); -void css_parse_style_sheet_str(CSSStyleSheet *s, const char *buffer, int flags); +void css_parse_style_sheet_str(CSSStyleSheet *s, void *error_opaque, const char *buffer, int flags); void css_parse_style_sheet(CSSStyleSheet *s, CSSParseState *b); void css_free_style_sheet(CSSStyleSheet **sp); void css_dump_style_sheet(CSSStyleSheet *s); @@ -683,14 +684,16 @@ typedef const struct QECharset QECharset; XMLState *xml_begin(CSSStyleSheet *style_sheet, int flags, CSSAbortFunc *abort_func, void *abort_opaque, - const char *filename, QECharset *charset); + void *error_opaque, const char *filename, + QECharset *charset); int xml_parse(XMLState *s, char *buf, int buf_len); CSSBox *xml_end(XMLState **sp); CSSBox *xml_parse_buffer(struct EditBuffer *b, const char *name, int offset_start, int offset_end, CSSStyleSheet *style_sheet, int flags, - CSSAbortFunc *abort_func, void *abort_opaque); + CSSAbortFunc *abort_func, void *abort_opaque, + void *error_opaque); int find_entity(const char *str); const char *find_entity_str(int code); @@ -699,9 +702,7 @@ const char *find_entity_str(int code); /* The following functions must be provided by the user */ /* error reporting during parsing */ -void html_error(int line_num, const char *fmt, va_list ap); - -void css_error(const char *filename, int line_num, const char *msg); +void css_error(void *error_opaque, const char *filename, int line_num, const char *msg); /* file handling (for external scripts/css) */ struct CSSFile; diff --git a/libqhtml/cssparse.c b/libqhtml/cssparse.c index 2e8e0b0..7727605 100644 --- a/libqhtml/cssparse.c +++ b/libqhtml/cssparse.c @@ -48,7 +48,7 @@ #include static void css_error1(CSSParseState *b, const char *fmt, ...) - qe__attr_printf(2,3); + qe__attr_printf(2,3); static void css_error1(CSSParseState *b, const char *fmt, ...) { @@ -56,8 +56,8 @@ static void css_error1(CSSParseState *b, const char *fmt, ...) va_list ap; va_start(ap, fmt); vsnprintf(buf, sizeof(buf), fmt, ap); - css_error(b->filename, b->line_num, buf); va_end(ap); + css_error(b->error_opaque, b->filename, b->line_num, buf); } /***********************************************************/ @@ -1131,9 +1131,10 @@ void css_parse_style_sheet(CSSStyleSheet *s, CSSParseState *b) #endif } -void css_parse_style_sheet_str(CSSStyleSheet *s, const char *buffer, int flags) +void css_parse_style_sheet_str(CSSStyleSheet *s, void *error_opaque, const char *buffer, int flags) { CSSParseState b1, *b = &b1; + b->error_opaque = error_opaque; b->ptr = buffer; b->filename = "builtin"; b->line_num = 1; diff --git a/libqhtml/xmlparse.c b/libqhtml/xmlparse.c index bc3533f..75dbeb1 100644 --- a/libqhtml/xmlparse.c +++ b/libqhtml/xmlparse.c @@ -283,6 +283,7 @@ struct XMLState { int pretaglen; char pretag[32]; /* current tag in XML_STATE_PRETAG */ StringBuffer str; + void *error_opaque; char filename[MAX_FILENAME_SIZE]; CharsetDecodeState charset_state; }; @@ -291,7 +292,8 @@ struct XMLState { XMLState *xml_begin(CSSStyleSheet *style_sheet, int flags, CSSAbortFunc *abort_func, void *abort_opaque, - const char *filename, QECharset *charset) + void *error_opaque, const char *filename, + QECharset *charset) { XMLState *s; @@ -310,6 +312,7 @@ XMLState *xml_begin(CSSStyleSheet *style_sheet, int flags, s->abort_opaque = abort_opaque; s->base_font = 3; s->line_num = 1; + s->error_opaque = error_opaque; pstrcpy(s->filename, sizeof(s->filename), filename); s->charset = charset; if (charset) { @@ -797,7 +800,7 @@ static void html_eval_tag(XMLState *s, CSSBox *box) } static void xml_error(XMLState *s, const char *fmt, ...) - qe__attr_printf(2,3); + qe__attr_printf(2,3); static void xml_error(XMLState *s, const char *fmt, ...) { @@ -806,8 +809,8 @@ static void xml_error(XMLState *s, const char *fmt, ...) va_start(ap, fmt); vsnprintf(buf, sizeof(buf), fmt, ap); - css_error(s->filename, s->line_num, buf); va_end(ap); + css_error(s->error_opaque, s->filename, s->line_num, buf); } /* XXX: avoid using strings in tag_closed and generalize */ @@ -1198,6 +1201,7 @@ static int xml_parse_internal(XMLState *s, const char *buf_start, int buf_len, if (!xml_tagcmp(s->pretag, "style")) { if (s->style_sheet) { CSSParseState b1, *bp = &b1; + bp->error_opaque = s->error_opaque; bp->ptr = (char *)s->str.buf; bp->line_num = s->line_num; /* XXX: incorrect */ bp->filename = s->filename; @@ -1321,13 +1325,14 @@ CSSBox *xml_end(XMLState **sp) CSSBox *xml_parse_buffer(struct EditBuffer *b, const char *name, int offset_start, int offset_end, CSSStyleSheet *style_sheet, int flags, - CSSAbortFunc *abort_func, void *abort_opaque) + CSSAbortFunc *abort_func, void *abort_opaque, + void *error_opaque) { XMLState *s; CSSBox *box; int ret; - s = xml_begin(style_sheet, flags, abort_func, abort_opaque, name, NULL); + s = xml_begin(style_sheet, flags, abort_func, abort_opaque, error_opaque, name, NULL); ret = xml_parse_internal(s, NULL, offset_end - offset_start, b, offset_start); box = xml_end(&s); if (ret < 0) { diff --git a/modes/archive.c b/modes/archive.c index 7ddabef..9577729 100644 --- a/modes/archive.c +++ b/modes/archive.c @@ -1,7 +1,7 @@ /* * Mode for viewing archive files for QEmacs. * - * Copyright (c) 2002-2023 Charlie Gordon. + * Copyright (c) 2002-2024 Charlie Gordon. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -149,8 +149,8 @@ static int archive_buffer_load(EditBuffer *b, FILE *f) eb_printf(b, " Directory of %s archive %s\n", atp->name, b->filename); qe_shell_subst(cmd, sizeof(cmd), atp->list_cmd, b->filename, NULL); - new_shell_buffer(b, NULL, get_basename(b->filename), NULL, NULL, cmd, - atp->sf_flags | SF_INFINITE | SF_BUFED_MODE); + qe_new_shell_buffer(b->qs, b, NULL, get_basename(b->filename), NULL, + NULL, cmd, atp->sf_flags | SF_INFINITE | SF_BUFED_MODE); /* XXX: should check for archiver error */ /* XXX: should delay BF_SAVELOG until buffer is fully loaded */ @@ -205,8 +205,8 @@ static int archive_init(QEmacsState *qs) } archive_types = archive_type_array; - eb_register_data_type(&archive_data_type); - qe_register_mode(&archive_mode, MODEF_DATATYPE | MODEF_SHELLPROC); + qe_register_data_type(qs, &archive_data_type); + qe_register_mode(qs, &archive_mode, MODEF_DATATYPE | MODEF_SHELLPROC); return 0; } @@ -297,8 +297,9 @@ static int compress_buffer_load(EditBuffer *b, FILE *f) b->data_type_name = ctp->name; eb_clear(b); qe_shell_subst(cmd, sizeof(cmd), ctp->load_cmd, b->filename, NULL); - new_shell_buffer(b, NULL, get_basename(b->filename), NULL, NULL, cmd, - ctp->sf_flags | SF_INFINITE | SF_AUTO_CODING | SF_AUTO_MODE); + qe_new_shell_buffer(b->qs, b, NULL, get_basename(b->filename), NULL, + NULL, cmd, + ctp->sf_flags | SF_INFINITE | SF_AUTO_CODING | SF_AUTO_MODE); /* XXX: should check for archiver error */ /* XXX: should delay BF_SAVELOG until buffer is fully loaded */ b->flags |= BF_READONLY; @@ -352,8 +353,8 @@ static int compress_init(QEmacsState *qs) } compress_types = compress_type_array; - eb_register_data_type(&compress_data_type); - qe_register_mode(&compress_mode, MODEF_DATATYPE | MODEF_SHELLPROC); + qe_register_data_type(qs, &compress_data_type); + qe_register_mode(qs, &compress_mode, MODEF_DATATYPE | MODEF_SHELLPROC); return 0; } @@ -386,8 +387,8 @@ static int wget_buffer_load(EditBuffer *b, FILE *f) eb_clear(b); qe_shell_subst(cmd, sizeof(cmd), "wget -q -O - $1", b->filename, NULL); - new_shell_buffer(b, NULL, get_basename(b->filename), NULL, NULL, cmd, - SF_INFINITE | SF_AUTO_CODING | SF_AUTO_MODE); + qe_new_shell_buffer(b->qs, b, NULL, get_basename(b->filename), NULL, + NULL, cmd, SF_INFINITE | SF_AUTO_CODING | SF_AUTO_MODE); /* XXX: should refilter by content type */ /* XXX: should have a way to keep http headers --save-headers */ /* XXX: should check for wget error */ @@ -426,8 +427,8 @@ static int wget_init(QEmacsState *qs) wget_mode.mode_probe = wget_mode_probe; wget_mode.data_type = &wget_data_type; - eb_register_data_type(&wget_data_type); - qe_register_mode(&wget_mode, MODEF_DATATYPE | MODEF_SHELLPROC); + qe_register_data_type(qs, &wget_data_type); + qe_register_mode(qs, &wget_mode, MODEF_DATATYPE | MODEF_SHELLPROC); return 0; } @@ -480,8 +481,8 @@ static int man_buffer_load(EditBuffer *b, FILE *f) eb_clear(b); qe_shell_subst(cmd, sizeof(cmd), "man $1", b->filename, NULL); - new_shell_buffer(b, NULL, get_basename(b->filename), NULL, NULL, cmd, - SF_COLOR | SF_INFINITE); + qe_new_shell_buffer(b->qs, b, NULL, get_basename(b->filename), NULL, + NULL, cmd, SF_COLOR | SF_INFINITE); /* XXX: should check for man error */ /* XXX: should delay BF_SAVELOG until buffer is fully loaded */ b->flags |= BF_READONLY; @@ -518,8 +519,8 @@ static int man_init(QEmacsState *qs) man_mode.mode_probe = man_mode_probe; man_mode.data_type = &man_data_type; - eb_register_data_type(&man_data_type); - qe_register_mode(&man_mode, MODEF_DATATYPE | MODEF_SHELLPROC); + qe_register_data_type(qs, &man_data_type); + qe_register_mode(qs, &man_mode, MODEF_DATATYPE | MODEF_SHELLPROC); return 0; } diff --git a/modes/bufed.c b/modes/bufed.c index d60f3fc..5c19e6e 100644 --- a/modes/bufed.c +++ b/modes/bufed.c @@ -2,7 +2,7 @@ * Buffer editor mode for QEmacs. * * Copyright (c) 2001-2002 Fabrice Bellard. - * Copyright (c) 2002-2023 Charlie Gordon. + * Copyright (c) 2002-2024 Charlie Gordon. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -127,9 +127,9 @@ static int bufed_sort_func(void *opaque, const void *p1, const void *p2) return (sort_mode & BUFED_SORT_DESCENDING) ? -res : res; } -static void build_bufed_list(BufedState *bs, EditState *s) +static void build_bufed_list(EditState *s, BufedState *bs) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; EditBuffer *b, *b1; StringItem *item; int i, line, topline, col, vpos; @@ -170,7 +170,7 @@ static void build_bufed_list(BufedState *bs, EditState *s) int len, style0; item = bs->items.items[i]; - b1 = check_buffer((EditBuffer**)(void *)&item->opaque); + b1 = qe_check_buffer(qs, (EditBuffer**)(void *)&item->opaque); style0 = (b1->flags & BF_SYSTEM) ? BUFED_STYLE_SYSTEM : 0; if ((bs->last_index == -1 && b1 == bs->cur_buffer) @@ -262,7 +262,7 @@ static void build_bufed_list(BufedState *bs, EditState *s) } } -static EditBuffer *bufed_get_buffer(BufedState *bs, EditState *s) +static EditBuffer *bufed_get_buffer(EditState *s, BufedState *bs) { int index; @@ -270,7 +270,7 @@ static EditBuffer *bufed_get_buffer(BufedState *bs, EditState *s) if (index < 0 || index >= bs->items.nb_items) return NULL; - return check_buffer((EditBuffer**)(void *)&bs->items.items[index]->opaque); + return qe_check_buffer(s->qs, (EditBuffer**)(void *)&bs->items.items[index]->opaque); } static void bufed_select(EditState *s, int temp) @@ -284,8 +284,8 @@ static void bufed_select(EditState *s, int temp) return; if (temp < 0) { - b = check_buffer(&bs->cur_buffer); - last_buffer = check_buffer(&bs->last_buffer); + b = qe_check_buffer(s->qs, &bs->cur_buffer); + last_buffer = qe_check_buffer(s->qs, &bs->last_buffer); } else { index = list_get_pos(s); if (index < 0 || index >= bs->items.nb_items) @@ -294,10 +294,10 @@ static void bufed_select(EditState *s, int temp) if (temp > 0 && index == bs->last_index) return; - b = check_buffer((EditBuffer**)(void *)&bs->items.items[index]->opaque); + b = qe_check_buffer(s->qs, (EditBuffer**)(void *)&bs->items.items[index]->opaque); last_buffer = bs->cur_buffer; } - e = check_window(&bs->cur_window); + e = qe_check_window(s->qs, &bs->cur_window); if (e && b) { switch_to_buffer(e, b); e->last_buffer = last_buffer; @@ -311,7 +311,7 @@ static void bufed_select(EditState *s, int temp) /* delete bufed window */ do_delete_window(s, 1); if (e) - e->qe_state->active_window = e; + e->qs->active_window = e; } } else { bs->last_index = index; @@ -350,7 +350,7 @@ static void bufed_kill_item(void *opaque, StringItem *item, int index) { BufedState *bs; EditState *s = opaque; - EditBuffer *b = check_buffer((EditBuffer**)(void *)&item->opaque); + EditBuffer *b = qe_check_buffer(s->qs, (EditBuffer**)(void *)&item->opaque); if (!(bs = bufed_get_state(s, 1))) return; @@ -376,12 +376,13 @@ static void bufed_kill_buffer(EditState *s) string_selection_iterate(&bs->items, list_get_pos(s), bufed_kill_item, s); bufed_select(s, 1); - build_bufed_list(bs, s); + build_bufed_list(s, bs); } /* show a list of buffers */ static void do_buffer_list(EditState *s, int argval) { + QEmacsState *qs = s->qs; BufedState *bs; EditBuffer *b; EditState *e; @@ -394,10 +395,10 @@ static void do_buffer_list(EditState *s, int argval) if (s->flags & WF_POPLEFT) { /* avoid messing with the dired pane */ s = find_window(s, KEY_RIGHT, s); - s->qe_state->active_window = s; + qs->active_window = s; } - b = eb_scratch("*bufed*", BF_SYSTEM | BF_UTF8 | BF_STYLE1); + b = qe_new_buffer(qs, "*bufed*", BC_REUSE | BC_CLEAR | BF_SYSTEM | BF_UTF8 | BF_STYLE1); if (!b) return; @@ -420,7 +421,7 @@ static void do_buffer_list(EditState *s, int argval) if (argval > 4) bs->flags |= BUFED_ALL_VISIBLE; } - build_bufed_list(bs, e); + build_bufed_list(e, bs); /* if active buffer is found, go directly on it */ for (i = 0; i < bs->items.nb_items; i++) { @@ -439,12 +440,12 @@ static void bufed_clear_modified(EditState *s) if (!(bs = bufed_get_state(s, 1))) return; - b = bufed_get_buffer(bs, s); + b = bufed_get_buffer(s, bs); if (!b) return; b->modified = 0; - build_bufed_list(bs, s); + build_bufed_list(s, bs); } static void bufed_toggle_read_only(EditState *s) @@ -455,12 +456,12 @@ static void bufed_toggle_read_only(EditState *s) if (!(bs = bufed_get_state(s, 1))) return; - b = bufed_get_buffer(bs, s); + b = bufed_get_buffer(s, bs); if (!b) return; b->flags ^= BF_READONLY; - build_bufed_list(bs, s); + build_bufed_list(s, bs); } static void bufed_refresh(EditState *s, int toggle) @@ -480,7 +481,7 @@ static void bufed_refresh(EditState *s, int toggle) bs->flags |= BUFED_SYSTEM_VISIBLE; } - build_bufed_list(bs, s); + build_bufed_list(s, bs); } static void bufed_set_sort(EditState *s, int order) @@ -496,7 +497,7 @@ static void bufed_set_sort(EditState *s, int order) bufed_sort_order = order; bs->last_index = -1; - build_bufed_list(bs, s); + build_bufed_list(s, bs); } static void bufed_display_hook(EditState *s) @@ -609,9 +610,9 @@ static int bufed_init(QEmacsState *qs) bufed_mode.display_hook = bufed_display_hook; bufed_mode.bindings = bufed_bindings; - qe_register_mode(&bufed_mode, MODEF_VIEW); - qe_register_commands(&bufed_mode, bufed_commands, countof(bufed_commands)); - qe_register_commands(NULL, bufed_global_commands, countof(bufed_global_commands)); + qe_register_mode(qs, &bufed_mode, MODEF_VIEW); + qe_register_commands(qs, &bufed_mode, bufed_commands, countof(bufed_commands)); + qe_register_commands(qs, NULL, bufed_global_commands, countof(bufed_global_commands)); return 0; } diff --git a/modes/dired.c b/modes/dired.c index 444ecab..d2eccb3 100644 --- a/modes/dired.c +++ b/modes/dired.c @@ -764,7 +764,7 @@ static int dired_format_details(DiredState *ds, DiredItem *dip, static void dired_update_buffer(DiredState *ds, EditBuffer *b, EditState *s, int flags) { - QEmacsState *qs = &qe_state; // EditBuffer should have qe_state field + QEmacsState *qs = b->qs; char buf[MAX_FILENAME_SIZE]; DiredItem *dip, *cur_item; int i, col, w, width, window_width, top_line, indent; @@ -1382,7 +1382,7 @@ static void dired_select(EditState *s, int mode) e = find_window(s, KEY_RIGHT, NULL); if (e) { #if 1 - s->qe_state->active_window = e; + s->qs->active_window = e; if (mode == 1) { /* XXX: should keep BF_PREVIEW flag and set pager-mode */ e->b->flags &= ~BF_PREVIEW; @@ -1425,9 +1425,12 @@ static EditState *dired_view_file(EditState *s, const char *filename) return e; } else { /* if file failed to load, show a scratch buffer */ - b = eb_new("*scratch*", BF_SAVELOG | BF_UTF8 | BF_PREVIEW); - eb_printf(b, "Cannot load file %s", filename); - switch_to_buffer(e, b); + b = qe_new_buffer(s->qs, "*scratch*", BF_SAVELOG | BF_UTF8 | BF_PREVIEW); + if (b) { + // XXX: should show error cause + eb_printf(b, "Cannot load file %s", filename); + switch_to_buffer(e, b); + } return NULL; } } @@ -1464,7 +1467,7 @@ static void dired_parent(EditState *s, int collapse) if (s->b->flags & BF_PREVIEW) { EditState *e = find_window(s, KEY_LEFT, NULL); if (e && (e->flags & WF_FILELIST)) { - s->qe_state->active_window = e; + s->qs->active_window = e; return; } } @@ -1616,7 +1619,7 @@ static int dired_mode_init(EditState *s, EditBuffer *b, int flags) if (flags & MODEF_NEWINSTANCE) { b->flags |= BF_DIRED; ds->header_lines = 2; - if (s->width <= s->qe_state->width / 3) + if (s->width <= s->qs->width / 3) ds->header_lines = 1; eb_create_style_buffer(b, BF_STYLE1); /* XXX: File system charset should be detected automatically */ @@ -1656,7 +1659,7 @@ static int dired_mode_probe(ModeDef *mode, ModeProbeData *p) void do_dired_path(EditState *s, const char *filename) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; EditBuffer *b; EditState *e; DiredState *ds; @@ -1677,7 +1680,10 @@ void do_dired_path(EditState *s, const char *filename) goto new_window; } } - b = eb_scratch("*dired*", BF_READONLY | BF_UTF8); + b = qe_new_buffer(qs, "*dired*", BC_REUSE | BC_CLEAR | BF_READONLY | BF_UTF8); + if (!b) + return; + e = insert_window_left(b, qs->width / 5, WF_MODELINE | WF_FILELIST); if (!e) return; @@ -1917,12 +1923,12 @@ static int dired_init(QEmacsState *qs) dired_mode.display_hook = dired_display_hook; dired_mode.get_default_path = dired_get_default_path; - //eb_register_data_type(&dired_data_type); - qe_register_mode(&dired_mode, /* MODEF_DATATYPE | */ MODEF_MAJOR | MODEF_VIEW); - qe_register_variables(dired_variables, countof(dired_variables)); - qe_register_commands(&dired_mode, dired_commands, countof(dired_commands)); - qe_register_commands(NULL, dired_global_commands, countof(dired_global_commands)); - qe_register_completion(&dired_sort_completion); + //qe_register_data_type(qs, &dired_data_type); + qe_register_mode(qs, &dired_mode, /* MODEF_DATATYPE | */ MODEF_MAJOR | MODEF_VIEW); + qe_register_variables(qs, dired_variables, countof(dired_variables)); + qe_register_commands(qs, &dired_mode, dired_commands, countof(dired_commands)); + qe_register_commands(qs, NULL, dired_global_commands, countof(dired_global_commands)); + qe_register_completion(qs, &dired_sort_completion); filelist_init(qs); @@ -1967,7 +1973,7 @@ static void filelist_display_hook(EditState *s) char buf[MAX_FILENAME_SIZE]; char dir[MAX_FILENAME_SIZE]; char filename[MAX_FILENAME_SIZE]; - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; EditState *e; int i, len, offset, target_line; @@ -2018,7 +2024,7 @@ static void filelist_display_hook(EditState *s) void do_filelist(EditState *s, int argval) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; EditState *e; e = insert_window_left(s->b, qs->width / 5, WF_MODELINE | WF_FILELIST); @@ -2069,9 +2075,9 @@ static int filelist_init(QEmacsState *qs) filelist_mode.mode_init = filelist_mode_init; filelist_mode.display_hook = filelist_display_hook; - qe_register_mode(&filelist_mode, MODEF_VIEW); - qe_register_commands(&filelist_mode, filelist_commands, countof(filelist_commands)); - qe_register_commands(NULL, filelist_global_commands, countof(filelist_global_commands)); + qe_register_mode(qs, &filelist_mode, MODEF_VIEW); + qe_register_commands(qs, &filelist_mode, filelist_commands, countof(filelist_commands)); + qe_register_commands(qs, NULL, filelist_global_commands, countof(filelist_global_commands)); return 0; } diff --git a/modes/docbook.c b/modes/docbook.c index 6649eb4..a24d867 100644 --- a/modes/docbook.c +++ b/modes/docbook.c @@ -2,7 +2,7 @@ * WYSIWYG Docbook mode for QEmacs. * * Copyright (c) 2002 Fabrice Bellard. - * Copyright (c) 2003-2023 Charlie Gordon. + * Copyright (c) 2003-2024 Charlie Gordon. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -63,7 +63,7 @@ static int docbook_init(QEmacsState *qs) docbook_mode.mode_probe = docbook_mode_probe; docbook_mode.mode_init = docbook_mode_init; - qe_register_mode(&docbook_mode, MODEF_VIEW); + qe_register_mode(qs, &docbook_mode, MODEF_VIEW); return 0; } diff --git a/modes/fractal.c b/modes/fractal.c index 7455965..2e94029 100644 --- a/modes/fractal.c +++ b/modes/fractal.c @@ -877,7 +877,7 @@ static void fractal_display(EditState *s) { } s->display_invalid = 0; } - if (s->qe_state->active_window == s) { + if (s->qs->active_window == s) { /* Update cursor */ int xc = s->xleft; int yc = s->ytop; @@ -923,7 +923,7 @@ static void fractal_display(EditState *s) { } s->display_invalid = 0; } - if (s->qe_state->active_window == s) { + if (s->qs->active_window == s) { /* Update cursor */ int xc = s->xleft; int yc = s->ytop; @@ -1045,7 +1045,7 @@ static void do_fractal_help(EditState *s) if (ms == NULL) return; - b = new_help_buffer(); + b = new_help_buffer(s); if (!b) return; @@ -1206,6 +1206,7 @@ static void fractal_mode_free(EditBuffer *b, void *state) { } static void do_mandelbrot_test(EditState *s, int argval) { + QEmacsState *qs = s->qs; EditBuffer *b; if (!fractal_mode.name) { @@ -1222,16 +1223,12 @@ static void do_mandelbrot_test(EditState *s, int argval) { #if USE_BITMAP_API || USE_DRAW_PICTURE fractal_mode.display = fractal_display; #endif - qe_register_mode(&fractal_mode, MODEF_NOCMD | MODEF_VIEW); - qe_register_commands(&fractal_mode, fractal_commands, countof(fractal_commands)); + qe_register_mode(qs, &fractal_mode, MODEF_NOCMD | MODEF_VIEW); + qe_register_commands(qs, &fractal_mode, fractal_commands, countof(fractal_commands)); } - b = eb_find("*Mandelbrot*"); - if (b) { - eb_clear(b); - } else { - b = eb_new("*Mandelbrot*", BF_UTF8 | BF_STYLE4); - } + // XXX: should handle multiple Mandelbrot sets for comparison + b = qe_new_buffer(qs, "*Mandelbrot*", BC_REUSE | BC_CLEAR | BF_UTF8 | BF_STYLE4); if (!b) return; @@ -1256,8 +1253,8 @@ static const CmdDef fractal_global_commands[] = { static int fractal_init(QEmacsState *qs) { - qe_register_mode(&fractint_mode, MODEF_SYNTAX); - qe_register_commands(NULL, fractal_global_commands, countof(fractal_global_commands)); + qe_register_mode(qs, &fractint_mode, MODEF_SYNTAX); + qe_register_commands(qs, NULL, fractal_global_commands, countof(fractal_global_commands)); return 0; } diff --git a/modes/hex.c b/modes/hex.c index 26b1669..6987a80 100644 --- a/modes/hex.c +++ b/modes/hex.c @@ -2,7 +2,7 @@ * Hexadecimal modes for QEmacs. * * Copyright (c) 2000-2001 Fabrice Bellard. - * Copyright (c) 2002-2023 Charlie Gordon. + * Copyright (c) 2002-2024 Charlie Gordon. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -372,12 +372,12 @@ static ModeDef hex_mode = { static int hex_init(QEmacsState *qs) { /* first register mode(s) */ - qe_register_mode(&binary_mode, MODEF_VIEW); - qe_register_mode(&hex_mode, MODEF_VIEW); + qe_register_mode(qs, &binary_mode, MODEF_VIEW); + qe_register_mode(qs, &hex_mode, MODEF_VIEW); /* commands and default keys */ - qe_register_commands(&binary_mode, binary_commands, countof(binary_commands)); - qe_register_commands(&hex_mode, hex_commands, countof(hex_commands)); + qe_register_commands(qs, &binary_mode, binary_commands, countof(binary_commands)); + qe_register_commands(qs, &hex_mode, hex_commands, countof(hex_commands)); return 0; } diff --git a/modes/html.c b/modes/html.c index 4f3e4f7..51a07fc 100644 --- a/modes/html.c +++ b/modes/html.c @@ -2,7 +2,7 @@ * Graphical HTML mode for QEmacs. * * Copyright (c) 2001-2002 Fabrice Bellard. - * Copyright (c) 2003-2023 Charlie Gordon. + * Copyright (c) 2003-2024 Charlie Gordon. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -110,11 +110,12 @@ static void recompute_offset(EditState *s) } /* output error message in error buffer */ -void css_error(const char *filename, int line_num, const char *msg) +void css_error(void *error_opaque, const char *filename, int line_num, const char *msg) { + QEmacsState *qs = error_opaque; EditBuffer *b; - b = eb_find_new(HTML_ERROR_BUFFER, BF_READONLY | BF_UTF8); + b = qe_new_buffer(qs, HTML_ERROR_BUFFER, BC_REUSE | BF_READONLY | BF_UTF8); if (!b) return; b->flags &= ~BF_READONLY; @@ -153,6 +154,7 @@ static int html_test_abort(qe__unused__ void *opaque) static void html_display(EditState *s) { + QEmacsState *qs = s->qs; HTMLState *hs; CSSRect cursor_pos; DirType dirc; @@ -187,8 +189,9 @@ static void html_display(EditState *s) css_delete_document(&hs->css_ctx); /* find error message buffer */ - b = eb_find(HTML_ERROR_BUFFER); + b = qe_find_buffer_name(qs, HTML_ERROR_BUFFER); if (b) { + // FIXME: should use eb_clear()? eb_delete(b, 0, b->total_size); } @@ -209,7 +212,7 @@ static void html_display(EditState *s) hs->top_box = xml_parse_buffer(s->b, s->b->name, 0, s->b->total_size, hs->css_ctx->style_sheet, hs->parse_flags, - html_test_abort, NULL); + html_test_abort, NULL, qs); timer_stop("xml_parse_buffer"); if (!hs->top_box) return; @@ -333,7 +336,7 @@ static void html_display(EditState *s) } /* display cursor */ - if (cursor_found && s->qe_state->active_window == s) { + if (cursor_found && qs->active_window == s) { int x, y, w, h; x = cursor_pos.x1; @@ -568,7 +571,7 @@ static void html_move_up_down(EditState *s, int dir) if (!hs->up_to_date) return; - if (s->qe_state->last_cmd_func != (CmdFunc)do_up_down) + if (s->qs->last_cmd_func != (CmdFunc)do_up_down) s->up_down_last_x = -1; html_move_up_down1(s, dir, 0); @@ -803,7 +806,7 @@ static void load_default_style_sheet(HTMLState *hs, const char *stylesheet_str, style_sheet = css_new_style_sheet(); - css_parse_style_sheet_str(style_sheet, stylesheet_str, flags); + css_parse_style_sheet_str(style_sheet, hs->base.qs, stylesheet_str, flags); hs->default_style_sheet = style_sheet; } @@ -943,8 +946,8 @@ static int html_init(QEmacsState *qs) { css_init(); - qe_register_mode(&html_mode, MODEF_VIEW); - qe_register_commands(&html_mode, html_commands, countof(html_commands)); + qe_register_mode(qs, &html_mode, MODEF_VIEW); + qe_register_commands(qs, &html_mode, html_commands, countof(html_commands)); return 0; } diff --git a/modes/image.c b/modes/image.c index c8bc33d..69ec0c0 100644 --- a/modes/image.c +++ b/modes/image.c @@ -2,7 +2,7 @@ * Image mode for QEmacs. * * Copyright (c) 2002-2003 Fabrice Bellard. - * Copyright (c) 2003-2023 Charlie Gordon. + * Copyright (c) 2003-2024 Charlie Gordon. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -924,10 +924,10 @@ static CompletionDef pixel_format_completion = { static int image_init(QEmacsState *qs) { av_register_all(); - eb_register_data_type(&image_data_type); - qe_register_mode(&image_mode, MODEF_DATATYPE | MODEF_VIEW); - qe_register_commands(&image_mode, image_commands, countof(image_commands)); - qe_register_completion(&pixel_format_completion); + qe_register_data_type(qs, &image_data_type); + qe_register_mode(qs, &image_mode, MODEF_DATATYPE | MODEF_VIEW); + qe_register_commands(qs, &image_mode, image_commands, countof(image_commands)); + qe_register_completion(qs, &pixel_format_completion); return 0; } diff --git a/modes/latex-mode.c b/modes/latex-mode.c index 19088d4..aeca537 100644 --- a/modes/latex-mode.c +++ b/modes/latex-mode.c @@ -241,32 +241,26 @@ static void latex_cmd_run(void *opaque, char *cmd, struct latex_function *func = (struct latex_function *)opaque; char dir[MAX_FILENAME_SIZE]; const char *path = NULL; + EditState *s = func->es; + QEmacsState *qs = s->qs; if (cmd == NULL) { - put_status(func->es, "Aborted"); + put_status(s, "Aborted"); return; } /* get the directory of the open file and change into it */ - if (func->es->b) { - path = get_default_path(func->es->b, func->es->b->total_size, - dir, sizeof dir); - } + path = get_default_path(s->b, s->b->total_size, dir, sizeof dir); if (func->output_to_buffer) { - /* if the buffer already exists, kill it */ - EditBuffer *b = eb_find("*LaTeX output*"); - if (b) { - /* XXX: e should not become invalid */ - qe_kill_buffer(b); - } - - /* create new buffer */ - b = new_shell_buffer(NULL, NULL, "*LaTeX output*", NULL, path, cmd, - SF_COLOR | SF_INFINITE); + EditBuffer *b; + /* invoke command in shell buffer */ + b = qe_new_shell_buffer(qs, NULL, s, "*LaTeX output*", NULL, + path, cmd, SF_COLOR | SF_INFINITE | + SF_REUSE_BUFFER | SF_ERASE_BUFFER); if (b) { /* XXX: try to split window if necessary */ - switch_to_buffer(func->es, b); + switch_to_buffer(s, b); } } else { int pid = fork(); @@ -356,10 +350,10 @@ static CompletionDef latex_completion = { static int latex_init(QEmacsState *qs) { - qe_register_mode(&latex_mode, MODEF_SYNTAX); - qe_register_mode(&texinfo_mode, MODEF_SYNTAX); - qe_register_commands(&latex_mode, latex_commands, countof(latex_commands)); - qe_register_completion(&latex_completion); + qe_register_mode(qs, &latex_mode, MODEF_SYNTAX); + qe_register_mode(qs, &texinfo_mode, MODEF_SYNTAX); + qe_register_commands(qs, &latex_mode, latex_commands, countof(latex_commands)); + qe_register_completion(qs, &latex_completion); return 0; } diff --git a/modes/markdown.c b/modes/markdown.c index 1747727..c51d1af 100644 --- a/modes/markdown.c +++ b/modes/markdown.c @@ -108,11 +108,11 @@ static int mkd_scan_chunk(const char32_t *str, int i0, return 0; } -static int mkd_add_lang(const char *lang_name, char c) { +static int mkd_add_lang(QEmacsState *qs, const char *lang_name, char c) { ModeDef *m; int lang = 0; - if (lang_name && (m = qe_find_mode(lang_name, MODEF_SYNTAX)) != NULL) { + if (lang_name && (m = qe_find_mode(qs, lang_name, MODEF_SYNTAX)) != NULL) { for (lang = 1; lang < MKD_LANG_MAX; lang++) { if (mkd_lang_def[lang] == NULL) mkd_lang_def[lang] = m; @@ -270,7 +270,7 @@ static void mkd_colorize_line(QEColorizeContext *cp, lang_name[len] = '\0'; if (len) { /* XXX: unrecognised info-string should select text-mode */ - lang = mkd_add_lang(lang_name, str[j]); + lang = mkd_add_lang(cp->s->qs, lang_name, str[j]); } else if (lang == 0) { // get default lang is from mode; @@ -636,7 +636,7 @@ static void do_mkd_goto(EditState *s, const char *dest) static void do_mkd_mark_element(EditState *s, int subtree) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; int offset, offset1, level; offset = mkd_find_heading(s, s->offset, &level, 0); @@ -651,7 +651,7 @@ static void do_mkd_mark_element(EditState *s, int subtree) s->offset = offset1; /* activate region hilite */ - if (s->qe_state->hilite_region) + if (s->qs->hilite_region) s->region_style = QE_STYLE_REGION_HILITE; } @@ -778,7 +778,10 @@ static void do_mkd_move_subtree(EditState *s, int dir) } offset2 = mkd_next_heading(s, offset1, level, &level2); } - b1 = eb_new("*tmp*", BF_SYSTEM | (s->b->flags & BF_STYLES)); + // XXX: should have a way to move buffer contents + b1 = qe_new_buffer(s->qs, "*tmp*", BF_SYSTEM | (s->b->flags & BF_STYLES)); + if (!b1) + return; eb_set_charset(b1, s->b->charset, s->b->eol_type); eb_insert_buffer_convert(b1, 0, s->b, offset, size); eb_delete(s->b, offset, size); @@ -915,7 +918,7 @@ static int litcoffee_mode_init(EditState *s, EditBuffer *b, int flags) s->indent_tabs_mode = 0; /* XXX: should come from mode.default_wrap */ s->wrap = WRAP_WORD; - s->mode->colorize_flags = mkd_add_lang("coffee", 0); + s->mode->colorize_flags = mkd_add_lang(s->qs, "coffee", 0); } return 0; } @@ -930,10 +933,10 @@ static ModeDef litcoffee_mode = { static int mkd_init(QEmacsState *qs) { - qe_register_mode(&mkd_mode, MODEF_SYNTAX); - qe_register_commands(&mkd_mode, mkd_commands, countof(mkd_commands)); - qe_register_mode(&litcoffee_mode, MODEF_SYNTAX); - qe_register_commands(&litcoffee_mode, mkd_commands, countof(mkd_commands)); + qe_register_mode(qs, &mkd_mode, MODEF_SYNTAX); + qe_register_commands(qs, &mkd_mode, mkd_commands, countof(mkd_commands)); + qe_register_mode(qs, &litcoffee_mode, MODEF_SYNTAX); + qe_register_commands(qs, &litcoffee_mode, mkd_commands, countof(mkd_commands)); return 0; } diff --git a/modes/mpeg.c b/modes/mpeg.c index 4e0f218..c543148 100644 --- a/modes/mpeg.c +++ b/modes/mpeg.c @@ -176,7 +176,7 @@ static ModeDef mpeg_mode = { static int mpeg_init(QEmacsState *qs) { - qe_register_mode(&mpeg_mode, MODEF_MAJOR | MODEF_VIEW); + qe_register_mode(qs, &mpeg_mode, MODEF_MAJOR | MODEF_VIEW); return 0; } diff --git a/modes/orgmode.c b/modes/orgmode.c index 5ff3070..edcff01 100644 --- a/modes/orgmode.c +++ b/modes/orgmode.c @@ -462,7 +462,7 @@ static void do_org_goto(EditState *s, const char *dest) static void do_org_mark_element(EditState *s, int subtree) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; int offset, offset1, level; offset = org_find_heading(s, s->offset, &level, 0); @@ -477,7 +477,7 @@ static void do_org_mark_element(EditState *s, int subtree) s->offset = offset1; /* activate region hilite */ - if (s->qe_state->hilite_region) + if (s->qs->hilite_region) s->region_style = QE_STYLE_REGION_HILITE; } @@ -638,7 +638,10 @@ static void do_org_move_subtree(EditState *s, int dir) } offset2 = org_next_heading(s, offset1, level, &level2); } - b1 = eb_new("*tmp*", BF_SYSTEM | (s->b->flags & BF_STYLES)); + // XXX: should have a way to move buffer contents + b1 = qe_new_buffer(s->qs, "*tmp*", BF_SYSTEM | (s->b->flags & BF_STYLES)); + if (!b1) + return; eb_set_charset(b1, s->b->charset, s->b->eol_type); eb_insert_buffer_convert(b1, 0, s->b, offset, size); eb_delete(s->b, offset, size); @@ -767,8 +770,8 @@ static ModeDef org_mode = { static int org_init(QEmacsState *qs) { - qe_register_mode(&org_mode, MODEF_SYNTAX); - qe_register_commands(&org_mode, org_commands, countof(org_commands)); + qe_register_mode(qs, &org_mode, MODEF_SYNTAX); + qe_register_commands(qs, &org_mode, org_commands, countof(org_commands)); return 0; } diff --git a/modes/shell.c b/modes/shell.c index 3b2add2..6b69d29 100644 --- a/modes/shell.c +++ b/modes/shell.c @@ -84,7 +84,6 @@ typedef struct ShellState { int utf8_len; EditBuffer *b; EditBuffer *b_color; /* color buffer, one byte per char */ - struct QEmacsState *qe_state; const char *ka1, *ka3, *kb2, *kc1, *kc3, *kcbt, *kspd; const char *kbeg, *kbs, *kent, *kdch1, *kich1; const char *kcub1, *kcud1, *kcuf1, *kcuu1; @@ -192,7 +191,8 @@ const char *get_shell(void) #define QE_TERM_YSIZE 25 #define QE_TERM_YSIZE_INFINITE 10000 -static int run_process(const char *cmd, int *fd_ptr, int *pid_ptr, +static int run_process(ShellState *s, + const char *cmd, int *fd_ptr, int *pid_ptr, int cols, int rows, const char *path, int shell_flags) { @@ -204,7 +204,7 @@ static int run_process(const char *cmd, int *fd_ptr, int *pid_ptr, pty_fd = get_pty(tty_name, sizeof(tty_name)); if (pty_fd < 0) { - put_status(NULL, "run_process: cannot get tty: %s", + put_status(s->b->qs->active_window, "run_process: cannot get tty: %s", strerror(errno)); return -1; } @@ -219,7 +219,7 @@ static int run_process(const char *cmd, int *fd_ptr, int *pid_ptr, pid = fork(); if (pid < 0) { - put_status(NULL, "run_process: cannot fork"); + put_status(s->b->qs->active_window, "run_process: cannot fork"); return -1; } if (pid == 0) { @@ -306,18 +306,19 @@ static int run_process(const char *cmd, int *fd_ptr, int *pid_ptr, /* VT100 emulation */ static void qe_trace_term(ShellState *s, const char *msg) { - eb_trace_bytes(msg, -1, EB_TRACE_FLUSH | EB_TRACE_EMULATE); - eb_trace_bytes(": ", -1, EB_TRACE_EMULATE); - eb_trace_bytes(s->term_buf, s->term_len, EB_TRACE_EMULATE); + QEmacsState *qs = s->base.qs; + qe_trace_bytes(qs, msg, -1, EB_TRACE_FLUSH | EB_TRACE_EMULATE); + qe_trace_bytes(qs, ": ", -1, EB_TRACE_EMULATE); + qe_trace_bytes(qs, s->term_buf, s->term_len, EB_TRACE_EMULATE); } #define TRACE_MSG(s, m) qe_trace_term(s, m) #define TRACE_PRINTF(s, ...) do { \ - if (s->qe_state->trace_buffer) { \ - if (s->qe_state->trace_buffer_state) \ - eb_putc(s->qe_state->trace_buffer, '\n'); \ - eb_printf(s->qe_state->trace_buffer, __VA_ARGS__); \ - s->qe_state->trace_buffer_state = 0; \ + if (s->base.qs->trace_buffer) { \ + if (s->base.qs->trace_buffer_state) \ + eb_putc(s->base.qs->trace_buffer, '\n'); \ + eb_printf(s->base.qs->trace_buffer, __VA_ARGS__); \ + s->base.qs->trace_buffer_state = 0; \ } \ } while(0) @@ -484,8 +485,8 @@ static void qe_term_write(ShellState *s, const char *buf, int len) if (len < 0) len = strlen(buf); - if (s->qe_state->trace_buffer) - eb_trace_bytes(buf, len, EB_TRACE_PTY); + if (s->base.qs->trace_buffer) + qe_trace_bytes(s->base.qs, buf, len, EB_TRACE_PTY); while (len > 0) { ret = write(s->pty_fd, buf, len); @@ -1268,7 +1269,7 @@ static int qe_term_csi_m(ShellState *s, const int *params, int count) static void qe_term_update_cursor(qe__unused__ ShellState *s) { #if 0 - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->base.qs; EditState *e; if (s->cur_offset == -1) @@ -1312,8 +1313,8 @@ static void shell_key(void *opaque, int key) return; if (key == KEY_CTRL('o')) { - qe_ungrab_keys(); - unget_key(key); + qe_ungrab_keys(s->base.qs); + qe_unget_key(s->base.qs, key); return; } p = buf; @@ -1416,7 +1417,7 @@ static void qe_term_emulate(ShellState *s, int c) break; case 7: /* BEL Bell (Ctrl-G). */ // XXX: should check for visible-bell - put_status(NULL, "Ding!"); + put_status(s->b->qs->active_window, "Ding!"); break; case 8: /* BS Backspace (Ctrl-H). */ //TRACE_PRINTF(s, "BS: "); @@ -2162,7 +2163,7 @@ static void qe_term_emulate(ShellState *s, int c) if (s->shell_flags & SF_INTERACTIVE) { /* only grab keys in interactive qe_term buffers */ s->grab_keys = 1; - qe_grab_keys(shell_key, s); + qe_grab_keys(s->base.qs, shell_key, s); /* Should also clear screen */ } if (!s->use_alternate_screen) { @@ -2247,7 +2248,7 @@ static void qe_term_emulate(ShellState *s, int c) case 1049: /* Use Normal Screen Buffer and restore cursor as in DECRC. */ if (s->shell_flags & SF_INTERACTIVE) { - qe_ungrab_keys(); + qe_ungrab_keys(s->base.qs); s->grab_keys = 0; } if (s->use_alternate_screen) { @@ -2383,9 +2384,9 @@ static void shell_read_cb(void *opaque) return; b = s->b; - qs = s->qe_state; + qs = s->base.qs; if (qs->trace_buffer) - eb_trace_bytes(buf, len, EB_TRACE_SHELL); + qe_trace_bytes(qs, buf, len, EB_TRACE_SHELL); /* Suspend BF_READONLY flag to allow shell output to readonly buffer */ save_readonly = b->flags & BF_READONLY; @@ -2437,7 +2438,7 @@ static void shell_read_cb(void *opaque) } /* now we do some refresh (should just invalidate?) */ - edit_display(qs); + qe_display(qs); dpy_flush(qs->screen); } @@ -2496,7 +2497,7 @@ static void shell_pid_cb(void *opaque, int status) return; b = s->b; - qs = s->qe_state; + qs = s->base.qs; *buf = '\0'; if (s->caption) { @@ -2541,7 +2542,7 @@ static void shell_pid_cb(void *opaque, int status) /* remove shell input mode */ s->grab_keys = 0; - qe_ungrab_keys(); + qe_ungrab_keys(qs); for (e = qs->first_window; e != NULL; e = e->next_window) { if (e->b == b) { e->interactive = 0; @@ -2556,27 +2557,35 @@ static void shell_pid_cb(void *opaque, int status) //shell_mode_free(b, s); // called by qe_free_mode_data qe_free_mode_data(&s->base); } - edit_display(qs); + qe_display(qs); dpy_flush(qs->screen); } -EditBuffer *new_shell_buffer(EditBuffer *b0, EditState *e, - const char *bufname, const char *caption, - const char *path, - const char *cmd, int shell_flags) +EditBuffer *qe_new_shell_buffer(QEmacsState *qs, EditBuffer *b0, EditState *e, + const char *bufname, const char *caption, + const char *path, const char *cmd, + int shell_flags) { - QEmacsState *qs = &qe_state; ShellState *s; EditBuffer *b; const char *lang; int cols, rows; + if (!b0 && (shell_flags & SF_REUSE_BUFFER)) { + b0 = qe_find_buffer_name(qs, bufname); + if (b0) { + if (shell_flags & SF_ERASE_BUFFER) + eb_clear(b0); + } + } + b = b0; if (!b) { - b = eb_new(bufname, BF_SAVELOG | BF_SHELL); + b = qe_new_buffer(qs, bufname, BF_SAVELOG | BF_SHELL); if (!b) return NULL; } + shell_flags &= ~(SF_REUSE_BUFFER | SF_ERASE_BUFFER); eb_set_buffer_name(b, bufname); /* ensure that the name is unique */ if (shell_flags & SF_COLOR) { @@ -2607,7 +2616,6 @@ EditBuffer *new_shell_buffer(EditBuffer *b0, EditState *e, s->b = b; s->pty_fd = -1; s->pid = -1; - s->qe_state = qs; s->caption = caption; s->shell_flags = shell_flags; s->cur_prompt = s->cur_offset = b->total_size; @@ -2624,7 +2632,7 @@ EditBuffer *new_shell_buffer(EditBuffer *b0, EditState *e, s->cols = cols; s->rows = rows; - if (run_process(cmd, &s->pty_fd, &s->pid, cols, rows, path, shell_flags) < 0) { + if (run_process(s, cmd, &s->pty_fd, &s->pid, cols, rows, path, shell_flags) < 0) { if (!b0) eb_free(&b); return NULL; @@ -2638,14 +2646,15 @@ EditBuffer *new_shell_buffer(EditBuffer *b0, EditState *e, /* If a window is attached to buffer b, activate it, otherwise attach window s to buffer b. + *sp is not NULL. */ static EditBuffer *try_show_buffer(EditState **sp, const char *bufname) { EditState *e, *s = *sp; - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; EditBuffer *b; - b = eb_find(bufname); + b = qe_find_buffer_name(qs, bufname); if (b && s->b != b) { e = eb_find_window(b, NULL); if (e) { @@ -2704,8 +2713,8 @@ static void do_shell(EditState *e, int argval) } /* create new shell buffer or restart shell in current buffer */ - b = new_shell_buffer(b, e, "*shell*", "Shell process", curpath, NULL, - SF_COLOR | SF_INTERACTIVE); + b = qe_new_shell_buffer(e->qs, b, e, "*shell*", "Shell process", + curpath, NULL, SF_COLOR | SF_INTERACTIVE); if (!b) return; @@ -2731,7 +2740,7 @@ static void do_man(EditState *s, const char *arg) if (s->flags & WF_POPLEFT) { /* avoid messing with the dired pane */ s = find_window(s, KEY_RIGHT, s); - s->qe_state->active_window = s; + s->qs->active_window = s; } /* Assume standard man command */ @@ -2742,8 +2751,8 @@ static void do_man(EditState *s, const char *arg) return; /* create new buffer */ - b = new_shell_buffer(NULL, s, bufname, NULL, NULL, cmd, - SF_COLOR | SF_INFINITE); + b = qe_new_shell_buffer(s->qs, NULL, s, bufname, NULL, + NULL, cmd, SF_COLOR | SF_INFINITE); if (!b) return; @@ -2765,7 +2774,7 @@ static void do_ssh(EditState *s, const char *arg) if (s->flags & WF_POPLEFT) { /* avoid messing with the dired pane */ s = find_window(s, KEY_RIGHT, s); - s->qe_state->active_window = s; + s->qs->active_window = s; } /* Use standard ssh command */ @@ -2773,8 +2782,8 @@ static void do_ssh(EditState *s, const char *arg) snprintf(bufname, sizeof(bufname), "*ssh-%s*", arg); /* create new buffer */ - b = new_shell_buffer(NULL, s, bufname, "ssh", NULL, cmd, - SF_COLOR | SF_INTERACTIVE); + b = qe_new_shell_buffer(s->qs, NULL, s, bufname, "ssh", + NULL, cmd, SF_COLOR | SF_INTERACTIVE); if (!b) return; @@ -3142,7 +3151,7 @@ static void do_shell_yank(EditState *e) * made asynchronous via an auxiliary buffer. */ int offset; - QEmacsState *qs = e->qe_state; + QEmacsState *qs = e->qs; EditBuffer *b = qs->yank_buffers[qs->yank_current]; e->b->mark = e->offset; @@ -3207,7 +3216,7 @@ static void do_shell_refresh(EditState *e, int flags) ShellState *s; if ((s = shell_get_state(e, 1)) != NULL) { - QEmacsState *qs = e->qe_state; + QEmacsState *qs = e->qs; EditState *e1; /* update the terminal size and notify process */ @@ -3248,7 +3257,7 @@ static void do_shell_toggle_input(EditState *e) if ((s->shell_flags & SF_INTERACTIVE) && e->offset >= e->b->total_size) { e->interactive = 1; if (s->grab_keys) - qe_grab_keys(shell_key, s); + qe_grab_keys(s->base.qs, shell_key, s); #if 0 if (e->interactive) { qe_term_update_cursor(s); @@ -3325,30 +3334,28 @@ static char *shell_get_default_path(EditBuffer *b, int offset, static void do_shell_command(EditState *e, const char *cmd) { char curpath[MAX_FILENAME_SIZE]; + QEmacsState *qs = e->qs; EditBuffer *b; get_default_path(e->b, e->offset, curpath, sizeof curpath); - /* if the buffer already exists, kill it */ - b = eb_find("*shell command output*"); - if (b) { - qe_kill_buffer(b); - } - /* create new buffer */ - b = new_shell_buffer(NULL, e, "*shell command output*", NULL, curpath, cmd, - SF_COLOR | SF_INFINITE); + b = qe_new_shell_buffer(qs, NULL, e, "*shell command output*", NULL, + curpath, cmd, SF_COLOR | SF_INFINITE | + SF_REUSE_BUFFER | SF_ERASE_BUFFER); if (!b) return; /* XXX: try to split window if necessary */ switch_to_buffer(e, b); + // FIXME: if command prompts for input, the buffer should use shell_mode edit_set_mode(e, &pager_mode); } static void do_compile(EditState *s, const char *cmd) { char curpath[MAX_FILENAME_SIZE]; + QEmacsState *qs = s->qs; EditBuffer *b; if (s->flags & (WF_POPUP | WF_MINIBUF)) @@ -3359,21 +3366,16 @@ static void do_compile(EditState *s, const char *cmd) if (s->flags & WF_POPLEFT) { /* avoid messing with the dired pane */ s = find_window(s, KEY_RIGHT, s); - s->qe_state->active_window = s; - } - - /* if the buffer already exists, kill it */ - b = eb_find("*compilation*"); - if (b) { - qe_kill_buffer(b); + qs->active_window = s; } if (!cmd || !*cmd) cmd = "make"; /* create new buffer */ - b = new_shell_buffer(NULL, s, "*compilation*", "Compilation", curpath, cmd, - SF_COLOR | SF_INFINITE); + b = qe_new_shell_buffer(qs, NULL, s, "*compilation*", "Compilation", + curpath, cmd, SF_COLOR | SF_INFINITE | + SF_REUSE_BUFFER | SF_ERASE_BUFFER); if (!b) return; @@ -3386,7 +3388,7 @@ static void do_compile(EditState *s, const char *cmd) static void do_next_error(EditState *s, int arg, int dir) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; EditState *e; EditBuffer *b; int offset, found_offset; @@ -3409,10 +3411,10 @@ static void do_next_error(EditState *s, int arg, int dir) * in buffer least recently used order */ - if ((b = eb_find(error_buffer)) == NULL) { - if ((b = eb_find("*compilation*")) == NULL - && (b = eb_find("*shell*")) == NULL - && (b = eb_find("*errors*")) == NULL) { + if ((b = qe_find_buffer_name(qs, error_buffer)) == NULL) { + if ((b = qe_find_buffer_name(qs, "*compilation*")) == NULL + && (b = qe_find_buffer_name(qs, "*shell*")) == NULL + && (b = qe_find_buffer_name(qs, "*errors*")) == NULL) { put_status(s, "No compilation buffer"); return; } @@ -3580,8 +3582,8 @@ static int shell_grab_filename(const char32_t *buf, int n, char *dest, int size) static ModeDef *mode_cache[STATE_SHELL_MODE + 1]; static int mode_cache_len = 1; -static int shell_find_mode(const char *filename) { - ModeDef *m = qe_find_mode_filename(filename, MODEF_SYNTAX); +static int qe_shell_find_mode(QEmacsState *qs, const char *filename) { + ModeDef *m = qe_find_mode_filename(qs, filename, MODEF_SYNTAX); int i; for (i = 0; i < mode_cache_len; i++) { @@ -3613,7 +3615,7 @@ void shell_colorize_line(QEColorizeContext *cp, if (str[0] == '+' || str[0] == '-') { if (match_string(str, n, "+++ ") || match_string(str, n, "--- ")) { shell_grab_filename(str + 4, n - 4, filename, countof(filename)); - cp->colorize_state = shell_find_mode(filename); + cp->colorize_state = qe_shell_find_mode(cp->s->qs, filename); cp->colorize_state |= STATE_SHELL_SKIP | STATE_SHELL_KEEP; return; } else @@ -3637,7 +3639,7 @@ void shell_colorize_line(QEColorizeContext *cp, i = 4; i += shell_grab_filename(str + i, n - i, filename, countof(filename)); if (match_string(str + i, n - i, " <==")) { - cp->colorize_state = shell_find_mode(filename); + cp->colorize_state = qe_shell_find_mode(cp->s->qs, filename); cp->colorize_state |= STATE_SHELL_KEEP; return; } @@ -3662,7 +3664,7 @@ void shell_colorize_line(QEColorizeContext *cp, if ((w = match_string(str + i, n - i, commands[k])) != 0) { i += w; shell_grab_filename(str + i, n - i, filename, countof(filename)); - cp->colorize_state = shell_find_mode(filename); + cp->colorize_state = qe_shell_find_mode(cp->s->qs, filename); cp->colorize_state |= STATE_SHELL_KEEP; start = n; return; @@ -3685,7 +3687,7 @@ void shell_colorize_line(QEColorizeContext *cp, continue; } i += w; - mc = shell_find_mode(filename); + mc = qe_shell_find_mode(cp->s->qs, filename); if (!mc) continue; c = str[i]; @@ -3916,9 +3918,9 @@ static int shell_init(QEmacsState *qs) shell_mode.delete_bytes = shell_delete_bytes; shell_mode.get_default_path = shell_get_default_path; - qe_register_mode(&shell_mode, MODEF_NOCMD | MODEF_VIEW); - qe_register_commands(&shell_mode, shell_commands, countof(shell_commands)); - qe_register_commands(NULL, shell_global_commands, countof(shell_global_commands)); + qe_register_mode(qs, &shell_mode, MODEF_NOCMD | MODEF_VIEW); + qe_register_commands(qs, &shell_mode, shell_commands, countof(shell_commands)); + qe_register_commands(qs, NULL, shell_global_commands, countof(shell_global_commands)); /* populate and register pager mode and commands */ // XXX: remove this mess: should just inherit with fallback @@ -3928,7 +3930,7 @@ static int shell_init(QEmacsState *qs) pager_mode.mode_init = pager_mode_init; pager_mode.bindings = pager_bindings; - qe_register_mode(&pager_mode, MODEF_NOCMD | MODEF_VIEW); + qe_register_mode(qs, &pager_mode, MODEF_NOCMD | MODEF_VIEW); return 0; } diff --git a/modes/stb.c b/modes/stb.c index 5136f3f..2d4eac3 100644 --- a/modes/stb.c +++ b/modes/stb.c @@ -1,7 +1,7 @@ /* * QEmacs graphics mode for image files * - * Copyright (c) 2017-2023 Charlie Gordon. + * Copyright (c) 2017-2024 Charlie Gordon. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -105,7 +105,7 @@ static void image_display(EditState *s) { } s->display_invalid = 0; } - if (s->qe_state->active_window == s) { + if (s->qs->active_window == s) { /* Update cursor */ int xc = s->xleft; int yc = s->ytop; @@ -161,7 +161,7 @@ static ModeDef stb_mode = { static int stb_init(QEmacsState *qs) { - qe_register_mode(&stb_mode, MODEF_VIEW); + qe_register_mode(qs, &stb_mode, MODEF_VIEW); return 0; } diff --git a/modes/unihex.c b/modes/unihex.c index e215367..f76c7b6 100644 --- a/modes/unihex.c +++ b/modes/unihex.c @@ -2,7 +2,7 @@ * Unicode Hexadecimal mode for QEmacs. * * Copyright (c) 2000-2001 Fabrice Bellard. - * Copyright (c) 2002-2023 Charlie Gordon. + * Copyright (c) 2002-2024 Charlie Gordon. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -267,7 +267,7 @@ static ModeDef unihex_mode = { }; static int unihex_init(QEmacsState *qs) { - qe_register_mode(&unihex_mode, MODEF_VIEW); + qe_register_mode(qs, &unihex_mode, MODEF_VIEW); return 0; } diff --git a/modes/video.c b/modes/video.c index f11aa7b..78e16fa 100644 --- a/modes/video.c +++ b/modes/video.c @@ -221,7 +221,7 @@ static inline VideoState *video_get_state(EditState *e, int status) static void video_refresh_timer(void *opaque) { EditState *s = opaque; - QEmacsState *qs = &qe_state; + QEmacsState *qs = s->qs; VideoState *is; VideoPicture *vp; @@ -243,7 +243,7 @@ static void video_refresh_timer(void *opaque) is->no_background = 1; /* XXX: horrible, needs complete rewrite */ /* display picture */ - edit_display(qs); + qe_display(qs); dpy_flush(qs->screen); /* update queue size and signal for next picture */ @@ -267,7 +267,7 @@ static void video_refresh_timer(void *opaque) is->no_background = 1; /* XXX: horrible, needs complete rewrite */ /* display picture */ - edit_display(qs); + qe_display(qs); dpy_flush(qs->screen); } else { is->video_timer = qe_add_timer(100, s, video_refresh_timer); @@ -830,7 +830,7 @@ static int video_mode_init(EditState *s, EditBuffer *b, int flags) { if (s) { VideoState *is = qe_get_buffer_mode_data(b, &video_mode, NULL); - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; int err, video_playing; EditState *e; @@ -1026,9 +1026,9 @@ static EditBufferDataType video_data_type = { }; static int video_init(QEmacsState *qs) { - eb_register_data_type(&video_data_type); - qe_register_mode(&video_mode, MODEF_DATATYPE | MODEF_VIEW); - qe_register_commands(&video_mode, video_commands, countof(video_commands)); + qe_register_data_type(qs, &video_data_type); + qe_register_mode(qs, &video_mode, MODEF_DATATYPE | MODEF_VIEW); + qe_register_commands(qs, &video_mode, video_commands, countof(video_commands)); return 0; } diff --git a/plugins/my_plugin.c b/plugins/my_plugin.c index f2a354a..318ee68 100644 --- a/plugins/my_plugin.c +++ b/plugins/my_plugin.c @@ -17,7 +17,7 @@ static const CmdDef my_commands[] = { static int my_plugin_init(QEmacsState *qs) { /* commands and default keys */ - qe_register_commands(NULL, my_commands, countof(my_commands)); + qe_register_commands(qs, NULL, my_commands, countof(my_commands)); return 0; } diff --git a/qe.c b/qe.c index 489806f..6d35e39 100644 --- a/qe.c +++ b/qe.c @@ -42,7 +42,7 @@ void print_at_byte(QEditScreen *screen, int x, int y, int width, int height, const char *str, QETermStyle style); static EditBuffer *predict_switch_to_buffer(EditState *s); -static void qe_key_process(int key); +static void qe_key_process(QEmacsState *qs, int key); static int generic_save_window_data(EditState *s); static int generic_mode_init(EditState *s); @@ -50,10 +50,10 @@ static void generic_mode_close(EditState *s); static void generic_text_display(EditState *s); static void display1(DisplayState *ds); #ifndef CONFIG_TINY -static void save_selection(QEmacsState *qs, int copy); +static void qe_save_selection(QEmacsState *qs, int copy); #endif -QEmacsState qe_state; +static QEmacsState qe_state; /* should handle multiple screens, and multiple sessions */ static QEditScreen global_screen; static int screen_width = 0; @@ -87,9 +87,8 @@ static int generic_mode_probe(ModeDef *mode, ModeProbeData *p) return 1; } -ModeDef *qe_find_mode(const char *name, int flags) +ModeDef *qe_find_mode(QEmacsState *qs, const char *name, int flags) { - QEmacsState *qs = &qe_state; ModeDef *m; strstart(name, "lang-", &name); @@ -104,9 +103,8 @@ ModeDef *qe_find_mode(const char *name, int flags) return m; } -ModeDef *qe_find_mode_filename(const char *filename, int flags) +ModeDef *qe_find_mode_filename(QEmacsState *qs, const char *filename, int flags) { - QEmacsState *qs = &qe_state; ModeDef *m; for (m = qs->first_mode; m; m = m->next) { @@ -119,9 +117,8 @@ ModeDef *qe_find_mode_filename(const char *filename, int flags) return m; } -void qe_register_mode(ModeDef *m, int flags) +void qe_register_mode(QEmacsState *qs, ModeDef *m, int flags) { - QEmacsState *qs = &qe_state; ModeDef **p; /* register mode in mode list (at end) */ @@ -208,18 +205,18 @@ void qe_register_mode(ModeDef *m, int flags) def->val = 0; def->action.ESs = do_set_mode; /* register allocated command */ - qe_register_commands(NULL, def, -1); + qe_register_commands(qs, NULL, def, -1); } if (m->bindings) { int i; for (i = 0; m->bindings[i]; i += 2) { - qe_register_bindings(&m->first_key, m->bindings[i + 1], m->bindings[i]); + qe_register_bindings(qs, &m->first_key, m->bindings[i + 1], m->bindings[i]); } } } void mode_complete(CompleteState *cp, CompleteFunc enumerate) { - QEmacsState *qs = cp->s->qe_state; + QEmacsState *qs = cp->s->qs; ModeDef *m; for (m = qs->first_mode; m != NULL; m = m->next) { @@ -236,9 +233,8 @@ static CompletionDef mode_completion = { /* commands handling */ -const CmdDef *qe_find_cmd(const char *cmd_name) +const CmdDef *qe_find_cmd(QEmacsState *qs, const char *cmd_name) { - QEmacsState *qs = &qe_state; const CmdDef *d; int i, j; @@ -252,7 +248,7 @@ const CmdDef *qe_find_cmd(const char *cmd_name) } void command_complete(CompleteState *cp, CompleteFunc enumerate) { - QEmacsState *qs = cp->s->qe_state; + QEmacsState *qs = cp->s->qs; const CmdDef *d; int i, j; @@ -274,7 +270,7 @@ int eb_command_print_entry(EditBuffer *b, const CmdDef *d, EditState *s) { qe_get_prototype(d, buf, sizeof buf); len += eb_puts(b, buf); #ifndef CONFIG_TINY - if (qe_list_bindings(d, s->mode, 1, buf, sizeof buf)) { + if (qe_list_bindings(b->qs, d, s->mode, 1, buf, sizeof buf)) { b->cur_style = QE_STYLE_COMMENT; if (len + 1 < 40) { b->tab_width = max_int(len + 1, b->tab_width); @@ -291,7 +287,7 @@ int eb_command_print_entry(EditBuffer *b, const CmdDef *d, EditState *s) { } int command_print_entry(CompleteState *cp, EditState *s, const char *name) { - const CmdDef *d = qe_find_cmd(name); + const CmdDef *d = qe_find_cmd(s->qs, name); if (d) { // XXX: should pass the target window return eb_command_print_entry(s->b, d, s); @@ -374,7 +370,7 @@ static int qe_unregister_binding(KeyDef **lp, unsigned int *keys, int nb_keys) { } /* if mode is non NULL, the defined keys are only active in this mode */ -static int qe_register_command_bindings(KeyDef **lp, const CmdDef *d, const char *keystr) +static int qe_register_command_bindings(QEmacsState *qs, KeyDef **lp, const CmdDef *d, const char *keystr) { unsigned int keys[MAX_KEYS]; int nb_keys, res = -2; @@ -387,12 +383,12 @@ static int qe_register_command_bindings(KeyDef **lp, const CmdDef *d, const char return res; } -int qe_register_bindings(KeyDef **lp, const char *cmd_name, const char *keys) { - return qe_register_command_bindings(lp, qe_find_cmd(cmd_name), keys); +int qe_register_bindings(QEmacsState *qs, KeyDef **lp, const char *cmd_name, const char *keys) { + return qe_register_command_bindings(qs, lp, qe_find_cmd(qs, cmd_name), keys); } int qe_register_transient_binding(QEmacsState *qs, const char *cmd_name, const char *keys) { - return qe_register_command_bindings(&qs->first_transient_key, qe_find_cmd(cmd_name), keys); + return qe_register_command_bindings(qs, &qs->first_transient_key, qe_find_cmd(qs, cmd_name), keys); } static void qe_unregister_bindings(KeyDef **lp, const char *keystr) { @@ -407,9 +403,8 @@ static void qe_unregister_bindings(KeyDef **lp, const char *keystr) { } /* if mode is non NULL, the defined keys are only active in this mode */ -int qe_register_commands(ModeDef *m, const CmdDef *cmds, int len) +int qe_register_commands(QEmacsState *qs, ModeDef *m, const CmdDef *cmds, int len) { - QEmacsState *qs = &qe_state; KeyDef **lp = m ? &m->first_key : &qs->first_key; const CmdDef *d; int i, allocated = 0; @@ -431,7 +426,7 @@ int qe_register_commands(ModeDef *m, const CmdDef *cmds, int len) if (i >= qs->cmd_array_size) { int n = max_int(i + 16, 32); if (!qe_realloc_array(&qs->cmd_array, n)) { - put_status(NULL, "Out of memory"); + qe_put_error(qs, "Out of memory"); return -1; } qs->cmd_array_size = n; @@ -445,7 +440,7 @@ int qe_register_commands(ModeDef *m, const CmdDef *cmds, int len) for (d = cmds, i = len; i-- > 0; d++) { const char *p = d->name + strlen(d->name) + 1; if (*p) - qe_register_command_bindings(lp, d, p); + qe_register_command_bindings(qs, lp, d, p); } return 0; } @@ -453,8 +448,9 @@ int qe_register_commands(ModeDef *m, const CmdDef *cmds, int len) void do_set_key(EditState *s, const char *keystr, const char *cmd_name, int local) { - KeyDef **lp = local ? &s->mode->first_key : &s->qe_state->first_key; - int res = qe_register_bindings(lp, cmd_name, keystr); + QEmacsState *qs = s->qs; + KeyDef **lp = local ? &s->mode->first_key : &qs->first_key; + int res = qe_register_bindings(qs, lp, cmd_name, keystr); if (res == -2) put_status(s, "Invalid keys: %s", keystr); if (res == -1) @@ -462,16 +458,12 @@ void do_set_key(EditState *s, const char *keystr, } void do_unset_key(EditState *s, const char *keystr, int local) { - KeyDef **lp = local ? &s->mode->first_key : &s->qe_state->first_key; + KeyDef **lp = local ? &s->mode->first_key : &s->qs->first_key; qe_unregister_bindings(lp, keystr); } -void do_toggle_control_h(EditState *s, int set) +void qe_toggle_control_h(QEmacsState *qs, int set) { - /* Achtung Minen! do_toggle_control_h can be called from tty_init - * with a NULL EditState. - */ - QEmacsState *qs = s ? s->qe_state : &qe_state; ModeDef *m; KeyDef *kd; int i; @@ -512,6 +504,10 @@ void do_toggle_control_h(EditState *s, int set) } } +void do_toggle_control_h(EditState *s, int set) { + qe_toggle_control_h(s->qs, set); +} + static const char * const epsilon_bindings[] = { "C-w", "isearch-toggle-word-match", "isearch", "M-w", "isearch-yank-word", "isearch", @@ -556,19 +552,19 @@ static const char * const gosmacs_bindings[] = { NULL }; -static void register_emulation_bindings(QEmacsState *qs, const char * const *pp) { +static void qe_register_emulation_bindings(QEmacsState *qs, const char * const *pp) { int i; for (i = 0; pp[i]; i += 3) { KeyDef **lp = &qs->first_key; if (pp[i + 2]) { - ModeDef *mode = qe_find_mode(pp[i + 2], 0); + ModeDef *mode = qe_find_mode(qs, pp[i + 2], 0); if (!mode) continue; lp = &mode->first_key; } qe_unregister_bindings(lp, pp[i]); if (pp[i]) - qe_register_bindings(lp, pp[i + 1], pp[i]); + qe_register_bindings(qs, lp, pp[i + 1], pp[i]); } } @@ -577,20 +573,20 @@ static void do_qemacs_version(EditState *s) { } void do_set_emulation(EditState *s, const char *name) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; if (strequal(name, "epsilon")) { - register_emulation_bindings(qs, epsilon_bindings); + qe_register_emulation_bindings(qs, epsilon_bindings); qs->emulation_flags = 1; qs->flag_split_window_change_focus = 1; } else if (strequal(name, "emacs") || strequal(name, "xemacs")) { - register_emulation_bindings(qs, emacs_bindings); + qe_register_emulation_bindings(qs, emacs_bindings); qs->emulation_flags = 0; qs->flag_split_window_change_focus = 0; } else if (strequal(name, "gosmacs")) { - register_emulation_bindings(qs, gosmacs_bindings); + qe_register_emulation_bindings(qs, gosmacs_bindings); qs->emulation_flags = 2; } else if (strequal(name, "vi") || strequal(name, "vim")) { @@ -618,7 +614,7 @@ struct QETraceDef const qe_trace_defs[] = { size_t const qe_trace_defs_count = sizeof(qe_trace_defs) / sizeof (qe_trace_defs[0]); void do_set_trace_flags(EditState *s, int flags) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; qs->trace_flags = flags; if (qs->trace_flags) { @@ -627,7 +623,9 @@ void do_set_trace_flags(EditState *s, int flags) { size_t i; if (!qs->trace_buffer) { - qs->trace_buffer = eb_new("*trace*", BF_SYSTEM | BF_UTF8); + qs->trace_buffer = qe_new_buffer(qs, "*trace*", BF_SYSTEM | BF_UTF8); + if (!qs->trace_buffer) + return; } if (!eb_find_window(qs->trace_buffer, NULL)) { EditState *e = qe_split_window(s, SW_STACKED, 75); @@ -651,7 +649,7 @@ void do_set_trace_flags(EditState *s, int flags) { } void do_toggle_trace_mode(EditState *s, int argval) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; if (argval == NO_ARG) { /* toggle trace mode */ do_set_trace_flags(s, qs->trace_flags ? 0 : EB_TRACE_ALL); @@ -662,7 +660,7 @@ void do_toggle_trace_mode(EditState *s, int argval) { void do_set_trace_options(EditState *s, const char *options) { const char *p = options; - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; int flags = qs->trace_flags; for (;;) { @@ -783,7 +781,7 @@ static CompletionDef color_completion = { void do_bof(EditState *s) { - maybe_set_mark(s); + do_maybe_set_mark(s); if (s->mode->move_bof) s->mode->move_bof(s); @@ -791,7 +789,7 @@ void do_bof(EditState *s) void do_eof(EditState *s) { - maybe_set_mark(s); + do_maybe_set_mark(s); if (s->mode->move_eof) s->mode->move_eof(s); @@ -799,7 +797,7 @@ void do_eof(EditState *s) void do_bol(EditState *s) { - maybe_set_mark(s); + do_maybe_set_mark(s); if (s->mode->move_bol) s->mode->move_bol(s); @@ -807,7 +805,7 @@ void do_bol(EditState *s) void do_eol(EditState *s) { - maybe_set_mark(s); + do_maybe_set_mark(s); if (s->mode->move_eol) s->mode->move_eol(s); @@ -817,7 +815,7 @@ void do_word_left_right(EditState *s, int n) { int dir = n < 0 ? -1 : 1; - maybe_set_mark(s); + do_maybe_set_mark(s); for (; n != 0; n -= dir) { if (s->mode->move_word_left_right) @@ -927,7 +925,7 @@ void do_mark_region(EditState *s, int mark, int offset) s->b->mark = clamp_offset(mark, 0, s->b->total_size); s->offset = clamp_offset(offset, 0, s->b->total_size); /* activate region hilite */ - if (s->qe_state->hilite_region) + if (s->qs->hilite_region) s->region_style = QE_STYLE_REGION_HILITE; } @@ -1014,7 +1012,7 @@ void do_delete_char(EditState *s, int argval) return; if (argval == NO_ARG) { - if (s->qe_state->last_cmd_func != (CmdFunc)do_append_next_kill) { + if (s->qs->last_cmd_func != (CmdFunc)do_append_next_kill) { /* delete character with its combining glyphs */ eb_delete_glyphs(s->b, s->offset, 1); return; @@ -1125,14 +1123,14 @@ void do_backspace(EditState *s, int argval) return; } if (argval == NO_ARG) { - if ((s->qe_state->last_cmd_func == (CmdFunc)do_tabulate || - s->qe_state->last_cmd_func == (CmdFunc)do_backward_delete_tab) + if ((s->qs->last_cmd_func == (CmdFunc)do_tabulate || + s->qs->last_cmd_func == (CmdFunc)do_backward_delete_tab) && !s->indent_tabs_mode && !s->multi_cursor_active) { do_backward_delete_tab(s, 1); - s->qe_state->this_cmd_func = (CmdFunc)do_backward_delete_tab; + s->qs->this_cmd_func = (CmdFunc)do_backward_delete_tab; return; } - if (s->qe_state->last_cmd_func != (CmdFunc)do_append_next_kill) { + if (s->qs->last_cmd_func != (CmdFunc)do_append_next_kill) { /* backspace without prefix argument deletes combining accents */ if (eb_delete_chars(s->b, s->offset, -1)) { /* special case for composing */ @@ -1249,7 +1247,7 @@ void do_up_down(EditState *s, int n) { int dir = n < 0 ? -1 : 1; - maybe_set_mark(s); + do_maybe_set_mark(s); for (; n != 0; n -= dir) { #ifndef CONFIG_TINY @@ -1271,16 +1269,16 @@ void do_left_right(EditState *s, int n) { int dir = n < 0 ? -1 : 1; - maybe_set_mark(s); + do_maybe_set_mark(s); for (; n != 0; n -= dir) { #ifndef CONFIG_TINY if (s->b->flags & BF_PREVIEW) { EditState *e = find_window(s, KEY_LEFT, NULL); if (e && (e->flags & WF_FILELIST) - && s->qe_state->active_window == s + && s->qs->active_window == s && dir < 0 && eb_at_bol(s->b, s->offset)) { - s->qe_state->active_window = e; + s->qs->active_window = e; return; } } @@ -1296,7 +1294,7 @@ void text_move_up_down(EditState *s, int dir) DisplayState ds1, *ds = &ds1; CursorContext cm; - if (s->qe_state->last_cmd_func != (CmdFunc)do_up_down) + if (s->qs->last_cmd_func != (CmdFunc)do_up_down) s->up_down_last_x = -1; get_cursor_pos(s, &cm); @@ -1420,7 +1418,7 @@ void do_scroll_left_right(EditState *s, int n) void do_scroll_up_down(EditState *s, int dir) { - maybe_set_mark(s); + do_maybe_set_mark(s); if (s->mode->scroll_up_down) s->mode->scroll_up_down(s, dir); @@ -1690,7 +1688,7 @@ static int mouse_goto_func(DisplayState *ds, to select the right column. */ void text_mouse_goto(EditState *s, int x, int y, QEEvent *ev) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; EditState *curw = qs->active_window; MouseGotoContext m1, *m = &m1; DisplayState ds1, *ds = &ds1; @@ -1763,7 +1761,8 @@ void text_mouse_goto(EditState *s, int x, int y, QEEvent *ev) } /* activate window unless curw is modal */ - if (!(curw && (curw->flags & (WF_POPUP | WF_MINIBUF)))) { + if (!(curw && (curw->flags & (WF_POPUP | WF_MINIBUF))) + && !qs->key_ctx.grab_key_cb) { qs->active_window = s; } if (s->mouse_force_highlight) @@ -2006,11 +2005,12 @@ static void quote_key(void *opaque, int key) // qemacs supports special keys and inserts the keyboard sequence struct QuoteKeyArgument *qa = opaque; EditState *s = qa->s; + QEmacsState *qs = s->qs; int repeat = qa->argval; put_status(s, ""); /* erase "Quote: " message */ /* Achtung! this should free the grab data */ - qe_ungrab_keys(); + qe_ungrab_keys(qs); if (!s) return; @@ -2022,7 +2022,6 @@ static void quote_key(void *opaque, int key) do_delete_selection(s); if (s->mode->write_char) { - QEmacsState *qs = s->qe_state; int save_overwrite = s->overwrite; /* quoted-insert always inserts characters */ s->overwrite = 0; @@ -2037,19 +2036,23 @@ static void quote_key(void *opaque, int key) } } s->overwrite = save_overwrite; - edit_display(s->qe_state); + qe_display(qs); dpy_flush(&global_screen); } } void do_quoted_insert(EditState *s, int argval) { + QEmacsState *qs = s->qs; struct QuoteKeyArgument *qa = qe_mallocz(struct QuoteKeyArgument); + if (qa == NULL) // FIXME: error message? + return; + qa->s = s; qa->has_arg = (argval != NO_ARG); qa->argval = qa->has_arg ? argval : 1; - qe_grab_keys(quote_key, qa); + qe_grab_keys(qs, quote_key, qa); put_status(s, "Quote: "); } @@ -2196,8 +2199,8 @@ void do_tabulate(EditState *s, int argval) if (s->b->flags & BF_PREVIEW) { EditState *e = find_window(s, KEY_LEFT, NULL); if (e && (e->flags & WF_FILELIST) - && s->qe_state->active_window == s) { - s->qe_state->active_window = e; + && s->qs->active_window == s) { + s->qs->active_window = e; return; } } @@ -2289,7 +2292,7 @@ void do_space(EditState *s, int key, int argval) #endif static void do_unknown_key(EditState *s) { - QEmacsState *qs = s ? s->qe_state : &qe_state; + QEmacsState *qs = s->qs; char buf[80]; buf_t out[1]; int i; @@ -2331,9 +2334,9 @@ void do_set_mark(EditState *s) put_status(s, "Mark set"); } -void maybe_set_mark(EditState *s) +void do_maybe_set_mark(EditState *s) { - if (!s->region_style && is_shift_key(s->qe_state->last_key)) { + if (!s->region_style && is_shift_key(s->qs->last_key)) { do_set_mark(s); } } @@ -2343,7 +2346,8 @@ void do_mark_whole_buffer(EditState *s) do_mark_region(s, s->b->total_size, 0); } -EditBuffer *new_yank_buffer(QEmacsState *qs, EditBuffer *base) +/* base buffer may be null */ +EditBuffer *qe_new_yank_buffer(QEmacsState *qs, EditBuffer *base) { char bufname[32]; EditBuffer *b; @@ -2353,15 +2357,20 @@ EditBuffer *new_yank_buffer(QEmacsState *qs, EditBuffer *base) cur = (cur + 1) % NB_YANK_BUFFERS; qs->yank_current = cur; /* Maybe should instead just clear the buffer and reset styles */ - qe_kill_buffer(qs->yank_buffers[cur]); + qe_kill_buffer(qs, qs->yank_buffers[cur]); + // XXX: qe_kill_buffer should have cleared this already qs->yank_buffers[cur] = NULL; } snprintf(bufname, sizeof(bufname), "*kill-%d*", cur + 1); if (base) { - b = eb_new(bufname, BF_SYSTEM | (base->flags & BF_STYLES)); + b = qe_new_buffer(qs, bufname, BF_SYSTEM | (base->flags & BF_STYLES)); + if (!b) + return NULL; eb_set_charset(b, base->charset, base->eol_type); } else { - b = eb_new(bufname, BF_SYSTEM); + b = qe_new_buffer(qs, bufname, BF_SYSTEM); + if (!b) + return NULL; } qs->yank_buffers[cur] = b; return b; @@ -2374,7 +2383,7 @@ void do_append_next_kill(qe__unused__ EditState *s) void do_kill(EditState *s, int p1, int p2, int dir, int keep) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; int len, tmp; EditBuffer *b; @@ -2390,7 +2399,7 @@ void do_kill(EditState *s, int p1, int p2, int dir, int keep) b = qs->yank_buffers[qs->yank_current]; if (!b || !dir || qs->last_cmd_func != (CmdFunc)do_append_next_kill) { /* append kill if last command was kill already */ - b = new_yank_buffer(qs, s->b); + b = qe_new_yank_buffer(qs, s->b); } /* insert at beginning or end depending on kill direction */ eb_insert_buffer_convert(b, dir < 0 ? 0 : b->total_size, s->b, p1, len); @@ -2519,7 +2528,7 @@ void do_yank(EditState *s) { qemacs: with a C-u prefix, yank n copies of the last killed block */ int size; - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; EditBuffer *b; if (s->b->flags & BF_READONLY) @@ -2545,7 +2554,7 @@ void do_yank(EditState *s) { void do_yank_pop(EditState *s) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; if (qs->last_cmd_func != (CmdFunc)do_yank) { put_status(s, "Previous command was not a yank"); @@ -2635,6 +2644,7 @@ QEModeData *qe_create_buffer_mode_data(EditBuffer *b, ModeDef *m) if (md) { md->mode = m; md->b = b; + md->qs = b->qs; md->next = b->mode_data_list; b->mode_data_list = md; } @@ -2670,6 +2680,7 @@ QEModeData *qe_create_window_mode_data(EditState *s, ModeDef *m) if (md) { md->mode = m; md->s = s; + md->qs = s->qs; s->mode_data = md; } } @@ -2690,11 +2701,15 @@ void *qe_get_window_mode_data(EditState *e, ModeDef *m, int status) } void *check_mode_data(void **pp) { - QEmacsState *qs = &qe_state; QEModeData *md = *pp; + QEmacsState *qs; EditBuffer *b; EditState *e; + if (md == NULL) + return NULL; + + qs = md->qs; for (b = qs->first_buffer; b != NULL; b = b->next) { QEModeData **mdp; for (mdp = &b->mode_data_list; *mdp; mdp = &(*mdp)->next) { @@ -2716,7 +2731,7 @@ int qe_free_mode_data(QEModeData *md) if (!md) return 0; - if (check_buffer(&md->b)) { + if (qe_check_buffer(md->qs, &md->b)) { EditBuffer *b = md->b; QEModeData **mdp; for (mdp = &b->mode_data_list; *mdp; mdp = &(*mdp)->next) { @@ -2730,7 +2745,7 @@ int qe_free_mode_data(QEModeData *md) } } } - if (check_window(&md->s)) { + if (qe_check_window(md->qs, &md->s)) { if (md->s->mode_data == md) { md->s->mode_data = NULL; rc = 0; @@ -2769,7 +2784,7 @@ int edit_set_mode(EditState *s, ModeDef *m) /* try to remove the raw or mode specific data if it is no longer used. */ data_count = 0; - for (e = s->qe_state->first_window; e != NULL; e = e->next_window) { + for (e = s->qs->first_window; e != NULL; e = e->next_window) { if (e != s && e->b == b) { if (e->mode && e->mode->data_type != &raw_data_type) data_count++; @@ -2869,7 +2884,7 @@ void do_set_mode(EditState *s, const char *name) s = qe_find_target_window(s, 0); /* XXX: should check if mode is appropriate */ - m = qe_find_mode(name, 0); + m = qe_find_mode(s->qs, name, 0); if (m) edit_set_mode(s, m); else @@ -2900,7 +2915,7 @@ QECharset *read_charset(EditState *s, const char *charset_str, charset_str = buf; } - charset = find_charset(charset_str); + charset = qe_find_charset(s->qs, charset_str); if (!charset) { put_status(s, "Unknown charset '%s'", charset_str); return NULL; @@ -2967,7 +2982,9 @@ void do_convert_buffer_file_coding_system(EditState *s, b = s->b; - b1 = eb_new("*tmp*", b->flags & BF_STYLES); + b1 = qe_new_buffer(s->qs, "*tmp*", b->flags & BF_STYLES); + if (!b1) + return; eb_set_charset(b1, charset, eol_type); /* preserve positions */ @@ -3024,25 +3041,25 @@ void do_toggle_bidir(EditState *s) static void update_setting(EditState *s, const char *name, int *pval, int argval) { *pval = (argval == NO_ARG) ? !*pval : (argval > 0); - s->qe_state->complete_refresh = 1; + s->qs->complete_refresh = 1; put_status(s, "%s %s", name, *pval ? "enabled" : "disabled"); } static void do_line_number_mode(EditState *s, int argval) { - update_setting(s, "line-number-mode", &s->qe_state->line_number_mode, argval); + update_setting(s, "line-number-mode", &s->qs->line_number_mode, argval); } static void do_column_number_mode(EditState *s, int argval) { - update_setting(s, "column-number-mode", &s->qe_state->column_number_mode, argval); + update_setting(s, "column-number-mode", &s->qs->column_number_mode, argval); } static void do_global_linum_mode(EditState *s, int argval) { - update_setting(s, "global-linum-mode", &s->qe_state->global_linum_mode, argval); + update_setting(s, "global-linum-mode", &s->qs->global_linum_mode, argval); } static int has_linum_mode(EditState *s) { return (s->b->linum_mode_set ? s->b->linum_mode : - (s->qe_state->global_linum_mode && + (s->qs->global_linum_mode && !(s->b->flags & (BF_DIRED | BF_SHELL)) && !(s->flags & (WF_POPUP | WF_MINIBUF)))); } @@ -3390,9 +3407,9 @@ void text_mode_line(EditState *s, buf_t *out) basic_mode_line(s, out, wrap_mode); eb_get_pos(s->b, &line_num, &col_num, s->offset); - if (s->qe_state->line_number_mode) + if (s->qs->line_number_mode) buf_printf(out, "--L%d", line_num + 1); - if (s->qe_state->column_number_mode) + if (s->qs->column_number_mode) buf_printf(out, "--C%d", col_num + 1); buf_printf(out, "--%s", s->b->charset->name); if (s->b->eol_type == EOL_DOS) @@ -3428,7 +3445,7 @@ void display_mode_line(EditState *s) s->mode->get_mode_line(s, out); if (!strequal(buf, s->modeline_shadow)) { print_at_byte(s->screen, s->xleft, y, s->width, - s->qe_state->mode_line_height, + s->qs->mode_line_height, buf, QE_STYLE_MODE_LINE); pstrcpy(s->modeline_shadow, sizeof(s->modeline_shadow), buf); } @@ -3437,7 +3454,7 @@ void display_mode_line(EditState *s) void display_window_borders(EditState *e) { - QEmacsState *qs = e->qe_state; + QEmacsState *qs = e->qs; if (e->borders_invalid) { if (e->flags & (WF_POPUP | WF_RSEPARATOR)) { @@ -3745,7 +3762,7 @@ void do_set_style(EditState *e, const char *stylestr, } break; } - e->qe_state->complete_refresh = 1; + e->qs->complete_refresh = 1; } void do_define_color(EditState *e, const char *name, const char *value) @@ -3767,7 +3784,7 @@ void do_set_display_size(qe__unused__ EditState *s, int w, int h) possible. It does not hide the modeline not the status line */ void do_toggle_full_screen(EditState *s) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; QEditScreen *screen = s->screen; if (screen->dpy.dpy_full_screen) { @@ -3799,7 +3816,7 @@ void do_set_window_style(EditState *s, const char *stylestr) void do_set_system_font(EditState *s, const char *qe_font_name, const char *system_fonts) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; int font_type; font_type = css_get_enum(qe_font_name, "fixed,serif,sans"); @@ -5030,7 +5047,7 @@ int text_display_line(EditState *s, DisplayState *ds, int offset) colored_nb_chars = get_colorized_line(cp, offset, &offset0, line_num); if (s->mode == &list_mode) { // TODO: should use a `colorize_line_hook` for this - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; int i; if ((qs->active_window == s || s->force_highlight) && @@ -5137,7 +5154,7 @@ int text_display_line(EditState *s, DisplayState *ds, int offset) display_printf(ds, offset0, offset, "^%c", ('@' + c) & 127); } else if (c >= 128 - && (s->qe_state->show_unicode == 1 || + && (s->qs->show_unicode == 1 || c == 0xfeff || /* Display BOM as \uFEFF to make it explicit */ c > MAX_UNICODE_DISPLAY || (c < 160 && s->b->charset == &charset_raw))) { @@ -5220,7 +5237,7 @@ static void generic_text_display(EditState *s) bottom = s->mode->display_line(s, ds, offset); if (m->xc == NO_CURSOR) { /* XXX: should not happen */ - put_error(NULL, "ERROR: cursor not found"); + put_error(s, "ERROR: cursor not found"); ds->y = 0; } else { ds->y = m->yc + m->cursor_height; @@ -5318,7 +5335,7 @@ static void generic_text_display(EditState *s) yc = m->yc; if (xc != NO_CURSOR && yc != NO_CURSOR - && s->qe_state->active_window == s) { + && s->qs->active_window == s) { int x, y, w, h; x = s->xleft + xc; y = s->ytop + yc; @@ -5579,11 +5596,12 @@ static void free_cmd(ExecCmdState **esp); void exec_command(EditState *s, const CmdDef *d, int argval, int key) { + QEmacsState *qs = s->qs; ExecCmdState *es; const char *argdesc; - if (qe_state.trace_buffer) - eb_trace_bytes(d->name, -1, EB_TRACE_COMMAND); + if (qs->trace_buffer) + qe_trace_bytes(qs, d->name, -1, EB_TRACE_COMMAND); argdesc = d->spec; if (*argdesc == '*') { @@ -5623,7 +5641,7 @@ void exec_command(EditState *s, const CmdDef *d, int argval, int key) static void parse_arguments(ExecCmdState *es) { EditState *s = es->s; - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; QErrorContext ec; const CmdDef *d = es->d; CmdArg *argp; @@ -5678,7 +5696,7 @@ static void parse_arguments(ExecCmdState *es) /* if no argument specified, try to ask it to the user */ if (get_arg && cas.prompt[0] != '\0') { char def_input[1024]; - StringArray *hist = qe_get_history(cas.history); + StringArray *hist = qe_get_history(qs, cas.history); /* XXX: currently, default input is handled non generically */ /* XXX: should use completion function for default input? */ def_input[0] = '\0'; @@ -5731,7 +5749,7 @@ static void parse_arguments(ExecCmdState *es) s->compose_len = 0; } #ifndef CONFIG_TINY - save_selection(qs, FALSE); + qe_save_selection(qs, FALSE); #endif /* Save and restore ec context */ ec = qs->ec; @@ -5790,12 +5808,12 @@ static void arg_edit_cb(void *opaque, char *str, CompletionDef *completion) switch (es->args_type[index]) { case CMD_ARG_INT: if (completion && completion->convert_entry) { - val = completion->convert_entry(str, &p); + val = completion->convert_entry(es->s, str, &p); } else { val = strtol_c(str, &p, 0); } if (*p != '\0') { - put_status(NULL, "Invalid number: %s", str); + put_status(es->s, "Invalid number: %s", str); goto fail; } es->args[index].n = val; @@ -5827,7 +5845,7 @@ void do_execute_command(EditState *s, const char *cmd, int argval) const CmdDef *d; /* XXX: should test for '(' and '=' and evaluate script instead */ - d = qe_find_cmd(cmd); + d = qe_find_cmd(s->qs, cmd); if (d) { exec_command(s, d, argval, 0); } else { @@ -5837,7 +5855,7 @@ void do_execute_command(EditState *s, const char *cmd, int argval) void window_display(EditState *s) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; CSSRect rect; /* set the clipping rectangle to the whole window */ @@ -5861,7 +5879,7 @@ void window_display(EditState *s) /* display all windows */ /* XXX: should use correct clipping to avoid popups display hacks */ -void edit_display(QEmacsState *qs) +void qe_display(QEmacsState *qs) { EditState *s; int has_popups, has_minibuf; @@ -5926,7 +5944,7 @@ void edit_display(QEmacsState *qs) elapsed_time = get_clock_ms() - start_time; if (elapsed_time >= 100) - put_status(s, "|edit_display: %dms", elapsed_time); + put_status(s, "|qe_display: %dms", elapsed_time); qs->complete_refresh = 0; } @@ -5941,18 +5959,18 @@ void edit_display(QEmacsState *qs) `show-macro`, `dump-macro` to ease macro debugging and timing */ -static void clear_macro(QEmacsState *qs) { +static void qe_clear_macro(QEmacsState *qs) { qe_free(&qs->macro_keys); qs->macro_keys_size = 0; qs->nb_macro_keys = 0; qs->nb_macro_keys_run = 0; } -static void stop_macro(QEmacsState *qs) { +static void qe_stop_macro(QEmacsState *qs) { // XXX: should output a message if (qs->defining_macro) { qs->defining_macro = 0; - clear_macro(qs); + qe_clear_macro(qs); } qs->executing_macro = 0; qs->macro_key_index = -1; @@ -5971,14 +5989,14 @@ void do_start_kbd_macro(EditState *s) Use `call-last-kbd-macro` (bound to `C-x e` or `C-\`) to replay the keystrokes. */ - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; if (qs->defining_macro) { put_status(s, "Already defining kbd macro: restarting"); } else { put_status(s, "Defining kbd macro..."); } - clear_macro(qs); + qe_clear_macro(qs); qs->defining_macro = 1; qs->macro_counter = 0; } @@ -5987,7 +6005,7 @@ void do_start_kbd_macro(EditState *s) #define save_last_kbd_macro(s) #else static void save_last_kbd_macro(EditState *s) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; char buf[32]; buf_t out[1]; DynBuf db[1]; @@ -6012,28 +6030,28 @@ static void save_last_kbd_macro(EditState *s) { haskey = (len != 1); } p = dbuf_str(db); - hist = qe_get_history("macrokeys"); + hist = qe_get_history(qs, "macrokeys"); remove_string(hist, p); add_string(hist, p, 0); dbuf_free(db); } -static void macro_add_key(int key); +static void qe_macro_add_key(QEmacsState *qs, int key); static void do_edit_last_kbd_macro(EditState *s, const char *keys) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; const char *p; if (!keys || !*keys) return; - clear_macro(qs); + qe_clear_macro(qs); qs->macro_counter = 0; p = keys; while (qe_skip_spaces(&p)) { int key = strtokey(&p); - macro_add_key(key); + qe_macro_add_key(qs, key); } save_last_kbd_macro(s); put_status(s, "Keyboard macro redefined"); @@ -6041,7 +6059,7 @@ static void do_edit_last_kbd_macro(EditState *s, const char *keys) { static void do_name_last_kbd_macro(EditState *s, const char *name) { - StringArray *hist = qe_get_history("macrokeys"); + StringArray *hist = qe_get_history(s->qs, "macrokeys"); if (hist && hist->nb_items) { do_define_kbd_macro(s, name, hist->items[hist->nb_items - 1]->str, NULL); } @@ -6049,9 +6067,11 @@ static void do_name_last_kbd_macro(EditState *s, const char *name) static void do_insert_kbd_macro(EditState *s, const char *name) { + QEmacsState *qs = s->qs; EditBuffer *b = s->b; + if (name && *name) { - const CmdDef *d = qe_find_cmd(name); + const CmdDef *d = qe_find_cmd(qs, name); if (d && d->action.ESs == do_execute_macro_keys) { const char *keys = d->spec + 2; /* skip @{ */ b->offset = s->offset; @@ -6066,7 +6086,7 @@ static void do_insert_kbd_macro(EditState *s, const char *name) s->offset = b->offset; } } else { - StringArray *hist = qe_get_history("macrokeys"); + StringArray *hist = qe_get_history(qs, "macrokeys"); if (hist && hist->nb_items) { const char *keys = hist->items[hist->nb_items - 1]->str; b->offset = s->offset; @@ -6092,18 +6112,18 @@ static void do_read_kbd_macro(EditState *s, int mark, int offset) { } static void show_macro_counter(EditState *s) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; put_status(s, "new macro counter: %d", qs->macro_counter); } static void do_macro_add_counter(EditState *s, int arg) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; qs->macro_counter += arg; show_macro_counter(s); } static void do_macro_set_counter(EditState *s, int arg) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; qs->macro_counter = arg; show_macro_counter(s); } @@ -6167,7 +6187,7 @@ static int check_format_string(const char *fmt1, const char *fmt2, int max_width } static void do_macro_insert_counter(EditState *s, int arg) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; int (*eb_printf_fun)(EditBuffer *b, const char *fmt, ...) = eb_printf; const char *fmt = qs->macro_format; int n = qs->macro_counter; @@ -6185,7 +6205,7 @@ static void do_macro_insert_counter(EditState *s, int arg) { } static void do_macro_set_format(EditState *s, const char *fmt) { - QEmacsState *qs = &qe_state; + QEmacsState *qs = s->qs; qe_free(&qs->macro_format); if (fmt) qs->macro_format = qe_strdup(fmt); @@ -6200,7 +6220,7 @@ void do_end_kbd_macro(EditState *s) Stop recording the keyboard macro. The last keyboard macro can be run using `call-last-kbd-macro`. */ - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; /* if called inside a macro, it is last recorded keys, so ignore it */ @@ -6226,7 +6246,7 @@ void do_call_last_kbd_macro(EditState *s, int argval) Run the last keyboard macro recorded by `start-kbd-macro`. Repeat `argval` times. */ - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; int set_repeat = (qs->last_key == 'e'); if (qs->defining_macro) { @@ -6244,7 +6264,7 @@ void do_call_last_kbd_macro(EditState *s, int argval) qs->macro_key_index++) { int key = qs->macro_keys[qs->macro_key_index]; - qe_key_process(key); + qe_key_process(qs, key); if (qs->macro_key_index < 0) { // After 0 kbd macro iterations: Keyboard macro terminated by a command ringing the bell argval = 0; @@ -6261,7 +6281,7 @@ void do_call_last_kbd_macro(EditState *s, int argval) void do_execute_macro_keys(EditState *s, const char *keys) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; const char *p; int key; @@ -6274,7 +6294,7 @@ void do_execute_macro_keys(EditState *s, const char *keys) p = keys; while (qe_skip_spaces(&p)) { key = strtokey(&p); - qe_key_process(key); + qe_key_process(qs, key); if (!qs->executing_macro) { // After 0 kbd macro iterations: Keyboard macro terminated by a command ringing the bell } @@ -6301,7 +6321,7 @@ void do_define_kbd_macro(EditState *s, const char *name, const char *keys, */ snprintf(buf, size, "@{%s}%c", keys, 0); - d = qe_find_cmd(name); + d = qe_find_cmd(s->qs, name); if (d && d->action.ESs == do_execute_macro_keys) { /* redefininig a macro */ /* XXX: freeing the current macro definition may cause a crash if it @@ -6320,7 +6340,7 @@ void do_define_kbd_macro(EditState *s, const char *name, const char *keys, def->val = 0; def->action.ESs = do_execute_macro_keys; /* register allocated command */ - qe_register_commands(NULL, def, -1); + qe_register_commands(s->qs, NULL, def, -1); } if (key_bind && *key_bind) { do_set_key(s, key_bind, name, 0); @@ -6330,7 +6350,7 @@ void do_define_kbd_macro(EditState *s, const char *name, const char *keys, #ifndef CONFIG_TINY static void qe_save_macro(EditState *s, const CmdDef *def, EditBuffer *b) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; char buf[32]; buf_t outbuf, *out; int i; @@ -6358,7 +6378,7 @@ static void qe_save_macro(EditState *s, const CmdDef *def, EditBuffer *b) void qe_save_macros(EditState *s, EditBuffer *b) { - QEmacsState *qs = &qe_state; + QEmacsState *qs = s->qs; const CmdDef *d; int i, j; @@ -6378,9 +6398,8 @@ void qe_save_macros(EditState *s, EditBuffer *b) #define MACRO_KEY_INCR 64 -static void macro_add_key(int key) +static void qe_macro_add_key(QEmacsState *qs, int key) { - QEmacsState *qs = &qe_state; int new_size; if (qs->nb_macro_keys >= qs->macro_keys_size) { @@ -6495,22 +6514,7 @@ static void do_add_multi_cursor(EditState *s) { /*---------------- key dispatcher ----------------*/ -typedef struct QEKeyContext { - int has_arg; - int argval; - int is_escape; - int nb_keys; - int describe_key; /* if true, the following command is only displayed */ - void (*grab_key_cb)(void *opaque, int key); - void *grab_key_opaque; - unsigned int keys[MAX_KEYS]; - char buf[128]; -} QEKeyContext; - -// XXX: Should be accessible via qe_state -static QEKeyContext key_ctx; - -void do_prefix_argument(qe__unused__ EditState *s, int key) { +void do_prefix_argument(EditState *s, int key) { /* Behavior of prefix-argument keys: C-u: increment c->has_arg @@ -6523,8 +6527,8 @@ void do_prefix_argument(qe__unused__ EditState *s, int key) { if !c->is_numeric_arg: set c->arval and c->is_numeric_arg else: multiply c->argval and add digit */ - /* XXX: should get key_ctx from s->qe_state */ - QEKeyContext *c = &key_ctx; + QEmacsState *qs = s->qs; + QEKeyContext *c = &qs->key_ctx; if (key == KEY_CTRL('u')) { /* increment has_arg and multiply argval unless already numeric */ @@ -6554,9 +6558,9 @@ void do_prefix_argument(qe__unused__ EditState *s, int key) { /* * All typed keys are sent to the callback. Previous grab is aborted */ -void qe_grab_keys(void (*cb)(void *opaque, int key), void *opaque) +void qe_grab_keys(QEmacsState *qs, void (*cb)(void *opaque, int key), void *opaque) { - QEKeyContext *c = &key_ctx; + QEKeyContext *c = &qs->key_ctx; /* CG: Should free previous grab? */ /* CG: Should grabing be window dependent ? */ @@ -6567,10 +6571,9 @@ void qe_grab_keys(void (*cb)(void *opaque, int key), void *opaque) /* * Abort key grabing */ -void qe_ungrab_keys(void) +void qe_ungrab_keys(QEmacsState *qs) { - QEmacsState *qs = &qe_state; - QEKeyContext *c = &key_ctx; + QEKeyContext *c = &qs->key_ctx; /* CG: Should have an indicator to free previous grab */ c->grab_key_cb = NULL; @@ -6601,9 +6604,8 @@ KeyDef *qe_find_binding(unsigned int *keys, int nb_keys, KeyDef *kd, int exact) return kd; } -KeyDef *qe_find_current_binding(unsigned int *keys, int nb_keys, ModeDef *m, int exact) +KeyDef *qe_find_current_binding(QEmacsState *qs, unsigned int *keys, int nb_keys, ModeDef *m, int exact) { - QEmacsState *qs = &qe_state; KeyDef *kd; if (qs->first_transient_key) { @@ -6622,10 +6624,9 @@ KeyDef *qe_find_current_binding(unsigned int *keys, int nb_keys, ModeDef *m, int return qe_find_binding(keys, nb_keys, qs->first_key, exact); } -static void qe_key_process(int key) +static void qe_key_process(QEmacsState *qs, int key) { - QEmacsState *qs = &qe_state; - QEKeyContext *c = &key_ctx; + QEKeyContext *c = &qs->key_ctx; EditState *s; KeyDef *kd; const CmdDef *d; @@ -6635,7 +6636,7 @@ static void qe_key_process(int key) unsigned int key_redirect = KEY_NONE; if (qs->defining_macro && !qs->executing_macro) { - macro_add_key(key); + qe_macro_add_key(qs, key); } again: @@ -6680,7 +6681,7 @@ static void qe_key_process(int key) } /* see if one command is found */ - kd = qe_find_current_binding(c->keys, c->nb_keys, s->mode, 0); + kd = qe_find_current_binding(qs, c->keys, c->nb_keys, s->mode, 0); if (!kd) { /* no key found */ unsigned int key_default = KEY_DEFAULT; @@ -6693,7 +6694,7 @@ static void qe_key_process(int key) if (!c->nb_keys) goto next; } - kd = qe_find_current_binding(&key_default, 1, s->mode, 1); + kd = qe_find_current_binding(qs, &key_default, 1, s->mode, 1); if (kd) goto exec_cmd; } @@ -6703,7 +6704,7 @@ static void qe_key_process(int key) /* redirect to unmodified version */ // TODO: need more redirections key_redirect = key & 0xff; - kd = qe_find_current_binding(&key_redirect, 1, s->mode, 1); + kd = qe_find_current_binding(qs, &key_redirect, 1, s->mode, 1); if (kd) goto exec_cmd; } @@ -6712,12 +6713,12 @@ static void qe_key_process(int key) buf_puts(out, "No command on "); buf_put_keys(out, c->keys, c->nb_keys); if (qs->trace_buffer) - eb_trace_bytes(buf1, -1, EB_TRACE_COMMAND); + qe_trace_bytes(qs, buf1, -1, EB_TRACE_COMMAND); put_status(s, "%s%s", buf1, c->describe_key ? "" : "\007"); c->describe_key = 0; qe_key_init(c); if (qs->trace_buffer) - edit_display(qs); + qe_display(qs); dpy_flush(&global_screen); return; } else @@ -6774,21 +6775,22 @@ static void qe_key_process(int key) qs->last_key = key; } exec_command(s, d, argval, key); - if (multi_cursor_active && check_window(&s)) { + if (multi_cursor_active && qe_check_window(qs, &s)) { + int i; if (s != qs->active_window) { /* end multi-cursor session upto window change */ s->multi_cursor_active = 0; } s->multi_cursor[0].offset = s->offset; - for (int i = 1; s->multi_cursor_active && i < s->multi_cursor_len; i++) { + for (i = 1; s->multi_cursor_active && i < s->multi_cursor_len; i++) { swap_int(&s->b->mark, &s->multi_cursor[i].mark); swap_int(&s->offset, &s->multi_cursor[i].offset); s->multi_cursor_cur = i; /* prevent append-next-kill */ - if (s->qe_state->last_cmd_func == (CmdFunc)do_append_next_kill) + if (s->qs->last_cmd_func == (CmdFunc)do_append_next_kill) qs->last_cmd_func = NULL; exec_command(s, d, argval, key); - if (!check_window(&s)) + if (!qe_check_window(qs, &s)) break; s->multi_cursor_cur = 0; swap_int(&s->b->mark, &s->multi_cursor[i].mark); @@ -6805,7 +6807,7 @@ static void qe_key_process(int key) } qe_key_init(c); // XXX: should delay until after macro execution - edit_display(qs); + qe_display(qs); dpy_flush(&global_screen); /* CG: should move ungot key handling to generic event dispatch */ if (qs->ungot_key != -1) { @@ -6828,7 +6830,7 @@ static void qe_key_process(int key) } put_status(s, "~%s", c->buf); if (qs->trace_buffer) - edit_display(qs); + qe_display(qs); dpy_flush(&global_screen); } @@ -6861,7 +6863,7 @@ void print_at_byte(QEditScreen *screen, } /* XXX: should take va_list */ -static void eb_format_message(QEmacsState *qs, const char *bufname, +static void qe_format_message(QEmacsState *qs, const char *bufname, const char *message) { char header[128]; @@ -6876,7 +6878,7 @@ static void eb_format_message(QEmacsState *qs, const char *bufname, if (qs->ec.function) buf_printf(out, "%s: ", qs->ec.function); - eb = eb_find_new(bufname, BF_UTF8); + eb = qe_new_buffer(qs, bufname, BC_REUSE | BF_UTF8); if (eb) { eb_printf(eb, "%s%s\n", header, message); } else { @@ -6884,10 +6886,9 @@ static void eb_format_message(QEmacsState *qs, const char *bufname, } } -void put_error(EditState *s, const char *fmt, ...) +/* Produce an error message from internal sources */ +void qe_put_error(QEmacsState *qs, const char *fmt, ...) { - /* CG: s may be NULL! */ - QEmacsState *qs = &qe_state; char buf[MAX_SCREEN_WIDTH]; va_list ap; @@ -6895,14 +6896,41 @@ void put_error(EditState *s, const char *fmt, ...) vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); - eb_format_message(qs, "*errors*", buf); - put_status(s, "!\007%s", buf); + put_status(qs ? qs->active_window : NULL, "!\007\006%s", buf); } +void qe_dpy_error(QEditScreen *s, const char *fmt, ...) +{ + char buf[MAX_SCREEN_WIDTH]; + va_list ap; + + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + + put_status(s->qs->active_window, "!\007\006%s", buf); +} + +/* Display an error message in the status area. + `s` may be NULL in extreme circumstances + */ +void put_error(EditState *s, const char *fmt, ...) +{ + char buf[MAX_SCREEN_WIDTH]; + va_list ap; + + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + + put_status(s, "!\007\006%s", buf); +} + +/* Display a message in the status area. + `s` may be NULL in extreme circumstances + */ void put_status(EditState *s, const char *fmt, ...) { - /* XXX: s may be NULL! */ - QEmacsState *qs = s ? s->qe_state : &qe_state; char buf[MAX_SCREEN_WIDTH]; const char *p; va_list ap; @@ -6910,20 +6938,19 @@ void put_status(EditState *s, const char *fmt, ...) int diag = 0; int force = 0; int beep = 0; + int error = 0; va_start(ap, fmt); vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); - if (qs->active_window && (qs->active_window->flags & WF_MINIBUF)) { - /* display status messages in diag area if minibuffer is active */ - diag = 1; - } - for (p = buf;; p++) { if (*p == '\007') { beep = 1; } else + if (*p == '\006') { + error = 1; + } else if (*p == '|') { diag = 1; } else @@ -6937,11 +6964,17 @@ void put_status(EditState *s, const char *fmt, ...) } } - if (qs->screen->dpy.dpy_probe) { + if (s && s->qs->screen->dpy.dpy_probe) { + /* Display message on screen if initialized */ + QEmacsState *qs = s->qs; int width = qs->screen->width; int height = qs->status_height; int x = 0, y = qs->screen->height - height; + if (qs->active_window && (qs->active_window->flags & WF_MINIBUF)) { + /* display status messages in diag area if minibuffer is active */ + diag = 1; + } if (diag) { if (force || !strequal(p, qs->diag_shadow)) { /* right align display and overwrite last diag message */ @@ -6960,20 +6993,24 @@ void put_status(EditState *s, const char *fmt, ...) pstrcpy(qs->status_shadow, sizeof(qs->status_shadow), p); } } - } - if (!silent && qe_skip_spaces(&p)) - eb_format_message(qs, "*messages*", p); - if (beep) { - stop_macro(qs); - if (s) + if (!silent && qe_skip_spaces(&p)) { + if (error) + qe_format_message(qs, "*errors*", p); + qe_format_message(qs, "*messages*", p); + } + if (beep) { + qe_stop_macro(qs); dpy_sound_bell(s->screen); + } + } else { + if (qe_skip_spaces(&p)) + fprintf(stderr, "qe: %s\n", p); } } #if 0 -EditState *find_file_window(const char *filename) +EditState *qe_find_file_window(QEmacsState *qs, const char *filename) { - QEmacsState *qs = &qe_state; EditState *s; for (s = qs->first_window; s; s = s->next_window) { @@ -7037,7 +7074,7 @@ void switch_to_buffer(EditState *s, EditBuffer *b) memset(s, 0, SAVED_DATA_SIZE); mode = b->default_mode; /* default values */ - s->indent_width = s->qe_state->default_tab_width; + s->indent_width = s->qs->default_tab_width; s->default_style = QE_STYLE_DEFAULT; s->wrap = mode ? mode->default_wrap : WRAP_AUTO; } @@ -7074,7 +7111,7 @@ static int edit_detach_list(EditState **ep, EditState *s) { /* detach the window from the window tree. */ static void edit_detach(EditState *s) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; /* unlink the window from the frame */ edit_detach_list(&qs->first_window, s); @@ -7091,7 +7128,7 @@ static void edit_detach(EditState *s) /* move a window before another one */ static void edit_attach(EditState *s, EditState *e) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; EditState **ep; if (s != e) { @@ -7110,6 +7147,7 @@ static void edit_attach(EditState *s, EditState *e) } s->next_window = *ep; *ep = s; + // FIXME: This side effect should not be necessary if (qs->active_window == NULL) qs->active_window = s; } @@ -7118,7 +7156,7 @@ static void edit_attach(EditState *s, EditState *e) /* compute the client area from the window position */ void compute_client_area(EditState *s) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; int x1, y1, x2, y2; x1 = s->x1; @@ -7159,15 +7197,14 @@ void compute_client_area(EditState *s) EditState *edit_new(EditBuffer *b, int x1, int y1, int width, int height, int flags) { - /* b may be NULL ??? */ - QEmacsState *qs = &qe_state; + QEmacsState *qs = b->qs; EditState *s, *e; s = qe_mallocz(EditState); if (!s) return NULL; - s->qe_state = qs; + s->qs = qs; s->screen = qs->screen; s->x1 = x1; s->y1 = y1; @@ -7258,7 +7295,8 @@ void file_complete(CompleteState *cp, CompleteFunc enumerate) pstrcat(file, sizeof(file), "*"); if (cp->completion->flags & CF_RESOURCE) { - ffst = find_file_open(qe_state.res_path, file, FF_PATH | FF_NOXXDIR); + QEmacsState *qs = cp->s->qs; + ffst = find_file_open(qs->res_path, file, FF_PATH | FF_NOXXDIR); } else { int flags = FF_NOXXDIR; if (cp->completion->flags & CF_DIRNAME) @@ -7323,7 +7361,7 @@ static CompletionDef resource_completion = { #endif void buffer_complete(CompleteState *cp, CompleteFunc enumerate) { - QEmacsState *qs = cp->s->qe_state; + QEmacsState *qs = cp->s->qs; EditBuffer *b; for (b = qs->first_buffer; b != NULL; b = b->next) { @@ -7335,7 +7373,8 @@ void buffer_complete(CompleteState *cp, CompleteFunc enumerate) { static int buffer_print_entry(CompleteState *cp, EditState *s, const char *name) { EditBuffer *b = s->b; - EditBuffer *b1 = eb_find(name); + QEmacsState *qs = s->qs; + EditBuffer *b1 = qe_find_buffer_name(qs, name); int len; if (b1) { @@ -7388,9 +7427,8 @@ static int completion_sort_func(const void *p1, const void *p2) } /* register a new completion method */ -void qe_register_completion(CompletionDef *cp) +void qe_register_completion(QEmacsState *qs, CompletionDef *cp) { - QEmacsState *qs = &qe_state; CompletionDef **p; for (p = &qs->first_completion;; p = &(*p)->next) { @@ -7412,12 +7450,12 @@ void qe_register_completion(CompletionDef *cp) cp->sort_func = completion_sort_func; } -static CompletionDef *find_completion(const char *name) +static CompletionDef *qe_find_completion(QEmacsState *qs, const char *name) { CompletionDef *p; if (name[0] != '\0') { - for (p = qe_state.first_completion; p != NULL; p = p->next) { + for (p = qs->first_completion; p != NULL; p = p->next) { if (strequal(p->name, name)) return p; } @@ -7523,7 +7561,7 @@ static int match_strings(const char *s1, const char *s2, int len) { } void do_minibuffer_complete(EditState *s, int type, int key, int argval) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; int count, i, match_len, start, end; CompleteState cs; StringItem **outputs; @@ -7560,7 +7598,7 @@ void do_minibuffer_complete(EditState *s, int type, int key, int argval) { } /* check completion window */ - check_window(&mb->completion_popup_window); + qe_check_window(s->qs, &mb->completion_popup_window); if (mb->completion_popup_window && mb->completion_stage > 1) { /* toggle completion popup on TAB */ mb->completion_stage = 0; @@ -7633,8 +7671,10 @@ void do_minibuffer_complete(EditState *s, int type, int key, int argval) { if (!mb->completion_popup_window) { char buf[60]; - b = eb_new("*completion*", - BF_SYSTEM | BF_UTF8 | BF_TRANSIENT | BF_STYLE_COMP); + b = qe_new_buffer(qs, "*completion*", + BF_SYSTEM | BF_UTF8 | BF_TRANSIENT | BF_STYLE_COMP); + if (!b) + return; b->default_mode = &list_mode; w1 = qs->screen->width; h1 = qs->screen->height - qs->status_height; @@ -7700,14 +7740,14 @@ static void do_minibuffer_electric_key(EditState *s, int key, int argval) { /* space does completion only if a completion method is defined */ void do_minibuffer_complete_space(EditState *s, int key, int argval) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; MinibufState *mb = minibuffer_get_state(s, 0); if (!mb || !mb->completion || !mb->completion->enumerate || (mb->completion->flags & CF_SPACE_OK)) { do_char(s, key, argval); } else - if (check_window(&mb->completion_popup_window) + if (qe_check_window(s->qs, &mb->completion_popup_window) && qs->last_cmd_func == qs->this_cmd_func && mb->completion_count > 1) { /* page through the list */ @@ -7724,7 +7764,7 @@ static void do_minibuffer_char(EditState *s, int key, int argval) do_char(s, key, argval); // XXX: this should be triggered by any minibuffer modification - if (mb && check_window(&mb->completion_popup_window)) { + if (mb && qe_check_window(s->qs, &mb->completion_popup_window)) { /* automatic filtering of completion list */ // XXX: should prevent auto-completion do_minibuffer_complete(s, COMPLETION_OTHER, key, argval); @@ -7735,7 +7775,7 @@ static void do_minibuffer_char(EditState *s, int key, int argval) static void do_minibuffer_move_bof(EditState *s) { MinibufState *mb = minibuffer_get_state(s, 0); - if (mb && check_window(&mb->completion_popup_window)) { + if (mb && qe_check_window(s->qs, &mb->completion_popup_window)) { //mb->completion_popup_window->force_highlight = 1; do_bof(mb->completion_popup_window); return; @@ -7746,7 +7786,7 @@ static void do_minibuffer_move_bof(EditState *s) { static void do_minibuffer_move_eof(EditState *s) { MinibufState *mb = minibuffer_get_state(s, 0); - if (mb && check_window(&mb->completion_popup_window)) { + if (mb && qe_check_window(s->qs, &mb->completion_popup_window)) { //mb->completion_popup_window->force_highlight = 1; do_eof(mb->completion_popup_window); return; @@ -7758,7 +7798,7 @@ static void do_minibuffer_scroll_up_down(EditState *s, int dir) { MinibufState *mb = minibuffer_get_state(s, 0); - if (mb && check_window(&mb->completion_popup_window)) { + if (mb && qe_check_window(s->qs, &mb->completion_popup_window)) { //mb->completion_popup_window->force_highlight = 1; do_scroll_up_down(mb->completion_popup_window, dir); } @@ -7773,8 +7813,7 @@ static void minibuffer_set_str(EditState *s, int start, int end, const char *str } /* CG: should use buffer of responses */ -StringArray *qe_get_history(const char *name) { - QEmacsState *qs = &qe_state; +StringArray *qe_get_history(QEmacsState *qs, const char *name) { HistoryEntry *p; if (name[0] == '\0') @@ -7795,7 +7834,7 @@ StringArray *qe_get_history(const char *name) { void do_minibuffer_history(EditState *s, int n) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; MinibufState *mb; StringArray *hist; int index; @@ -7806,7 +7845,7 @@ void do_minibuffer_history(EditState *s, int n) return; /* if completion visible, move in it */ - if (check_window(&mb->completion_popup_window)) { + if (qe_check_window(s->qs, &mb->completion_popup_window)) { mb->completion_popup_window->force_highlight = 1; do_up_down(mb->completion_popup_window, n); return; @@ -7861,7 +7900,7 @@ void do_minibuffer_exit(EditState *s, int do_abort) if ((mb = minibuffer_get_state(s, 1)) == NULL) return; - cw = check_window(&mb->completion_popup_window); + cw = qe_check_window(s->qs, &mb->completion_popup_window); if (!do_abort) { /* if completion is activated, then select current file only if @@ -7936,7 +7975,7 @@ void minibuffer_edit(EditState *e, const char *input, const char *prompt, void (*cb)(void *opaque, char *buf, CompletionDef *completion), void *opaque) { - QEmacsState *qs = &qe_state; + QEmacsState *qs = e->qs; MinibufState *mb; EditState *s; EditBuffer *b; @@ -7944,12 +7983,14 @@ void minibuffer_edit(EditState *e, const char *input, const char *prompt, /* check if already in minibuffer editing */ if (e->flags & WF_MINIBUF) { - put_status(NULL, "|Already editing in minibuffer"); + put_status(e, "|Already editing in minibuffer"); cb(opaque, NULL, NULL); return; } - b = eb_new("*minibuf*", BF_SYSTEM | BF_SAVELOG | BF_UTF8); + b = qe_new_buffer(qs, "*minibuf*", BF_SYSTEM | BF_SAVELOG | BF_UTF8); + if (!b) + return; b->default_mode = &minibuffer_mode; s = edit_new(b, 0, qs->screen->height - qs->status_height, @@ -7970,7 +8011,7 @@ void minibuffer_edit(EditState *e, const char *input, const char *prompt, mb->completion_flags = 1; completion_name++; } - mb->completion = find_completion(completion_name); + mb->completion = qe_find_completion(qs, completion_name); } mb->history = hist; mb->history_saved_offset = 0; @@ -8004,7 +8045,7 @@ static void minibuffer_mode_free(EditBuffer *b, void *state) if (!mb) return; - if (check_window(&mb->completion_popup_window)) + if (qe_check_window(b->qs, &mb->completion_popup_window)) edit_close(&mb->completion_popup_window); cb = mb->cb; @@ -8013,7 +8054,7 @@ static void minibuffer_mode_free(EditBuffer *b, void *state) mb->opaque = NULL; if (cb) { - put_status(NULL, "!Abort."); + put_status(b->qs->active_window, "!Abort."); (*cb)(opaque, NULL, NULL); } } @@ -8068,7 +8109,7 @@ static const CmdDef minibuffer_commands[] = { isearch_toggle_word_match) }; -void minibuffer_init(QEmacsState *qs) +void qe_minibuffer_init(QEmacsState *qs) { /* populate and register minibuffer mode and commands */ // XXX: remove this mess: should just inherit with fallback @@ -8080,8 +8121,8 @@ void minibuffer_init(QEmacsState *qs) minibuffer_mode.move_bof = do_minibuffer_move_bof; minibuffer_mode.move_eof = do_minibuffer_move_eof; minibuffer_mode.scroll_up_down = do_minibuffer_scroll_up_down; - qe_register_mode(&minibuffer_mode, MODEF_NOCMD | MODEF_VIEW); - qe_register_commands(&minibuffer_mode, minibuffer_commands, countof(minibuffer_commands)); + qe_register_mode(qs, &minibuffer_mode, MODEF_NOCMD | MODEF_VIEW); + qe_register_commands(qs, &minibuffer_mode, minibuffer_commands, countof(minibuffer_commands)); } /* list paging mode */ @@ -8151,7 +8192,7 @@ static int list_init(QEmacsState *qs) list_mode.mode_probe = NULL; list_mode.mode_init = list_mode_init; list_mode.display_hook = list_display_hook; - qe_register_mode(&list_mode, MODEF_NOCMD | MODEF_VIEW); + qe_register_mode(qs, &list_mode, MODEF_NOCMD | MODEF_VIEW); return 0; } @@ -8162,13 +8203,16 @@ static ModeDef popup_mode; /* Verify that window still exists, return argument or NULL, * update handle if window is invalid. */ -EditState *check_window(EditState **sp) +EditState *qe_check_window(QEmacsState *qs, EditState **sp) { - QEmacsState *qs = &qe_state; + EditState *e0 = *sp; EditState *e; + if (e0 == NULL) + return NULL; + for (e = qs->first_window; e != NULL; e = e->next_window) { - if (e == *sp) + if (e == e0) return e; } return *sp = NULL; @@ -8176,7 +8220,7 @@ EditState *check_window(EditState **sp) void do_popup_exit(EditState *s) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; if (s->flags & WF_POPUP) { /* only do this for a popup? */ @@ -8191,7 +8235,7 @@ void do_popup_exit(EditState *s) /* show a popup on a readonly buffer */ EditState *show_popup(EditState *s, EditBuffer *b, const char *caption) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; EditState *e; int w, h, w1, h1; @@ -8208,13 +8252,15 @@ EditState *show_popup(EditState *s, EditBuffer *b, const char *caption) b->default_mode = &popup_mode; b->flags |= BF_READONLY; e = edit_new(b, (w1 - w) / 2, (h1 - h) / 2, w, h, WF_POPUP); - if (caption) - e->caption = qe_strdup(caption); - /* XXX: should come from mode.default_wrap */ - e->wrap = WRAP_TRUNCATE; - e->target_window = s; - qs->active_window = e; - do_refresh(e); + if (e != NULL) { + if (caption) + e->caption = qe_strdup(caption); + /* XXX: should come from mode.default_wrap */ + e->wrap = WRAP_TRUNCATE; + e->target_window = s; + qs->active_window = e; + do_refresh(e); + } return e; } @@ -8232,8 +8278,8 @@ static void popup_init(QEmacsState *qs) memcpy(&popup_mode, &text_mode, offsetof(ModeDef, first_key)); popup_mode.name = "popup"; popup_mode.mode_probe = NULL; - qe_register_mode(&popup_mode, MODEF_VIEW); - qe_register_commands(&popup_mode, popup_commands, countof(popup_commands)); + qe_register_mode(qs, &popup_mode, MODEF_VIEW); + qe_register_commands(qs, &popup_mode, popup_commands, countof(popup_commands)); } #ifndef CONFIG_TINY @@ -8241,7 +8287,7 @@ static void popup_init(QEmacsState *qs) under it (XXX: should try to move them first */ EditState *insert_window_left(EditBuffer *b, int width, int flags) { - QEmacsState *qs = &qe_state; + QEmacsState *qs = b->qs; EditState *e, *e_next, *e_new; for (e = qs->first_window; e != NULL; e = e_next) { @@ -8267,7 +8313,7 @@ EditState *insert_window_left(EditBuffer *b, int width, int flags) /* return a window on the side of window 's' */ EditState *find_window(EditState *s, int key, EditState *def) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; EditState *e; /* CG: Should compute cursor position to disambiguate @@ -8296,7 +8342,7 @@ EditState *find_window(EditState *s, int key, EditState *def) void do_find_window(EditState *s, int key) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; if (!qs->first_transient_key) { put_status(s, "window navigation, repeat with , , , "); @@ -8312,11 +8358,11 @@ void do_find_window(EditState *s, int key) /* Give a good guess to the user for the next buffer */ static EditBuffer *predict_switch_to_buffer(EditState *s) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; EditBuffer *b; /* try and switch to the last buffer attached to the window */ - b = check_buffer(&s->last_buffer); + b = qe_check_buffer(qs, &s->last_buffer); if (b) return b; @@ -8339,12 +8385,12 @@ void do_switch_to_buffer(EditState *s, const char *bufname) return; /* XXX: Default buffer charset should be selectable */ - b = eb_find_new(bufname, BF_SAVELOG | BF_UTF8); + b = qe_new_buffer(s->qs, bufname, BC_REUSE | BF_SAVELOG | BF_UTF8); if (b) switch_to_buffer(s, b); } -int eb_count_buffers(QEmacsState *qs, EditBuffer *b0, int *countp, int mask, int val) { +int qe_count_buffers(QEmacsState *qs, EditBuffer *b0, int *countp, int mask, int val) { EditBuffer *b; int index = 0, count = 0; for (b = qs->first_buffer; b; b = b->next) { @@ -8358,7 +8404,7 @@ int eb_count_buffers(QEmacsState *qs, EditBuffer *b0, int *countp, int mask, int return index; } -EditBuffer *eb_get_buffer_from_index(QEmacsState *qs, int index, int mask, int val) { +EditBuffer *qe_get_buffer_from_index(QEmacsState *qs, int index, int mask, int val) { EditBuffer *b; for (b = qs->first_buffer; b; b = b->next) { if ((b->flags & mask) == val) { @@ -8374,7 +8420,7 @@ EditBuffer *eb_get_buffer_from_index(QEmacsState *qs, int index, int mask, int v direction. Set up repeat map */ void do_buffer_navigation(EditState *s, int argval, int dir) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; int buffer_index, buffer_count; EditBuffer *b; @@ -8382,7 +8428,7 @@ void do_buffer_navigation(EditState *s, int argval, int dir) if (s->flags & (WF_POPUP | WF_MINIBUF)) return; - buffer_index = eb_count_buffers(qs, s->b, &buffer_count, BF_SYSTEM, 0); + buffer_index = qe_count_buffers(qs, s->b, &buffer_count, BF_SYSTEM, 0); /* no action if single non system buffer */ if (buffer_count <= 1) return; @@ -8392,7 +8438,7 @@ void do_buffer_navigation(EditState *s, int argval, int dir) qe_register_transient_binding(qs, "previous-buffer", "left, C-left"); } buffer_index = (buffer_index + argval * dir) % buffer_count; - b = eb_get_buffer_from_index(qs, buffer_index, BF_SYSTEM, 0); + b = qe_get_buffer_from_index(qs, buffer_index, BF_SYSTEM, 0); if (b) switch_to_buffer(s, b); } @@ -8409,6 +8455,7 @@ void do_not_modified(EditState *s, int argval) static void kill_buffer_confirm_cb(void *opaque, char *reply, CompletionDef *completion) { + EditBuffer *b = opaque; int yes_replied; if (!reply) @@ -8417,35 +8464,34 @@ static void kill_buffer_confirm_cb(void *opaque, char *reply, CompletionDef *com qe_free(&reply); if (!yes_replied) return; - qe_kill_buffer(opaque); + qe_kill_buffer(b->qs, b); } void do_kill_buffer(EditState *s, const char *bufname, int force) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; char buf[1024]; EditBuffer *b; - b = eb_find(bufname); + b = qe_find_buffer_name(qs, bufname); if (!b) { put_status(s, "No buffer %s", bufname); } else { /* if modified and associated to a filename, then ask */ if (!force && b->modified && b->filename[0] != '\0') { - stop_macro(qs); + qe_stop_macro(qs); snprintf(buf, sizeof(buf), "Buffer %s modified; kill anyway? (yes or no) ", bufname); minibuffer_edit(s, NULL, buf, NULL, NULL, kill_buffer_confirm_cb, b); } else { - qe_kill_buffer(b); + qe_kill_buffer(qs, b); } } } -void qe_kill_buffer(EditBuffer *b) +void qe_kill_buffer(QEmacsState *qs, EditBuffer *b) { - QEmacsState *qs = &qe_state; EditState *e; EditBuffer *b1 = NULL; @@ -8470,7 +8516,11 @@ void qe_kill_buffer(EditBuffer *b) break; } if (!b1) { - b1 = eb_new("*scratch*", BF_SAVELOG | BF_UTF8); + /* XXX: no regular buffer to show: we are killing the last + * regular buffer... Try and allocate a scratch buffer, + * but if this fails, all odds are off. + */ + b1 = qe_new_buffer(qs, "*scratch*", BF_SAVELOG | BF_UTF8); } } switch_to_buffer(e, b1); @@ -8488,6 +8538,7 @@ void qe_kill_buffer(EditBuffer *b) /* now we can safely delete buffer */ eb_free(&b); + // XXX: should just return an update flag? do_refresh(qs->first_window); } @@ -8605,7 +8656,7 @@ static int probe_mode(EditState *s, EditBuffer *b, QECharset *charset, EOLType eol_type) { u8 buf[4097]; - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; char fname[MAX_FILENAME_SIZE]; ModeDef *m; ModeProbeData probe_data; @@ -8705,12 +8756,12 @@ static int probe_mode(EditState *s, EditBuffer *b, } EditState *qe_find_target_window(EditState *s, int activate) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; EditState *e; /* Find the target window for some commands run from the dired window */ if (s->flags & WF_POPUP) { - e = check_window(&s->target_window); + e = qe_check_window(s->qs, &s->target_window); if (e) { if (activate && qs->active_window == s) qs->active_window = e; @@ -8804,7 +8855,7 @@ void qe_set_next_mode(EditState *s, int n, int status) */ int qe_load_file(EditState *s, const char *filename1, int lflags, int bflags) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; u8 buf[4097]; char filename[MAX_FILENAME_SIZE]; int st_mode, buf_size, mode_score; @@ -8817,7 +8868,7 @@ int qe_load_file(EditState *s, const char *filename1, int lflags, int bflags) QECharset *charset = &charset_utf8; if ((lflags & LF_LOAD_RESOURCE) && !strchr(filename1, '/')) { - if (find_resource_file(filename, sizeof(filename), filename1)) { + if (qe_find_resource_file(qs, filename, sizeof(filename), filename1)) { put_status(s, "Cannot find resource file '%s'", filename1); return -1; } @@ -8841,7 +8892,7 @@ int qe_load_file(EditState *s, const char *filename1, int lflags, int bflags) #endif if (s->flags & (WF_POPUP | WF_MINIBUF)) - return - 1; + return -1; if (lflags & LF_SPLIT_WINDOW) { /* Split window if window large enough and not empty */ @@ -8861,7 +8912,7 @@ int qe_load_file(EditState *s, const char *filename1, int lflags, int bflags) } #endif /* If file already loaded in existing buffer, switch to that */ - b = eb_find_file(filename); + b = qe_find_buffer_file(qs, filename); if (b != NULL) { switch_to_buffer(s, b); return 0; @@ -8875,7 +8926,10 @@ int qe_load_file(EditState *s, const char *filename1, int lflags, int bflags) } /* Create new buffer with unique name from filename */ - b = eb_new(get_basename(filename), BF_SAVELOG | bflags); + b = qe_new_buffer(qs, get_basename(filename), BF_SAVELOG | bflags); + if (!b) { + return -1; + } eb_set_filename(b, filename); /* XXX: should actually initialize SAVED_DATA area in new buffer */ @@ -8981,7 +9035,7 @@ int qe_load_file(EditState *s, const char *filename1, int lflags, int bflags) #ifndef CONFIG_TINY void qe_save_open_files(EditState *s, EditBuffer *b) { - QEmacsState *qs = &qe_state; + QEmacsState *qs = s->qs; EditBuffer *b1; eb_puts(b, "// open files:\n"); @@ -9021,7 +9075,7 @@ static void load_completion_cb(void *opaque, int err) if (!s->b->probed) { qe_set_next_mode(s, 0, 0); } - edit_display(s->qe_state); + qe_display(s->qs); dpy_flush(&global_screen); } #endif @@ -9157,6 +9211,7 @@ typedef struct QuitState { enum QSState state; int modified; EditBuffer *b; + QEmacsState *qs; } QuitState; static void quit_examine_buffers(QuitState *is); @@ -9172,7 +9227,7 @@ static void do_suspend_qemacs(EditState *s, int argval) void do_exit_qemacs(EditState *s, int argval) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; QuitState *is; if (argval != NO_ARG) { @@ -9188,16 +9243,17 @@ void do_exit_qemacs(EditState *s, int argval) is->modified = 0; is->state = QS_ASK; is->b = qs->first_buffer; + is->qs = qs; - stop_macro(qs); - qe_grab_keys(quit_key, is); + qe_stop_macro(qs); + qe_grab_keys(qs, quit_key, is); quit_examine_buffers(is); } /* analyse next buffer and ask question if needed */ static void quit_examine_buffers(QuitState *is) { - QEmacsState *qs = &qe_state; + QEmacsState *qs = is->qs; EditBuffer *b; while (is->b != NULL) { @@ -9221,15 +9277,15 @@ static void quit_examine_buffers(QuitState *is) } is->b = is->b->next; } - qe_ungrab_keys(); + qe_ungrab_keys(qs); /* now asks for confirmation or exit directly */ if (is->modified) { - stop_macro(qs); + qe_stop_macro(qs); minibuffer_edit(qs->active_window, NULL, "Modified buffers exist; exit anyway? (yes or no) ", NULL, NULL, quit_confirm_cb, NULL); - edit_display(&qe_state); + qe_display(qs); dpy_flush(&global_screen); } else { #ifdef CONFIG_SESSION @@ -9274,8 +9330,8 @@ static void quit_key(void *opaque, int ch) break; case KEY_CTRL('g'): /* abort */ - qe_ungrab_keys(); - put_status(NULL, "\007Quit"); + qe_ungrab_keys(is->qs); + put_status(is->qs->active_window, "\007Quit"); dpy_flush(&global_screen); return; default: @@ -9336,7 +9392,7 @@ void edit_invalidate(EditState *s, int all) s->display_invalid = 1; if (all) { EditState *e; - for (e = s->qe_state->first_window; e != NULL; e = e->next_window) { + for (e = s->qs->first_window; e != NULL; e = e->next_window) { if (e->b == s->b) { s->modeline_shadow[0] = '\0'; s->display_invalid = 1; @@ -9348,8 +9404,7 @@ void edit_invalidate(EditState *s, int all) /* refresh the screen, s1 can be any edit window */ void do_refresh(EditState *s1) { - /* CG: s1 may be NULL */ - QEmacsState *qs = s1 ? s1->qe_state : &qe_state; + QEmacsState *qs = s1->qs; EditState *e; int new_status_height, new_mode_line_height, content_height; int width, height, resized; @@ -9436,14 +9491,14 @@ void do_refresh(EditState *s1) if (resized) { /* CG: should compute column count w/ default count */ - put_status(NULL, "Screen is now %d by %d (%d rows)", + put_status(s1, "Screen is now %d by %d (%d rows)", width, height, height / new_status_height); } } void do_repeat(EditState *s, int argval) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; int active = (s == qs->active_window); if (!qs->first_transient_key) @@ -9458,11 +9513,11 @@ void do_repeat(EditState *s, int argval) void do_refresh_complete(EditState *s) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; qs->complete_refresh = 1; - if (s->qe_state->last_cmd_func == (CmdFunc)do_refresh_complete) { + if (s->qs->last_cmd_func == (CmdFunc)do_refresh_complete) { do_center_cursor(s, 1); } else { do_refresh(s); @@ -9471,7 +9526,7 @@ void do_refresh_complete(EditState *s) EditState *get_next_window(EditState *s, int mask, int val) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; EditState *e, *s0 = s; for (;;) { @@ -9489,7 +9544,7 @@ EditState *get_next_window(EditState *s, int mask, int val) EditState *get_previous_window(EditState *s, int mask, int val) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; EditState *e, *s0 = s; for (;;) { @@ -9507,7 +9562,7 @@ EditState *get_previous_window(EditState *s, int mask, int val) static EditState **get_window_link(EditState *s) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; EditState **ep = &qs->first_window; for (;;) { if (*ep == s) @@ -9521,14 +9576,16 @@ static EditState **get_window_link(EditState *s) void do_other_window(EditState *s) { - QEmacsState *qs = s->qe_state; - qs->active_window = get_next_window(s, 0, 0); + EditState *e = get_next_window(s, 0, 0); + if (e) + s->qs->active_window = e; } void do_previous_window(EditState *s) { - QEmacsState *qs = s->qe_state; - qs->active_window = get_previous_window(s, 0, 0); + EditState *e = get_previous_window(s, 0, 0); + if (e) + s->qs->active_window = e; } /* Delete a window and try to resize other windows so that it gets @@ -9536,7 +9593,7 @@ void do_previous_window(EditState *s) is the only window or if it is the minibuffer window. */ void do_delete_window(EditState *s, int force) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; EditState *e, *e1 = NULL; int count, pass, x1, y1, x2, y2; @@ -9551,7 +9608,7 @@ void do_delete_window(EditState *s, int force) if (s->flags & WF_POPUP) { // XXX: this causes a crash on C-g from bufed - //e1 = check_window(&s->target_window); + //e1 = qe_check_window(s->qs, &s->target_window); } else { /* Try to merge the window with adjacent windows. * If this cannot be done, just leave a hole and force full @@ -9609,7 +9666,7 @@ void do_delete_window(EditState *s, int force) void do_delete_other_windows(EditState *s, int all) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; EditState *e; if (s->flags & (WF_POPUP | WF_MINIBUF)) @@ -9653,7 +9710,7 @@ void do_hide_window(EditState *s, int set) void do_delete_hidden_windows(EditState *s) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; EditState *e, *e1; for (e = qs->first_window; e != NULL; e = e1) { @@ -9707,7 +9764,7 @@ EditState *qe_split_window(EditState *s, int side_by_side, int prop) void do_split_window(EditState *s, int prop, int side_by_side) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; EditState *e = qe_split_window(s, side_by_side, prop == NO_ARG ? 50 : prop); if (e && qs->flag_split_window_change_focus) @@ -9716,7 +9773,7 @@ void do_split_window(EditState *s, int prop, int side_by_side) void do_window_swap_states(EditState *s) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; uint8_t buffer[offsetof(EditState, flags) - offsetof(EditState, xleft)]; int mask = WF_POPUP | WF_MINIBUF | WF_HIDDEN | WF_POPLEFT | WF_FILELIST; int flags; @@ -9752,7 +9809,7 @@ void do_window_swap_states(EditState *s) #ifndef CONFIG_TINY void do_create_window(EditState *s, const char *filename, const char *layout) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; static const char * const names[] = { "x1:", "y1:", "x2:", "y2:", "flags:", "wrap:", "offset:", "offset.col:", "mark:", "mark.col:", "top:", "top.col:", @@ -9765,7 +9822,7 @@ void do_create_window(EditState *s, const char *filename, const char *layout) const char *p = layout; EditBuffer *b1; - b1 = eb_find_file(filename); + b1 = qe_find_buffer_file(qs, filename); if (!b1) { put_status(s, "create_window: no such file loaded: %s", filename); return; @@ -9781,7 +9838,7 @@ void do_create_window(EditState *s, const char *filename, const char *layout) } } if (strstart(p, "mode:", &p)) { - m = qe_find_mode(p, 0); + m = qe_find_mode(qs, p, 0); break; } if (n >= countof(args)) @@ -9801,6 +9858,8 @@ void do_create_window(EditState *s, const char *filename, const char *layout) wrap = (enum WrapType)args[5]; s = edit_new(b1, x1, y1, x2 - x1, y2 - y1, flags); + if (s == NULL) + return; if (m) edit_set_mode(s, m); s->wrap = wrap; @@ -9815,7 +9874,7 @@ void do_create_window(EditState *s, const char *filename, const char *layout) void qe_save_window_layout(EditState *s, EditBuffer *b) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; const EditState *e; int offset_row, offset_col; int mark_row, mark_col; @@ -9864,9 +9923,13 @@ int qe_load_session(EditState *s) void do_save_session(EditState *s, int popup) { - EditBuffer *b = eb_scratch("*session*", BF_UTF8); + EditBuffer *b; time_t now; + b = qe_new_buffer(s->qs, "*session*", BC_REUSE | BC_CLEAR | BF_UTF8); + if (!b) + return; + eb_printf(b, "// qemacs version: %s\n", QE_VERSION); now = time(NULL); eb_printf(b, "// session saved: %s\n", ctime(&now)); @@ -9899,15 +9962,16 @@ void do_describe_key_briefly(EditState *s, const char *keystr, int argval) { int nb_keys, len; const char *p = keystr; KeyDef *kd; + QEmacsState *qs = s->qs; nb_keys = strtokeys(p, keys, MAX_KEYS, &p); if (!nb_keys || *p) { put_status(s, "%s is not a valid key sequence", keystr); return; } - kd = qe_find_current_binding(keys, nb_keys, s->mode, 0); + kd = qe_find_current_binding(qs, keys, nb_keys, s->mode, 0); if (!kd && nb_keys == 1 && !KEY_IS_SPECIAL(keys[0]) && !KEY_IS_CONTROL(keys[0])) { - kd = qe_find_current_binding(&key_default, 1, s->mode, 1); + kd = qe_find_current_binding(qs, &key_default, 1, s->mode, 1); } if (kd) { if (kd->nb_keys == nb_keys) { @@ -9927,24 +9991,16 @@ void do_describe_key_briefly(EditState *s, const char *keystr, int argval) { #endif } -EditBuffer *new_help_buffer(void) +EditBuffer *new_help_buffer(EditState *s) { - EditBuffer *b; - - b = eb_find("*Help*"); - if (b) { - eb_clear(b); - } else { - b = eb_new("*Help*", BF_SYSTEM | BF_UTF8 | BF_STYLE1); - } - return b; + return qe_new_buffer(s->qs, "*Help*", BC_REUSE | BC_CLEAR | BF_SYSTEM | BF_UTF8 | BF_STYLE1); } void do_help_for_help(EditState *s) { EditBuffer *b; - b = new_help_buffer(); + b = new_help_buffer(s); if (!b) return; @@ -10011,7 +10067,7 @@ int qe__is_user_input_pending(void) void window_get_min_size(EditState *s, int *w_ptr, int *h_ptr) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; int w, h; /* XXX: currently, a small square */ @@ -10026,7 +10082,7 @@ void window_get_min_size(EditState *s, int *w_ptr, int *h_ptr) /* resize a window on bottom right edge */ int window_resize(EditState *s, int target_w, int target_h) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; EditState *e; int delta_y, delta_x, min_w, min_h; @@ -10107,7 +10163,7 @@ enum { /* remove temporary selection colorization and selection area */ // TODO: clean this mess -static void save_selection(QEmacsState *qs, int copy) +static void qe_save_selection(QEmacsState *qs, int copy) { EditState *e; int selection_showed; @@ -10119,9 +10175,9 @@ static void save_selection(QEmacsState *qs, int copy) } if (selection_showed && qs->motion_type == MOTION_TEXT) { qs->motion_type = MOTION_NONE; - e = check_window(&qs->motion_target); + e = qe_check_window(qs, &qs->motion_target); if (e != NULL && copy) { - eb_trace_bytes("copy-region", -1, EB_TRACE_COMMAND); + qe_trace_bytes(qs, "copy-region", -1, EB_TRACE_COMMAND); do_copy_region(e); /* activate region hilite */ if (qs->hilite_region) @@ -10133,11 +10189,11 @@ static void save_selection(QEmacsState *qs, int copy) /* XXX: need a more general scheme for other modes such as HTML/image */ void wheel_scroll_up_down(EditState *s, int dir) { - QEmacsState *qs = &qe_state; + QEmacsState *qs = s->qs; int line_height; if (qs->trace_buffer && s->b != qs->trace_buffer) { - eb_trace_bytes(dir < 0 ? "wheel-scroll-up" : "wheel-scroll-down", + qe_trace_bytes(qs, dir < 0 ? "wheel-scroll-up" : "wheel-scroll-down", -1, EB_TRACE_COMMAND); } @@ -10150,12 +10206,12 @@ void wheel_scroll_up_down(EditState *s, int dir) } static void call_mouse_goto(EditState *e, int x, int y, QEEvent *ev) { - eb_trace_bytes("mouse-goto", -1, EB_TRACE_COMMAND); + qe_trace_bytes(e->qs, "mouse-goto", -1, EB_TRACE_COMMAND); if (e->mode->mouse_goto) e->mode->mouse_goto(e, x, y, ev); } -static void reverse_window_list(QEmacsState *qs) { +static void qe_reverse_window_list(QEmacsState *qs) { EditState *e = qs->first_window; EditState *last = NULL; while (e != NULL) { @@ -10168,7 +10224,7 @@ static void reverse_window_list(QEmacsState *qs) { } static int check_mouse_event(EditState *e, QEEvent *ev) { - QEmacsState *qs = e->qe_state; + QEmacsState *qs = e->qs; EditState *curw = qs->active_window; int mouse_x = ev->button_event.x; int mouse_y = ev->button_event.y; @@ -10184,6 +10240,15 @@ static int check_mouse_event(EditState *e, QEEvent *ev) { switch (ev->button_event.button) { case QE_BUTTON_LEFT: // TODO: should cancel popup, minibuf? + if (e->interactive) { + /* TODO: should re-enable interactive shell behavior + * if mouse_goto sets the point to the end of buffer + */ + if (!qs->key_ctx.grab_key_cb) { + /* TODO: virtualize mouse events to shell process */ + e->interactive = 0; + } + } if (curw && curw->isearch_state) { /* Cancel pending search */ QEEvent ev1, *evp = qe_event_clear(&ev1); @@ -10196,7 +10261,7 @@ static int check_mouse_event(EditState *e, QEEvent *ev) { return 0; if (!e->mode->mouse_goto) goto no_handler; - save_selection(qs, FALSE); + qe_save_selection(qs, FALSE); e->show_selection = 0; e->region_style = 0; call_mouse_goto(e, mouse_x - e->xleft, mouse_y - e->ytop, ev); @@ -10213,7 +10278,7 @@ static int check_mouse_event(EditState *e, QEEvent *ev) { put_status(e, "no mouse handler for mode %s", e->mode->name); return 0; } - save_selection(qs, FALSE); + qe_save_selection(qs, FALSE); call_mouse_goto(e, mouse_x - e->xleft, mouse_y - e->ytop, ev); do_yank(e); break; @@ -10226,7 +10291,7 @@ static int check_mouse_event(EditState *e, QEEvent *ev) { default: return 0; } - edit_display(qs); + qe_display(qs); dpy_flush(qs->screen); return 1; } @@ -10295,7 +10360,7 @@ static int check_mouse_event(EditState *e, QEEvent *ev) { } static void handle_mouse_motion(EditState *e, QEEvent *ev) { - QEmacsState *qs = &qe_state; + QEmacsState *qs = e->qs; int mouse_x = ev->button_event.x; int mouse_y = ev->button_event.y; int scale = (qs->screen->media & CSS_MEDIA_TTY) ? 1 : 8; @@ -10333,7 +10398,7 @@ static void handle_mouse_motion(EditState *e, QEEvent *ev) { if (mouse_x >= e->xleft && mouse_x < e->xleft + e->width) { /* if inside the buffer, then update cursor position */ call_mouse_goto(e, mouse_x - e->xleft, mouse_y - e->ytop, ev); - edit_display(qs); + qe_display(qs); dpy_flush(qs->screen); } break; @@ -10376,7 +10441,7 @@ static void handle_mouse_motion(EditState *e, QEEvent *ev) { compute_client_area(e); //do_refresh(qs->first_window); qs->complete_refresh = 1; - edit_display(qs); + qe_display(qs); dpy_flush(qs->screen); } } @@ -10387,7 +10452,7 @@ static void handle_mouse_motion(EditState *e, QEEvent *ev) { qs->motion_y = mouse_y; window_resize(e, e->x2 - e->x1, qs->motion_y - e->y1); do_refresh(qs->first_window); - edit_display(qs); + qe_display(qs); dpy_flush(qs->screen); } break; @@ -10397,7 +10462,7 @@ static void handle_mouse_motion(EditState *e, QEEvent *ev) { qs->motion_x = mouse_x; window_resize(e, qs->motion_x - e->x1, e->y2 - e->y1); do_refresh(qs->first_window); - edit_display(qs); + qe_display(qs); dpy_flush(qs->screen); } break; @@ -10412,23 +10477,23 @@ void qe_mouse_event(QEmacsState *qs, QEEvent *ev) case QE_BUTTON_RELEASE_EVENT: // TODO: should handle frame and buffer buttons // TODO: should handle double/triple click - save_selection(qs, TRUE); + qe_save_selection(qs, TRUE); qs->motion_type = MOTION_NONE; qs->motion_target = NULL; break; case QE_BUTTON_PRESS_EVENT: // TODO: should use doubly linked list - reverse_window_list(qs); + qe_reverse_window_list(qs); for (e = qs->first_window; e != NULL; e = e->next_window) { if (check_mouse_event(e, ev)) break; } - reverse_window_list(qs); + qe_reverse_window_list(qs); break; case QE_MOTION_EVENT: - //eb_trace_bytes("mouse-move", -1, EB_TRACE_COMMAND); - e = check_window(&qs->motion_target); + //qe_trace_bytes(qs, "mouse-move", -1, EB_TRACE_COMMAND); + e = qe_check_window(qs, &qs->motion_target); if (e != NULL) { /* dispatch move drag event if mouse was captured */ handle_mouse_motion(e, ev); @@ -10444,9 +10509,8 @@ void qe_mouse_event(QEmacsState *qs, QEEvent *ev) #endif /* put key in the unget buffer so that get_key() will return it */ -void unget_key(int key) +void qe_unget_key(QEmacsState *qs, int key) { - QEmacsState *qs = &qe_state; qs->ungot_key = key; } @@ -10462,16 +10526,16 @@ void qe_handle_event(QEmacsState *qs, QEEvent *ev) buf_printf(out, "0x%04X ", ev->key_event.key); buf_put_key(out, ev->key_event.key); buf_put_byte(out, ' '); - eb_trace_bytes(buf, out->len, EB_TRACE_KEY); + qe_trace_bytes(qs, buf, out->len, EB_TRACE_KEY); } - qe_key_process(ev->key_event.key); + qe_key_process(qs, ev->key_event.key); break; case QE_EXPOSE_EVENT: do_refresh(qs->first_window); goto redraw; case QE_UPDATE_EVENT: redraw: - edit_display(qs); + qe_display(qs); dpy_flush(qs->screen); break; #ifndef CONFIG_TINY @@ -10492,12 +10556,12 @@ void qe_handle_event(QEmacsState *qs, QEEvent *ev) buf_printf(out, "%d %d %d %d %d ", ev->button_event.type, ev->button_event.shift, ev->button_event.button, ev->button_event.x, ev->button_event.y); - eb_trace_bytes(buf, out->len, EB_TRACE_MOUSE); + qe_trace_bytes(qs, buf, out->len, EB_TRACE_MOUSE); } qe_mouse_event(qs, ev); break; case QE_SELECTION_CLEAR_EVENT: - save_selection(qs, FALSE); + qe_save_selection(qs, FALSE); goto redraw; #endif default: @@ -10608,9 +10672,8 @@ ModeDef text_mode = { }; /* find a resource file */ -int find_resource_file(char *path, int path_size, const char *pattern) +int qe_find_resource_file(QEmacsState *qs, char *path, int path_size, const char *pattern) { - QEmacsState *qs = &qe_state; FindFileState *ffst; int ret; @@ -10624,9 +10687,9 @@ int find_resource_file(char *path, int path_size, const char *pattern) return ret; } -FILE *open_resource_file(const char *name) { +FILE *qe_open_resource_file(QEmacsState *qs, const char *name) { char filename[MAX_FILENAME_SIZE]; - if (find_resource_file(filename, sizeof(filename), name) >= 0) + if (qe_find_resource_file(qs, filename, sizeof(filename), name) >= 0) return fopen(filename, "r"); else return NULL; @@ -10636,7 +10699,7 @@ FILE *open_resource_file(const char *name) { void do_load_config_file(EditState *e, const char *file) { - QEmacsState *qs = e->qe_state; + QEmacsState *qs = e->qs; FindFileState *ffst; char filename[MAX_FILENAME_SIZE]; @@ -10661,7 +10724,13 @@ void do_load_qerc(EditState *e, const char *filename) { char buf[MAX_FILENAME_SIZE]; char *p = buf; - QEmacsState *qs = e->qe_state; + QEmacsState *qs = e->qs; + /* FIXME: should run script in restricted mode: + - protect against window and buffer deletion + - prevent buffer changes? + - prevent window changes? + - only allow customisation variable updates? + */ EditState *saved = qs->active_window; for (;;) { @@ -10674,7 +10743,7 @@ void do_load_qerc(EditState *e, const char *filename) qs->active_window = e; parse_config_file(e, buf); } - if (check_window(&saved)) + if (qe_check_window(qs, &saved)) qs->active_window = saved; } @@ -10682,7 +10751,7 @@ void do_load_qerc(EditState *e, const char *filename) /* command line option handling */ static CmdLineOptionDef *first_cmd_options; -void qe_register_cmd_line_options(CmdLineOptionDef *table) +void qe_register_cmd_line_options(QEmacsState *qs, CmdLineOptionDef *table) { CmdLineOptionDef **pp, *p; @@ -10750,7 +10819,7 @@ static void show_usage(void) exit(1); } -static int parse_command_line(int argc, char **argv) +static int qe_parse_command_line(QEmacsState *qs, int argc, char **argv) { int optind_; @@ -10794,9 +10863,8 @@ static int parse_command_line(int argc, char **argv) if (bstr_equal(opt1, shortname) || bstr_equal(opt2, name)) { if (p->need_arg && optarg_ == NULL) { if (optind_ >= argc) { - put_error(NULL, - "cmdline argument %.*s expected for --%.*s", - argname.len, argname.s, name.len, name.s); + qe_put_error(qs, "cmdline argument %.*s expected for --%.*s", + argname.len, argname.s, name.len, name.s); goto next_cmd; } optarg_ = argv[optind_++]; @@ -10815,7 +10883,7 @@ static int parse_command_line(int argc, char **argv) p->u.func_noarg(); break; case CMD_LINE_TYPE_FARG: - p->u.func_arg(optarg_); + p->u.func_arg(qs, optarg_); break; case CMD_LINE_TYPE_NONE: case CMD_LINE_TYPE_NEXT: @@ -10826,7 +10894,7 @@ static int parse_command_line(int argc, char **argv) p++; } } - put_error(NULL, "unknown cmdline option '%s'", arg); + qe_put_error(qs, "unknown cmdline option '%s'", arg); next_cmd: ; } @@ -10835,14 +10903,13 @@ static int parse_command_line(int argc, char **argv) void do_add_resource_path(EditState *s, const char *path) { - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; pstrcat(qs->res_path, sizeof(qs->res_path), ":"); pstrcat(qs->res_path, sizeof(qs->res_path), path); } -void set_user_option(const char *user) +static void qe_set_user_option(QEmacsState *qs, const char *user) { - QEmacsState *qs = &qe_state; char path[MAX_FILENAME_SIZE]; const char *home_path; @@ -10887,10 +10954,10 @@ void set_user_option(const char *user) "/usr/lib/qe"); } -void set_tty_charset(const char *name) +static void qe_set_tty_charset(QEmacsState *qs, const char *name) { - qe_free(&qe_state.tty_charset); - qe_state.tty_charset = qe_strdup(name); + qe_free(&qs->tty_charset); + qs->tty_charset = qe_strdup(name); } static CmdLineOptionDef cmd_options[] = { @@ -10905,13 +10972,13 @@ static CmdLineOptionDef cmd_options[] = { "keep a single window when loading multiple files"), CMD_LINE_BOOL("nw", "no-windows", &force_tty, "force tty terminal usage"), - CMD_LINE_FARG("c", "charset", "CHARSET", set_tty_charset, + CMD_LINE_FARG("c", "charset", "CHARSET", qe_set_tty_charset, "specify tty charset"), #ifdef CONFIG_SESSION CMD_LINE_BOOL("s", "use-session", &use_session_file, "load and save session files"), #endif - CMD_LINE_FARG("u", "user", "USER", set_user_option, + CMD_LINE_FARG("u", "user", "USER", qe_set_user_option, "load ~USER/.qe/config instead of your own"), CMD_LINE_FVOID("V", "version", show_version, "display version information and exit"), @@ -11562,7 +11629,7 @@ QEStyleDef qe_styles[QE_STYLE_NB] = { #ifdef CONFIG_DLL -static void load_all_modules(QEmacsState *qs) +static void qe_load_all_modules(QEmacsState *qs) { QErrorContext ec; FindFileState *ffst; @@ -11582,8 +11649,7 @@ static void load_all_modules(QEmacsState *qs) h = dlopen(filename, RTLD_LAZY); if (!h) { char *error = dlerror(); - put_status(NULL, "Could not open module '%s': %s", - filename, error); + qe_put_error(qs, "Could not open module '%s': %s", filename, error); continue; } #if 0 @@ -11609,9 +11675,7 @@ static void load_all_modules(QEmacsState *qs) #endif if (!init_func) { dlclose(h); - put_status(NULL, - "Could not find qemacs initializer in module '%s'", - filename); + qe_put_error(qs, "Could not find qemacs initializer in module '%s'", filename); continue; } @@ -11626,12 +11690,6 @@ static void load_all_modules(QEmacsState *qs) #endif -typedef struct QEArgs { - QEmacsState *qs; - int argc; - char **argv; -} QEArgs; - static CompletionDef charset_completion = { .name = "charset", .enumerate = charset_complete, @@ -11674,58 +11732,65 @@ static void qe_init(void *opaque) qs->input_size = countof(qs->input_buf_def); qs->double_click_threshold = DEFAULT_DOUBLE_CLICK_THRESHOLD; - /* setup resource path */ - set_user_option(NULL); + // FIXME: Achtung Minen! qs->active_window is NULL until + // the first window is created for the "*scratch*" buffer - eb_init(qs); + /* setup resource path */ + qe_set_user_option(qs, NULL); + + qe_data_init(qs); charset_init(qs); - input_methods_init(qs); + qe_input_methods_init(qs); colors_init(); #ifdef CONFIG_ALL_KMAPS - if (find_resource_file(filename, sizeof(filename), "kmaps") >= 0) - load_input_methods(filename); + if (qe_find_resource_file(qs, filename, sizeof(filename), "kmaps") >= 0) + qe_load_input_methods(qs, filename); #endif #ifdef CONFIG_UNICODE_JOIN - if (find_resource_file(filename, sizeof(filename), "ligatures") >= 0) + if (qe_find_resource_file(qs, filename, sizeof(filename), "ligatures") >= 0) load_ligatures(filename); #endif /* init basic modules */ - qe_register_mode(&text_mode, MODEF_VIEW); - qe_register_commands(NULL, basic_commands, countof(basic_commands)); - qe_register_cmd_line_options(cmd_options); + qe_register_mode(qs, &text_mode, MODEF_VIEW); + qe_register_commands(qs, NULL, basic_commands, countof(basic_commands)); + qe_register_cmd_line_options(qs, cmd_options); - qe_register_completion(&buffer_completion); - qe_register_completion(&charset_completion); - qe_register_completion(&color_completion); - qe_register_completion(&command_completion); - qe_register_completion(&file_completion); - qe_register_completion(&mode_completion); - qe_register_completion(&style_completion); - qe_register_completion(&style_property_completion); + qe_register_completion(qs, &buffer_completion); + qe_register_completion(qs, &charset_completion); + qe_register_completion(qs, &color_completion); + qe_register_completion(qs, &command_completion); + qe_register_completion(qs, &file_completion); + qe_register_completion(qs, &mode_completion); + qe_register_completion(qs, &style_completion); + qe_register_completion(qs, &style_property_completion); #ifndef CONFIG_TINY - qe_register_completion(&dir_completion); - qe_register_completion(&resource_completion); + qe_register_completion(qs, &dir_completion); + qe_register_completion(qs, &resource_completion); #endif - minibuffer_init(qs); + qe_minibuffer_init(qs); list_init(qs); popup_init(qs); /* init all external modules in link order */ - init_all_modules(qs); + qe_init_all_modules(qs); #ifdef CONFIG_DLL /* load all dynamic modules */ - load_all_modules(qs); + qe_load_all_modules(qs); #endif /* init of the editor state */ qs->screen = &global_screen; /* create first buffer */ - b = eb_new("*scratch*", BF_SAVELOG | BF_UTF8); + b = qe_new_buffer(qs, "*scratch*", BF_SAVELOG | BF_UTF8); + if (!b) { + // XXX: should exit or return fatal error code + return; + } /* will be positionned by do_refresh() */ s = edit_new(b, 0, 0, 0, 0, WF_MODELINE); @@ -11734,10 +11799,10 @@ static void qe_init(void *opaque) * null display driver to have a consistent state * else many commands such as put_status would crash. */ - screen_init(&global_screen, NULL, screen_width, screen_height); + qe_screen_init(qs, &global_screen, NULL, screen_width, screen_height); /* handle options */ - _optind = parse_command_line(argc, argv); + _optind = qe_parse_command_line(qs, argc, argv); /* load config file unless command line option given */ if (!no_init_file) { @@ -11745,7 +11810,7 @@ static void qe_init(void *opaque) s = qs->active_window; } - qe_key_init(&key_ctx); + qe_key_init(&qs->key_ctx); /* select the suitable display manager */ for (;;) { @@ -11754,7 +11819,7 @@ static void qe_init(void *opaque) fprintf(stderr, "No suitable display found, exiting\n"); exit(1); } - if (screen_init(&global_screen, dpy, screen_width, screen_height) < 0) { + if (qe_screen_init(qs, &global_screen, dpy, screen_width, screen_height) < 0) { /* Just disable the display and try another */ //fprintf(stderr, "Could not initialize display '%s', exiting\n", // dpy->name); @@ -11764,7 +11829,7 @@ static void qe_init(void *opaque) } } - put_status(NULL, "%s display %dx%d", + put_status(s, "%s display %dx%d", dpy->name, qs->screen->width, qs->screen->height); qe_event_init(qs); @@ -11831,12 +11896,12 @@ static void qe_init(void *opaque) put_status(s, "Tiny QEmacs %s - Press F1 for help", QE_VERSION); #else put_status(s, "QEmacs %s - Press F1 for help", QE_VERSION); - b = eb_find("*errors*"); + b = qe_find_buffer_name(qs, "*errors*"); if (b != NULL) { show_popup(s, b, "Errors"); } #endif - edit_display(qs); + qe_display(qs); dpy_flush(&global_screen); qs->ec.function = NULL; } @@ -11858,7 +11923,7 @@ int main(int argc, char **argv) #ifdef CONFIG_ALL_KMAPS /* unmap/free input methods file */ - unload_input_methods(); + qe_unload_input_methods(qs); #endif #ifdef CONFIG_UNICODE_JOIN /* free ligature arrays */ @@ -11870,7 +11935,7 @@ int main(int argc, char **argv) #ifndef CONFIG_TINY /* exit all external modules in link order */ - exit_all_modules(qs); + qe_exit_all_modules(qs); if (free_everything) { /* free all structures for valgrind */ @@ -11925,7 +11990,7 @@ int main(int argc, char **argv) free_font_cache(&global_screen); // before dpy_close()? qe_free(&qs->buffer_cache); qs->buffer_cache_size = qs->buffer_cache_len = 0; - clear_macro(qs); + qe_clear_macro(qs); qe_free(&qs->macro_format); } #endif diff --git a/qe.h b/qe.h index 7c45f6b..b3aa8b7 100644 --- a/qe.h +++ b/qe.h @@ -117,6 +117,13 @@ void unregister_bottom_half(void (*cb)(void *opaque), void *opaque); QETimer *qe_add_timer(int delay, void *opaque, void (*cb)(void *opaque)); void qe_kill_timer(QETimer **tip); +/* opaque argument for url_main_loop */ +typedef struct QEArgs { + QEmacsState *qs; + int argc; + char **argv; +} QEArgs; + /* main loop for Unix programs using liburlio */ void url_main_loop(void (*init)(void *opaque), void *opaque); @@ -157,7 +164,7 @@ typedef struct CmdLineOptionDef { int *int_ptr; const char **string_ptr; void (*func_noarg)(void); - void (*func_arg)(const char *); + void (*func_arg)(QEmacsState *qs, const char *); struct CmdLineOptionDef *next; } u; } CmdLineOptionDef; @@ -171,10 +178,10 @@ typedef struct CmdLineOptionDef { #define CMD_LINE_FARG(s,n,a,p,h) { s "|" n "|" a "|" h, CMD_LINE_TYPE_FARG, TRUE, { .func_arg = p }} #define CMD_LINE_LINK() { NULL, CMD_LINE_TYPE_NEXT, FALSE, { NULL }} -void qe_register_cmd_line_options(CmdLineOptionDef *table); +void qe_register_cmd_line_options(QEmacsState *qs, CmdLineOptionDef *table); -int find_resource_file(char *path, int path_size, const char *pattern); -FILE *open_resource_file(const char *name); +int qe_find_resource_file(QEmacsState *qs, char *path, int path_size, const char *pattern); +FILE *qe_open_resource_file(QEmacsState *qs, const char *name); /* qe event handling */ @@ -240,10 +247,10 @@ static inline QEEvent *qe_event_clear(QEEvent *ev) { void qe_handle_event(QEmacsState *qs, QEEvent *ev); /* CG: Should optionally attach grab to a window */ /* CG: Should deal with opaque object life cycle */ -void qe_grab_keys(void (*cb)(void *opaque, int key), void *opaque); -void qe_ungrab_keys(void); +void qe_grab_keys(QEmacsState *qs, void (*cb)(void *opaque, int key), void *opaque); +void qe_ungrab_keys(QEmacsState *qs); KeyDef *qe_find_binding(unsigned int *keys, int nb_keys, KeyDef *kd, int exact); -KeyDef *qe_find_current_binding(unsigned int *keys, int nb_keys, ModeDef *m, int exact); +KeyDef *qe_find_current_binding(QEmacsState *qs, unsigned int *keys, int nb_keys, ModeDef *m, int exact); /* colorize & transform a line, lower level then ColorizeFunc */ /* XXX: should return `len`, the number of valid codepoints copied to @@ -367,8 +374,11 @@ typedef struct EditBufferDataType { #define BF_STYLE8 0x4000 /* buffer has 8 byte styles */ #define BF_STYLE_COMP (QE_TERM_STYLE_BITS <= 16 ? BF_STYLE2 : QE_TERM_STYLE_BITS <= 32 ? BF_STYLE4 : BF_STYLE8) #define BF_IS_STYLE 0x8000 /* buffer is a styles buffer */ -#define BF_IS_LOG 0x10000 /* buffer is a log buffer */ -#define BF_SHELL 0x20000 /* buffer is a shell buffer */ +#define BF_IS_LOG 0x10000 /* buffer is a log buffer */ +#define BF_SHELL 0x20000 /* buffer is a shell buffer */ +/* buffer creation flags */ +#define BC_REUSE 0x100000 /* reuse existing buffer with same name */ +#define BC_CLEAR 0x200000 /* erase found buffer with same name */ struct EditBuffer { OWNED Page *page_table; @@ -479,9 +489,16 @@ typedef struct LogBuffer { int size; } LogBuffer; -void eb_trace_bytes(const void *buf, int size, int state); +void qe_trace_bytes(QEmacsState *qs, const void *buf, int size, int state); +void qe_data_init(QEmacsState *qs); + +EditBuffer *qe_find_buffer_name(QEmacsState *qs, const char *name); +EditBuffer *qe_find_buffer_file(QEmacsState *qs, const char *filename); +EditBuffer *qe_new_buffer(QEmacsState *qs, const char *name, int flags); +void eb_clear(EditBuffer *b); +void eb_free(EditBuffer **ep); +EditState *eb_find_window(EditBuffer *b, EditState *def); -void eb_init(QEmacsState *qs); int eb_read_one_byte(EditBuffer *b, int offset); int eb_read(EditBuffer *b, int offset, void *buf, int size); int eb_write(EditBuffer *b, int offset, const void *buf, int size); @@ -492,23 +509,15 @@ int eb_insert(EditBuffer *b, int offset, const void *buf, int size); int eb_delete(EditBuffer *b, int offset, int size); int eb_replace(EditBuffer *b, int offset, int size, const void *buf, int size1); void eb_free_log_buffer(EditBuffer *b); -EditBuffer *eb_new(const char *name, int flags); -EditBuffer *eb_scratch(const char *name, int flags); -void eb_clear(EditBuffer *b); -void eb_free(EditBuffer **ep); -EditBuffer *eb_find(const char *name); -EditBuffer *eb_find_new(const char *name, int flags); -EditBuffer *eb_find_file(const char *filename); -EditState *eb_find_window(EditBuffer *b, EditState *e); void eb_set_charset(EditBuffer *b, QECharset *charset, EOLType eol_type); -qe__attr_nonnull((3)) +qe__attr_nonnull((1,3)) char32_t eb_nextc(EditBuffer *b, int offset, int *next_ptr); -qe__attr_nonnull((3)) +qe__attr_nonnull((1,3)) char32_t eb_prevc(EditBuffer *b, int offset, int *prev_ptr); -qe__attr_nonnull((3)) +qe__attr_nonnull((1,3)) char32_t eb_next_glyph(EditBuffer *b, int offset, int *next_ptr); -qe__attr_nonnull((3)) +qe__attr_nonnull((1,3)) char32_t eb_prev_glyph(EditBuffer *b, int offset, int *prev_ptr); int eb_skip_accents(EditBuffer *b, int offset); int eb_skip_glyphs(EditBuffer *b, int offset, int n); @@ -608,12 +617,10 @@ int eb_is_in_indentation(EditBuffer *b, int offset); int eb_goto_eol(EditBuffer *b, int offset); int eb_next_line(EditBuffer *b, int offset); -int eb_count_buffers(QEmacsState *qs, EditBuffer *b0, int *totalp, int mask, int val); -EditBuffer *eb_get_buffer_from_index(QEmacsState *qs, int index, int mask, int val); +int qe_count_buffers(QEmacsState *qs, EditBuffer *b0, int *totalp, int mask, int val); +EditBuffer *qe_get_buffer_from_index(QEmacsState *qs, int index, int mask, int val); -void eb_register_data_type(EditBufferDataType *bdt); -EditBufferDataType *eb_probe_data_type(const char *filename, int st_mode, - uint8_t *buf, int buf_size); +void qe_register_data_type(QEmacsState *qs, EditBufferDataType *bdt); void eb_set_data_type(EditBuffer *b, EditBufferDataType *bdt); void eb_invalidate_raw_data(EditBuffer *b); extern EditBufferDataType raw_data_type; @@ -646,16 +653,16 @@ void eb_delete_properties(EditBuffer *b, int offset, int offset2); #else /* QE_MODULE */ -void init_all_modules(QEmacsState *qs); -void exit_all_modules(QEmacsState *qs); +void qe_init_all_modules(QEmacsState *qs); +void qe_exit_all_modules(QEmacsState *qs); #define qe_module_init(fn) \ - extern int module_##fn(QEmacsState *qs); \ - int module_##fn(QEmacsState *qs) { return fn(qs); } + extern int qe_module_##fn(QEmacsState *qs); \ + int qe_module_##fn(QEmacsState *qs) { return fn(qs); } #define qe_module_exit(fn) \ - extern void module_##fn(QEmacsState *qs); \ - void module_##fn(QEmacsState *qs) { fn(qs); } + extern void qe_module_##fn(QEmacsState *qs); \ + void qe_module_##fn(QEmacsState *qs) { fn(qs); } #endif /* QE_MODULE */ @@ -780,7 +787,7 @@ struct EditState { OWNED char *caption; /* optional window caption or title, utf8 */ //const char *mode_line; //const char *title; - struct QEmacsState *qe_state; + struct QEmacsState *qs; struct QEditScreen *screen; /* copy of qe_state->screen */ /* display shadow to optimize redraw */ char modeline_shadow[MAX_SCREEN_WIDTH]; @@ -824,6 +831,7 @@ struct QEModeData { ModeDef *mode; EditState *s; EditBuffer *b; + QEmacsState *qs; /* Other mode specific data follows */ }; @@ -942,6 +950,20 @@ extern QEStyleDef qe_styles[QE_STYLE_NB]; /* QEmacs state structure */ +#define MAX_KEYS 10 + +typedef struct QEKeyContext { + int has_arg; + int argval; + int is_escape; + int nb_keys; + int describe_key; /* if true, the following command is only displayed */ + void (*grab_key_cb)(void *opaque, int key); + void *grab_key_opaque; + unsigned int keys[MAX_KEYS]; + char buf[128]; +} QEKeyContext; + #define NB_YANK_BUFFERS 10 typedef struct QErrorContext { @@ -1080,6 +1102,10 @@ struct QEmacsState { u8 *input_buf; u8 input_buf_def[32]; struct Equivalent *first_equivalent; + + /* key dispatching */ + QEKeyContext key_ctx; + /* mouse handling */ EditState *motion_target; int motion_type, motion_border, motion_x, motion_y; @@ -1089,8 +1115,6 @@ struct QEmacsState { int mouse_clicks; /* 1..3 */ }; -extern QEmacsState qe_state; - struct QETraceDef { int flags; char name[12]; @@ -1103,8 +1127,6 @@ extern size_t const qe_trace_defs_count; /* dynamic key binding storage */ -#define MAX_KEYS 10 - struct KeyDef { struct KeyDef *next; const struct CmdDef *cmd; @@ -1112,7 +1134,7 @@ struct KeyDef { unsigned int keys[1]; }; -void unget_key(int key); +void qe_unget_key(QEmacsState *qs, int key); /* command definitions */ @@ -1210,14 +1232,14 @@ typedef struct CmdDef { /* command not implemented yet */ #define CMDx(name, bindings, desc, ...) -ModeDef *qe_find_mode(const char *name, int flags); -ModeDef *qe_find_mode_filename(const char *filename, int flags); -void qe_register_mode(ModeDef *m, int flags); +ModeDef *qe_find_mode(QEmacsState *qs, const char *name, int flags); +ModeDef *qe_find_mode_filename(QEmacsState *qs, const char *filename, int flags); +void qe_register_mode(QEmacsState *qs, ModeDef *m, int flags); void mode_complete(CompleteState *cp, CompleteFunc enumerate); -int qe_register_commands(ModeDef *m, const CmdDef *cmds, int len); -int qe_register_bindings(KeyDef **lp, const char *cmd_name, const char *keys); +int qe_register_commands(QEmacsState *qs, ModeDef *m, const CmdDef *cmds, int len); +int qe_register_bindings(QEmacsState *qs, KeyDef **lp, const char *cmd_name, const char *keys); int qe_register_transient_binding(QEmacsState *qs, const char *cmd_name, const char *keys); -const CmdDef *qe_find_cmd(const char *cmd_name); +const CmdDef *qe_find_cmd(QEmacsState *qs, const char *cmd_name); int qe_get_prototype(const CmdDef *d, char *buf, int size); /* text display system */ @@ -1368,19 +1390,19 @@ struct InputMethod { InputMethod *next; }; -void register_input_method(InputMethod *m); +void qe_register_input_method(QEmacsState *qs, InputMethod *m); void do_set_input_method(EditState *s, const char *method); void do_switch_input_method(EditState *s); -void input_methods_init(QEmacsState *qs); -int load_input_methods(const char *filename); -void unload_input_methods(void); +void qe_input_methods_init(QEmacsState *qs); +int qe_load_input_methods(QEmacsState *qs, const char *filename); +void qe_unload_input_methods(QEmacsState *qs); /* the following will be suppressed */ #define LINE_MAX_SIZE 256 /* minibuffer & status */ -void minibuffer_init(QEmacsState *qs); +void qe_minibuffer_init(QEmacsState *qs); typedef struct CompletionDef { const char *name; @@ -1391,7 +1413,7 @@ typedef struct CompletionDef { /* get the entry string from the line in the popup window */ int (*get_entry)(EditState *s, char *dest, int size, int offset); /* convert final string to a number */ - long (*convert_entry)(const char *s, const char **endp); + long (*convert_entry)(EditState *s, const char *str, const char **endp); #define CF_FILENAME 1 #define CF_NO_FUZZY 2 #define CF_SPACE_OK 4 @@ -1406,15 +1428,18 @@ typedef struct CompletionDef { struct CompletionDef *next; } CompletionDef; -void qe_register_completion(CompletionDef *cp); +void qe_register_completion(QEmacsState *qs, CompletionDef *cp); void put_status(EditState *s, const char *fmt, ...) qe__attr_printf(2,3); void put_error(EditState *s, const char *fmt, ...) qe__attr_printf(2,3); +void qe_put_error(QEmacsState *qs, const char *fmt, ...) qe__attr_printf(2,3); +void qe_dpy_error(QEditScreen *s, const char *fmt, ...) qe__attr_printf(2,3); + void minibuffer_edit(EditState *e, const char *input, const char *prompt, StringArray *hist, const char *completion_name, void (*cb)(void *opaque, char *buf, CompletionDef *completion), void *opaque); -StringArray *qe_get_history(const char *name); +StringArray *qe_get_history(QEmacsState *qs, const char *name); void command_complete(CompleteState *cp, CompleteFunc enumerate); int eb_command_print_entry(EditBuffer *b, const CmdDef *d, EditState *s); int command_print_entry(CompleteState *cp, EditState *s, const char *name); @@ -1470,8 +1495,9 @@ void compute_client_area(EditState *s); void edit_close(EditState **sp); EditState *edit_new(EditBuffer *b, int x1, int y1, int width, int height, int flags); -EditBuffer *check_buffer(EditBuffer **sp); -EditState *check_window(EditState **sp); +EditBuffer *qe_check_buffer(QEmacsState *qs, EditBuffer **sp); +EditState *qe_check_window(QEmacsState *qs, EditState **sp); +void qe_kill_buffer(QEmacsState *qs, EditBuffer *b); int get_glyph_width(QEditScreen *screen, EditState *s, QETermStyle style, char32_t c); int get_line_height(QEditScreen *screen, EditState *s, QETermStyle style); void do_refresh(EditState *s); @@ -1487,7 +1513,7 @@ void do_split_window(EditState *s, int prop, int side_by_side); void do_create_window(EditState *s, const char *filename, const char *layout); void qe_save_window_layout(EditState *s, EditBuffer *b); -void edit_display(QEmacsState *qs); +void qe_display(QEmacsState *qs); void edit_invalidate(EditState *s, int all); void display_mode_line(EditState *s); int edit_set_mode(EditState *s, ModeDef *m); @@ -1524,7 +1550,6 @@ void do_search_string(EditState *s, const char *search_str, int dir); void do_refresh_complete(EditState *s); void do_kill_buffer(EditState *s, const char *bufname, int force); void switch_to_buffer(EditState *s, EditBuffer *b); -void qe_kill_buffer(EditBuffer *b); /* text mode */ @@ -1554,7 +1579,7 @@ void do_delete_char(EditState *s, int argval); void do_indent_rigidly_by(EditState *s, int start, int end, int argval); void do_indent_rigidly_to_tab_stop(EditState *s, int start, int end, int dir); void do_tabulate(EditState *s, int argval); -EditBuffer *new_yank_buffer(QEmacsState *qs, EditBuffer *base); +EditBuffer *qe_new_yank_buffer(QEmacsState *qs, EditBuffer *base); void do_append_next_kill(EditState *s); void do_kill(EditState *s, int p1, int p2, int dir, int keep); void do_kill_region(EditState *s); @@ -1579,6 +1604,7 @@ void text_mouse_goto(EditState *s, int x, int y, QEEvent *ev); void basic_mode_line(EditState *s, buf_t *out, int c1); void text_mode_line(EditState *s, buf_t *out); void do_toggle_full_screen(EditState *s); +void qe_toggle_control_h(QEmacsState *qs, int set); void do_toggle_control_h(EditState *s, int set); /* misc */ @@ -1588,7 +1614,6 @@ void do_set_trace_flags(EditState *s, int flags); void do_toggle_trace_mode(EditState *s, int argval); void do_set_trace_options(EditState *s, const char *options); void do_cd(EditState *s, const char *name); -int qe_register_command_binding(ModeDef *m, const CmdDef *d, const char *keystr); void do_set_key(EditState *s, const char *keystr, const char *cmd_name, int local); void do_unset_key(EditState *s, const char *keystr, int local); void do_bof(EditState *s); @@ -1611,7 +1636,7 @@ void do_center_cursor(EditState *s, int force); void do_quoted_insert(EditState *s, int argval); void do_overwrite_mode(EditState *s, int argval); // should take argval -void maybe_set_mark(EditState *s); +void do_maybe_set_mark(EditState *s); void do_set_mark(EditState *s); void do_mark_whole_buffer(EditState *s); void do_yank(EditState *s); @@ -1688,15 +1713,13 @@ void do_delete_other_windows(EditState *s, int all); void do_hide_window(EditState *s, int set); void do_delete_hidden_windows(EditState *s); void do_describe_key_briefly(EditState *s, const char *keystr, int argval); -EditBuffer *new_help_buffer(void); +EditBuffer *new_help_buffer(EditState *s); void do_help_for_help(EditState *s); void qe_event_init(QEmacsState *qs); void window_get_min_size(EditState *s, int *w_ptr, int *h_ptr); int window_resize(EditState *s, int target_w, int target_h); void wheel_scroll_up_down(EditState *s, int dir); void qe_mouse_event(QEmacsState *qs, QEEvent *ev); -void set_user_option(const char *user); -void set_tty_charset(const char *name); /* values */ @@ -1818,7 +1841,7 @@ enum { }; void do_transpose(EditState *s, int cmd); -int qe_list_bindings(const CmdDef *d, ModeDef *mode, int inherit, char *buf, int size); +int qe_list_bindings(QEmacsState *qs, const CmdDef *d, ModeDef *mode, int inherit, char *buf, int size); void do_show_bindings(EditState *s, const char *cmd_name); void do_describe_bindings(EditState *s, int argval); void do_apropos(EditState *s, const char *str); @@ -1907,8 +1930,10 @@ void shell_colorize_line(QEColorizeContext *cp, #define SF_AUTO_CODING 0x08 #define SF_AUTO_MODE 0x10 #define SF_BUFED_MODE 0x20 -EditBuffer *new_shell_buffer(EditBuffer *b0, EditState *e, - const char *bufname, const char *caption, - const char *path, - const char *cmd, int shell_flags); +#define SF_REUSE_BUFFER 0x1000 +#define SF_ERASE_BUFFER 0x2000 +EditBuffer *qe_new_shell_buffer(QEmacsState *qs, EditBuffer *b0, EditState *e, + const char *bufname, const char *caption, + const char *path, const char *cmd, + int shell_flags); #endif diff --git a/qescript.c b/qescript.c index 25062fa..29af960 100644 --- a/qescript.c +++ b/qescript.c @@ -182,10 +182,21 @@ static int qe_cfg_append_str_byte(QEmacsDataSource *ds, unsigned char c) { return ds->len; } +static void qe_cfg_error(QEmacsDataSource *ds, const char *fmt, ...) qe__attr_printf(2,3); +static void qe_cfg_error(QEmacsDataSource *ds, const char *fmt, ...) { + char buf[MAX_SCREEN_WIDTH]; + va_list ap; + + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + + put_status(ds->s, "!\007\006script error: %s", buf); +} + // XXX: Should use strunquote parser from util.c // XXX: Should remove string length limitation using allocation static int qe_cfg_parse_string(QEmacsDataSource *ds, const char **pp, int delim) { - EditState *s = ds->s; const char *p = *pp; int triple = 0; int res = 0; @@ -207,17 +218,17 @@ static int qe_cfg_parse_string(QEmacsDataSource *ds, const char **pp, int delim) /* encoding issues deliberately ignored */ unsigned char c = *p; if (c == '\0') { - put_error(s, "unterminated string"); + qe_cfg_error(ds, "unterminated string"); res = -1; break; } if (c == '\n') { if (!triple) { - put_error(s, "newline in simple string"); + qe_cfg_error(ds, "newline in simple string"); res = -1; break; } - ds->s->qe_state->ec.lineno = ++ds->line_num; + ds->s->qs->ec.lineno = ++ds->line_num; } p++; if (c == delim) { @@ -233,7 +244,7 @@ static int qe_cfg_parse_string(QEmacsDataSource *ds, const char **pp, int delim) int maxc = -1; #endif if (*p == '\0') { - put_error(s, "unterminated string"); + qe_cfg_error(ds, "unterminated string"); res = -1; break; } @@ -242,7 +253,7 @@ static int qe_cfg_parse_string(QEmacsDataSource *ds, const char **pp, int delim) case '\n': // escaped newlines contribute no character to the string // XXX: should ignore leading white space? - ds->s->qe_state->ec.lineno = ++ds->line_num; + ds->s->qs->ec.lineno = ++ds->line_num; continue; case 'n': c = '\n'; break; case 'r': c = '\r'; break; @@ -306,7 +317,7 @@ static int qe_cfg_next_token(QEmacsDataSource *ds) { if (c == '\n') { /* set has_seen_newline for automatic semicolon insertion */ ds->newline_seen = 1; - ds->s->qe_state->ec.lineno = ++ds->line_num; + ds->s->qs->ec.lineno = ++ds->line_num; continue; } if (qe_isspace(c)) @@ -328,7 +339,7 @@ static int qe_cfg_next_token(QEmacsDataSource *ds) { break; } if (c == '\n') - ds->s->qe_state->ec.lineno = ++ds->line_num; + ds->s->qs->ec.lineno = ++ds->line_num; } continue; } @@ -403,7 +414,7 @@ static int qe_cfg_next_token(QEmacsDataSource *ds) { strtoll_c(ds->start_p, &ds->p, 0); if (qe_isalnum_(*ds->p)) { /* type suffixes not supported */ - put_error(ds->s, "invalid number"); + qe_cfg_error(ds, "invalid number"); return ds->tok = TOK_ERR; } return ds->tok = TOK_NUMBER; @@ -428,7 +439,7 @@ static int qe_cfg_next_token(QEmacsDataSource *ds) { } } ds->p = cs8(p); - put_error(ds->s, "unsupported operator: %c", c); + qe_cfg_error(ds, "unsupported operator: %c", c); return ds->tok = c; } } @@ -447,7 +458,7 @@ static int expect_token(QEmacsDataSource *ds, int tok) { return 1; } else { /* tok is a single byte token, no need to pretty print */ - put_error(ds->s, "'%c' expected", tok); + qe_cfg_error(ds, "'%c' expected", tok); return 0; } } @@ -468,12 +479,12 @@ static int qe_cfg_getvalue(QEmacsDataSource *ds, QEValue *sp) { break; default: case VAR_UNKNOWN: - put_error(ds->s, "no variable %s", sp->u.str); + qe_cfg_error(ds, "no variable %s", sp->u.str); qe_cfg_set_void(sp); return 1; } #else - put_error(ds->s, "no variable %s", sp->u.str); + qe_cfg_error(ds, "no variable %s", sp->u.str); #endif } return 0; @@ -631,7 +642,7 @@ static int qe_cfg_skip_expr(QEmacsDataSource *ds); static int qe_cfg_check_lvalue(QEmacsDataSource *ds, QEValue *sp) { if (sp->type != TOK_ID) { - put_error(ds->s, "not a variable"); + qe_cfg_error(ds, "not a variable"); return 1; } return 0; @@ -651,7 +662,7 @@ static int qe_cfg_expr(QEmacsDataSource *ds, QEValue *sp, int prec0, int skip) { if (sp >= ds->sp_max) { if (sp >= ds->stack + countof(ds->stack)) { - put_error(ds->s, "stack overflow"); + qe_cfg_error(ds, "stack overflow"); return qe_cfg_skip_expr(ds); } ds->sp_max = sp + 1; @@ -723,7 +734,7 @@ again: } default: qe_cfg_set_void(sp); - put_error(ds->s, "invalid expression"); + qe_cfg_error(ds, "invalid expression"); goto fail; } @@ -756,7 +767,7 @@ again: case '(': /* function call */ /* XXX: should move this code to qe_cfg_call() */ if (sp->type == TOK_ID) { - const CmdDef *d = qe_find_cmd(sp->u.str); + const CmdDef *d = qe_find_cmd(ds->s->qs, sp->u.str); if (!d) { #ifndef CONFIG_TINY if (strequal(sp->u.str, "char")) { @@ -779,7 +790,7 @@ again: } else #endif { - put_error(ds->s, "unknown command '%s'", sp->u.str); + qe_cfg_error(ds, "unknown command '%s'", sp->u.str); goto fail; } } @@ -787,7 +798,7 @@ again: goto fail; continue; } - put_error(ds->s, "invalid function call"); + qe_cfg_error(ds, "invalid function call"); goto fail; #ifndef CONFIG_TINY case TOK_INC: /* post increment: convert to first(x, x += 1) */ @@ -811,7 +822,7 @@ again: continue; case '.': /* property / method accessor */ if (ds->tok != TOK_ID) { - put_error(ds->s, "expected property name"); + qe_cfg_error(ds, "expected property name"); goto fail; } if (qe_cfg_getvalue(ds, sp)) @@ -822,11 +833,11 @@ again: qe_cfg_next_token(ds); continue; } - put_error(ds->s, "no such property '%s'", ds->str); + qe_cfg_error(ds, "no such property '%s'", ds->str); goto fail; #endif default: - put_error(ds->s, "unsupported operator '%c'", op); + qe_cfg_error(ds, "unsupported operator '%c'", op); goto fail; } //continue; // never reached @@ -850,7 +861,7 @@ again: if (qe_cfg_op(ds, sp, op)) goto fail; #else - put_error(ds->s, "unsupported operator '%c'", op); + qe_cfg_error(ds, "unsupported operator '%c'", op); goto fail; #endif } @@ -898,7 +909,7 @@ static int qe_cfg_op(QEmacsDataSource *ds, QEValue *sp, int op) { return 1; break; default: - put_error(ds->s, "invalid string operator '%c'", op); + qe_cfg_error(ds, "invalid string operator '%c'", op); return 1; } } else { @@ -916,7 +927,7 @@ static int qe_cfg_op(QEmacsDataSource *ds, QEValue *sp, int op) { case TOK_MOD_EQ: if (sp[1].u.value == 0 || (sp->u.value == LLONG_MIN && sp[1].u.value == -1)) { // XXX: should pretty print op for `/=` and `%=` - put_error(ds->s, "'%c': division overflow", op); + qe_cfg_error(ds, "'%c': division overflow", op); return 1; } if (op == '/' || op == TOK_DIV_EQ) @@ -985,7 +996,7 @@ static int qe_cfg_op(QEmacsDataSource *ds, QEValue *sp, int op) { sp->u.value = sp[1].u.value; break; default: - put_error(ds->s, "invalid numeric operator '%c'", op); + qe_cfg_error(ds, "invalid numeric operator '%c'", op); return 1; } } @@ -1009,7 +1020,7 @@ static int qe_cfg_assign(QEmacsDataSource *ds, QEValue *sp, int op) { qe_cfg_move(sp + 1, sp); *sp = val; #else - put_error(ds->s, "unsupported operator %c", op); + qe_cfg_error(ds, "unsupported operator %c", op); return 1; #endif } @@ -1027,7 +1038,7 @@ static int qe_cfg_assign(QEmacsDataSource *ds, QEValue *sp, int op) { ds->s->b->tab_width = sp[1].u.value; } else if (strequal(sp->u.str, "default-tab-width")) { - ds->s->qe_state->default_tab_width = sp[1].u.value; + ds->s->qs->default_tab_width = sp[1].u.value; } else if (strequal(sp->u.str, "indent-tabs-mode")) { ds->s->indent_tabs_mode = sp[1].u.value; @@ -1036,7 +1047,7 @@ static int qe_cfg_assign(QEmacsDataSource *ds, QEValue *sp, int op) { ds->s->indent_width = sp[1].u.value; } else { /* ignore other variables without a warning */ - put_error(ds->s, "unsupported variable %s", sp->u.str); + qe_cfg_error(ds, "unsupported variable %s", sp->u.str); return 1; } qe_cfg_swap(sp, sp + 1); /* do not reload value */ @@ -1088,16 +1099,16 @@ static int qe_cfg_get_args(QEmacsDataSource *ds, QEValue *sp, int n1, int n2) { return -1; sep = ','; if (qe_cfg_expr(ds, sp + nargs, PREC_ASSIGNMENT, 0)) { - put_error(ds->s, "invalid argument"); // need function name + qe_cfg_error(ds, "invalid argument"); // need function name return -1; } } if (nargs < n1) { - put_error(ds->s, "missing arguments"); // need function name + qe_cfg_error(ds, "missing arguments"); // need function name return -1; } if (nargs > n2) { - put_error(ds->s, "extra arguments"); // need function name + qe_cfg_error(ds, "extra arguments"); // need function name return -1; } return nargs; @@ -1116,7 +1127,7 @@ static void qe_cfg_free_args(QEmacsDataSource *ds, int nb_args, static int qe_cfg_call(QEmacsDataSource *ds, QEValue *sp, const CmdDef *d) { EditState *s = ds->s; - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; const char *r; int nb_args, sep, i, ret; CmdArgSpec cas; @@ -1138,7 +1149,7 @@ static int qe_cfg_call(QEmacsDataSource *ds, QEValue *sp, const CmdDef *d) { while ((ret = parse_arg(&r, &cas)) != 0) { if (ret < 0 || nb_args >= MAX_CMD_ARGS) { - put_error(s, "invalid command definition '%s'", d->name); + qe_cfg_error(ds, "invalid command definition '%s'", d->name); return -1; } args[nb_args].p = NULL; @@ -1202,7 +1213,7 @@ static int qe_cfg_call(QEmacsDataSource *ds, QEValue *sp, const CmdDef *d) { then match actual command arguments */ if (qe_cfg_expr(ds, sp, PREC_ASSIGNMENT, 0)) { - put_error(s, "missing arguments for %s", d->name); + qe_cfg_error(ds, "missing arguments for %s", d->name); qe_cfg_free_args(ds, i, args, args_type); return -1; } @@ -1228,7 +1239,7 @@ static int qe_cfg_call(QEmacsDataSource *ds, QEValue *sp, const CmdDef *d) { } } if (!has_token(ds, ')')) { - put_error(s, "too many arguments for %s", d->name); + qe_cfg_error(ds, "too many arguments for %s", d->name); qe_cfg_free_args(ds, nb_args, args, args_type); return -1; } @@ -1240,7 +1251,7 @@ static int qe_cfg_call(QEmacsDataSource *ds, QEValue *sp, const CmdDef *d) { qs->last_cmd_func = qs->this_cmd_func; if (qs->active_window) s = qs->active_window; - check_window(&s); + qe_check_window(qs, &s); ds->s = s; sp->type = TOK_VOID; qe_cfg_free_args(ds, nb_args, args, args_type); @@ -1254,7 +1265,7 @@ static int qe_cfg_stmt(QEmacsDataSource *ds, QEValue *sp, int skip) { /* handle blocks */ while (!has_token(ds, '}')) { if (ds->tok == TOK_EOF) { - put_error(ds->s, "missing '}'"); + qe_cfg_error(ds, "missing '}'"); return 1; } res |= qe_cfg_stmt(ds, sp, skip); @@ -1284,14 +1295,14 @@ static int qe_cfg_stmt(QEmacsDataSource *ds, QEValue *sp, int skip) { /* consume `;` if any or is current token first on line */ if (!has_token(ds, ';') && ds->tok != TOK_EOF && ds->tok != '}' && !ds->newline_seen) { //if (!res) - put_error(ds->s, "missing ';'"); + qe_cfg_error(ds, "missing ';'"); } return res; } static int qe_parse_script(EditState *s, QEmacsDataSource *ds) { - QEmacsState *qs = s->qe_state; - QErrorContext ec = qs->ec; + QEmacsState *qs = s->qs; + QErrorContext ec_save = qs->ec; QEValue *sp = &ds->stack[0]; ds->s = s; @@ -1311,7 +1322,7 @@ static int qe_parse_script(EditState *s, QEmacsDataSource *ds) { qe_free(&ds->allocated_buf); ds->p = ds->buf = NULL; } - qs->ec = ec; + qs->ec = ec_save; return sp->type; } @@ -1363,7 +1374,7 @@ static void qe_cfg_postprocess(EditState *s, QEmacsDataSource *ds, int argval) { } break; default: - put_error(s, "unexpected value type: %d", sp->type); + qe_cfg_error(ds, "unexpected value type: %d", sp->type); break; } } @@ -1378,7 +1389,7 @@ void do_eval_expression(EditState *s, const char *expression, int argval) ds.buf = expression; ds.filename = ""; if (qe_parse_script(s, &ds) == TOK_ERR) { - put_error(s, "evaluation error"); + // error already reported } else { qe_cfg_postprocess(s, &ds, argval); } @@ -1402,14 +1413,14 @@ static int do_eval_buffer_region(EditState *s, int start, int stop, int argval) /* extract region as UTF-8 with a size limit */ length = eb_get_region_content_size(s->b, start, stop); if (length > MAX_SCRIPT_LENGTH || !(buf = qe_malloc_array(char, length + 1))) { - put_error(s, "buffer too large"); + put_error(s, "buffer region too large"); return -1; } length = eb_get_region_contents(s->b, start, stop, buf, length + 1, 0); ds.buf = ds.allocated_buf = buf; ds.filename = s->b->name; if (qe_parse_script(s, &ds) == TOK_ERR) { - put_error(s, "evaluation error"); + // error already reported res = 1; } else { if (argval != NO_ARG && !check_read_only(s)) { @@ -1462,7 +1473,7 @@ static void symbol_complete(CompleteState *cp, CompleteFunc enumerate) { } static int symbol_print_entry(CompleteState *cp, EditState *s, const char *name) { - const CmdDef *d = qe_find_cmd(name); + const CmdDef *d = qe_find_cmd(s->qs, name); if (d) { return command_print_entry(cp, s, name); } else { @@ -1495,9 +1506,9 @@ static const CmdDef parser_commands[] = { }; static int parser_init(QEmacsState *qs) { - qe_register_commands(NULL, parser_commands, countof(parser_commands)); + qe_register_commands(qs, NULL, parser_commands, countof(parser_commands)); #ifndef CONFIG_TINY - qe_register_completion(&symbol_completion); + qe_register_completion(qs, &symbol_completion); #endif return 0; } diff --git a/search.c b/search.c index 1070bc4..c5af567 100644 --- a/search.c +++ b/search.c @@ -201,7 +201,7 @@ static int eb_search(EditBuffer *b, int dir, int flags, regexp_bytes = lre_compile(®exp_len, error_message, sizeof(error_message), source, source_len, re_flags, NULL); if (regexp_bytes == NULL) { - //put_status(NULL, "regexp compile error: %s", error_message); + //put_status(b->qs->active_window, "regexp compile error: %s", error_message); return -1; } capture_num = lre_get_capture_count(regexp_bytes); @@ -209,7 +209,7 @@ static int eb_search(EditBuffer *b, int dir, int flags, if (capture_num == 0 || capture == NULL) { qe_free(®exp_bytes); qe_free(&capture); - //put_status(NULL, "cannot allocate capture array for %d entries", capture_num); + //put_status(b->qs->active_window, "cannot allocate capture array for %d entries", capture_num); return -1; } for (offset1 = offset;;) { @@ -512,7 +512,7 @@ static void isearch_run(ISearchState *is) { /* display search string */ out = buf_init(&outbuf, ubuf, sizeof(ubuf)); if (is->found_offset < 0 && len > 0) { - if (is->s->qe_state->macro_key_index >= 0) { + if (is->s->qs->macro_key_index >= 0) { /* if macro is running, abort search and macro */ isearch_exit(is->s, KEY_RET); put_status(s, "\007"); @@ -535,7 +535,7 @@ static void isearch_run(ISearchState *is) { /* display text */ do_center_cursor(s, 0); - edit_display(s->qe_state); + qe_display(s->qs); put_status(s, "%s", out->buf); /* XXX: why NULL? */ elapsed_time = get_clock_ms() - start_time; if (elapsed_time >= 100) @@ -620,7 +620,7 @@ static void isearch_yank_kill(EditState *s) { // XXX: does not work for hex search modes ISearchState *is = s->isearch_state; if (is) { - QEmacsState *qs = is->s->qe_state; + QEmacsState *qs = is->s->qs; isearch_grab(is, qs->yank_buffers[qs->yank_current], 0, -1); } } @@ -645,7 +645,7 @@ static void isearch_addpos(EditState *s, int dir) { is->dir = dir; if (is->search_u32_len == 0 && is->dir == curdir) { /* retrieve last search string from search history list */ - StringArray *hist = qe_get_history("search"); + StringArray *hist = qe_get_history(s->qs, "search"); if (hist && hist->nb_items) { const char *str = hist->items[hist->nb_items - 1]->str; if (str) { @@ -763,13 +763,14 @@ void isearch_toggle_word_match(EditState *s) { static void isearch_end(ISearchState *is) { /* save current search string to the search history buffer */ - StringArray *hist = qe_get_history("search"); + QEmacsState *qs = is->s->qs; + StringArray *hist = qe_get_history(qs, "search"); if (*is->search_str && hist) { remove_string(hist, is->search_str); add_string(hist, is->search_str, 0); } is->search_flags &= ~SEARCH_FLAG_ACTIVE; - edit_display(is->s->qe_state); + qe_display(qs); dpy_flush(is->s->screen); } @@ -805,7 +806,7 @@ static void isearch_exit(EditState *s, int key) { /* do not keep search matches lingering */ s->isearch_state = NULL; if (key != KEY_RET && key != KEY_QUIT) { - unget_key(key); + qe_unget_key(s->qs, key); } isearch_end(is); } @@ -813,6 +814,7 @@ static void isearch_exit(EditState *s, int key) { static void isearch_key(void *opaque, int key) { ISearchState *is = opaque; + QEmacsState *qs = is->s->qs; unsigned int keys[1] = { key }; if (is->quoting) { @@ -837,7 +839,7 @@ static void isearch_key(void *opaque, int key) { } if (!(is->search_flags & SEARCH_FLAG_ACTIVE)) { /* This should free the ISearchState grab data if allocated */ - qe_ungrab_keys(); + qe_ungrab_keys(qs); } } @@ -847,7 +849,7 @@ static ISearchState *set_search_state(EditState *s, int argval, int dir) { int flags = SEARCH_FLAG_DEFAULT | SEARCH_FLAG_ACTIVE; /* stop displaying search matches on last window */ - e = check_window(&is->s); + e = qe_check_window(s->qs, &is->s); if (e) { e->isearch_state = NULL; } @@ -878,6 +880,7 @@ static ISearchState *set_search_state(EditState *s, int argval, int dir) { /* XXX: handle busy */ void do_isearch(EditState *s, int argval, int dir) { ISearchState *is; + QEmacsState *qs = s->qs; /* prevent search from minibuffer */ if (s->flags & WF_MINIBUF) @@ -885,7 +888,7 @@ void do_isearch(EditState *s, int argval, int dir) { is = set_search_state(s, argval, dir); if (is != NULL) { - qe_grab_keys(isearch_key, is); + qe_grab_keys(qs, isearch_key, is); isearch_run(is); } } @@ -943,7 +946,7 @@ void isearch_colorize_matches(EditState *s, char32_t *buf, int len, return; search_flags = is->search_flags; - if (check_window(&is->minibuffer)) { + if (qe_check_window(s->qs, &is->minibuffer)) { /* refresh target window for search matches */ // XXX: should perform this once per window with a NULL buf char contents[1024]; @@ -1025,7 +1028,7 @@ static void query_replace_help(QueryReplaceState *is) { if (is->help_window) return; - b = new_help_buffer(); + b = new_help_buffer(s); if (!b) return; @@ -1058,11 +1061,11 @@ static void query_replace_abort(QueryReplaceState *is) s->b->mark = is->start_offset; s->region_style = 0; - put_status(NULL, "Replaced %d occurrences", is->nb_reps); + put_status(s, "Replaced %d occurrences", is->nb_reps); /* Achtung: should free the grab data */ - qe_ungrab_keys(); + qe_ungrab_keys(s->qs); qe_free(&is); - edit_display(s->qe_state); + qe_display(s->qs); dpy_flush(s->screen); } @@ -1118,8 +1121,8 @@ static void query_replace_run(QueryReplaceState *is) s->b->mark = is->found_offset; s->region_style = QE_STYLE_SEARCH_MATCH; do_center_cursor(s, 0); - edit_display(s->qe_state); - put_status(NULL, "%s", out->buf); + qe_display(s->qs); + put_status(s, "%s", out->buf); dpy_flush(s->screen); } @@ -1127,13 +1130,15 @@ static void query_replace_key(void *opaque, int key) { QueryReplaceState *is = opaque; EditState *s = is->s; - QEmacsState *qs = s->qe_state; + QEmacsState *qs = s->qs; - if (check_window(&is->help_window)) { + if (qe_check_window(qs, &is->help_window)) { do_delete_window(is->help_window, 0); is->help_window = NULL; + // FIXME: this should be implicit as s should be the target window + // of the is->help_window popup. qs->active_window = s; - edit_display(is->s->qe_state); + qe_display(qs); dpy_flush(is->s->screen); return; } @@ -1231,7 +1236,7 @@ static void query_replace(EditState *s, const char *search_str, is->start_offset = is->last_offset = s->offset; is->found_offset = is->found_end = s->offset; - qe_grab_keys(query_replace_key, is); + qe_grab_keys(s->qs, query_replace_key, is); query_replace_run(is); } @@ -1367,7 +1372,9 @@ void do_search_string(EditState *s, const char *search_str, int mode) } if (mode == CMD_LIST_MATCHING_LINES) { // XXX: should check prefix argument to clear buffer - b1 = eb_find_new("*occur*", BF_UTF8 | (s->b->flags & BF_STYLES)); + b1 = qe_new_buffer(s->qs, "*occur*", BC_REUSE | BF_UTF8 | (s->b->flags & BF_STYLES)); + if (!b1) + return; start = b1->total_size; } @@ -1654,10 +1661,10 @@ static ModeDef isearch_mode = { }; static int search_init(QEmacsState *qs) { - qe_register_mode(&isearch_mode, MODEF_NOCMD); - qe_register_commands(&isearch_mode, isearch_commands, countof(isearch_commands)); - qe_register_commands(NULL, search_commands, countof(search_commands)); - qe_register_completion(&search_completion); + qe_register_mode(qs, &isearch_mode, MODEF_NOCMD); + qe_register_commands(qs, &isearch_mode, isearch_commands, countof(isearch_commands)); + qe_register_commands(qs, NULL, search_commands, countof(search_commands)); + qe_register_completion(qs, &search_completion); return 0; } diff --git a/tools/cptoqe.c b/tools/cptoqe.c index ae4d039..0134fbe 100644 --- a/tools/cptoqe.c +++ b/tools/cptoqe.c @@ -2,7 +2,7 @@ * Convert Unicode 8-bit code page files to QEmacs format * * Copyright (c) 2002 Fabrice Bellard. - * Copyright (c) 2007-2023 Charlie Gordon. + * Copyright (c) 2007-2024 Charlie Gordon. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -267,7 +267,7 @@ static void handle_cp(FILE *f0, const char *name, const char *fname, int lineno) "\n\n", eol_char, min_code, max_code, name_id); - add_init(" qe_register_charset(&charset_"); + add_init(" qe_register_charset(qs, &charset_"); add_init(name_id); add_init(");\n"); } @@ -323,7 +323,7 @@ int main(int argc, char **argv) "\n" " * More Charsets and Tables for QEmacs" "\n" " *" "\n" " * Copyright (c) 2002 Fabrice Bellard." - "\n" " * Copyright (c) 2002-2023 Charlie Gordon." + "\n" " * Copyright (c) 2002-2024 Charlie Gordon." "\n" " *" "\n" " * Permission is hereby granted, free of charge, to any person obtaining a copy" "\n" " * of this software and associated documentation files (the \"Software\"), to deal" @@ -347,7 +347,7 @@ int main(int argc, char **argv) "\n" "#include \"qe.h\"" "\n" ""); - add_init("int charset_more_init(QEmacsState *qs)\n{\n"); + add_init("int qe_charset_more_init(QEmacsState *qs)\n{\n"); for (i = 1; i < argc; i++) { filename = argv[i]; @@ -390,7 +390,7 @@ int main(int argc, char **argv) } add_init("\n return 0;\n}\n\n" - "qe_module_init(charset_more_init);\n"); + "qe_module_init(qe_charset_more_init);\n"); printf("%s", module_init); diff --git a/tools/jistoqe.c b/tools/jistoqe.c index e4fca19..a625a94 100644 --- a/tools/jistoqe.c +++ b/tools/jistoqe.c @@ -2,7 +2,7 @@ * Convert Unicode JIS tables to QEmacs format * * Copyright (c) 2002 Fabrice Bellard. - * Copyright (c) 2002-2023 Charlie Gordon. + * Copyright (c) 2002-2024 Charlie Gordon. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -147,7 +147,7 @@ int main(int argc, char **argv) "\n" " * JIS Tables for QEmacs" "\n" " *" "\n" " * Copyright (c) 2002 Fabrice Bellard." - "\n" " * Copyright (c) 2002-2023 Charlie Gordon." + "\n" " * Copyright (c) 2002-2024 Charlie Gordon." "\n" " *" "\n" " * Permission is hereby granted, free of charge, to any person obtaining a copy" "\n" " * of this software and associated documentation files (the \"Software\"), to deal" diff --git a/tty.c b/tty.c index 04f7f9e..db08360 100644 --- a/tty.c +++ b/tty.c @@ -284,7 +284,7 @@ static const char *getenv1(const char *name) { return p ? p : ""; } -static int tty_dpy_init(QEditScreen *s, +static int tty_dpy_init(QEditScreen *s, QEmacsState *qs, qe__unused__ int w, qe__unused__ int h) { TTYState *ts; @@ -298,6 +298,7 @@ static int tty_dpy_init(QEditScreen *s, } tty_screen = s; + s->qs = qs; s->STDIN = stdin; s->STDOUT = stdout; s->priv_data = ts; @@ -486,13 +487,13 @@ static int tty_dpy_init(QEditScreen *s, tty_term_set_raw(s); /* Get charset from command line option */ - s->charset = find_charset(qe_state.tty_charset); + s->charset = qe_find_charset(qs, qs->tty_charset); if (ts->term_code == TERM_CYGWIN) s->charset = &charset_8859_1; if (ts->term_code == TERM_TW100) - s->charset = find_charset("atarist"); + s->charset = qe_find_charset(qs, "atarist"); // XXX: default charset for non tty invocations should be UTF-8 if (!s->charset && !isatty(fileno(s->STDOUT))) @@ -570,7 +571,7 @@ static int tty_dpy_init(QEditScreen *s, s->charset = &charset_utf8; } } - put_status(NULL, "tty charset: %s", s->charset->name); + put_status(qs->active_window, "tty charset: %s", s->charset->name); atexit(tty_term_exit); @@ -596,7 +597,7 @@ static int tty_dpy_init(QEditScreen *s, #if 0 if (ts->term_flags & KBS_CONTROL_H) { - do_toggle_control_h(NULL, 1); + qe_toggle_control_h(qs, 1); } #endif return 0; @@ -742,7 +743,7 @@ static int tty_dpy_is_user_input_pending(QEditScreen *s) static int tty_get_clipboard(QEditScreen *s, int ch) { - QEmacsState *qs = &qe_state; + QEmacsState *qs = s->qs; TTYState *ts = s->priv_data; EditBuffer *b; size_t size; @@ -767,7 +768,7 @@ static int tty_get_clipboard(QEditScreen *s, int ch) if (!contents) return -1; if (qs->trace_buffer) - eb_trace_bytes(contents, size, EB_TRACE_CLIPBOARD); + qe_trace_bytes(qs, contents, size, EB_TRACE_CLIPBOARD); if (size == ts->clipboard_size && !memcmp(ts->clipboard, contents, size)) { qe_free(&contents); return 0; @@ -776,7 +777,7 @@ static int tty_get_clipboard(QEditScreen *s, int ch) ts->clipboard = contents; ts->clipboard_size = size; /* copy terminal selection a new yank buffer */ - b = new_yank_buffer(qs, NULL); + b = qe_new_yank_buffer(qs, NULL); eb_set_charset(b, &charset_utf8, EOL_UNIX); eb_write(b, 0, contents, size); return 1; @@ -785,7 +786,7 @@ static int tty_get_clipboard(QEditScreen *s, int ch) static int tty_request_clipboard(QEditScreen *s) { - eb_trace_bytes("tty-request-clipboard", -1, EB_TRACE_COMMAND); + qe_trace_bytes(s->qs, "tty-request-clipboard", -1, EB_TRACE_COMMAND); TTY_FPUTS("\033]52;;?\007", s->STDOUT); fflush(s->STDOUT); return 1; @@ -794,7 +795,7 @@ static int tty_request_clipboard(QEditScreen *s) static int tty_set_clipboard(QEditScreen *s) { // TODO: make this selectable - QEmacsState *qs = &qe_state; + QEmacsState *qs = s->qs; TTYState *ts = s->priv_data; EditBuffer *b = qs->yank_buffers[qs->yank_current]; size_t size; @@ -817,7 +818,7 @@ static int tty_set_clipboard(QEditScreen *s) qe_free(&contents); return -1; } - eb_trace_bytes("tty-set-clipboard", -1, EB_TRACE_COMMAND); + qe_trace_bytes(qs, "tty-set-clipboard", -1, EB_TRACE_COMMAND); qe_free(&ts->clipboard); ts->clipboard = contents; ts->clipboard_size = size; @@ -869,7 +870,7 @@ static int const csi_lookup[] = { static void tty_read_handler(void *opaque) { QEditScreen *s = opaque; - QEmacsState *qs = &qe_state; + QEmacsState *qs = s->qs; TTYState *ts = s->priv_data; QEEvent ev1, *ev = qe_event_clear(&ev1); u8 buf[1]; @@ -879,7 +880,7 @@ static void tty_read_handler(void *opaque) return; if (qs->trace_buffer) - eb_trace_bytes(buf, 1, EB_TRACE_TTY); + qe_trace_bytes(qs, buf, 1, EB_TRACE_TTY); shift = 0; ch = buf[0]; @@ -1124,7 +1125,7 @@ static void tty_read_handler(void *opaque) case 'I': // FocusIn enabled by CSI ? 1004 h ts->input_state = IS_NORM; ts->has_meta = 0; - eb_trace_bytes("tty-focus-in", -1, EB_TRACE_COMMAND); + qe_trace_bytes(qs, "tty-focus-in", -1, EB_TRACE_COMMAND); if (tty_clipboard > 0) { /* request clipboard contents into kill buffer if changed */ tty_request_clipboard(s); @@ -1133,7 +1134,7 @@ static void tty_read_handler(void *opaque) case 'O': // FocusOut ts->input_state = IS_NORM; ts->has_meta = 0; - eb_trace_bytes("tty-focus-out", -1, EB_TRACE_COMMAND); + qe_trace_bytes(qs, "tty-focus-out", -1, EB_TRACE_COMMAND); if (tty_clipboard > 0) { /* push last kill to clipboard if new */ tty_set_clipboard(s); @@ -1264,7 +1265,7 @@ static void tty_read_handler(void *opaque) if (qs->trace_buffer) { char buf1[32]; snprintf(buf1, sizeof buf1, "tty-osc-%d", n1); - eb_trace_bytes(buf1, -1, EB_TRACE_COMMAND); + qe_trace_bytes(qs, buf1, -1, EB_TRACE_COMMAND); } if (n1 == 52) { if (tty_clipboard > 0) { @@ -2141,12 +2142,13 @@ static QEDisplay tty_dpy = { tty_dpy_describe, tty_dpy_sound_bell, tty_dpy_suspend, + qe_dpy_error, NULL, /* next */ }; static int tty_init(QEmacsState *qs) { - return qe_register_display(&tty_dpy); + return qe_register_display(qs, &tty_dpy); } qe_module_init(tty_init); diff --git a/unix.c b/unix.c index 1ac2fd7..9ede6d2 100644 --- a/unix.c +++ b/unix.c @@ -319,6 +319,7 @@ static void url_block(void) void url_main_loop(void (*init)(void *opaque), void *opaque) { + QEArgs *ap = opaque; url_block_reset(); (*init)(opaque); for (;;) { @@ -326,11 +327,11 @@ void url_main_loop(void (*init)(void *opaque), void *opaque) break; url_block(); if (url_display_request) { - QEmacsState *qs = &qe_state; + QEmacsState *qs = ap->qs; //qs->complete_refresh = 1; - do_refresh(NULL); - edit_display(qs); + do_refresh(qs->first_window); + qe_display(qs); dpy_flush(qs->screen); url_display_request = 0; } diff --git a/util.c b/util.c index c6ae6da..5a9ecc2 100644 --- a/util.c +++ b/util.c @@ -2283,13 +2283,12 @@ int buf_quote_byte(buf_t *bp, unsigned char ch) { char *qe_encode64(const void *src, size_t len, size_t *sizep) { const u8 *p = src; - size_t size = len * 4 / 3 + 3; + size_t size = (len + 2) / 3 * 4 + 1; + size_t j = 0; char *buf = qe_malloc_bytes(size); - *sizep = 0; if (buf != NULL) { static const char dict[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - size_t j = 0; size_t i; uint32_t val; for (i = 0; i + 2 < len; i += 3) { @@ -2319,19 +2318,18 @@ char *qe_encode64(const void *src, size_t len, size_t *sizep) break; } buf[j] = '\0'; - *sizep = j; } + *sizep = j; return buf; } void *qe_decode64(const char *src, size_t len, size_t *sizep) { - size_t size = len * 3 / 4 + 2; + size_t size = (len + 3) / 4 * 3 + 1; + size_t j = 0; u8 *buf = qe_malloc_bytes(size); - *sizep = 0; if (buf != NULL) { int shift = 0; - size_t j = 0; size_t i; for (i = 0; i < len; i++) { //static const char Base64[] = @@ -2374,8 +2372,8 @@ void *qe_decode64(const char *src, size_t len, size_t *sizep) } } buf[j] = '\0'; - *sizep = j; } + *sizep = j; return buf; } diff --git a/variables.c b/variables.c index 748653e..4e9eb10 100644 --- a/variables.c +++ b/variables.c @@ -160,9 +160,8 @@ static VarDef var_table[] = { //G_VAR( "perl-mode-extensions", perl_mode.extensions, VAR_STRING, VAR_RW, NULL ) }; -static VarDef *qe_find_variable(const char *name) +static VarDef *qe_find_variable(QEmacsState *qs, const char *name) { - QEmacsState *qs = &qe_state; VarDef *vp; for (vp = qs->first_variable; vp; vp = vp->next) { @@ -176,7 +175,7 @@ static VarDef *qe_find_variable(const char *name) } void variable_complete(CompleteState *cp, CompleteFunc enumerate) { - QEmacsState *qs = cp->s->qe_state; + QEmacsState *qs = cp->s->qs; const VarDef *vp; for (vp = qs->first_variable; vp; vp = vp->next) { @@ -195,7 +194,7 @@ QVarType qe_get_variable(EditState *s, const char *name, /* find standard variable and user variables */ // XXX: should also have window, buffer, mode properties? - vp = qe_find_variable(name); + vp = qe_find_variable(s->qs, name); if (!vp) { /* Try environment */ str = getenv(name); @@ -223,7 +222,7 @@ QVarType qe_get_variable(EditState *s, const char *name, ptr = vp->value.ptr; break; case VAR_STATE: - ptr = (const u8*)s->qe_state + vp->value.offset; + ptr = (const u8*)s->qs + vp->value.offset; break; case VAR_BUFFER: ptr = (const u8*)s->b + vp->value.offset; @@ -336,10 +335,11 @@ static QVarType qe_variable_set_value_generic(EditState *s, VarDef *vp, void *pt QVarType qe_set_variable(EditState *s, const char *name, const char *value, int num) { + QEmacsState *qs = s->qs; void *ptr; VarDef *vp; - vp = qe_find_variable(name); + vp = qe_find_variable(qs, name); if (!vp) { /* Create user variable (global/buffer/window/mode?) */ vp = qe_mallocz(VarDef); @@ -356,7 +356,7 @@ QVarType qe_set_variable(EditState *s, const char *name, vp->value.num = num; vp->type = VAR_NUMBER; } - qe_register_variables(vp, 1); + qe_register_variables(qs, vp, 1); return vp->type; } else if (vp->rw == VAR_RO) { @@ -370,7 +370,7 @@ QVarType qe_set_variable(EditState *s, const char *name, ptr = vp->value.ptr; break; case VAR_STATE: - ptr = (u8*)s->qe_state + vp->value.offset; + ptr = (u8*)qs + vp->value.offset; break; case VAR_BUFFER: ptr = (u8*)s->b + vp->value.offset; @@ -426,11 +426,11 @@ static void do_describe_variable(EditState *s, const char *name) { EditBuffer *b; VarDef *vp; - if ((vp = qe_find_variable(name)) == NULL) { + if ((vp = qe_find_variable(s->qs, name)) == NULL) { put_status(s, "No variable %s", name); return; } - b = new_help_buffer(); + b = new_help_buffer(s); if (!b) return; @@ -446,9 +446,8 @@ static void do_describe_variable(EditState *s, const char *name) { show_popup(s, b, "Help"); } -void qe_register_variables(VarDef *vars, int count) +void qe_register_variables(QEmacsState *qs, VarDef *vars, int count) { - QEmacsState *qs = &qe_state; VarDef *vp; for (vp = vars; vp < vars + count; vp++) { @@ -463,14 +462,13 @@ void qe_register_variables(VarDef *vars, int count) /* should register this as help function */ void qe_list_variables(EditState *s, EditBuffer *b) { - QEmacsState *qs = s->qe_state; char buf[MAX_FILENAME_SIZE]; char typebuf[32]; const char *type; const VarDef *vp; eb_puts(b, "\n variables:\n\n"); - for (vp = qs->first_variable; vp; vp = vp->next) { + for (vp = s->qs->first_variable; vp; vp = vp->next) { /* XXX: merge with variable_print_entry() */ switch (vp->type) { case VAR_NUMBER: @@ -497,14 +495,13 @@ void qe_list_variables(EditState *s, EditBuffer *b) void qe_save_variables(EditState *s, EditBuffer *b) { - QEmacsState *qs = s->qe_state; char buf[MAX_FILENAME_SIZE]; char varname[32], *p; const VarDef *vp; eb_puts(b, "// variables:\n"); /* Only save customized variables */ - for (vp = qs->first_variable; vp; vp = vp->next) { + for (vp = s->qs->first_variable; vp; vp = vp->next) { if (vp->rw != VAR_RW_SAVE || !vp->modified) continue; pstrcpy(varname, countof(varname), vp->name); @@ -569,7 +566,7 @@ int eb_variable_print_entry(EditBuffer *b, VarDef *vp, EditState *s) { } int variable_print_entry(CompleteState *cp, EditState *s, const char *name) { - VarDef *vp = qe_find_variable(name); + VarDef *vp = qe_find_variable(s->qs, name); if (vp) { // XXX: should pass the target window return eb_variable_print_entry(s->b, vp, s); @@ -601,11 +598,11 @@ static const CmdDef var_commands[] = { "s{Describe variable: }[variable]|variable|") }; -static int vars_init(QEmacsState *qs) { - qe_register_variables(var_table, countof(var_table)); - qe_register_commands(NULL, var_commands, countof(var_commands)); - qe_register_completion(&variable_completion); +static int variables_init(QEmacsState *qs) { + qe_register_variables(qs, var_table, countof(var_table)); + qe_register_commands(qs, NULL, var_commands, countof(var_commands)); + qe_register_completion(qs, &variable_completion); return 0; } -qe_module_init(vars_init); +qe_module_init(variables_init); diff --git a/variables.h b/variables.h index b8354a0..0ff0e93 100644 --- a/variables.h +++ b/variables.h @@ -100,7 +100,7 @@ struct VarDef { #define W_VAR(name,fld,type,rw,desc) W_VAR_F(name, fld, type, rw, NULL, desc) #define M_VAR(name,fld,type,rw,desc) M_VAR_F(name, fld, type, rw, NULL, desc) -void qe_register_variables(VarDef *vars, int count); +void qe_register_variables(QEmacsState *qs, VarDef *vars, int count); void variable_complete(CompleteState *cp, CompleteFunc enumerate); int eb_variable_print_entry(EditBuffer *b, VarDef *vp, EditState *s); int variable_print_entry(CompleteState *cp, EditState *s, const char *name); diff --git a/win32.c b/win32.c index fe352d9..3fc3198 100644 --- a/win32.c +++ b/win32.c @@ -38,6 +38,7 @@ typedef struct WinWindow { HWND w; HDC hdc; HFONT font; + QEmacsState *qs; } WinWindow; typedef struct QEEventQ { @@ -128,7 +129,7 @@ static void init_application(void) RegisterClass(&wc); } -static int win_init(QEditScreen *s, int w, int h) +static int win_init(QEditScreen *s, QEmacsState *qs, int w, int h) { int xsize, ysize, font_ysize; TEXTMETRIC tm; @@ -140,7 +141,9 @@ static int win_init(QEditScreen *s, int w, int h) s->priv_data = NULL; s->media = CSS_MEDIA_SCREEN; + s->qs = qs; + win_ctx.qs = qs; win_ctx.font = CreateFont(-12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, FIXED_PITCH, "fixed"); @@ -362,7 +365,7 @@ LRESULT CALLBACK qe_wnd_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) case WM_SIZE: if (wParam != SIZE_MINIMIZED) { - QEmacsState *qs = &qe_state; + QEmacsState *qs = win_ctx.qs; QEEvent ev; qe_event_clear(&ev); @@ -380,7 +383,7 @@ LRESULT CALLBACK qe_wnd_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) saved_hdc = win_ctx.hdc; win_ctx.hdc = ps.hdc; SelectObject(win_ctx.hdc, win_ctx.font); - do_refresh(NULL); + do_refresh(qs->active_window); EndPaint(win_ctx.w, &ps); win_ctx.hdc = saved_hdc; @@ -538,12 +541,13 @@ static QEDisplay win32_dpy = { NULL, /* dpy_describe */ NULL, /* dpy_sound_bell */ NULL, /* dpy_suspend */ + qe_dpy_error, /* dpy_error */ NULL, /* next */ }; static int win32_init(QEmacsState *qs) { - return qe_register_display(&win32_dpy); + return qe_register_display(qs, &win32_dpy); } qe_module_init(win32_init); diff --git a/x11.c b/x11.c index 039d453..8422efc 100644 --- a/x11.c +++ b/x11.c @@ -58,6 +58,7 @@ static void xv_init(QEditScreen *s); static void x11_handle_event(void *opaque); typedef struct X11State { + QEmacsState *qs; Display *display; int xscreen; Window window; @@ -192,7 +193,7 @@ static int x11_dpy_probe(void) return 1; } -static int x11_dpy_init(QEditScreen *s, int w, int h) +static int x11_dpy_init(QEditScreen *s, QEmacsState *qs, int w, int h) { XSizeHints hint; int xsize, ysize; @@ -205,6 +206,11 @@ static int x11_dpy_init(QEditScreen *s, int w, int h) XGCValues gc_val; X11State *xs = qe_mallocz(X11State); + if (xs == NULL) { + fprintf(stderr, "Cannot allocate X11State.\n"); + return -1; + } + s->qs = xs->qs = qs; s->priv_data = xs; s->media = CSS_MEDIA_SCREEN; @@ -691,7 +697,6 @@ static void get_entry(char *buf, int buf_size, const char **pp) static QEFont *x11_dpy_open_font(QEditScreen *s, int style, int size) { - QEmacsState *qs = &qe_state; X11State *xs = s->priv_data; char family[128]; const char *family_list, *p1; @@ -710,7 +715,7 @@ static QEFont *x11_dpy_open_font(QEditScreen *s, int style, int size) font_index = ((style & QE_FONT_FAMILY_MASK) >> QE_FONT_FAMILY_SHIFT) - 1; if ((unsigned)font_index >= NB_FONT_FAMILIES) font_index = 0; /* fixed font is default */ - family_list = qs->system_fonts[font_index]; + family_list = s->qs->system_fonts[font_index]; if (family_list[0] == '\0') family_list = default_x11_fonts[font_index]; @@ -1111,7 +1116,6 @@ static Bool test_event(qe__unused__ Display *dpy, XEvent *ev, static void x11_dpy_selection_request(QEditScreen *s) { X11State *xs = s->priv_data; - QEmacsState *qs = &qe_state; Window w; Atom prop; Atom utf8; @@ -1142,7 +1146,7 @@ static void x11_dpy_selection_request(QEditScreen *s) prop = xev.xselection.property; /* copy GUI selection a new yank buffer */ - b = new_yank_buffer(qs, NULL); + b = qe_new_yank_buffer(s->qs, NULL); eb_set_charset(b, &charset_utf8, EOL_UNIX); nread = 0; @@ -1172,7 +1176,7 @@ static void selection_send(X11State *xs, XSelectionRequestEvent *rq) { static Atom xa_targets = None; static Atom xa_formats[] = { None, None, None, None }; - QEmacsState *qs = &qe_state; + QEmacsState *qs = xs->qs; unsigned char *buf; XEvent ev; EditBuffer *b; @@ -1306,7 +1310,7 @@ static void qe_expose_add(QEditScreen *s, QExposeRegion *rgn, static void qe_expose_flush(QEditScreen *s, QExposeRegion *rgn) { if (rgn->pending) { - QEmacsState *qs = &qe_state; + QEmacsState *qs = s->qs; QEEvent ev1, *ev = qe_event_clear(&ev1); /* Ignore expose region */ @@ -1320,7 +1324,7 @@ static void qe_expose_flush(QEditScreen *s, QExposeRegion *rgn) static void x11_handle_event(void *opaque) { QEditScreen *s = opaque; - QEmacsState *qs = &qe_state; + QEmacsState *qs = s->qs; X11State *xs = s->priv_data; char buf[16]; XEvent xev; @@ -1449,7 +1453,7 @@ static void x11_handle_event(void *opaque) key_state = KEY_STATE_COMMAND; #endif #if 0 - // XXX: should use eb_trace_bytes(buf, out->len, EB_TRACE_KEY); + // XXX: should use qe_trace_bytes(qs, buf, out->len, EB_TRACE_KEY); fprintf(stderr, "keysym=%lx state=%lx%s%s%s len=%d buf[0]='\\x%02x'\n", (long)keysym, (long)xev.xkey.state, (key_state & KEY_STATE_SHIFT) ? " shft" : "", @@ -1948,20 +1952,20 @@ static QEDisplay x11_dpy = { NULL, /* dpy_describe */ NULL, /* dpy_sound_bell */ NULL, /* dpy_suspend */ + qe_dpy_error, /* dpy_error */ NULL, /* next */ }; static void x11_list_fonts(EditState *s, int argval) { - QEmacsState *qs = s->qe_state; - QEditScreen *screen = qs->screen; + QEditScreen *screen = s->qs->screen; X11State *xs = screen->priv_data; char buf[80]; EditBuffer *b; int i, count; char **list; - b = new_help_buffer(); + b = new_help_buffer(s); if (!b) return; @@ -1999,11 +2003,11 @@ static CmdLineOptionDef cmd_options[] = { }; static int x11_init(QEmacsState *qs) { - qe_register_cmd_line_options(cmd_options); - qe_register_commands(NULL, x11_commands, countof(x11_commands)); + qe_register_cmd_line_options(qs, cmd_options); + qe_register_commands(qs, NULL, x11_commands, countof(x11_commands)); if (force_tty) return 0; - return qe_register_display(&x11_dpy); + return qe_register_display(qs, &x11_dpy); } qe_module_init(x11_init);