aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Fürmetz <fuermetz@mailbox.org>2017-07-27 14:18:30 +0200
committerLukas Fürmetz <fuermetz@mailbox.org>2017-07-27 14:18:30 +0200
commitd35f9d9030c33cdc0e89763d0eca30a54f31a65d (patch)
treeecc416b8046ac2b2a73caf195833f2b5189772a0
parent2f0c340d8923284fdcd6e1eeac9db724103c84ed (diff)
Implement dynamic window size change
-rw-r--r--vterm-module.c26
-rw-r--r--vterm-module.h2
-rw-r--r--vterm.el10
3 files changed, 35 insertions, 3 deletions
diff --git a/vterm-module.c b/vterm-module.c
index 6f169c2..465fa27 100644
--- a/vterm-module.c
+++ b/vterm-module.c
@@ -173,7 +173,7 @@ static void vterm_redraw(VTerm *vt, emacs_env *env) {
erase_buffer(env);
- char buffer[rows * cols];
+ char buffer[(rows + 1) * cols];
int length = 0;
VTermScreenCell cell;
VTermScreenCell lastCell;
@@ -208,7 +208,7 @@ static void vterm_redraw(VTerm *vt, emacs_env *env) {
// row * (width + 1) because of newline character
// col + 1 because (goto-char 1) sets point to first position
- int point = (pos.row * 81) + pos.col + 1;
+ int point = (pos.row * (cols + 1)) + pos.col + 1;
goto_char(env, point);
}
@@ -358,6 +358,24 @@ static emacs_value Fvterm_kill(emacs_env *env, ptrdiff_t nargs,
return env->intern(env, "nil");
}
+static emacs_value Fvterm_set_size(emacs_env *env, ptrdiff_t nargs,
+ emacs_value args[], void *data) {
+ struct Term *term = env->get_user_ptr(env, args[0]);
+ int rows = env->extract_integer(env, args[1]);
+ int cols = env->extract_integer(env, args[2]);
+
+ int old_rows, old_cols;
+ vterm_get_size(term->vt, &old_rows, &old_cols);
+
+ if (cols != old_cols || rows != old_rows) {
+ struct winsize size = {rows, cols, 0, 0};
+ ioctl(term->masterfd, TIOCSWINSZ, &size);
+ vterm_set_size(term->vt, rows, cols);
+ }
+
+ return env->intern(env, "nil");
+}
+
int emacs_module_init(struct emacs_runtime *ert) {
emacs_env *env = ert->get_environment(ert);
emacs_value fun;
@@ -374,6 +392,10 @@ int emacs_module_init(struct emacs_runtime *ert) {
"Kill the the shell process.", NULL);
bind_function(env, "vterm-kill", fun);
+ fun = env->make_function(env, 3, 3, Fvterm_set_size,
+ "Sets the size of the terminal.", NULL);
+ bind_function(env, "vterm-set-size", fun);
+
provide(env, "vterm-module");
return 0;
diff --git a/vterm-module.h b/vterm-module.h
index 2af8d47..57a2381 100644
--- a/vterm-module.h
+++ b/vterm-module.h
@@ -36,4 +36,6 @@ static emacs_value Fvterm_update(emacs_env *env, ptrdiff_t nargs,
emacs_value args[], void *data);
static emacs_value Fvterm_kill(emacs_env *env, ptrdiff_t nargs,
emacs_value args[], void *data);
+static emacs_value Fvterm_set_size(emacs_env *env, ptrdiff_t nargs,
+ emacs_value args[], void *data);
int emacs_module_init(struct emacs_runtime *ert);
diff --git a/vterm.el b/vterm.el
index 8381f0b..e109560 100644
--- a/vterm.el
+++ b/vterm.el
@@ -23,7 +23,8 @@ be send to the terminal.")
buffer-read-only t)
(setq-local scroll-conservatively 101)
(setq-local scroll-margin 0)
- (add-hook 'kill-buffer-hook #'vterm-kill-buffer-hook t t))
+ (add-hook 'kill-buffer-hook #'vterm-kill-buffer-hook t t)
+ (add-hook 'window-size-change-functions #'vterm-window-size-change t t))
;; Keybindings
(define-key vterm-mode-map [t] #'vterm-self-insert)
@@ -71,4 +72,11 @@ be send to the terminal.")
(cancel-timer vterm-timer)
(vterm-kill vterm-term)))
+(defun vterm-window-size-change (frame)
+ (dolist (window (window-list frame 1))
+ (let ((buffer (window-buffer window)))
+ (with-current-buffer buffer
+ (when (eq major-mode 'vterm-mode)
+ (vterm-set-size vterm-term (window-height) (window-width)))))))
+
(provide 'vterm)