Merge branch 'master' into rexy712
This commit is contained in:
commit
263c7fefbf
54
configure.ac
54
configure.ac
@ -167,6 +167,30 @@ if test "x$enable_extra" != xno; then
|
||||
AC_DEFINE(ENABLE_EXTRA, 1, [Define this to have an Easter egg.])
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(formatter,
|
||||
AS_HELP_STRING([--disable-formatter], [Disable the formatting tool]))
|
||||
if test "x$enable_tiny" = xyes; then
|
||||
if test "x$enable_formatter" = xyes; then
|
||||
if test "x$enable_color" != xyes; then
|
||||
AC_MSG_ERROR([
|
||||
*** --enable-formatter needs both --enable-color and --enable-nanorc to work])
|
||||
fi
|
||||
else
|
||||
enable_formatter=no
|
||||
fi
|
||||
fi
|
||||
if test "x$enable_color" = xno; then
|
||||
if test "x$enable_formatter" = xyes; then
|
||||
AC_MSG_ERROR([
|
||||
*** --enable-formatter cannot work with --disable-color nor --disable-nanorc])
|
||||
else
|
||||
enable_formatter=no
|
||||
fi
|
||||
fi
|
||||
if test "x$enable_formatter" != xno; then
|
||||
AC_DEFINE(ENABLE_FORMATTER, 1, [Define this to have access to a formatter.])
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(help,
|
||||
AS_HELP_STRING([--disable-help], [Disable the built-in help texts]))
|
||||
if test "x$enable_tiny" = xyes; then
|
||||
@ -220,7 +244,7 @@ if test "x$enable_libmagic" = xyes; then
|
||||
if test "x$enable_tiny" = xyes; then
|
||||
if test "x$enable_color" != xyes; then
|
||||
AC_MSG_ERROR([
|
||||
*** --enable-libmagic needs --enable-color and --enable-nanorc to work])
|
||||
*** --enable-libmagic needs both --enable-color and --enable-nanorc to work])
|
||||
fi
|
||||
fi
|
||||
if test "x$enable_color" = xno; then
|
||||
@ -229,6 +253,30 @@ if test "x$enable_libmagic" = xyes; then
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(linter,
|
||||
AS_HELP_STRING([--disable-linter], [Disable the linting tool]))
|
||||
if test "x$enable_tiny" = xyes; then
|
||||
if test "x$enable_linter" = xyes; then
|
||||
if test "x$enable_color" != xyes; then
|
||||
AC_MSG_ERROR([
|
||||
*** --enable-linter needs both --enable-color and --enable-nanorc to work])
|
||||
fi
|
||||
else
|
||||
enable_linter=no
|
||||
fi
|
||||
fi
|
||||
if test "x$enable_color" = xno; then
|
||||
if test "x$enable_linter" = xyes; then
|
||||
AC_MSG_ERROR([
|
||||
*** --enable-linter cannot work with --disable-color nor --disable-nanorc])
|
||||
else
|
||||
enable_linter=no
|
||||
fi
|
||||
fi
|
||||
if test "x$enable_linter" != xno; then
|
||||
AC_DEFINE(ENABLE_LINTER, 1, [Define this to have access to a linter.])
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(linenumbers,
|
||||
AS_HELP_STRING([--disable-linenumbers], [Disable line numbering]))
|
||||
if test "x$enable_tiny" = xyes; then
|
||||
@ -286,14 +334,14 @@ if test "x$enable_operatingdir" != xno; then
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(speller,
|
||||
AS_HELP_STRING([--disable-speller], [Disable the spell-checker functions]))
|
||||
AS_HELP_STRING([--disable-speller], [Disable the spell-checking tool]))
|
||||
if test "x$enable_tiny" = xyes; then
|
||||
if test "x$enable_speller" != xyes; then
|
||||
enable_speller=no
|
||||
fi
|
||||
fi
|
||||
if test "x$enable_speller" != xno; then
|
||||
AC_DEFINE(ENABLE_SPELLER, 1, [Define this to have the spell-checker functions.])
|
||||
AC_DEFINE(ENABLE_SPELLER, 1, [Define this to have access to a spell checker.])
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(tabcomp,
|
||||
|
||||
@ -150,16 +150,18 @@
|
||||
<b>--disable-color</b> Disable color and syntax highlighting
|
||||
<b>--disable-comment</b> Disable the comment/uncomment function
|
||||
<b>--disable-extra</b> Disable the easter egg
|
||||
<b>--disable-formatter</b> Disable the formatting tool
|
||||
<b>--disable-help</b> Disable the built-in help texts
|
||||
<b>--disable-histories</b> Disable the saving of search strings and cursor positions
|
||||
<b>--disable-justify</b> Disable the justify/unjustify functions
|
||||
<b>--disable-libmagic</b> Disable the use of libmagic for determining a file's syntax
|
||||
<b>--disable-linenumbers</b> Disable line numbering
|
||||
<b>--disable-linter</b> Disable the linting tool
|
||||
<b>--disable-mouse</b> Disable mouse support
|
||||
<b>--disable-multibuffer</b> Disable the opening of multiple file buffers
|
||||
<b>--disable-nanorc</b> Disable the use of .nanorc files
|
||||
<b>--disable-operatingdir</b> Disable the setting of an operating directory
|
||||
<b>--disable-speller</b> Disable the spell-checker functions
|
||||
<b>--disable-speller</b> Disable the spell-checking tool
|
||||
<b>--disable-tabcomp</b> Disable the tab-completion functions
|
||||
<b>--disable-wordcomp</b> Disable the word-completion function
|
||||
<b>--disable-wrapping</b> Disable all hard-wrapping of text</pre>
|
||||
|
||||
@ -74,6 +74,12 @@ using the arrow keys. Holding down the Ctrl or Alt key too will increase
|
||||
the stride.
|
||||
Any cursor movement without Shift being held will cancel such a selection.
|
||||
.sp
|
||||
Any valid Unicode code point can be inserted into the buffer by typing
|
||||
\fBM\-V\fR followed by the hexadecimal digits of the code point (concluded
|
||||
with \fB<Space>\fR or \fB<Enter>\fR when it are fewer than six digits).
|
||||
A literal control code (except \fB^J\fR) can be inserted by typing
|
||||
\fBM\-V\fR followed by the pertinent keystroke.
|
||||
.sp
|
||||
The two lines at the bottom of the screen show some important commands;
|
||||
the built-in help (\fB^G\fR) lists all the available ones.
|
||||
The default key bindings can be changed via a \fInanorc\fR file -- see
|
||||
|
||||
@ -222,14 +222,18 @@ typed the key with that value.
|
||||
|
||||
@item
|
||||
For any possible character, pressing @kbd{M-V} (Alt+V) and then typing a
|
||||
six-digit hexadecimal number (starting with @kbd{0} or @kbd{1}) will enter the
|
||||
corresponding Unicode character into the buffer.
|
||||
series of hexadecimal digits (at most six, or concluded with @kbd{Enter} or
|
||||
@kbd{Space}) will enter the corresponding Unicode character into the buffer.
|
||||
@end itemize
|
||||
|
||||
For example, typing @kbd{Esc Esc 2 3 4} will enter the character "ê" ---
|
||||
useful when writing about a French party. Typing @kbd{M-V 0 0 2 2 c 4}
|
||||
will enter the symbol "⋄", a little diamond.
|
||||
|
||||
Typing @kbd{M-V} followed by anything other than a hexadecimal digit
|
||||
will enter this keystroke verbatim into the buffer, allowing the user
|
||||
to insert literal control codes (except @code{^J}) or escape sequences.
|
||||
|
||||
@node Commands
|
||||
@section Commands
|
||||
|
||||
@ -1201,6 +1205,14 @@ It also means that lookahead and lookbehind are not possible.
|
||||
A complete explanation can be found in the manual of GNU grep:
|
||||
@code{info grep regular}.
|
||||
|
||||
Each regular expression in a @file{nanorc} file should be wrapped in
|
||||
double quotes (@code{""}). Multiple regular expressions can follow
|
||||
each other on a line by separating them with blanks. This means that
|
||||
a regular expression cannot contain a double quote followed by a blank.
|
||||
When you need this combination inside a regular expression,
|
||||
then either the double quote or the blank should be put
|
||||
between square brackets (@code{[]}).
|
||||
|
||||
A separate syntax can be defined for each kind of file
|
||||
via the following commands in a nanorc file:
|
||||
|
||||
@ -1336,9 +1348,9 @@ Rebinds @code{key} to @code{function} in the context of @code{menu}
|
||||
@item bind key "string" menu
|
||||
Makes @code{key} produce @code{string} in the context of @code{menu}
|
||||
(or in all menus where the key exists when @code{all} is used).
|
||||
Besides literal text, the @code{string} may contain function names
|
||||
between braces. These functions will be invoked when the key is typed.
|
||||
To include a literal opening brace, use @code{@{@{@}}.
|
||||
Besides literal text and/or control codes, the @code{string} may contain
|
||||
function names between braces. These functions will be invoked when the
|
||||
key is typed. To include a literal opening brace, use @code{@{@{@}}.
|
||||
|
||||
@item unbind key menu
|
||||
Unbinds @code{key} from @code{menu}
|
||||
@ -1346,6 +1358,16 @@ Unbinds @code{key} from @code{menu}
|
||||
|
||||
@end table
|
||||
|
||||
Note that @code{bind key "@{function@}" menu} is equivalent to
|
||||
@code{bind key function menu}, except that for the latter form
|
||||
@command{nano} will check the availabilty of the @code{function}
|
||||
in the given @code{menu} at startup time (and report an error if
|
||||
it does not exist there), whereas for the first form @command{nano}
|
||||
will check at execution time that the @code{function} exists but not
|
||||
whether it makes any sense in the current menu. The user has to take
|
||||
care that a function name between braces (or any sequence of them)
|
||||
is appropriate. Strange behavior can result when it is not.
|
||||
|
||||
@sp 1
|
||||
The format of @code{key} should be one of:
|
||||
|
||||
@ -1601,7 +1623,8 @@ Switches to editing/viewing the previous buffer when multiple buffers are open.
|
||||
Switches to editing/viewing the next buffer when multiple buffers are open.
|
||||
|
||||
@item verbatim
|
||||
Inserts the next keystroke verbatim into the file.
|
||||
Inserts the next keystroke verbatim into the file, or begins Unicode input
|
||||
when a hexadecimal digit is typed (@pxref{Entering Text} for details).
|
||||
|
||||
@item tab
|
||||
Inserts a tab at the current cursor location.
|
||||
@ -1941,6 +1964,9 @@ Exclude the single-keystroke comment/uncomment function (@w{@kbd{M-3}}).
|
||||
@item --disable-extra
|
||||
Exclude the Easter egg: a crawl of major contributors.
|
||||
|
||||
@item --disable-formatter
|
||||
Exclude the code for calling a formatting tool.
|
||||
|
||||
@item --disable-help
|
||||
Exclude the help texts (@kbd{^G}). This makes the binary much smaller,
|
||||
but also makes it difficult for new users to learn more than very basic
|
||||
@ -1966,6 +1992,9 @@ in most cases the regexes for filename and header line will be enough).
|
||||
Exclude the ability to show line numbers. This also eliminates
|
||||
the @option{-l} command-line option, which turns line numbering on.
|
||||
|
||||
@item --disable-linter
|
||||
Exclude the code for calling a linting tool.
|
||||
|
||||
@item --disable-mouse
|
||||
Exclude all mouse functionality. This also eliminates the @option{-m}
|
||||
command-line option, which enables the mouse functionality.
|
||||
|
||||
26
doc/nanorc.5
26
doc/nanorc.5
@ -426,6 +426,14 @@ It also means that lookahead and lookbehind are not possible.
|
||||
A complete explanation can be found in the manual page of GNU grep:
|
||||
\fBman grep\fR.
|
||||
.sp
|
||||
Each regular expression in a \fBnanorc\fR file should be wrapped in
|
||||
double quotes (\fB""\fR). Multiple regular expressions can follow
|
||||
each other on a line by separating them with blanks. This means that
|
||||
a regular expression cannot contain a double quote followed by a blank.
|
||||
When you need this combination inside a regular expression,
|
||||
then either the double quote or the blank should be put
|
||||
between square brackets (\fB[]\fR).
|
||||
.sp
|
||||
For each kind of file a separate syntax can be defined
|
||||
via the following commands:
|
||||
.TP
|
||||
@ -551,14 +559,23 @@ Rebinds the given \fIkey\fP to the given \fIfunction\fP in the given \fImenu\fP
|
||||
.BI bind " key " """" string """" " menu"
|
||||
Makes the given \fIkey\fR produce the given \fIstring\fR in the given
|
||||
\fImenu\fR (or in all menus where the key exists when \fBall\fR is used).
|
||||
Besides literal text, the \fIstring\fR may contain function names
|
||||
between braces. These functions will be invoked when the key is typed.
|
||||
To include a literal opening brace, use \fB{{}\fR.
|
||||
Besides literal text and/or control codes, the \fIstring\fR may contain
|
||||
function names between braces. These functions will be invoked when
|
||||
the key is typed. To include a literal opening brace, use \fB{{}\fR.
|
||||
.TP
|
||||
.BI unbind " key menu"
|
||||
Unbinds the given \fIkey\fP from the given \fImenu\fP (or from all
|
||||
menus where the key exists when \fBall\fP is used).
|
||||
.RE
|
||||
.sp
|
||||
Note that \fBbind \fIkey\fR \fB"{\fIfunction\fB}"\fR \fImenu\fR is equivalent
|
||||
to \fBbind \fIkey\fR \fIfunction\fR \fImenu\fR, except that for the latter form
|
||||
\fBnano\fR will check the availabilty of the \fIfunction\fR in the given \fImenu\fR
|
||||
at startup time (and report an error if it does not exist there), whereas for the
|
||||
first form \fBnano\fR will check at execution time that the \fIfunction\fR exists
|
||||
but not whether it makes any sense in the current menu. The user has to take care
|
||||
that a function name between braces (or any sequence of them) is appropriate.
|
||||
Strange behavior can result when it is not.
|
||||
|
||||
.TP
|
||||
The format of \fIkey\fP should be one of:
|
||||
@ -811,7 +828,8 @@ Switches to editing/viewing the previous buffer when multiple buffers are open.
|
||||
Switches to editing/viewing the next buffer when multiple buffers are open.
|
||||
.TP
|
||||
.B verbatim
|
||||
Inserts the next keystroke verbatim into the file.
|
||||
Inserts the next keystroke verbatim into the file, or begins Unicode input
|
||||
when a hexadecimal digit is typed.
|
||||
.TP
|
||||
.B tab
|
||||
Inserts a tab at the current cursor location.
|
||||
|
||||
@ -292,6 +292,9 @@
|
||||
## For copying a marked region to the system clipboard:
|
||||
# bind Sh-M-T "{execute}|xsel -ib{enter}{undo}" main
|
||||
|
||||
## For snipping trailing blanks when you save a file:
|
||||
# bind ^S "{execute}| sed 's/\s\+$//' {enter}{savefile}" main
|
||||
|
||||
## If you would like nano to have keybindings that are more "usual",
|
||||
## such as ^O for Open, ^F for Find, ^H for Help, and ^Q for Quit,
|
||||
## then uncomment these:
|
||||
|
||||
@ -255,63 +255,39 @@ void browser_refresh(void)
|
||||
wnoutrefresh(midwin);
|
||||
}
|
||||
|
||||
/* Look for the given needle in the list of files. If forwards is TRUE,
|
||||
* search forward in the list; otherwise, search backward. */
|
||||
/* Look for the given needle in the list of files, forwards or backwards. */
|
||||
void findfile(const char *needle, bool forwards)
|
||||
{
|
||||
size_t looking_at = selected;
|
||||
/* The location in the file list of the filename we're looking at. */
|
||||
const char *thename;
|
||||
/* The plain filename, without the path. */
|
||||
unsigned stash[sizeof(flags) / sizeof(flags[0])];
|
||||
/* A storage place for the current flag settings. */
|
||||
size_t began_at = selected;
|
||||
|
||||
/* Save the settings of all flags. */
|
||||
memcpy(stash, flags, sizeof(flags));
|
||||
|
||||
/* Search forward, case insensitive, and without regexes. */
|
||||
UNSET(BACKWARDS_SEARCH);
|
||||
UNSET(CASE_SENSITIVE);
|
||||
UNSET(USE_REGEXP);
|
||||
|
||||
/* Step through each filename in the list until a match is found or
|
||||
/* Iterate through the list of filenames, until a match is found or
|
||||
* we've come back to the point where we started. */
|
||||
while (TRUE) {
|
||||
if (forwards) {
|
||||
if (looking_at++ == list_length - 1) {
|
||||
looking_at = 0;
|
||||
if (selected++ == list_length - 1) {
|
||||
selected = 0;
|
||||
statusbar(_("Search Wrapped"));
|
||||
}
|
||||
} else {
|
||||
if (looking_at-- == 0) {
|
||||
looking_at = list_length - 1;
|
||||
if (selected-- == 0) {
|
||||
selected = list_length - 1;
|
||||
statusbar(_("Search Wrapped"));
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the bare filename, without the path. */
|
||||
thename = tail(filelist[looking_at]);
|
||||
|
||||
/* If the needle matches, we're done. And if we're back at the file
|
||||
* where we started, it is the only occurrence. */
|
||||
if (strstrwrapper(thename, needle, thename)) {
|
||||
if (looking_at == selected)
|
||||
/* When the needle occurs in the basename of the file, we have a match. */
|
||||
if (mbstrcasestr(tail(filelist[selected]), needle)) {
|
||||
if (selected == began_at)
|
||||
statusbar(_("This is the only occurrence"));
|
||||
break;
|
||||
return;
|
||||
}
|
||||
|
||||
/* If we're back at the beginning and didn't find any match... */
|
||||
if (looking_at == selected) {
|
||||
/* When we're back at the starting point without any match... */
|
||||
if (selected == began_at) {
|
||||
not_found_msg(needle);
|
||||
break;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Restore the settings of all flags. */
|
||||
memcpy(flags, stash, sizeof(flags));
|
||||
|
||||
/* Select the one we've found. */
|
||||
selected = looking_at;
|
||||
}
|
||||
|
||||
/* Prepare the prompt and ask the user what to search for; then search for it.
|
||||
|
||||
@ -214,16 +214,12 @@
|
||||
#define SHIFT_DELETE 0x45D
|
||||
#define SHIFT_TAB 0x45F
|
||||
|
||||
/* A special keycode for when a string bind has been partially implanted. */
|
||||
/* Special keycodes for when a string bind has been partially implanted
|
||||
* or has an unpaired opening brace, or when a function in a string bind
|
||||
* needs execution or a specified function name is invalid. */
|
||||
#define MORE_PLANTS 0x4EA
|
||||
|
||||
/* A special keycode for when a string bind has an unpaired opening brace. */
|
||||
#define MISSING_BRACE 0x4EB
|
||||
|
||||
/* A special keycode for when a function in a string bind needs execution. */
|
||||
#define PLANTED_COMMAND 0x4EC
|
||||
|
||||
/* A special keycode for when a function name in a string bind is invalid. */
|
||||
#define NO_SUCH_FUNCTION 0x4EF
|
||||
|
||||
/* A special keycode for when <Tab> is pressed while the mark is on. */
|
||||
@ -658,14 +654,13 @@ typedef struct keystruct {
|
||||
typedef struct funcstruct {
|
||||
void (*func)(void);
|
||||
/* The actual function to call. */
|
||||
const char *desc;
|
||||
/* The function's short description, for example "Where Is". */
|
||||
const char *tag;
|
||||
/* The function's help-line label, for example "Where Is". */
|
||||
#ifdef ENABLE_HELP
|
||||
const char *help;
|
||||
/* The help-screen text for this function. */
|
||||
const char *phrase;
|
||||
/* The function's description for in the help viewer. */
|
||||
bool blank_after;
|
||||
/* Whether there should be a blank line after the help text
|
||||
* for this function. */
|
||||
/* Whether to distance this function from the next in the help viewer. */
|
||||
#endif
|
||||
int menus;
|
||||
/* In what menus this function applies. */
|
||||
|
||||
26
src/files.c
26
src/files.c
@ -57,7 +57,7 @@ void make_new_buffer(void)
|
||||
openfile->next = newnode;
|
||||
|
||||
/* There is more than one buffer: show "Close" in help lines. */
|
||||
exitfunc->desc = close_tag;
|
||||
exitfunc->tag = close_tag;
|
||||
more_than_one = !inhelp || more_than_one;
|
||||
}
|
||||
#endif
|
||||
@ -218,7 +218,7 @@ bool write_lockfile(const char *lockfilename, const char *filename, bool modifie
|
||||
strncpy(&lockdata[108], filename, 768);
|
||||
lockdata[1007] = (modified) ? 0x55 : 0x00;
|
||||
|
||||
wroteamt = fwrite(lockdata, sizeof(char), LOCKSIZE, filestream);
|
||||
wroteamt = fwrite(lockdata, 1, LOCKSIZE, filestream);
|
||||
|
||||
free(lockdata);
|
||||
|
||||
@ -627,7 +627,7 @@ void close_buffer(void)
|
||||
|
||||
/* When just one buffer remains open, show "Exit" in the help lines. */
|
||||
if (openfile && openfile == openfile->next)
|
||||
exitfunc->desc = exit_tag;
|
||||
exitfunc->tag = exit_tag;
|
||||
}
|
||||
#endif /* ENABLE_MULTIBUFFER */
|
||||
|
||||
@ -989,7 +989,14 @@ void send_data(const linestruct *line, int fd)
|
||||
|
||||
/* Send each line, except a final empty line. */
|
||||
while (line != NULL && (line->next != NULL || line->data[0] != '\0')) {
|
||||
fprintf(tube, "%s%s", line->data, line->next == NULL ? "" : "\n");
|
||||
size_t length = recode_LF_to_NUL(line->data);
|
||||
|
||||
if (fwrite(line->data, 1, length, tube) < length)
|
||||
exit(5);
|
||||
|
||||
if (line->next && putc('\n', tube) == EOF)
|
||||
exit(6);
|
||||
|
||||
line = line->next;
|
||||
}
|
||||
|
||||
@ -1530,12 +1537,12 @@ int copy_file(FILE *inn, FILE *out, bool close_out)
|
||||
int (*flush_out_fnc)(FILE *) = (close_out) ? fclose : fflush;
|
||||
|
||||
do {
|
||||
charsread = fread(buf, sizeof(char), BUFSIZ, inn);
|
||||
charsread = fread(buf, 1, BUFSIZ, inn);
|
||||
if (charsread == 0 && ferror(inn)) {
|
||||
retval = -1;
|
||||
break;
|
||||
}
|
||||
if (fwrite(buf, sizeof(char), charsread, out) < charsread) {
|
||||
if (fwrite(buf, 1, charsread, out) < charsread) {
|
||||
retval = 2;
|
||||
break;
|
||||
}
|
||||
@ -1857,13 +1864,12 @@ bool write_file(const char *name, FILE *thefile, bool normal,
|
||||
statusbar(_("Writing..."));
|
||||
|
||||
while (TRUE) {
|
||||
size_t data_len = strlen(line->data);
|
||||
size_t wrote;
|
||||
size_t data_len, wrote;
|
||||
|
||||
/* Decode LFs as the NULs that they are, before writing to disk. */
|
||||
recode_LF_to_NUL(line->data);
|
||||
data_len = recode_LF_to_NUL(line->data);
|
||||
|
||||
wrote = fwrite(line->data, sizeof(char), data_len, thefile);
|
||||
wrote = fwrite(line->data, 1, data_len, thefile);
|
||||
|
||||
/* Re-encode any embedded NULs as LFs. */
|
||||
recode_NUL_to_LF(line->data, data_len);
|
||||
|
||||
26
src/global.c
26
src/global.c
@ -317,8 +317,8 @@ void discard_buffer(void) {;}
|
||||
void do_cancel(void) {;}
|
||||
|
||||
/* Add a function to the linked list of functions. */
|
||||
void add_to_funcs(void (*function)(void), int menus, const char *desc,
|
||||
const char *help, bool blank_after)
|
||||
void add_to_funcs(void (*function)(void), int menus, const char *tag,
|
||||
const char *phrase, bool blank_after)
|
||||
{
|
||||
funcstruct *f = nmalloc(sizeof(funcstruct));
|
||||
|
||||
@ -331,9 +331,9 @@ void add_to_funcs(void (*function)(void), int menus, const char *desc,
|
||||
f->next = NULL;
|
||||
f->func = function;
|
||||
f->menus = menus;
|
||||
f->desc = desc;
|
||||
f->tag = tag;
|
||||
#ifdef ENABLE_HELP
|
||||
f->help = help;
|
||||
f->phrase = phrase;
|
||||
f->blank_after = blank_after;
|
||||
#endif
|
||||
}
|
||||
@ -692,10 +692,12 @@ void shortcut_init(void)
|
||||
const char *browserrefresh_gist = N_("Refresh the file list");
|
||||
const char *gotodir_gist = N_("Go to directory");
|
||||
#endif
|
||||
#ifdef ENABLE_COLOR
|
||||
#ifdef ENABLE_LINTER
|
||||
const char *lint_gist = N_("Invoke the linter, if available");
|
||||
const char *prevlint_gist = N_("Go to previous linter msg");
|
||||
const char *nextlint_gist = N_("Go to next linter msg");
|
||||
#endif
|
||||
#ifdef ENABLE_FORMATTER
|
||||
const char *formatter_gist =
|
||||
N_("Invoke a program to format/arrange/manipulate the buffer");
|
||||
#endif
|
||||
@ -1023,9 +1025,11 @@ void shortcut_init(void)
|
||||
add_to_funcs(do_spell, MMAIN,
|
||||
N_("Spell Check"), WHENHELP(spell_gist), TOGETHER);
|
||||
#endif
|
||||
#ifdef ENABLE_COLOR
|
||||
#ifdef ENABLE_LINTER
|
||||
add_to_funcs(do_linter, MMAIN,
|
||||
N_("Linter"), WHENHELP(lint_gist), TOGETHER);
|
||||
#endif
|
||||
#ifdef ENABLE_FORMATTER
|
||||
add_to_funcs(do_formatter, MMAIN,
|
||||
N_("Formatter"), WHENHELP(formatter_gist), BLANKAFTER);
|
||||
#endif
|
||||
@ -1065,7 +1069,7 @@ void shortcut_init(void)
|
||||
add_to_funcs(do_spell, MEXECUTE,
|
||||
N_("Spell Check"), WHENHELP(spell_gist), TOGETHER);
|
||||
#endif
|
||||
#ifdef ENABLE_COLOR
|
||||
#ifdef ENABLE_LINTER
|
||||
add_to_funcs(do_linter, MEXECUTE,
|
||||
N_("Linter"), WHENHELP(lint_gist), BLANKAFTER);
|
||||
#endif
|
||||
@ -1073,7 +1077,7 @@ void shortcut_init(void)
|
||||
add_to_funcs(do_full_justify, MEXECUTE,
|
||||
N_("Full Justify"), WHENHELP(fulljustify_gist), TOGETHER);
|
||||
#endif
|
||||
#ifdef ENABLE_COLOR
|
||||
#ifdef ENABLE_FORMATTER
|
||||
add_to_funcs(do_formatter, MEXECUTE,
|
||||
N_("Formatter"), WHENHELP(formatter_gist), BLANKAFTER);
|
||||
#endif
|
||||
@ -1153,7 +1157,7 @@ void shortcut_init(void)
|
||||
add_to_funcs(discard_buffer, MWRITEFILE,
|
||||
N_("Discard buffer"), WHENHELP(discardbuffer_gist), BLANKAFTER);
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
#ifdef ENABLE_LINTER
|
||||
add_to_funcs(do_page_up, MLINTER,
|
||||
/* TRANSLATORS: The next two strings may be up to 37 characters each. */
|
||||
N_("Previous Linter message"), WHENHELP(prevlint_gist), TOGETHER);
|
||||
@ -1207,9 +1211,11 @@ void shortcut_init(void)
|
||||
#ifdef ENABLE_JUSTIFY
|
||||
add_to_sclist(MMAIN, "^J", '\n', do_justify, 0);
|
||||
#endif
|
||||
#ifdef ENABLE_COLOR
|
||||
#ifdef ENABLE_LINTER
|
||||
add_to_sclist(MMAIN, "M-B", 0, do_linter, 0);
|
||||
add_to_sclist(MEXECUTE, "^Y", 0, do_linter, 0);
|
||||
#endif
|
||||
#ifdef ENABLE_FORMATTER
|
||||
add_to_sclist(MMAIN, "M-F", 0, do_formatter, 0);
|
||||
add_to_sclist(MEXECUTE, "^O", 0, do_formatter, 0);
|
||||
#endif
|
||||
|
||||
@ -224,7 +224,7 @@ void help_init(void)
|
||||
* plus translated text, plus one or two \n's. */
|
||||
for (f = allfuncs; f != NULL; f = f->next)
|
||||
if (f->menus & currmenu)
|
||||
allocsize += strlen(_(f->help)) + 21;
|
||||
allocsize += strlen(_(f->phrase)) + 21;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* If we're on the main list, we also count the toggle help text.
|
||||
@ -282,7 +282,7 @@ void help_init(void)
|
||||
ptr += 10;
|
||||
|
||||
/* The shortcut's description. */
|
||||
ptr += sprintf(ptr, "%s\n", _(f->help));
|
||||
ptr += sprintf(ptr, "%s\n", _(f->phrase));
|
||||
|
||||
if (f->blank_after)
|
||||
ptr += sprintf(ptr, "\n");
|
||||
|
||||
@ -304,12 +304,10 @@ bool write_list(const linestruct *head, FILE *histfile)
|
||||
const linestruct *item;
|
||||
|
||||
for (item = head; item != NULL; item = item->next) {
|
||||
size_t length = strlen(item->data);
|
||||
|
||||
/* Decode 0x0A bytes as embedded NULs. */
|
||||
recode_LF_to_NUL(item->data);
|
||||
size_t length = recode_LF_to_NUL(item->data);
|
||||
|
||||
if (fwrite(item->data, sizeof(char), length, histfile) < length)
|
||||
if (fwrite(item->data, 1, length, histfile) < length)
|
||||
return FALSE;
|
||||
if (putc('\n', histfile) == EOF)
|
||||
return FALSE;
|
||||
@ -451,14 +449,13 @@ void save_poshistory(void)
|
||||
path_and_place = nmalloc(strlen(item->filename) + 44);
|
||||
sprintf(path_and_place, "%s %zd %zd\n",
|
||||
item->filename, item->linenumber, item->columnnumber);
|
||||
length = strlen(path_and_place);
|
||||
|
||||
/* Encode newlines in filenames as NULs. */
|
||||
recode_LF_to_NUL(path_and_place);
|
||||
length = recode_LF_to_NUL(path_and_place);
|
||||
/* Restore the terminating newline. */
|
||||
path_and_place[length - 1] = '\n';
|
||||
|
||||
if (fwrite(path_and_place, sizeof(char), length, histfile) < length)
|
||||
if (fwrite(path_and_place, 1, length, histfile) < length)
|
||||
jot_error(N_("Error writing %s: %s"), poshistname, strerror(errno));
|
||||
|
||||
free(path_and_place);
|
||||
|
||||
66
src/nano.c
66
src/nano.c
@ -430,10 +430,9 @@ void window_init(void)
|
||||
int toprows = ((ISSET(EMPTY_LINE) && LINES > 6) ? 2 : 1);
|
||||
int bottomrows = ((ISSET(NO_HELP) || LINES < 6) ? 1 : 3);
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (ISSET(MINIBAR) || ISSET(ZERO))
|
||||
toprows = 0;
|
||||
#endif
|
||||
|
||||
editwinrows = LINES - toprows - bottomrows + (ISSET(ZERO) ? 1 : 0);
|
||||
|
||||
/* Set up the normal three subwindows. */
|
||||
@ -487,7 +486,7 @@ void mouse_init(void)
|
||||
#endif /* ENABLE_MOUSE */
|
||||
|
||||
/* Print the usage line for the given option to the screen. */
|
||||
void print_opt(const char *shortflag, const char *longflag, const char *desc)
|
||||
void print_opt(const char *shortflag, const char *longflag, const char *description)
|
||||
{
|
||||
int firstwidth = breadth(shortflag);
|
||||
int secondwidth = breadth(longflag);
|
||||
@ -500,7 +499,7 @@ void print_opt(const char *shortflag, const char *longflag, const char *desc)
|
||||
if (secondwidth < 24)
|
||||
printf("%*s", 24 - secondwidth, " ");
|
||||
|
||||
printf("%s\n", _(desc));
|
||||
printf("%s\n", _(description));
|
||||
}
|
||||
|
||||
/* Explain how to properly use nano and its command-line options. */
|
||||
@ -695,6 +694,9 @@ void version(void)
|
||||
#ifdef ENABLE_EXTRA
|
||||
printf(" --enable-extra");
|
||||
#endif
|
||||
#ifdef ENABLE_FORMATTER
|
||||
printf(" --enable-formatter");
|
||||
#endif
|
||||
#ifdef ENABLE_HELP
|
||||
printf(" --enable-help");
|
||||
#endif
|
||||
@ -710,6 +712,9 @@ void version(void)
|
||||
#ifdef ENABLE_LINENUMBERS
|
||||
printf(" --enable-linenumbers");
|
||||
#endif
|
||||
#ifdef ENABLE_LINTER
|
||||
printf(" --enable-linter");
|
||||
#endif
|
||||
#ifdef ENABLE_MOUSE
|
||||
printf(" --enable-mouse");
|
||||
#endif
|
||||
@ -744,6 +749,9 @@ void version(void)
|
||||
#ifndef ENABLE_EXTRA
|
||||
printf(" --disable-extra");
|
||||
#endif
|
||||
#ifndef ENABLE_FORMATTER
|
||||
printf(" --disable-formatter");
|
||||
#endif
|
||||
#ifndef ENABLE_HELP
|
||||
printf(" --disable-help");
|
||||
#endif
|
||||
@ -759,6 +767,9 @@ void version(void)
|
||||
#ifndef ENABLE_LINENUMBERS
|
||||
printf(" --disable-linenumbers");
|
||||
#endif
|
||||
#ifndef ENABLE_LINTER
|
||||
printf(" --disable-linter");
|
||||
#endif
|
||||
#ifndef ENABLE_MOUSE
|
||||
printf(" --disable-mouse");
|
||||
#endif
|
||||
@ -1277,10 +1288,10 @@ void unbound_key(int code)
|
||||
* (from the keyboard) that nano does not recognize. */
|
||||
statusline(AHEM, _("Unknown sequence"));
|
||||
#ifdef ENABLE_NANORC
|
||||
else if (code == NO_SUCH_FUNCTION)
|
||||
statusline(AHEM, _("Unknown function: %s"), commandname);
|
||||
else if (code == MISSING_BRACE)
|
||||
statusline(AHEM, _("Missing }"));
|
||||
else if (code == NO_SUCH_FUNCTION)
|
||||
statusline(AHEM, _("No such function: %s"), commandname);
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
else if (code > KEY_F0 && code < KEY_F0 + 25)
|
||||
@ -1297,17 +1308,17 @@ void unbound_key(int code)
|
||||
#endif
|
||||
#ifdef ENABLE_NANORC
|
||||
if (shifted_metas && 'A' <= code && code <= 'Z')
|
||||
statusline(AHEM, _("Unbound key: Sh-M-%c"), code);
|
||||
statusline(AHEM, _("Unbound key: %s%c"), "Sh-M-", code);
|
||||
else
|
||||
#endif
|
||||
statusline(AHEM, _("Unbound key: M-%c"), toupper(code));
|
||||
statusline(AHEM, _("Unbound key: %s%c"), "M-", toupper(code));
|
||||
} else if (code == ESC_CODE)
|
||||
statusline(AHEM, _("Unbindable key: ^["));
|
||||
else if (code < 0x20)
|
||||
statusline(AHEM, _("Unbound key: ^%c"), code + 0x40);
|
||||
statusline(AHEM, _("Unbound key: %s%c"), "^", code + 0x40);
|
||||
#if defined(ENABLE_BROWSER) || defined (ENABLE_HELP)
|
||||
else
|
||||
statusline(AHEM, _("Unbound key: %c"), code);
|
||||
statusline(AHEM, _("Unbound key: %s%c"), "", code);
|
||||
#endif
|
||||
set_blankdelay_to_one();
|
||||
}
|
||||
@ -1386,9 +1397,8 @@ bool wanted_to_move(void (*func)(void))
|
||||
/* Return TRUE when the given function makes a change -- no good for view mode. */
|
||||
bool changes_something(const void *f)
|
||||
{
|
||||
return (f == do_savefile || f == do_writeout || f == do_enter ||
|
||||
f == do_tab || f == do_delete || f == do_backspace ||
|
||||
f == cut_text || f == paste_text || f == do_replace ||
|
||||
return (f == do_savefile || f == do_writeout || f == do_enter || f == do_tab ||
|
||||
f == do_delete || f == do_backspace || f == cut_text || f == paste_text ||
|
||||
#ifndef NANO_TINY
|
||||
f == chop_previous_word || f == chop_next_word ||
|
||||
f == zap_text || f == cut_till_eof || f == do_execute ||
|
||||
@ -1400,13 +1410,13 @@ bool changes_something(const void *f)
|
||||
#ifdef ENABLE_SPELLER
|
||||
f == do_spell ||
|
||||
#endif
|
||||
#ifdef ENABLE_COLOR
|
||||
#ifdef ENABLE_FORMATTER
|
||||
f == do_formatter ||
|
||||
#endif
|
||||
#ifdef ENABLE_WORDCOMPLETION
|
||||
f == complete_a_word ||
|
||||
#endif
|
||||
f == do_verbatim_input);
|
||||
f == do_replace || f == do_verbatim_input);
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
@ -1545,6 +1555,8 @@ void process_a_keystroke(void)
|
||||
/* The keystroke we read in: a character or a shortcut. */
|
||||
static char *puddle = NULL;
|
||||
/* The input buffer for actual characters. */
|
||||
static size_t capacity = 12;
|
||||
/* The size of the input buffer; gets doubled whenever needed. */
|
||||
static size_t depth = 0;
|
||||
/* The length of the input buffer. */
|
||||
#ifndef NANO_TINY
|
||||
@ -1591,21 +1603,23 @@ void process_a_keystroke(void)
|
||||
refresh_needed = TRUE;
|
||||
}
|
||||
#endif
|
||||
/* Store the byte, and leave room for a terminating zero. */
|
||||
puddle = nrealloc(puddle, depth + 2);
|
||||
/* When the input buffer (plus room for terminating NUL) is full,
|
||||
* extend it; otherwise, if it does not exist yet, create it. */
|
||||
if (depth + 1 == capacity) {
|
||||
capacity = 2 * capacity;
|
||||
puddle = nrealloc(puddle, capacity);
|
||||
} else if (!puddle)
|
||||
puddle = nmalloc(capacity);
|
||||
|
||||
puddle[depth++] = (char)input;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we have a command, or if there aren't any other key codes waiting,
|
||||
* it's time to insert the gathered bytes into the edit buffer. */
|
||||
if ((function || waiting_keycodes() == 0) && puddle != NULL) {
|
||||
/* If there are gathered bytes and we have a command or no other key codes
|
||||
* are waiting, it's time to insert these bytes into the edit buffer. */
|
||||
if (depth > 0 && (function || waiting_keycodes() == 0)) {
|
||||
puddle[depth] = '\0';
|
||||
|
||||
inject(puddle, depth);
|
||||
|
||||
free(puddle);
|
||||
puddle = NULL;
|
||||
depth = 0;
|
||||
}
|
||||
|
||||
@ -2506,6 +2520,10 @@ int main(int argc, char **argv)
|
||||
/* After handling the files on the command line, allow inserting files. */
|
||||
UNSET(NOREAD_MODE);
|
||||
|
||||
/* Nano is a hands-on editor -- it needs a keyboard. */
|
||||
if (!isatty(STDIN_FILENO))
|
||||
die(_("Standard input is not a terminal\n"));
|
||||
|
||||
/* If no filenames were given, or all of them were invalid things like
|
||||
* directories, then open a blank buffer and allow editing. Otherwise,
|
||||
* switch from the last opened file to the next, that is: the first. */
|
||||
|
||||
44
src/prompt.c
44
src/prompt.c
@ -182,16 +182,12 @@ void copy_the_answer(void)
|
||||
void paste_into_answer(void)
|
||||
{
|
||||
size_t pastelen = strlen(cutbuffer->data);
|
||||
char *fusion = nmalloc(strlen(answer) + pastelen + 1);
|
||||
|
||||
/* Concatenate: the current answer before the cursor, the first line
|
||||
* of the cutbuffer, plus the rest of the current answer. */
|
||||
strncpy(fusion, answer, typing_x);
|
||||
strncpy(fusion + typing_x, cutbuffer->data, pastelen);
|
||||
strcpy(fusion + typing_x + pastelen, answer + typing_x);
|
||||
answer = nrealloc(answer, strlen(answer) + pastelen + 1);
|
||||
memmove(answer + typing_x + pastelen, answer + typing_x,
|
||||
strlen(answer) - typing_x + 1);
|
||||
strncpy(answer + typing_x, cutbuffer->data, pastelen);
|
||||
|
||||
free(answer);
|
||||
answer = fusion;
|
||||
typing_x += pastelen;
|
||||
}
|
||||
#endif
|
||||
@ -256,6 +252,8 @@ void absorb_character(int input, functionptrtype function)
|
||||
{
|
||||
static char *puddle = NULL;
|
||||
/* The input buffer. */
|
||||
static size_t capacity = 8;
|
||||
/* The size of the input buffer; gets doubled whenever needed. */
|
||||
static size_t depth = 0;
|
||||
/* The length of the input buffer. */
|
||||
|
||||
@ -267,21 +265,23 @@ void absorb_character(int input, functionptrtype function)
|
||||
beep();
|
||||
else if (!ISSET(RESTRICTED) || currmenu != MWRITEFILE ||
|
||||
openfile->filename[0] == '\0') {
|
||||
puddle = nrealloc(puddle, depth + 2);
|
||||
/* When the input buffer (plus room for terminating NUL) is full,
|
||||
* extend it; otherwise, if it does not exist yet, create it. */
|
||||
if (depth + 1 == capacity) {
|
||||
capacity = 2 * capacity;
|
||||
puddle = nrealloc(puddle, capacity);
|
||||
} else if (!puddle)
|
||||
puddle = nmalloc(capacity);
|
||||
|
||||
puddle[depth++] = (char)input;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we got a shortcut, or if there aren't any other keystrokes waiting,
|
||||
* it's time to insert all characters in the input buffer (if not empty)
|
||||
* into the answer, and then clear the input buffer. */
|
||||
if ((function || waiting_keycodes() == 0) && puddle != NULL) {
|
||||
/* If there are gathered bytes and we have a command or no other key codes
|
||||
* are waiting, it's time to insert these bytes into the answer. */
|
||||
if (depth > 0 && (function || waiting_keycodes() == 0)) {
|
||||
puddle[depth] = '\0';
|
||||
|
||||
inject_into_answer(puddle, depth);
|
||||
|
||||
free(puddle);
|
||||
puddle = NULL;
|
||||
depth = 0;
|
||||
}
|
||||
}
|
||||
@ -442,7 +442,7 @@ functionptrtype acquire_an_answer(int *actual, bool *listed,
|
||||
#ifndef NANO_TINY
|
||||
/* If the window size changed, go reformat the prompt string. */
|
||||
if (input == KEY_WINCH) {
|
||||
refresh_func();
|
||||
refresh_func(); /* Only needed when in file browser. */
|
||||
*actual = KEY_WINCH;
|
||||
#ifdef ENABLE_HISTORIES
|
||||
free(stored_string);
|
||||
@ -595,20 +595,18 @@ int do_prompt(int menu, const char *provided, linestruct **history_list,
|
||||
|
||||
function = acquire_an_answer(&retval, &listed, history_list, refresh_func);
|
||||
free(prompt);
|
||||
prompt = saved_prompt;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (retval == KEY_WINCH)
|
||||
goto redo_theprompt;
|
||||
#endif
|
||||
|
||||
/* If we're done with this prompt, restore the x position to what
|
||||
* it was at a possible previous prompt. */
|
||||
/* Restore a possible previous prompt and maybe the typing position. */
|
||||
prompt = saved_prompt;
|
||||
if (function == do_cancel || function == do_enter)
|
||||
typing_x = was_typing_x;
|
||||
|
||||
/* If we left the prompt via Cancel or Enter, set the return value
|
||||
* properly. */
|
||||
/* Set the proper return value for Cancel and Enter. */
|
||||
if (function == do_cancel)
|
||||
retval = -1;
|
||||
else if (function == do_enter)
|
||||
|
||||
@ -470,7 +470,9 @@ ssize_t do_replace_loop(const char *needle, bool whole_word_only,
|
||||
const linestruct *real_current, size_t *real_current_x);
|
||||
void do_replace(void);
|
||||
void ask_for_and_do_replacements(void);
|
||||
#if !defined(NANO_TINY) || defined(ENABLE_SPELLER) || defined (ENABLE_LINTER) || defined (ENABLE_FORMATTER)
|
||||
void goto_line_posx(ssize_t line, size_t pos_x);
|
||||
#endif
|
||||
void goto_line_and_column(ssize_t line, ssize_t column, bool retain_answer,
|
||||
bool interactive);
|
||||
void do_gotolinecolumn(void);
|
||||
@ -524,8 +526,10 @@ void do_full_justify(void);
|
||||
#ifdef ENABLE_SPELLER
|
||||
void do_spell(void);
|
||||
#endif
|
||||
#ifdef ENABLE_COLOR
|
||||
#ifdef ENABLE_LINTER
|
||||
void do_linter(void);
|
||||
#endif
|
||||
#ifdef ENABLE_FORMATTER
|
||||
void do_formatter(void);
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
@ -544,7 +548,7 @@ int digits(ssize_t n);
|
||||
bool parse_num(const char *str, ssize_t *result);
|
||||
bool parse_line_column(const char *str, ssize_t *line, ssize_t *column);
|
||||
void recode_NUL_to_LF(char *string, size_t length);
|
||||
void recode_LF_to_NUL(char *string);
|
||||
size_t recode_LF_to_NUL(char *string);
|
||||
#if !defined(ENABLE_TINY) || defined(ENABLE_TABCOMP) || defined(ENABLE_BROWSER)
|
||||
void free_chararray(char **array, size_t len);
|
||||
#endif
|
||||
@ -574,15 +578,18 @@ void get_region(linestruct **top, size_t *top_x, linestruct **bot, size_t *bot_x
|
||||
void get_range(linestruct **top, linestruct **bot);
|
||||
#endif
|
||||
size_t number_of_characters_in(const linestruct *begin, const linestruct *end);
|
||||
#ifndef NANO_TINY
|
||||
#if !defined(NANO_TINY) || defined(ENABLE_SPELLER) || defined (ENABLE_LINTER) || defined (ENABLE_FORMATTER)
|
||||
linestruct *line_from_number(ssize_t number);
|
||||
#endif
|
||||
|
||||
/* Most functions in winio.c. */
|
||||
linestruct *get_next_visible_line(linestruct *line);
|
||||
linestruct *get_prev_visible_line(linestruct *line);
|
||||
#ifndef NANO_TINY
|
||||
void record_macro(void);
|
||||
void run_macro(void);
|
||||
#endif
|
||||
void reserve_space_for(size_t newsize);
|
||||
size_t waiting_keycodes(void);
|
||||
#ifdef ENABLE_NANORC
|
||||
void implant(const char *string);
|
||||
|
||||
48
src/rcfile.c
48
src/rcfile.c
@ -153,18 +153,6 @@ static bool seen_color_command = FALSE;
|
||||
static colortype *lastcolor = NULL;
|
||||
/* The end of the color list for the current syntax. */
|
||||
#endif
|
||||
|
||||
#define NUMBER_OF_MENUS 16
|
||||
char *menunames[NUMBER_OF_MENUS] = { "main", "search", "replace", "replacewith",
|
||||
"yesno", "gotoline", "writeout", "insert",
|
||||
"execute", "help", "spell", "linter",
|
||||
"browser", "whereisfile", "gotodir",
|
||||
"all" };
|
||||
int menusymbols[NUMBER_OF_MENUS] = { MMAIN, MWHEREIS, MREPLACE, MREPLACEWITH,
|
||||
MYESNO, MGOTOLINE, MWRITEFILE, MINSERTFILE,
|
||||
MEXECUTE, MHELP, MSPELL, MLINTER,
|
||||
MBROWSER, MWHEREISFILE, MGOTODIR,
|
||||
MMOST|MBROWSER|MHELP|MYESNO };
|
||||
#endif /* ENABLE_NANORC */
|
||||
|
||||
#if defined(ENABLE_NANORC) || defined(ENABLE_HISTORIES)
|
||||
@ -276,9 +264,11 @@ keystruct *strtosc(const char *input)
|
||||
!strcmp(input, "speller"))
|
||||
s->func = do_spell;
|
||||
#endif
|
||||
#ifdef ENABLE_COLOR
|
||||
#ifdef ENABLE_LINTER
|
||||
else if (!strcmp(input, "linter"))
|
||||
s->func = do_linter;
|
||||
#endif
|
||||
#ifdef ENABLE_FORMATTER
|
||||
else if (!strcmp(input, "formatter"))
|
||||
s->func = do_formatter;
|
||||
#endif
|
||||
@ -493,6 +483,18 @@ keystruct *strtosc(const char *input)
|
||||
return s;
|
||||
}
|
||||
|
||||
#define NUMBER_OF_MENUS 16
|
||||
char *menunames[NUMBER_OF_MENUS] = { "main", "search", "replace", "replacewith",
|
||||
"yesno", "gotoline", "writeout", "insert",
|
||||
"execute", "help", "spell", "linter",
|
||||
"browser", "whereisfile", "gotodir",
|
||||
"all" };
|
||||
int menusymbols[NUMBER_OF_MENUS] = { MMAIN, MWHEREIS, MREPLACE, MREPLACEWITH,
|
||||
MYESNO, MGOTOLINE, MWRITEFILE, MINSERTFILE,
|
||||
MEXECUTE, MHELP, MSPELL, MLINTER,
|
||||
MBROWSER, MWHEREISFILE, MGOTODIR,
|
||||
MMOST|MBROWSER|MHELP|MYESNO };
|
||||
|
||||
/* Return the symbol that corresponds to the given menu name. */
|
||||
int name_to_menu(const char *name)
|
||||
{
|
||||
@ -502,7 +504,7 @@ int name_to_menu(const char *name)
|
||||
if (strcmp(name, menunames[index]) == 0)
|
||||
return menusymbols[index];
|
||||
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return the name that corresponds to the given menu symbol. */
|
||||
@ -785,6 +787,12 @@ void parse_binding(char *ptr, bool dobind)
|
||||
goto free_things;
|
||||
}
|
||||
|
||||
menu = name_to_menu(menuptr);
|
||||
if (menu == 0) {
|
||||
jot_error(N_("Unknown menu: %s"), menuptr);
|
||||
goto free_things;
|
||||
}
|
||||
|
||||
if (dobind) {
|
||||
/* If the thing to bind starts with a double quote, it is a string,
|
||||
* otherwise it is the name of a function. */
|
||||
@ -799,17 +807,11 @@ void parse_binding(char *ptr, bool dobind)
|
||||
newsc = strtosc(funcptr);
|
||||
|
||||
if (newsc == NULL) {
|
||||
jot_error(N_("Cannot map name \"%s\" to a function"), funcptr);
|
||||
jot_error(N_("Unknown function: %s"), funcptr);
|
||||
goto free_things;
|
||||
}
|
||||
}
|
||||
|
||||
menu = name_to_menu(menuptr);
|
||||
if (menu < 1) {
|
||||
jot_error(N_("Cannot map name \"%s\" to a menu"), menuptr);
|
||||
goto free_things;
|
||||
}
|
||||
|
||||
/* Wipe the given shortcut from the given menu. */
|
||||
for (keystruct *s = sclist; s != NULL; s = s->next)
|
||||
if ((s->menus & menu) && s->keycode == keycode)
|
||||
@ -1348,7 +1350,7 @@ static void check_vitals_mapped(void)
|
||||
if (f->func == vitals[v] && f->menus & inmenus[v]) {
|
||||
if (first_sc_for(inmenus[v], f->func) == NULL) {
|
||||
jot_error(N_("No key is bound to function '%s' in menu '%s'. "
|
||||
" Exiting.\n"), f->desc, menu_to_name(inmenus[v]));
|
||||
" Exiting.\n"), f->tag, menu_to_name(inmenus[v]));
|
||||
die(_("If needed, use nano with the -I option "
|
||||
"to adjust your nanorc settings.\n"));
|
||||
} else
|
||||
@ -1530,7 +1532,7 @@ void parse_rcfile(FILE *rcstream, bool just_syntax, bool intros_only)
|
||||
}
|
||||
|
||||
if (rcopts[i].name == NULL) {
|
||||
jot_error(N_("Unknown option \"%s\""), option);
|
||||
jot_error(N_("Unknown option: %s"), option);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
17
src/search.c
17
src/search.c
@ -222,8 +222,9 @@ int findnextstr(const char *needle, bool whole_word_only, int modus,
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
/* The match is valid. */
|
||||
break;
|
||||
/* When not on the magic line, the match is valid. */
|
||||
if (line->next || line->data[0])
|
||||
break;
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
@ -738,6 +739,7 @@ void ask_for_and_do_replacements(void)
|
||||
"Replaced %zd occurrences", numreplaced), numreplaced);
|
||||
}
|
||||
|
||||
#if !defined(NANO_TINY) || defined(ENABLE_SPELLER) || defined (ENABLE_LINTER) || defined (ENABLE_FORMATTER)
|
||||
/* Go to the specified line and x position. */
|
||||
void goto_line_posx(ssize_t linenumber, size_t pos_x)
|
||||
{
|
||||
@ -747,13 +749,18 @@ void goto_line_posx(ssize_t linenumber, size_t pos_x)
|
||||
recook |= perturbed;
|
||||
#endif
|
||||
|
||||
openfile->current = line_from_number(linenumber);
|
||||
if (linenumber < openfile->filebot->lineno)
|
||||
openfile->current = line_from_number(linenumber);
|
||||
else
|
||||
openfile->current = openfile->filebot;
|
||||
|
||||
openfile->current_x = pos_x;
|
||||
openfile->placewewant = xplustabs();
|
||||
UNFOLD_SEGMENT(openfile->current);
|
||||
|
||||
refresh_needed = TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Go to the specified line and column, or ask for them if interactive
|
||||
* is TRUE. In the latter case also update the screen afterwards.
|
||||
@ -839,9 +846,9 @@ void goto_line_and_column(ssize_t line, ssize_t column, bool retain_answer,
|
||||
openfile->placewewant = breadth(openfile->current->data);
|
||||
#endif
|
||||
|
||||
/* When the position was manually given, center the target line. */
|
||||
/* When a line number was manually given, center the target line. */
|
||||
if (interactive) {
|
||||
adjust_viewport(CENTERING);
|
||||
adjust_viewport((*answer == ',') ? STATIONARY : CENTERING);
|
||||
refresh_needed = TRUE;
|
||||
} else {
|
||||
int rows_from_tail;
|
||||
|
||||
24
src/text.c
24
src/text.c
@ -665,7 +665,7 @@ void do_undo(void)
|
||||
break;
|
||||
}
|
||||
|
||||
if (undidmsg && !pletion_line)
|
||||
if (undidmsg && !ISSET(ZERO) && !pletion_line)
|
||||
statusline(HUSH, _("Undid %s"), undidmsg);
|
||||
|
||||
openfile->current_undo = openfile->current_undo->next;
|
||||
@ -835,7 +835,7 @@ void do_redo(void)
|
||||
break;
|
||||
}
|
||||
|
||||
if (redidmsg)
|
||||
if (redidmsg && !ISSET(ZERO))
|
||||
statusline(HUSH, _("Redid %s"), redidmsg);
|
||||
|
||||
openfile->current_undo = u;
|
||||
@ -2039,7 +2039,7 @@ void do_full_justify(void)
|
||||
}
|
||||
#endif /* ENABLE_JUSTIFY */
|
||||
|
||||
#if defined(ENABLE_SPELLER) || defined (ENABLE_COLOR)
|
||||
#if defined(ENABLE_SPELLER) || defined (ENABLE_LINTER) || defined (ENABLE_FORMATTER)
|
||||
/* Set up an argument list for executing the given command. */
|
||||
void construct_argument_list(char ***arguments, char *command, char *filename)
|
||||
{
|
||||
@ -2056,7 +2056,9 @@ void construct_argument_list(char ***arguments, char *command, char *filename)
|
||||
(*arguments)[count - 2] = filename;
|
||||
(*arguments)[count - 1] = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(ENABLE_SPELLER) || defined (ENABLE_FORMATTER)
|
||||
/* Open the specified file, and if that succeeds, remove the text of the marked
|
||||
* region or of the entire buffer and read the file contents into its place. */
|
||||
bool replace_buffer(const char *filename, undo_type action, const char *operation)
|
||||
@ -2234,7 +2236,7 @@ void treat(char *tempfile_name, char *theprogram, bool spelling)
|
||||
statusline(REMARK, _("Buffer has been processed"));
|
||||
#endif
|
||||
}
|
||||
#endif /* ENABLE_SPELLER || ENABLE_COLOR */
|
||||
#endif /* ENABLE_SPELLER || ENABLE_FORMATTER */
|
||||
|
||||
#ifdef ENABLE_SPELLER
|
||||
/* Let the user edit the misspelled word. Return FALSE if the user cancels. */
|
||||
@ -2579,7 +2581,7 @@ void do_spell(void)
|
||||
}
|
||||
#endif /* ENABLE_SPELLER */
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
#ifdef ENABLE_LINTER
|
||||
/* Run a linting program on the current buffer. */
|
||||
void do_linter(void)
|
||||
{
|
||||
@ -2926,7 +2928,9 @@ void do_linter(void)
|
||||
titlebar(NULL);
|
||||
#endif
|
||||
}
|
||||
#endif /* ENABLE_LINTER */
|
||||
|
||||
#ifdef ENABLE_FORMATTER
|
||||
/* Run a manipulation program on the contents of the buffer. */
|
||||
void do_formatter(void)
|
||||
{
|
||||
@ -2961,7 +2965,7 @@ void do_formatter(void)
|
||||
unlink(temp_name);
|
||||
free(temp_name);
|
||||
}
|
||||
#endif /* ENABLE_COLOR */
|
||||
#endif /* ENABLE_FORMATTER */
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Our own version of "wc". Note that the character count is in
|
||||
@ -3051,7 +3055,13 @@ void do_verbatim_input(void)
|
||||
if (count < 999)
|
||||
inject(bytes, count);
|
||||
|
||||
wipe_statusbar();
|
||||
#ifndef NANO_TINY
|
||||
/* Ensure that the feedback will be overwritten, or clear it. */
|
||||
if (ISSET(ZERO) && currmenu == MMAIN)
|
||||
wredrawln(midwin, editwinrows - 1, 1);
|
||||
else
|
||||
#endif
|
||||
wipe_statusbar();
|
||||
} else
|
||||
/* TRANSLATORS: An invalid verbatim Unicode code was typed. */
|
||||
statusline(AHEM, _("Invalid code"));
|
||||
|
||||
13
src/utils.c
13
src/utils.c
@ -168,14 +168,19 @@ void recode_NUL_to_LF(char *string, size_t length)
|
||||
}
|
||||
}
|
||||
|
||||
/* In the given string, recode each embedded newline as a NUL. */
|
||||
void recode_LF_to_NUL(char *string)
|
||||
/* In the given string, recode each embedded newline as a NUL,
|
||||
* and return the number of bytes in the string. */
|
||||
size_t recode_LF_to_NUL(char *string)
|
||||
{
|
||||
char *beginning = string;
|
||||
|
||||
while (*string != '\0') {
|
||||
if (*string == '\n')
|
||||
*string = '\0';
|
||||
string++;
|
||||
}
|
||||
|
||||
return (string - beginning);
|
||||
}
|
||||
|
||||
#if !defined(ENABLE_TINY) || defined(ENABLE_TABCOMP) || defined(ENABLE_BROWSER)
|
||||
@ -484,7 +489,9 @@ void get_range(linestruct **top, linestruct **bot)
|
||||
also_the_last = TRUE;
|
||||
}
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
#if !defined(NANO_TINY) || defined(ENABLE_SPELLER) || defined (ENABLE_LINTER) || defined (ENABLE_FORMATTER)
|
||||
/* Return a pointer to the line that has the given line number. */
|
||||
linestruct *line_from_number(ssize_t number)
|
||||
{
|
||||
@ -499,7 +506,7 @@ linestruct *line_from_number(ssize_t number)
|
||||
|
||||
return line;
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
#endif
|
||||
|
||||
/* Count the number of characters from begin to end, and return it. */
|
||||
size_t number_of_characters_in(const linestruct *begin, const linestruct *end)
|
||||
|
||||
244
src/winio.c
244
src/winio.c
@ -46,8 +46,14 @@ static int *key_buffer = NULL;
|
||||
/* A buffer for the keystrokes that haven't been handled yet. */
|
||||
static int *nextcodes = NULL;
|
||||
/* A pointer pointing at the next keycode in the keystroke buffer. */
|
||||
static size_t capacity = 32;
|
||||
/* The size of the keystroke buffer; gets doubled whenever needed. */
|
||||
static size_t waiting_codes = 0;
|
||||
/* The number of key codes waiting in the keystroke buffer. */
|
||||
#ifdef ENABLE_NANORC
|
||||
static const char *plants_pointer = NULL;
|
||||
/* Points into the expansion string for the current implantation. */
|
||||
#endif
|
||||
static int digit_count = 0;
|
||||
/* How many digits of a three-digit character code we've eaten. */
|
||||
static bool reveal_cursor = FALSE;
|
||||
@ -56,18 +62,14 @@ static bool linger_after_escape = FALSE;
|
||||
/* Whether to give ncurses some time to get the next code. */
|
||||
static int statusblank = 0;
|
||||
/* The number of keystrokes left before we blank the status bar. */
|
||||
size_t from_x = 0;
|
||||
static size_t from_x = 0;
|
||||
/* From where in the relevant line the current row is drawn. */
|
||||
size_t till_x = 0;
|
||||
static size_t till_x = 0;
|
||||
/* Until where in the relevant line the current row is drawn. */
|
||||
static bool has_more = FALSE;
|
||||
/* Whether the current line has more text after the displayed part. */
|
||||
static bool is_shorter = TRUE;
|
||||
/* Whether a row's text is narrower than the screen's width. */
|
||||
#ifdef ENABLE_NANORC
|
||||
static const char *plants_pointer = NULL;
|
||||
/* Points into the expansion string for the current implantation. */
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
static size_t sequel_column = 0;
|
||||
/* The starting column of the next chunk when softwrapping. */
|
||||
@ -86,7 +88,7 @@ void add_to_macrobuffer(int code)
|
||||
macro_buffer[macro_length - 1] = code;
|
||||
}
|
||||
|
||||
/* Remove the last key code plus any trailing Esc codes from macro buffer. */
|
||||
/* Remove the last key code plus any leading Esc codes from macro buffer. */
|
||||
void snip_last_keystroke(void)
|
||||
{
|
||||
macro_length--;
|
||||
@ -126,7 +128,8 @@ void run_macro(void)
|
||||
return;
|
||||
}
|
||||
|
||||
key_buffer = nrealloc(key_buffer, macro_length * sizeof(int));
|
||||
if (macro_length > capacity)
|
||||
reserve_space_for(macro_length);
|
||||
|
||||
for (size_t i = 0; i < macro_length; i++)
|
||||
key_buffer[i] = macro_buffer[i];
|
||||
@ -186,6 +189,17 @@ linestruct *get_prev_visible_line(linestruct *line)
|
||||
return line->prev;
|
||||
}
|
||||
|
||||
/* Allocate the requested space for the keystroke buffer. */
|
||||
void reserve_space_for(size_t newsize)
|
||||
{
|
||||
if (newsize < capacity)
|
||||
die(_("Too much input at once\n"));
|
||||
|
||||
key_buffer = nrealloc(key_buffer, newsize * sizeof(int));
|
||||
nextcodes = key_buffer;
|
||||
capacity = newsize;
|
||||
}
|
||||
|
||||
/* Control character compatibility:
|
||||
*
|
||||
* - Ctrl-H is Backspace under ASCII, ANSI, VT100, and VT220.
|
||||
@ -209,22 +223,17 @@ linestruct *get_prev_visible_line(linestruct *line)
|
||||
* We support escape sequences for ANSI, VT100, VT220, VT320, the Linux
|
||||
* console, the FreeBSD console, the Mach console, xterm, and Terminal,
|
||||
* and some for Konsole, rxvt, Eterm, and iTerm2. Among these sequences,
|
||||
* there are several conflicts and omissions:
|
||||
* there are some conflicts:
|
||||
*
|
||||
* - Tab on ANSI == PageUp on FreeBSD console; the former is omitted.
|
||||
* - PageUp on FreeBSD console == Tab on ANSI; the latter is omitted.
|
||||
* (Ctrl-I is also Tab on ANSI, which we already support.)
|
||||
* - PageDown on FreeBSD console == Center (5) on numeric keypad with
|
||||
* NumLock off on Linux console; the latter is omitted. (The editing
|
||||
* keypad key is more important to have working than the numeric
|
||||
* keypad key, because the latter has no value when NumLock is off.)
|
||||
* - F1 on FreeBSD console == the mouse key on xterm/rxvt/Eterm; the
|
||||
* latter is omitted. (Mouse input will only work properly if the
|
||||
* extended keypad value KEY_MOUSE is generated on mouse events
|
||||
* instead of the escape sequence.)
|
||||
* NumLock off on Linux console; the latter is useless and omitted.
|
||||
* - F1 on FreeBSD console == the mouse sequence on xterm/rxvt/Eterm;
|
||||
* the latter is omitted. (Mouse input works only when KEY_MOUSE
|
||||
* is generated on mouse events, not with the raw escape sequence.)
|
||||
* - F9 on FreeBSD console == PageDown on Mach console; the former is
|
||||
* omitted. (The editing keypad is more important to have working
|
||||
* than the function keys, because the functions of the former are
|
||||
* not arbitrary and the functions of the latter are.)
|
||||
* omitted. (Moving the cursor is more important than a function key.)
|
||||
* - F10 on FreeBSD console == PageUp on Mach console; the former is
|
||||
* omitted. (Same as above.) */
|
||||
|
||||
@ -251,6 +260,7 @@ void read_keys_from(WINDOW *frame)
|
||||
lastmessage != INFO) || spotlighted)) {
|
||||
timed = TRUE;
|
||||
halfdelay(ISSET(QUICK_BLANK) ? 8 : 15);
|
||||
/* Counteract a side effect of half-delay mode. */
|
||||
disable_kb_interrupt();
|
||||
}
|
||||
#endif
|
||||
@ -267,6 +277,7 @@ void read_keys_from(WINDOW *frame)
|
||||
|
||||
if (timed) {
|
||||
timed = FALSE;
|
||||
/* Leave half-delay mode. */
|
||||
raw();
|
||||
|
||||
if (input == ERR) {
|
||||
@ -298,10 +309,13 @@ void read_keys_from(WINDOW *frame)
|
||||
|
||||
curs_set(0);
|
||||
|
||||
/* Initiate the keystroke buffer, and save the keycode in it. */
|
||||
key_buffer = nrealloc(key_buffer, sizeof(int));
|
||||
nextcodes = key_buffer;
|
||||
/* When there is no keystroke buffer yet, allocate one. */
|
||||
if (!key_buffer)
|
||||
reserve_space_for(capacity);
|
||||
|
||||
key_buffer[0] = input;
|
||||
|
||||
nextcodes = key_buffer;
|
||||
waiting_codes = 1;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
@ -335,10 +349,11 @@ void read_keys_from(WINDOW *frame)
|
||||
if (input == ERR)
|
||||
break;
|
||||
|
||||
/* Extend the keystroke buffer, and save the keycode at its end. */
|
||||
key_buffer = nrealloc(key_buffer, ++waiting_codes * sizeof(int));
|
||||
key_buffer[waiting_codes - 1] = input;
|
||||
nextcodes = key_buffer;
|
||||
/* When the keystroke buffer is full, extend it. */
|
||||
if (waiting_codes == capacity)
|
||||
reserve_space_for(2 * capacity);
|
||||
|
||||
key_buffer[waiting_codes++] = input;
|
||||
}
|
||||
|
||||
/* Restore blocking-input mode. */
|
||||
@ -361,16 +376,11 @@ size_t waiting_keycodes(void)
|
||||
/* Add the given keycode to the front of the keystroke buffer. */
|
||||
void put_back(int keycode)
|
||||
{
|
||||
/* If the keystroke buffer is at maximum capacity, don't add anything. */
|
||||
if (waiting_codes + 1 < waiting_codes)
|
||||
return;
|
||||
|
||||
/* If there is no room at the head of the keystroke buffer, make room. */
|
||||
if (nextcodes == key_buffer) {
|
||||
key_buffer = nrealloc(key_buffer, (waiting_codes + 1) * sizeof(int));
|
||||
if (waiting_codes)
|
||||
memmove(key_buffer + 1, key_buffer, waiting_codes * sizeof(int));
|
||||
nextcodes = key_buffer;
|
||||
if (waiting_codes == capacity)
|
||||
reserve_space_for(2 * capacity);
|
||||
memmove(key_buffer + 1, key_buffer, waiting_codes * sizeof(int));
|
||||
} else
|
||||
nextcodes--;
|
||||
|
||||
@ -411,19 +421,24 @@ int get_code_from_plantation(void)
|
||||
commandname = measured_copy(plants_pointer + 1, closing - plants_pointer - 1);
|
||||
planted_shortcut = strtosc(commandname);
|
||||
|
||||
if (planted_shortcut) {
|
||||
plants_pointer = closing + 1;
|
||||
if (*plants_pointer != '\0')
|
||||
put_back(MORE_PLANTS);
|
||||
return PLANTED_COMMAND;
|
||||
} else
|
||||
if (!planted_shortcut)
|
||||
return NO_SUCH_FUNCTION;
|
||||
|
||||
plants_pointer = closing + 1;
|
||||
|
||||
if (*plants_pointer != '\0')
|
||||
put_back(MORE_PLANTS);
|
||||
|
||||
return PLANTED_COMMAND;
|
||||
} else {
|
||||
char *opening = strchr(plants_pointer, '{');
|
||||
int length = (opening ? opening - plants_pointer : strlen(plants_pointer));
|
||||
int length;
|
||||
|
||||
if (opening)
|
||||
if (opening) {
|
||||
length = opening - plants_pointer;
|
||||
put_back(MORE_PLANTS);
|
||||
} else
|
||||
length = strlen(plants_pointer);
|
||||
|
||||
for (int index = length - 1; index >= 0; index--)
|
||||
put_back((unsigned char)plants_pointer[index]);
|
||||
@ -1397,79 +1412,48 @@ int get_kbinput(WINDOW *frame, bool showcursor)
|
||||
#ifdef ENABLE_UTF8
|
||||
#define INVALID_DIGIT -77
|
||||
|
||||
/* If the given symbol is a valid hexadecimal digit, multiply it by factor
|
||||
* and add the result to the given unicode, and return PROCEED to signify
|
||||
* okay. When not a hexadecimal digit, return the symbol itself. */
|
||||
long add_unicode_digit(int symbol, long factor, long *unicode)
|
||||
{
|
||||
if ('0' <= symbol && symbol <= '9')
|
||||
*unicode += (symbol - '0') * factor;
|
||||
else if ('a' <= tolower(symbol) && tolower(symbol) <= 'f')
|
||||
*unicode += (tolower(symbol) - 'a' + 10) * factor;
|
||||
else
|
||||
return INVALID_DIGIT;
|
||||
|
||||
return PROCEED;
|
||||
}
|
||||
|
||||
/* For each consecutive call, gather the given symbol into a six-digit Unicode
|
||||
* (from 000000 to 10FFFF, case-insensitive). When it is complete, return the
|
||||
* assembled Unicode; until then, return PROCEED when the symbol is valid. */
|
||||
/* For each consecutive call, gather the given symbol into a Unicode code point.
|
||||
* When it's complete (with six digits, or when Space or Enter is typed), return
|
||||
* the assembled code. Until then, return PROCEED when the symbol is valid, or
|
||||
* an error code for anything other than hexadecimal, Space, and Enter. */
|
||||
long assemble_unicode(int symbol)
|
||||
{
|
||||
static long unicode = 0;
|
||||
static int digits = 0;
|
||||
long retval = PROCEED;
|
||||
long outcome = PROCEED;
|
||||
|
||||
switch (++digits) {
|
||||
case 1:
|
||||
unicode = (symbol - '0') * 0x100000;
|
||||
break;
|
||||
case 2:
|
||||
/* The second digit must be zero if the first was one, but
|
||||
* may be any hexadecimal value if the first was zero. */
|
||||
if (symbol == '0' || unicode == 0)
|
||||
retval = add_unicode_digit(symbol, 0x10000, &unicode);
|
||||
else
|
||||
retval = INVALID_DIGIT;
|
||||
break;
|
||||
case 3:
|
||||
/* Later digits may be any hexadecimal value. */
|
||||
retval = add_unicode_digit(symbol, 0x1000, &unicode);
|
||||
break;
|
||||
case 4:
|
||||
retval = add_unicode_digit(symbol, 0x100, &unicode);
|
||||
break;
|
||||
case 5:
|
||||
retval = add_unicode_digit(symbol, 0x10, &unicode);
|
||||
break;
|
||||
case 6:
|
||||
retval = add_unicode_digit(symbol, 0x1, &unicode);
|
||||
/* If also the sixth digit was a valid hexadecimal value, then
|
||||
* the Unicode sequence is complete, so return it. */
|
||||
if (retval == PROCEED)
|
||||
retval = unicode;
|
||||
break;
|
||||
}
|
||||
if ('0' <= symbol && symbol <= '9')
|
||||
unicode = (unicode << 4) + symbol - '0';
|
||||
else if ('a' <= (symbol | 0x20) && (symbol | 0x20) <= 'f')
|
||||
unicode = (unicode << 4) + (symbol | 0x20) - 'a' + 10;
|
||||
else if (symbol == '\r' || symbol == ' ')
|
||||
outcome = unicode;
|
||||
else
|
||||
outcome = INVALID_DIGIT;
|
||||
|
||||
/* If also the sixth digit was a valid hexadecimal value, then the
|
||||
* Unicode sequence is complete, so return it (when it's valid). */
|
||||
if (++digits == 6 && outcome == PROCEED)
|
||||
outcome = (unicode < 0x110000) ? unicode : INVALID_DIGIT;
|
||||
|
||||
/* Show feedback only when editing, not when at a prompt. */
|
||||
if (retval == PROCEED && currmenu == MMAIN) {
|
||||
char partial[7] = "......";
|
||||
if (outcome == PROCEED && currmenu == MMAIN) {
|
||||
char partial[7] = " ";
|
||||
|
||||
/* Construct the partial result, right-padding it with dots. */
|
||||
snprintf(partial, digits + 1, "%06lX", unicode);
|
||||
partial[digits] = '.';
|
||||
sprintf(partial + 6 - digits, "%0*lX", digits, unicode);
|
||||
|
||||
/* TRANSLATORS: This is shown while a six-digit hexadecimal
|
||||
* Unicode character code (%s) is being typed in. */
|
||||
statusline(INFO, _("Unicode Input: %s"), partial);
|
||||
}
|
||||
|
||||
/* If we have an end result, reset the Unicode digit counter. */
|
||||
if (retval != PROCEED)
|
||||
/* If we have an end result, reset the value and the counter. */
|
||||
if (outcome != PROCEED) {
|
||||
unicode = 0;
|
||||
digits = 0;
|
||||
}
|
||||
|
||||
return retval;
|
||||
return outcome;
|
||||
}
|
||||
#endif /* ENABLE_UTF8 */
|
||||
|
||||
@ -1483,7 +1467,6 @@ int *parse_verbatim_kbinput(WINDOW *frame, size_t *count)
|
||||
|
||||
reveal_cursor = TRUE;
|
||||
|
||||
/* Read in the first code. */
|
||||
keycode = get_input(frame);
|
||||
|
||||
#ifndef NANO_TINY
|
||||
@ -1498,14 +1481,14 @@ int *parse_verbatim_kbinput(WINDOW *frame, size_t *count)
|
||||
yield = nmalloc(6 * sizeof(int));
|
||||
|
||||
#ifdef ENABLE_UTF8
|
||||
/* If the first code is a valid Unicode starter digit (0 or 1),
|
||||
* commence Unicode input. Otherwise, put the code back. */
|
||||
if (using_utf8() && (keycode == '0' || keycode == '1')) {
|
||||
/* If the key code is a hexadecimal digit, commence Unicode input. */
|
||||
if (using_utf8() && isxdigit(keycode)) {
|
||||
long unicode = assemble_unicode(keycode);
|
||||
char multibyte[MB_CUR_MAX];
|
||||
|
||||
reveal_cursor = FALSE;
|
||||
|
||||
/* Gather at most six hexadecimal digits. */
|
||||
while (unicode == PROCEED) {
|
||||
keycode = get_input(frame);
|
||||
unicode = assemble_unicode(keycode);
|
||||
@ -1518,7 +1501,7 @@ int *parse_verbatim_kbinput(WINDOW *frame, size_t *count)
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
/* For an invalid digit, discard its possible continuation bytes. */
|
||||
/* For an invalid keystroke, discard its possible continuation bytes. */
|
||||
if (unicode == INVALID_DIGIT) {
|
||||
if (keycode == ESC_CODE && waiting_codes) {
|
||||
get_input(NULL);
|
||||
@ -1599,9 +1582,6 @@ char *get_verbatim_kbinput(WINDOW *frame, size_t *count)
|
||||
/* Turn bracketed-paste mode back on. */
|
||||
printf("\x1B[?2004h");
|
||||
fflush(stdout);
|
||||
|
||||
if (ISSET(ZERO) && currmenu == MMAIN)
|
||||
wredrawln(midwin, editwinrows - 1, 1);
|
||||
#endif
|
||||
|
||||
/* Turn flow control characters back on if necessary and turn the
|
||||
@ -2533,7 +2513,7 @@ void bottombars(int menu)
|
||||
if (index + 2 >= number)
|
||||
thiswidth += COLS % itemwidth;
|
||||
|
||||
post_one_key(s->keystr, _(f->desc), thiswidth);
|
||||
post_one_key(s->keystr, _(f->tag), thiswidth);
|
||||
|
||||
index++;
|
||||
}
|
||||
@ -3794,16 +3774,17 @@ void spotlight_softwrapped(size_t from_col, size_t to_col)
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_EXTRA
|
||||
#define CREDIT_LEN 54
|
||||
#define CREDIT_LEN 52
|
||||
#define XLCREDIT_LEN 9
|
||||
|
||||
/* Fully blank the terminal screen, then slowly "crawl" the credits over it.
|
||||
* Abort the crawl upon any keystroke. */
|
||||
void do_credits(void)
|
||||
{
|
||||
bool with_empty_line = ISSET(EMPTY_LINE);
|
||||
bool with_interface = !ISSET(ZERO);
|
||||
bool with_help = !ISSET(NO_HELP);
|
||||
int kbinput = ERR, crpos = 0, xlpos = 0;
|
||||
int crpos = 0, xlpos = 0;
|
||||
|
||||
const char *credits[CREDIT_LEN] = {
|
||||
NULL, /* "The nano text editor" */
|
||||
NULL, /* "version" */
|
||||
@ -3851,13 +3832,11 @@ void do_credits(void)
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"(C) 2022",
|
||||
"Free Software Foundation, Inc.",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"https://nano-editor.org/"
|
||||
};
|
||||
|
||||
@ -3873,8 +3852,8 @@ void do_credits(void)
|
||||
N_("Thank you for using nano!")
|
||||
};
|
||||
|
||||
if (with_empty_line || with_help) {
|
||||
UNSET(EMPTY_LINE);
|
||||
if (with_interface || with_help) {
|
||||
SET(ZERO);
|
||||
SET(NO_HELP);
|
||||
window_init();
|
||||
}
|
||||
@ -3882,49 +3861,38 @@ void do_credits(void)
|
||||
nodelay(midwin, TRUE);
|
||||
scrollok(midwin, TRUE);
|
||||
|
||||
blank_titlebar();
|
||||
blank_edit();
|
||||
blank_statusbar();
|
||||
|
||||
wrefresh(topwin);
|
||||
wrefresh(midwin);
|
||||
wrefresh(footwin);
|
||||
napms(700);
|
||||
napms(600);
|
||||
|
||||
for (crpos = 0; crpos < CREDIT_LEN + editwinrows / 2; crpos++) {
|
||||
if (crpos < CREDIT_LEN) {
|
||||
const char *what;
|
||||
const char *text = credits[crpos];
|
||||
|
||||
if (credits[crpos] == NULL)
|
||||
what = _(xlcredits[xlpos++]);
|
||||
else
|
||||
what = credits[crpos];
|
||||
if (!text)
|
||||
text = _(xlcredits[xlpos++]);
|
||||
|
||||
mvwaddstr(midwin, editwinrows - 1 - (editwinrows % 2),
|
||||
COLS / 2 - breadth(what) / 2 - 1, what);
|
||||
mvwaddstr(midwin, editwinrows - 1, (COLS - breadth(text)) / 2, text);
|
||||
wrefresh(midwin);
|
||||
}
|
||||
|
||||
if ((kbinput = wgetch(midwin)) != ERR)
|
||||
if (wgetch(midwin) != ERR)
|
||||
break;
|
||||
|
||||
napms(700);
|
||||
napms(600);
|
||||
wscrl(midwin, 1);
|
||||
wrefresh(midwin);
|
||||
|
||||
if ((kbinput = wgetch(midwin)) != ERR)
|
||||
if (wgetch(midwin) != ERR)
|
||||
break;
|
||||
|
||||
napms(700);
|
||||
napms(600);
|
||||
wscrl(midwin, 1);
|
||||
wrefresh(midwin);
|
||||
}
|
||||
|
||||
if (kbinput != ERR)
|
||||
ungetch(kbinput);
|
||||
|
||||
if (with_empty_line)
|
||||
SET(EMPTY_LINE);
|
||||
if (with_interface)
|
||||
UNSET(ZERO);
|
||||
if (with_help)
|
||||
UNSET(NO_HELP);
|
||||
window_init();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user