Commit Graph

308 Commits

Author SHA1 Message Date
zeertzjq
d82e105727 vim-patch:9.0.2187: Visual not drawn with 'breakindent' when line doesn't fit (#26765)
Problem:  Visual selection isn't drawn with 'breakindent' when the line
          doesn't fit in the window (Jaehwang Jung)
Solution: Adjust wlv->fromcol also for 'breakindent' (zeertzjq)

closes: vim/vim#13767
closes: vim/vim#13768

23627722d3
2023-12-28 07:47:22 +08:00
luukvbaal
ec74538044 fix(column): correct width after truncated 'statuscolumn' error (#26737)
Problem:  Default number column has incorrect width after 'statuscolumn'
          is unset due to an error, but was also truncated.
Solution: Reverse 'statuscolumn' error and truncate return branches.
2023-12-26 09:07:58 +08:00
luukvbaal
bbd5c6363c feat(extmarks): add virt_text_repeat_linebreak flag (#26625)
Problem:  Unable to predict which byte-offset to place virtual text to
          make it repeat visually in the wrapped part of a line.
Solution: Add a flag to nvim_buf_set_extmark() that causes virtual
          text to repeat in wrapped lines.
2023-12-26 07:16:03 +08:00
zeertzjq
ddc8dd187d refactor(drawline): reduce size of wlv.extra[] (#26733)
It's now only used for transchar_hex(), which only needs 11 bytes.
2023-12-25 18:57:55 +08:00
zeertzjq
242261d4e7 refactor(IWYU): move evalarg_T to eval_defs.h (#26716) 2023-12-23 08:28:17 +08:00
luukvbaal
e632396bab refactor(drawline): avoid storing info to draw 'statuscolumn' (#26712)
We no longer return to the main loop in win_line() to put column
characters on the screen. Simplify and sync statuscolumn drawing
logic with that of statusline.
2023-12-23 06:31:07 +08:00
Lewis Russell
2b0acacb3c fix(decor): allow adding providers during redraw
Fixes: #26652
2023-12-22 20:27:07 +00:00
Luuk van Baal
35d98888bd refactor(drawline): simplify draw_statuscol() and remove draw_state references 2023-12-22 12:07:15 +01:00
bfredl
66ac327db2 refactor(drawline): remove LineDrawState and wlv->saved_n_extra
We do not need an enum to keep track of what place in win_line() we
currently are at. We already have a variable which keeps track where
in the code we currently are (and thus what part of the line we are
currently rendering), it is called the _program counter_. When we need
non-linear or self-referential control-flow anyway for a laugh, we
have a mechanism for that, it is called _function calls_.

Do not "save" and "restore" the wlv->n_extra state every time the
columns are to be drawn. This sort of thing needs to go away. Instead of
setting the n_extra variables and then going to the outer while loop,
the text in the columns can be rendered by just simply putting the text
into the cells of the screen line, right away. Even in nvim this can be
tricky sometimes, luckily we can use function calls to abstract this
logic, which means that this handy data structure called the _call
stack_ is handling saving away state temporarily, and restoring it back
when we need it again.

Lastly, but not least, as we now have direct control how signs
are rendered, these can be stored as schar_T[2] and be directly
put on screen as such.
2023-12-22 10:54:28 +01:00
zeertzjq
8533adb484 refactor(IWYU): move decor provider types to decoration_defs.h (#26692) 2023-12-21 16:50:05 +08:00
dundargoc
7f6b775b45 refactor: use bool to represent boolean values 2023-12-19 11:43:21 +01:00
zeertzjq
06ff540e1c vim-patch:9.0.2151: 'breakindent' is not drawn after diff filler lines (#26412)
Problem:  'breakindent' is not drawn after diff filler lines.
Solution: Correct check for whether 'breakindent' should be drawn.

closes: vim/vim#13624

588f20dece

Cherry-pick Test_diff_with_syntax() change from patch 9.0.1257.
2023-12-06 07:16:02 +08:00
zeertzjq
a6cba103ce refactor: move some constants out of vim_defs.h (#26298) 2023-11-29 20:32:40 +08:00
dundargoc
79b6ff28ad refactor: fix headers with IWYU 2023-11-28 22:23:56 +01:00
bfredl
ae3685798d feat(decoration): allow conceal_char to be a composing char
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.
2023-11-28 10:35:25 +01:00
dundargoc
6c14ae6bfa refactor: rename types.h to types_defs.h 2023-11-27 21:57:51 +01:00
dundargoc
f4aedbae4c build(IWYU): fix includes for undo_defs.h 2023-11-27 19:33:17 +01:00
zeertzjq
6361806aa2 refactor: move garray_T to garray_defs.h (#26227) 2023-11-26 22:58:52 +08:00
dundargoc
a827003e30 build: rework IWYU mapping files
Create mapping to most of the C spec and some POSIX specific functions.
This is more robust than relying files shipped with IWYU.
2023-11-25 17:41:33 +01:00
bfredl
0b38fe4dbb refactor(decorations): break up Decoration struct into smaller pieces
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
2023-11-22 09:28:54 +01:00
Luuk van Baal
585eeacb24 refactor(sign): store 'signcolumn' width range when it is set
Problem:  Minimum and maximum signcolumn width is determined each redraw.
Solution: Determine and store 'signcolumn' range when option is set.
2023-11-21 09:38:32 +00:00
dundargoc
a6e3d93421 refactor: enable formatting for ternaries
This requires removing the "Inner expression should be aligned" rule
from clint as it prevents essentially any formatting regarding ternary
operators.
2023-11-20 19:57:09 +01:00
dundargoc
ac1113ded5 refactor: follow style guide
- reduce variable scope
- prefer initialization over declaration and assignment
2023-11-19 15:08:35 +01:00
bfredl
df87266b23 Merge pull request #25724 from luukvbaal/signmerge
refactor(sign): move legacy signs to extmarks
2023-11-18 15:04:14 +01:00
Luuk van Baal
c4afb9788c refactor(sign): move legacy signs to extmarks
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.
2023-11-17 15:10:15 +01:00
bfredl
b522cb1ac3 refactor(grid): make screen rendering more multibyte than ever before
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.
2023-11-17 12:58:57 +01:00
dundargoc
28f4f3c484 refactor: follow style guide
- reduce variable scope
- prefer initialization over declaration and assignment
- use bool to represent boolean values
2023-11-13 23:39:56 +01:00
luukvbaal
d3582e102b feat(statuscolumn): re-evaluate for every screen line (#25885)
Problem:  v:virtnum is less useful than it could be.
Solution: Always re-evaluate 'statuscolumn', and update v:virtnum
          accordingly.
2023-11-13 11:24:02 +08:00
dundargoc
353a4be7e8 build: remove PVS
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.
2023-11-12 21:26:39 +01:00
bfredl
74581ec7eb refactor(drawline): avoid xmalloc/xfree cycles on each screenline 2023-11-09 21:55:21 +01:00
bfredl
83db9115af refactor(grid): reimplement 'rightleft' as a post-processing step
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.
2023-11-05 21:19:35 +01:00
dundargoc
acc646ad8f refactor: the long goodbye
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.
2023-11-05 20:19:06 +01:00
dundargoc
5f03a1eaab build(lint): remove unnecessary clint.py rules
Uncrustify is the source of truth where possible.
Remove any redundant checks from clint.py.
2023-10-23 20:06:21 +02:00
zeertzjq
0818d65528 fix(extmarks): skip virt_text if it is out of window (#25658) 2023-10-15 19:36:19 +08:00
zeertzjq
bf70a33f5e vim-patch:8.1.0822: peeking and flushing output slows down execution (#25629)
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)

cb574f4154
2023-10-14 09:58:30 +08:00
zeertzjq
dac79b165d vim-patch:9.0.2017: linebreak applies for leading whitespace
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

dd75fcfbdf

Co-authored-by: Christian Brabandt <cb@256bit.org>
2023-10-12 07:02:49 +08:00
bfredl
ddef39299f refactor(grid): do arabic shaping in one place
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.
2023-10-08 15:22:45 +02:00
bfredl
a58bb21544 refactor(grid): get rid of unbatched grid_puts and grid_putchar
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)
2023-10-06 10:16:30 +02:00
zeertzjq
dc6d0d2daf refactor: reorganize option header files (#25437)
- 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
2023-09-30 14:41:34 +08:00
zeertzjq
cf8b2c0e74 build(iwyu): add a few more _defs.h mappings (#25435) 2023-09-30 12:05:28 +08:00
bfredl
e33269578b refactor(grid): unify the two put-text-on-the-screen code paths
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.
2023-09-29 15:38:25 +02:00
zeertzjq
dfa8b582a6 fix(extmarks): draw TAB in virt_text properly with 'rl' (#25381) 2023-09-27 10:48:14 +08:00
zeertzjq
7d4967547b vim-patch:9.0.1938: multispace wrong when scrolling horizontally (#25348)
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

abc808112e
2023-09-25 06:31:52 +08:00
zeertzjq
64e8a3c4d1 fix(ui): handle virtual text with multiple hl in more cases (#25304) 2023-09-22 15:36:24 +08:00
zeertzjq
34a786bc49 fix(extmarks): inline virt_text support multiple hl groups (#25303) 2023-09-22 14:21:58 +08:00
zeertzjq
6555176f34 vim-patch:9.0.1923: curswant wrong on click with 've' and 'nowrap' set (#25293)
Problem:  curswant wrong on click with 've' and 'nowrap' set
Solution: Add w_leftcol to mouse click column.

closes: vim/vim#13142

db54e989b5
2023-09-22 05:44:45 +08:00
zeertzjq
dc6c11394b fix(statuscolumn): update number hl for each screen line (#25277) 2023-09-21 07:03:26 +08:00
Ibby
23c21e7630 fix(extmarks): account for rightleft when drawing virt text (#25262)
Co-authored-by: zeertzjq <zeertzjq@outlook.com>
2023-09-20 22:39:54 +08:00
bfredl
ee20e9e669 refactor(grid): unused grid->line_wraps delenda est
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.
2023-09-20 10:24:07 +02:00
bfredl
8da986ea87 refactor(grid): change schar_T representation to be more compact
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.
2023-09-19 11:25:31 +02:00