aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vterm-module.c34
-rw-r--r--vterm-module.h3
-rw-r--r--vterm.el17
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);
diff --git a/vterm.el b/vterm.el
index 2e9e974..963a826 100644
--- a/vterm.el
+++ b/vterm.el
@@ -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