diff options
author | zeertzjq <zeertzjq@outlook.com> | 2024-06-30 06:40:31 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-30 06:40:31 +0800 |
commit | e7020306a19a5211c834966ec067fff3b981bdb9 (patch) | |
tree | 79436a276599e9c62f69d308d2d963e7f3dee1ac /src | |
parent | 435d0182d293e70b14a5655c976c3c6daa6ea765 (diff) | |
download | rneovim-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.c | 47 | ||||
-rw-r--r-- | src/nvim/option_vars.h | 1 | ||||
-rw-r--r-- | src/nvim/options.lua | 5 | ||||
-rw-r--r-- | src/nvim/optionstr.c | 2 |
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 }; |