aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/drawscreen.c
Commit message (Collapse)AuthorAge
* refactor(grid): unify the two put-text-on-the-screen code pathsbfredl2023-09-29
| | | | | | | | | | | | | | | | | | | | | | | The screen grid refactors will continue until morale improves. Jokes aside, this is quite a central installment in the series. Before this refactor, there were two fundamentally distinct codepaths for getting some text on the screen: - the win_line() -> grid_put_linebuf() -> ui_line() call chain used for buffer text, with linebuf_char as a temporary scratch buffer - the grid_line_start/grid_line_puts/grid_line_flush() -> ui_line() path used for every thing else: statuslines, messages and the command line. Here the grid->chars[] array itself doubles as a scratch buffer. With this refactor, the later family of functions still exist, however they now as well render to linebuf_char just like win_line() did, and grid_put_linebuf() is called in the end to calculate delta changes. This means we don't need any duplicate logic for delta calculations anymore. Later down the line, it will be possible to share more logic operating on this scratch buffer, like doing 'rightleft' reversal and arabic shaping as a post-processing step.
* refactor(grid): use batched updates for statusline and rulerbfredl2023-09-27
|
* fix(ui): "resize -1" with cmdheight=0 #24758nwounkn2023-09-24
| | | | | | | | | | | | | Problem: Crash from: set cmdheight=0 redrawdebug=invalid resize -1 Solution: Do not invalidate first `p_ch` `msg_grid` rows in `update_screen` when scrolling the screen down after displaying a message, because they may be used later for drawing cmdline. Fixes #22154
* refactor(grid): properly namespace and separate stateful grid functionsbfredl2023-09-22
| | | | | | | | | | | | | | | | | | | | | | | This is a step in an ongoing refactor where the "grid_puts" and "grid_put_linebuf" code paths will share more of the implementation (in particular for delta calculation, doublewidth and 'arabicshape' handling). But it also makes sense by its own as a cleanup, and is thus committed separately. Before this change many of the low level grid functions grid_puts, grid_fill etc could both be used in a standalone fashion but also as part of a batched line update which would be finally transmitted as a single grid_line call (via ui_line() ). This was initially useful to quickly refactor pre-existing vim code to use batched logic safely. However, this pattern is not really helpful for maintainable and newly written code, where the "grid" and "row" arguments are just needlessly repeated. This simplifies these calls to just use grid and row as specified in the initial grid_line_start(grid, row) call. This also makes the intent clear whether any grid_puts() call is actually part of a batch or not, which is better in the long run when more things get refactored to use effective (properly batched) updates.
* fix(ui): handle virtual text with multiple hl in more cases (#25304)zeertzjq2023-09-22
|
* Merge pull request #25261 from bfredl/nolinewrapbfredl2023-09-20
|\ | | | | refactor(grid): unused grid->line_wraps delenda est
| * refactor(grid): unused grid->line_wraps delenda estbfredl2023-09-20
| | | | | | | | | | | | This is not used as part of the logic to actually implement TUI line wrapping In vim (especially gvim) it is used to emulate terminal-style text selection. But in nvim we don't do that, and have no plans to reintroduce it.
* | fix: avoid ui_grid_cursor_goto when drawing window separatorsJędrzej Boczar2023-09-19
|/
* refactor(grid): change schar_T representation to be more compactbfredl2023-09-19
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Previously, a screen cell would occupy 28+4=32 bytes per cell as we always made space for up to MAX_MCO+1 codepoints in a cell. As an example, even a pretty modest 50*80 screen would consume 50*80*2*32 = 256000, i e a quarter megabyte With the factor of two due to the TUI side buffer, and even more when using msg_grid and/or ext_multigrid. This instead stores a 4-byte union of either: - a valid UTF-8 sequence up to 4 bytes - an escape char which is invalid UTF-8 (0xFF) plus a 24-bit index to a glyph cache This avoids allocating space for huge composed glyphs _upfront_, while still keeping rendering such glyphs reasonably fast (1 hash table lookup + one plain index lookup). If the same large glyphs are using repeatedly on the screen, this is still a net reduction of memory/cache consumption. The only case which really gets worse is if you blast the screen full with crazy emojis and zalgo text and even this case only leads to 4 extra bytes per char. When only <= 4-byte glyphs are used, plus the 4-byte attribute code, i e 8 bytes in total there is a factor of four reduction of memory use. Memory which will be quite hot in cache as the screen buffer is scanned over in win_line() buffer text drawing A slight complication is that the representation depends on host byte order. I've tested this manually by compling and running this in qemu-s390x and it works fine. We might add a qemu based solution to CI at some point.
* feat(float): implement footerEvgeni Chasnovski2023-08-26
| | | | | | | | Problem: Now way to show text at the bottom part of floating window border (a.k.a. "footer"). Solution: Allows `footer` and `footer_pos` config fields similar to `title` and `title_pos`.
* refactor(float): extract "title" and "title_pos" handlingEvgeni Chasnovski2023-08-26
|
* fix(statuscolumn): force full redraw when signcolumn is invalid (#24859)luukvbaal2023-08-26
| | | Fix #24655
* refactor(change): do API changes to buffer without curbuf switchbfredl2023-08-26
| | | | | | | | | | | | | | | | | | | | | | | Most of the messy things when changing a non-current buffer is not about the buffer, it is about windows. In particular, it is about `curwin`. When editing a non-current buffer which is displayed in some other window in the current tabpage, one such window will be "borrowed" as the curwin. But this means if two or more non-current windows displayed the buffers, one of them will be treated differenty. this is not desirable. In particular, with nvim_buf_set_text, cursor _column_ position was only corrected for one single window. Two new tests are added: the test with just one non-current window passes, but the one with two didn't. Two corresponding such tests were also added for nvim_buf_set_lines. This already worked correctly on master, but make sure this is well-tested for future refactors. Also, nvim_create_buf no longer invokes autocmds just because you happened to use `scratch=true`. No option value was changed, therefore OptionSet must not be fired.
* refactor(memline): distinguish mutating uses of ml_get_buf()bfredl2023-08-24
| | | | | | | | | | | | | | ml_get_buf() takes a third parameters to indicate whether the caller wants to mutate the memline data in place. However the vast majority of the call sites is using this function just to specify a buffer but without any mutation. This makes it harder to grep for the places which actually perform mutation. Solution: Remove the bool param from ml_get_buf(). it now works like ml_get() except for a non-current buffer. Add a new ml_get_buf_mut() function for the mutating use-case, which can be grepped along with the other ml_replace() etc functions which can modify the memline.
* vim-patch:9.0.1747: screenpos() may cause unnecessary redraw (#24792)zeertzjq2023-08-19
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: screenpos() may cause unnecessary redraw. Solution: Don't unnecessarily reset VALID_WROW flag. VALID_WROW flag is only used by two functions: validate_cursor() and cursor_valid(), and cursor_valid() is only used once in ex_sleep(). When adjust_plines_for_skipcol() was first added in patch 9.0.0640, it was called in two functions: comp_botline() and curs_rows(). - comp_botline() is called in two places: - onepage(), which resets VALID_WROW flag immediately afterwards. - validate_botline_win(), where resetting a VALID_ flag is strange. - curs_rows() is called in two places: - curs_columns(), which sets VALID_WROW flag afterwards. - validate_cline_row(), which is only used by GUI mouse focus. Therefore resetting VALID_WROW there doesn't seem to do anything useful. Also, a w_skipcol check (which resets VALID_WROW flag) was added to check_cursor_moved() in patch 9.0.0734, which seems to make more sense than resetting that flag in the middle of a computation. While at it make adjust_plines_for_skipcol() and textpos2screenpos() a bit less confusing: - Make adjust_plines_for_skipcol() return "off" instead of "n - off". - Use 0-based "row" in textpos2screenpos() until W_WINROW is added. closes: vim/vim#12832 https://github.com/vim/vim/commit/6235a109c48ff2559eca3b16578c429ffb61eadc
* vim-patch:9.0.1729: screenpos() wrong when w_skipcol and cpoptions+=n (#24773)zeertzjq2023-08-18
| | | | | | | | | Problem: screenpos() wrong result with w_skipcol and cpoptions+=n Solution: Use adjust_plines_for_skipcol() instead of subtracting w_skipcol. closes: vim/vim#12625 https://github.com/vim/vim/commit/bfe377b8f2d080e5f85c8cbecf3533456e1d6312
* fix(window): prevent win_size_restore from changing cmdheightSean Dewar2023-07-26
| | | | | | | | | | | | | | | | | | | | | Currently it only skips if `Rows` changed, but it's possible for the height of the usable area for windows to change (e.g: via `&ch`, `&stal` or `&ls`), which can cause the value of `&cmdheight` to change when the sizes are restored. This is a Vim bug, so I've submitted a PR there too. No telling when it'll be merged though, given the current lack of activity there. `ROWS_AVAIL` is convenient here, but also subtracts the `global_stl_height()`. Not ideal, as we also care about the height of the last statusline for other values of `&ls`. Meh. Introduce `last_stl_height` for getting the height of the last statusline and use it in `win_size_save/restore` and `last_status` (means `last_status_rec`'s `statusline` argument will now be true if `&ls` is 3, but that does not change the behaviour). Also corrects the logic in `comp_col` to not assume there's a last statusline if `&ls` is 1 and the last window is floating.
* feat(decoration_provider): log errors as error messagesThomas Vigouroux2023-07-19
|
* fix(folds): fix missing virt_lines above when fold is hidden (#24274)zeertzjq2023-07-07
|
* fix(statusline): redraw when VIsual_mode changes (#23933)zeertzjq2023-06-06
|
* fix(folds): allow overlay virtual text on folded line (#23892)zeertzjq2023-06-03
| | | Also always check for fi_level before fi_lines.
* refactor(drawscreen): avoid spell check on folded or filler lineszeertzjq2023-06-01
|
* vim-patch:9.0.1595: line pointer becomes invalid when using spell checkingLuuk van Baal2023-06-01
| | | | | | | Problem: Line pointer becomes invalid when using spell checking. Solution: Call ml_get() at the right places. (Luuk van Baal, closes vim/vim#12456) https://github.com/vim/vim/commit/e84c773d42e8b6ef0f8ae9b6c7312e0fd47909af
* vim-patch:9.0.1585: weird use of static variables for spell checkingLuuk van Baal2023-06-01
| | | | | | | | Problem: Weird use of static variables for spell checking. Solution: Move the variables to a structure and pass them from win_update() to win_line(). (Luuk van Baal, closes vim/vim#12448) https://github.com/vim/vim/commit/30805a1aba0067cf0087f9a0e5c184562433e2e7
* vim-patch:9.0.1578: SpellCap highlight not always updated when needed (#23755)luukvbaal2023-05-26
| | | | | | | | Problem: SpellCap highlight not always updated when needed. Solution: Handle updating line below closed fold and other situations where only part of the window is redrawn. (Luuk van Baal, closes vim/vim#12428, closes vim/vim#12420) https://github.com/vim/vim/commit/2ac6497f0ef186f0e3ba67d7f0a485bfb612bb08
* vim-patch:9.0.1512: inserting lines when scrolling with 'smoothscroll' setLuuk van Baal2023-05-07
| | | | | | | | Problem: Inserting lines when scrolling with 'smoothscroll' set. Solution: Adjust line height computation for w_skipcol. (Luuk van Baal, closes vim/vim#12350) https://github.com/vim/vim/commit/c8502f9b880b6d23baa4f9d28b60e1ceb442e35f
* fix(ui): adjust 'smoothscroll' for inner dimensionsLuuk van Baal2023-05-02
|
* vim-patch:9.0.0652: 'smoothscroll' not tested with 'number' and "n" in 'cpo'Luuk van Baal2023-05-02
| | | | | | | | | Problem: 'smoothscroll' not tested with 'number' and "n" in 'cpo'. Solution: Add tests, fix uncovered problem. https://github.com/vim/vim/commit/b6aab8f44beb8c5d99393abdc2c9faab085c72aa Co-authored-by: Bram Moolenaar <Bram@vim.org>
* refactor: uncrustifydundargoc2023-04-26
| | | | Notable changes: replace all infinite loops to `while(true)` and remove `int` from `unsigned int`.
* fix(column): don't reset 'statuscolumn' width after it has been drawnluukvbaal2023-04-24
| | | | | | | | Problem: 'statuscolumn' width may be reset after it has been drawn when multiple windows contain the same buffer. This results in an offset for the drawn cursor position. Solution: Loop over all windows (twice) prior to drawing them to reset the 'statuscolumn' width and validate the sign column when necessary.
* fix(column): rebuild status column when sign column is invalidLuuk van Baal2023-04-19
|
* fix(ruler): show ruler of curwin with no statusline in cmdlineSean Dewar2023-04-17
| | | | | | | | | | | | | | | | | | | | | Problem: After neovim/neovim@846a056, only the ruler for current floating or last window without a statusline is drawn in the cmdline. This means that if the current window is not one of these, but has no statusline, its ruler will not be drawn anymore. Solution: Make `showmode()` draw the ruler of the current window or the last window in the cmdline if it has no statusline. This also maintains the previously restored floating window case (`float->w_status_height` should be 0). This behaviour should again match Vim, but without the overdraw it seems to do to achieve the same effect; it calls `showmode()` to draw the ruler for the last window without a statusline, then may draw over it in `showruler()` (which is now `show_cursor_info_later()` in Nvim) to show the ruler for the current window..? It's very confusing. Also update the logic in `win_redr_ruler()` to mirror the check done in `showmode()`, so that the ruler doesn't potentially draw over the long ins-completion mode message in some cases.
* fix(ui): ruler is not redrawn in cmdline with redrawstatusLuuk van Baal2023-04-02
|
* Merge pull request #22844 from luukvbaal/stlrecordingbfredl2023-04-02
|\ | | | | fix(ui): recording change doesn't trigger statusline redraw
| * fix(ui): recording change doesn't trigger statusline redrawLuuk van Baal2023-04-01
| |
* | refactor: add const and remove unnecessary casts (#22841)ii142023-04-01
|/
* fix(column): invalidate statuscolumn width when UPD_NOT_VALID (#22723)luukvbaal2023-03-19
|
* refactor(extmarks): some minor internal API changesbfredl2023-03-16
| | | | | | | | | extranges and a bunch of other improvements are coming for 0.10 This gets in some minor surrounding API changes to avoid rebase conflicts until then. - decorations will be able to be specific to windows - adjust deletion API to fit with extranges
* refactor(screen): screen.c delenda estbfredl2023-03-14
| | | | | | | | | | | | | drawscreen.c vs screen.c makes absolutely no sense. The screen exists only to draw upon it, therefore helper functions are distributed randomly between screen.c and the file that does the redrawing. In addition screen.c does a lot of drawing on the screen. It made more sense for vim/vim as our grid.c is their screen.c Not sure if we want to dump all the code for option chars into optionstr.c, so keep these in a optionchar.c for now.
* fix(screen): redraw the ruler for a current floating windowbfredl2023-03-14
| | | | | | | Semi-regression. The "ruler" behavior for a floating window was never really specified but in practice followed the users cursor movements in normal mode in a focused float, which seems like a reasonable behavior to now specify.
* refactor(redraw): make cursor position redraw use the "redraw later" patternbfredl2023-03-12
|
* perf(statusline): UI elements are always redrawn on K_EVENTLuuk van Baal2023-03-08
| | | | | Problem: 'statusline'-format UI elements are redrawn on each K_EVENT. Solution: Only redraw UI elements when something relevant has changed.
* fix(win_update): don't use unintialized memory in edge case (#22266)zeertzjq2023-02-15
| | | | | | | This fixes two clang warnings. Using an unintialized "cursorline_fi" without assigning to it is not something that should normally happen, and in case it happens it will likely cause another redraw, but still don't use unintialized memory.
* fix(folds): cursorline highlight is not always applied on closed folds (#22242)luukvbaal2023-02-14
| | | | | | | Problem: The cursorline highlight logic checks for `w_cursor.lnum` which may be different from the line number passed to `win_line()` even when the cursor is actually on that line. Solution: Update cursor line highlight logic to check for the line number of the start of a closed fold if necessary.
* fix(ui): make sure screen is valid after resizingzeertzjq2023-02-13
| | | | | | | | | | | | | | | | | Problem: When not inside an Ex command, screen_resize() calls update_screen(), which calls screenclear() and set the screen as valid. However, when inside an Ex command, redrawing is postponed so update_screen() screen doesn't do anything, and the screen is still invalid after the resize, causing ui_comp_raw_line() to be no-op until update_screen() is called on the main loop. Solution: Restore the call to screenclear() inside screen_resize() so that the screen is invalid after screen_resize(). Since screenclear() changes redraw type from UPD_CLEAR to UPD_NOT_VALID, it is called at most once for each resize, so this shouldn't change how much code is run in the common (not inside an Ex command) case.
* refactor: reduce scope of locals as per the style guide (#22211)dundargoc2023-02-11
|
* vim-patch:partial:9.0.1237: code is indented more than necessary (#21971)zeertzjq2023-01-24
| | | | | | | | | Problem: Code is indented more than necessary. Solution: Use an early return where it makes sense. (Yegappan Lakshmanan, closes vim/vim#11858) https://github.com/vim/vim/commit/6ec66660476562e643deceb7c325cd0e8c903663 Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
* fix(extmarks): problems with folded virtual lines (#21930)luukvbaal2023-01-23
| | | | | | | | | | | | | | Problem: When a folded line has virtual lines attached, the following problems occur: - The virtual lines are drawn empty. - The 'foldtext' line is drawn empty. - The cursor is drawn incorrectly. Solution: Check whether virtual lines belong to a folded line. Fix #17027 Fix #19557 Fix #21837 Co-authored-by: zeertzjq <zeertzjq@outlook.com>
* feat(ui): add 'statuscolumn' optionluukvbaal2023-01-09
| | | | | | | | Problem: Unable to customize the column next to a window ('gutter'). Solution: Add 'statuscolumn' option that follows the 'statusline' syntax, allowing to customize the status column. Also supporting the %@ click execute function label. Adds new items @C and @s which will print the fold and sign columns. Line numbers and signs can be clicked, highlighted, aligned, transformed, margined etc.
* fix(decoration): do not reset must_redraw after calling providers (#21459)zeertzjq2022-12-21
| | | | Resetting must_redraw caused a strange bug #21278, so don't do it. Remove the goto as well, as it doesn't make much sense after #20665.