Problem: popup: missing Popup, PopupBorder and PopupTitle highlight groups
Solution: add Popup, PopupBorder and PopupTitle highlight groups and
fall back to Pmenu related highlighting groups (Yasuhiro Matsumoto).
fixes: #20110closes: #20208
Signed-off-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: In a multi-line statusline (and 'tabpanel'), %#XX# / %N*
set on one row do not persist on subsequent rows.
build_stl_str_hl_local() rebuilds stl_items[] from scratch
on every line break ("%@" or "\n"), so the highlight is
reset at each row boundary even though within a row it
stays until %* (or another %# / %*).
Solution: Carry the last Highlight item's stl_minwid across line
breaks via a new in/out int* parameter "carry_hl". At the
start of each row, pre-insert a Highlight item from the
carried value so the row begins under the same highlight;
before returning, update the carried value with the row's
final Highlight item. Apply the same carry to the
tabpanel rendering loop (Hirohito Higashi).
related: #19123
closes: #20180
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: Compile warning about unused variable
(Tony Mechelynck, after v9.2.0452)
Solution: Initialize the variable
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Since v9.2.0349, the vertical separator cell at status line
rows is drawn as a space with StatusLine highlight, hiding the
user's 'fillchars' "vert" or "stl"/"stlnc" character at that
cell (after v9.2.0349)
Solution: Drop the status line blend. At status line rows the separator
cell goes back to using the status fillchar when adjacent
status lines are connected, or the vsep character otherwise.
(Same as before v9.2.0348)
Keep the VertSplitNC highlight group introduced in v9.2.0349. The
highlight (VertSplit vs VertSplitNC) is selected based on whether the
current window is adjacent to the separator at the row.
Vertical separators are redrawn on current-window changes and on
:redrawstatus[!] so the VertSplit/VertSplitNC highlight is updated
immediately.
fixes: #20089
related: #19951
closes: #20167
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: screen_line() has four near-identical blocks computing
the popup_attr, the combined attr, the blend value and
the underlying base attr in sequence when handling popups
with opacity. The duplication makes the function long
and hard to follow, and changes have to be applied to all
four sites.
Solution: Extract the shared computation into popup_blend_with_base()
and popup_base_attr_or() helpers, and cache per-popup
attrs once via popup_opacity_T. No behavior change
(Yasuhiro Matsumoto).
closes: #20154
Signed-off-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: With a multi-line statusline clicking on a "%[FuncName]...%[]"
or "%@FuncName@..." region defined on a row other than the
last drawn row does not invoke the handler (Christian
Robinson, after v9.2.0338)
Solution: In win_redr_custom() the click region table reflects only the
last iteration of the per-row draw loop, so click regions are
recorded only for the last row. Move the click-region
resolution inside the loop and append regions for each row
using vim_realloc(). This also fixes a leak of
clicktab[].funcname for non-last rows (Hirohito Higashi).
fixes: #20116closes: #20120
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: In a vertical split where the pum overlaps the windows vsep column,
background draws (vsep at cursor row, status line,
redraw_vseps, idle ins_redraw) can write into cells that are
covered by the pum, because skip_for_popup() only protects
those cells while pum_will_redraw is set.
Solution: In skip_for_popup(), also skip cells under a visible pum when
the current draw is not the pum itself (screen_zindex
POPUPMENU_ZINDEX). Exclude the wildmenu pum (MODE_CMDLINE):
while the cmdline grows, pum_row is briefly stale and
protecting those cells would blank a cell of the wrapped
cmdline row (Yasuhiro Matsumoto).
closes: #20093
Signed-off-by: Yasuhiro Matsumoto <mattn.jp@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: 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>
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: cannot style non-current window separator
Solution: Add the VertSplitNC highlighting group
(Hirohito Higashi).
Add VertSplitNC highlight group for vertical separators of non-current
windows, similar to StatusLine/StatusLineNC distinction. The separator
adjacent to the current window uses VertSplit, others use VertSplitNC.
Default: linked to VertSplit.
At the current window's status line rows, the separator cell is drawn as
a space with the StatusLine highlight so it blends into the status line
without a stray fillchar glyph.
Also:
- :redrawstatus[!] now also redraws vertical separators.
- statusline height changes trigger vsep redraw.
closes: #19951
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: Cannot handle mouseclicks in the tabline
Solution: Support %[FuncName] click regions in 'tabline', add "area" key
to the click info dict (Yasuhiro Matsumoto).
The previous implementation resolved and stored click regions only for
per-window statuslines; the tabline path in win_redr_custom() (wp==NULL)
parsed %[FuncName] but discarded the regions, and tabline clicks were
dispatched via TabPageIdxs[] which didn't know about them.
Add a global tabline_stl_click array populated from the tabline path,
refactor stl_click_handler() to take the regions directly, and dispatch
matching clicks from do_mouse() before falling through to tab selection.
The winid entry in the callback dict is 0 for tabline clicks.
related: #19841
closes: #19950
Supported by AI.
Signed-off-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: popup: still opacity rendering issues
Solution: Fix remaining issues, see below
(Yasuhiro Matsumoto).
This PR fixes the following issues:
- Padding blend hole at wide char boundary: when a padding cell overlaps
the second half of a wide character, the right half's attr value is
unreliable. Use the left half's saved attr for blending instead.
- Wide char background split at popup boundary: when a wide character in
an upper popup straddles the edge of a lower opacity popup, both
halves got different background colors. Since terminals cannot render
different left/right background colors for a wide character, detect
the lower popup with popup_is_over_opacity() and use the non-popup
side's underlying attr for both halves.
- Wrong blend color with cterm-only highlights under 'termguicolors':
when a popup highlight has ctermbg but no guibg, bg_rgb is set to
CTERMCOLOR (not INVALCOLOR). hl_blend_attr() used this value as a real
RGB color, producing gray instead of the intended color. Use
COLOR_INVALID() to detect both INVALCOLOR and CTERMCOLOR, and fall back
to converting the cterm color number to RGB.
closes: #19943
Signed-off-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Cannot handle mouseclicks in the statusline
Solution: Add the %[FuncName] statusline item to define clickable
regions with a callback function. (Yasuhiro Matsumoto)
closes: #19841
Signed-off-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: When a tabpanel expression returns a different number of lines on
successive evaluations, the computed row offset can become negative,
causing screen_fill() to receive an invalid start_row and crash
(after v9.1.1391).
Solution: Clamp the row argument in screen_fill_tailing_area() to zero,
add a safety check in screen_fill() for negative start_row
(Michał Majchrowicz)
Supported by AI
Co-authored-by: Michał Majchrowicz <mmajchrowicz@afine.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: tabpanel: corrupted tabpanel during scrolling causing flicker
Solution: When the tabpanel is visible, force a line-by-line redraw in
win_do_lines() similarly to popup handling (Yasuhiro Matsumoto).
When a vertical tabpanel is visible, terminal scroll operations in
win_do_lines() affect the full screen width, corrupting the tabpanel
area. The tabpanel is then redrawn via redraw_tabpanel, causing visible
flicker. Return FAIL to force line-by-line redraw instead, analogous to
the existing popup_visible check.
closes: #19832
Signed-off-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: showmode message may not be displayed (Yee Cheng Chin)
Solution: Don't call char_avail() in skip_showmode(), but check
for anything in the stuff and typeahead buffer
(Hirohito Higashi).
Fix "-- VISUAL --" not shown when terminal responses are pending
When starting Vim with a script that enters Visual mode (e.g.
"vim -S script.vim"), the "-- VISUAL --" mode message sometimes
doesn't appear. This happens because skip_showmode() calls
char_avail(), which reads raw terminal input and picks up terminal
response escape sequences (e.g. t_RV response). Combined with
!KeyTyped (which is TRUE after script execution), this causes
skip_showmode() to return TRUE, preventing the mode from being
displayed.
Fix this by checking only the stuff buffer and typeahead buffer for
pending characters, instead of char_avail() which also reads raw
terminal input. This way, terminal response sequences no longer
interfere with mode display.
fixes: #16620closes: #19801
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Christian Brabandt <cb@256bit.org>
Signed-off-by: Hirohito Higashi <h.east.727@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: still possible flicker
Solution: Use redraw_as_cleared() instead of screenclear() to avoid
flicker (Yasuhiro Matsumoto).
When the window width matches the frame width, screenclear() causes
visible flicker. Use redraw_as_cleared() instead which marks the
screen for redraw without actually clearing it.
closes: #19732
Signed-off-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: MS-Windows: Rendering artifacts with DirectX
(Alexander Zhura)
Solution: Force redraw (Yasuhiro Matsumoto)
DirectWrite subpixel rendering (especially with CFF/OTF fonts) can
extend glyph pixels beyond cell boundaries. Vim already handles the
forward direction (redraw the next character when the current one
changes) for MS-Windows antialiasing, but the backward direction was
missing.
Add gui.directx_enabled flag accessible from screen.c and extend the
existing spill-over handling to:
- Redraw the current character when the previous one changed (backward)
- Force redraw of the next character in screen_puts_len() and
screen_fill() paths
fixes: #19586closes: #19761
Signed-off-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: When using transparent popups in the Win32 console, redrawing
background windows causes flickering. This happens because
the background is drawn opaquely before the popup blends
and draws on top.
Solution: Implement a Z-index mask to suppress screen_char() output for
cells covered by an opacity popup. Disable the Clear-to-EOL
(T_CE) optimization for lines overlapping these popups to
prevent accidental erasure (Yasuhiro Matsumoto).
closes: #19697
Signed-off-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: When drawing a custom tabline, if topframe->fr_width is
larger than Columns (possible during tab closure with
showtabpanel=1), Vim writes past the end of the
TabPageIdxs[] array.
Solution: Cap the column limit at Columns to ensure TabPageIdxs is
never accessed out-of-bounds (thinca).
closes: #19725
Supported by AI
Signed-off-by: thinca <thinca@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: popup: windows flicker when updating text
Solution: Only refresh the popup mask if the position or size changed,
manually set the window redraw type instead of using
redraw_win_later() to avoid triggering a full screen redraw.
Handle opacity 100 correctly. Keep "firstline" sticky when
setting options (Yasuhiro Matsumoto).
related: #19510
closes: #19559
Signed-off-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: popup: flickering on opaque popups with overlapping text,
even if they are opaque (after v9.2.0016).
Solution: Prevent double redrawing by skipping background updates for
opaque popups. Revert changes to test dumps
(Javier Jaramago Fernández).
A flickering effect was introduced in commit v9.2.0016 (commit:
6c203072f) for all popups. This is a consequence of a double redraw of
the overlapping background characters. This could be expected for
transparent popups, but, it should exclude opaque ones. For a complete
fix of the flickering this commit is required in combination with fix
present in v9.2.0064 (commit: 97c5bed84b).
Additionally this commit reverts changes introduced for tests dumps for
masks in commits 6c203072f and cded5e220. These dumps were updated
preventing characters from popups to take into account the masks
specified for them. This forces the redraw of popup characters, even
when masks attempt to prevent them, leading to flickering effects. See
issues #19510 and PR: #19534.
closes: #19534
Signed-off-by: Javier Jaramago Fernández <jaramago.fernandez.javier@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: 'listchars' "leadtab" not used in :list (after 9.2.0088).
Solution: Also check for "leadtab" when using :list. Fix memory leak on
E1572 if "multispace" or "leadmultispace" is set (zeertzjq).
closes: #19557
Signed-off-by: zeertzjq <zeertzjq@outlook.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Coverity complains about uninitialized var, also gcc warns
about a few other variables possibly being used uninitialized
(Tony Mechelynck, after v9.2.0093)
Solution: Initialize a few other variables.
Coverity CID: 1683101
closes: #19561
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Not possible to have window-local highlighting groups
(Hima)
Solution: Port Neovims 'winhighlight' option to Vim (Foxe Chen).
fixes: #3576closes: #19493
Signed-off-by: Foxe Chen <chen.foxe@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: cannot display tabs for indentation
Solution: Add the "leadtab" value to the 'listchars' option to
distinguish between tabs used for indentation and tabs used
for alignment (HarshK97).
closes: #19094
Signed-off-by: HarshK97 <harshkapse1234@gmail.com>
Signed-off-by: zeertzjq <zeertzjq@outlook.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Cannot have a mutli-line statusline.
Solution: Add support for multi-line statusline
(Hirohito Higashi).
closes: #19123
Signed-off-by: Hirohito Higashi <h.east.727@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Popup windows leave ghost images when moved. Visual options
do not trigger a redraw when updated via popup_setoptions().
An empty borderhighlight list fails to clear existing
highlights.
Solution: Modify f_popup_move() in src/popupwin.c to save the old
position before moving and force a redraw. Enhance
f_popup_setoptions() to trigger a redraw when
visual-affecting options change. Modify
apply_general_options() to explicitly clear border
highlights when an empty list is provided
(Yasuhiro Matsumoto).
closes: #19297
Signed-off-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: In screen_line(), there is a potential integer underflow when
accessing ScreenAttrs[off_to - 1] if off_to is zero.
(Coverity CID 1681430, after v9.2.0017)
Solution: Add a check to ensure off_to > 0 before accessing the
previous attribute index.
related: #19272
closes: #19479
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: syntax highlighting lost in popup with opacity lower than 100
(after v9.2.0017)
Solution: Before blending, combine the popup's window color attribute
with the character's own attribute using hl_combine_attr()
(Yasuhiro Matsumoto).
related: #19272
closes: #19478
Signed-off-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: popup: Popup windows do not support a transparency setting.
Solution: Add the "opacity" option to popup windows to support
transparency when using the GUI or 'termguicolors'
(Yasuhiro Matsumoto).
closes: #19272
Signed-off-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: When a popup window's border overwrites part of a wide
character from another popup, the remaining half loses its
original attribute (background color) because it is reset to 0.
Solution: Modify screen_line(), screen_puts_len(), and screen_fill() to
preserve the existing ScreenAttrs value when clearing wide
character boundaries. Also ensure background data is refreshed
for transparent popup cells (Yasuhiro Matsumoto).
closes: #19299
Signed-off-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: When a popup window partially overlaps a wide character
it results in truncated or garbage display.
Solution: When a wide character is partially blocked by a popup, clear both
cells in the screen buffer to prevent garbage (Yasuhiro Matsumoto).
closes: #19271
Signed-off-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: tabpanel: inconsistent use of cmdline and message area with
tabpanel
Solution: Reduce the cmdline and message area by the horizontal size of
the tabpanel (Hirohito Higashi)
closes: #18678
Signed-off-by: Hirohito Higashi <h.east.727@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Generating prototype files does not work on all platforms
Solution: Rework prototypes generation using python instead of cproto,
enable it in CI to test it for each PR (Hirohito Higashi).
closes: #18045
Signed-off-by: Hirohito Higashi <h.east.727@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Cannot configure the inner foldlevel indicator for the
foldcolumn
Solution: Add "foldinner" suboption value to the 'fillchar' option
(Maria José Solano).
closes: #18365
Signed-off-by: Maria José Solano <majosolano99@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: tabpanel not drawn correctly with wrapped lines
(utubo, after v9.1.1534)
Solution: Use Columns as width, not the frame width
(Hirohito Higashi)
fixes: #17774closes: #17809
Signed-off-by: Hirohito Higashi <h.east.727@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: The ruler disappears after typing the second character during
insert mode completion, even when completion messages are
suppressed ('shortmess' includes "c"). This makes the UI
appear inconsistent.
Solution: Ensure the ruler is restored during screen redraw when popup
completion is active (Girish Palya).
Notes:
No new tests were added, as existing screen dump tests were updated to
reflect the corrected behavior.
closes: #17770
Signed-off-by: Girish Palya <girishji@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: close button "X" is visible in the non-GUI 'tabline', even
when the mouse is disabled
Solution: only show the button when 'mouse' contains any of the flags
"anvi" (Girish Palya)
The tabline always displays an "X" (close) button, and the info popup
shows both a close button and a resize handle—even when the mouse is
disabled. These UI elements are only actionable with the mouse and serve
no purpose for keyboard users who disable the mouse. Displaying
non-functional, clickable elements in a non-GUI environment is
misleading and adds unnecessary visual clutter.
So remove the close button and resize handle when the mouse is disabled.
They appear again when mouse is enabled.
closes: #17765
Signed-off-by: Girish Palya <girishji@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: tabpanel: there are still some problems with the tabpanel with
column handling
Solution: fix the problems and refactor Tabpanel feature (Hirohito
Higashi).
fixes: #17423fixes: #17332closes: #17336
Signed-off-by: Hirohito Higashi <h.east.727@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Vim does not have a tabpanel
Solution: include the tabpanel feature
(Naruhiko Nishino, thinca)
closes: #17263
Co-authored-by: thinca <thinca@gmail.com>
Signed-off-by: Naruhiko Nishino <naru123456789@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>