From f133e554ff80191fd8e2eed3c8d68669e8c44764 Mon Sep 17 00:00:00 2001 From: jixiuf Date: Tue, 15 Oct 2019 23:02:52 +0800 Subject: Support sending Elisp Command to Emacs Buffer --- README.md | 9 +++++++++ elisp.c | 4 ++++ elisp.h | 2 ++ vterm-module.c | 22 ++++++++++++++++++++++ vterm-module.h | 3 +++ vterm.el | 7 +++++++ 6 files changed, 47 insertions(+) diff --git a/README.md b/README.md index 07fe24a..406ddd3 100644 --- a/README.md +++ b/README.md @@ -167,6 +167,15 @@ function chpwd() { } ``` +## Send Elisp Command +```sh +if [[ "$INSIDE_EMACS" = 'vterm' ]]; then + function vi(){ + echo -n "\e]51;E(find-file \"$@\")\e\\" + } +fi + +``` ## Related packages - [vterm-toggle](https://github.com/jixiuf/vterm-toggle): Toggles between a vterm and the current buffer diff --git a/elisp.c b/elisp.c index e57f43f..36705b8 100644 --- a/elisp.c +++ b/elisp.c @@ -126,3 +126,7 @@ void set_directory(emacs_env *env, emacs_value string) { void vterm_invalidate(emacs_env *env) { env->funcall(env, Fvterm_invalidate, 0, NULL); } +emacs_value vterm_eval(emacs_env *env, emacs_value string){ + return env->funcall(env, Fvterm_eval, 1, (emacs_value[]){string}); + +} diff --git a/elisp.h b/elisp.h index ebc2fcb..efee3d3 100644 --- a/elisp.h +++ b/elisp.h @@ -49,6 +49,7 @@ emacs_value Fvterm_set_directory; emacs_value Fvterm_invalidate; emacs_value Feq; emacs_value Fvterm_get_color; +emacs_value Fvterm_eval; // Utils void bind_function(emacs_env *env, const char *name, emacs_value Sfun); @@ -78,5 +79,6 @@ void set_title(emacs_env *env, emacs_value string); void set_directory(emacs_env *env, emacs_value string); void vterm_invalidate(emacs_env *env); emacs_value vterm_get_color(emacs_env *env, int index); +emacs_value vterm_eval(emacs_env *env, emacs_value string); #endif /* ELISP_H */ diff --git a/vterm-module.c b/vterm-module.c index 43b2163..e0a3fb6 100644 --- a/vterm-module.c +++ b/vterm-module.c @@ -426,6 +426,14 @@ static void term_redraw(Term *term, emacs_env *env) { env, env->make_string(env, term->directory, strlen(term->directory))); term->directory_changed = false; } + if (term->elisp_code_changed) { + term->elisp_code_changed = false; + emacs_value elisp_code = + env->make_string(env, term->elisp_code, strlen(term->elisp_code)); + vterm_eval(env, elisp_code); + free(term->elisp_code); + term->elisp_code = NULL; + } term->is_invalidated = false; } @@ -669,6 +677,10 @@ void term_finalize(void *object) { free(term->directory); term->directory = NULL; } + if (term->elisp_code) { + free(term->elisp_code); + term->elisp_code = NULL; + } if (term->pty_fd > 0) { close(term->pty_fd); @@ -696,6 +708,12 @@ static int osc_callback(const char *command, size_t cmdlen, void *user) { strcpy(term->directory, &buffer[4]); term->directory_changed = true; return 1; + } else if (cmdlen > 4 && buffer[0] == '5' && buffer[1] == '1' && + buffer[2] == ';' && buffer[3] == 'E') { + term->elisp_code = malloc(cmdlen - 4 + 1); + strcpy(term->elisp_code, &buffer[4]); + term->elisp_code_changed = true; + return 1; } return 0; } @@ -753,6 +771,8 @@ emacs_value Fvterm_new(emacs_env *env, ptrdiff_t nargs, emacs_value args[], term->directory = NULL; term->directory_changed = false; + term->elisp_code = NULL; + term->elisp_code_changed = false; return env->make_user_ptr(env, term_finalize, term); } @@ -903,6 +923,8 @@ int emacs_module_init(struct emacs_runtime *ert) { Feq = env->make_global_ref(env, env->intern(env, "eq")); Fvterm_get_color = env->make_global_ref(env, env->intern(env, "vterm--get-color")); + Fvterm_eval = + env->make_global_ref(env, env->intern(env, "vterm--eval")); // Exported functions emacs_value fun; diff --git a/vterm-module.h b/vterm-module.h index 1c8ae34..4d9b1a6 100644 --- a/vterm-module.h +++ b/vterm-module.h @@ -64,6 +64,9 @@ typedef struct Term { char *directory; bool directory_changed; + char *elisp_code; + bool elisp_code_changed; + int width, height; int height_resize; diff --git a/vterm.el b/vterm.el index 9dc546c..8e103a8 100644 --- a/vterm.el +++ b/vterm.el @@ -623,5 +623,12 @@ Argument INDEX index of color." (t ;-2 background (face-background 'vterm-color-default nil 'default)))) +(defun vterm--eval(str) + "evaluate Elisp code contained in a string. +Argument STR Elisp code." + (eval (car (read-from-string + (format "(progn %s)" str))))) + + (provide 'vterm) ;;; vterm.el ends here -- cgit v1.0