diff options
| author | Lukas Fürmetz <fuermetz@mailbox.org> | 2019-08-03 15:35:39 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-08-03 15:35:39 +0200 |
| commit | 887025823b22a3ca5cdaacbba6e0bf771a68b154 (patch) | |
| tree | 57bccec4d8fb93956791a8a0eb8b7c42881f549a /vterm-module.c | |
| parent | 3d0b5e4c46e66b37b258e948469f7c010d49c077 (diff) | |
| parent | dd012fa9986171221c0bce9d9fdb64332e1044a1 (diff) | |
Merge pull request #110 from akermu/directory_tracking
Add directory tracking via OSC callback
Diffstat (limited to 'vterm-module.c')
| -rw-r--r-- | vterm-module.c | 62 |
1 files changed, 58 insertions, 4 deletions
diff --git a/vterm-module.c b/vterm-module.c index 4ec78dc..21ace5f 100644 --- a/vterm-module.c +++ b/vterm-module.c @@ -376,6 +376,7 @@ static void term_redraw_cursor(Term *term, emacs_env *env) { static void term_redraw(Term *term, emacs_env *env) { term_redraw_cursor(term, env); + if (term->is_invalidated) { long bufline_before = env->extract_integer(env, buffer_line_number(env)); refresh_scrollback(term, env); @@ -384,10 +385,17 @@ static void term_redraw(Term *term, emacs_env *env) { env->extract_integer(env, buffer_line_number(env)) - bufline_before; adjust_topline(term, env, line_added); } - if (term->is_title_changed) { + + if (term->title_changed) { set_title(env, env->make_string(env, term->title, strlen(term->title))); - term->is_title_changed = false; + term->title_changed = false; + } + + if (term->directory_changed) { + set_directory(env, env->make_string(env, term->directory, strlen(term->directory))); + term->directory_changed = false; } + term->is_invalidated = false; } @@ -417,6 +425,7 @@ static bool is_key(unsigned char *key, size_t len, char *key_description) { return (len == strlen(key_description) && memcmp(key, key_description, len) == 0); } + static void term_set_title(Term *term, char *title) { size_t len = strlen(title); if (term->title) { @@ -425,7 +434,7 @@ static void term_set_title(Term *term, char *title) { term->title = malloc(sizeof(char) * (len + 1)); strncpy(term->title, title, len); term->title[len] = 0; - term->is_title_changed = true; + term->title_changed = true; return; } @@ -621,6 +630,11 @@ void term_finalize(void *object) { term->title = NULL; } + if (term->directory) { + free(term->directory); + term->directory = NULL; + } + if (term->pty_fd > 0) { close(term->pty_fd); } @@ -630,6 +644,37 @@ void term_finalize(void *object) { free(term); } +static int osc_callback(const char *command, size_t cmdlen, void *user) +{ + Term *term = (Term *) user; + char buffer[cmdlen + 1]; + + buffer[cmdlen] = '\0'; + memcpy(buffer, command, cmdlen); + + if (term->directory != NULL) { + free(term->directory); + term->directory = NULL; + } + + if (cmdlen > 3 && buffer[0] == '5' && buffer[1] == '1' && buffer[2] == ';') { + term->directory = malloc(cmdlen - 3 + 1); + strcpy(term->directory, &buffer[3]); + term->directory_changed = true; + return 1; + } + return 0; +} + +static VTermParserCallbacks parser_callbacks = { + .text = NULL, + .control = NULL, + .escape = NULL, + .csi = NULL, + .osc = &osc_callback, + .dcs = NULL, +}; + emacs_value Fvterm_new(emacs_env *env, ptrdiff_t nargs, emacs_value args[], void *data) { Term *term = malloc(sizeof(Term)); @@ -642,6 +687,10 @@ emacs_value Fvterm_new(emacs_env *env, ptrdiff_t nargs, emacs_value args[], vterm_set_utf8(term->vt, 1); term->vts = vterm_obtain_screen(term->vt); + + VTermState *state = vterm_obtain_state(term->vt); + vterm_state_set_unrecognised_fallbacks(state, &parser_callbacks, term); + vterm_screen_reset(term->vts, 1); vterm_screen_set_callbacks(term->vts, &vterm_screen_callbacks, term); vterm_screen_set_damage_merge(term->vts, VTERM_DAMAGE_SCROLL); @@ -657,7 +706,10 @@ emacs_value Fvterm_new(emacs_env *env, ptrdiff_t nargs, emacs_value args[], term->pty_fd = -1; term->title = NULL; - term->is_title_changed = false; + term->title_changed = false; + + term->directory = NULL; + term->directory_changed = false; return env->make_user_ptr(env, term_finalize, term); } @@ -796,6 +848,8 @@ int emacs_module_init(struct emacs_runtime *ert) { Fvterm_set_title = env->make_global_ref(env, env->intern(env, "vterm--set-title")); + Fvterm_set_directory = + env->make_global_ref(env, env->intern(env, "vterm--set-directory")); Fvterm_invalidate = env->make_global_ref(env, env->intern(env, "vterm--invalidate")); Feq = env->make_global_ref(env, env->intern(env, "eq")); |
