[vim/vim] Add history to prompt buffer (PR #19700)

11 views
Skip to first unread message

Foxe Chen

unread,
Mar 15, 2026, 1:25:13 PM (2 days ago) Mar 15
to vim/vim, Subscribed

Fixes #5010. Adds history to the prompt buffer, like a command line shell. Will add tests later

cc @puremourning what are your thoughts on this? Thanks.


You can view, comment on, or merge this pull request online at:

  https://github.com/vim/vim/pull/19700

Commit Summary

  • 20e4612 add history to prompt buffer

File Changes

(11 files)

Patch Links:


Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/19700@github.com>

zeertzjq

unread,
Mar 15, 2026, 7:11:53 PM (2 days ago) Mar 15
to vim/vim, Subscribed

@zeertzjq commented on this pull request.


In runtime/doc/builtin.txt:

> @@ -8434,6 +8444,27 @@ printf({fmt}, {expr1} ...)				*printf()*
 
 		Return type: |String|
 
+prompt_gethistory({buf}, [, {max}])			*prompt_gethistory*
⬇️ Suggested change
-prompt_gethistory({buf}, [, {max}])			*prompt_gethistory*
+prompt_gethistory({buf} [, {max}])			*prompt_gethistory()*

In runtime/doc/builtin.txt:

> @@ -8449,6 +8480,69 @@ prompt_getprompt({buf})					*prompt_getprompt()*
 
 		{only available when compiled with the |+channel| feature}
 
+prompt_histgoto({buf}, {offset}, [, {relative}])	*prompt_histgoto*
⬇️ Suggested change
-prompt_histgoto({buf}, {offset}, [, {relative}])	*prompt_histgoto*
+prompt_histgoto({buf}, {offset} [, {relative}])		*prompt_histgoto()*

In runtime/doc/builtin.txt:

> +		moving through the prompt history.
+
+		In both cases, the values will be clamped between the maximum
+		and minimum possible offsets or indexes.
+
+		By default if not provided, "relative" is true.  Returns true
+		if position in history moved.
+
+		Can also be used as a |method|: >
+			GetBuffer()->prompt_histgoto()
+<
+		Return type: |Bool|
+
+		{only available when compiled with the |+channel| feature}
+
+prompt_histsearch({buf}, {offset}, [, {text}])		*prompt_histsearch*
⬇️ Suggested change
-prompt_histsearch({buf}, {offset}, [, {text}])		*prompt_histsearch*
+prompt_histsearch({buf}, {offset} [, {text}])		*prompt_histsearch()*

In runtime/doc/builtin.txt:

> @@ -8487,6 +8581,46 @@ prompt_setcallback({buf}, {expr})			*prompt_setcallback()*
 
 <		{only available when compiled with the |+channel| feature}
 
+prompt_sethistory({buf}, {entries}, [, {set-current}])	*prompt_sethistory*
⬇️ Suggested change
-prompt_sethistory({buf}, {entries}, [, {set-current}])	*prompt_sethistory*
+prompt_sethistory({buf}, {entries} [, {set-current}])	*prompt_sethistory()*

In runtime/doc/builtin.txt:

> +		If the buffer doesn't exist or isn't a prompt buffer, an empty
+		list is returned.
+
+		"entries" is a list of strings, ordered from most recent to
+		oldest.  If "set-current" is true, the first string in the
+		list should be the text that has not been entered yet in the
+		prompt.
+
+		By default if not provided, "set-current" is true.
+
+		Can also be used as a |method|: >
+			GetBuffer()->prompt_sethistory()
+<
+		{only available when compiled with the |+channel| feature}
+
+prompt_sethistsize({buf}, {max})			*prompt_sethistsize*
⬇️ Suggested change
-prompt_sethistsize({buf}, {max})			*prompt_sethistsize*
+prompt_sethistsize({buf}, {max})			*prompt_sethistsize()*

In runtime/doc/channel.txt:

> @@ -1434,6 +1434,18 @@ Any command that starts Insert mode, such as "a", "i", "A" and "I", will move
 the cursor to the last line.  "A" will move to the end of the line, "I" to the
 start of the line.
 
+The prompt buffer has a default history size of 100 entries.  This means you
+can access previously typed prompts via <Up> and do the opposite with <Down>
+in Insert mode.
+
+Before moving through the prompt history, the current text that has not been
+entered yet is saved, so you can go back to it.  If an entry in history is
+currently selected as the text, and is modified, then it will become the
+"non-entered" text, and the position in history will be reset.
+
+There are multiple builtin functions to manipulate this history functionality,
+see builtin.txt
⬇️ Suggested change
-see builtin.txt
+see |builtin.txt|.

In runtime/doc/builtin.txt:

> @@ -479,9 +479,19 @@ pow({x}, {y})			Float	{x} to the power of {y}
 preinserted()			Number	whether text is inserted after cursor
 prevnonblank({lnum})		Number	line nr of non-blank line <= {lnum}
 printf({fmt}, {expr1}...)	String	format text
+prompt_gethistory({buf})	List	get prompt history

Signature doesn't match


Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/19700/review/3950767662@github.com>

Foxe Chen

unread,
Mar 15, 2026, 8:28:12 PM (2 days ago) Mar 15
to vim/vim, Push

@64-bitman pushed 1 commit.

  • d15e80d add history to prompt buffer


View it on GitHub or unsubscribe.
You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/19700/before/20e461225e9e58bef53186d723dbf5b75f87d90a/after/d15e80dfc4f020031b6e3142f60c12257b3d51e7@github.com>

Foxe Chen

unread,
Mar 15, 2026, 8:29:19 PM (2 days ago) Mar 15
to vim/vim, Push

@64-bitman pushed 1 commit.

  • 6cf5c01 add history to prompt buffer

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/19700/before/d15e80dfc4f020031b6e3142f60c12257b3d51e7/after/6cf5c010629c09a029616488b53f5087c8db313d@github.com>

Foxe Chen

unread,
Mar 15, 2026, 8:30:04 PM (2 days ago) Mar 15
to vim/vim, Subscribed

@64-bitman commented on this pull request.


In src/job.c:

> +
+/*
+ * Add a prompt to the prompt history of the current buffer. This will trim the
+ * oldest entries if the maximum size is reached. Empty text is ignored.
+ */
+    static void
+add_prompt_history(char_u *text)
+{
+    garray_T	*ga = &curbuf->b_prompt_hist.bh_hist;
+    char_u	*save;
+
+    if (*text == NUL || curbuf->b_prompt_hist.bh_max == 0)
+	// Ignore empty text or history disabled
+	return;
+
+    save = text == NULL ? NULL : vim_strsave(text);

Fixed


Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/19700/review/3950912137@github.com>

Foxe Chen

unread,
Mar 15, 2026, 8:35:28 PM (2 days ago) Mar 15
to vim/vim, Push

@64-bitman pushed 1 commit.

  • d126ed6 add history to prompt buffer

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/19700/before/6cf5c010629c09a029616488b53f5087c8db313d/after/d126ed6e6037d7b92d12ad6c01a96497da31b091@github.com>

Foxe Chen

unread,
Mar 15, 2026, 8:40:11 PM (2 days ago) Mar 15
to vim/vim, Push

@64-bitman pushed 1 commit.

  • ac5f3c8 add history to prompt buffer

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/19700/before/d126ed6e6037d7b92d12ad6c01a96497da31b091/after/ac5f3c8c0a0d82ad719e3e2f03e37f42dc8180e6@github.com>

zeertzjq

unread,
Mar 15, 2026, 8:41:40 PM (2 days ago) Mar 15
to vim/vim, Subscribed

@zeertzjq commented on this pull request.


In runtime/doc/builtin.txt:

> @@ -479,9 +479,20 @@ pow({x}, {y})			Float	{x} to the power of {y}
 preinserted()			Number	whether text is inserted after cursor
 prevnonblank({lnum})		Number	line nr of non-blank line <= {lnum}
 printf({fmt}, {expr1}...)	String	format text
+prompt_gethistory({buf}, [, {max}])	
⬇️ Suggested change
-prompt_gethistory({buf}, [, {max}])	
+prompt_gethistory({buf} [, {max}])	

In runtime/doc/builtin.txt:

> @@ -8434,6 +8445,27 @@ printf({fmt}, {expr1} ...)				*printf()*
 
 		Return type: |String|
 
+prompt_gethistory({buf}, [, {max}])			*prompt_gethistory()*
⬇️ Suggested change
-prompt_gethistory({buf}, [, {max}])			*prompt_gethistory()*
+prompt_gethistory({buf} [, {max}])			*prompt_gethistory()*

In runtime/doc/builtin.txt:

> @@ -8449,6 +8481,69 @@ prompt_getprompt({buf})					*prompt_getprompt()*
 
 		{only available when compiled with the |+channel| feature}
 
+prompt_histgoto({buf}, {offset}, [, {relative}])	*prompt_histgoto()*
⬇️ Suggested change
-prompt_histgoto({buf}, {offset}, [, {relative}])	*prompt_histgoto()*
+prompt_histgoto({buf}, {offset} [, {relative}])		*prompt_histgoto()*

In runtime/doc/builtin.txt:

> +		moving through the prompt history.
+
+		In both cases, the values will be clamped between the maximum
+		and minimum possible offsets or indexes.
+
+		By default if not provided, "relative" is true.  Returns true
+		if position in history moved.
+
+		Can also be used as a |method|: >
+			GetBuffer()->prompt_histgoto()
+<
+		Return type: |Bool|
+
+		{only available when compiled with the |+channel| feature}
+
+prompt_histsearch({buf}, {offset}, [, {text}])		*prompt_histsearch()*
⬇️ Suggested change
-prompt_histsearch({buf}, {offset}, [, {text}])		*prompt_histsearch()*
+prompt_histsearch({buf}, {offset} [, {text}])		*prompt_histsearch()*

In runtime/doc/builtin.txt:

> @@ -8487,6 +8582,46 @@ prompt_setcallback({buf}, {expr})			*prompt_setcallback()*
 
 <		{only available when compiled with the |+channel| feature}
 
+prompt_sethistory({buf}, {entries}, [, {set-current}])	*prompt_sethistory()*
⬇️ Suggested change
-prompt_sethistory({buf}, {entries}, [, {set-current}])	*prompt_sethistory()*
+prompt_sethistory({buf}, {entries} [, {set-current}])	*prompt_sethistory()*

In runtime/doc/channel.txt:

> @@ -1434,6 +1434,18 @@ Any command that starts Insert mode, such as "a", "i", "A" and "I", will move
 the cursor to the last line.  "A" will move to the end of the line, "I" to the
 start of the line.
 
+The prompt buffer has a default history size of 100 entries.  This means you
+can access previously typed prompts via <Up> and do the opposite with <Down>
+in Insert mode.
+
+Before moving through the prompt history, the current text that has not been
+entered yet is saved, so you can go back to it.  If an entry in history is
+currently selected as the text, and is modified, then it will become the
+"non-entered" text, and the position in history will be reset.
+
+There are multiple builtin functions to manipulate this history functionality,
+see |builtin.tx|t
⬇️ Suggested change
-see |builtin.tx|t
+see |builtin.txt|.


Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/19700/review/3950946174@github.com>

Foxe Chen

unread,
Mar 15, 2026, 8:42:30 PM (2 days ago) Mar 15
to vim/vim, Push

@64-bitman pushed 1 commit.

  • 5c732a2 add history to prompt buffer

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/19700/before/ac5f3c8c0a0d82ad719e3e2f03e37f42dc8180e6/after/5c732a20fc6b25a905b8ff9e80e81c9fafd4b138@github.com>

Foxe Chen

unread,
Mar 15, 2026, 8:44:32 PM (2 days ago) Mar 15
to vim/vim, Push

@64-bitman pushed 1 commit.

  • b2198b0 add history to prompt buffer

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/19700/before/5c732a20fc6b25a905b8ff9e80e81c9fafd4b138/after/b2198b04b11d6a846b27eccbb46285b98fa9f870@github.com>

Foxe Chen

unread,
Mar 15, 2026, 8:50:36 PM (2 days ago) Mar 15
to vim/vim, Push

@64-bitman pushed 1 commit.

  • 072d55b add history to prompt buffer

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/19700/before/b2198b04b11d6a846b27eccbb46285b98fa9f870/after/072d55b5c151721172e9e399963514604b947444@github.com>

Foxe Chen

unread,
Mar 15, 2026, 9:03:24 PM (2 days ago) Mar 15
to vim/vim, Push

@64-bitman pushed 1 commit.

  • fce5ff4 add history to prompt buffer

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/19700/before/072d55b5c151721172e9e399963514604b947444/after/fce5ff448dc2fa162acb2a026bf870446c1cae61@github.com>

Foxe Chen

unread,
Mar 15, 2026, 9:11:08 PM (2 days ago) Mar 15
to vim/vim, Push

@64-bitman pushed 1 commit.

  • a1baab6 add history to prompt buffer

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/19700/before/fce5ff448dc2fa162acb2a026bf870446c1cae61/after/a1baab6c60bcc7380c86dc531a245512f7d14294@github.com>

Foxe Chen

unread,
Mar 15, 2026, 10:05:24 PM (2 days ago) Mar 15
to vim/vim, Push

@64-bitman pushed 1 commit.

  • f9002eb add history to prompt buffer

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/19700/before/a1baab6c60bcc7380c86dc531a245512f7d14294/after/f9002eb412094d259f548d34c439d32b7df2f0d7@github.com>

Foxe Chen

unread,
Mar 16, 2026, 10:56:16 AM (2 days ago) Mar 16
to vim/vim, Subscribed

@64-bitman commented on this pull request.


In runtime/doc/builtin.txt:

> +		if position in history moved.
+
+		Can also be used as a |method|: >
+			GetBuffer()->prompt_histgoto()
+<
+		Return type: |vim9-boolean|
+
+		{only available when compiled with the |+channel| feature}
+
+prompt_histsearch({buf}, {offset} [, {text}])		*prompt_histsearch()*
+		Search for a specific entry in the prompt history and set the
+		current text.  {buf} can be a buffer name or number.  See
+		|prompt-buffer|.
+
+		If the buffer doesn't exist or isn't a prompt buffer, an empty
+		list is returned.

todo fix


Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/19700/review/3954450877@github.com>

Foxe Chen

unread,
Mar 17, 2026, 9:35:25 AM (14 hours ago) Mar 17
to vim/vim, Push

@64-bitman pushed 1 commit.

  • c8898b0 add history to prompt buffer

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/19700/before/f9002eb412094d259f548d34c439d32b7df2f0d7/after/c8898b07729e5fd94d8bbdb3eebfd87da9287b74@github.com>

Christian Brabandt

unread,
Mar 17, 2026, 6:25:07 PM (6 hours ago) Mar 17
to vim/vim, Subscribed

@chrisbra commented on this pull request.

I have only looked at the provided API, but I think this can be improved.


In runtime/doc/builtin.txt:

> @@ -8434,6 +8445,27 @@ printf({fmt}, {expr1} ...)				*printf()*
 
 		Return type: |String|
 
+prompt_gethistory({buf} [, {max}])			*prompt_gethistory()*
+		Returns a list of up to "max" entries for the prompt history
+		of {buf}.  {buf} can be a buffer name or number.  See
+		|prompt-buffer|.
+
+		If the buffer doesn't exist or isn't a prompt buffer, an empty
+		list is returned.
+
+		If "max" is not provided, then the entire history is returned.
+		The first item in the list is always the current text (text
+		that has not been entered yet by the user).  Use a "max" value
⬇️ Suggested change
-		that has not been entered yet by the user).  Use a "max" value
+If "max" is not provided, then the entire history is returned.  The list order is always from the most recent entry to the oldest, with the very first item in the list being the current text on the prompt line (which may be an empty string if nothing has been typed).

In runtime/doc/builtin.txt:

> @@ -8434,6 +8445,27 @@ printf({fmt}, {expr1} ...)				*printf()*
 
 		Return type: |String|
 
+prompt_gethistory({buf} [, {max}])			*prompt_gethistory()*

This is different from e.g. histget(). Is this inconsistency okay?


In runtime/doc/builtin.txt:

>  prompt_setcallback({buf}, {expr})
 				none	set prompt callback function
+prompt_sethistory({buf}, {entries} [, {set-current}])
+				none	set prompt history
+prompt_sethistsize({buf}, {max})
+				Number	set maximum number of items in prompt
+					history

I am looking at the existing history functions: histget(), histadd(), histdel() and histnr(). I think we should use a naming, prompt_hist<action>


In runtime/doc/builtin.txt:

> +		|prompt-buffer|.
+
+		If the buffer doesn't exist or isn't a prompt buffer, false is
+		returned.
+
+		If "relative" is true, then "offset" is a offset from the
+		current position in history, and can be positive (go up in
+		history) or negative (go down in hisotry).
+
+		If "relative" is false, then "offset" is an absolute index
+		starting at zero in the prompt history.  A value of -1 will
+		move the current position to the non-entered text saved before
+		moving through the prompt history.
+
+		In both cases, the values will be clamped between the maximum
+		and minimum possible offsets or indexes.

clamped is a bit unusual in the help files, how about this:

In both cases, the value is limited to the available range:
If the index or offset would move the position beyond the oldest
entry or past the current text, it will stay at the first or
last entry respectively. No error is given.


In runtime/doc/builtin.txt:

> +
+		In both cases, the values will be clamped between the maximum
+		and minimum possible offsets or indexes.
+
+		By default if not provided, "relative" is true.  Returns true
+		if position in history moved.
+
+		Can also be used as a |method|: >
+			GetBuffer()->prompt_histgoto()
+<
+		Return type: |vim9-boolean|
+
+		{only available when compiled with the |+channel| feature}
+
+prompt_histsearch({buf}, {offset} [, {text}])		*prompt_histsearch()*
+		Search for a specific entry in the prompt history and set the
⬇️ Suggested change
-		Search for a specific entry in the prompt history and set the
+		Search for a specific entry {text} in the prompt history and set the

In runtime/doc/builtin.txt:

> +prompt_histsearch({buf}, {offset} [, {text}])		*prompt_histsearch()*
+		Search for a specific entry in the prompt history and set the
+		current text.  {buf} can be a buffer name or number.  See
+		|prompt-buffer|.
+
+		If the buffer doesn't exist or isn't a prompt buffer, false is
+		returned.
+
+		"offset" is a relative index to the nth entry in history that
+		has the "text" as its prefix.  For example: >
+			hello
+			hey
+			world!
+			inprogress|  <current position>
+<		To go to "hello" is history, do >vim
+			call prompt_histsearch(bufnr(), 2, "he")

This is a bit strange. The function is called search, why do we need to provide an offset?


In runtime/doc/builtin.txt:

> +		In both cases, the values will be clamped between the maximum
+		and minimum possible offsets or indexes.
+
+		By default if not provided, "relative" is true.  Returns true
+		if position in history moved.
+
+		Can also be used as a |method|: >
+			GetBuffer()->prompt_histgoto()
+<
+		Return type: |vim9-boolean|
+
+		{only available when compiled with the |+channel| feature}
+
+prompt_histsearch({buf}, {offset} [, {text}])		*prompt_histsearch()*
+		Search for a specific entry in the prompt history and set the
+		current text.  {buf} can be a buffer name or number.  See

should this not just return a list of history entries or the indexes? Why set the text? That is what the goto function is for, no?


In runtime/doc/builtin.txt:

> +
+		If the new history list is smaller than the old one then older
+		entries are removed from history.  If one of the removed
+		entries is currently selected, then the current position
+		(non-entered text) is set to the now updated oldest entry.
+
+		By default if not provided, "set-current" is true.
+
+		Can also be used as a |method|: >
+			GetBuffer()->prompt_sethistory()
+<
+		{only available when compiled with the |+channel| feature}
+
+prompt_sethistsize({buf}, {max})			*prompt_sethistsize()*
+		Set the maximum prompt history size of {buf} to "max".  {buf}
+		can be a buffer name or number.  See |prompt-buffer|.

shouldn't this be an option?


In runtime/doc/builtin.txt:

> @@ -8499,8 +8645,6 @@ prompt_setinterrupt({buf}, {expr})			*prompt_setinterrupt()*
 		Can also be used as a |method|: >
 			GetBuffer()->prompt_setinterrupt(callback)
 <
-		Return type: |Number|
-

why is this removed?


Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/19700/review/3963991712@github.com>

Foxe Chen

unread,
Mar 17, 2026, 6:31:30 PM (5 hours ago) Mar 17
to vim/vim, Subscribed
64-bitman left a comment (vim/vim#19700)

I have only looked at the provided API, but I think this can be improved.

Yes. I would also like feedback from @puremourning if they are available


Reply to this email directly, view it on GitHub.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/19700/c4078378251@github.com>

Reply all
Reply to author
Forward
0 new messages