diff options
| author | jixiufeng <jixiufeng@luojilab.com> | 2018-11-24 00:38:51 +0800 |
|---|---|---|
| committer | jixiufeng <jixiufeng@luojilab.com> | 2018-12-24 10:53:34 +0800 |
| commit | 5a983333ada75a1422108919301eec7ef5a0f7aa (patch) | |
| tree | ee446d787aefbb98c1a4b5dd44de828f54cff4e1 | |
| parent | ec958982b889b4ea65216d70fa8128dcd413256a (diff) | |
Improves performance when receiving large bursts of data.
| -rw-r--r-- | elisp.c | 9 | ||||
| -rw-r--r-- | elisp.h | 4 | ||||
| -rw-r--r-- | vterm-module.c | 19 | ||||
| -rw-r--r-- | vterm-module.h | 2 | ||||
| -rw-r--r-- | vterm.el | 28 |
5 files changed, 57 insertions, 5 deletions
@@ -107,9 +107,11 @@ void delete_lines(emacs_env *env, int linenum, int count, bool del_whole_line) { void recenter(emacs_env *env, emacs_value pos) { env->funcall(env, Frecenter, 1, (emacs_value[]){pos}); } + void forward_char(emacs_env *env, emacs_value n) { env->funcall(env, Fforward_char, 1, (emacs_value[]){n}); } + emacs_value buffer_line_number(emacs_env *env) { return env->funcall(env, Fbuffer_line_number, 0, (emacs_value[]){}); } @@ -143,6 +145,11 @@ emacs_value get_hex_color_bg(emacs_env *env, emacs_value face) { return env->funcall(env, Fvterm_face_color_hex, 2, (emacs_value[]){face, Qbackground}); } + void set_title(emacs_env *env, emacs_value string) { - env->funcall(env, Fvterm_set_title, 1, (emacs_value[]){string}); + env->funcall(env, Fvterm_set_title, 1, (emacs_value[]){string}); +} + +void vterm_invalidate(emacs_env *env) { + env->funcall(env, Fvterm_invalidate, 0, NULL); } @@ -40,6 +40,7 @@ emacs_value Fblink_cursor_mode; emacs_value Fget_buffer_window; emacs_value Fselected_window; emacs_value Fvterm_set_title; +emacs_value Fvterm_invalidate; // Utils void bind_function(emacs_env *env, const char *name, emacs_value Sfun); @@ -68,6 +69,7 @@ void recenter(emacs_env *env, emacs_value pos); void forward_char(emacs_env *env, emacs_value n); emacs_value get_buffer_window(emacs_env *env); emacs_value selected_window(emacs_env *env); -void set_title(emacs_env *env, emacs_value string) ; +void set_title(emacs_env *env, emacs_value string); +void vterm_invalidate(emacs_env *env); #endif /* ELISP_H */ diff --git a/vterm-module.c b/vterm-module.c index e1bbf6d..5f5196f 100644 --- a/vterm-module.c +++ b/vterm-module.c @@ -665,12 +665,19 @@ static emacs_value Fvterm_update(emacs_env *env, ptrdiff_t nargs, // Flush output term_flush_output(term, env); - - term_redraw(term, env); + if (term->is_invalidated) { + vterm_invalidate(env); + } return env->make_integer(env, 0); } +static emacs_value Fvterm_redraw(emacs_env *env, ptrdiff_t nargs, + emacs_value args[], void *data) { + Term *term = env->get_user_ptr(env, args[0]); + term_redraw(term, env); + return env->make_integer(env, 0); +} static emacs_value Fvterm_write_input(emacs_env *env, ptrdiff_t nargs, emacs_value args[], void *data) { Term *term = env->get_user_ptr(env, args[0]); @@ -749,6 +756,9 @@ int emacs_module_init(struct emacs_runtime *ert) { Fvterm_set_title = env->make_global_ref(env, env->intern(env, "vterm--set-title")); + Fvterm_invalidate = + env->make_global_ref(env, env->intern(env, "vterm--invalidate")); + // Faces Qterm = env->make_global_ref(env, env->intern(env, "vterm")); Qterm_color_black = @@ -778,6 +788,11 @@ int emacs_module_init(struct emacs_runtime *ert) { "Process io and update the screen.", NULL); bind_function(env, "vterm--update", fun); + + fun = + env->make_function(env, 1, 1, Fvterm_redraw, "Redraw the screen.", NULL); + bind_function(env, "vterm--redraw", fun); + fun = env->make_function(env, 2, 2, Fvterm_write_input, "Write input to vterm.", NULL); bind_function(env, "vterm--write-input", fun); diff --git a/vterm-module.h b/vterm-module.h index d985033..bd05dc4 100644 --- a/vterm-module.h +++ b/vterm-module.h @@ -87,6 +87,8 @@ static emacs_value Fvterm_new(emacs_env *env, ptrdiff_t nargs, emacs_value args[], void *data); static emacs_value Fvterm_update(emacs_env *env, ptrdiff_t nargs, emacs_value args[], void *data); +static emacs_value Fvterm_redraw(emacs_env *env, ptrdiff_t nargs, + emacs_value args[], void *data); int emacs_module_init(struct emacs_runtime *ert); #endif /* VTERM_MODULE_H */ @@ -81,6 +81,7 @@ for different shell. " :type 'hook :group 'vterm) + (defface vterm '((t :inherit default)) "Default face to use in Term mode." @@ -146,7 +147,8 @@ for different shell. " (setq-local scroll-margin 0) (add-hook 'window-size-change-functions #'vterm--window-size-change t t) - (let ((process-environment (append '("TERM=xterm") process-environment))) + (let ((process-environment (append '("TERM=xterm") process-environment)) + (process-adaptive-read-buffering nil)) (setq vterm--process (make-process :name "vterm" @@ -225,6 +227,30 @@ for different shell. " (dolist (char (string-to-list string)) (vterm--update vterm--term (char-to-string char) nil nil nil)))) +(defvar vterm--redraw-timer nil) +(make-variable-buffer-local 'vterm--redraw-timer) + +(defvar vterm-timer-delay 0.01 + "Delay for refreshing the terminal buffer after receiving updates from +libvterm. Improves performance when receiving large bursts of data. +If nil, never delay") + +(defun vterm--invalidate() + (if vterm-timer-delay + (unless vterm--redraw-timer + (setq vterm--redraw-timer + (run-with-timer vterm-timer-delay nil + #'vterm--delayed-redraw (current-buffer)))) + (vterm--delayed-redraw (current-buffer)))) + +(defun vterm--delayed-redraw(buffer) + (with-current-buffer buffer + (let ((inhibit-redisplay t) + (inhibit-read-only t)) + (when vterm--term + (vterm--redraw vterm--term))) + (setq vterm--redraw-timer nil))) + ;;;###autoload (defun vterm () "Create a new vterm." |
