Problem: Vim9: can't use v:true for option flags.
Solution: Add tv_get_bool_chk(). (closesvim/vim#6725)
----
"tv_get_bool_or_number_chk()" without vim9 params is identical to
"tv_get_number_chk()".
"tv_get_number_chk()" and tv"_get_bool_chk()" are identical
after excluding new vim9 params.
Yes, "want_bool" param is N/A because of "in_vim9script()".
If I port it, then I will refactor these macros or "static inline"
functions within "src/nvim/eval/typval.h".
----
36967b32fd
Co-authored-by: Bram Moolenaar <Bram@vim.org>
Problem: Vim9: hasmapto(), mapcheck() and maparg() do not take "true" as
argument.
Solution: Use tv_get_bool(). (closesvim/vim#6822, closesvim/vim#6824)
04d594b9c1
Co-authored-by: Bram Moolenaar <Bram@vim.org>
Problem: Vim9: index() does not take "true" as argument.
Solution: Use tv_get_bool_chk(). (closesvim/vim#6823)
6c553f9c04
Co-authored-by: Bram Moolenaar <Bram@vim.org>
Problem: Vim9: getreg() does not take "true" as argument.
Solution: Use tv_get_bool_chk(). (closesvim/vim#6820)
67ff97ded7
Co-authored-by: Bram Moolenaar <Bram@vim.org>
Problem: Vim9: expand() does not take "true" as argument.
Solution: Use tv_get_bool_chk(). (closesvim/vim#6819)
551d25e765
Co-authored-by: Bram Moolenaar <Bram@vim.org>
Problem: Crash when getcompletiontype()/getcompletion() gets a NULL string
(dvaave2025).
Solution: Do not write the NUL terminator in set_cmd_context() when the
cursor column is at or past the end of the string, since the
string may be a read-only literal.
fixes: vim/vim#20963closes: vim/vim#20964
Supported by AI.
e2dcefa0d8
Co-authored-by: Christian Brabandt <cb@256bit.org>
Problem: Closing the current tab page resets the alternate tab page, even
when that is another tab page which still exists, so that
CTRL-Tab stops working (igorlfs).
Solution: Restore the last used tab page after entering another one to
close the current one (Hirohito Higashi).
related: vim/vim#20965
closes: vim/vim#20973a05bd64c1d
Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Problem:
The insert-mode completion progress-message is in "running" state while
the user is selecting an item. That is noisy and unwanted UX; it was
only intended for the "Scanning..." task.
Solution:
End the progress-msg just after `ins_compl_show_statusmsg`.
Problem:
Some builtin features emit progress-messages which never "complete".
- On failure, `:write` does not complete the progress-msg it started.
- ins-completion never ends its "Scanning..." message.
Solution:
- `buf_write()` emits "failed" status on failure.
- `ins_compl_stop()` ends the completion one.
Problem: Vim9: error when passing getreginfo() result to setreg().
Solution: Use dict_get_bool() for "isunnamed". (closesvim/vim#6784)
6a950581da
Co-authored-by: Bram Moolenaar <Bram@vim.org>
Problem: Vim9: bufname('%') gives an error.
Solution: Only give an error for wrong argument type. (closesvim/vim#6807)
02aaad9109
Co-authored-by: Bram Moolenaar <Bram@vim.org>
Problem:
filemess() treats an empty suffix as "a buffer write is starting", but
readfile() calls it that way too. So ":read" (and ":edit", …) opens a
`nvim.bufwrite "<file>"` progress that is never completed.
Users of e.g. ghostty will see a stuck "progress" spinner.
Solution:
Only `buf_write()` starts the progress, via `filemess_progress()`.
Problem:
:bcd (buffer-local directory) is not preserved after
`nvim_open_win` or `nvim_win_set_buf`
Analysis:
set_curbuf() ends with update_cwd(), which falls back to
os_chdir(globaldir) when the target buffer has no b_localdir.
Solution:
Pass kCtxKeepCwd to ctx_switch().
Problem:
Re-editing a buffer (`:edit!`, re-reading a dir.lua buffer, etc.) drops
its `:bcd` directory, so the CWD falls back to the global one. Whereas
other buffer-local state (`b:` vars, local options) survives a reload.
Solution:
Don't clear buf dir in `buf_freeall()`; `do_ecmd()` calls that when
reloading/re-editing. `free_buffer_stuff()` still clears them when
a buffer is freed or reused for another file.
Problem: `TabLineSel` by default is defined with only bold attribute.
This makes selected tabpage stand out relatively well, but when used
in custom tabline it will be combined with `TabLineFill` (which is
reserved for the "non tabpage" part of the tabline).
Plus the behavior is not consistent with the default 'tabline' which
combines it with `Normal`.
Solution: Explicitly define background and foreground colors to come
from `Normal` to ensure the current default 'tabline' behavior even in
custom tabline.
The more semantically driven solution here is to link `TabLineSel` to
`StatusLine`. This makes it more aligned with how `TabLine` is linked
to `StatusLineNC`. But the current "bold text with `Normal` colors" is
argued to look better as a default.
Also make sure that 'notermguicolors' highlighting in default and
custom tablines is the same: the current tabpage does not have
underline and is not bold.
Problem:
'linebreak' filler and 'breakindent'/'showbreak' padding are screen
cells with no buffer character behind them, yet a decoration draws over
them whether or not it asked to cover such cells. A highlight bounded to
its text then paints a tail out to the edge of the row, most visible on
inline code spans from plugins. That same highlight already leaves the
cells past the end of a line alone, so it treats identical cells two
different ways.
Solution:
Only a decoration with 'hl_eol' draws the gaps, which is what the flag
already means at the end of a line. A full-width background such as a
fenced code block sets it and still covers them. Classic :syntax has no
such flag and is unchanged.
Problem:
- buf-local CWD scope is lower priority than :lcd, which is weird.
```
win > buf > tab > global
```
- No way to clear current CWD at a given scope.
Solution:
- Rerrange scope precedence to:
```
buf > win > tab > global
```
- Introduce "bang" variants (`:bcd!`/`:lcd!`/`:tcd!`) which clears the
local CWD for the given scope.
vim-patch:8.2.1091: no check if opening a pty works
vim-patch:8.2.1120: Python code not tested properly
vim-patch:9.2.0911: makefiles do not build hardcopy_postscript.c
vim-patch:9.2.0915: tests: two terminal tests in test_popupwin fail on FreeBSD
vim-patch:8.2.0290: running individual test differs from all tests
vim-patch:8.2.1132: Vim9: return type of repeat() is not specific enough
vim-patch:8.2.1133: Vim9: return type of add() is not specific enough
vim-patch:8.2.1136: Vim9: return type of argv() is always any
vim-patch:8.2.1138: Vim9: return type of copy() and deepcopy() is any
vim-patch:8.2.1140: Vim9: return type of extend() is any
vim-patch:8.2.1141: Vim9: return type of filter() is any
vim-patch:8.2.1142: Vim9: return type of insert() is any
vim-patch:8.2.1143: Vim9: return type of remove() is any
vim-patch:8.2.1144: Vim9: return type of reverse() is any
vim-patch:8.2.1158: build error
vim-patch:8.2.1176: Vim9: not enough type checking in Vim9 script
vim-patch:8.2.1191: Vim9: crash when function calls itself
vim-patch:8.2.1205: Vim9: && and || work different when not compiled
vim-patch:8.2.1290: Vim9: cannot replace a global function
vim-patch:8.2.1355: Vim9: no error using :let for options and registers
vim-patch:8.2.1373: Vim9: no error for assigning to non-existing script var
vim-patch:8.2.1376: Vim9: expression mapping causes error for using :import
vim-patch:8.2.1380: Vim9: return type of getreg() is always a string
vim-patch:8.2.1387: Vim9: cannot assign to single letter variable with type
vim-patch:8.2.1403: Vim9: Vim highlighting may fail in cmdline window
vim-patch:8.2.1437: Vim9: 'statusline' is evaluated using Vim9 script syntax
vim-patch:8.2.1447: Vim9: return type of keys() is list
vim-patch:8.2.1459: Vim9: declaring script var in script does not infer the type
vim-patch:8.2.1477: Vim9: error when using bufnr('%')
vim-patch:8.2.1502: Vim9: can use += with a :let command at script level
vim-patch:8.2.1509: vertical separator is cleared when dragging a popup window
vim-patch:8.2.1514: multibyte vertical separator is cleared when dragging popup
vim-patch:8.2.4962: files show up in git status
vim-patch:9.2.0918: screen: fill char with a zero low byte is stored as a NUL cell
vim-patch:9.2.0919: screen: the wrong array is copied into ScreenCols on a resize
Problem:
Evaluating 'statuscolumn' overwrites transchar_charbuf[], which breaks
the drawing of an unprintable char if p_extra points there.
Solution:
Make a copy in wlv.extra so that it won't be overwritten.
Problem:
Giving a window a status line when `'laststatus'` starts requiring one
takes the row from a resizable frame found by walking up the frame
tree, but only the window's own leaf frame is grown back. Every frame
between the leaf and the donor keeps its old height, so a later resize
hands out a row that does not exist and a window's status line ends up
on the command line.
Solution:
Grow the window's frame with `frame_setheight()`, which takes the row
from a neighbouring frame and keeps every enclosing frame consistent.
Problem:
- Explicit `:bcd` (etc.) persists from `nvim_buf_call()` but not from an
autocmd handler targeting a hidden buf (`LspAttach`, `TermRequest`, …),
which needs a `vim.schedule()` workaround.
- `vim._with()` is supposed to work as a "sandbox", discarding
side-effects, but it leaks CWD changes: `:lcd` from a `win` context,
any chdir from a visible-buffer context.
Solution:
- Explicit :cd/:tcd/:bcd during a temp context persists by default.
- "Ambient" directory changes ('autochdir', existing win-local CWD,
etc.) are still undone, as before.
- Add `kCtxKeepDirs`: snapshot/restore the target's full CWD state
(w/b/tp-local, global, cwd). Used by `vim._with()` and `'inccommand'`,
which must not leak state.
Problem: Vim9: true and false not recognized in Vim9 script.
Solution: Recognize true and false.
5d2eb0fff0
Co-authored-by: Bram Moolenaar <Bram@vim.org>
Problem: After :diffget into an empty buffer, undo does not restore the
empty buffer, the last line stays behind (Narendran
Gopalakrishnan)
Solution: Include the empty line of the empty buffer in the undo
information, it is deleted once the first line was obtained
(Hirohito Higashi).
fixes: vim/vim#20950closes: vim/vim#20951c44f35ca1a
Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Problem: ins_compl_add() checks for a duplicate by scanning the whole
match list, making collection of N matches quadratic.
Solution: Look matches up in a hashtab instead; each entry counts the
matches with that string (Samuel Schlesinger).
closes: vim/vim#2092631b7b1a7da
Co-authored-by: Samuel Schlesinger <sgschlesinger@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
vim-patch:fe712ced6 Fix duplicated code that only appears in git.
vim-patch:8.2.1032: error message for declaring a variable cannot be translated
vim-patch:8.2.4344: Amiga: header file included twice
vim-patch:9.1.0979: VMS: type warning with $XDG_VIMRC_FILE
vim-patch:8f214168b runtime(doc): Update os-support section for Amiga OS
vim-patch:9.1.1894: global_runtime_dir appends /after directory when using XDG
vim-patch:9.2.0029: STRLEN() used for a string literal
vim-patch:4ed08ee60 runtime(doc): document Solaris as supported OS
vim-patch:9.2.0897: GTK3 X11 redraws are not coalesced
vim-patch:9.2.0900: FocusGained still triggered when closing dialog
vim-patch:bc71c0b3f runtime(doc): remove todo entries that are fixed
vim-patch:9.2.0903: Vim9: cannot use an exported function of an autoload import
vim-patch:9.2.0905: MS-Windows: ghost cursor with ligatures
vim-patch:78ebe0f42 CI: bump clang to v22 in ci-linux_asan
vim-patch:8.2.0972: Vim9 script variable declarations need a type
vim-patch:8.2.0973: Vim9: type is not checked when assigning to a script variable
vim-patch:8.2.1003: Vim9: return type of sort() is too generic
vim-patch:8.2.1024: Vim9: no error for using "let g:var = val"
vim-patch:8.2.1028: Vim9: no error for declaring buffer, window, etc. variable
vim-patch:8.2.3722: Amiga: superfluous messages for freeing lots of yanked text
vim-patch:8.2.3837: QNX: crash when compiled with GUI but using terminal
vim-patch:8.2.3881: QNX: crash when compiled with GUI but using terminal
vim-patch:9.1.0337: Missing entry for XDG vimrc file in :version
vim-patch:9.1.0345: Problem: gvimrc not sourced from XDG_CONFIG_HOME
vim-patch:9.1.0393: 'viewdir' not respecting $XDG_CONFIG_HOME
vim-patch:9.1.0680: VMS does not have defined uintptr_t
vim-patch:9.1.1803: Amiga: build errors
Problem:
With `laststatus=3`, a pager float shares the main grid's statusline
row. Setting a diagnostic fires `DiagnosticChanged`, whose handler calls
`nvim__redraw({ statusline = true })`.
Analysis:
Inside the autocmd, `curwin` is temporarily switched to the tiled window
showing that buffer, so `win_redr_status()` paints its statusline over
the pager's `[Pager]` statusline on the shared row. After the autocmd,
`curwin` is restored but the pager statusline is never repainted.
Solution:
Use `ctx_saved_curwin()` decide whether to draw the global statusline,
matching `win_redr_stl_expr()` and `update_screen()`. No behavior change
if no buffer-context switch is active.
Problem: An OSC 52 sequence from a :terminal job passes the decoded
payload to the clipboard provider as a single list item. Command-line
providers (pbcopy, xclip, ...) receive it with channel semantics, where
a newline inside an item is sent as NUL (:h chansend()), so multiline
copies arrive with NUL bytes instead of newlines.
Solution: Split the payload on newlines into a proper list of lines.
A trailing newline yields a final empty item, which chansend() turns
back into a newline, so payloads round-trip exactly.
Problem: A winbar-only window with zero text height still occupies one row,
but win_update() returns early on w_view_height == 0 and skips the
vertical separator.
Solution: Also draw the vertical separator in the early return path.
Problem:
Buffer-local CWD (:bcd) is "sticky", similar to window-local CWD (:lcd).
But this contradicts one of its main benefits: per-buffer "project root"
for LSP, OSC7.
Other problems:
- A buffer created with :edit/:enew/:new silently inherits b_localdir
(and b_prevdir) from the previous buffer.
- curbuf_reusable() refuses to recycle a scratch buffer that has
`b_localdir`.
- After :new/:vnew/:tabnew the CWD sticks to previous buffer's
`b_localdir` even though the new curbuf has none, so :new is not
equivalent to ":split | enew", and getcwd() disagrees with
haslocaldir().
- Requires "which buffer spawned this buffer" semantics that no other
buffer-local state has.
Solution:
Drop sticky/inherit behavior of buffer-local CWD (:bcd).
- do_ecmd: always apply the new curbuf's dir (`fix_current_dir`), like
`do_autochdir` already does. :tabnew from a :bcd buffer now reverts to
global CWD (and fires DirChanged), same as :tabnew from a :lcd window.
- curbuf_reusable(): recycling a scratch buffer frees its b_localdir.
To get sticky/inherit behavior of CWD, use `:lcd`.
Problem:
No way to set a buffer-local directory.
Use-cases:
- "Root dir" for LSP (and the "project" concept).
- `:terminal` OSC 7
Solution:
Add `:bcd` command.
- Extend `getcwd()` to take a third arg; `getcwd(-1, -1, bunfr)` returns
the buffer-local working directory.
- Buffer-local directories have less priority than window-local
ones, and more priority than tab-local ones.
Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
Problem:
Ignore is linked to Normal by default, making the text visible instead
of hidden.
Solution:
Replace the default link with an explicit highlight definition using
ctermfg=0 guifg=bg.
Problem:
Assigning to the local value of a global-local boolean option
('autoread', 'autocomplete', 'fsync') aborts:
Assertion failed: (curval.type == newval.type), function
ex_let_option, file vars.c, line 1408.
ex_let_one
ex_let_vars
ex_let
execute_cmd0
do_cmdline
call_user_func
...
eval_map_expr
vgetorpeek
vgetc
state_enter
main
A global-local option may have local value `kObjectTypeUnset`, but
`ex_let_option()` guards only `kObjectTypeNil`.
Solution:
When curval is Unset, resolve it to the inherited global value.