- If a mouse event is bound to a Lua function, pass *tcell.EventMouse to
this Lua function, so that it can find out the position where a button
was clicked etc, just like the built-in MousePress and MouseMultiCursor
actions.
- Make mouse actions more a first-class citizen: allow chaining them and
running onAction and preAction callbacks for them, just like key actions.
Improve user experience: if we are at a line with a new (i.e.
not highlighted yet) trailingws and we begin selecting text,
don't highlight the trailingws until we are done with selection,
even if we moved the cursor to another line while selecting.
Handle the case when the cursor itself hasn't really moved to
another line, but its line number has changed due to insert
or remove of some lines above.
In this case, if the cursor is still at its new trailingws,
we should not reset NewTrailingWsY to -1 but update it to the
new line number.
A scenario exemplifying this issue:
Bind some key, e.g. Alt-r, to such a lua function:
function insertNewlineAbove(bp)
bp.Buf:Insert(buffer.Loc(0, bp.Cursor.Y), "\n")
end
Then in a file containing these lines:
aaa
bbb
ccc
insert a space at the end of bbb line, and then press Alt-r.
bbb and ccc are moved one line down, but also the trailing space
after bbb becomes highlighted, which isn't what we expect.
This commit fixes that.
Fix unwanted highlighting of whitespace in the new line when inserting
a newline after a bracket (when hltrailingws is on). To fix it, change
the order of operations: insert the new empty line after all other
things, to avoid moving the cursor between lines after that.
Added option `hltrailingws` for highlighting trailing whitespaces
at the end of lines. Note that it behaves in a "smart" way.
It doesn't highlight newly added (transient) trailing whitespaces
that naturally occur while typing text. It would be annoying to
see transient highlighting every time we enter a space at the end
of a line while typing.
So a newly added trailing whitespace starts being highlighting
only after the cursor moves to another line. Thus the highlighting
serves its purpose: it draws our attention to annoying sloppy
forgotten trailing whitespaces.
Added option `hltaberrors` which helps to spot sloppy whitespace errors
with tabs used instead of spaces or vice versa.
It uses the value of `tabstospaces` option as a criterion whether a
tab or space character is an error or not.
If `tabstospaces` is on, we probably expect that the file should contain
no tab characters, so any tab character is highlighted as an error.
If `tabstospaces` is off, we probably expect that the file uses
indentation with tabs, so space characters in the initial indent part
of lines are highlighted as errors.
* Fix gutter overwriting other split pane
When we resize a split pane to a very small width, so that the gutter
does not fit in the pane, it overwrites the sibling split pane.
To fix it, clean up the calculation of gutter width, buffer width and
scrollbar width, so that they add up exactly to the window width, and
ensure that we don't draw the gutter beyond this calculated gutter
width (gutterOffset).
As a bonus, this also fixes the crash #3052 (observed when resizing a
split pane to a very small width, if wordwrap is enabled), by ensuring
that bufWidth is never negative.
[*] By the gutter we mean of course gutter + diffgutter + ruler.
* Don't display line numbers if buffer width is 0 and softwrap is on
If softwrap is enabled, the line numbers displayed in the ruler depend
on the heights of the displayed softwrapped lines, which depend on the
width of the displayed buffer. If this width is 0 (e.g. after resizing
buffer pane to a very small width), there is no displayed text at all,
so line numbers don't make sense. So don't display line numbers in this
case.
* Fix buffer text overwriting scrollbar when window width is 1 char
Fix the following funny issue: if we open 3 vertical split panes (i.e.
with 2 vertical dividers between them) and drag the rightmost divider
to the left (for resizing the middle and the rightmost split panes), it
does not stop at the leftmost divider but jumps over it and then hovers
over the leftmost split pane. And likewise with horizontal split panes.
* Update docs to include `matchbracestyle`
* Add `matchbracestyle` to infocomplete.go
* Add validator and default settings for `matchbracestyle`
* Highlight or underline braces based on `matchbracestyle`
* Add `match-brace` to default colorschemes
* Correct `FindMatchingBrace()` counting
Make brace under the cursor have priority over brace to the left in
ambiguous cases when matching braces
Co-authored-by: Dmitry Maluka <dmitrymaluka@gmail.com>
* Fix conflicts
---------
Co-authored-by: Jöran Karl <3951388+JoeKar@users.noreply.github.com>
Co-authored-by: Dmitry Maluka <dmitrymaluka@gmail.com>
* Update C syntax with keywords up to C23.
* Update C syntax with some GCC extensions.
* Update C# syntax with new keywords up to C# 12.
* Update C# syntax with preprocessor directives.
* Add Cake build script (C#) syntax.
* Add MSBuild (XML) syntax.
* SpawnMultiCursorUp/Down: change order of adding cursors
SpawnMultiCursor{Up,Down} currently works in a tricky way: instead of
creating a new cursor above or below, it moves the current "primary"
cursor above or below, and then creates a new cursor below or above the
new position of the current cursor (i.e. at its previous position),
creating an illusion for the user that the current (top-most or
bottom-most) cursor is a newly spawned cursor.
This trick causes at least the following issues:
- When the line above or below, where we spawn a new cursor, is shorter
than the current cursor position in the current line, the new cursor
is placed at the end of this short line (which is expected), but also
the current cursor unexpectedly changes its x position and moves
below/above the new cursor.
- When removing a cursor in RemoveMultiCursor (default Alt-p key), it
non-intuitively removes the cursor which, from the user point of view,
is not the last but the last-but-one cursor.
Fix these issues by replacing the trick with a straightforward logic:
just create the new cursor above or below the last one.
Note that this fix has a user-visible side effect: the last cursor is
no longer the "primary" one (since it is now the last in the list, not
the first), so e.g. when the user clears multicursors via Esc key, the
remaining cursor is the first one, not the last one. I assume it's ok.
* SpawnMultiCursorUp/Down: move common code to a helper fn
* SpawnMultiCursorUp/Down: honor visual width and LastVisualX
Make spawning multicursors up/down behave more similarly to cursor
movements up/down. This change fixes 2 issues at once:
- SpawnMultiCursorUp/Down doesn't take into account the visual width of
the text before the cursor, which may be different from its character
width (e.g. if it contains tabs). So e.g. if the number of tabs before
the cursor in the current line is not the same as in the new line, the
new cursor is placed at an unexpected location.
- SpawnMultiCursorUp/Down doesn't take into account the cursor's
remembered x position (LastVisualX) when e.g. spawning a new cursor
in the below line which is short than the current cursor position, and
then spawning yet another cursor in the next below line which is
longer than this short line.
* SpawnMultiCursorUp/Down: honor softwrap
When softwrap is enabled and the current line is wrapped, make
SpawnMultiCursor{Up,Down} spawn cursor in the next visual line within
this wrapped line, similarly to how we handle cursor movements up/down
within wrapped lines.
* SpawnMultiCursorUp/Down: deselect when spawning cursors
To avoid weird user experience (spawned cursors messing with selections
of existing cursors).
It is useful to be able to use mouse not only for adding new cursors
but also for removing them. So let's modify MouseMultiCursor behavior:
if a cursor already exists at the mouse click location, remove it.
If ~/.config/micro/plug directory contains a plugin with the same name
as a built-in plugin, the expected behavior is that the user-defined
plugin in ~/.config/micro/plug is loaded instead of the built-in one.
Whereas the existing behavior is that the built-in plugin is used
instead of the user-defined one. Even worse, it is buggy: in this case
the plugin is registered twice, so its callbacks are executed twice
(e.g. with the autoclose plugin, a bracket is autoclosed with two
closing brackets instead of one).
Fix this by ensuring that if a plugin with the same name exists in the
~/.config/micro/plug directory, the built-in one is ignored.
Fixes#3029
It doesn't seem necessary to write settings to settings.json when
registering a new option. The option is set to its default value, which
means that it will not be written to settings.json (precisely because
it's the default value), so the contents of settings.json don't change
and thus don't need to be written again.
This unneeded writing, in particular, causes unexpected "The file on
disk has changed. Reload file? (y,n,esc)" each time when we open
settings.json via micro.
Fixes#2647
Avoid code duplication between RegisterCommonOption() and
RegisterCommonOptionPlug(), exactly the same way as it is done for
RegisterGlobalOption() and RegisterGlobalOptionPlug().