diff --git a/runtime/lua/vim/_core/ui2/messages.lua b/runtime/lua/vim/_core/ui2/messages.lua index 1961084c38..4182fd573b 100644 --- a/runtime/lua/vim/_core/ui2/messages.lua +++ b/runtime/lua/vim/_core/ui2/messages.lua @@ -126,7 +126,7 @@ local function set_virttext(type, tgt) }) local row = texth.end_row local col = fn.virtcol2col(win, row + 1, texth.end_vcol) - local scol = fn.screenpos(win, row + 1, col).col ---@type integer + local scol = fn.screenpos(win, row + 1, col).endcol ---@type integer if type ~= 'last' then -- Calculate at which column to place the virt_text such that it is at the end @@ -179,7 +179,8 @@ local function set_virttext(type, tgt) -- Crop text on last screen row and find byte offset to place mark at. local vcol = texth.end_vcol - (scol - M.cmd.last_col) - col = vcol <= 0 and 0 or fn.virtcol2col(win, row + 1, vcol) + col = vcol <= 0 and 0 or fn.virtcol2col(win, row + 1, vcol + 1) - 1 + scol = fn.screenpos(win, row + 1, col).endcol M.cmd.prev_msg = mode > 0 and '' or M.cmd.prev_msg M.virt.cmd = mode > 0 and { {}, {} } or M.virt.cmd api.nvim_buf_set_text(ui.bufs.cmd, row, col, row, -1, { mode > 0 and ' ' or '' }) diff --git a/test/functional/ui/messages2_spec.lua b/test/functional/ui/messages2_spec.lua index 7fbee747fa..334b42365d 100644 --- a/test/functional/ui/messages2_spec.lua +++ b/test/functional/ui/messages2_spec.lua @@ -1118,4 +1118,94 @@ describe('messages2', function() -----------------------------------1,1 All| ]]) end) + + it('crops long messages to make place for ruler', function() + command('set noruler | echo "-"->repeat(&columns)') + screen:expect([[ + ^ | + {1:~ }|*12 + -----------------------------------------------------| + ]]) + feed('') + command('set ruler showcmd | echo "-"->repeat(&columns)') + screen:expect([[ + ^ | + {1:~ }|*12 + -----------------------------------0,0-1 All| + ]]) + feed('') + -- message with multibyte characters + command('echo "∙"->repeat(&columns)') + screen:expect([[ + ^ | + {1:~ }|*12 + ∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙0,0-1 All| + ]]) + feed('') + -- message with multicell characters + command('echo "-".."🙂"->repeat(&columns/2-1)') + screen:expect([[ + ^ | + {1:~ }|*12 + -🙂🙂🙂🙂🙂🙂🙂🙂🙂🙂🙂🙂🙂🙂🙂🙂🙂0,0-1 All| + ]]) + feed('') + command('echo "🙂"->repeat(&columns/2)') + screen:expect([[ + ^ | + {1:~ }|*12 + 🙂🙂🙂🙂🙂🙂🙂🙂🙂🙂🙂🙂🙂🙂🙂🙂🙂 0,0-1 All| + ]]) + feed('') + -- when cmdheight>1, only the last line is cropped + command('set cmdheight=2 | redraw | echo "-"->repeat(2*&columns)') + screen:expect([[ + ^ | + {1:~ }|*11 + -----------------------------------------------------| + -----------------------------------0,0-1 All| + ]]) + feed('') + command('set cmdheight=2 showbreak=> | redraw | echo "-"->repeat(2*&columns-1)') + screen:expect([[ + ^ | + {1:~ }|*11 + -----------------------------------------------------| + {1:>}----------------------------------0,0-1 All| + ]]) + command('set showbreak&') + feed('') + -- ruler is not shown after dismissing expanded cmdline with key press -> no need to crop + command('set cmdheight=1 | redraw | echo "-"->repeat(2*&columns)') + feed('k') + screen:expect([[ + ^ | + {1:~ }|*12 + -----------------------------------------------------| + ]]) + feed('') + -- messages are deferred until showcmd is cleared -> no need to crop for showcmd + command('lua vim.defer_fn(function() vim.cmd[[echo "-"->repeat(&columns)]] end, 50)') + feed('g') + screen:expect([[ + ^ | + {1:~ }|*12 + g 0,0-1 All| + ]]) + screen:sleep(100) + feed('') + screen:expect([[ + ^ | + {1:~ }|*12 + -----------------------------------0,0-1 All| + ]]) + feed('') + -- when the ruler is configured smaller, there is more space for messages + command('set rulerformat=%l | redraw | echo "-"->repeat(&columns)') + screen:expect([[ + ^ | + {1:~ }|*12 + ----------------------------------------------------0| + ]]) + end) end)