Skip to content

Conversation

@mattn
Copy link
Member

@mattn mattn commented Jan 7, 2026

Problem

When using conceal feature inside popup windows with fixed width, text is incorrectly truncated before reaching the popup's maxwidth. This happens because the conceal mechanism uses boguscols to track "phantom columns" for concealed characters, causing the rendering logic to think the line has reached the window width earlier than it actually has.

Reproduction

Run the following script:

set nocp
let lines = [
      \ "Here is a SECRET word that will be hidden."]

let s:win = popup_create(lines, {
      \ 'line': 1,
      \ 'col': 1,
      \ 'minwidth': 40,
      \ 'maxwidth': 40,
      \ 'maxheight': 10,
      \ 'border': [1,1,1,1],
      \ 'borderchars': ['-', '|', '-', '|', '+', '+', '+', '+'],
      \ 'wrap': 1,
      \ 'title': ' Conceal Popup Example ',
      \ })

call win_execute(s:win, join([
      \ 'setlocal conceallevel=2',
      \ 'setlocal concealcursor=nvic',
      \ 'syntax match HiddenSecret /SECRET/ conceal containedin=ALL',
      \ ], " | "))

redraw

Current (Incorrect) Output

+ Conceal Popup Example -----------------+
|Here is a  word that will be hidde      |
|n.                                      |
+----------------------------------------+

The text is truncated at "hidde" (40 characters including the concealed "SECRET" word's phantom space), cutting off "n." from "hidden."

Expected Output

+ Conceal Popup Example -----------------+
|Here is a  word that will be hidden.    |
|                                        |
+----------------------------------------+

The full text should be displayed within the 40-character width, since "SECRET" (6 chars) is concealed to a single space, making the actual visible text 37 characters.

Root Cause

In drawline.c, the conceal handling for wrapped lines uses boguscols to track phantom columns. The logic advances both wlv.col and wlv.boguscols to maintain consistent cursor positioning in normal windows. However, for popup windows with fixed maxwidth, this causes premature line wrapping because:

  1. wlv.col is incremented for each concealed character (to maintain cursor position)
  2. When wlv.col >= wp->w_width, the line is considered full and wraps
  3. But in popup windows, this prevents the actual visible text from using the full width

Solution

For popup windows with fixed width, skip the boguscols and col adjustments during conceal processing. This allows the actual visible content to determine when the line should wrap, rather than including phantom columns in the calculation.

The fix adds a check !WIN_IS_POPUP(wp) before adjusting wlv.col and wlv.boguscols in the conceal handling code, ensuring popup windows render concealed text correctly while maintaining the existing behavior for normal windows (where cursor position calculations depend on these adjustments).

truncated prematurely. The boguscols mechanism for tracking phantom
columns makes the line wrap too early.

Skip boguscols adjustments for popup windows to allow full text display.
@mattn
Copy link
Member Author

mattn commented Jan 7, 2026

FYI, this changes works fine with multi-byte text.

+ Conceal Popup Example -----------------+
|Here is a  word that will be hiddeあいう|
|えn.                                    |
+----------------------------------------+

mattn added 2 commits January 7, 2026 14:45
Test conceal with TAB characters to verify n_extra handling works
correctly. TAB characters are expanded using n_extra mechanism.
@mattn mattn force-pushed the popup-conceal-wrap branch from 7201deb to 5d07148 Compare January 7, 2026 12:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants