I copied all files except dot files (.github and .gitignore), the _examples
folder, and go.mod/go.sum.
At some point we may want to copy the files back to the gocui repo when other
clients (e.g. lazydocker) want to use the newer versions of them.
When switching to a different repo, and then back to the original one, searching
would no longer work. The reason is that our contexts set callbacks on their
views; when switching to a different repo we instantiate a new set of contexts,
so they will overwrite the views' callbacks with their new ones, but when
switching back to the original repo, we reuse the old contexts because they are
still in memory, but they won't set their callbacks again since they only do
this on construction.
To fix this, replace the view-local callbacks with a global one on the gui that
takes the view as an argument, so that the callback can look up the associated
context dynamically.
This brings in https://github.com/jesseduffield/gocui/pull/98 with the following
fix:
Fix rendering of CRLF sequence ('\r\n')
The FirstGraphemeCluster call returns this as a single character; we want to
treat it the same way as a single \n.
This would be a problem if e.g. a progress bar used \r repeatedly to paint over
the same line, and then printed a \n to move on to the next line; the last pair
of \r and \n was swallowed.
Another scenario where this was a problem was if you stream output of a command
to the log, and the command used \r\n as line feeds. This happens for example
for a background fetch that fails with an error; in that case we print the
combined output (stdout plus stderr) to the log after the command finished, and
for some reason it uses \r\n in that case (I can't actually explain why; when I
do `git fetch --all | xxd` I see only bare \n characters). All output would
appear on one line then.
Also, filter out escape sequences for character set designation; there's nothing
useful we can do with them. In practice, the only one that you are likely to see
is `ESC ( B`, which is sent as part of tput sgr0, which is sometimes used in
scripts to reset all graphics attributes to defaults.
Move SetContentLineCount into OverwriteLinesAndClearEverythingElse. Calling it
separately beforehand is not concurrency safe; we need both to happen
when the view's writeMutex is locked.
It is possible to scroll the selection out of view using the mouse wheel; after
doing this, it would sometimes scroll into view by itself again, for example
when a background fetch occurred. In the files panel this would even happen
every 10s with every regular files refresh.
Fix this by adding a scrollIntoView parameter to HandleFocus, which is false by
default, and is only set to true from controllers that change the selection.
Adaptions are for this gocui commit:
Cleanup: remove Is* error functions
- Use errors.Is instead of quality comparisons. This is better because it
matches wrapped errors as well, which we will need later in this branch.
- Inline the errors.Is calls at the call sites. This is idiomatic go, we don't
need helper functions for this.
See https://go.dev/blog/go1.13-errors for more about this.
This updates gocui to include https://github.com/jesseduffield/gocui/pull/68 and
https://github.com/jesseduffield/gocui/pull/69, which changes views to not have
an extra blank line at the end when content ending in a newline character is
written to them. This makes text views more consistent with list views, which
don't have a blank line after the last list entry either.
Original commit message of the gocui change:
This fixes View.Size, Width and Height to be the correct (outer) size of a view
including its frame, and InnerSize/InnerWidth/InnerHeight to be the usable
client area exluding the frame. Previously, Size was actually the InnerSize (and
a lot of client code used it as such, so these need to be changed to InnerSize).
InnerSize, on the other hand, was *one* less than Size (not two, as you would
have expected), and in many cases this was made up for at call sites by adding 1
(e.g. in calcRealScrollbarStartEnd, parseInput, and many other places in the
lazygit code).
There are still some weird things left that I didn't address here:
- a view's lower-right coordinates (x1/y1) are one less than you would expect.
For example, a view with a 2x2 client area like this:
╭──╮
│ab│
│cd│
╰──╯
in the top-left corner of the screen (x0 and y0 both zero) has x1/xy at 3, not
4 as would be more natural.
- a view without a frame has its coordinates extended by 1 on all sides; to
illustrate, the same 2x2 view as before but without a frame, sitting in the
top-left corder of the screen, has coordinates x0=-1, y0=-1, x1=2, y1=2. This
is highly confusing and unexpected.
I left these as they are because they would be even more of a breaking change,
and also because they don't have quite as much of an impact on general app code.
An inactive selection is one where the view is part of the context stack, but
not the active view. For example, the files view when you enter the staging
panel, or any view when you open a panel.
In Gui.onWorker we only make the minimum possible change to get things to
compile after the API-breaking change of the gocui update; we'll make this
cleaner later in this branch.