This stops trying to see if the previous line is wider if it is a
prefix of the current one.
Which turns out to be true often enough that it's a net benefit.
This passes character width as an argument for a few functions.
In particular, it hardcodes a width of "1" for a space literal.
There's no reason to compute wcwidth for the length of the prompt.
This measured *all* the characters on the commandline, and saved all
of them in another wcstring_list_t, just to then do... nothing with
that info.
Also, it did wcslen for something that we already have as wcstring,
reserved a vector and did a bunch of work for autosuggestions that
isn't necessary if we have more than one line.
Instead, we do what we need, which is to figure out if we are
multiline and how wide the first line is.
Fixes#5866.
line_shared_prefix explains in its comment that
> If the prefix ends on a combining character, do not include the
previous character in the prefix.
But that's not what it does.
Instead, what it appears to do is to return idx for *every* combining
mark. This seems wrong to begin with, and it also requires checking
wcwidth for *every* character.
So instead we don't do that. If we find the mismatch, we check if it's
a combining mark, and then go back to the previous character (i.e. the
one before the one that the combining mark is for).
My tests found no issues with this, other than a 20% reduction in
pasting time.
The old commit #3f820f0 "Disable ONLCR mapping of NL output to CR-NL"
incorrectly used c_iflag instead of c_oflag, and I copied that error
in my patch. Fixed that. However, there seems to be other problems
trying to use "\x1B[A", which I have not tried to debug, so comment that out.
(However, #3f820f0 seems to mostly work if we fix it to use c_oflag.)
This runs build_tools/style.fish, which runs clang-format on C++, fish_indent on fish and (new) black on python.
If anything is wrong with the formatting, we should fix the tools, but automated formatting is worth it.
* Some comment fixes and renaming of is_iterm2_escape_seq.
The comment for is_iterm2_escape_seq incorrectly says "CSI followed by ]".
This is wrong, because CSI is ESC followed by [ (or the seldom-used 0x9b).
The procedure actually matches Operating System Command (OSC) escape codes.
Since there is nothing iterm2-specific about OSC, is_osc_escape_seq
would be a better name.
Also s_desired_append_char documents a non-existent parameter.
* Update broken iterm2 url in comment.
The code already allowed for variable width (multicell) *display* of the
newline omitted character, but there was no way to define it as being
more than one `wchar_t`.
This lets us use a string on console sessions (^J aka newline feed)
instead of an ambiguous character like `@` (used in some versions of
vim for ^M) or `~` (what we were using).
C++11 provides std::min/std::max which we're using all over,
obviating the need for our own templates for this.
util.h now only provides two things: get_time and wcsfilecmp.
This commit removes everything that includes it which doesn't
use either; most because they no longer need mini or maxi from
it but some others were #including it unnecessarily.
This helps on netbsd, because enter_standout_mode et al are const
there.
These methods don't alter their argument, so they should have been
const to begin with.
This is non-const on macOS, but some of the args we pass are always
const on netbsd.
I have no idea why you'd ever want this to modify its argument, but whatever.
This reverts commit 3f820f0edf.
While the premise described by @nbuwe is sound in #4505, we are now
apparently relying on this behavior is some places (although
inadvertently as there doesn't seem to be a deliberate acknowledgement
of that anywhere).
Turning off ONLCR causes things like indented multiline commands to not
appear correct at the tty (subsequent lines appear both at column 0 and
again indented).
Per @nbuwe's excellent explanation in #4505, we can save on output
to the tty by maintaining column location after NL by disabling the
ONLCR terminal mode.
Closes#4505.
While supported by gcc and clang, \e is a gcc-specific extension and not
formally defined in the C or C++ standards.
See [0] for a list of valid escapes.
[0]: https://stackoverflow.com/a/10220539/17027
Turns out the segfaults we've been getting in our tests are because we set $TERM to "dumb".
So we only clear the line if the terminal isn't dumb.
This reverts commit 745a88f2f6.
Fixes#2320.
When the pager wants to use the full screen to show many options, it reserves
space at the top to see the command. Previously it pretended the command was a
prompt and engaged the prompt layout mechanism to compute these lines. Instead
let's juts count newlines since escape sequences within commands are very rare.
There were several issues with the way that the include tests for curses.h
were being done that were ultimately causing fish to use the headers from
ncurses but link against curses on platforms that provide an actual
libcurses.so that isn't just a symlink to libncurses.so
In particular, the old code was first testing for curses's cureses.h and then
falling back to libncurses's implementation of the same - but that logic was
reversed when it came to including term.h, in which case it was testing for
the ncurses term.h and falling back to the curses.h header. Long story short,
while cmake will link against libcurses.so if both libcurses.so and
libncurses.so are present (unless CURSES_NEED_NCURSES evaluates to TRUE, but
that makes ncurses a hard requirement), but we were brining in some of the
defines from the ncurses headers, causing SIGSEGV panics when fish ultimately
tried to access variables that weren't exported or were mapped to undefined
areas of memory in the other library.
Additionally it is an error to include termios.h prior to including the plain
Jane curses.h (not ncurses/curses.h), causing errors about unimplemented types
SGTTY/chtype. So far as I can tell, both curses.h and ncurses/curses.h pull in
termios.h themselves so it shouldn't even be necessary to manually include it,
but I have just moved its #include below that of curses.h
The type cached_esc_sequences_t caches escape sequences, and is tasked
with finding an escape sequence that prefixes a given string. Before
this fix, it did so by storing the lengths of cached escape sequences,
and searching for substrings of that length. The new implementation
instead stores all cached escape sequences in a sorted vector, and uses
binary search to find the shortest escape sequence that is a prefix of
the input. This is a substantial simplification that also reduces
allocations.
* Fix clearing abandoned line with VTE
With VTE-based terminals, resizing currently causes multi-line prompts
to go weird.
This changes the sequence we use to clear the line to one suggested by
a VTE
developer (https://bugzilla.gnome.org/show_bug.cgi?id=763390#c4).
It changes nothing in konsole 17.04.3 and urxvt 9.22, but they already
work.
Note that this does not fix the case where output did not end in a
newline, but that doesn't seem to be up to us. Also, it only affects
those lines.
Fixes#2320.
* Use terminfo definition instead of hardcoding
Thanks to @ixjlyons.
This is the first step to implementing issue #4200 is to stop subclassing
env_var_t from wcstring. Not too surprisingly doing this identified
several places that were incorrectly treating env_var_t and wcstring as
interchangeable types. I'm not talking about those places that passed
an env_var_t instance to a function that takes a wcstring. I'm talking
about doing things like assigning the former to the latter type, relying
on the implicit conversion, and thus losing information.
We also rename `env_get_string()` to `env_get()` for symmetry with
`env_set()` and to make it clear the function does not return a string.
There should be just one place that calls `setupterm()`. While refactoring
the code I also decided to not make initializing the curses subsystem a
fatal error. We now try two fallback terminal names ("ansi" and "dumb")
and if those can't be used we still end up with a usable shell.
Fixes#3850
I recently upgraded the software on my macOS server and was dismayed to
see that cppcheck reported a huge number of format string errors due to
mismatches between the format string and its arguments from calls to
`assert()`. It turns out they are due to the macOS header using `%lu`
for the line number which is obviously wrong since it is using the C
preprocessor `__LINE__` symbol which evaluates to a signed int.
I also noticed that the macOS implementation writes to stdout, rather
than stderr. It also uses `printf()` which can be a problem on some
platforms if the stream is already in wide mode which is the normal case
for fish.
So implement our own `assert()` implementation. This also eliminates
double-negative warnings that we get from some of our calls to
`assert()` on some platforms by oclint.
Also reimplement the `DIE()` macro in terms of our internal
implementation.
Rewrite `assert(0 && msg)` statements to `DIE(msg)` for clarity and to
eliminate oclint warnings about constant expressions.
Fixes#3276, albeit not in the fashion I originally envisioned.
Cache the escape sequences we've seen when checking for those which
don't take any visual space when writing the prompt or similar strings.
This reduces the cost of determining the true cost of such strings by a
full order of magnitude if they include lots of such escape sequences.
Periodically sort the cached escape sequence lengths based on feedback
from cache hits so that we're always checking for the most likely
sequence lengths first.
Also cache the prompt layouts to avoid doing the calculations if the
prompt doesn't change.
Fixes#3793
We should never use stdio functions that use stdout implicitly. Saving a
few characters isn't worth the inconsistency. Too, using the forms such
as `fwprintf()` which take an explicit stream makes it easier to find
the places we write to stdout versus stderr.
Fixes#3728
On some platforms, notably GNU libc, you cannot mix narrow and wide
stdio functions on a stream like stdout or stderr. Doing so will drop
the output of one or the other. This change makes all output to the
stderr stream consistently use the wide forms.
This change also converts some fprintf(stderr,...) calls to debug()
calls where appropriate.
Fixes#3692