Saving a buffer every time without even checking if it was modified
(i.e. even when the user is not editing the buffer) is wasteful,
especially if the autosave period is set to a short value.
1. doesn't need a given parameter to set the VERSION,
since it is determined itself
2. moves the *.deb only in case package-deb.sh succeeded
3. rename *.tar.gz to *.tgz shorten the extension to...
4. add SHA256 sums per artifact
The lastCutTime feature (reset the clipboard instead of appending to the
clipboard if the last CutLine was more than 10 seconds ago) was
implemented 8 years ago but was always buggy and never really worked,
until we have accidentally found and fixed the bug just now. No one ever
complained or noticed that, which means it is not a very useful feature.
Fixing it changes the existing behavior (essentially adds a new feature
which did not really exist before) and there is no reason to assume that
this new behavior will be welcome by users. So it's better to remove
this feature.
According to tcell documentation, Rune() should only be used for KeyRune
events. Otherwise its return value is not guaranteed and should not be
relied upon.
This fixes issue #2947: Esc key not working on Windows, since tcell
sends lone Esc key event with rune == 0 on Unix but with rune == 27
(the keycode) on Windows.
Similarly to CutLine, DeleteLine and CopyLine actions, if there is a
selection, duplicate not just the current line but all the lines covered
(fully or partially) by the selection.
- Add a new Duplicate action which just duplicates the selection (and
returns false if there is no selection).
- Change the behavior of the DuplicateLine action to only duplicate the
current line, not the selection.
- Change the default action bound to Ctrl-d from DuplicateLine to
Duplicate|DuplicateLine, so that the default behavior doesn't change.
This allows the user to rebind keybindings in a more flexible way, i.e.
to choose whether a key should duplicate just lines, or just selections,
or both, - in a similar fashion to Copy, Cut, Delete actions.
If we ever encounter this clipboard.Read() failure, return false
immediately. Otherwise, InfoBar.Error(err) will have no effect (it will
be immediately overwritten by InfoBar.Message()) so we won't even know
that there was an error.
Weird behavior is observed e.g. if we cut some lines with CutLine, then
copy some selection with Copy, then cut some other lines with CutLine,
and then paste. The pasted cliboard contains not just the lines that
were cut at the last step, but also the selection that was copied before
that.
Fix that by resetting the CutLine's repeated line cuts whenever we
copy anything to the clipboard via any other action (Cut, Copy or
CopyLine).
Since CutLine may add lines to the clipboard instead of replacing the
clipboard, improve its info message to show how many lines are in the
clipboard in total, not just how many lines were added to it last time.
When there is a selection containing multiple lines, CutLine, DeleteLine
and CopyLine actions currently cut/delete/copy just the "current" line,
as usual. This behavior is at least confusing, since when there is a
selection, the cursor is not displayed, so the user doesn't know which
line is the current one.
So change the behavior. When there is a multi-line selection,
cut/delete/copy all lines covered by the selection, not just the current
line. Note that it will cut/delete/copy whole lines, not just the
selection itself, i.e. if the first and/or the last line of the
selection is only partially within the selection, we will
cut/delete/copy the entire first and last lines nonetheless.
Change behavior of the Cut action: don't implicitly call CutLine if
there is no selection. Instead, make it return false in this case
and change the default Ctrl-x binding to Cut|CutLine, to make it clear,
explicit and in line with Copy and CopyLine actions.
Make Copy return false if there is no selection, and change the default
binding for Ctrl-c from CopyLine|Copy to Copy|CopyLine accordingly,
to make the semantics more meaningful: copying selection always fails
if there is no selection.
The CutLine action has a feature: if we execute it multiple times to cut
multiple lines, new cut lines are added to the previously cut lines in
the clipboard instead of replacing the clipboard, unless those
previously cut lines have been already pasted or the last cut was more
than 10 seconds ago. This last bit doesn't really work: newly cut lines
are appended to the clipboard regardless of when was the last cut.
So fix it.
When the cursor is at the last line of buffer and it is an empty line,
CopyLine does not copy this line, which is correct, but it shows a bogus
"Copied line" message. Fix this by adding a check for that, same as in
CutLine and DeleteLine.
After executing the CopyLine action, moving cursor up or down
unexpectedly moves cursor to the beginning of the line, since its
LastVisualX value is lost in the selection/deselection manipulations.
Fix this by restoring the original LastVisualX.
After executing CutLine or DeleteLine action, the cursor is at the
beginning of a line (as expected) but then moving the cursor up or down
moves it to an unexpected location in the middle of the next or previous
line. Fix this by updating the cursor's LastVisualX.
Instead of passing a single brace pair to FindMatchingBrace(), make it
traverse all brace pairs in buffer.BracePairs on its own.
This has the following advantages:
1. Makes FindMatchingBrace() easier to use, in particular much easier
to use from Lua.
2. Lets FindMatchingBrace() ensure that we use just one matching brace -
the higher-priority one. This fixes the following issues:
([foo]bar)
^
when the cursor is on `[`:
- Both `[]` and `()` pairs are highlighted, whereas the expected
behavior is that only one pair is highlighted - the one that the
JumpToMatchingBrace action would jump to.
- JumpToMatchingBrace action incorrectly jumps to `)` instead of
`]` (which should take higher priority in this case).
In contrast, with `((foo)bar)` it works correctly.
Implement a radical approach to improving abilities of plugins to detect
and handle various changes of micro's state: add onAnyEvent callback
which is called, literally, after any event. A plugin can use this
callback to compare a state after the previous event and after the
current event, and thus is able to catch various events that cannot be
detected using other callbacks.
Some examples of such events:
- change of current working directory
- switching cursor focus between a bufpane and the command bar
- change of message text in the status bar
When updateDiffSync() is called asynchronously, it should lock the
line array when calling Bytes(), to prevent race if the line array is
being modified by the main goroutine in the meantime.