When using +/ or +?, any minor feedback should be cleared,
to not distract from the highligted search result.
This fixes https://savannah.gnu.org/bugs/?60669.
Bug existed since version 5.5, commit b86f7868,
since the manner of grading status-bar messages changed.
After a "+" only c, r, C, and R are valid characters,
and only when immediately followed by / or ?.
This fixes https://savannah.gnu.org/bugs/?60667.
Bug existed since version 4.4, commit 2326bf6,
since searching at startup with +/ or +? was introduced.
The "^_" has always been poorly legible (the underscore melting into
the bottom of the terminal) and difficult to type (Shift+Ctrl+minus).
The "^/" is both more readable and easier to type.
In terminal emulators, "^/" is shown, but on a Linux console "^-",
as ^/ does a backspace in the default console key mapping.
Also, allow using "^-" when rebinding ^_ in a nanorc file.
This addresses https://savannah.gnu.org/bugs/?57393.
Simply adding the number of bytes in the quoting part is not entirely
correct, but... currently the indenting and commenting routines also
assume that the whitespace and commenting characters that are added or
removed are single-byte characters... It will require another patch
to make this all fully correct, but for the default configuration
(and probably most other cases) the current fix will work fine.
This fixes https://savannah.gnu.org/bugs/?60605.
Bug existed since version 4.4, commit 8fce33af from two years ago,
since this automatic copying of the quoting part was introduced.
This fixes https://savannah.gnu.org/bugs/?60596.
Bug existed since version 4.4, commit 8fce33af from two years ago,
since this automatic copying of the quoting part was introduced.
When on a one-row terminal a message gets automatically "dropped"
after a few moments, the subsequent waiting for a keystroke should
not think that there is still a message on the status bar.
This fixes https://savannah.gnu.org/bugs/?60591.
Bug existed since commit 8d974cd2 from two days ago.
When there is just one row and there is a message, it is not a good idea
to draw the contents of the buffer as it would overwrite the message.
This fixes https://savannah.gnu.org/bugs/?60582.
Bug existed since version 2.7.0, since nano allows very flat terminals,
and was made worse by commit 2cf28f9d from yesterday.
Redraw the content of the edit window (for the undone final completion)
before pushing out the "No further matches" message, so that the latter
will not get overwritten by the buffer content -- in case the terminal
has just one row.
This fixes https://savannah.gnu.org/bugs/?60581.
Bug existed since commit 2cf28f9d from yesterday.
Only important error messages (ALERT) and information that the user
requested (^C, M-D) should stay put until the next keystroke. Other
messages should be overwritten by the text of the buffer after just
a few moments, to make a one-row terminal slightly more friendly.
This addresses https://savannah.gnu.org/bugs/?60570.
When showing a message on the status bar, the cursor should be off.
This fixes https://savannah.gnu.org/bugs/?60510.
Bug existed since version 2.7.0, since nano allows very flat terminals.
When there is just one row, the text to be edited needs to be shown
there, not some meta information about the cursor position.
This fixes https://savannah.gnu.org/bugs/?60563.
Bug existed since version 2.7.0, since nano allows very flat terminals.
Since version 5.6, commit 76742cc1, nano highlights the search match,
which means that the screen gets refreshed anyhow, so this specific
refresh for a one-row terminal is no longer needed.
This prevents read() from returning unexpectedly and causing a crash.
This fixes https://savannah.gnu.org/bugs/?60537.
Reported-by: Filips Romāns <frfilips@gmail.com>
Bug existed since version 2.4.2, since the handling of SIGWINCH changed.
That is: call edit_refresh() right away, to prevent the edit_refresh()
in the main loop from overwriting the status-bar message.
This fixes https://savannah.gnu.org/bugs/?60516.
Bug existed since version 2.7.2, commit f920e0d3.
That is: call edit_refresh() right away, to prevent the edit_refresh()
in the main loop from overwriting the status-bar message.
This fixes https://savannah.gnu.org/bugs/?60518.
Bug existed since version 5.6, commit 76742cc1.
When there is just one row, the user wants to see text on this row,
not a bar with some meta info.
This fixes https://savannah.gnu.org/bugs/?60508.
Bug existed since version 5.5, since the minibar was introduced
with commit d31cc373.
This reduces startup time by seven percent (when using the standard set
of syntaxes) when opening just one file that doesn't match any syntax,
and more than ten percent when opening multiple files. It takes some
extra memory, but... not wasting CPU cycles is more important.
This addresses https://savannah.gnu.org/bugs/?56433.
When undoing several actions, it is possible for the line at the top
of the screen to be removed, leaving 'edittop' pointing to a structure
that has been freed. Soon after, 'edittop' is referenced to determine
whether the cursor is offscreen... Prevent this invalid reference by
stepping 'edittop' one line back in that special case. This changes
the normal centering behavior of Undo when the cursor goes offscreen,
but... so be it.
When a single node is deleted, it is always possible to step one line
back, because a buffer contains always at least one line (even though
maybe empty), so if the current line could be deleted, there must be
one before it (when at the top of the screen).
This fixes https://savannah.gnu.org/bugs/?60436.
Bug existed since version 2.3.3, commit 60815461,
since undoing does not always center the cursor.
Since two commits ago, the position of the indicator shows the position
of the viewport relative to the full buffer in terms of actual lines,
not of visual chunks (to avoid excessive computation). But the size of
the indicator stayed constant, as if it always covered as many lines as
the edit window has rows. But the latter will not be the case when
softwrapping occurs. Therefore, when softwrapping, compute how many
actual lines are visible in the viewport, and adjust the size of the
indicator accordingly.
Whenever softwrap was toggled on or line numbers were toggled on/off or
the window was resized, the extra rows per line needed to be recomputed
for ALL the lines. For large files with many long lines this was too
costly.
(This change causes the indicator to have an incorrect size when there
are many softwrapped chunks onscreen, but that will be addressed later.)
This fixes https://savannah.gnu.org/bugs/?60429.
Problem existed since version 5.0, since the indicator was introduced.
This makes the handling of plain ASCII a tiny bit slower, but it
affects only the users of --constantshow without --minibar, so...
All other uses of mbstrlen() and collect_char() are not in speed-
critical code paths.
Since the previous commit, mbwidth() is used only to determine whether
a character is either double width or zero width. There is no need to
return the actual width of the character; a simple yes or no is enough.
Transforming mbwidth() into is_doublewidth() also allows streamlining
it and is_zerowidth() a bit, so that they become slightly faster.
The number of bytes in the character were determined twice: first in
mbwidth() and then in char_length(). Do it just once, in mbtowide().
Also, avoid calling is_cntrl_char(), because it does unneeded checks
when we already know that the high bit is set.
This duplicates some code, but advance_over() is called a lot, so it
is important that it is as fast as possible.
This shouldn't slow down plain ASCII, as the extra checks (use_utf8
and *string < 0xA0) are done only for non-ASCII (apart from DEL).
The 'start_index' was in index in the given text, while 'index' is an
index in the displayable string. Having both of them using 'index' in
their name was somewhat confusing.
For a normal file (without overlong lines) the strlen() wasn't much
of a problem. But when there are very long lines, it wasted time
counting stuff that wouldn't be displayed on the current row anyway,
and reserved *far* too much memory for the displayable string.
Problem existed since commit cf0eed6c from five years ago that traded
a continuous comparison (of the used space with the reserved space)
against a one-time big reservation up front involving a strlen().
In retrospect that was not a good trade-off when softwrapping.
The extra check (charwidth == 0) is incurred only by characters that
have their high bit set, so the average file (with only ASCII) is not
affected by this -- it just loses an unneeded call of strlen().
In UTF-8 valid multibyte characters are at most four bytes long,
and now that we no longer make use of mblen() and mbtowc() from
the underlying system, we won't get five- or six-byte sequences
mistakenly reported as valid (by glibc). So it is always enough
to reserve space for just four bytes per character.
Calling wctomb() with NULL as the first parameter returns zero in a
UTF-8 locale, meaning that there is no state, so there is no point
in resetting it either.
The two calls of draw_row() are each immediately preceded by a call to
display_string(), which has already determined from which x position
and until which x position in the relevant line the current row will
be drawn -- doing this again in draw_row() is a waste of time. Even
though it is ugly, pass the two data points from one function to the
other via global variables.
For normal files (without overlong lines), this saves on average some
fifty calls of advance_over() per row. When softwrapping a file with
overlong lines, the savings for each softwrapped chunk are much higher.
(Well, it now checks that ^G is still the first shortcut that is bound
to 'do_help', but that is good enough: if the user did any rebinding,
they probably do not need any reminder about how to invoke 'Help'.)
This fixes https://savannah.gnu.org/bugs/?60315.
Reported-by: Robert Goulding <goulding.2@nd.edu>
This saves a function call, and the passing and checking of the
MAXCHARLEN parameter, and the checking whether wc is maybe NULL
(which for nano is never the case), and who knows what other
overheads mbtowc() has, and our workaround for glibc.
Code was written after looking at gnulib/lib/mbrtowc-impl-utf8.h.
Most implementations of mblen() do a call to mbtowc(), which is
a waste of time when all we want to know is the number of bytes
(and when we already know that we're using UTF-8 and that the
first byte is at least 0xC2).
(This also avoids burdening correct implementations with the
workaround that was needed only for glibc.)
Code was written after looking at gnulib/lib/mbrtowc-impl-utf8.h.
The mblen() and mbtowc() functions will happily return 4 or 5 or 6
for byte sequences that start with 0xF4 0x90 or higher. But those
sequences encode for U+110000 or higher, which are not valid Unicode
code points. The libc of FreeBSD and OpenBSD and Alpine correctly
return -1 for such sequences. Make nano behave correctly also when
linked against glibc, so that invalid sequences are always presented
as a series of invalid bytes and never as a single invalid code.
This fixes https://savannah.gnu.org/bugs/?60262.
Bug existed since before version 2.0.0.
The call of this function in make_mbchar() does not add anything,
because wctomb() already returns -1 for codes U+D800 to U+DFFF,
and parse_verbatim_kbinput() already rejects anything that starts
with U+11.... or higher, so make_mbchar() is never called for codes
beyond U+10FFFF.
And the call in display_string() just needs to check for wc <= 0x10FFFF
because mbtowc() already returns -1 for codes U+D800 to U+DFFF.
That is, accept U+FDD0 to U+FDEF, and accept U+xxFFFE and U+xxFFFF
for xx from 00 to 10 hex, being the 66 reserved "non-characters".
It may not be wise of the user to input these "things" (by typing
their code after M-V), but the codes are valid Unicode code points
and should not be rejected.
See https://www.unicode.org/faq/private_use.html#nonchar8 et al.
This fixes https://savannah.gnu.org/bugs/?60263.
Bug existed since before version 2.0.0.
When inserting a file into the current buffer, the 'fmt' element will
already be set. When we avoid overwriting the current value of 'fmt'
(when it's other than UNSPECIFIED), we don't need to save and restore
the value when inserting a file.
When saving the buffer under a different name, it should by default
have the same format as the original file.
This fixes https://savannah.gnu.org/bugs/?60278.
Bug existed since version 2.6.0, commit 0293eac1.
This improves the fix for https://savannah.gnu.org/bugs/?60269,
by not dropping error messages that happen before a buffer is opened.
This basically reverts commit b63c90bf from a year ago, except that
it now always deletes the created buffer when the user does not want
to override the lock file, also when it is the only buffer.
Set the 'format' of a file only when it has been fully read in,
so that this field can be used to indicate that any later error
message cannot be meant for this buffer.
This fixes https://savannah.gnu.org/bugs/?60269.
Bug existed since commit 6bf52dcc from yesterday.
Make sure there is an 'openfile' record before trying to save an
error message in this record.
This fixes https://savannah.gnu.org/bugs/?60268.
Bug existed since commit ede64d7e from yesterday.
When opening multiple files and some of them had an error, only the
first message was shown and the others were lost -- indicated only
by three dots. Improve upon this by storing the first error message
for each buffer and showing this message when the buffer is first
switched to.
Requested-by: Mike Frysinger <vapier@gentoo.org>
That is: reserve for the current line and current character the number
of positions needed for the total number of lines and characters, and
reserve two positions for both the current column and the total number
of columns. This will keep all nine numbers in the output in the same
place -- as long as there are no lines with more than 99 columns. In
this latter case there will still be some jitter, but all-in-all the
output is much stabler than it was.
Suggested-by: Mike Frysinger <vapier@gentoo.org>
The number of lines in a group is the difference in line numbers
between the last line and the first line *plus one*.
This fixes https://savannah.gnu.org/bugs/?60104.
Bug existed since version 2.9.0, since indenting and unindenting
became undoable, and commit f722c532 formed a part of that.
Allocating it again would leak the existing space.
This fixes https://savannah.gnu.org/bugs/?60172.
Reported-by: Mike Frysinger <vapier@gentoo.org>
Bug existed since version 5.6, commit 1fdd23d3.
When the version number is a trio, the version string will occupy
ten bytes and the terminating NUL byte would not be written (which
was not a problem as byte 12 of the lock data is zero anyway).
But it's better to not have the compiler complain, so allow writing
the terminating NUL byte outside of the ten bytes reserved for the
version string.
This fixes https://savannah.gnu.org/bugs/?60149.
Reported-by: Peter Passchier <peter@passchier.net>
Reported-by: Liu Hao <lh_mouse@126.com>
Bug existed since version 5.6, since a special color for highlighting
search matches was introduced in commit 87fe73dd.
Full justification (like justification of a selection) is probably
a rather rare action -- and possibly even an unintended action --
so it's good to give feedback about what happened also when using
the minibar.
When a line is marked as JUSTONTHIS, there should be no second start
match on that line, because otherwise the line would have been marked
as STARTSHERE (unless there is also a second end match -- but it's
fine to do unnecessary refreshes in this unlikely case, as long as
the necessary refreshes are made).
This fixes https://savannah.gnu.org/bugs/?60074.
Bug existed since version 2.5.0, but has been masked (for the C syntax)
by unnecessary refreshes since version 4.1, commit c9605e73.
When a line is marked as NOTHING, then the existence or the appearance
of an end match is irrelevant: there is no unpaired start match, so no
recoloring would occur, so there is no need to refresh.
When a line is marked as WOULDBE, then the existence or the appearance
of a start match is irrelevant (for the lines after the first WOULDBE
line): there already is an unpaired start match, so another one will
not change anything, so no refresh is needed. Only the appearance of
an end match would recolor things and thus require a refresh. However,
start and end regexes could match the same thing, so an end might get
misinterpreted as a start. So the rule has to check for the absence
of both a start and an end match, like for WHOLELINE.
This addresses https://savannah.gnu.org/bugs/?60072.
A step forward needs to be forced not when both start match and
end match have zero length, but when the "full match" (all text
from the start of the start match to the end of the end match)
covers zero bytes. In other words: the start and end match are
both of zero length AND are at the same spot.
Now that a search match gets highlighted, the unsuspecting user might
think that the text is selected, because it is colorized the same way
as selected text. Avoid this by colorizing a highlighted search match
with its own specific color, black on yellow by default.
In addition, suppress the feedback for M-C also when --minibar
isn't used, as the feedback obscures the effect of the toggle:
showing information about the cursor position on the status bar.
This fixes https://savannah.gnu.org/bugs/?60019.
Bug existed since commit 7545eb5b from one week ago.
Highlighting an occurrence is so much clearer than just putting the
cursor on it. People seem to like it. So let's make this how nano
behaves by default.
Take two conditions that are relevant only for a rather unlikely case
(a start match without a corresponding end match) out of an inner loop.
Give the case its own, dedicated loop.
When leaving the multidata unset (as was done until now) and the
end match is offscreen, then this could lead to miscolorings later
when jumping over this end match instead of scrolling past it.
This fixes https://savannah.gnu.org/bugs/?60012.
Bug existed since before version 2.1.10.
When a large piece of text or code is pasted or inserted, it could
contain matches for start= and end= regexes, and backtracking from
the current screen could mistake an end for a start and could thus
miscolor things. Avoid this by recalculating the multiline cache
for pastes and insertions that cover more than a screenful.
This fixes https://savannah.gnu.org/bugs/?59982.
Bug existed since version 2.6.0, but existed also before 2.4.3.
This allows having an even leaner interface, and gives the M-C toggle
an appropriate function (instead of leaving it a "dead" keystroke).
Suggested-by: Sébastien Desreux <seb@h-k.fr>
If a paste (or insertion) is more than a screenful, it will not set
'focusing' to FALSE. In that case, and when line numbers are already
active, then 'focusing' should be kept set to TRUE, despite it getting
set to FALSE by ensure_firstcolumn_is_aligned(). That latter action
is meant to cushion size changes of the edit window, but in this case
the large paste (or insertion) should trump the size change.
This fixes https://savannah.gnu.org/bugs/?59981.
Bug existed since version 2.8.3, commit 2b385478.
Commit 43d94692 fixed a miscoloring bug [1] by doing proper backtracking
for multiline regexes. But this change also solves an older miscoloring
issue [2] without needing to recalculate all the multiline data. So...
just drop the old fix. (This isn't perfect: it's probably possible to
cook up a replacement scheme where things get miscolored, but... until
then, this is good enough.)
[1] https://savannah.gnu.org/bugs/?59948
[2] https://savannah.gnu.org/bugs/?58481
Also, there is no need to set 'refresh_needed' in do_replace_loop(),
because each replacement prompt will call edit_refresh() anyway, and
the functions that call do_replace_loop() will set it afterward.
The precalc_multicolorinfo() routine will assign a value to every
element for every line without looking at any current value, so
wiping the data first is a waste of time.
After having been allocated, the multidata will get computed
immediately, in precalc_multicolorinfo() and draw_row(), so
first setting each element to -1 is a small waste of time.
The initialization of -1 cannot possibly match with NOTHING or
WHOLELINE or the other available values.
(Also, put in a warning, as I don't think an onscreen line without
a multidata cache can occur at all.)
Backtracking from the first row is needed in case a start match was
added recently somewhere offscreen and the user jumped to the current
location (instead of scrolling) so that the CWOULDBE markings did not
reach the current lines.
Also, search for an end match only for the first screen row. For the
other rows, rely on the CENDAFTER, CWHOLELINE, and CWOULDBE values to
indicate whether there *is* an end match (the first two values) or not.
This saves considerable time when there is no end match in the large
remainder of a buffer: it will search in vain for the end match just
once, instead of for every row of the screen.
This fixes https://savannah.gnu.org/bugs/?59948,
and addresses https://savannah.gnu.org/bugs/?59945.
Bug existed since version 2.7.5, commit b3bcc8ee.
Like the other two fragments that advance over a zero-length match,
also this fragment should avoid the possibility of stepping beyond
the end of the line.
When a zero-length match is beyond the width of the screen, there
is no point in continuing evaluating the rule, so the check for
"offscreen to the right" needs to come first. The check for a
zero-width match needs to come second because otherwise we would
get stuck on such a match when it is offscreen to the left.
When the match of a coloring regex is beyond the width of the screen,
there is no point in continuing to evaluate the regex for the rest of
the line, because any other matches will be offscreen too.
This will save some time when there are several overlong lines.
A syntax has on average a dozen coloring rules, but on average maybe
three or four pieces of text (rough estimate) in a line get painted.
So, on average, it is cheaper to call wattron() and wattroff() only
when actually coloring a piece of text, instead of calling wattron()
before starting to evaluate each rule and wattroff() after finishing
its evaluation.
When reaching end-of-line after having found a zero-width end match,
nano should not continue at 'seek-an-end' but instead at 'step_two':
going on to seek a start match in the current line.
(There is no bug report, because I cannot figure out how to trigger
this issue and cause nano to misbehave. The problem was found while
reviewing the comments.)
Bug existed since commit 9a4a5454 from four years ago,
but the behavior was poorer before that commit.
When the filename, header-line, and magic regexes are first compiled
while reading in the rc files (to check their validity), REG_NOSUB is
used, but for some reason this wasn't done when each of these regexes
gets recompiled in order to be used. Fix this oversight. It shaves
some twenty percent off of each of these regexes' compiling time.
The combining characters (that are zero-width) start at U+0300.
After that it's pretty much chaos, width-wise.
The mbwidth() function is not called for control characters (whose
representation takes up two columns), as they are handled separately.
The calls of mbwidth() that *can* happen with a control character as
argument are only to determine whether the character is zero-width,
and then it doesn't matter whether the exact width is 1 or 2.
An invalid UTF-8 starter byte should not be represented in the same way
as a valid Unicode character.
This fixes https://savannah.gnu.org/bugs/?59832.
Bug existed since two weeks ago, since the mini-bar code was merged.
The first byte of a multi-byte UTF-8 sequence must be in the range
0xC2...0xFF. Any other byte cannot be a starter byte and can thus
immediately be treated as a single byte.
When the tail of the answer still fits exactly on the screen, the ">"
continuation character should not be shown -- also when the start of
the answer is "scrolled off" to the left.
This fixes https://savannah.gnu.org/bugs/?59816.
Bug existed in this form since version 4.0, commit 56181896.
When making small movements in the lower right corner, ncurses can
get confused about where the cursor actually is -- a double-width
character seems to throw its calculations off.
This addresses https://savannah.gnu.org/bugs/?59808.
Bug existed since version 5.4, commit 39705c60.