aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vterm-module.c73
-rw-r--r--vterm-module.h27
-rw-r--r--vterm.el26
3 files changed, 83 insertions, 43 deletions
diff --git a/vterm-module.c b/vterm-module.c
index 7d44293..edf8237 100644
--- a/vterm-module.c
+++ b/vterm-module.c
@@ -2,9 +2,11 @@
#include "elisp.h"
#include "utf8.h"
#include <assert.h>
+#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
+#include <termios.h>
#include <unistd.h>
#include <vterm.h>
@@ -528,13 +530,24 @@ static void term_flush_output(Term *term, emacs_env *env) {
static void term_process_key(Term *term, unsigned char *key, size_t len,
VTermModifier modifier) {
if (is_key(key, len, "<return>")) {
- vterm_keyboard_key(term->vt, VTERM_KEY_ENTER, modifier);
+ if (term->pty_fd > 0) {
+ struct termios keys;
+ tcgetattr(term->pty_fd, &keys);
+ if (keys.c_iflag & ICRNL)
+ vterm_keyboard_unichar(term->vt, 10, modifier);
+ else
+ vterm_keyboard_unichar(term->vt, 13, modifier);
+ } else {
+ vterm_keyboard_key(term->vt, VTERM_KEY_ENTER, modifier);
+ }
} else if (is_key(key, len, "<start_paste>")) {
vterm_keyboard_start_paste(term->vt);
} else if (is_key(key, len, "<end_paste>")) {
vterm_keyboard_end_paste(term->vt);
} else if (is_key(key, len, "<tab>")) {
vterm_keyboard_key(term->vt, VTERM_KEY_TAB, modifier);
+ } else if (is_key(key, len, "<backtab>") || is_key(key, len, "<iso-lefttab>")) {
+ vterm_keyboard_key(term->vt, VTERM_KEY_TAB, VTERM_MOD_SHIFT);
} else if (is_key(key, len, "<backspace>")) {
vterm_keyboard_key(term->vt, VTERM_KEY_BACKSPACE, modifier);
} else if (is_key(key, len, "<escape>")) {
@@ -593,17 +606,7 @@ static void term_process_key(Term *term, unsigned char *key, size_t len,
}
}
-static void term_put_caret(Term *term, emacs_env *env, int row, int col,
- int offset) {
- int rows, cols;
- vterm_get_size(term->vt, &rows, &cols);
- // row * (cols + 1) because of newline character
- // col + 1 because (goto-char 1) sets point to first position
- int point = ((row + term->sb_current) * (cols + 1)) + col + 1 + offset;
- goto_char(env, point);
-}
-
-static void term_finalize(void *object) {
+void term_finalize(void *object) {
Term *term = (Term *)object;
for (int i = 0; i < term->sb_current; i++) {
free(term->sb_buffer[i]);
@@ -613,13 +616,17 @@ static void term_finalize(void *object) {
term->title = NULL;
}
+ if (term->pty_fd > 0) {
+ close(term->pty_fd);
+ }
+
free(term->sb_buffer);
vterm_free(term->vt);
free(term);
}
-static emacs_value Fvterm_new(emacs_env *env, ptrdiff_t nargs,
- emacs_value args[], void *data) {
+emacs_value Fvterm_new(emacs_env *env, ptrdiff_t nargs, emacs_value args[],
+ void *data) {
Term *term = malloc(sizeof(Term));
int rows = env->extract_integer(env, args[0]);
@@ -642,6 +649,7 @@ static emacs_value Fvterm_new(emacs_env *env, ptrdiff_t nargs,
term->invalid_end = rows;
term->width = cols;
term->height = rows;
+ term->pty_fd = -1;
term->title = NULL;
term->is_title_changed = false;
@@ -649,8 +657,8 @@ static emacs_value Fvterm_new(emacs_env *env, ptrdiff_t nargs,
return env->make_user_ptr(env, term_finalize, term);
}
-static emacs_value Fvterm_update(emacs_env *env, ptrdiff_t nargs,
- emacs_value args[], void *data) {
+emacs_value Fvterm_update(emacs_env *env, ptrdiff_t nargs, emacs_value args[],
+ void *data) {
Term *term = env->get_user_ptr(env, args[0]);
// Process keys
@@ -679,14 +687,15 @@ static emacs_value Fvterm_update(emacs_env *env, ptrdiff_t nargs,
return env->make_integer(env, 0);
}
-static emacs_value Fvterm_redraw(emacs_env *env, ptrdiff_t nargs,
- emacs_value args[], void *data) {
+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) {
+
+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]);
ptrdiff_t len = string_bytes(env, args[1]);
char bytes[len];
@@ -699,8 +708,8 @@ static emacs_value Fvterm_write_input(emacs_env *env, ptrdiff_t nargs,
return env->make_integer(env, 0);
}
-static emacs_value Fvterm_set_size(emacs_env *env, ptrdiff_t nargs,
- emacs_value args[], void *data) {
+emacs_value Fvterm_set_size(emacs_env *env, ptrdiff_t nargs, emacs_value args[],
+ void *data) {
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]);
@@ -714,6 +723,22 @@ static emacs_value Fvterm_set_size(emacs_env *env, ptrdiff_t nargs,
return Qnil;
}
+
+emacs_value Fvterm_set_pty_name(emacs_env *env, ptrdiff_t nargs,
+ emacs_value args[], void *data) {
+ Term *term = env->get_user_ptr(env, args[0]);
+
+ if (nargs > 1) {
+ ptrdiff_t len = string_bytes(env, args[1]);
+ char filename[len];
+
+ env->copy_string_contents(env, args[1], filename, &len);
+
+ term->pty_fd = open(filename, O_RDONLY);
+ }
+ return Qnil;
+}
+
int emacs_module_init(struct emacs_runtime *ert) {
emacs_env *env = ert->get_environment(ert);
@@ -794,6 +819,10 @@ int emacs_module_init(struct emacs_runtime *ert) {
"Sets the size of the terminal.", NULL);
bind_function(env, "vterm--set-size", fun);
+ fun = env->make_function(env, 2, 2, Fvterm_set_pty_name,
+ "Sets the name of the pty.", NULL);
+ bind_function(env, "vterm--set-pty-name", fun);
+
provide(env, "vterm-module");
return 0;
diff --git a/vterm-module.h b/vterm-module.h
index 356a6dd..ca0bcb5 100644
--- a/vterm-module.h
+++ b/vterm-module.h
@@ -59,6 +59,8 @@ typedef struct Term {
bool is_title_changed;
int width, height;
+
+ int pty_fd;
} Term;
static bool compare_cells(VTermScreenCell *a, VTermScreenCell *b);
@@ -74,18 +76,23 @@ static void term_redraw(Term *term, emacs_env *env);
static void term_flush_output(Term *term, emacs_env *env);
static void term_process_key(Term *term, unsigned char *key, size_t len,
VTermModifier modifier);
-static void term_put_caret(Term *term, emacs_env *env, int row, int col,
- int offset);
static void invalidate_terminal(Term *term, int start_row, int end_row);
static void refresh_size(Term *term);
-static void term_finalize(void *object);
-
-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);
+void term_finalize(void *object);
+
+emacs_value Fvterm_new(emacs_env *env, ptrdiff_t nargs, emacs_value args[],
+ void *data);
+emacs_value Fvterm_update(emacs_env *env, ptrdiff_t nargs, emacs_value args[],
+ void *data);
+emacs_value Fvterm_redraw(emacs_env *env, ptrdiff_t nargs, emacs_value args[],
+ void *data);
+emacs_value Fvterm_write_input(emacs_env *env, ptrdiff_t nargs,
+ emacs_value args[], void *data);
+emacs_value Fvterm_set_size(emacs_env *env, ptrdiff_t nargs, emacs_value args[],
+ void *data);
+emacs_value Fvterm_set_pty_name(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 560aa75..0f391be 100644
--- a/vterm.el
+++ b/vterm.el
@@ -232,20 +232,22 @@ If nil, never delay")
:name "vterm"
:buffer (current-buffer)
:command `("/bin/sh" "-c"
- ,(format "stty -nl sane iutf8 rows %d columns %d >/dev/null && exec %s"
+ ,(format "stty -nl sane iutf8 erase ^? rows %d columns %d >/dev/null && exec %s"
(window-body-height)
(window-body-width)
vterm-shell))
:coding 'no-conversion
:connection-type 'pty
:filter #'vterm--filter
- :sentinel (when vterm-exit-functions #'vterm--sentinel)))))
+ :sentinel (when vterm-exit-functions #'vterm--sentinel))))
+ (vterm--set-pty-name vterm--term (process-tty-name vterm--process)))
;; Keybindings
(define-key vterm-mode-map [tab] #'vterm--self-insert)
+(define-key vterm-mode-map [backtab] #'vterm--self-insert)
(define-key vterm-mode-map [backspace] #'vterm--self-insert)
(define-key vterm-mode-map [M-backspace] #'vterm--self-insert)
-(define-key vterm-mode-map [return] #'vterm-send-return)
+(define-key vterm-mode-map [return] #'vterm--self-insert)
(define-key vterm-mode-map [left] #'vterm--self-insert)
(define-key vterm-mode-map [right] #'vterm--self-insert)
(define-key vterm-mode-map [up] #'vterm--self-insert)
@@ -274,6 +276,15 @@ If nil, never delay")
unless (member key vterm-keymap-exceptions)
collect key))))
+(defun vterm-event-basic-type (event)
+ "Same as `event-basic-type', except the downcasing of EVENT."
+ (if (consp event)
+ (setq event (car event)))
+ (if (symbolp event)
+ (car (get event 'event-symbol-elements))
+ (let* ((base (logand event (1- ?\A-\^@))))
+ (if (< base 32) (logior base 64) base))))
+
(defun vterm--self-insert ()
"Sends invoking key to libvterm."
(interactive)
@@ -282,7 +293,7 @@ If nil, never delay")
(shift (memq 'shift modifiers))
(meta (memq 'meta modifiers))
(ctrl (memq 'control modifiers)))
- (when-let ((key (key-description (vector (event-basic-type last-input-event)))))
+ (when-let ((key (key-description (vector (vterm-event-basic-type last-input-event)))))
(vterm-send-key key shift meta ctrl)))))
(defun vterm-send-key (key &optional shift meta ctrl)
@@ -290,8 +301,6 @@ If nil, never delay")
(when vterm--term
(let ((inhibit-redisplay t)
(inhibit-read-only t))
- (when (and shift (not meta) (not ctrl))
- (setq key (upcase key)))
(vterm--update vterm--term key shift meta ctrl))))
(defun vterm-send-ctrl-c ()
@@ -304,11 +313,6 @@ If nil, never delay")
(interactive)
(vterm-send-key "_" nil nil t))
-(defun vterm-send-return ()
- "Sends C-m to the libvterm."
- (interactive)
- (process-send-string vterm--process "\C-m"))
-
(defun vterm-yank ()
"Implementation of `yank' (paste) in vterm."
(interactive)