aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/drawline.c
Commit message (Collapse)AuthorAge
* refactor: move some constants out of vim_defs.h (#26298)zeertzjq2023-11-29
|
* refactor: fix headers with IWYUdundargoc2023-11-28
|
* feat(decoration): allow conceal_char to be a composing charbfredl2023-11-28
| | | | | | | | decor->text.str pointer must go. This removes it for conceal char, in preparation for a larger PR which will also handle the sign case. By actually allowing composing chars for a conceal chars, this becomes a feature and not just a refactor, as a bonus.
* refactor: rename types.h to types_defs.hdundargoc2023-11-27
|
* build(IWYU): fix includes for undo_defs.hdundargoc2023-11-27
|
* refactor: move garray_T to garray_defs.h (#26227)zeertzjq2023-11-26
|
* build: rework IWYU mapping filesdundargoc2023-11-25
| | | | | Create mapping to most of the C spec and some POSIX specific functions. This is more robust than relying files shipped with IWYU.
* refactor(decorations): break up Decoration struct into smaller piecesbfredl2023-11-22
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Remove the monolithic Decoration struct. Before this change, each extmark could either represent just a hl_id + priority value as a inline decoration, or it would take a pointer to this monolitic 112 byte struct which has to be allocated. This change separates the decorations into two pieces: DecorSignHighlight for signs, highlights and simple set-flag decorations (like spell, ui-watched), and DecorVirtText for virtual text and lines. The main separation here is whether they are expected to allocate more memory. Currently this is not really true as sign text has to be an allocated string, but the plan is to get rid of this eventually (it can just be an array of two schar_T:s). Further refactors are expected to improve the representation of each decoration kind individually. The goal of this particular PR is to get things started by cutting the Gordian knot which was the monolithic struct Decoration. Now, each extmark can either contain chained indicies/pointers to these kinds of objects, or it can fit a subset of DecorSignHighlight inline. The point of this change is not only to make decorations smaller in memory. In fact, the main motivation is to later allow them to grow _larger_, but on a dynamic, on demand fashion. As a simple example, it would be possible to augment highlights to take a list of multiple `hl_group`:s, which then would trivially map to a chain of multiple DecorSignHighlight entries. One small feature improvement included with this refactor itself, is that the restriction that extmarks cannot be removed inside a decoration provider has been lifted. These are instead safely lifetime extended on a "to free" list until the current iteration of screen drawing is done. NB: flags is a mess. but DecorLevel is useless, this slightly less so
* refactor(sign): store 'signcolumn' width range when it is setLuuk van Baal2023-11-21
| | | | | Problem: Minimum and maximum signcolumn width is determined each redraw. Solution: Determine and store 'signcolumn' range when option is set.
* refactor: enable formatting for ternariesdundargoc2023-11-20
| | | | | | This requires removing the "Inner expression should be aligned" rule from clint as it prevents essentially any formatting regarding ternary operators.
* refactor: follow style guidedundargoc2023-11-19
| | | | | - reduce variable scope - prefer initialization over declaration and assignment
* Merge pull request #25724 from luukvbaal/signmergebfredl2023-11-18
|\ | | | | refactor(sign): move legacy signs to extmarks
| * refactor(sign): move legacy signs to extmarksLuuk van Baal2023-11-17
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: The legacy signlist data structures and associated functions are redundant since the introduction of extmark signs. Solution: Store signs defined through the legacy commands in a hashmap, placed signs in the extmark tree. Replace signlist associated functions. Usage of the legacy sign commands should yield no change in behavior with the exception of: - "orphaned signs" are now always removed when the line it is placed on is deleted. This used to depend on the value of 'signcolumn'. - It is no longer possible to place multiple signs with the same identifier in a single group on multiple lines. This will now move the sign instead. Moreover, both signs placed through the legacy sign commands and through |nvim_buf_set_extmark()|: - Will show up in both |sign-place| and |nvim_buf_get_extmarks()|. - Are displayed by increasing sign identifier, left to right. Extmark signs used to be ordered decreasingly as opposed to legacy signs.
* | refactor(grid): make screen rendering more multibyte than ever beforebfredl2023-11-17
|/ | | | | | | | | | | | | | | | | | Problem: buffer text with composing chars are converted from UTF-8 to an array of up to seven UTF-32 values and then converted back to UTF-8 strings. Solution: Convert buffer text directly to UTF-8 based schar_T values. The limit of the text size is now in schar_T bytes, which is currently 31+1 but easily could be raised as it no longer multiplies the size of the entire screen grid when not used, the full size is only required for temporary scratch buffers. Also does some general cleanup to win_line text handling, which was unnecessarily complicated due to multibyte rendering being an "opt-in" feature long ago. Nowadays, a char is just a char, regardless if it consists of one ASCII byte or multiple bytes.
* refactor: follow style guidedundargoc2023-11-13
| | | | | | - reduce variable scope - prefer initialization over declaration and assignment - use bool to represent boolean values
* feat(statuscolumn): re-evaluate for every screen line (#25885)luukvbaal2023-11-13
| | | | | Problem: v:virtnum is less useful than it could be. Solution: Always re-evaluate 'statuscolumn', and update v:virtnum accordingly.
* build: remove PVSdundargoc2023-11-12
| | | | | | | We already have an extensive suite of static analysis tools we use, which causes a fair bit of redundancy as we get duplicate warnings. PVS is also prone to give false warnings which creates a lot of work to identify and disable.
* refactor(drawline): avoid xmalloc/xfree cycles on each screenlinebfredl2023-11-09
|
* refactor(grid): reimplement 'rightleft' as a post-processing stepbfredl2023-11-05
| | | | | | | | | | | | | problem: checks for wp->w_p_rl are all over the place, making simple things like "advance column one cell" incredibly complicated. solution: always fill linebuf_char[] using an incrementing counter, and then mirror the buffer as a post-processing step This was "easier" that I first feared, because the stupid but simple workaround for things like keeping linenumbers still left-right, e.g. "mirror them and them mirror them once more" is more or less what vim did already. So let's just keep doing that.
* refactor: the long goodbyedundargoc2023-11-05
| | | | | | long is 32 bits on windows, while it is 64 bits on other architectures. This makes the type suboptimal for a codebase meant to be cross-platform. Replace it with more appropriate integer types.
* build(lint): remove unnecessary clint.py rulesdundargoc2023-10-23
| | | | | Uncrustify is the source of truth where possible. Remove any redundant checks from clint.py.
* fix(extmarks): skip virt_text if it is out of window (#25658)zeertzjq2023-10-15
|
* vim-patch:8.1.0822: peeking and flushing output slows down execution (#25629)zeertzjq2023-10-14
| | | | | | | Problem: Peeking and flushing output slows down execution. Solution: Do not update the mode message when global_busy is set. Do not flush when only peeking for a character. (Ken Takata) https://github.com/vim/vim/commit/cb574f415486adff645ce384979bfecf27f5be8c
* vim-patch:9.0.2017: linebreak applies for leading whitespacezeertzjq2023-10-12
| | | | | | | | | | | | | Problem: linebreak applies for leading whitespace Solution: only apply linebreak, once we have found non-breakat chars in the line closes: vim/vim#13228 closes: vim/vim#13243 https://github.com/vim/vim/commit/dd75fcfbdff1934c6e531b5a89ebc636318bf4a2 Co-authored-by: Christian Brabandt <cb@256bit.org>
* refactor(grid): do arabic shaping in one placebfredl2023-10-08
| | | | | | | | | | | | | | | | | | | | | | | | | | | The 'arabicshape' feature of vim is a transformation of unicode text to make arabic and some related scripts look better at display time. In particular the content of a cell will be adjusted depending on the (original) content of the cells just before and after it. This is implemented by the arabic_shape() function in nvim. Before this commit, shaping was invoked in four different contexts: - when rendering buffer text in win_line() - in line_putchar() for rendering virtual text - as part of grid_line_puts, used by messages and statuslines and similar - as part of draw_cmdline() for drawing the cmdline This replaces all these with a post-processing step in grid_put_linebuf(), which has become the entry point for all text rendering after recent refactors. An aim of this is to make the handling of multibyte text yet simpler. One of the main reasons multibyte chars needs to be "parsed" into codepoint arrays of composing chars is so that these could be inspected for the purpose of shaping. This can likely be vastly simplified in many contexts where only the total length (in bytes) and width of composed char is needed.
* refactor(grid): get rid of unbatched grid_puts and grid_putcharbfredl2023-10-06
| | | | | | | | | | | | | | | This finalizes the long running refactor from the old TUI-focused grid implementation where text-drawing cursor was not separated from the visible cursor. Still, the pattern of setting cursor position together with updating a line was convenient. Introduce grid_line_cursor_goto() to still allow this but now being explicit about it. Only having batched drawing functions makes code involving drawing a bit longer. But it is better to be explicit, and this highlights cases where multiple small redraws can be grouped together. This was the case for most of the changed places (messages, lastline, and :intro)
* refactor: reorganize option header files (#25437)zeertzjq2023-09-30
| | | | | | - Move vimoption_T to option.h - option_defs.h is for option-related types - option_vars.h corresponds to Vim's option.h - option_defs.h and option_vars.h don't include each other
* build(iwyu): add a few more _defs.h mappings (#25435)zeertzjq2023-09-30
|
* 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.
* fix(extmarks): draw TAB in virt_text properly with 'rl' (#25381)zeertzjq2023-09-27
|
* vim-patch:9.0.1938: multispace wrong when scrolling horizontally (#25348)zeertzjq2023-09-25
| | | | | | | | | | Problem: multispace wrong when scrolling horizontally Solution: Update position in "multispace" or "leadmultispace" also in skipped chars. Reorder conditions to be more consistent. closes: vim/vim#13145 closes: vim/vim#13147 https://github.com/vim/vim/commit/abc808112ee5df58a9f612f2bb5a65389c2c14e1
* fix(ui): handle virtual text with multiple hl in more cases (#25304)zeertzjq2023-09-22
|
* fix(extmarks): inline virt_text support multiple hl groups (#25303)zeertzjq2023-09-22
|
* vim-patch:9.0.1923: curswant wrong on click with 've' and 'nowrap' set (#25293)zeertzjq2023-09-22
| | | | | | | | Problem: curswant wrong on click with 've' and 'nowrap' set Solution: Add w_leftcol to mouse click column. closes: vim/vim#13142 https://github.com/vim/vim/commit/db54e989b5cff3cc6442dfc500e3962cc1c0b6d0
* fix(statuscolumn): update number hl for each screen line (#25277)zeertzjq2023-09-21
|
* fix(extmarks): account for rightleft when drawing virt text (#25262)Ibby2023-09-20
| | | Co-authored-by: zeertzjq <zeertzjq@outlook.com>
* 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.
* 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(folds): support virtual text format for 'foldtext' (#25209)zeertzjq2023-09-17
| | | Co-authored-by: Lewis Russell <lewis6991@gmail.com>
* fix(extmarks): overlay virt_text position after 'showbreak' (#25175)zeertzjq2023-09-15
| | | Also make virt_text_hide work properly.
* fix(extmarks): draw virt_text below diff filler lines properly (#25170)zeertzjq2023-09-15
| | | fix(extmarks): draw virt_text properly below diff filler lines
* fix(extmarks): fix wrong virt_text position after wrapped TAB (#25168)zeertzjq2023-09-15
|
* fix(extmarks): properly handle virt_text on next screen line (#25166)zeertzjq2023-09-15
| | | | TODO: virt_text_hide doesn't work for the first char on a wrapped screen line, and it's not clear how to fix that.
* refactor(drawline): remove unnecessary inline virt checks (#25163)zeertzjq2023-09-15
|
* feat(extmark): support proper multiline rangesbfredl2023-09-12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The removes the previous restriction that nvim_buf_set_extmark() could not be used to highlight arbitrary multi-line regions The problem can be summarized as follows: let's assume an extmark with a hl_group is placed covering the region (5,0) to (50,0) Now, consider what happens if nvim needs to redraw a window covering the lines 20-30. It needs to be able to ask the marktree what extmarks cover this region, even if they don't begin or end here. Therefore the marktree needs to be augmented with the information covers a point, not just what marks begin or end there. To do this, we augment each node with a field "intersect" which is a set the ids of the marks which overlap this node, but only if it is not part of the set of any parent. This ensures the number of nodes that need to be explicitly marked grows only logarithmically with the total number of explicitly nodes (and thus the number of of overlapping marks). Thus we can quickly iterate all marks which overlaps any query position by looking up what leaf node contains that position. Then we only need to consider all "start" marks within that leaf node, and the "intersect" set of that node and all its parents. Now, and the major source of complexity is that the tree restructuring operations (to ensure that each node has T-1 <= size <= 2*T-1) also need to update these sets. If a full inner node is split in two, one of the new parents might start to completely overlap some ranges and its ids will need to be moved from its children's sets to its own set. Similarly, if two undersized nodes gets joined into one, it might no longer completely overlap some ranges, and now the children which do needs to have the have the ids in its set instead. And then there are the pivots! Yes the pivot operations when a child gets moved from one parent to another.
* vim-patch:9.0.1813: linebreak incorrect drawn with breakindent (#24917)zeertzjq2023-08-29
| | | | | | | | | Problem: 'linebreak' is incorrectly drawn after 'breakindent'. Solution: Don't include 'breakindent' size when already after it. closes: vim/vim#12937 closes: vim/vim#12940 https://github.com/vim/vim/commit/1d3e0e8f3110a7807431eae056914ccea57b057b
* vim-patch:9.0.1800: Cursor position still wrong with 'showbreak' and virtual ↵zeertzjq2023-08-28
| | | | | | | | | | | | | | | | text Problem: Cursor position still wrong with 'showbreak' and virtual text after last character or 'listchars' "eol". Solution: Remove unnecessary w_wcol adjustment in curs_columns(). Also fix first char of virtual text not shown at the start of a screen line. closes: vim/vim#12478 closes: vim/vim#12532 closes: vim/vim#12904 https://github.com/vim/vim/commit/6a3897232aecd3e8b9e8b23955e55c1993e5baec
* 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.
* fix(ui): wrong display with 0-width inline virt_text at eol (#24854)zeertzjq2023-08-24
|
* vim-patch:9.0.1783: Display issues with virt text smoothscroll and showbreakzeertzjq2023-08-23
| | | | | | | | | | | Problem: Wrong display with wrapping virtual text or unprintable chars, 'showbreak' and 'smoothscroll'. Solution: Don't skip cells taken by 'showbreak' in screen lines before "w_skipcol". Combined "n_skip" and "skip_cells". closes: vim/vim#12597 https://github.com/vim/vim/commit/b557f4898208105b674df605403cac1b1292707b