aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2024-06-30 06:40:31 +0800
committerGitHub <noreply@github.com>2024-06-30 06:40:31 +0800
commite7020306a19a5211c834966ec067fff3b981bdb9 (patch)
tree79436a276599e9c62f69d308d2d963e7f3dee1ac /src
parent435d0182d293e70b14a5655c976c3c6daa6ea765 (diff)
downloadrneovim-e7020306a19a5211c834966ec067fff3b981bdb9.tar.gz
rneovim-e7020306a19a5211c834966ec067fff3b981bdb9.tar.bz2
rneovim-e7020306a19a5211c834966ec067fff3b981bdb9.zip
feat(jumplist): allow opting out of removing unloaded buffers (#29347)
Problem: Cannot opt out of removing unloaded buffers from the jumplist. Solution: Only enable that with "unload" flag in 'jumpoptions'.
Diffstat (limited to 'src')
-rw-r--r--src/nvim/buffer.c47
-rw-r--r--src/nvim/option_vars.h1
-rw-r--r--src/nvim/options.lua5
-rw-r--r--src/nvim/optionstr.c2
4 files changed, 36 insertions, 19 deletions
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index 57245ce3f5..3812ff6b44 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -1396,8 +1396,10 @@ int do_buffer(int action, int start, int dir, int count, int forceit)
// If the buffer to be deleted is not the current one, delete it here.
if (buf != curbuf) {
- // Remove the buffer to be deleted from the jump list.
- buf_remove_from_jumplist(buf);
+ if (jop_flags & JOP_UNLOAD) {
+ // Remove the buffer to be deleted from the jump list.
+ buf_remove_from_jumplist(buf);
+ }
close_windows(buf, false);
@@ -1420,28 +1422,37 @@ int do_buffer(int action, int start, int dir, int count, int forceit)
if (au_new_curbuf.br_buf != NULL && bufref_valid(&au_new_curbuf)) {
buf = au_new_curbuf.br_buf;
} else if (curwin->w_jumplistlen > 0) {
- // Remove the current buffer from the jump list.
- buf_remove_from_jumplist(curbuf);
+ if (jop_flags & JOP_UNLOAD) {
+ // Remove the current buffer from the jump list.
+ buf_remove_from_jumplist(curbuf);
+ }
// It's possible that we removed all jump list entries, in that case we need to try another
// approach
if (curwin->w_jumplistlen > 0) {
- // If the index is the same as the length, the current position was not yet added to the jump
- // list. So we can safely go back to the last entry and search from there.
- if (curwin->w_jumplistidx == curwin->w_jumplistlen) {
- curwin->w_jumplistidx = curwin->w_jumplistlen - 1;
- }
-
int jumpidx = curwin->w_jumplistidx;
+ if (jop_flags & JOP_UNLOAD) {
+ // If the index is the same as the length, the current position was not yet added to the
+ // jump list. So we can safely go back to the last entry and search from there.
+ if (jumpidx == curwin->w_jumplistlen) {
+ jumpidx = curwin->w_jumplistidx = curwin->w_jumplistlen - 1;
+ }
+ } else {
+ jumpidx--;
+ if (jumpidx < 0) {
+ jumpidx = curwin->w_jumplistlen - 1;
+ }
+ }
+
forward = jumpidx;
- do {
+ while ((jop_flags & JOP_UNLOAD) || jumpidx != curwin->w_jumplistidx) {
buf = buflist_findnr(curwin->w_jumplist[jumpidx].fmark.fnum);
if (buf != NULL) {
- // Skip unlisted bufs. Also skip a quickfix
+ // Skip current and unlisted bufs. Also skip a quickfix
// buffer, it might be deleted soon.
- if (!buf->b_p_bl || bt_quickfix(buf)) {
+ if (buf == curbuf || !buf->b_p_bl || bt_quickfix(buf)) {
buf = NULL;
} else if (buf->b_ml.ml_mfp == NULL) {
// skip unloaded buf, but may keep it for later
@@ -1452,8 +1463,10 @@ int do_buffer(int action, int start, int dir, int count, int forceit)
}
}
if (buf != NULL) { // found a valid buffer: stop searching
- curwin->w_jumplistidx = jumpidx;
- update_jumplist = false;
+ if (jop_flags & JOP_UNLOAD) {
+ curwin->w_jumplistidx = jumpidx;
+ update_jumplist = false;
+ }
break;
}
// advance to older entry in jump list
@@ -1466,7 +1479,7 @@ int do_buffer(int action, int start, int dir, int count, int forceit)
if (jumpidx == forward) { // List exhausted for sure
break;
}
- } while (jumpidx != curwin->w_jumplistidx);
+ }
}
}
@@ -3728,7 +3741,7 @@ void ex_buffer_all(exarg_T *eap)
// Open the buffer in this window.
swap_exists_action = SEA_DIALOG;
- set_curbuf(buf, DOBUF_GOTO, false);
+ set_curbuf(buf, DOBUF_GOTO, !(jop_flags & JOP_UNLOAD));
if (!bufref_valid(&bufref)) {
// Autocommands deleted the buffer.
swap_exists_action = SEA_NONE;
diff --git a/src/nvim/option_vars.h b/src/nvim/option_vars.h
index 404e58661c..3326c0879a 100644
--- a/src/nvim/option_vars.h
+++ b/src/nvim/option_vars.h
@@ -540,6 +540,7 @@ EXTERN char *p_jop; ///< 'jumpooptions'
EXTERN unsigned jop_flags;
#define JOP_STACK 0x01
#define JOP_VIEW 0x02
+#define JOP_UNLOAD 0x04
EXTERN char *p_keymap; ///< 'keymap'
EXTERN char *p_kp; ///< 'keywordprg'
EXTERN char *p_km; ///< 'keymodel'
diff --git a/src/nvim/options.lua b/src/nvim/options.lua
index efa2ea7dd9..365679261c 100644
--- a/src/nvim/options.lua
+++ b/src/nvim/options.lua
@@ -4495,7 +4495,7 @@ return {
{
abbreviation = 'jop',
cb = 'did_set_jumpoptions',
- defaults = { if_true = '' },
+ defaults = { if_true = 'unload' },
deny_duplicates = true,
desc = [=[
List of words that change the behavior of the |jumplist|.
@@ -4508,6 +4508,9 @@ return {
view When moving through the jumplist, |changelist|,
|alternate-file| or using |mark-motions| try to
restore the |mark-view| in which the action occurred.
+
+ unload Remove unloaded buffers from the jumplist.
+ EXPERIMENTAL: this flag may change in the future.
]=],
expand_cb = 'expand_set_jumpoptions',
full_name = 'jumpoptions',
diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c
index 4cd830a2fc..cdbb8c2d6d 100644
--- a/src/nvim/optionstr.c
+++ b/src/nvim/optionstr.c
@@ -137,7 +137,7 @@ static char *(p_fdc_values[]) = { "auto", "auto:1", "auto:2", "auto:3", "auto:4"
"5", "6", "7", "8", "9", NULL };
static char *(p_spo_values[]) = { "camel", "noplainbuffer", NULL };
static char *(p_icm_values[]) = { "nosplit", "split", NULL };
-static char *(p_jop_values[]) = { "stack", "view", NULL };
+static char *(p_jop_values[]) = { "stack", "view", "unload", NULL };
static char *(p_tpf_values[]) = { "BS", "HT", "FF", "ESC", "DEL", "C0", "C1", NULL };
static char *(p_rdb_values[]) = { "compositor", "nothrottle", "invalid", "nodelta", "line",
"flush", NULL };