aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Fürmetz <fuermetz@mailbox.org>2019-01-22 22:46:41 +0100
committerGitHub <noreply@github.com>2019-01-22 22:46:41 +0100
commit777d215db8d94746fe555ec2f8e794e78fb504dc (patch)
tree0bde6172bf1340b2ef2032b9a35d0e8c66b21efb
parentc339f7f8234f55096981411e215423538b9c11a8 (diff)
parent5a983333ada75a1422108919301eec7ef5a0f7aa (diff)
Merge pull request #39 from jixiuf/performance-improve
Improves performance when receiving large bursts of data.
-rw-r--r--elisp.c9
-rw-r--r--elisp.h4
-rw-r--r--vterm-module.c19
-rw-r--r--vterm-module.h2
-rw-r--r--vterm.el28
5 files changed, 57 insertions, 5 deletions
diff --git a/elisp.c b/elisp.c
index e132262..69599ae 100644
--- a/elisp.c
+++ b/elisp.c
@@ -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);
}
diff --git a/elisp.h b/elisp.h
index c200754..07fc6d5 100644
--- a/elisp.h
+++ b/elisp.h
@@ -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 */
diff --git a/vterm.el b/vterm.el
index ba42192..2641d76 100644
--- a/vterm.el
+++ b/vterm.el
@@ -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"
@@ -227,6 +229,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."