Problem: DECRQM was still sent to Apple Terminal.app before its DA2
reply was processed, leaving a literal "pp" on screen.
may_req_decrqm() was called from vim_main2()
right after may_req_termresponse(), at which point
term_props[TPR_DECRQM].tpr_status was still TPR_UNKNOWN, so
the `!= TPR_NO` guard let the request through (after v9.2.0387)
Solution: Send DECRQM from handle_version_response() once
term_props[TPR_DECRQM].tpr_status == TPR_YES, the same
pattern already used for t_RS (TPR_CURSOR_STYLE) and t_RC
(TPR_CURSOR_BLINK), which deliberately wait for the DA2
reply to avoid the same echo-on-screen issue on Apple
Terminal.app and Gnome terminal. Drop the now-unused
may_req_decrqm() helper and its call site in vim_main2()
(Hirohito Higashi).
fixes: #19852
related: #19938
closes: #20038
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: John Marriott <basilisk@internode.on.net>
Signed-off-by: Hirohito Higashi <h.east.727@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Sending DECRQM from handle_version_response() caused DECRPM
responses to arrive during user input processing, leaving
bytes in typebuf when clear_showcmd() ran. This made
visual-mode showcmd (e.g. "7" line count after V<C-D><C-D>)
intermittently disappear, failing many screendump tests on CI.
Solution: Move DECRQM request out of handle_version_response() and send
it at startup via may_req_decrqm(), following the existing
may_req_termresponse() and may_req_bg_color() pattern.
Add TPR_DECRQM property set per terminal from the DA2 reply,
and route DECRQM sends through a may_req_decrqm() helper using
the termrequest_T pattern, skipping terminals known to
mishandle it (Foxe Chen, Hirohito Higashi).
fixes: #19852closes: #19938
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Hirohito Higashi <h.east.727@gmail.com>
Co-Authored-By: Foxe Chen <chen.foxe@gmail.com>
Signed-off-by: Hirohito Higashi <h.east.727@gmail.com>
Signed-off-by: Foxe Chen <chen.foxe@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: No scroll/scrollbar support in the tabpanel
Solution: Add support for it (Yasuhiro Matsumoto)
closes: #19979
Signed-off-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Code like ${!#} flags the "#" as shDerefWordError [1]; the "!prefix"
syntax region delegates to one of the shDerefSpecial handlers via
@shDerefList, but it misses the "#" case as valid for ${##} and ${!#}.
[1]: https://vi.stackexchange.com/q/48617/10604
Correct that. Indirection is only valid in Bash in Ksh, so rearrange the
"!" handling to be conditional.
closes: #20016
Helped-by: Christian Brabandt <cb@256bit.org>
Signed-off-by: D. Ben Knoble <ben.knoble+github@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Integer overflow with "ze" and large 'sidescrolloff'.
Solution: Check for overflow to avoid negative w_leftcol (zeertzjq).
closes: #20026
Signed-off-by: zeertzjq <zeertzjq@outlook.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
A new graphqlEscape syntax graph has been introduced to represent escape
sequences within strings, including the braced unicode form (\u{H+})
added in the September 2025 specification.
See: https://spec.graphql.org/September2025/closes: #20030
Signed-off-by: Jon Parise <jon@indelible.org>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: A <Cmd> command executed from Insert mode can sync undo and
move the cursor before the next edit. stop_arrow() saved the
new cursor line for undo, but left Insstart at the previous
insertion point. A line-start backspace could then delete
lines above the saved line without saving the joined range,
leaving a pending undo entry whose bottom resolved above
its top and raising E340.
Solution: Update Insstart and Insstart_textlen after the pending undo
save so the next edit starts from the command-updated cursor
position (Jaehwang Jung).
closes: #20031
AI-assisted: Codex
Signed-off-by: Jaehwang Jung <tomtomjhj@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: runtime(netrw): shell-injection via sftp: and file: URLs
(Joshua Rogers)
Solution: Escape temporary file names, harden filename suffix regex,
drop unused g:netrw_tmpfile_escape variable
Supported by AI
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Wayland: focus-stealing is non-working
Solution: Remove it, the feature could be re-implemented using
clipboard-providers feature, see :h wayland-primary-selection
(Foxe Chen).
closes: #19984
Signed-off-by: Foxe Chen <chen.foxe@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: ins_compl_stop() sets compl_best_matches = 0, but that's a
pointer, should reset compl_num_bests instead,
find_common_prefix() reads cpt_sources_array[cur_source] without
checking cur_source != -1 which causes an OOB for -1,
find_next_completion_match(): second `if` in the pending loop
should be `else if`. Forward paging only moves one step per call.
Solution: Reset compl_num_bests instead, add a check for cur_source not
equal -1, change if to else if (glepnir)
closes: #20000
Signed-off-by: glepnir <glephunter@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: gui.color_approx in gui_T has not been assigned anywhere since
patch 7.4.2094 ("The color allocation in X11 is overly
complicated", 2016), which dropped the single "gui.color_approx = TRUE;"
site. Because the member is zero-initialized and never written, the
check "if (gui.color_approx)" in gui_mch_init() is always false and the
"E458: Cannot allocate colormap entry, ..." warning can never be
emitted.
Solution: Remove the struct member and the unreachable branch. The E458
error definition is removed. Update the example error code
"E458" in the ex_eval.c comment to "E457" accordingly.
closes: #20007
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Hirohito Higashi <h.east.727@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Several win_T fields are declared as "int" or "char" but are
used strictly as boolean flags with TRUE/FALSE values. The
integer types obscure the boolean intent and are wider than
needed.
Solution: Change the following win_T members to bool (stdbool.h) and
update their assignments from TRUE/FALSE to true/false
accordingly.
The following conversions have been done:
- int -> bool (10 members):
w_set_curswant, w_botfill, w_old_botfill, w_do_win_fix_cursor,
w_popup_fixed, w_border_highlight_isset, w_cline_folded,
w_redr_status, w_arg_idx_invalid, w_has_scrollbar
- char -> bool (4 members):
w_topline_was_set, w_ru_empty, w_fold_manual, w_foldinvalid
No existing code compares these members against TRUE/FALSE explicitly or
uses ++/-- / bitwise ops on them, so only plain assignments are
affected.
Excluded:
- w_locked (recursion counter with ++/--),
- w_want_scrollbar (may hold -1 from dict_get_bool),
- w_winbar_height (used in arithmetic and exposed as number via
getwininfo()).
related: #20005
closes: #20008
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Hirohito Higashi <h.east.727@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Several gui_T fields are declared as "int" or "char" but are
used strictly as boolean flags with TRUE/FALSE values. The
integer types obscure the boolean intent and are wider than
needed.
Solution: Change the following gui_T members to bool (stdbool.h) and
update their assignments from TRUE/FALSE to true/false
accordingly (Hirohito Higashi)
The following conversions have been done:
- int -> bool (11 members):
in_focus, in_use, starting, dying, dofork, dospawn,
pointer_hidden, force_redraw, directx_enabled, font_can_bold,
which_scrollbars[3]
- char -> bool (2 members):
cursor_is_valid, menu_is_active
No existing code compares these members against TRUE/FALSE explicitly
(e.g. "== TRUE"), so only plain assignments are affected.
gui_init() used counter-style "--gui.starting" / "++gui.starting" to
temporarily clear the flag across a call to gui_mch_enable_menu().
With gui.starting now bool this triggers -Werror=bool-operation, so
replace it with an explicit save/restore.
X11 Bool members (rsrc_rev_video, color_approx) are intentionally left
unchanged: rsrc_rev_video is registered as an X Toolkit resource with
XtRBool / sizeof(Bool) and must keep the int-sized X11 Bool type.
closes: #20005
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Hirohito Higashi <h.east.727@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: When an `if` condition is constant true, the `else` block is
skipped during compilation. However, any `elseif` condition
within that skipped block was still compiled. This caused
errors when the condition referenced variables only declared
in the skipped block or when it checked for missing features
(like `has('clipboard')`) (Coacher)
Solution: In compile_elseif(), when scope->se_skip_save is
already SKIP_YES, skip compiling the elseif condition
expression using skip_expr_cctx() (Furkan Sahin)
fixes: #19160closes: #20021
Signed-off-by: Furkan Sahin <furkan-dev@proton.me>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: prop_find() does not find a virt text in the starting line
(@rickhowe, after v9.2.0320)
Solution: Do not skip virtual text properties with tp_col == MAXCOL on
the starting line (Furkan Sahin)
The column matching logic incorrectly skipped virtual text properties
with tp_col == MAXCOL on the starting line. Exclude such properties
from the column range check so they are always found.
fixes: #20013closes: #20019
Signed-off-by: Furkan Sahin <furkan-dev@proton.me>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: c_CTRL-{G,T} does not handle offset, when cycling between
matches
Solution: Refactor parsing logic into parse_search_pattern_offset() and
handle offsets, note: highlighting does not handle offsets
yet (Barrett Ruth).
fixes: #19991closes: #19998
Signed-off-by: Barrett Ruth <br.barrettruth@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Ctrl-R mapping not triggered during completion.
Solution: Move Ctrl-R check out of vim_is_ctrl_x_key()
(zeertzjq).
fixes: #20004closes: #20006
Signed-off-by: zeertzjq <zeertzjq@outlook.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: pum: rendering issues with multibyte text and opacity
Solution: Fix trailing-cell handling near popup text boundary,
use popup attrs on opaque popup text,
preserve right border when bg wide char spills,
blend popup text bg with underlying bg,
fix wide background char corruption
(Yasuhiro Matsumoto)
closes: #20017
Signed-off-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Also:
- drop a few trailing whitespaces
- mark the oneline keyword for :syn keyword as error in the
Vim syntax script, add tests for it.
closes: #20018
Signed-off-by: Eisuke Kawashima <e-kwsm@users.noreply.github.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: filetype: ghostty config files are not recognized
Solution: Detect ghostty configuration files as ghostty filetype,
include a simple ghostty filetype plugin (Bez Hermoso)
closes: #20002
Co-authored-by: Christian Brabandt <cb@256bit.org>
Signed-off-by: Bez Hermoso <me@bez.dev>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Duplicate code with literal string_T assignment
Solution: Add STR_LITERAL_SET() macro for string_T literal assignment
(Hirohito Higashi).
Previously, assigning a string literal to a string_T variable required
two lines that repeated the literal:
s.string = (char_u *)"open";
s.length = STRLEN_LITERAL("open");
Writing the literal twice is error-prone -- a typo in one of them
leaves the pointer and the cached length out of sync.
Add a STR_LITERAL_SET() macro in macros.h so that the assignment can
be written in one statement with the literal appearing only once:
STR_LITERAL_SET(s, "open");
Replace all occurrences of the two-line pattern across the codebase
with the new macro.
No functional change.
related: #19999
related: #20023
closes: #20025
Signed-off-by: Hirohito Higashi <h.east.727@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: multiple definitions of STRING_INIT macro
Solution: Refactor use of STRING_INIT and use a single
STR_LITERAL_INIT() macro instead
(Hirohito Higashi)
Consolidate the ad-hoc STRING_INIT() macros that were defined and used
locally in multiple source files. Define a single STR_LITERAL_INIT()
macro in macros.h and replace all previous STRING_INIT() usages with it.
No functional change.
related: #19999
closes: #20023
Signed-off-by: Hirohito Higashi <h.east.727@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: too many strlen() calls when adding strings to dicts
Solution: Refactor code to use string_T, use dict_add_string_len()
instead of dict_add_string() (John Marriott)
Additionally:
- In textprop.c, in function prop_fill_dict() use a string_T to store
local variable text_align.
- In popupwin.c, use a string_T to store struct member pp_name in struct
poppos_entry_T.
- In mark.c, refactor function add_mark() to pass in the length of
argument mname.
- In insexpand.c:
->Use a string_T to store the elements of static array
ctrl_x_mode_names.
->Refactor function trigger_complete_done_event():
->->change type of argument char_u *word to string_T *word.
->->make one access of array ctrl_x_mode_names instead of two.
->Refactor function ins_compl_mode() to accept a string_T to return the
resulting string.
- In fileio.c:
->Refactor function getftypewfd() to accept a string_T to return the
resulting string.
->In function create_readdirex_item() use a string_T to store local
variable q.
- In cmdexpand.c, store global cmdline_orig as a string_T.
- In autocmd.c, in function f_autocmd_get() use a string_T to store local
variables event_name and group_name. Measure their lengths once when
they are assigned so they are not remeasured on each call to
dict_add_string() in the subsequent for loop.
- In channel.c, in function channel_part_info() drop local variable status
and use s instead. Make s a string_T.
closes: #19999
Signed-off-by: John Marriott <basilisk@internode.on.net>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: runtime(netrw): ~ note expanded on MS Windows
(Tom Vamvanij)
Solution: Expand ~ on MS Windows (Yasuhiro Matsumoto)
On Windows, ":Explore ~" did nothing because the tilde expansion was
gated to Unix/Cygwin only. Additionally, substitute() interprets
backslashes in the replacement string specially (e.g. \U as a case
modifier), which would corrupt $HOME values like C:\Users\name even
if the branch were taken.
Include has("win32") in the guard, anchor the pattern to the start of
the string, and escape backslashes, ampersands and tildes in $HOME
before substituting.
fixes: #20003closes: #20014
Signed-off-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: pum: flicker when updating pum in place
Solution: Skip update_screen() when the popup menu is redrawn
at the same position (Yasuhiro Matsumoto).
closes: #20015
Signed-off-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: using int as bool
Solution: refactor: use bool type for internal flags in buf_T
(Hirohito Higashi)
Change the type of 23 internal state flag fields in buf_T from int
to bool for improved type clarity and code readability.
These fields are pure boolean flags that are never accessed via the
option system's varp (which uses *(int *)varp = value), never compared
with int fields holding non-0/1 values, and never use tristate values.
Converted fields:
- State flags: b_dev_valid, b_saving, b_mod_set, b_new_change,
b_marks_read, b_modified_was_set, b_did_filetype, b_keep_filetype,
b_au_did_filetype, b_u_synced, b_scanned, b_p_initialized
- Characteristic flags: b_has_textprop, b_may_swap, b_did_warn,
b_help, b_spell, b_shortname, b_has_sign_column, b_netbeans_file,
b_was_netbeans_file, b_write_to_channel, b_diff_failed
All TRUE/FALSE assignments to these fields have been updated to
true/false accordingly. The type of temporary save variables
(e.g. help_save in tag.c) has also been adjusted to bool.
Option value fields (b_p_XXX) are kept as int because they are
accessed via the option system and some use tristate (-1) semantics.
Fields compared with int option values (b_start_eof, b_start_eol,
b_start_bomb) are also kept as int to preserve comparison integrity.
closes: #20020
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Hirohito Higashi <h.east.727@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Vim9: variable shadowed by script-local function
(Mao-Yining)
Solution: Set is_global flag to true in find_func() (Furkan Sahin)
fixes: #20009closes: #20011
Signed-off-by: Furkan Sahin <furkan-dev@proton.me>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Resizing a smoothscrolled wrapped window to its textoff width
with 'showbreak' can leave wrapped continuation lines with
zero text width. win_lbr_chartabsize() still runs the partial max_head_vcol calculation in
that state and divides by width2, crashing during redraw.
Solution: Skip that partial head calculation when the wrapped
continuation width is zero, matching the other width2 guards
in charset.c (Jaehwang Jung)
closes: #20012
AI-assisted: Codex
Signed-off-by: Jaehwang Jung <tomtomjhj@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: tests: no tests for ch_listen() with IPs
Solution: Add tests that this is disallowed
(Zdenek Dohnal)
The functionality was removed, so the test is to make sure it fails
as expected.
closes: #19997
Signed-off-by: Zdenek Dohnal <zdohnal@redhat.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Before 71fd19d7ac this function went
through a `:!` command on all platforms, so it needed special escaping for `#` and
others. After that commit it doesn't go through that path on unix
platforms. Then with 48581f2ba9 this
escaping was re-added on unix and it's needs since it goes through
`sh -c`, but it should not have the extra escaping specific to `:!`.
Specifically my original broken command is:
```
PATH=/usr/bin:/bin VIMRUNTIME=~/dev/vim/runtime ./src/vim -u NONE -c 'call dist#vim9#Open("https://github.com/keith/dotfiles/blob/7bce9f5c697df6a549cf97bf5606d8b639e5bf5a/vimrc#L19")'
```
Where the `#L19` ends up being opened as `%5C#L19`. But I verified this
case still works as well:
```
PATH=/usr/bin:/bin VIMRUNTIME=~/dev/vim/runtime ./src/vim -u NONE -c 'call dist#vim9#Open("foo bar.txt")'
```
Which is what would otherwise break if we weren't doing any shell
escaping on unix.
closes: #19996
Signed-off-by: Keith Smiley <keithbsmiley@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Say explicitly that ":setlocal" sets the local value, while ":set" also
sets the global value.
related: #19993
Signed-off-by: zeertzjq <zeertzjq@outlook.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Added the fallowing.
djangoStatement:
- querystring: Added in version Django 5.2.
- lorem: Added in version Django 1.8.
- verbatim: Added in version Django 1.10.
djangoFilter:
- force_escape: Added in version Django 1.8.
- iriencode: Added in version Django 1.8.
- json_script: Added in version 2.1.
- truncatechars_html: Added in version 1.7.
> According to current documentation the added keywords are supported [Django version 6](https://docs.djangoproject.com/en/6.0/ref/templates/builtins).
related: #19994
Signed-off-by: tecis <67809811+tecis@users.noreply.github.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Cannot handle mouse-clicks in the tabpanel
Solution: Add support using the %[FuncName] atom for the tabpanel
(Yasuhiro Matsumoto)
Extend the statusline/tabline click region mechanism to work with
'tabpanel'. The callback receives a dict with "area" set to "tabpanel"
and a "tabnr" key indicating which tab page label was clicked.
closes: #19960
Signed-off-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: wrong VertSplitNC highlighting on winbar
(Maxim Kim, after v9.2.0349)
Solution: Use VertSplit instead of VertSplitNC for winbar rows
(Hirohito Higashi).
vsep_row_is_curwin() and right_neighbor_at_row() used W_WINROW() which
excludes winbar rows from the window's range. This caused the vertical
separator at winbar rows to use VertSplitNC even when curwin is adjacent.
Use w_winrow directly so winbar rows are included in the range check.
fixes: #19985closes: #19987
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Hirohito Higashi <h.east.727@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: runtime(vimball): still path traversal attacks possible
Solution: block Windows driver letter paths (Yasuhiro Matsumoto)
The path traversal check in vimball#Vimball() did not reject file
names starting with a Windows drive letter (e.g. "C:/foo"). Backslashes
are normalized to forward slashes earlier, so UNC paths are caught by
the leading-slash check, but absolute drive-letter paths slipped
through and could write outside of g:vimball_home on Windows.
Add a "^\a:" check next to the existing "^/" check, and cover it with
a new test.
closes: #19989
Signed-off-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: [security]: command injection via backticks in tag files
(Srinivas Piskala Ganesh Babu, Andy Ngo)
Solution: Disallow backticks before attempting to expand filenames.
Github Advisory:
https://github.com/vim/vim/security/advisories/GHSA-cwgx-gcj7-6qh8
Supported by AI
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Cannot apply 'scrolloff' context lines at end of file
Solution: Add the 'scrolloffpad' option to keep 'scrolloff' context even
when at the end of the file (McAuley Penney).
closes: #19040
Signed-off-by: McAuley Penney <jacobmpenney@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: runtime(tar): missing path traversal checks in tar#Extract()
Solution: Add check for leading slash, however gnu tar should already
detect this (q1uf3ng)
tar#Extract() did not check for ../ sequences or absolute paths,
unlike zip#Extract() which was patched in recent commits. Add the
same checks: ../ (relative traversal), leading slash (Unix), drive
letter and UNC/leading slash (Windows).
closes: #19981
Signed-off-by: q1uf3ng <q1uf3ng@protone.me>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: filetype: not all Bitbake include files are recognized
Solution: Enhance the file detection logic and consider varflags
(Martin Schwan)
closes: #19983
Signed-off-by: Martin Schwan <m.schwan@phytec.de>
Signed-off-by: Christian Brabandt <cb@256bit.org>