diff options
| -rw-r--r-- | vterm-module.c | 34 | ||||
| -rw-r--r-- | vterm-module.h | 3 | ||||
| -rw-r--r-- | vterm.el | 17 |
3 files changed, 54 insertions, 0 deletions
diff --git a/vterm-module.c b/vterm-module.c index 512d973..1fcaad6 100644 --- a/vterm-module.c +++ b/vterm-module.c @@ -13,6 +13,7 @@ static LineInfo *alloc_lineinfo() { LineInfo *info = malloc(sizeof(LineInfo)); info->directory = NULL; + info->prompt_col = -1; return info; } void free_lineinfo(LineInfo *line) { @@ -853,6 +854,11 @@ static int osc_callback(const char *command, size_t cmdlen, void *user) { } term->lines[i]->directory = malloc(cmdlen - 4 + 1); strcpy(term->lines[i]->directory, &buffer[4]); + if (i == term->cursor.row) { + term->lines[i]->prompt_col = term->cursor.col; + } else { + term->lines[i]->prompt_col = -1; + } } return 1; } else if (cmdlen > 4 && buffer[0] == '5' && buffer[1] == '1' && @@ -1047,6 +1053,27 @@ emacs_value Fvterm_get_icrnl(emacs_env *env, ptrdiff_t nargs, return Qnil; } +emacs_value Fvterm_get_prompt_point(emacs_env *env, ptrdiff_t nargs, + emacs_value args[], void *data) { + Term *term = env->get_user_ptr(env, args[0]); + int linenum = env->extract_integer(env, args[1]); + if (linenum >= term->linenum) { + linenum = term->linenum; + } + for (int l = linenum; l >= 1; l--) { + int cur_row = linenr_to_row(term, l); + LineInfo *info = get_lineinfo(term, cur_row); + if (info != NULL && info->prompt_col >= 0) { + goto_line(env, l); + size_t offset = get_col_offset(term, cur_row, info->prompt_col); + forward_char(env, env->make_integer(env, info->prompt_col - offset)); + + return point(env); + } + } + return Qnil; +} + emacs_value Fvterm_reset_cursor_point(emacs_env *env, ptrdiff_t nargs, emacs_value args[], void *data) { Term *term = env->get_user_ptr(env, args[0]); @@ -1145,6 +1172,13 @@ int emacs_module_init(struct emacs_runtime *ert) { fun = env->make_function(env, 2, 2, Fvterm_get_pwd, "Get the working directory of at line n.", NULL); bind_function(env, "vterm--get-pwd-raw", fun); + fun = env->make_function(env, 2, 2, Fvterm_get_prompt_point, + "Get the end postion of current prompt.", NULL); + bind_function(env, "vterm--get-prompt-point-internal", fun); + fun = env->make_function(env, 1, 1, Fvterm_reset_cursor_point, + "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); diff --git a/vterm-module.h b/vterm-module.h index 1680000..57450f4 100644 --- a/vterm-module.h +++ b/vterm-module.h @@ -20,6 +20,7 @@ int plugin_is_GPL_compatible; typedef struct LineInfo { char *directory; /* working directory */ + int prompt_col; /* end column of the prompt,if current line contains prompt */ } LineInfo; typedef struct ScrollbackLine { @@ -119,6 +120,8 @@ emacs_value Fvterm_get_icrnl(emacs_env *env, ptrdiff_t nargs, emacs_value Fvterm_get_pwd(emacs_env *env, ptrdiff_t nargs, emacs_value args[], void *data); +emacs_value Fvterm_get_prompt_point(emacs_env *env, ptrdiff_t nargs, + emacs_value args[], void *data); emacs_value Fvterm_reset_cursor_point(emacs_env *env, ptrdiff_t nargs, emacs_value args[], void *data); @@ -760,6 +760,14 @@ the called functions." (apply (cadr f) args) (message "Failed to find command: %s" command)))) +(defun vterm--get-prompt-point () + "Get the position of the end of current prompt." + (let (pt) + (save-excursion + (setq pt (vterm--get-prompt-point-internal + vterm--term (line-number-at-pos)))) + pt)) + (defun vterm-reset-cursor-point () "Make sure the cursor at the right postion." (interactive) @@ -771,5 +779,14 @@ the called functions." (vterm-reset-cursor-point))) +(defun vterm--at-prompt-p () + "Check whether the cursor postion is at shell prompt or not." + (let ((pt (point)) + (term-cursor-pt (vterm--get-cursor-point)) + (prompt-pt (vterm--get-prompt-point))) + (unless prompt-pt + (user-error "vterm--at-prompt-p error,Please search `vterm_prompt_end' in the README.md")) + (= pt term-cursor-pt (or prompt-pt 0)))) + (provide 'vterm) ;;; vterm.el ends here |
