aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--elisp.c9
-rw-r--r--elisp.h5
-rw-r--r--vterm-module.c36
-rw-r--r--vterm-module.h1
-rw-r--r--vterm.el19
5 files changed, 67 insertions, 3 deletions
diff --git a/elisp.c b/elisp.c
index be61b4a..36d6782 100644
--- a/elisp.c
+++ b/elisp.c
@@ -49,6 +49,15 @@ void put_text_property(emacs_env *env, emacs_value string, emacs_value property,
(emacs_value[]){start, end, property, value, string});
}
+void add_text_properties(emacs_env *env, emacs_value string,
+ emacs_value property) {
+ emacs_value start = env->make_integer(env, 0);
+ emacs_value end = length(env, string);
+
+ env->funcall(env, Fadd_text_properties, 4,
+ (emacs_value[]){start, end, property, string});
+}
+
void erase_buffer(emacs_env *env) { env->funcall(env, Ferase_buffer, 0, NULL); }
void insert(emacs_env *env, emacs_value string) {
diff --git a/elisp.h b/elisp.h
index 53da46b..ab5cc98 100644
--- a/elisp.h
+++ b/elisp.h
@@ -24,6 +24,8 @@ emacs_value Qbar;
emacs_value Qhbar;
emacs_value Qcursor_type;
emacs_value Qemacs_major_version;
+emacs_value Qvterm_line_wrap;
+emacs_value Qrear_nonsticky;
// Emacs functions
emacs_value Fsymbol_value;
@@ -43,6 +45,7 @@ emacs_value Fwindow_body_height;
emacs_value Fpoint;
emacs_value Fput_text_property;
+emacs_value Fadd_text_properties;
emacs_value Fset;
emacs_value Fvterm_flush_output;
emacs_value Fget_buffer_window_list;
@@ -64,6 +67,8 @@ emacs_value list(emacs_env *env, emacs_value elements[], ptrdiff_t len);
emacs_value nth(emacs_env *env, int idx, emacs_value list);
void put_text_property(emacs_env *env, emacs_value string, emacs_value property,
emacs_value value);
+void add_text_properties(emacs_env *env, emacs_value string,
+ emacs_value property);
void erase_buffer(emacs_env *env);
void insert(emacs_env *env, emacs_value string);
void goto_char(emacs_env *env, int pos);
diff --git a/vterm-module.c b/vterm-module.c
index 73330e6..a635427 100644
--- a/vterm-module.c
+++ b/vterm-module.c
@@ -257,6 +257,8 @@ static void refresh_lines(Term *term, emacs_env *env, int start_row,
int offset = 0;
for (i = start_row; i < end_row; i++) {
+
+ int newline = 0;
for (j = 0; j < end_col; j++) {
fetch_cell(term, i, j, &cell);
@@ -270,6 +272,9 @@ static void refresh_lines(Term *term, emacs_env *env, int start_row,
if (cell.chars[0] == 0) {
if (is_eol(term, end_col, i, j)) {
/* This cell is EOL if this and every cell to the right is black */
+ buffer[length] = '\n';
+ length++;
+ newline = 1;
break;
}
buffer[length] = ' ';
@@ -290,8 +295,13 @@ static void refresh_lines(Term *term, emacs_env *env, int start_row,
}
}
- buffer[length] = '\n';
- length++;
+ if (!newline) {
+ emacs_value text = render_text(env, term, buffer, length, &lastCell);
+ insert(env, text);
+ length = 0;
+ text = render_fake_newline(env, term);
+ insert(env, text);
+ }
}
emacs_value text = render_text(env, term, buffer, length, &lastCell);
insert(env, text);
@@ -657,6 +667,21 @@ static emacs_value render_text(emacs_env *env, Term *term, char *buffer,
return text;
}
+static emacs_value render_fake_newline(emacs_env *env, Term *term) {
+
+ emacs_value text;
+ text = env->make_string(env, "\n", 1);
+
+ emacs_value properties;
+
+ properties =
+ list(env, (emacs_value[]){Qvterm_line_wrap, Qt, Qrear_nonsticky, Qt}, 4);
+
+ add_text_properties(env, text, properties);
+
+ return text;
+}
+
static emacs_value color_to_rgb_string(emacs_env *env, Term *term,
VTermColor *color) {
if (VTERM_COLOR_IS_DEFAULT_FG(color)) {
@@ -1129,6 +1154,10 @@ int emacs_module_init(struct emacs_runtime *ert) {
Qextend = env->make_global_ref(env, env->intern(env, ":extend"));
Qemacs_major_version =
env->make_global_ref(env, env->intern(env, "emacs-major-version"));
+ Qvterm_line_wrap =
+ env->make_global_ref(env, env->intern(env, "vterm-line-wrap"));
+ Qrear_nonsticky =
+ env->make_global_ref(env, env->intern(env, "rear-nonsticky"));
Qface = env->make_global_ref(env, env->intern(env, "font-lock-face"));
Qbox = env->make_global_ref(env, env->intern(env, "box"));
@@ -1146,6 +1175,8 @@ int emacs_module_init(struct emacs_runtime *ert) {
Fgoto_char = env->make_global_ref(env, env->intern(env, "goto-char"));
Fput_text_property =
env->make_global_ref(env, env->intern(env, "put-text-property"));
+ Fadd_text_properties =
+ env->make_global_ref(env, env->intern(env, "add-text-properties"));
Fset = env->make_global_ref(env, env->intern(env, "set"));
Fvterm_flush_output =
env->make_global_ref(env, env->intern(env, "vterm--flush-output"));
@@ -1212,7 +1243,6 @@ int emacs_module_init(struct emacs_runtime *ert) {
"Reset cursor postion.", NULL);
bind_function(env, "vterm--reset-point", fun);
-
fun = env->make_function(env, 1, 1, Fvterm_get_icrnl,
"Gets the icrnl state of the pty", NULL);
bind_function(env, "vterm--get-icrnl", fun);
diff --git a/vterm-module.h b/vterm-module.h
index 5be8b49..752d744 100644
--- a/vterm-module.h
+++ b/vterm-module.h
@@ -90,6 +90,7 @@ static bool compare_cells(VTermScreenCell *a, VTermScreenCell *b);
static bool is_key(unsigned char *key, size_t len, char *key_description);
static emacs_value render_text(emacs_env *env, Term *term, char *string,
int len, VTermScreenCell *cell);
+static emacs_value render_fake_newline(emacs_env *env, Term *term);
static emacs_value color_to_rgb_string(emacs_env *env, Term *term,
VTermColor *color);
diff --git a/vterm.el b/vterm.el
index b44300e..0daaf42 100644
--- a/vterm.el
+++ b/vterm.el
@@ -264,6 +264,9 @@ If nil, never delay")
(setq-local hscroll-margin 0)
(setq-local hscroll-step 1)
(setq-local truncate-lines t)
+ (add-function :filter-return
+ (local 'filter-buffer-substring-function)
+ #'vterm--filter-buffer-substring)
(setq vterm--process
(make-process
:name "vterm"
@@ -876,5 +879,21 @@ Effectively toggle between the two positions."
(goto-char prompt-pt)
(beginning-of-line)))))
+(defun vterm--remove-fake-newlines ()
+ (goto-char (point-min))
+ (let (fake-newline)
+ (while (setq fake-newline (next-single-property-change (point)
+ 'vterm-line-wrap))
+ (goto-char fake-newline)
+ (cl-assert (eq ?\n (char-after)))
+ (let ((inhibit-read-only t))
+ (delete-char 1)))))
+
+(defun vterm--filter-buffer-substring (content)
+ (with-temp-buffer
+ (insert content)
+ (vterm--remove-fake-newlines)
+ (buffer-string)))
+
(provide 'vterm)
;;; vterm.el ends here