Ensure that the selection start is always before the selection end,
regardless of the direction of a mouse selection, to make
h.Cursor.Deselect() handle its `start` argument correctly.
This makes the cursor behavior after mouse selections consistent with
the cursor behavior after keyboard selections.
Fixes#3055
Previously `CursorDown` function called `Deselect` with a wrong
argument which lead to the situation when cursor was moved to the
start instead of the end of the selection
Signed-off-by: Yevhen Babiichuk (DustDFG) <dfgdust@gmail.com>
Fix the following buggy behavior:
1. bind "<n><a>" to the Paste action in the command bar
2. open a split pane, type some text and press Ctrl-q to close it
3. answer "n" to the "Save changes before closing?" prompt
4. press Ctrl-e to open the command prompt and press "a"
-> result: instead of inserting the "a" letter, clipboard is pasted.
It is not really defined what is the meaning of this return value.
Currently this value is always true. And even if this value actually
meant something (for example, the result of the last executed action
in the chain), we should not use this value in HandleEvent(). The key
event handling logic should behave the same regardless of whether the
action triggered by this key succeeded or not.
If onBufPaneOpen callback execution fails (e.g. due to a Lua runtime
error), report this error to the user, like we do for all other Lua
callbacks, rather than silently continue working as if nothing
happened.
After reloading a file that has been externally modified, the buffer
view may become invalid: the displayed subset of lines of the file may
no longer exist, since the file may have been truncated. So relocate the
buffer view in this case.
In particular, this fixes crashes caused by out of bounds accesses to
the line array by displayBuffer() trying to display no longer existing
lines.
* parser: Precise error message for missing `start` & `end` in region
* parser: Check and prompt for empty patterns and region properties
* syntax: Remove empty identifier pattern from log definition
Fix `set filetype unknown` not working as expected in the following
scenario:
1. open foo.txt (no filetype detected) -> ft is `unknown`, highlighted
with default.yaml, as expected
2. `set filetype go` -> ft is `go`, highlighted with go.yaml as expected
3. `set filetype unknown` -> ft is still `go`, still highlighted with
go.yaml (whereas expected behavior is: ft is `unknown`, highlighted
with default.yaml)
Fix that by always updating b.SyntaxDef value, not reusing the old one.
This also makes the code simpler and easier to understand.
This is necessary since DoEvent() isn't called in a loop like in the main
application, but as one-shot only and a async draw event can lead to ignore
the explicit injected events.
Additional checks have been added to check the presence of the expected buffers.
Currently onSetActive is called when the user clicks with the mouse on
a pane even if this pane is already active. We should avoid calling it
in this case.
Implementation detail: like with tabs in the previous commit, we cannot
check if the pane is already active just by checking the index passed
to the Tab's SetActive() (since the index may not change while the pane
itself changes), we need to check state of the pane itself. So we move
the onSetActive invocation from the Tab's SetActive() to the BufPane's
SetActive().
We should call the onSetActive callback not only when switching to
another bufpane within the same tab but also when switching to another
tab.
Note on implementation details:
- In SetActive() we need to check if the tab is not already active, to
avoid calling onSetActive for an already active bufpane.
- We cannot check that just by checking if the tab index passed to
SetActive() is different from the current active tab index, since this
index may remain the same even if the tab itself is different (in the
case of removing a tab from the tablist). So we need to check the tab
itself, not just the tab index. So we introduce the isActive field,
to track the tab's active state in the Tab structure itself.
Check if startline value is valid before passing it to input.State(),
to prevent a theoretically possible race when the number of lines
changes in the meantime, causing an out of bounds access.
Actually this race cannot happen: ReHighlightStates() is only called
from the main goroutine, and the line array is modified, again, only by
the main goroutine. So for now this change is rather cosmetic: it is
just to make the highligher API implementation self-sufficiently safe
without assumptions about which goroutines are using which API functions
and how.