diff options
-rw-r--r-- | runtime/doc/autocmd.txt | 3 | ||||
-rw-r--r-- | runtime/doc/diagnostic.txt | 3 | ||||
-rw-r--r-- | runtime/doc/news.txt | 3 | ||||
-rw-r--r-- | runtime/indent/json5.vim | 11 | ||||
-rw-r--r-- | runtime/lua/vim/diagnostic.lua | 21 | ||||
-rw-r--r-- | runtime/syntax/java.vim | 6 | ||||
-rw-r--r-- | src/nvim/auevents.lua | 1 | ||||
-rw-r--r-- | src/nvim/ex_docmd.c | 36 | ||||
-rw-r--r-- | src/nvim/ex_session.c | 3 | ||||
-rw-r--r-- | src/nvim/generators/gen_options.lua | 9 | ||||
-rw-r--r-- | src/nvim/option.c | 17 | ||||
-rw-r--r-- | src/nvim/option.h | 4 | ||||
-rw-r--r-- | src/nvim/option_vars.h | 4 | ||||
-rw-r--r-- | src/nvim/options.lua | 23 | ||||
-rw-r--r-- | src/nvim/tui/input.c | 4 | ||||
-rw-r--r-- | src/nvim/tui/tui.c | 60 | ||||
-rw-r--r-- | test/functional/terminal/tui_spec.lua | 3 | ||||
-rw-r--r-- | test/old/testdir/test_autocmd.vim | 56 | ||||
-rw-r--r-- | test/old/testdir/test_winfixbuf.vim | 140 |
19 files changed, 340 insertions, 67 deletions
diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt index 8890872e1a..b3974e3246 100644 --- a/runtime/doc/autocmd.txt +++ b/runtime/doc/autocmd.txt @@ -884,6 +884,9 @@ SafeState When nothing is pending, going to wait for the *SessionLoadPost* SessionLoadPost After loading the session file created using the |:mksession| command. + *SessionWritePost* +SessionWritePost After writing a session file by calling + the |:mksession| command. *ShellCmdPost* ShellCmdPost After executing a shell command with |:!cmd|, |:make| and |:grep|. Can be used to check for diff --git a/runtime/doc/diagnostic.txt b/runtime/doc/diagnostic.txt index c9e783ca62..a9172119d0 100644 --- a/runtime/doc/diagnostic.txt +++ b/runtime/doc/diagnostic.txt @@ -371,7 +371,8 @@ Lua module: vim.diagnostic *diagnostic-api* A table with the following keys: Fields: ~ - • {namespace}? (`integer`) Limit diagnostics to the given namespace. + • {namespace}? (`integer[]|integer`) Limit diagnostics to one or more + namespaces. • {lnum}? (`integer`) Limit diagnostics to the given line number. • {severity}? (`vim.diagnostic.SeverityFilter`) See |diagnostic-severity|. diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index 0222d547b0..1aee5c656b 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -408,6 +408,9 @@ The following changes to existing APIs or features add new behavior. "virtual_text" table, which gives users more control over how diagnostic virtual text is displayed. +• |vim.diagnostic.get()| and |vim.diagnostic.count()| accept multiple + namespaces rather than just a single namespace. + • Extmarks now fully support multi-line ranges, and a single extmark can be used to highlight a range of arbitrary length. The |nvim_buf_set_extmark()| API function already allowed you to define such ranges, but highlight regions diff --git a/runtime/indent/json5.vim b/runtime/indent/json5.vim new file mode 100644 index 0000000000..5977a4b912 --- /dev/null +++ b/runtime/indent/json5.vim @@ -0,0 +1,11 @@ +" Vim indent file +" Language: JSON5 +" Maintainer: The Vim Project <https://github.com/vim/vim> +" Last Change: 2024-03-26 + +if exists("b:did_indent") + finish +endif + +" Same as jsonc indenting for now +runtime! indent/jsonc.vim diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index d5075d7d3d..57491d155d 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -682,6 +682,13 @@ local function get_diagnostics(bufnr, opts, clamp) opts = opts or {} local namespace = opts.namespace + + if type(namespace) == 'number' then + namespace = { namespace } + end + + ---@cast namespace integer[] + local diagnostics = {} -- Memoized results of buf_line_count per bufnr @@ -742,11 +749,15 @@ local function get_diagnostics(bufnr, opts, clamp) end elseif bufnr == nil then for b, t in pairs(diagnostic_cache) do - add_all_diags(b, t[namespace] or {}) + for _, iter_namespace in ipairs(namespace) do + add_all_diags(b, t[iter_namespace] or {}) + end end else bufnr = get_bufnr(bufnr) - add_all_diags(bufnr, diagnostic_cache[bufnr][namespace] or {}) + for _, iter_namespace in ipairs(namespace) do + add_all_diags(bufnr, diagnostic_cache[bufnr][iter_namespace] or {}) + end end if opts.severity then @@ -785,7 +796,7 @@ end --- @param search_forward boolean --- @param bufnr integer --- @param opts vim.diagnostic.GotoOpts ---- @param namespace integer +--- @param namespace integer[]|integer --- @return vim.Diagnostic? local function next_diagnostic(position, search_forward, bufnr, opts, namespace) position[1] = position[1] - 1 @@ -1115,8 +1126,8 @@ end --- A table with the following keys: --- @class vim.diagnostic.GetOpts --- ---- Limit diagnostics to the given namespace. ---- @field namespace? integer +--- Limit diagnostics to one or more namespaces. +--- @field namespace? integer[]|integer --- --- Limit diagnostics to the given line number. --- @field lnum? integer diff --git a/runtime/syntax/java.vim b/runtime/syntax/java.vim index cf27e0dc91..1f0c158031 100644 --- a/runtime/syntax/java.vim +++ b/runtime/syntax/java.vim @@ -2,7 +2,7 @@ " Language: Java " Maintainer: Claudio Fleiner <claudio@fleiner.com> " URL: https://github.com/fleiner/vim/blob/master/runtime/syntax/java.vim -" Last Change: 2024 Mar 24 +" Last Change: 2024 Mar 25 " Please check :help java.vim for comments on some of the options available. @@ -91,7 +91,7 @@ if exists("java_highlight_all") || exists("java_highlight_java") || exists("ja " keywords can be pre-sorted and appended without disturbing " the current keyword placement. The below _match_es follow suit. - syn keyword javaR_JavaLang ArithmeticException ArrayIndexOutOfBoundsException ArrayStoreException ClassCastException IllegalArgumentException IllegalMonitorStateException IllegalThreadStateException IndexOutOfBoundsException NegativeArraySizeException NullPointerException NumberFormatException RuntimeException SecurityException StringIndexOutOfBoundsException IllegalStateException UnsupportedOperationException EnumConstantNotPresentException TypeNotPresentException IllegalCallerException LayerInstantiationException + syn keyword javaR_JavaLang ArithmeticException ArrayIndexOutOfBoundsException ArrayStoreException ClassCastException IllegalArgumentException IllegalMonitorStateException IllegalThreadStateException IndexOutOfBoundsException NegativeArraySizeException NullPointerException NumberFormatException RuntimeException SecurityException StringIndexOutOfBoundsException IllegalStateException UnsupportedOperationException EnumConstantNotPresentException TypeNotPresentException IllegalCallerException LayerInstantiationException WrongThreadException MatchException syn cluster javaTop add=javaR_JavaLang syn cluster javaClasses add=javaR_JavaLang hi def link javaR_JavaLang javaR_Java @@ -111,6 +111,8 @@ if exists("java_highlight_all") || exists("java_highlight_java") || exists("ja syn match javaC_JavaLang "\%(\<Enum\.\)\@<=\<EnumDesc\>" syn keyword javaC_JavaLang Boolean Character Class ClassLoader Compiler Double Float Integer Long Math Number Object Process Runtime SecurityManager String StringBuffer Thread ThreadGroup Byte Short Void InheritableThreadLocal Package RuntimePermission ThreadLocal StrictMath StackTraceElement Enum ProcessBuilder StringBuilder ClassValue Module ModuleLayer StackWalker Record syn match javaC_JavaLang "\<System\>" " See javaDebug. + " As of Java 21, java.lang.Compiler is no more (deprecated in Java 9). + syn keyword javaLangDeprecated Compiler syn cluster javaTop add=javaC_JavaLang syn cluster javaClasses add=javaC_JavaLang hi def link javaC_JavaLang javaC_Java diff --git a/src/nvim/auevents.lua b/src/nvim/auevents.lua index b931907fe3..3946ffd960 100644 --- a/src/nvim/auevents.lua +++ b/src/nvim/auevents.lua @@ -88,6 +88,7 @@ return { 'SafeState', -- going to wait for a character 'SearchWrapped', -- after the search wrapped around 'SessionLoadPost', -- after loading a session file + 'SessionWritePost', -- after writing a session file 'ShellCmdPost', -- after ":!cmd" 'ShellFilterPost', -- after ":1,2!cmd", ":w !cmd", ":r !cmd". 'Signal', -- after nvim process received a signal diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 1009e25081..ee738d9e92 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -216,6 +216,38 @@ static void restore_dbg_stuff(struct dbg_stuff *dsp) current_exception = dsp->current_exception; } +/// Check if ffname differs from fnum. +/// fnum is a buffer number. 0 == current buffer, 1-or-more must be a valid buffer ID. +/// ffname is a full path to where a buffer lives on-disk or would live on-disk. +static bool is_other_file(int fnum, char *ffname) +{ + if (fnum != 0) { + if (fnum == curbuf->b_fnum) { + return false; + } + + return true; + } + + if (ffname == NULL) { + return true; + } + + if (*ffname == NUL) { + return false; + } + + if (!curbuf->file_id_valid + && curbuf->b_sfname != NULL + && *curbuf->b_sfname != NUL) { + // This occurs with unsaved buffers. In which case `ffname` + // actually corresponds to curbuf->b_sfname + return path_fnamecmp(ffname, curbuf->b_sfname) != 0; + } + + return otherfile(ffname); +} + /// Repeatedly get commands for Ex mode, until the ":vi" command is given. void do_exmode(void) { @@ -5371,11 +5403,13 @@ static void ex_find(exarg_T *eap) /// ":edit", ":badd", ":balt", ":visual". static void ex_edit(exarg_T *eap) { + char *ffname = eap->cmdidx == CMD_enew ? NULL : eap->arg; + // Exclude commands which keep the window's current buffer if (eap->cmdidx != CMD_badd && eap->cmdidx != CMD_balt // All other commands must obey 'winfixbuf' / ! rules - && !check_can_set_curbuf_forceit(eap->forceit)) { + && (is_other_file(0, ffname) && !check_can_set_curbuf_forceit(eap->forceit))) { return; } diff --git a/src/nvim/ex_session.c b/src/nvim/ex_session.c index fb37bc86f1..416f18ccc5 100644 --- a/src/nvim/ex_session.c +++ b/src/nvim/ex_session.c @@ -12,6 +12,7 @@ #include "nvim/arglist.h" #include "nvim/arglist_defs.h" #include "nvim/ascii_defs.h" +#include "nvim/autocmd.h" #include "nvim/buffer.h" #include "nvim/buffer_defs.h" #include "nvim/eval.h" @@ -1092,6 +1093,8 @@ void ex_mkrc(exarg_T *eap) } xfree(viewFile); + + apply_autocmds(EVENT_SESSIONWRITEPOST, NULL, NULL, false, curbuf); } /// @return the name of the view file for the current buffer. diff --git a/src/nvim/generators/gen_options.lua b/src/nvim/generators/gen_options.lua index 749844e658..c0c0d6e0b4 100644 --- a/src/nvim/generators/gen_options.lua +++ b/src/nvim/generators/gen_options.lua @@ -164,14 +164,19 @@ local function dump_option(i, o) if o.enable_if then w(get_cond(o.enable_if)) end + + -- Options cannot be both hidden and immutable. + assert(not o.hidden or not o.immutable) + if o.varname then w(' .var=&' .. o.varname) - -- Immutable options can directly point to the default value. - elseif o.immutable then + -- Hidden and immutable options can directly point to the default value. + elseif o.hidden or o.immutable then w((' .var=&options[%u].def_val'):format(i - 1)) elseif #o.scope == 1 and o.scope[1] == 'window' then w(' .var=VAR_WIN') end + w(' .hidden=' .. (o.hidden and 'true' or 'false')) w(' .immutable=' .. (o.immutable and 'true' or 'false')) if #o.scope == 1 and o.scope[1] == 'global' then w(' .indir=PV_NONE') diff --git a/src/nvim/option.c b/src/nvim/option.c index 73a5af5520..e4f32ebec4 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -2898,8 +2898,6 @@ static const char *validate_num_option(OptIndex opt_idx, void *varp, OptInt *new } else if (value > p_wiw) { return e_winwidth; } - } else if (varp == &p_mco) { - *newval = MAX_MCO; } else if (varp == &p_titlelen) { if (value < 0) { return e_positive; @@ -3483,11 +3481,11 @@ static const char *did_set_option(OptIndex opt_idx, void *varp, OptVal old_value .os_win = curwin }; - if (direct) { - // Don't do any extra processing if setting directly. + if (direct || opt->immutable) { + // Don't do any extra processing if setting directly or if option is immutable. } - // Disallow changing immutable options. - else if (opt->immutable && !optval_equal(old_value, new_value)) { + // Disallow changing hidden options. + else if (opt->hidden && !optval_equal(old_value, new_value)) { errmsg = e_unsupportedoption; } // Disallow changing some options from secure mode. @@ -3511,8 +3509,9 @@ static const char *did_set_option(OptIndex opt_idx, void *varp, OptVal old_value restore_chartab = did_set_cb_args.os_restore_chartab; } - // If an error is detected, restore the previous value and don't do any further processing. - if (errmsg != NULL) { + // If option is immutable or if an error is detected, restore the previous value and don't do any + // further processing. + if (opt->immutable || errmsg != NULL) { set_option_varp(opt_idx, varp, old_value, true); // When resetting some values, need to act on it. if (restore_chartab) { @@ -4227,7 +4226,7 @@ static int optval_default(OptIndex opt_idx, void *varp) vimoption_T *opt = &options[opt_idx]; // Hidden or immutable options always use their default value. - if (varp == NULL || opt->immutable) { + if (varp == NULL || opt->hidden || opt->immutable) { return true; } diff --git a/src/nvim/option.h b/src/nvim/option.h index 7cf880b19b..2357aa68ac 100644 --- a/src/nvim/option.h +++ b/src/nvim/option.h @@ -49,7 +49,9 @@ typedef struct { ///< buffer-local option: global value idopt_T indir; ///< global option: PV_NONE; ///< local option: indirect option index - bool immutable; ///< option value cannot be changed from the default value. + bool hidden; ///< option is hidden and cannot be set. + bool immutable; ///< option value can be set but any attempt to change the option is + /// ignored. /// callback function to invoke after an option is modified to validate and /// apply the new value. diff --git a/src/nvim/option_vars.h b/src/nvim/option_vars.h index 175f2af896..35cea7c7bc 100644 --- a/src/nvim/option_vars.h +++ b/src/nvim/option_vars.h @@ -129,6 +129,8 @@ #define DFLT_FO_VIM "tcqj" #define FO_ALL "tcro/q2vlb1mMBn,aw]jp" // for do_set() +#define MAX_MCO 6 // fixed value for 'maxcombine' + // characters for the p_cpo option: #define CPO_ALTREAD 'a' // ":read" sets alternate file name #define CPO_ALTWRITE 'A' // ":write" sets alternate file name @@ -549,8 +551,6 @@ EXTERN char *p_mef; ///< 'makeef' EXTERN char *p_mp; ///< 'makeprg' EXTERN char *p_mps; ///< 'matchpairs' EXTERN OptInt p_mat; ///< 'matchtime' -EXTERN OptInt p_mco; ///< 'maxcombine' -#define MAX_MCO 6 // fixed value for 'maxcombine' EXTERN OptInt p_mfd; ///< 'maxfuncdepth' EXTERN OptInt p_mmd; ///< 'maxmapdepth' EXTERN OptInt p_mmp; ///< 'maxmempattern' diff --git a/src/nvim/options.lua b/src/nvim/options.lua index 9345a1e9f4..26a0c1a3a9 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -7,6 +7,7 @@ --- @field varname? string --- @field pv_name? string --- @field type 'boolean'|'number'|'string' +--- @field hidden? boolean --- @field immutable? boolean --- @field list? 'comma'|'onecomma'|'commacolon'|'onecommacolon'|'flags'|'flagscomma' --- @field scope vim.option_scope[] @@ -1340,7 +1341,7 @@ return { scope = { 'global' }, short_desc = N_('No description'), type = 'boolean', - immutable = true, + hidden = true, }, { abbreviation = 'cpt', @@ -2299,7 +2300,7 @@ return { scope = { 'global' }, short_desc = N_('No description'), type = 'boolean', - immutable = true, + hidden = true, }, { abbreviation = 'emo', @@ -3888,7 +3889,7 @@ return { scope = { 'global' }, short_desc = N_('No description'), type = 'boolean', - immutable = true, + hidden = true, }, { abbreviation = 'hkp', @@ -3897,7 +3898,7 @@ return { scope = { 'global' }, short_desc = N_('No description'), type = 'boolean', - immutable = true, + hidden = true, }, { abbreviation = 'hls', @@ -4295,7 +4296,7 @@ return { scope = { 'global' }, short_desc = N_('No description'), type = 'boolean', - immutable = true, + hidden = true, }, { abbreviation = 'isf', @@ -5141,12 +5142,12 @@ return { }, { abbreviation = 'mco', - defaults = { if_true = 6 }, + defaults = { if_true = imacros('MAX_MCO') }, full_name = 'maxcombine', scope = { 'global' }, short_desc = N_('maximum nr of combining characters displayed'), type = 'number', - varname = 'p_mco', + immutable = true, }, { abbreviation = 'mfd', @@ -6047,7 +6048,7 @@ return { scope = { 'global' }, short_desc = N_('enable prompt in Ex mode'), type = 'boolean', - immutable = true, + hidden = true, }, { abbreviation = 'pb', @@ -6304,7 +6305,7 @@ return { scope = { 'global' }, short_desc = N_('No description'), type = 'boolean', - immutable = true, + hidden = true, }, { defaults = { if_true = 2 }, @@ -8843,7 +8844,7 @@ return { scope = { 'global' }, short_desc = N_('No description'), type = 'boolean', - immutable = true, + hidden = true, }, { abbreviation = 'tw', @@ -9088,7 +9089,7 @@ return { scope = { 'global' }, short_desc = N_('No description'), type = 'boolean', - immutable = true, + hidden = true, }, { abbreviation = 'udir', diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c index 214474ff51..840e472a1c 100644 --- a/src/nvim/tui/input.c +++ b/src/nvim/tui/input.c @@ -442,12 +442,12 @@ static void tk_getkeys(TermInput *input, bool force) forward_modified_utf8(input, &key); } else if (key.type == TERMKEY_TYPE_MOUSE) { forward_mouse_event(input, &key); + } else if (key.type == TERMKEY_TYPE_MODEREPORT) { + handle_modereport(input, &key); } else if (key.type == TERMKEY_TYPE_UNKNOWN_CSI) { handle_unknown_csi(input, &key); } else if (key.type == TERMKEY_TYPE_OSC || key.type == TERMKEY_TYPE_DCS) { handle_term_response(input, &key); - } else if (key.type == TERMKEY_TYPE_MODEREPORT) { - handle_modereport(input, &key); } } diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index 1edcde5341..96054cf5cb 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -189,36 +189,6 @@ void tui_start(TUIData **tui_p, int *width, int *height, char **term, bool *rgb) *rgb = tui->rgb; } -void tui_set_key_encoding(TUIData *tui) - FUNC_ATTR_NONNULL_ALL -{ - switch (tui->input.key_encoding) { - case kKeyEncodingKitty: - out(tui, S_LEN("\x1b[>1u")); - break; - case kKeyEncodingXterm: - out(tui, S_LEN("\x1b[>4;2m")); - break; - case kKeyEncodingLegacy: - break; - } -} - -static void tui_reset_key_encoding(TUIData *tui) - FUNC_ATTR_NONNULL_ALL -{ - switch (tui->input.key_encoding) { - case kKeyEncodingKitty: - out(tui, S_LEN("\x1b[<1u")); - break; - case kKeyEncodingXterm: - out(tui, S_LEN("\x1b[>4;0m")); - break; - case kKeyEncodingLegacy: - break; - } -} - /// Request the terminal's mode (DECRQM). /// /// @see handle_modereport @@ -270,6 +240,36 @@ static void tui_query_kitty_keyboard(TUIData *tui) out(tui, S_LEN("\x1b[?u\x1b[c")); } +void tui_set_key_encoding(TUIData *tui) + FUNC_ATTR_NONNULL_ALL +{ + switch (tui->input.key_encoding) { + case kKeyEncodingKitty: + out(tui, S_LEN("\x1b[>1u")); + break; + case kKeyEncodingXterm: + out(tui, S_LEN("\x1b[>4;2m")); + break; + case kKeyEncodingLegacy: + break; + } +} + +static void tui_reset_key_encoding(TUIData *tui) + FUNC_ATTR_NONNULL_ALL +{ + switch (tui->input.key_encoding) { + case kKeyEncodingKitty: + out(tui, S_LEN("\x1b[<1u")); + break; + case kKeyEncodingXterm: + out(tui, S_LEN("\x1b[>4;0m")); + break; + case kKeyEncodingLegacy: + break; + } +} + /// Enable the alternate screen and emit other control sequences to start the TUI. /// /// This is also called when the TUI is resumed after being suspended. We reinitialize all state diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua index 03d0999f24..0300672a08 100644 --- a/test/functional/terminal/tui_spec.lua +++ b/test/functional/terminal/tui_spec.lua @@ -1485,7 +1485,8 @@ describe('TUI', function() feed_data('\027[201~') -- phase 3 screen:expect_unchanged() local _, rv = child_session:request('nvim_exec_lua', [[return _G.paste_phases]], {}) - eq({ 1, 2, 3 }, rv) + -- In rare cases there may be multiple chunks of phase 2 because of timing. + eq({ 1, 2, 3 }, { rv[1], rv[2], rv[#rv] }) end) it('allows termguicolors to be set at runtime', function() diff --git a/test/old/testdir/test_autocmd.vim b/test/old/testdir/test_autocmd.vim index 2b37ccf4a6..f1040b4b35 100644 --- a/test/old/testdir/test_autocmd.vim +++ b/test/old/testdir/test_autocmd.vim @@ -3901,4 +3901,60 @@ func Test_autocmd_creates_new_buffer_on_bufleave() bw c.txt endfunc +" Ensure `expected` was just recently written as a Vim session +func s:assert_session_path(expected) + call assert_equal(a:expected, v:this_session) +endfunc + +" Check for `expected` after a session is written to-disk. +func s:watch_for_session_path(expected) + execute 'autocmd SessionWritePost * ++once execute "call s:assert_session_path(\"' + \ . a:expected + \ . '\")"' +endfunc + +" Ensure v:this_session gets the full session path, if explicitly stated +func Test_explicit_session_absolute_path() + %bwipeout! + + let directory = getcwd() + + let v:this_session = "" + let name = "some_file.vim" + let expected = fnamemodify(name, ":p") + call s:watch_for_session_path(expected) + execute "mksession! " .. expected + + call delete(expected) +endfunc + +" Ensure v:this_session gets the full session path, if explicitly stated +func Test_explicit_session_relative_path() + %bwipeout! + + let directory = getcwd() + + let v:this_session = "" + let name = "some_file.vim" + let expected = fnamemodify(name, ":p") + call s:watch_for_session_path(expected) + execute "mksession! " .. name + + call delete(expected) +endfunc + +" Ensure v:this_session gets the full session path, if not specified +func Test_implicit_session() + %bwipeout! + + let directory = getcwd() + + let v:this_session = "" + let expected = fnamemodify("Session.vim", ":p") + call s:watch_for_session_path(expected) + mksession! + + call delete(expected) +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/test/old/testdir/test_winfixbuf.vim b/test/old/testdir/test_winfixbuf.vim index 320e73f378..d5e43cf33e 100644 --- a/test/old/testdir/test_winfixbuf.vim +++ b/test/old/testdir/test_winfixbuf.vim @@ -1125,6 +1125,146 @@ func Test_edit() call assert_equal(l:other, bufnr()) endfunc +" Fail :e when selecting a buffer from a relative path if in a different folder +" +" In this tests there's 2 buffers +" +" foo - lives on disk, in some folder. e.g. /tmp/foo +" foo - an in-memory buffer that has not been saved to disk. If saved, it +" would live in a different folder, /other/foo. +" +" The 'winfixbuf' is looking at the in-memory buffer and trying to switch to +" the buffer on-disk (and fails, because it's a different buffer) +func Test_edit_different_buffer_on_disk_and_relative_path_to_disk() + call s:reset_all_buffers() + + let l:file_on_disk = tempname() + let l:directory_on_disk1 = fnamemodify(l:file_on_disk, ":p:h") + let l:name = fnamemodify(l:file_on_disk, ":t") + execute "edit " . l:file_on_disk + write! + + let l:directory_on_disk2 = l:directory_on_disk1 . "_something_else" + + if !isdirectory(l:directory_on_disk2) + call mkdir(l:directory_on_disk2) + endif + + execute "cd " . l:directory_on_disk2 + execute "edit " l:name + + let l:current = bufnr() + + call assert_equal(l:current, bufnr()) + set winfixbuf + call assert_fails("edit " . l:file_on_disk, "E1513:") + call assert_equal(l:current, bufnr()) + + call delete(l:directory_on_disk1) + call delete(l:directory_on_disk2) +endfunc + +" Fail :e when selecting a buffer from a relative path if in a different folder +" +" In this tests there's 2 buffers +" +" foo - lives on disk, in some folder. e.g. /tmp/foo +" foo - an in-memory buffer that has not been saved to disk. If saved, it +" would live in a different folder, /other/foo. +" +" The 'winfixbuf' is looking at the on-disk buffer and trying to switch to +" the in-memory buffer (and fails, because it's a different buffer) +func Test_edit_different_buffer_on_disk_and_relative_path_to_memory() + call s:reset_all_buffers() + + let l:file_on_disk = tempname() + let l:directory_on_disk1 = fnamemodify(l:file_on_disk, ":p:h") + let l:name = fnamemodify(l:file_on_disk, ":t") + execute "edit " . l:file_on_disk + write! + + let l:directory_on_disk2 = l:directory_on_disk1 . "_something_else" + + if !isdirectory(l:directory_on_disk2) + call mkdir(l:directory_on_disk2) + endif + + execute "cd " . l:directory_on_disk2 + execute "edit " l:name + execute "cd " . l:directory_on_disk1 + execute "edit " l:file_on_disk + execute "cd " . l:directory_on_disk2 + + let l:current = bufnr() + + call assert_equal(l:current, bufnr()) + set winfixbuf + call assert_fails("edit " . l:name, "E1513:") + call assert_equal(l:current, bufnr()) + + call delete(l:directory_on_disk1) + call delete(l:directory_on_disk2) +endfunc + +" Fail to call `:e first` if called from a starting, in-memory buffer +func Test_edit_first_buffer() + call s:reset_all_buffers() + + set winfixbuf + let l:current = bufnr() + + call assert_fails("edit first", "E1513:") + call assert_equal(l:current, bufnr()) + + edit! first + call assert_equal(l:current, bufnr()) + edit! somewhere_else + call assert_notequal(l:current, bufnr()) +endfunc + +" Allow reloading a buffer using :e +func Test_edit_no_arguments() + call s:reset_all_buffers() + + let l:current = bufnr() + file some_buffer + + call assert_equal(l:current, bufnr()) + set winfixbuf + edit + call assert_equal(l:current, bufnr()) +endfunc + +" Allow :e selecting the current buffer +func Test_edit_same_buffer_in_memory() + call s:reset_all_buffers() + + let l:current = bufnr() + file same_buffer + + call assert_equal(l:current, bufnr()) + set winfixbuf + edit same_buffer + call assert_equal(l:current, bufnr()) +endfunc + +" Allow :e selecting the current buffer as a full path +func Test_edit_same_buffer_on_disk_absolute_path() + call s:reset_all_buffers() + + let l:file = tempname() + let l:current = bufnr() + execute "edit " . l:file + write! + + call assert_equal(l:current, bufnr()) + set winfixbuf + execute "edit " l:file + call assert_equal(l:current, bufnr()) + + call delete(l:file) +endfunc + " Fail :enew but :enew! is allowed func Test_enew() call s:reset_all_buffers() |