DLR and DB fixes mega-merge
git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@1235 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
Этот коммит содержится в:
родитель
cf2f6563ca
Коммит
6df90f5787
2
BUGS
2
BUGS
@ -105,7 +105,7 @@
|
||||
higuita@cadernoverde.com) (54) [FIXED].
|
||||
- When using autoindent (-i), wrapped text does not get autoindented
|
||||
(55, discovered by Mark Senior) [FIXED].
|
||||
- When using -R (regex) and -p (pico mode), subsequent searches after
|
||||
- When using -R (regex) and -p (Pico mode), subsequent searches after
|
||||
the first fail if no string is entered (56) [FIXED].
|
||||
- Page down on a file of editwinrows fails (again). Reported by Ryan
|
||||
Krebs (57) [FIXED].
|
||||
|
143
ChangeLog
143
ChangeLog
@ -14,8 +14,9 @@ CVS Code -
|
||||
- Many fixes to the help browser and shortcut lists: efficiency
|
||||
updates, consistency fixes, help text fixes and improvements,
|
||||
and spacing improvements. (David Benbennick)
|
||||
- Make more functions use const variables when possible. (David
|
||||
Benbennick)
|
||||
- Make some functions use const variables when possible, and
|
||||
also make them static when necessary. (David Benbennick,
|
||||
necessary redefined by Chris ;-)
|
||||
- Add Carl Drinkwater's backup file option (-B or --backup on the
|
||||
command line, M-B in nano's global shortcuts). If the original
|
||||
file is unchanged from when it was loaded, it is backed up to
|
||||
@ -33,20 +34,57 @@ CVS Code -
|
||||
--regexp as an alternative for -R; they were listed in nano's
|
||||
usage information, but weren't actually in nano. Also, display
|
||||
"-?" as an alternative for "-h" in nano's usage information,
|
||||
put the command line options in a more consistent (i. e. mostly
|
||||
put the command line options in a more consistent (i.e. mostly
|
||||
alphabetical) order in nano, put the long options in a more
|
||||
consistent order in rcfile.c and nanorc.sample, don't include
|
||||
rcfile options if their equivalent command line options are
|
||||
disabled, and remove obsolete relative option from
|
||||
nanorc.sample. (DLR)
|
||||
- Removed much unnecessary parts to the color code and reworks
|
||||
some of the color display (David Benbennick).
|
||||
- Change "File Name to Append/Prepend" to "File Name to
|
||||
Append/Prepend to". The original prompt could confusingly
|
||||
imply that we are appending/prepending another file to the
|
||||
current file, when we are actually appending/prepending the
|
||||
current file to another file. (DLR)
|
||||
- Put nano.1, nano.1.html, and nano.texi up to date. (DLR)
|
||||
- Typo fixes for the ChangeLog. (David Benbennick)
|
||||
- Put nano.1, nano.1.html, and nano.texi up to date, and fix a
|
||||
few inconsistencies in them. (DLR)
|
||||
- Typo fixes for the ChangeLog. (David Benbennick and DLR)
|
||||
- Complete rewrite of justification code to fix some bugs and
|
||||
improve its functionality. (David Benbennick)
|
||||
- If a variable isn't going to be used in tiny mode, #define it
|
||||
out when possible. (David Benbennick)
|
||||
- Major reworking of the cutting/screen-updating code in cut.c,
|
||||
some functions in utils.c, the cursor placement code in
|
||||
winio.c, and many, many other areas to increase efficiency.
|
||||
(David Benbennick)
|
||||
- Rework handling of prompts when there's a list of partial
|
||||
filename matches on the screen: remove kludgy case-by-case
|
||||
handling (which didn't even handle every case), and have
|
||||
statusq() handle it directly for all cases. (David Benbennick
|
||||
and DLR)
|
||||
- Fix some warnings and errors that show up when using gcc's
|
||||
-pedantic option. (DLR)
|
||||
- Add a comment to nanorc.sample warning that an out-of-range
|
||||
negative value for fill can make nano die complaining that
|
||||
the screen is too small (which may not be immediately
|
||||
obvious. (DLR)
|
||||
- There were some opendir() calls in files.c without
|
||||
corresponding closedir() calls; add them. (DLR)
|
||||
- Move align() and null_at() from nano.c to utils.c, and move
|
||||
the openfilestruct handling functions from nano.c to files.c.
|
||||
(DLR)
|
||||
- In color.c, start the "#ifdef ENABLE_COLOR" block after
|
||||
including all the header files, as rcfile.c does; this fixes
|
||||
a warning about ANSI C'S inability to handle blank files.
|
||||
(DLR)
|
||||
- Add command line option -I/--ignorercfiles to ignore
|
||||
/etc/nanorc and ~/.nanorc. (Carl Drinkwater)
|
||||
- files.c:
|
||||
new_file():
|
||||
- Make sure current_x is zero; this fixes a problem where the
|
||||
current cursor position wasn't reset when reading in a file in
|
||||
multibuffer mode. (David Benbennick)
|
||||
read_file(), read_line():
|
||||
- Rework to properly handle nulls in the input file, fix
|
||||
detection of binary files to properly mark a file as binary if
|
||||
@ -66,8 +104,19 @@ CVS Code -
|
||||
--enable-tiny is used. Since formatstr isn't ever used in tiny
|
||||
mode, don't bother even creating the variable. (David
|
||||
Benbennick and DLR)
|
||||
do_insertfile():
|
||||
- Memory leak fix. (David Benbennick)
|
||||
get_full_path():
|
||||
- Memory leak fix. Also, make it properly interpret ~/ notation
|
||||
so, among other things, the option "--operatingdir ~" works.
|
||||
(David Benbennick)
|
||||
check_operating_dir():
|
||||
- Memory leak fix. (David Benbennick)
|
||||
cwd_tab_completion():
|
||||
- Changed a variable name: dirName -> dirname. (DLR)
|
||||
append_slash_if_dir(), input_tab():
|
||||
- Changed a variable name: lastWasTab -> lastwastab. (DLR)
|
||||
- Changed variable names: lastWasTab -> lastwastab, matchBuf ->
|
||||
matchbuf. (DLR)
|
||||
- global.c:
|
||||
free_toggles():
|
||||
- Only include if we're not using tiny mode. (David Benbennick)
|
||||
@ -79,6 +128,8 @@ CVS Code -
|
||||
do_toggle() if Pico emulation mode is the toggle in question.
|
||||
Don't free the toggles here, either; it's unnecessary after the
|
||||
above change. (David Benbennick)
|
||||
- If wrapping is disabled, don't include the toggle for it.
|
||||
(DLR)
|
||||
shortcut_init():
|
||||
- Rework IFHELP macro (David Benbennick).
|
||||
- move.c:
|
||||
@ -90,6 +141,26 @@ CVS Code -
|
||||
- nanorc.sample:
|
||||
- Put in much less crappy example regex rules for c-file.
|
||||
- nano.c:
|
||||
do_char():
|
||||
- Fix a problem where, if ENABLE_COLOR wasn't used, typing
|
||||
characters on a marked line before the beginning of the mark
|
||||
would make the highlight short by one. (David Benbennick)
|
||||
die():
|
||||
- Rework slightly to remove redundant printing of last message
|
||||
and print all messages after resetting the terminal. (DLR)
|
||||
global_init():
|
||||
- Call die_too_small() when fill is 0. (DLR)
|
||||
usage():
|
||||
- List the options that are ignored for the purpose of Pico
|
||||
compatibility, and make some minor consistency fixes. (DLR)
|
||||
do_next_word(), do_prev_word():
|
||||
- Fix a problem where highlighting isn't done properly after
|
||||
calling either of these, and another problem where the cursor
|
||||
would move back too far in certain cases with do_prev_word().
|
||||
(David Benbennick)
|
||||
do_backspace():
|
||||
- Make sure placewewant is set properly, and that the mark is
|
||||
moved backwards. (David Benbennick)
|
||||
clear_filename():
|
||||
- Remove this function, as it has unneeded functionality, is
|
||||
short enough to be inlined, and is only called in two spots
|
||||
@ -97,6 +168,16 @@ CVS Code -
|
||||
do_int_spell(), do_alt_spell():
|
||||
- Rework to save the marked selection before doing spell checking
|
||||
and restore it afterward. (DLR)
|
||||
do_cont():
|
||||
- Handle the case where the window was resized while we were
|
||||
stopped. (David Benbennick)
|
||||
handle_sigwinch():
|
||||
- Make sure we adjust fill when the window is resized. (David
|
||||
Benbennick)
|
||||
- Call die_too_small() when fill is 0. (DLR)
|
||||
help_init():
|
||||
- Since the return value of snprintf() isn't well defined, use
|
||||
sprintf() instead. (David Benbennick)
|
||||
do_toggle():
|
||||
- Since the search mode toggles aren't global anymore, we don't
|
||||
need to explicitly block them here anymore (which will end up
|
||||
@ -109,8 +190,23 @@ CVS Code -
|
||||
hold a line number. (DLR)
|
||||
- Properly handle multiple -r settings on the command line. (Carl
|
||||
Drinkwater)
|
||||
- Fix a bug that prevented file insertion via the Insert key
|
||||
from working at all when --enable-multibuffer wasn't used
|
||||
(oops). (DLR)
|
||||
- Adapt David Benbennick's fix to get fill to accept negative
|
||||
numbers properly in parse_rcfile() (see below) to the
|
||||
handlers for the -r and -T options as well, so that -r/-T 0
|
||||
can be treated separately from -r/-T string. (DLR)
|
||||
- proto.h:
|
||||
- Remove external declaration of the global int fill, since
|
||||
it's now static. (DLR)
|
||||
- rcfile.c:
|
||||
colortoint():
|
||||
parse_rcfile():
|
||||
- Add David Benbennick's fix that allows fill to accept
|
||||
negative numbers properly. Specifically, use strtol() there
|
||||
instead of atoi() so that errors can be detected. Also
|
||||
adapted for tabsize by DLR.
|
||||
parse_next_regex(), colortoint():
|
||||
- Only include if ENABLE_COLOR is defined. (DLR)
|
||||
- search.c:
|
||||
search_init():
|
||||
@ -118,6 +214,9 @@ CVS Code -
|
||||
part of this function referencing them so that they still work.
|
||||
(DLR)
|
||||
- Remove unneeded toggles variable. (David Benbennick)
|
||||
- Fix a problem where the first character of buf was overwritten
|
||||
if the last search string was one third the number of columns
|
||||
plus one. (David Benbennick)
|
||||
findnextstr():
|
||||
- Update the current line at current_x if we don't find a match.
|
||||
Also, pass current_x_find to strstrwrapper() so we know whether
|
||||
@ -134,10 +233,16 @@ CVS Code -
|
||||
other than the terminating null in strings to newlines and
|
||||
back; they're used to handle null characters in files properly.
|
||||
(DLR)
|
||||
lowercase():
|
||||
- Remove, since it isn't actually used anywhere. (David
|
||||
Benbennick)
|
||||
strstrwrapper(): Set REG_NOTBOL when we're not at the beginning of a
|
||||
string, to avoid false positives when searching for regular
|
||||
expressions prefixed with ^. Make it take a new parameter,
|
||||
line_pos, to determine where we are in the string. (DLR)
|
||||
check_wildcard_match():
|
||||
- Changed variable names: retryPat -> retrypat, retryText ->
|
||||
retrytext. (DLR)
|
||||
- winio.c:
|
||||
actual_x_from_start():
|
||||
- Overhaul to make cursor placement more like that of Pico: add
|
||||
@ -158,16 +263,28 @@ CVS Code -
|
||||
(which should never occur under normal circumstances; they will
|
||||
only be there if the line had nulls in it and was unsunder()ed
|
||||
beforehand) as ^@'s. (DLR)
|
||||
- Display ASCII 0x80-0x9f as backslashes followed by 3-digit
|
||||
octal values to keep xterm from screwing up the display when
|
||||
some of them are printed as-is. (David Benbennick)
|
||||
statusbar():
|
||||
- Limit statusbar display to the number of columns less four, and
|
||||
don't allow it to go over its original row. (David Benbennick)
|
||||
do_help():
|
||||
- Add support for the handled keyboard escape sequences in the
|
||||
help menu, as they are needed with some terminals (e.g. xterm
|
||||
with TERM=ansi). (DLR)
|
||||
do_replace_highlight():
|
||||
- When using regexps, make sure the highlight is the length of
|
||||
the search result and not the regexp string. (DLR)
|
||||
- configure.ac:
|
||||
- Added ms to ALL_LINGUAS (Jordi).
|
||||
- Merged acconfig.h in (Jordi).
|
||||
- Fixed so that --enable-debug defines DEBUG and undefines
|
||||
NDEBUG. (Carl Drinkwater)
|
||||
- THANKS:
|
||||
- Completed a bit (Jordi).
|
||||
- Fixed David Benbennick's email address (David Benbennick).
|
||||
- Fixed David Benbennick's email address. (David Benbennick)
|
||||
- Typo fix. (DLR)
|
||||
GNU nano 1.1.9 - 05/12/2002
|
||||
- General:
|
||||
- Typos n misspellings all over the place (David Benbennick).
|
||||
@ -963,7 +1080,7 @@ nano-1.1.0 - 07/15/2001
|
||||
- Moved extension functions (Case Sensitive, Regexp, and Backwards
|
||||
Search, Append key in write file function) to Meta keys, as
|
||||
people are complaining loudly about nano not being control-key
|
||||
compatible with Pico, which is a Bag Thing (TM). Changes to
|
||||
compatible with Pico, which is a Bad Thing (TM). Changes to
|
||||
shortcut_init, toggle_init, new toggles for backwards and regexp
|
||||
(and you can now toggle all search options including regexp at
|
||||
the Search: prompt!) Changes to nanogetstr to enable Meta
|
||||
@ -1420,7 +1537,7 @@ General
|
||||
by Rocco Corsi.
|
||||
help_init()
|
||||
- Fix off by one error that was making ^G help in normal mode and
|
||||
^_ in pico mode not be displayed in the help (bug discovered by
|
||||
^_ in Pico mode not be displayed in the help (bug discovered by
|
||||
Rocco Corsi).
|
||||
do_toggle()
|
||||
- Added fix_editbot() call to fix improper redisplay of edit
|
||||
@ -2248,10 +2365,10 @@ nano-0.9.3 - 04/29/2000
|
||||
nano-0.9.2 - 04/15/2000
|
||||
- This release just fixes the serious segfault problem if nano is
|
||||
invoked any way other than using the absolute path. The bug was
|
||||
in the new code for checking whether nano is invoked as pico.
|
||||
in the new code for checking whether nano is invoked as 'pico'.
|
||||
|
||||
nano-0.9.1 - 04/14/2000
|
||||
- Added pico compatibility for ^T when in search or switch to switch
|
||||
- Added Pico compatibility for ^T when in search or switch to switch
|
||||
to the opposite function. Added one to REPLACE_LIST_LEN and
|
||||
WHEREIS_LIST_LEN in nano.h, new args to sc_init_one in global.c and
|
||||
new strings that will have to be gettext()ed. New argument 'replacing'
|
||||
@ -2373,7 +2490,7 @@ nano-0.8.4 - 02/11/2000
|
||||
- README: Updated my email address and the nano web page.
|
||||
|
||||
nano-0.8.3 - 02/08/2000
|
||||
- New pico mode (-p, --pico), toggles (more) compatibility with the
|
||||
- New Pico mode (-p, --pico), toggles (more) compatibility with the
|
||||
Pico messages displayed in the shortcut list. Note that there are still
|
||||
small differences in this mode.
|
||||
- nano.h: New shortcut struct format, for the benefit of i18n and
|
||||
|
6
NEWS
6
NEWS
@ -221,7 +221,7 @@
|
||||
The --nofollow option also works again for those who
|
||||
are real security nuts. There are also some display and
|
||||
search fixes, and the --disable-spell function was renamed
|
||||
to --disable-speller to be in line with nano and pico's
|
||||
to --disable-speller to be in line with nano and Pico's
|
||||
"speller" term.
|
||||
|
||||
12/02/2000 - Nano 0.9.22 is released, with many more changes and
|
||||
@ -416,13 +416,13 @@
|
||||
04/15/2000 - Nano 0.9.2 just fixes the serious segfault problem if
|
||||
nano is invoked any way other than using the absolute
|
||||
path. The bug was in the new code for checking whether
|
||||
nano is invoked as pico.
|
||||
nano is invoked as 'pico'.
|
||||
|
||||
04/14/2000 - 0.9.1 has some more Pico compatibility built-in. The
|
||||
option to switch to/from Search and Search/Replace
|
||||
(^T) is now available, and nano now displays the
|
||||
more Pico-like shortcut list when invoked as 'pico'
|
||||
(i.e. if pico is a symlink to nano). There is an
|
||||
(i.e. if 'pico' is a symlink to nano). There is an
|
||||
important change to the handling of symbolic links
|
||||
as well. Now, nano does the "correct" thing and
|
||||
automatically writes to the object of the symlink,
|
||||
|
2
THANKS
2
THANKS
@ -1,5 +1,5 @@
|
||||
The following people have helped GNU nano in some way or another.
|
||||
If we missed you here, let us now!
|
||||
If we missed you here, let us know!
|
||||
|
||||
Sharuzzaman Ahmat Raslan <sharuzzaman@excite.com>
|
||||
Bahasa Melayu Translator
|
||||
|
94
color.c
94
color.c
@ -21,8 +21,6 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
@ -33,6 +31,8 @@
|
||||
#include "proto.h"
|
||||
#include "nano.h"
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
|
||||
#ifdef ENABLE_NLS
|
||||
#include <libintl.h>
|
||||
#define _(string) gettext(string)
|
||||
@ -40,62 +40,7 @@
|
||||
#define _(string) (string)
|
||||
#endif
|
||||
|
||||
void color_on(WINDOW *win, int whatever)
|
||||
{
|
||||
/* Temporary fallback, if the color value hasn't been set,
|
||||
turn on highlighting */
|
||||
if (!colors[whatever - FIRST_COLORNUM].set) {
|
||||
wattron(win, A_REVERSE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (colors[whatever - FIRST_COLORNUM].bold)
|
||||
wattron(win, A_BOLD);
|
||||
|
||||
/* If the foreground color is black, we've switched fg and bg (see
|
||||
the comment in colorinit_one() about this) so turn on reverse so
|
||||
it looks like it's supposed to */
|
||||
if (colors[whatever - FIRST_COLORNUM].fg == COLOR_BLACK)
|
||||
wattron(win, A_REVERSE);
|
||||
|
||||
wattron(win, COLOR_PAIR(whatever));
|
||||
|
||||
}
|
||||
|
||||
void color_off(WINDOW *win, int whatever)
|
||||
{
|
||||
if (!colors[whatever - FIRST_COLORNUM].set) {
|
||||
wattroff(win, A_REVERSE);
|
||||
return;
|
||||
}
|
||||
|
||||
wattroff(win, COLOR_PAIR(whatever));
|
||||
|
||||
if (colors[whatever - FIRST_COLORNUM].fg == COLOR_BLACK)
|
||||
wattroff(win, A_REVERSE);
|
||||
|
||||
if (colors[whatever - FIRST_COLORNUM].bold)
|
||||
wattroff(win, A_BOLD);
|
||||
}
|
||||
|
||||
void colorinit_one(int colortoset, short fg, short bg, int bold)
|
||||
{
|
||||
colors[colortoset - FIRST_COLORNUM].fg = fg;
|
||||
colors[colortoset - FIRST_COLORNUM].bg = bg;
|
||||
colors[colortoset - FIRST_COLORNUM].bold = bold;
|
||||
colors[colortoset - FIRST_COLORNUM].set = 1;
|
||||
|
||||
/* Okay, so if they want a black foreground, do a switch on the fg
|
||||
and bg, because specifying black as the foreground color gives
|
||||
this ugly grey color. Then in color_on we will turn A_REVERSE
|
||||
which is probably what they want it to look like... */
|
||||
if (fg == COLOR_BLACK)
|
||||
init_pair(colortoset, bg, fg);
|
||||
else
|
||||
init_pair(colortoset, fg, bg);
|
||||
}
|
||||
|
||||
int do_colorinit(void)
|
||||
void do_colorinit(void)
|
||||
{
|
||||
int i;
|
||||
colortype *tmpcolor = NULL, *beforenow = NULL;
|
||||
@ -142,38 +87,7 @@ int do_colorinit(void)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if (use_default_colors() != ERR) {
|
||||
init_pair(COLOR_BLACK, -1, -1);
|
||||
init_pair(COLOR_GREEN, COLOR_GREEN, -1);
|
||||
init_pair(COLOR_WHITE, COLOR_WHITE, -1);
|
||||
init_pair(COLOR_RED, COLOR_RED, -1);
|
||||
init_pair(COLOR_CYAN, COLOR_CYAN, -1);
|
||||
init_pair(COLOR_MAGENTA, COLOR_MAGENTA, -1);
|
||||
init_pair(COLOR_BLUE, COLOR_BLUE, -1);
|
||||
init_pair(COLOR_YELLOW, COLOR_YELLOW, -1);
|
||||
|
||||
} else {
|
||||
init_pair(COLOR_BLACK, COLOR_BLACK, COLOR_BLACK);
|
||||
init_pair(COLOR_GREEN, COLOR_GREEN, COLOR_BLACK);
|
||||
init_pair(COLOR_WHITE, COLOR_WHITE, COLOR_BLACK);
|
||||
init_pair(COLOR_RED, COLOR_RED, COLOR_BLACK);
|
||||
init_pair(COLOR_CYAN, COLOR_CYAN, COLOR_BLACK);
|
||||
init_pair(COLOR_MAGENTA, COLOR_MAGENTA, COLOR_BLACK);
|
||||
init_pair(COLOR_BLUE, COLOR_BLUE, COLOR_BLACK);
|
||||
init_pair(COLOR_YELLOW, COLOR_YELLOW, COLOR_BLACK);
|
||||
}
|
||||
*/
|
||||
|
||||
/* Okay I'll be nice and comment these out for the commit =)
|
||||
colorinit_one(COLOR_TITLEBAR, COLOR_GREEN, COLOR_BLUE, 1);
|
||||
colorinit_one(COLOR_BOTTOMBARS, COLOR_GREEN, COLOR_BLUE, 1);
|
||||
colorinit_one(COLOR_STATUSBAR, COLOR_BLACK, COLOR_CYAN, 0);
|
||||
colorinit_one(COLOR_TEXT, COLOR_WHITE, COLOR_BLACK, 0);
|
||||
colorinit_one(COLOR_MARKER, COLOR_BLACK, COLOR_CYAN, 0);
|
||||
}
|
||||
*/
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Update the color information based on the current filename */
|
||||
|
22
configure.ac
22
configure.ac
@ -17,10 +17,18 @@ dnl Checks for header files.
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS(fcntl.h unistd.h malloc.h termios.h termio.h limits.h getopt.h regex.h)
|
||||
|
||||
dnl Turn off assert statements.
|
||||
AC_DEFINE(NDEBUG, 1, [Shut up the assert warnings :-)])
|
||||
|
||||
dnl options
|
||||
AC_ARG_ENABLE(debug,
|
||||
[ --enable-debug Enable debugging (disabled by default)],
|
||||
[if test x$enableval = xyes; then
|
||||
AC_DEFINE(DEBUG, 1, [Define this to enable nano debug messages and assert warnings.])
|
||||
debug_support=yes
|
||||
fi])
|
||||
|
||||
if test "$debug_support" != "yes"; then
|
||||
AC_DEFINE(NDEBUG, 1, [Shut up the assert warnings :-)])
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(tiny,
|
||||
[ --enable-tiny Disable features for the sake of size
|
||||
(currently disables detailed help and i18n)],
|
||||
@ -31,8 +39,8 @@ AC_ARG_ENABLE(tiny,
|
||||
AC_DEFINE(DISABLE_HELP, 1, [Define this to disable the ^G help menu.])
|
||||
AC_DEFINE(DISABLE_JUSTIFY, 1, [Define this to disable the justify routine.])
|
||||
AC_DEFINE(DISABLE_BROWSER, 1, [Define this to disable the built-in (crappy) file browser.])
|
||||
AC_DEFINE(DISABLE_MOUSE, 1, [Define this to disable the mouse functions.])
|
||||
AC_DEFINE(DISABLE_OPERATINGDIR, 1, [Define this to disable setting of the operating directory (chroot of sorts).])
|
||||
AC_DEFINE(DISABLE_MOUSE, 1, [Define this to disable the mouse functions.])
|
||||
AC_DEFINE(DISABLE_OPERATINGDIR, 1, [Define this to disable setting of the operating directory (chroot of sorts).])
|
||||
fi])
|
||||
|
||||
AC_ARG_ENABLE(extra,
|
||||
@ -118,7 +126,7 @@ AC_ARG_ENABLE(mouse,
|
||||
fi])
|
||||
|
||||
AC_ARG_ENABLE(operatingdir,
|
||||
[ --disable-operatingdir Disable setting of operating directory (chroot of sorts)],
|
||||
[ --disable-operatingdir Disable setting of operating directory (chroot of sorts)],
|
||||
[if test x$enableval != xyes; then
|
||||
AC_DEFINE(DISABLE_OPERATINGDIR, 1, [Define this to disable setting of the operating directory (chroot of sorts).])
|
||||
fi])
|
||||
@ -296,8 +304,6 @@ dnl Parse any configure options
|
||||
|
||||
LIBS="$LIBS $CURSES_LIB"
|
||||
|
||||
AC_ARG_ENABLE(debug, [ --enable-debug Enable debugging (def disabled)],)
|
||||
|
||||
AC_SUBST(CURSES_LIB)
|
||||
|
||||
if test "x$glib_cflags" != "x"
|
||||
|
439
cut.c
439
cut.c
@ -24,6 +24,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include "proto.h"
|
||||
#include "nano.h"
|
||||
|
||||
@ -34,17 +35,21 @@
|
||||
#define _(string) (string)
|
||||
#endif
|
||||
|
||||
static int marked_cut; /* Is the cutbuffer from a mark */
|
||||
static filestruct *cutbottom = NULL; /* Pointer to end of cutbuffer */
|
||||
static int marked_cut; /* Is the cutbuffer from a mark? */
|
||||
static filestruct *cutbottom = NULL; /* Pointer to end of cutbuffer */
|
||||
|
||||
void add_to_cutbuffer(filestruct * inptr)
|
||||
filestruct *get_cutbottom(void)
|
||||
{
|
||||
return cutbottom;
|
||||
}
|
||||
|
||||
void add_to_cutbuffer(filestruct *inptr)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, _("add_to_cutbuffer called with inptr->data = %s\n"),
|
||||
inptr->data);
|
||||
#endif
|
||||
|
||||
totsize -= strlen(inptr->data);
|
||||
if (cutbuffer == NULL) {
|
||||
cutbuffer = inptr;
|
||||
inptr->prev = NULL;
|
||||
@ -58,186 +63,168 @@ void add_to_cutbuffer(filestruct * inptr)
|
||||
}
|
||||
|
||||
#ifndef NANO_SMALL
|
||||
/* Cut a marked segment instead of a whole line. Only called from
|
||||
do_cut_text().
|
||||
destructive is whether to actually modify the file structure, if not then
|
||||
just copy the buffer into cutbuffer and don't pull it from the file */
|
||||
|
||||
void cut_marked_segment(filestruct * top, int top_x, filestruct * bot,
|
||||
int bot_x, int destructive)
|
||||
/* Cut a marked segment instead of a whole line.
|
||||
* The first cut character is top->data[top_x]. Unless top == bot, the
|
||||
* last cut line has length bot_x. That is, if bot_x > 0 then we cut to
|
||||
* bot->data[bot_x - 1].
|
||||
*
|
||||
* destructive is whether to actually modify the file structure, if not
|
||||
* then just copy the buffer into cutbuffer and don't pull it from the
|
||||
* file.
|
||||
*
|
||||
* If destructive, then we maintain totsize, totlines, filebot, the
|
||||
* magic line, and line numbers. Also, we set current and current_x so
|
||||
* the cursor will be on the first character after what was cut. We do
|
||||
* not do any screen updates. */
|
||||
void cut_marked_segment(filestruct *top, size_t top_x, filestruct *bot,
|
||||
size_t bot_x, int destructive)
|
||||
{
|
||||
filestruct *tmp, *next, *botcopy;
|
||||
char *tmpstr;
|
||||
int newsize;
|
||||
filestruct *tmp, *next;
|
||||
size_t newsize;
|
||||
|
||||
if (top == bot && top_x == bot_x)
|
||||
return;
|
||||
assert(top != NULL && bot != NULL);
|
||||
|
||||
/* Make top be no later than bot. */
|
||||
if (top->lineno > bot->lineno) {
|
||||
filestruct *swap = top;
|
||||
int swap2 = top_x;
|
||||
|
||||
top = bot;
|
||||
bot = swap;
|
||||
|
||||
top_x = bot_x;
|
||||
bot_x = swap2;
|
||||
} else if (top == bot && top_x > bot_x) {
|
||||
/* And bot_x can't be an earlier character than top_x. */
|
||||
int swap = top_x;
|
||||
|
||||
top_x = bot_x;
|
||||
bot_x = swap;
|
||||
}
|
||||
|
||||
/* Make the first cut line manually. */
|
||||
tmp = copy_node(top);
|
||||
newsize = (top == bot ? bot_x - top_x : strlen(top->data + top_x));
|
||||
memmove(tmp->data, top->data + top_x, newsize);
|
||||
null_at(&tmp->data, newsize);
|
||||
add_to_cutbuffer(tmp);
|
||||
|
||||
/* And make the remainder line manually too. */
|
||||
if (destructive) {
|
||||
current_x = top_x;
|
||||
totsize -= newsize;
|
||||
totlines -= bot->lineno - top->lineno;
|
||||
|
||||
newsize = top_x + strlen(bot->data + bot_x) + 1;
|
||||
if (top == bot) {
|
||||
/* In this case, the remainder line is shorter, so we must
|
||||
move text from the end forward first. */
|
||||
memmove(top->data + top_x, bot->data + bot_x,
|
||||
newsize - top_x);
|
||||
top->data = (char *)nrealloc(top->data,
|
||||
sizeof(char) * newsize);
|
||||
} else {
|
||||
totsize -= bot_x;
|
||||
|
||||
/* Here, the remainder line might get longer, so we realloc
|
||||
it first. */
|
||||
top->data = (char *)nrealloc(top->data,
|
||||
sizeof(char) * newsize);
|
||||
memmove(top->data + top_x, bot->data + bot_x,
|
||||
newsize - top_x);
|
||||
}
|
||||
}
|
||||
|
||||
/* Special case for cutting part of one line */
|
||||
if (top == bot) {
|
||||
int swap;
|
||||
|
||||
tmp = copy_node(top);
|
||||
newsize = abs(bot_x - top_x) + 1;
|
||||
tmpstr = charalloc(newsize + 1);
|
||||
|
||||
/* Make top_x always be before bot_x */
|
||||
if (top_x > bot_x) {
|
||||
swap = top_x;
|
||||
top_x = bot_x;
|
||||
bot_x = swap;
|
||||
}
|
||||
|
||||
strncpy(tmpstr, &top->data[top_x], newsize);
|
||||
|
||||
if (destructive) {
|
||||
memmove(&top->data[top_x], &top->data[bot_x],
|
||||
strlen(&top->data[bot_x]) + 1);
|
||||
align(&top->data);
|
||||
current_x = top_x;
|
||||
update_cursor();
|
||||
}
|
||||
tmpstr[newsize - 1] = '\0';
|
||||
tmp->data = tmpstr;
|
||||
add_to_cutbuffer(tmp);
|
||||
#ifdef DEBUG
|
||||
dump_buffer(cutbuffer);
|
||||
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set up the beginning of the cutbuffer */
|
||||
tmp = copy_node(top);
|
||||
tmpstr = charalloc(strlen(&top->data[top_x]) + 1);
|
||||
strcpy(tmpstr, &top->data[top_x]);
|
||||
free(tmp->data);
|
||||
tmp->data = tmpstr;
|
||||
|
||||
/* Chop off the end of the first line */
|
||||
tmpstr = charalloc(top_x + 1);
|
||||
strncpy(tmpstr, top->data, top_x);
|
||||
|
||||
if (destructive) {
|
||||
free(top->data);
|
||||
top->data = tmpstr;
|
||||
}
|
||||
|
||||
do {
|
||||
tmp = top->next;
|
||||
while (tmp != bot) {
|
||||
next = tmp->next;
|
||||
if (destructive)
|
||||
add_to_cutbuffer(tmp);
|
||||
else {
|
||||
filestruct *tmpcopy = NULL;
|
||||
|
||||
tmpcopy = copy_node(tmp);
|
||||
add_to_cutbuffer(tmpcopy);
|
||||
}
|
||||
totlines--;
|
||||
totsize--; /* newline (add_to_cutbuffer doesn't count newlines) */
|
||||
if (!destructive)
|
||||
tmp = copy_node(tmp);
|
||||
else
|
||||
totsize -= strlen(tmp->data);
|
||||
add_to_cutbuffer(tmp);
|
||||
tmp = next;
|
||||
}
|
||||
while (next != bot && next != NULL);
|
||||
|
||||
/* Make the last cut line manually. */
|
||||
tmp = copy_node(bot);
|
||||
null_at(&tmp->data, bot_x);
|
||||
add_to_cutbuffer(tmp);
|
||||
#ifdef DEBUG
|
||||
dump_buffer(cutbuffer);
|
||||
if (next == NULL)
|
||||
return;
|
||||
|
||||
/* Now, paste bot[bot_x] into top[top_x] */
|
||||
if (destructive) {
|
||||
|
||||
tmpstr = charalloc(top_x + strlen(&bot->data[bot_x]) + 1);
|
||||
strncpy(tmpstr, top->data, top_x);
|
||||
strcpy(&tmpstr[top_x], &bot->data[bot_x]);
|
||||
free(top->data);
|
||||
top->data = tmpstr;
|
||||
|
||||
/* We explicitly don't decrement totlines here because we don't snarf
|
||||
* up a newline when we're grabbing the last line of the mark. For
|
||||
* the same reason, we don't do an extra totsize decrement. */
|
||||
}
|
||||
|
||||
/* I honestly do not know why this is needed. After many hours of
|
||||
using gdb on an OpenBSD box, I can honestly say something is
|
||||
screwed somewhere. Not doing this causes update_line to annihilate
|
||||
the last line copied into the cutbuffer when the mark is set ?!?!? */
|
||||
botcopy = copy_node(bot);
|
||||
null_at(&botcopy->data, bot_x);
|
||||
next = botcopy->next;
|
||||
add_to_cutbuffer(botcopy);
|
||||
|
||||
#endif
|
||||
|
||||
if (destructive) {
|
||||
free(bot);
|
||||
|
||||
top->next = next;
|
||||
if (next != NULL)
|
||||
next->prev = top;
|
||||
|
||||
dump_buffer(cutbuffer);
|
||||
top->next = bot->next;
|
||||
if (top->next != NULL)
|
||||
top->next->prev = top;
|
||||
delete_node(bot);
|
||||
renumber(top);
|
||||
current = top;
|
||||
current_x = top_x;
|
||||
|
||||
/* If we're hitting the end of the buffer, we should clean that up. */
|
||||
if (bot == filebot) {
|
||||
if (next != NULL) {
|
||||
filebot = next;
|
||||
} else {
|
||||
filebot = top;
|
||||
if (top_x > 0)
|
||||
new_magicline();
|
||||
}
|
||||
filebot = top;
|
||||
assert(bot_x == 0);
|
||||
if (top_x > 0)
|
||||
new_magicline();
|
||||
}
|
||||
if (top->lineno < edittop->lineno)
|
||||
edit_update(top, CENTER);
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
int do_cut_text(void)
|
||||
{
|
||||
filestruct *tmp, *fileptr = current;
|
||||
filestruct *fileptr;
|
||||
#ifndef NANO_SMALL
|
||||
int dontupdate = 0;
|
||||
int cuttingtoend = 0;
|
||||
#endif
|
||||
|
||||
assert(current != NULL && current->data != NULL);
|
||||
|
||||
check_statblank();
|
||||
if (fileptr == NULL || fileptr->data == NULL)
|
||||
return 0;
|
||||
|
||||
tmp = fileptr->next;
|
||||
|
||||
if (!ISSET(KEEP_CUTBUFFER)) {
|
||||
free_filestruct(cutbuffer);
|
||||
cutbuffer = NULL;
|
||||
|
||||
marked_cut = 0;
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, _("Blew away cutbuffer =)\n"));
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Must let cutbuffer get blown away first before we do this... */
|
||||
if (fileptr == filebot && !ISSET(MARK_ISSET))
|
||||
/* You can't cut the magic line except with the mark. But
|
||||
trying does clear the cutbuffer if KEEP_CUTBUFFER is not set. */
|
||||
if (current == filebot
|
||||
#ifndef NANO_SMALL
|
||||
&& !ISSET(MARK_ISSET)
|
||||
#endif
|
||||
)
|
||||
return 0;
|
||||
|
||||
#ifndef NANO_SMALL
|
||||
if (ISSET(CUT_TO_END) && !ISSET(MARK_ISSET)) {
|
||||
if (current_x == strlen(current->data)) {
|
||||
assert(current_x >= 0 && current_x <= strlen(current->data));
|
||||
|
||||
/* If the line is empty and we didn't just cut a non-blank
|
||||
line, create a dummy line and add it to the cutbuffer */
|
||||
if (current->data[current_x] == '\0') {
|
||||
/* If the line is empty and we didn't just cut a non-blank
|
||||
line, create a dummy line and add it to the cutbuffer */
|
||||
if (marked_cut != 1 && current->next != filebot) {
|
||||
filestruct *junk = make_new_node(current);
|
||||
|
||||
filestruct *junk;
|
||||
|
||||
junk = NULL;
|
||||
junk = make_new_node(current);
|
||||
junk->data = charalloc(1);
|
||||
junk->data[0] = '\0';
|
||||
|
||||
add_to_cutbuffer(junk);
|
||||
#ifdef DEBUG
|
||||
dump_buffer(cutbuffer);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
do_delete();
|
||||
@ -250,104 +237,69 @@ int do_cut_text(void)
|
||||
|
||||
mark_beginx = strlen(current->data);
|
||||
mark_beginbuf = current;
|
||||
cuttingtoend = 1;
|
||||
dontupdate = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ISSET(MARK_ISSET)) {
|
||||
if (current->lineno <= mark_beginbuf->lineno) {
|
||||
/* Don't do_update and move the screen position if the marked
|
||||
area lies entirely within the screen buffer */
|
||||
if (current->lineno == mark_beginbuf->lineno
|
||||
|| (current->lineno >= edittop->lineno
|
||||
&& mark_beginbuf->lineno <= editbot->lineno))
|
||||
dontupdate = 1;
|
||||
|
||||
cut_marked_segment(current, current_x, mark_beginbuf,
|
||||
mark_beginx, 1);
|
||||
}
|
||||
else {
|
||||
/* Same as above, easier logic since we know it's a multi-line
|
||||
cut and mark_beginbuf is before current */
|
||||
if (mark_beginbuf->lineno >= edittop->lineno
|
||||
&& current->lineno <= editbot->lineno)
|
||||
dontupdate = 1;
|
||||
|
||||
cut_marked_segment(mark_beginbuf, mark_beginx, current,
|
||||
current_x, 1);
|
||||
}
|
||||
|
||||
/* Don't do_update() and move the screen position if the marked
|
||||
area lies entirely within the screen buffer */
|
||||
dontupdate |= current->lineno >= edittop->lineno &&
|
||||
current->lineno <= editbot->lineno &&
|
||||
mark_beginbuf->lineno >= edittop->lineno &&
|
||||
mark_beginbuf->lineno <= editbot->lineno;
|
||||
cut_marked_segment(current, current_x, mark_beginbuf,
|
||||
mark_beginx, 1);
|
||||
|
||||
placewewant = xplustabs();
|
||||
UNSET(MARK_ISSET);
|
||||
|
||||
marked_cut = 1;
|
||||
set_modified();
|
||||
if (dontupdate || cuttingtoend) {
|
||||
if (dontupdate) {
|
||||
fix_editbot();
|
||||
edit_refresh();
|
||||
} else
|
||||
edit_update(current, CENTER);
|
||||
|
||||
return 1;
|
||||
#else
|
||||
if (0) {
|
||||
#endif
|
||||
} else if (fileptr == fileage) {
|
||||
/* we're cutting the first line */
|
||||
if (fileptr->next != NULL) {
|
||||
fileptr = fileptr->next;
|
||||
tmp = fileptr;
|
||||
fileage = fileptr;
|
||||
add_to_cutbuffer(fileptr->prev);
|
||||
totsize--; /* get the newline */
|
||||
totlines--;
|
||||
fileptr->prev = NULL;
|
||||
current = fileptr;
|
||||
edit_update(fileage, CENTER);
|
||||
} else {
|
||||
add_to_cutbuffer(fileptr);
|
||||
fileage = make_new_node(NULL);
|
||||
fileage->data = charalloc(1);
|
||||
fileage->data[0] = '\0';
|
||||
current = fileage;
|
||||
}
|
||||
} else {
|
||||
if (fileptr->prev != NULL)
|
||||
fileptr->prev->next = fileptr->next;
|
||||
|
||||
if (fileptr->next != NULL) {
|
||||
(fileptr->next)->prev = fileptr->prev;
|
||||
current = fileptr->next;
|
||||
totlines--;
|
||||
totsize--; /* get the newline */
|
||||
}
|
||||
/* No longer an else here, because we never get here anymore...
|
||||
No need to cut the magic line, as it's empty */
|
||||
add_to_cutbuffer(fileptr);
|
||||
}
|
||||
#endif /* !NANO_SMALL */
|
||||
|
||||
totlines--;
|
||||
totsize -= strlen(current->data) + 1;
|
||||
fileptr = current;
|
||||
current = current->next;
|
||||
current->prev = fileptr->prev;
|
||||
add_to_cutbuffer(fileptr);
|
||||
#ifdef DEBUG
|
||||
dump_buffer(cutbuffer);
|
||||
#endif
|
||||
|
||||
if (fileptr == fileage)
|
||||
fileage = current;
|
||||
else
|
||||
current->prev->next = current;
|
||||
|
||||
if (fileptr == edittop)
|
||||
edittop = current;
|
||||
|
||||
renumber(current);
|
||||
edit_refresh();
|
||||
|
||||
dump_buffer(cutbuffer);
|
||||
reset_cursor();
|
||||
|
||||
set_modified();
|
||||
marked_cut = 0;
|
||||
current_x = 0;
|
||||
placewewant = 0;
|
||||
update_cursor();
|
||||
renumber(tmp);
|
||||
reset_cursor();
|
||||
SET(KEEP_CUTBUFFER);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int do_uncut_text(void)
|
||||
{
|
||||
filestruct *tmp = current, *fileptr = current, *newbuf, *newend;
|
||||
filestruct *tmp = current, *fileptr = current;
|
||||
filestruct *newbuf = NULL;
|
||||
filestruct *newend = NULL;
|
||||
#ifndef NANO_SMALL
|
||||
char *tmpstr, *tmpstr2;
|
||||
filestruct *hold = current;
|
||||
@ -359,29 +311,35 @@ int do_uncut_text(void)
|
||||
if (cutbuffer == NULL || fileptr == NULL)
|
||||
return 0; /* AIEEEEEEEEEEEE */
|
||||
|
||||
newbuf = copy_filestruct(cutbuffer);
|
||||
for (newend = newbuf; newend->next != NULL && newend != NULL;
|
||||
newend = newend->next) {
|
||||
totlines++;
|
||||
#ifndef NANO_SMALL
|
||||
if (!marked_cut || cutbuffer->next != NULL)
|
||||
#endif
|
||||
{
|
||||
newbuf = copy_filestruct(cutbuffer);
|
||||
for (newend = newbuf; newend->next != NULL && newend != NULL;
|
||||
newend = newend->next)
|
||||
totlines++;
|
||||
}
|
||||
|
||||
/* Hook newbuf into fileptr */
|
||||
#ifndef NANO_SMALL
|
||||
if (marked_cut) {
|
||||
int recenter_me = 0;
|
||||
/* Should we eventually use edit_update(CENTER)? */
|
||||
|
||||
/* If there's only one line in the cutbuffer */
|
||||
if (cutbuffer->next == NULL) {
|
||||
tmpstr =
|
||||
charalloc(strlen(current->data) + strlen(cutbuffer->data) +
|
||||
1);
|
||||
strncpy(tmpstr, current->data, current_x);
|
||||
strcpy(&tmpstr[current_x], cutbuffer->data);
|
||||
strcat(tmpstr, ¤t->data[current_x]);
|
||||
free(current->data);
|
||||
current->data = tmpstr;
|
||||
current_x += strlen(cutbuffer->data);
|
||||
totsize += strlen(cutbuffer->data);
|
||||
if (strlen(cutbuffer->data) == 0)
|
||||
totlines++;
|
||||
size_t buf_len = strlen(cutbuffer->data);
|
||||
size_t cur_len = strlen(current->data);
|
||||
|
||||
current->data = nrealloc(current->data, cur_len + buf_len + 1);
|
||||
memmove(current->data + current_x + buf_len,
|
||||
current->data + current_x, cur_len - current_x + 1);
|
||||
strncpy(current->data + current_x, cutbuffer->data, buf_len);
|
||||
/* Use strncpy to not copy the terminal '\0'. */
|
||||
|
||||
current_x += buf_len;
|
||||
totsize += buf_len;
|
||||
/* If we've uncut a line, make sure there's a magicline after
|
||||
it */
|
||||
if (current->next == NULL)
|
||||
@ -417,8 +375,8 @@ int do_uncut_text(void)
|
||||
newend->next = tmp;
|
||||
|
||||
/* If tmp isn't null, we're in the middle: update the
|
||||
* prev pointer. If it IS null, we're at the end; update
|
||||
* the filebot pointer */
|
||||
prev pointer. If it IS null, we're at the end; update
|
||||
the filebot pointer */
|
||||
|
||||
if (tmp != NULL)
|
||||
tmp->prev = newend;
|
||||
@ -434,21 +392,16 @@ int do_uncut_text(void)
|
||||
for (tmp = current->next; tmp != newend; tmp = tmp->next)
|
||||
totsize += strlen(tmp->data) + 1;
|
||||
|
||||
i = editbot->lineno;
|
||||
|
||||
current = newend;
|
||||
if (i < newend->lineno) {
|
||||
edit_update(current, CENTER);
|
||||
}
|
||||
else {
|
||||
edit_refresh();
|
||||
}
|
||||
if (editbot->lineno < newend->lineno)
|
||||
recenter_me = 1;
|
||||
}
|
||||
|
||||
/* If marked cut == 2, that means that we're doing a cut to end
|
||||
and we don't want anything else on the line, so we have to
|
||||
screw up all the work we just did and separate the line. There
|
||||
must be a better way to do this, but not at 1AM on a work night. */
|
||||
screw up all the work we just did and separate the line.
|
||||
There must be a better way to do this, but not at 1AM on a
|
||||
work night. */
|
||||
|
||||
if (marked_cut == 2) {
|
||||
tmp = make_new_node(current);
|
||||
@ -467,24 +420,27 @@ int do_uncut_text(void)
|
||||
/* Renumber from BEFORE where we pasted ;) */
|
||||
renumber(hold);
|
||||
|
||||
#ifdef DEBUG
|
||||
dump_buffer(fileage);
|
||||
dump_buffer(cutbuffer);
|
||||
#endif
|
||||
set_modified();
|
||||
edit_refresh();
|
||||
if (recenter_me)
|
||||
edit_update(current, CENTER);
|
||||
else
|
||||
edit_refresh();
|
||||
UNSET(KEEP_CUTBUFFER);
|
||||
return 0;
|
||||
#else
|
||||
if (0) {
|
||||
}
|
||||
#endif
|
||||
} else if (fileptr != fileage) {
|
||||
|
||||
if (fileptr != fileage) {
|
||||
tmp = fileptr->prev;
|
||||
tmp->next = newbuf;
|
||||
newbuf->prev = tmp;
|
||||
totlines++; /* Unmarked uncuts don't split lines */
|
||||
} else {
|
||||
} else
|
||||
fileage = newbuf;
|
||||
totlines++; /* Unmarked uncuts don't split lines */
|
||||
}
|
||||
totlines++; /* Unmarked uncuts don't split lines */
|
||||
|
||||
/* This is so uncutting at the top of the buffer will work => */
|
||||
if (current_y == 0)
|
||||
@ -494,23 +450,22 @@ int do_uncut_text(void)
|
||||
newend->next = fileptr;
|
||||
fileptr->prev = newend;
|
||||
|
||||
/* recalculate size *sigh* */
|
||||
/* Recalculate size *sigh* */
|
||||
for (tmp = newbuf; tmp != fileptr; tmp = tmp->next)
|
||||
totsize += strlen(tmp->data) + 1;
|
||||
|
||||
i = editbot->lineno;
|
||||
renumber(newbuf);
|
||||
if (i < newend->lineno) {
|
||||
if (i < newend->lineno)
|
||||
edit_update(fileptr, CENTER);
|
||||
}
|
||||
else {
|
||||
else
|
||||
edit_refresh();
|
||||
}
|
||||
|
||||
dump_buffer_reverse(fileptr);
|
||||
#ifdef DEBUG
|
||||
dump_buffer_reverse();
|
||||
#endif
|
||||
|
||||
set_modified();
|
||||
UNSET(KEEP_CUTBUFFER);
|
||||
edit_refresh();
|
||||
return 1;
|
||||
}
|
||||
|
2
faq.html
2
faq.html
@ -474,7 +474,7 @@ to have a completely consistent user interface across all user input
|
||||
functions. This means that regardless of whether you're being asked for
|
||||
a filename to insert or write, or a string to search for, the
|
||||
previous value is already inserted before the cursor. If you prefer the
|
||||
old behavior, use the pico emulation mode (-p or --pico) or just hit
|
||||
old behavior, use the Pico emulation mode (-p or --pico) or just hit
|
||||
Meta-P while in nano (see the ^G help text for more
|
||||
details).</font></blockquote>
|
||||
|
||||
|
83
files.c
83
files.c
@ -33,6 +33,7 @@
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <dirent.h>
|
||||
#include <assert.h>
|
||||
#include <pwd.h>
|
||||
#include "proto.h"
|
||||
#include "nano.h"
|
||||
@ -501,7 +502,9 @@ int do_insertfile(int loading_file)
|
||||
|
||||
free(realname);
|
||||
|
||||
#ifdef DEBUG
|
||||
dump_buffer(fileage);
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
if (loading_file)
|
||||
@ -578,6 +581,75 @@ int do_insertfile_void(void)
|
||||
}
|
||||
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
/* Create a new openfilestruct node. */
|
||||
openfilestruct *make_new_opennode(openfilestruct *prevnode)
|
||||
{
|
||||
openfilestruct *newnode = nmalloc(sizeof(openfilestruct));
|
||||
|
||||
newnode->filename = NULL;
|
||||
newnode->fileage = NULL;
|
||||
newnode->filebot = NULL;
|
||||
|
||||
newnode->prev = prevnode;
|
||||
newnode->next = NULL;
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
/* Splice a node into an existing openfilestruct. */
|
||||
void splice_opennode(openfilestruct *begin, openfilestruct *newnode,
|
||||
openfilestruct *end)
|
||||
{
|
||||
newnode->next = end;
|
||||
newnode->prev = begin;
|
||||
begin->next = newnode;
|
||||
if (end != NULL)
|
||||
end->prev = newnode;
|
||||
}
|
||||
|
||||
/* Unlink a node from the rest of the openfilestruct. */
|
||||
void unlink_opennode(const openfilestruct *fileptr)
|
||||
{
|
||||
assert(fileptr != NULL);
|
||||
|
||||
if (fileptr->prev != NULL)
|
||||
fileptr->prev->next = fileptr->next;
|
||||
|
||||
if (fileptr->next != NULL)
|
||||
fileptr->next->prev = fileptr->prev;
|
||||
}
|
||||
|
||||
/* Delete a node from the openfilestruct. */
|
||||
void delete_opennode(openfilestruct *fileptr)
|
||||
{
|
||||
if (fileptr != NULL) {
|
||||
if (fileptr->filename != NULL)
|
||||
free(fileptr->filename);
|
||||
if (fileptr->fileage != NULL)
|
||||
free_filestruct(fileptr->fileage);
|
||||
free(fileptr);
|
||||
}
|
||||
}
|
||||
|
||||
/* Deallocate all memory associated with this and later files,
|
||||
* including the lines of text. */
|
||||
void free_openfilestruct(openfilestruct *src)
|
||||
{
|
||||
if (src != NULL) {
|
||||
while (src->next != NULL) {
|
||||
src = src->next;
|
||||
delete_opennode(src->prev);
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, _("delete_opennode(): free'd a node, YAY!\n"));
|
||||
#endif
|
||||
}
|
||||
delete_opennode(src);
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, _("delete_opennode(): free'd last node.\n"));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Add/update an entry to the open_files openfilestruct. If update is
|
||||
* zero, a new entry is created; otherwise, the current entry is updated.
|
||||
@ -1414,7 +1486,9 @@ int write_file(char *name, int tmp, int append, int nonamechange)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
dump_buffer(fileage);
|
||||
#endif
|
||||
|
||||
f = fdopen(fd, append == 1 ? "ab" : "wb");
|
||||
if (!f) {
|
||||
@ -2742,20 +2816,11 @@ char *do_browser(char *inpath)
|
||||
|
||||
/* Hilight the currently selected file/dir */
|
||||
if (j == selected) {
|
||||
#ifdef ENABLE_COLOR
|
||||
color_on(edit, COLOR_STATUSBAR);
|
||||
#else
|
||||
wattron(edit, A_REVERSE);
|
||||
|
||||
#endif
|
||||
}
|
||||
waddnstr(edit, foo, strlen(foo));
|
||||
if (j == selected) {
|
||||
#ifdef ENABLE_COLOR
|
||||
color_off(edit, COLOR_STATUSBAR);
|
||||
#else
|
||||
wattroff(edit, A_REVERSE);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* And add some space between the cols */
|
||||
|
119
global.c
119
global.c
@ -37,6 +37,12 @@
|
||||
* Global variables
|
||||
*/
|
||||
|
||||
/* wrap_at might be set in rcfile.c or nano.c */
|
||||
int wrap_at = -CHARS_FROM_EOL;/* Right justified fill value, allows resize */
|
||||
char *last_search = NULL; /* Last string we searched for */
|
||||
char *last_replace = NULL; /* Last replacement string */
|
||||
int search_last_line; /* Is this the last search line? */
|
||||
|
||||
int flags = 0; /* Our new flag containing many options */
|
||||
WINDOW *edit; /* The file portion of the editor */
|
||||
WINDOW *topwin; /* Top line of screen */
|
||||
@ -66,10 +72,14 @@ openfilestruct *open_files = NULL; /* The list of open files */
|
||||
#endif
|
||||
|
||||
#ifndef DISABLE_JUSTIFY
|
||||
#ifdef HAVE_REGEX_H
|
||||
char *quotestr = "^([ \t]*[|>:}#])+";
|
||||
#else
|
||||
char *quotestr = "> "; /* Quote string */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
char *answer = NULL; /* Answer str to many questions */
|
||||
char *answer = NULL; /* Answer str to many questions */
|
||||
int totlines = 0; /* Total number of lines in the file */
|
||||
long totsize = 0; /* Total number of bytes in the file */
|
||||
int placewewant = 0; /* The column we'd like the cursor
|
||||
@ -79,7 +89,9 @@ int placewewant = 0; /* The column we'd like the cursor
|
||||
int tabsize = 8; /* Our internal tabsize variable */
|
||||
|
||||
char *hblank; /* A horizontal blank line */
|
||||
#ifndef DISABLE_HELP
|
||||
char *help_text; /* The text in the help window */
|
||||
#endif
|
||||
|
||||
/* More stuff for the marker select */
|
||||
|
||||
@ -113,14 +125,13 @@ shortcut *browser_list = NULL;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
colorstruct colors[NUM_NCOLORS];
|
||||
colortype *colorstrings = NULL;
|
||||
syntaxtype *syntaxes = NULL;
|
||||
char *syntaxstr = NULL;
|
||||
#endif
|
||||
|
||||
#if !defined(DISABLE_BROWSER) || !defined(DISABLE_MOUSE) || !defined(DISABLE_HELP)
|
||||
shortcut *currshortcut; /* Current shortcut list we're using */
|
||||
const shortcut *currshortcut; /* Current shortcut list we're using */
|
||||
#endif
|
||||
|
||||
#ifndef NANO_SMALL
|
||||
@ -133,23 +144,21 @@ toggle *toggles = NULL;
|
||||
regex_t search_regexp; /* Global to store compiled search regexp */
|
||||
regmatch_t regmatches[10]; /* Match positions for parenthetical
|
||||
subexpressions, max of 10 */
|
||||
#endif
|
||||
#ifdef ENABLE_COLOR
|
||||
regex_t color_regexp; /* Global to store compiled search regexp */
|
||||
regmatch_t colormatches[1]; /* Match positions for parenthetical */
|
||||
regex_t color_regexp; /* Global to store compiled search regexp */
|
||||
regmatch_t colormatches[1]; /* Match positions for parenthetical */
|
||||
|
||||
regex_t syntaxfile_regexp; /* Global to store compiled search regexp */
|
||||
regmatch_t synfilematches[1]; /* Match positions for parenthetical */
|
||||
regex_t syntaxfile_regexp; /* Global to store compiled search regexp */
|
||||
regmatch_t synfilematches[1]; /* Match positions for parenthetical */
|
||||
#endif /* ENABLE_COLOR */
|
||||
|
||||
#endif
|
||||
|
||||
int length_of_list(const shortcut *s)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (; s != NULL; s = s->next)
|
||||
i++;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
@ -211,17 +220,15 @@ static void toggle_init_one(int val, const char *desc, int flag)
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
/* Deallocate all of the toggles */
|
||||
/* Deallocate all of the toggles. */
|
||||
static void free_toggles(void)
|
||||
{
|
||||
toggle *pt; /* Think "previous toggle" */
|
||||
|
||||
while (toggles != NULL) {
|
||||
pt = toggles;
|
||||
toggle *pt = toggles; /* Think "previous toggle" */
|
||||
|
||||
toggles = toggles->next;
|
||||
free(pt);
|
||||
}
|
||||
toggles = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -229,10 +236,11 @@ static void toggle_init(void)
|
||||
{
|
||||
char *toggle_const_msg, *toggle_autoindent_msg, *toggle_suspend_msg,
|
||||
*toggle_nohelp_msg, *toggle_picomode_msg, *toggle_mouse_msg,
|
||||
*toggle_cuttoend_msg, *toggle_wrap_msg, *toggle_noconvert_msg,
|
||||
*toggle_dos_msg, *toggle_mac_msg, *toggle_backup_msg,
|
||||
*toggle_smooth_msg;
|
||||
|
||||
*toggle_cuttoend_msg, *toggle_noconvert_msg, *toggle_dos_msg,
|
||||
*toggle_mac_msg, *toggle_backup_msg, *toggle_smooth_msg;
|
||||
#ifndef DISABLE_WRAPPING
|
||||
char *toggle_wrap_msg;
|
||||
#endif
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
char *toggle_load_msg;
|
||||
#endif
|
||||
@ -256,7 +264,9 @@ static void toggle_init(void)
|
||||
toggle_mac_msg = _("Writing file in Mac format");
|
||||
toggle_backup_msg = _("Backing up file");
|
||||
toggle_smooth_msg = _("Smooth scrolling");
|
||||
#ifndef DISABLE_WRAPPING
|
||||
toggle_wrap_msg = _("Auto wrap");
|
||||
#endif
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
toggle_load_msg = _("Multiple file buffers");
|
||||
#endif
|
||||
@ -266,7 +276,9 @@ static void toggle_init(void)
|
||||
toggle_init_one(TOGGLE_SUSPEND_KEY, toggle_suspend_msg, SUSPEND);
|
||||
toggle_init_one(TOGGLE_NOHELP_KEY, toggle_nohelp_msg, NO_HELP);
|
||||
toggle_init_one(TOGGLE_PICOMODE_KEY, toggle_picomode_msg, PICO_MODE);
|
||||
#ifndef DISABLE_WRAPPING
|
||||
toggle_init_one(TOGGLE_WRAP_KEY, toggle_wrap_msg, NO_WRAP);
|
||||
#endif
|
||||
toggle_init_one(TOGGLE_MOUSE_KEY, toggle_mouse_msg, USE_MOUSE);
|
||||
toggle_init_one(TOGGLE_CUTTOEND_KEY, toggle_cuttoend_msg, CUT_TO_END);
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
@ -283,16 +295,12 @@ static void toggle_init(void)
|
||||
/* Deallocate the given shortcut. */
|
||||
static void free_shortcutage(shortcut **shortcutage)
|
||||
{
|
||||
shortcut *s, *ps;
|
||||
|
||||
assert(shortcutage != NULL);
|
||||
s = *shortcutage;
|
||||
while (s != NULL) {
|
||||
ps = s;
|
||||
s = s->next;
|
||||
while (*shortcutage != NULL) {
|
||||
shortcut *ps = *shortcutage;
|
||||
*shortcutage = (*shortcutage)->next;
|
||||
free(ps);
|
||||
}
|
||||
*shortcutage = NULL;
|
||||
}
|
||||
|
||||
void shortcut_init(int unjustify)
|
||||
@ -432,7 +440,6 @@ void shortcut_init(int unjustify)
|
||||
#endif
|
||||
|
||||
if (ISSET(PICO_MODE))
|
||||
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
/* this is so we can view multiple files */
|
||||
sc_init_one(&main_list, NANO_INSERTFILE_KEY, _("Read File"),
|
||||
@ -535,7 +542,7 @@ void shortcut_init(int unjustify)
|
||||
|
||||
sc_init_one(&main_list, NANO_ENTER_KEY, _("Enter"),
|
||||
IFHELP(nano_enter_msg, 0),
|
||||
KEY_ENTER, NANO_CONTROL_M, NOVIEW, do_enter_void);
|
||||
KEY_ENTER, NANO_CONTROL_M, NOVIEW, do_enter);
|
||||
|
||||
sc_init_one(&main_list, NANO_GOTO_KEY, _("Go To Line"),
|
||||
IFHELP(nano_goto_msg, NANO_ALT_GOTO_KEY),
|
||||
@ -544,11 +551,11 @@ void shortcut_init(int unjustify)
|
||||
#ifndef NANO_SMALL
|
||||
sc_init_one(&main_list, NANO_NEXTWORD_KEY, _("Next Word"),
|
||||
IFHELP(_("Move forward one word"), 0),
|
||||
0, 0, VIEW, do_next_word_void);
|
||||
0, 0, VIEW, do_next_word);
|
||||
|
||||
sc_init_one(&main_list, -9, _("Prev Word"),
|
||||
IFHELP(_("Move backward one word"), NANO_PREVWORD_KEY), 0, 0,
|
||||
VIEW, do_prev_word_void);
|
||||
VIEW, do_prev_word);
|
||||
#endif
|
||||
#if !defined(NANO_SMALL) && defined(HAVE_REGEX_H)
|
||||
sc_init_one(&main_list, -9, _("Find Other Bracket"),
|
||||
@ -654,10 +661,10 @@ void shortcut_init(int unjustify)
|
||||
IFHELP(nano_cancel_msg, 0), 0, 0, VIEW, 0);
|
||||
|
||||
sc_init_one(&goto_list, NANO_FIRSTLINE_KEY, _("First Line"),
|
||||
IFHELP(nano_firstline_msg, 0), 0, 0, VIEW, &do_first_line);
|
||||
IFHELP(nano_firstline_msg, 0), 0, 0, VIEW, do_first_line);
|
||||
|
||||
sc_init_one(&goto_list, NANO_LASTLINE_KEY, _("Last Line"),
|
||||
IFHELP(nano_lastline_msg, 0), 0, 0, VIEW, &do_last_line);
|
||||
IFHELP(nano_lastline_msg, 0), 0, 0, VIEW, do_last_line);
|
||||
|
||||
free_shortcutage(&help_list);
|
||||
|
||||
@ -781,11 +788,10 @@ void shortcut_init(int unjustify)
|
||||
/* This function is called just before calling exit(). Practically, the
|
||||
* only effect is to cause a segmentation fault if the various data
|
||||
* structures got bolloxed earlier. Thus, we don't bother having this
|
||||
* function unless debugging is turned on.
|
||||
*/
|
||||
* function unless debugging is turned on. */
|
||||
#ifdef DEBUG
|
||||
/* added by SPK for memory cleanup, gracefully return our malloc()s */
|
||||
void thanks_for_all_the_fish(void)
|
||||
void thanks_for_all_the_fish(void)
|
||||
{
|
||||
#ifndef DISABLE_OPERATINGDIR
|
||||
if (operating_dir != NULL)
|
||||
@ -816,15 +822,18 @@ void thanks_for_all_the_fish(void)
|
||||
free_shortcutage(&whereis_list);
|
||||
free_shortcutage(&replace_list);
|
||||
free_shortcutage(&replace_list_2);
|
||||
free_shortcutage(&help_list);
|
||||
free_shortcutage(&goto_list);
|
||||
free_shortcutage(&gotodir_list);
|
||||
free_shortcutage(&writefile_list);
|
||||
free_shortcutage(&insertfile_list);
|
||||
free_shortcutage(&help_list);
|
||||
free_shortcutage(&spell_list);
|
||||
#ifndef NANO_SMALL
|
||||
free_shortcutage(&extcmd_list);
|
||||
#endif
|
||||
#ifndef DISABLE_BROWSER
|
||||
free_shortcutage(&browser_list);
|
||||
#endif
|
||||
free_shortcutage(&gotodir_list);
|
||||
free_shortcutage(&goto_list);
|
||||
|
||||
#ifndef NANO_SMALL
|
||||
free_toggles();
|
||||
@ -833,19 +842,39 @@ void thanks_for_all_the_fish(void)
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
if (open_files != NULL) {
|
||||
/* We free the memory associated with each open file. */
|
||||
openfilestruct *next;
|
||||
|
||||
while (open_files->prev != NULL)
|
||||
open_files = open_files->prev;
|
||||
do {
|
||||
next = open_files->next;
|
||||
free_openfilestruct(open_files);
|
||||
open_files = next;
|
||||
} while (open_files != NULL);
|
||||
free_openfilestruct(open_files);
|
||||
}
|
||||
#else
|
||||
if (fileage != NULL)
|
||||
free_filestruct(fileage);
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
free(syntaxstr);
|
||||
while (syntaxes != NULL) {
|
||||
syntaxtype *bill = syntaxes;
|
||||
|
||||
free(syntaxes->desc);
|
||||
while (syntaxes->extensions != NULL) {
|
||||
exttype *bob = syntaxes->extensions;
|
||||
|
||||
syntaxes->extensions = bob->next;
|
||||
free(bob->val);
|
||||
free(bob);
|
||||
}
|
||||
while (syntaxes->color != NULL) {
|
||||
colortype *bob = syntaxes->color;
|
||||
|
||||
syntaxes->color = bob->next;
|
||||
free(bob->start);
|
||||
free(bob->end);
|
||||
free(bob);
|
||||
}
|
||||
syntaxes = syntaxes->next;
|
||||
free(bill);
|
||||
}
|
||||
#endif /* ENABLE_COLOR */
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
136
move.c
136
move.c
@ -24,6 +24,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include "proto.h"
|
||||
#include "nano.h"
|
||||
|
||||
@ -34,23 +35,6 @@
|
||||
#define _(string) (string)
|
||||
#endif
|
||||
|
||||
void page_down(void)
|
||||
{
|
||||
if (!ISSET(SMOOTHSCROLL)) {
|
||||
if (editbot != filebot) {
|
||||
edit_update(editbot->next, CENTER);
|
||||
center_cursor();
|
||||
} else {
|
||||
while (current != filebot)
|
||||
current = current->next;
|
||||
edit_update(current, CENTER);
|
||||
}
|
||||
} else {
|
||||
edit_update(editbot, NONE);
|
||||
}
|
||||
update_cursor();
|
||||
}
|
||||
|
||||
int do_page_down(void)
|
||||
{
|
||||
wrap_reset();
|
||||
@ -61,7 +45,7 @@ int do_page_down(void)
|
||||
return 0;
|
||||
|
||||
/* AHEM, if we only have a screen or less of text, DON'T do an
|
||||
edit_update, just move the cursor to editbot! */
|
||||
edit_update, just move the cursor to editbot! */
|
||||
if (edittop == fileage && editbot == filebot && totlines < editwinrows) {
|
||||
current = editbot;
|
||||
reset_cursor();
|
||||
@ -103,42 +87,18 @@ int do_end(void)
|
||||
current_x = strlen(current->data);
|
||||
placewewant = xplustabs();
|
||||
update_line(current, current_x);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* What happens when we want to go past the bottom of the buffer */
|
||||
int do_down(void)
|
||||
{
|
||||
wrap_reset();
|
||||
if (current->next != NULL) {
|
||||
if (placewewant > 0)
|
||||
current_x = actual_x(current->next, placewewant);
|
||||
else if (current_x > strlen(current->next->data))
|
||||
current_x = strlen(current->next->data);
|
||||
} else {
|
||||
UNSET(KEEP_CUTBUFFER);
|
||||
check_statblank();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (current_y < editwinrows - 1 && current != editbot)
|
||||
current_y++;
|
||||
else
|
||||
page_down();
|
||||
|
||||
update_cursor();
|
||||
update_line(current->prev, 0);
|
||||
update_line(current, current_x);
|
||||
UNSET(KEEP_CUTBUFFER);
|
||||
check_statblank();
|
||||
return 1;
|
||||
}
|
||||
|
||||
void page_up(void)
|
||||
{
|
||||
if (edittop != fileage) {
|
||||
if (!ISSET(SMOOTHSCROLL)) {
|
||||
#ifndef NANO_SMALL
|
||||
if (ISSET(SMOOTHSCROLL))
|
||||
edit_update(edittop->prev, TOP);
|
||||
else
|
||||
#endif
|
||||
{
|
||||
edit_update(edittop, CENTER);
|
||||
/* Now that we've updated the edit window, edittop might be
|
||||
at the top of the file; if so, just move the cursor up one
|
||||
@ -149,8 +109,6 @@ void page_up(void)
|
||||
current = current->prev;
|
||||
reset_cursor();
|
||||
}
|
||||
} else {
|
||||
edit_update(edittop->prev, NONE);
|
||||
}
|
||||
} else
|
||||
current_y = 0;
|
||||
@ -186,35 +144,72 @@ int do_up(void)
|
||||
{
|
||||
wrap_reset();
|
||||
if (current->prev != NULL) {
|
||||
if (placewewant > 0)
|
||||
current_x = actual_x(current->prev, placewewant);
|
||||
else if (current_x > strlen(current->prev->data))
|
||||
current_x = strlen(current->prev->data);
|
||||
current_x = actual_x(current->prev, placewewant);
|
||||
current = current->prev;
|
||||
if (current_y > 0) {
|
||||
update_line(current->next, 0);
|
||||
/* It is necessary to change current first, so the mark
|
||||
display will change! */
|
||||
current_y--;
|
||||
update_line(current, current_x);
|
||||
} else
|
||||
page_up();
|
||||
UNSET(KEEP_CUTBUFFER);
|
||||
check_statblank();
|
||||
}
|
||||
if (current_y > 0)
|
||||
current_y--;
|
||||
else
|
||||
page_up();
|
||||
return 1;
|
||||
}
|
||||
|
||||
update_cursor();
|
||||
update_line(current->next, 0);
|
||||
update_line(current, current_x);
|
||||
/* Return value 1 means we moved down, 0 means we were already at the
|
||||
* bottom. */
|
||||
int do_down(void) {
|
||||
wrap_reset();
|
||||
UNSET(KEEP_CUTBUFFER);
|
||||
check_statblank();
|
||||
|
||||
if (current->next == NULL)
|
||||
return 0;
|
||||
|
||||
current = current->next;
|
||||
current_x = actual_x(current, placewewant);
|
||||
|
||||
/* Note current_y is zero-based. This test checks for the cursor
|
||||
* being on the last row of the edit window. */
|
||||
if (current_y == editwinrows - 1) {
|
||||
#ifndef NANO_SMALL
|
||||
if (ISSET(SMOOTHSCROLL)) {
|
||||
/* In this case current_y does not change. The cursor
|
||||
* remains at the bottom of the edit window. */
|
||||
edittop = edittop->next;
|
||||
editbot = editbot->next;
|
||||
edit_refresh();
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
edit_update(editbot->next, CENTER);
|
||||
/* sets edittop so editbot->next is centered */
|
||||
center_cursor();
|
||||
/* sets current_y = editwinrows / 2 */
|
||||
}
|
||||
} else {
|
||||
update_line(current->prev, 0);
|
||||
update_line(current, current_x);
|
||||
current_y++;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int do_right(void)
|
||||
{
|
||||
if (current_x < strlen(current->data)) {
|
||||
current_x++;
|
||||
} else {
|
||||
if (do_down())
|
||||
current_x = 0;
|
||||
}
|
||||
assert(current_x <= strlen(current->data));
|
||||
|
||||
if (current->data[current_x] != '\0')
|
||||
current_x++;
|
||||
else if (current->next) {
|
||||
do_down();
|
||||
current_x = 0;
|
||||
}
|
||||
placewewant = xplustabs();
|
||||
update_cursor();
|
||||
update_line(current, current_x);
|
||||
UNSET(KEEP_CUTBUFFER);
|
||||
check_statblank();
|
||||
@ -226,13 +221,10 @@ int do_left(void)
|
||||
if (current_x > 0)
|
||||
current_x--;
|
||||
else if (current != fileage) {
|
||||
placewewant = 0;
|
||||
current_x = strlen(current->prev->data);
|
||||
do_up();
|
||||
current_x = strlen(current->data);
|
||||
}
|
||||
placewewant = xplustabs();
|
||||
|
||||
update_cursor();
|
||||
update_line(current, current_x);
|
||||
UNSET(KEEP_CUTBUFFER);
|
||||
check_statblank();
|
||||
|
55
nano.1
55
nano.1
@ -6,31 +6,31 @@
|
||||
.\" Public License for copying conditions. There is NO warranty.
|
||||
.\"
|
||||
.\" $Id$
|
||||
.TH NANO 1 "June 27, 2002"
|
||||
.TH NANO 1 "July 6, 2002"
|
||||
.\" Please adjust this date whenever revising the manpage.
|
||||
.\"
|
||||
.SH NAME
|
||||
nano \- Nano's ANOther editor, an enhanced free Pico Clone
|
||||
.SH SYNOPSIS
|
||||
.B nano
|
||||
.RI [options]\ [+LINE] " file"
|
||||
.I [\+LINE]\ [options]\ [file]
|
||||
.br
|
||||
.SH DESCRIPTION
|
||||
This manual page documents briefly the
|
||||
.B nano
|
||||
command.
|
||||
This manual page documents briefly the \fBnano\fP command.
|
||||
.PP
|
||||
.\" TeX users may be more comfortable with the \fB<whatever>\fP and
|
||||
.\" \fI<whatever>\fP escape sequences to invoke bold face and italics,
|
||||
.\" respectively.
|
||||
\fBnano\fP is a small, free and friendly editor which aims to replace
|
||||
Pico, the default editor included in the non-free Pine package. Rather
|
||||
than just copying Pico's look and feel,
|
||||
.B nano
|
||||
also implements some missing (or disabled by default) features in Pico,
|
||||
such as "search and replace" and "goto line number".
|
||||
than just copying Pico's look and feel, \fBnano\fP also implements some
|
||||
missing (or disabled by default) features in Pico, such as "search and
|
||||
replace" and "go to line number".
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \+\fILINE\fP
|
||||
Places cursor at \fILINE\fP on startup.
|
||||
.TP
|
||||
.B \-B (\-\-backup)
|
||||
When saving a file, back up the previous version of it to the current
|
||||
filename suffixed with a ~.
|
||||
@ -52,7 +52,7 @@ Write file in Mac format.
|
||||
.B \-N (\-\-noconvert)
|
||||
Disable automatic conversion of files from DOS/Mac format.
|
||||
.TP
|
||||
.B \-Q [str] (\-\-quotestr=[str])
|
||||
.B \-Q \fI[str]\fP (\-\-quotestr=\fI[str]\fP)
|
||||
Set the quoting string for justifying. The default is "> ".
|
||||
.TP
|
||||
.B \-R (\-\-regexp)
|
||||
@ -61,15 +61,15 @@ Enable regular expression matching for search strings, as well as
|
||||
.TP
|
||||
.B \-S (\-\-smooth)
|
||||
Enable smooth scrolling. Text will scroll line-by-line, instead of the
|
||||
usual chunk-by-chunk behaviour.
|
||||
usual chunk-by-chunk behavior.
|
||||
.TP
|
||||
.B \-T [num] (\-\-tabsize=[num])
|
||||
.B \-T \fI[num]\fP (\-\-tabsize=\fI[num]\fP)
|
||||
Set the size (width) of a tab.
|
||||
.TP
|
||||
.B \-V (\-\-version)
|
||||
Show the current version number and author.
|
||||
.TP
|
||||
.B \-Y (\-\-syntax=[str])
|
||||
.B \-Y \fI[str]\fP (\-\-syntax=\fI[str]\fP)
|
||||
Specify a specific syntax highlighting from the .nanorc to use, if
|
||||
available.
|
||||
.TP
|
||||
@ -93,7 +93,7 @@ a new file, do not follow it. Good for editing files in /tmp, perhaps?
|
||||
.B \-m (\-\-mouse)
|
||||
Enable mouse support (if available for your system).
|
||||
.TP
|
||||
.B \-o [dir] (\-\-operatingdir=[dir])
|
||||
.B \-o \fI[dir]\fP (\-\-operatingdir=\fI[dir]\fP)
|
||||
Set operating directory. Makes nano set up something similar to a
|
||||
chroot.
|
||||
.TP
|
||||
@ -102,13 +102,13 @@ Emulate Pico as closely as possible. This affects both the "shortcut
|
||||
list" at the bottom of the screen, as well as the display and entry of
|
||||
previous search and replace strings.
|
||||
.TP
|
||||
.B \-r [#cols] (\-\-fill=[#cols])
|
||||
.B \-r \fI[#cols]\fP (\-\-fill=\fI[#cols]\fP)
|
||||
Wrap lines at column #cols. By default, this is the width of the
|
||||
screen, less eight. If this value is negative, wrapping will occur at
|
||||
#cols from the right of the screen, allowing it to vary along with the
|
||||
screen width if the screen is resized.
|
||||
.TP
|
||||
.B \-s [prog] (\-\-speller=[prog])
|
||||
.B \-s \fI[prog]\fP (\-\-speller=\fI[prog]\fP)
|
||||
Enable alternative spell checker command.
|
||||
.TP
|
||||
.B \-t (\-\-tempfile)
|
||||
@ -128,25 +128,22 @@ Enable suspend ability.
|
||||
.TP
|
||||
.B \-a, \-b, \-e, \-f, \-g, \-j
|
||||
Ignored, for compatibility with Pico.
|
||||
.TP
|
||||
.B \+LINE
|
||||
Places cursor at LINE on startup.
|
||||
.SH NOTES
|
||||
Nano will try to dump the buffer into an emergency file in some cases.
|
||||
Mainly, this will happen if Nano receives a SIGHUP or runs out of
|
||||
memory, when it will write the buffer into a file named "nano.save" if
|
||||
the buffer didn't have a name already, or will add a ".save" suffix to
|
||||
the current filename. If an emergency file with that name already exists
|
||||
in the current directory, ".save" and a number (e.g. ".save.1") will be
|
||||
suffixed to the current filename in order to make it unique. In
|
||||
multibuffer mode, nano will write all the open buffers to the respective
|
||||
emergency files.
|
||||
\fBnano\fP will try to dump the buffer into an emergency file in some
|
||||
cases. Mainly, this will happen if \fBnano\fP receives a SIGHUP or runs
|
||||
out of memory, when it will write the buffer into a file named
|
||||
"nano.save" if the buffer didn't have a name already, or will add a
|
||||
".save" suffix to the current filename. If an emergency file with that
|
||||
name already exists in the current directory, ".save" and a number (e.g.
|
||||
".save.1") will be suffixed to the current filename in order to make it
|
||||
unique. In multibuffer mode, \fBnano\fP will write all the open buffers
|
||||
to the respective emergency files.
|
||||
.SH BUGS
|
||||
Please send any comments or bug reports to
|
||||
.br
|
||||
.B nano@nano-editor.org.
|
||||
.br
|
||||
The nano mailing list is available from
|
||||
The \fBnano\fP mailing list is available from
|
||||
.br
|
||||
.B nano-devel@gnu.org.
|
||||
To subscribe, email to nano-devel-request@gnu.org with a
|
||||
|
61
nano.1.html
61
nano.1.html
@ -3,7 +3,7 @@ Content-type: text/html
|
||||
<HTML><HEAD><TITLE>Manpage of NANO</TITLE>
|
||||
</HEAD><BODY>
|
||||
<H1>NANO</H1>
|
||||
Section: User Commands (1)<BR>Updated: June 27, 2002<BR><A HREF="#index">Index</A>
|
||||
Section: User Commands (1)<BR>Updated: July 5, 2002<BR><A HREF="#index">Index</A>
|
||||
<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR>
|
||||
|
||||
|
||||
@ -17,17 +17,14 @@ nano - Nano's ANOther editor, an enhanced free Pico Clone
|
||||
|
||||
<B>nano</B>
|
||||
|
||||
[options] [+LINE]<I> file</I>
|
||||
<I>[+LINE] [options] [file]</I>
|
||||
|
||||
<BR>
|
||||
|
||||
<A NAME="lbAD"> </A>
|
||||
<H2>DESCRIPTION</H2>
|
||||
|
||||
This manual page documents briefly the
|
||||
<B>nano</B>
|
||||
|
||||
command.
|
||||
This manual page documents briefly the <B>nano</B> command.
|
||||
<P>
|
||||
|
||||
|
||||
@ -35,15 +32,17 @@ command.
|
||||
|
||||
<B>nano</B> is a small, free and friendly editor which aims to replace
|
||||
Pico, the default editor included in the non-free Pine package. Rather
|
||||
than just copying Pico's look and feel,
|
||||
<B>nano</B>
|
||||
|
||||
also implements some missing (or disabled by default) features in Pico,
|
||||
such as "search and replace" and "goto line number".
|
||||
than just copying Pico's look and feel, <B>nano</B> also implements some
|
||||
missing (or disabled by default) features in Pico, such as "search and
|
||||
replace" and "go to line number".
|
||||
<A NAME="lbAE"> </A>
|
||||
<H2>OPTIONS</H2>
|
||||
|
||||
<DL COMPACT>
|
||||
<DT><B>+</B><I>LINE</I>
|
||||
|
||||
<DD>
|
||||
Places cursor at <I>LINE</I> on startup.
|
||||
<DT><B>-B (--backup)</B>
|
||||
|
||||
<DD>
|
||||
@ -71,7 +70,7 @@ Write file in Mac format.
|
||||
|
||||
<DD>
|
||||
Disable automatic conversion of files from DOS/Mac format.
|
||||
<DT><B>-Q [str] (--quotestr=[str])</B>
|
||||
<DT><B>-Q </B><I>[str]</I> (--quotestr=<I>[str]</I>)
|
||||
|
||||
<DD>
|
||||
Set the quoting string for justifying. The default is "> ".
|
||||
@ -84,8 +83,8 @@ Enable regular expression matching for search strings, as well as
|
||||
|
||||
<DD>
|
||||
Enable smooth scrolling. Text will scroll line-by-line, instead of the
|
||||
usual chunk-by-chunk behaviour.
|
||||
<DT><B>-T [num] (--tabsize=[num])</B>
|
||||
usual chunk-by-chunk behavior.
|
||||
<DT><B>-T </B><I>[num]</I> (--tabsize=<I>[num]</I>)
|
||||
|
||||
<DD>
|
||||
Set the size (width) of a tab.
|
||||
@ -93,7 +92,7 @@ Set the size (width) of a tab.
|
||||
|
||||
<DD>
|
||||
Show the current version number and author.
|
||||
<DT><B>-Y (--syntax=[str])</B>
|
||||
<DT><B>-Y </B><I>[str]</I> (--syntax=<I>[str]</I>)
|
||||
|
||||
<DD>
|
||||
Specify a specific syntax highlighting from the .nanorc to use, if
|
||||
@ -124,7 +123,7 @@ a new file, do not follow it. Good for editing files in /tmp, perhaps?
|
||||
|
||||
<DD>
|
||||
Enable mouse support (if available for your system).
|
||||
<DT><B>-o [dir] (--operatingdir=[dir])</B>
|
||||
<DT><B>-o </B><I>[dir]</I> (--operatingdir=<I>[dir]</I>)
|
||||
|
||||
<DD>
|
||||
Set operating directory. Makes nano set up something similar to a
|
||||
@ -135,14 +134,14 @@ chroot.
|
||||
Emulate Pico as closely as possible. This affects both the "shortcut
|
||||
list" at the bottom of the screen, as well as the display and entry of
|
||||
previous search and replace strings.
|
||||
<DT><B>-r [#cols] (--fill=[#cols])</B>
|
||||
<DT><B>-r </B><I>[#cols]</I> (--fill=<I>[#cols]</I>)
|
||||
|
||||
<DD>
|
||||
Wrap lines at column #cols. By default, this is the width of the
|
||||
screen, less eight. If this value is negative, wrapping will occur at
|
||||
#cols from the right of the screen, allowing it to vary along with the
|
||||
screen width if the screen is resized.
|
||||
<DT><B>-s [prog] (--speller=[prog])</B>
|
||||
<DT><B>-s </B><I>[prog]</I> (--speller=<I>[prog]</I>)
|
||||
|
||||
<DD>
|
||||
Enable alternative spell checker command.
|
||||
@ -170,23 +169,19 @@ Enable suspend ability.
|
||||
|
||||
<DD>
|
||||
Ignored, for compatibility with Pico.
|
||||
<DT><B>+LINE</B>
|
||||
|
||||
<DD>
|
||||
Places cursor at LINE on startup.
|
||||
</DL>
|
||||
<A NAME="lbAF"> </A>
|
||||
<H2>NOTES</H2>
|
||||
|
||||
Nano will try to dump the buffer into an emergency file in some cases.
|
||||
Mainly, this will happen if Nano receives a SIGHUP or runs out of
|
||||
memory, when it will write the buffer into a file named "nano.save" if
|
||||
the buffer didn't have a name already, or will add a ".save" suffix to
|
||||
the current filename. If an emergency file with that name already exists
|
||||
in the current directory, ".save" and a number (e.g. ".save.1") will be
|
||||
suffixed to the current filename in order to make it unique. In
|
||||
multibuffer mode, nano will write all the open buffers to the respective
|
||||
emergency files.
|
||||
<B>nano</B> will try to dump the buffer into an emergency file in some
|
||||
cases. Mainly, this will happen if <B>nano</B> receives a SIGHUP or runs
|
||||
out of memory, when it will write the buffer into a file named
|
||||
"nano.save" if the buffer didn't have a name already, or will add a
|
||||
".save" suffix to the current filename. If an emergency file with that
|
||||
name already exists in the current directory, ".save" and a number (e.g.
|
||||
".save.1") will be suffixed to the current filename in order to make it
|
||||
unique. In multibuffer mode, <B>nano</B> will write all the open buffers
|
||||
to the respective emergency files.
|
||||
<A NAME="lbAG"> </A>
|
||||
<H2>BUGS</H2>
|
||||
|
||||
@ -197,7 +192,7 @@ Please send any comments or bug reports to
|
||||
|
||||
<BR>
|
||||
|
||||
The nano mailing list is available from
|
||||
The <B>nano</B> mailing list is available from
|
||||
<BR>
|
||||
|
||||
<B><A HREF="mailto:nano-devel@gnu.org">nano-devel@gnu.org</A>.</B>
|
||||
@ -234,6 +229,6 @@ used by others).
|
||||
This document was created by
|
||||
<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>,
|
||||
using the manual pages.<BR>
|
||||
Time: 21:45:15 GMT, June 27, 2002
|
||||
Time: 03:38:25 GMT, July 06, 2002
|
||||
</BODY>
|
||||
</HTML>
|
||||
|
2007
nano.c
2007
nano.c
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
48
nano.h
48
nano.h
@ -124,6 +124,7 @@ typedef struct shortcut {
|
||||
struct shortcut *next;
|
||||
} shortcut;
|
||||
|
||||
#ifndef NANO_SMALL
|
||||
typedef struct toggle {
|
||||
int val; /* Sequence to toggle the key. Should only need 1 */
|
||||
const char *desc; /* Description for when toggle is, uh, toggled,
|
||||
@ -132,19 +133,17 @@ typedef struct toggle {
|
||||
int flag; /* What flag actually gets toggled */
|
||||
struct toggle *next;
|
||||
} toggle;
|
||||
#endif /* !NANO_SMALL */
|
||||
|
||||
#ifdef ENABLE_NANORC
|
||||
typedef struct rcoption {
|
||||
char *name;
|
||||
int flag;
|
||||
} rcoption;
|
||||
|
||||
#endif /* ENABLE_NANORC */
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
|
||||
#define COLORSTRNUM 16
|
||||
|
||||
typedef struct colortype {
|
||||
int fg; /* fg color */
|
||||
int bg; /* bg color */
|
||||
@ -162,9 +161,10 @@ typedef struct exttype {
|
||||
|
||||
typedef struct syntaxtype {
|
||||
char *desc; /* Name of this syntax type */
|
||||
struct exttype *extensions; /* List of extensions that this applies to */
|
||||
exttype *extensions; /* List of extensions that this applies to */
|
||||
colortype *color; /* color struct for this syntax */
|
||||
struct syntaxtype *next;
|
||||
|
||||
} syntaxtype;
|
||||
|
||||
#endif /* ENABLE_COLOR */
|
||||
@ -200,12 +200,11 @@ typedef struct syntaxtype {
|
||||
#define ALT_KEYPAD (1<<25)
|
||||
#define NO_CONVERT (1<<26)
|
||||
#define BACKUP_FILE (1<<27)
|
||||
#define NO_RCFILE (1<<28)
|
||||
|
||||
/* Control key sequences, changing these would be very very bad */
|
||||
|
||||
#ifndef NANO_SMALL
|
||||
# define NANO_CONTROL_SPACE 0
|
||||
#endif
|
||||
#define NANO_CONTROL_SPACE 0
|
||||
#define NANO_CONTROL_A 1
|
||||
#define NANO_CONTROL_B 2
|
||||
#define NANO_CONTROL_C 3
|
||||
@ -336,6 +335,8 @@ know what you're doing */
|
||||
#define NANO_NEXTWORD_KEY NANO_CONTROL_SPACE
|
||||
#define NANO_PREVWORD_KEY NANO_ALT_SPACE
|
||||
|
||||
#ifndef NANO_SMALL
|
||||
/* Toggles do not exist with NANO_SMALL. */
|
||||
#define TOGGLE_CONST_KEY NANO_ALT_C
|
||||
#define TOGGLE_AUTOINDENT_KEY NANO_ALT_I
|
||||
#define TOGGLE_SUSPEND_KEY NANO_ALT_Z
|
||||
@ -353,18 +354,18 @@ know what you're doing */
|
||||
#define TOGGLE_SMOOTH_KEY NANO_ALT_S
|
||||
#define TOGGLE_NOCONVERT_KEY NANO_ALT_N
|
||||
#define TOGGLE_BACKUP_KEY NANO_ALT_B
|
||||
#endif /* !NANO_SMALL */
|
||||
|
||||
#define MAIN_VISIBLE 12
|
||||
|
||||
#define VIEW 1
|
||||
#define NOVIEW 0
|
||||
|
||||
#define NONE 3
|
||||
#define TOP 2
|
||||
#define CENTER 1
|
||||
#define BOTTOM 0
|
||||
typedef enum {
|
||||
CENTER, TOP, NONE
|
||||
} topmidbotnone;
|
||||
|
||||
/* Minimum editor window rows required for Nano to work correctly */
|
||||
/* Minimum editor window rows required for nano to work correctly */
|
||||
#define MIN_EDITOR_ROWS 3
|
||||
|
||||
/* Default number of characters from end-of-line where text wrapping occurs */
|
||||
@ -373,25 +374,4 @@ know what you're doing */
|
||||
/* Minimum fill length (space available for text before wrapping occurs) */
|
||||
#define MIN_FILL_LENGTH 10
|
||||
|
||||
/* Color specific defines */
|
||||
#ifdef ENABLE_COLOR
|
||||
typedef struct colorstruct {
|
||||
int fg;
|
||||
int bg;
|
||||
int bold;
|
||||
int set;
|
||||
} colorstruct;
|
||||
|
||||
#define FIRST_COLORNUM 16
|
||||
|
||||
#define COLOR_TITLEBAR 16
|
||||
#define COLOR_BOTTOMBARS 17
|
||||
#define COLOR_STATUSBAR 18
|
||||
#define COLOR_TEXT 19
|
||||
#define COLOR_MARKER 20
|
||||
|
||||
#define NUM_NCOLORS 5
|
||||
|
||||
#endif /* ENABLE_COLOR */
|
||||
|
||||
#endif /* ifndef NANO_H */
|
||||
#endif /* !NANO_H */
|
||||
|
88
nano.texi
88
nano.texi
@ -13,7 +13,7 @@
|
||||
|
||||
@dircategory Editors
|
||||
@direntry
|
||||
* Nano: (nano). Small and friendly text editor.
|
||||
* nano: (nano). Small and friendly text editor.
|
||||
@end direntry
|
||||
|
||||
@c tex
|
||||
@ -35,26 +35,26 @@ This manual is part of the GNU @code{nano} distribution.@*
|
||||
@sp4
|
||||
Copyright (C) 1999, 2000, 2001, 2002 Chris Allegretta.
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this manual provided the copyright notice and this permission notice
|
||||
are preserved on all copies.
|
||||
Permission is granted to make and distribute verbatim copies of this
|
||||
manual provided the copyright notice and this permission notice are
|
||||
preserved on all copies.
|
||||
|
||||
@iftex
|
||||
Permission is granted to process this file through TeX and print the
|
||||
results, provided the printed document carries copying permission
|
||||
notice identical to this one except for the removal of this paragraph
|
||||
(this paragraph not being relevant to the printed manual).
|
||||
results, provided the printed document carries copying permission notice
|
||||
identical to this one except for the removal of this paragraph (this
|
||||
paragraph not being relevant to the printed manual).
|
||||
@end iftex
|
||||
|
||||
Permission is granted to copy and distribute modified versions of this
|
||||
manual under the conditions for verbatim copying, provided that the entire
|
||||
resulting derived work is distributed under the terms of a permission
|
||||
notice identical to this one.
|
||||
manual under the conditions for verbatim copying, provided that the
|
||||
entire resulting derived work is distributed under the terms of a
|
||||
permission notice identical to this one.
|
||||
|
||||
Permission is granted to copy and distribute translations of this manual
|
||||
into another language, under the above conditions for modified versions,
|
||||
except that this permission notice may be stated in a translation approved
|
||||
by the Foundation.
|
||||
except that this permission notice may be stated in a translation
|
||||
approved by the Foundation.
|
||||
|
||||
You may contact the author by:
|
||||
e-mail: @email{chrisa@@asty.org}@*
|
||||
@ -62,7 +62,8 @@ e-mail: @email{chrisa@@asty.org}@*
|
||||
|
||||
@node Top, Introduction, (dir), (dir)
|
||||
|
||||
This manual documents GNU nano, a small and friendly text editor.
|
||||
This manual documents GNU @code{nano}, a small and friendly text
|
||||
editor.
|
||||
|
||||
@menu
|
||||
* Introduction::
|
||||
@ -77,11 +78,10 @@ This manual documents GNU nano, a small and friendly text editor.
|
||||
@node Introduction, Editor Basics, Top, Top
|
||||
@chapter Introduction
|
||||
|
||||
GNU @code{nano} is a small and friendly text editor. Besides basic
|
||||
text editing, @code{nano} offers many extra features like an
|
||||
interactive search and replace, goto line number, auto-indentation,
|
||||
feature toggles, internationalization support, and filename tab
|
||||
completion.
|
||||
GNU @code{nano} is a small and friendly text editor. Besides basic text
|
||||
editing, @code{nano} offers many extra features like an interactive
|
||||
search and replace, goto line number, auto-indentation, feature toggles,
|
||||
internationalization support, and filename tab completion.
|
||||
|
||||
@menu
|
||||
* Overview::
|
||||
@ -94,7 +94,7 @@ completion.
|
||||
@code{nano} [GNU long option] [option] +LINE [ @var{ file ...} ]
|
||||
|
||||
The original goal for @code{nano} was a complete bug-for-bug compatible
|
||||
emulation of Pico, but consistency is now a slightly higher priority.
|
||||
emulation of Pico, but consistency is now a slightly higher priority.
|
||||
There is a flag to implement (nearly) complete Pico emulation, (option -p
|
||||
or GNU long option --pico). This can also be toggled from within
|
||||
@code{nano} by typing Meta-P. @xref{Pico Compatibility}, for more
|
||||
@ -122,7 +122,7 @@ Enable multiple file buffers, if available.
|
||||
@item -K, --keypad
|
||||
Do not use the ncurses keypad() call unless necessary. Try this flag if
|
||||
you find that the arrow keys on the numeric keypad do not work for you
|
||||
under nano.
|
||||
under @code{nano}.
|
||||
|
||||
@item -M, --mac
|
||||
Write file in Mac format.
|
||||
@ -172,7 +172,8 @@ Enables the use of the mouse to select text (currently only useful for
|
||||
running under the X window system).
|
||||
|
||||
@item -o [dir], --operatingdir=[dir]
|
||||
Set operating directory. Makes nano set up something similar to a chroot.
|
||||
Set operating directory. Makes @code{nano} set up something similar to a
|
||||
chroot.
|
||||
|
||||
@item -p, --pico
|
||||
Emulate Pico as closely as possible, sacrificing consistency for correct
|
||||
@ -272,8 +273,8 @@ current file name, or "New Buffer" if the file has not yet been named.
|
||||
The section on the right will display "Modified" if the file has been
|
||||
modified since it was last saved or opened.
|
||||
|
||||
Special modes: When nano is in "File browser" mode, the center section
|
||||
will display the current directory instead of the filename.
|
||||
Special modes: When @code{nano} is in "File browser" mode, the center
|
||||
section will display the current directory instead of the filename.
|
||||
@xref{The File Browser}.
|
||||
|
||||
@node The Statusbar, Shortcut Lists, The Titlebar, Editor Basics
|
||||
@ -378,7 +379,7 @@ statusbar and the file browser is exited.
|
||||
@node Pico Compatibility, Building and Configure Options, The File Browser, Top
|
||||
@chapter Pico Compatibility
|
||||
|
||||
Nano does not completely emulate Pico by default. The following
|
||||
nano does not completely emulate Pico by default. The following
|
||||
differences apply to the default mode and Pico Compatibility mode:
|
||||
|
||||
@table @code
|
||||
@ -423,17 +424,17 @@ to force these functions to behave in the Pico fashion.
|
||||
@node Building and Configure Options, , Pico Compatibility, Top
|
||||
@chapter Building and Configure Options
|
||||
|
||||
Building nano from source is fairly straightforward if you are familiar
|
||||
Building @code{nano} from source is fairly straightforward if you are familiar
|
||||
with compiling programs with autoconf support:
|
||||
|
||||
tar xvfz nano-x.y.z.tar.gz (where x.y.z is the version of nano)
|
||||
tar xvfz nano-x.y.z.tar.gz (where x.y.z is the version of @code{nano})
|
||||
cd nano-x.y.z/
|
||||
./configure
|
||||
make
|
||||
make install
|
||||
|
||||
if you are looking to optimize nano for size, you may want to consider
|
||||
the following command line options:
|
||||
if you are looking to optimize @code{nano} for size, you may want to
|
||||
consider the following command line options:
|
||||
|
||||
|
||||
@table @code
|
||||
@ -448,38 +449,39 @@ Disable the justify (^J)/unjustify (^U) functions in the editor.
|
||||
Disables spell checker ability.
|
||||
|
||||
@item --disable-help
|
||||
Disables the help function (^G). Disabling this option makes the
|
||||
binary much smaller, but makes it difficult for new users
|
||||
to learn more than very basic things about using the editor.
|
||||
Disables the help function (^G). Disabling this option makes the binary
|
||||
much smaller, but makes it difficult for new users to learn more than
|
||||
very basic things about using the editor.
|
||||
|
||||
@item --disable-browser
|
||||
Disables the mini file browser (^O) when reading or writing files.
|
||||
|
||||
@item --enable-tiny
|
||||
This options disables all the above. It also disables some of
|
||||
the larger internals of the editor, like the marker code (^^) and
|
||||
the cut to line (-k) option which it depends on to work properly.
|
||||
It also disables the function toggles and mouse support.
|
||||
This options disables all the above. It also disables some of the larger
|
||||
internals of the editor, like the marker code (^^) and the cut to line
|
||||
(-k) option which it depends on to work properly. It also disables the
|
||||
function toggles and mouse support.
|
||||
|
||||
@item --disable-wrapping
|
||||
Disables all word wrapping in the editor. This also eliminates the
|
||||
-w command line flag, as nonwrapping is then the default behavior.
|
||||
Disables all word wrapping in the editor. This also eliminates the -w
|
||||
command line flag, as nonwrapping is then the default behavior.
|
||||
|
||||
@item --disable-mouse
|
||||
Disables all mouse functionality. This also disables the -m command line
|
||||
flag which enables the mouse functions.
|
||||
Disables all mouse functionality. This also disables the -m command
|
||||
line flag which enables the mouse functions.
|
||||
|
||||
@item --disable-operatingdir
|
||||
Disables setting of operating directory. This also disables the -o
|
||||
command line flag.
|
||||
|
||||
@item --disable-nls
|
||||
Disables Native Language support. This will make the available GNU nano
|
||||
translations unusable.
|
||||
Disables Native Language support. This will make the available GNU
|
||||
@code{nano} translations unusable.
|
||||
|
||||
@item --with-slang
|
||||
Compiling GNU nano with Slang is supported, and will make the binary
|
||||
notably smaller than if compiled with ncurses or other curses libraries.
|
||||
Compiling GNU @code{nano} with Slang is supported, and will make the
|
||||
binary notably smaller than if compiled with ncurses or other curses
|
||||
libraries.
|
||||
|
||||
@end table
|
||||
|
||||
|
@ -17,6 +17,8 @@
|
||||
# set cut
|
||||
|
||||
# Use this value instead of the default
|
||||
# An out-of-range negative value can make nano die complaining that the
|
||||
# screen is too small
|
||||
# set fill -8
|
||||
|
||||
# Use alternate keypad routines
|
||||
@ -46,9 +48,12 @@
|
||||
# Use Pico Compatibility mode for the shortcut lists and search text
|
||||
# set pico
|
||||
|
||||
# Use this as the quoting string. You shouldn't need to change this,
|
||||
# but...... default "> "
|
||||
# set quotestr "// "
|
||||
# The email-quote string. This is a "regular expression" if your
|
||||
# system supports them, otherwise a literal string. Default
|
||||
# set quotestr "^([ \t]*[|>:}#])+" if you have regexps, otherwise
|
||||
# set quotestr "> ".
|
||||
# You can get old nano quoted-justify behavior via:
|
||||
# set quotestr "(> )+"
|
||||
|
||||
# Do regular expression searches by default
|
||||
# set regexp
|
||||
@ -62,7 +67,7 @@
|
||||
# Allow nano to be suspended with ^Z
|
||||
# set suspend
|
||||
|
||||
# Use this tab size instead of the default
|
||||
# Use this tab size instead of the default; it must be greater than 0
|
||||
# set tabsize 4
|
||||
|
||||
# Save automatically on exit, don't prompt
|
||||
@ -85,7 +90,7 @@
|
||||
# color will use a transparent color. If you don't want this, be sure
|
||||
# to set the background color to black or white.
|
||||
|
||||
# syntax "c-file" ".*\.c" ".*\.h"
|
||||
# syntax "c-file" ".*\.c$" ".*\.h$"
|
||||
# color red "\<[A-Z_]\{2,\}\>"
|
||||
# color green "\<float\>" "\<char\>" "\<int\>" "\<void\>"
|
||||
# color green "\<static\>" "\<const\>" "\<struct\>"
|
||||
@ -99,7 +104,7 @@
|
||||
|
||||
# color brightyellow "<[^= ]*>" "\"[^"]*\""
|
||||
# color brightblue "//.*"
|
||||
# color brightblue start="/\*.*" end="\*/"
|
||||
# color brightblue start="/\*" end="\*/"
|
||||
|
||||
# For this you will probably want to set your editor to "nano -Y mutt"
|
||||
|
||||
|
372
proto.h
372
proto.h
@ -29,13 +29,14 @@
|
||||
|
||||
#include "nano.h"
|
||||
|
||||
extern int wrap_at;
|
||||
extern int editwinrows;
|
||||
extern int current_x, current_y, totlines;
|
||||
extern int placewewant;
|
||||
extern int mark_beginx, samelinewrap;
|
||||
extern int mark_beginx;
|
||||
extern long totsize;
|
||||
extern int temp_opt;
|
||||
extern int fill, wrap_at, flags,tabsize;
|
||||
extern int wrap_at, flags, tabsize;
|
||||
extern int search_last_line;
|
||||
extern int currslen;
|
||||
|
||||
@ -47,7 +48,10 @@ extern WINDOW *edit, *topwin, *bottomwin;
|
||||
extern char *filename;
|
||||
extern struct stat originalfilestat;
|
||||
extern char *answer;
|
||||
extern char *hblank, *help_text;
|
||||
extern char *hblank;
|
||||
#ifndef DISABLE_HELP
|
||||
extern char *help_text;
|
||||
#endif
|
||||
extern char *last_search;
|
||||
extern char *last_replace;
|
||||
#ifndef DISABLE_OPERATINGDIR
|
||||
@ -57,6 +61,13 @@ extern char *full_operating_dir;
|
||||
#ifndef DISABLE_SPELLER
|
||||
extern char *alt_speller;
|
||||
#endif
|
||||
#ifndef DISABLE_TABCOMP
|
||||
char *real_dir_from_tilde(char *buf);
|
||||
#endif
|
||||
#ifndef DISABLE_BROWSER
|
||||
char *do_browse_from(char *inpath);
|
||||
#endif
|
||||
|
||||
extern struct stat fileinfo;
|
||||
extern filestruct *current, *fileage, *edittop, *editbot, *filebot;
|
||||
extern filestruct *cutbuffer, *mark_beginbuf;
|
||||
@ -69,6 +80,8 @@ extern openfilestruct *open_files;
|
||||
extern colortype *colorstrings;
|
||||
extern syntaxtype *syntaxes;
|
||||
extern char *syntaxstr;
|
||||
extern regex_t color_regexp;
|
||||
extern regmatch_t colormatches[1];
|
||||
#endif
|
||||
|
||||
extern shortcut *shortcut_list;
|
||||
@ -83,235 +96,200 @@ extern shortcut *help_list;
|
||||
#ifndef DISABLE_BROWSER
|
||||
extern shortcut *browser_list, *gotodir_list;
|
||||
#endif
|
||||
extern shortcut *currshortcut;
|
||||
extern const shortcut *currshortcut;
|
||||
|
||||
#ifdef HAVE_REGEX_H
|
||||
extern int use_regexp, regexp_compiled;
|
||||
extern regex_t search_regexp;
|
||||
extern regmatch_t regmatches[10];
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
extern regex_t color_regexp;
|
||||
extern regmatch_t colormatches[1];
|
||||
|
||||
extern regex_t syntaxfile_regexp;
|
||||
extern regmatch_t synfilematches[1];
|
||||
#endif /* ENABLE_COLOR */
|
||||
#endif /* HAVE_REGEX_H */
|
||||
|
||||
#ifndef NANO_SMALL
|
||||
extern toggle *toggles;
|
||||
#endif
|
||||
|
||||
extern toggle *toggles;
|
||||
/* Functions we want available */
|
||||
|
||||
/* Programs we want available */
|
||||
/* Public functions in color.c */
|
||||
#ifdef ENABLE_COLOR
|
||||
void set_colorpairs(void);
|
||||
void do_colorinit(void);
|
||||
void update_color(void);
|
||||
#endif /* ENABLE_COLOR */
|
||||
|
||||
/* public functions in global.c */
|
||||
/* Public functions in cut.c */
|
||||
int do_cut_text(void);
|
||||
int do_uncut_text(void);
|
||||
filestruct *get_cutbottom(void);
|
||||
void add_to_cutbuffer(filestruct *inptr);
|
||||
void cut_marked_segment(filestruct *top, size_t top_x, filestruct *bot,
|
||||
size_t bot_x, int destructive);
|
||||
|
||||
/* Public functions in files.c */
|
||||
int write_file(char *name, int tmpfile, int append, int nonamechange);
|
||||
int open_file(const char *filename, int insert, int quiet);
|
||||
int read_file(FILE *f, const char *filename, int quiet);
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
openfilestruct *make_new_opennode(openfilestruct *prevnode);
|
||||
void splice_opennode(openfilestruct *begin, openfilestruct *newnode, openfilestruct *end);
|
||||
void unlink_opennode(const openfilestruct *fileptr);
|
||||
void delete_opennode(openfilestruct *fileptr);
|
||||
void free_openfilestruct(openfilestruct *src);
|
||||
int add_open_file(int update);
|
||||
int close_open_file(void);
|
||||
int open_prevfile_void(void);
|
||||
int open_nextfile_void(void);
|
||||
#endif
|
||||
#ifndef DISABLE_OPERATINGDIR
|
||||
int check_operating_dir(char *currpath, int allow_tabcomp);
|
||||
#endif
|
||||
int do_writeout(char *path, int exiting, int append);
|
||||
char *input_tab(char *buf, int place, int *lastwastab, int *newplace, int *list);
|
||||
void new_file(void);
|
||||
int do_writeout_void(void);
|
||||
int do_insertfile_void(void);
|
||||
char *get_next_filename(const char *name);
|
||||
#ifndef DISABLE_SPELLER
|
||||
char *safe_tempnam(const char *dirname, const char *filename_prefix);
|
||||
#endif
|
||||
|
||||
/* Public functions in global.c */
|
||||
int length_of_list(const shortcut *s);
|
||||
void shortcut_init(int unjustify);
|
||||
#ifdef DEBUG
|
||||
void thanks_for_all_the_fish(void);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
char *revstrstr(char *haystack, char *needle, char *rev_start);
|
||||
char *stristr(char *haystack, char *needle);
|
||||
char *revstristr(char *haystack, char *needle, char *rev_start);
|
||||
char *strstrwrapper(char *haystack, char *needle, char *rev_start, int line_pos);
|
||||
int search_init(int replacing);
|
||||
int renumber(filestruct * fileptr);
|
||||
int free_filestruct(filestruct * src);
|
||||
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
int free_openfilestruct(openfilestruct * src);
|
||||
#endif
|
||||
|
||||
int xplustabs(void);
|
||||
int do_yesno(int all, int leavecursor, char *msg, ...);
|
||||
int actual_x(filestruct * fileptr, int xplus);
|
||||
int strnlenpt(char *buf, int size);
|
||||
int strlenpt(char *buf);
|
||||
int statusq(int allowtabs, shortcut s[], char *def, char *msg, ...);
|
||||
int write_file(char *name, int tmpfile, int append, int nonamechange);
|
||||
int do_cut_text(void);
|
||||
int do_uncut_text(void);
|
||||
int no_help(void);
|
||||
int renumber_all(void);
|
||||
int open_file(const char *filename, int insert, int quiet);
|
||||
int do_insertfile(int loading_file);
|
||||
int num_of_digits(int n);
|
||||
int open_pipe(char *command);
|
||||
int read_file(FILE *f, const char *filename, int quiet);
|
||||
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
int add_open_file(int update);
|
||||
#endif
|
||||
|
||||
#ifndef DISABLE_OPERATINGDIR
|
||||
int check_operating_dir(char *currpath, int allow_tabcomp);
|
||||
#endif
|
||||
|
||||
#ifndef NANO_SMALL
|
||||
int do_next_word_void(void);
|
||||
int do_prev_word_void(void);
|
||||
#endif /* !NANO_SMALL */
|
||||
|
||||
int do_writeout(char *path, int exiting, int append);
|
||||
int do_gotoline(int line, int save_pos);
|
||||
int is_whole_word(int curr_pos, filestruct *fileptr, char *searchword);
|
||||
int do_replace_loop(char *prevanswer, filestruct *begin, int *beginx,
|
||||
int wholewords, int *i);
|
||||
int do_find_bracket(void);
|
||||
|
||||
#if defined (ENABLE_MULTIBUFFER) || !defined (DISABLE_SPELLER)
|
||||
void do_gotopos(int line, int pos_x, int pos_y, int pos_placewewant);
|
||||
#endif
|
||||
|
||||
/* Now in move.c */
|
||||
/* Public functions in move.c */
|
||||
int do_first_line(void);
|
||||
int do_last_line(void);
|
||||
size_t xplustabs(void);
|
||||
size_t actual_x(const filestruct *fileptr, size_t xplus);
|
||||
size_t strnlenpt(const char *buf, size_t size);
|
||||
size_t strlenpt(const char *buf);
|
||||
void reset_cursor(void);
|
||||
void blank_bottombars(void);
|
||||
void blank_edit(void);
|
||||
void blank_statusbar(void);
|
||||
void blank_statusbar_refresh(void);
|
||||
void check_statblank(void);
|
||||
void titlebar(const char *path);
|
||||
void bottombars(const shortcut *s);
|
||||
void set_modified(void);
|
||||
int do_up(void);
|
||||
int do_down(void);
|
||||
int do_left(void);
|
||||
int do_right(void);
|
||||
int check_wildcard_match(const char *text, const char *pattern);
|
||||
|
||||
char *input_tab(char *buf, int place, int *lastwastab, int *newplace, int *list);
|
||||
char *real_dir_from_tilde(char *buf);
|
||||
|
||||
void signal_init(void);
|
||||
void unsunder(char *str, int true_len);
|
||||
void sunder(char *str);
|
||||
void lowercase(char *src);
|
||||
void blank_bottombars(void);
|
||||
void check_wrap(filestruct * inptr);
|
||||
void dump_buffer(filestruct * inptr);
|
||||
void align(char **strp);
|
||||
void edit_refresh(void), edit_refresh_clearok(void);
|
||||
void edit_update(filestruct * fileptr, int topmidbotnone);
|
||||
void update_cursor(void);
|
||||
void delete_node(filestruct * fileptr);
|
||||
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
void delete_opennode(openfilestruct * fileptr);
|
||||
#endif
|
||||
|
||||
void set_modified(void);
|
||||
void dump_buffer_reverse(filestruct * inptr);
|
||||
void reset_cursor(void);
|
||||
void check_statblank(void);
|
||||
void update_line(filestruct * fileptr, int index);
|
||||
void fix_editbot(void);
|
||||
void statusbar(char *msg, ...);
|
||||
void blank_statusbar(void);
|
||||
void titlebar(char *path);
|
||||
void previous_line(void);
|
||||
void center_cursor(void);
|
||||
void bottombars(const shortcut *s);
|
||||
void blank_statusbar_refresh(void);
|
||||
void nperror(const char *s);
|
||||
void *mallocstrcpy(char *dest, char *src);
|
||||
void wrap_reset(void);
|
||||
void display_main_list(void);
|
||||
void nano_small_msg(void);
|
||||
void nano_disable_msg(void);
|
||||
void do_early_abort(void);
|
||||
void *nmalloc(size_t howmuch);
|
||||
void *nrealloc(void *ptr, size_t howmuch);
|
||||
void die(char *msg, ...);
|
||||
void die_save_file(char *die_filename);
|
||||
void new_file(void);
|
||||
void new_magicline(void);
|
||||
void splice_node(filestruct *begin, filestruct *newnode, filestruct *end);
|
||||
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
void splice_opennode(openfilestruct *begin, openfilestruct *newnode, openfilestruct *end);
|
||||
#endif
|
||||
|
||||
void null_at(char **data, int index);
|
||||
void page_up(void);
|
||||
void blank_edit(void);
|
||||
void search_init_globals(void);
|
||||
void replace_abort(void);
|
||||
void add_to_cutbuffer(filestruct * inptr);
|
||||
void do_replace_highlight(int highlight_flag, char *word);
|
||||
int do_page_up(void);
|
||||
int do_page_down(void);
|
||||
int do_home(void);
|
||||
int do_end(void);
|
||||
|
||||
/* Public functions in nano.c */
|
||||
void renumber(filestruct *fileptr);
|
||||
void free_filestruct(filestruct *src);
|
||||
int no_help(void);
|
||||
void renumber_all(void);
|
||||
int open_pipe(const char *command);
|
||||
int do_prev_word(void);
|
||||
int do_next_word(void);
|
||||
void delete_node(filestruct *fileptr);
|
||||
void wrap_reset(void);
|
||||
void do_early_abort(void);
|
||||
void die(const char *msg, ...);
|
||||
void splice_node(filestruct *begin, filestruct *newnode, filestruct *end);
|
||||
void nano_disabled_msg(void);
|
||||
void window_init(void);
|
||||
void do_mouse(void);
|
||||
void print_view_warning(void);
|
||||
void unlink_node(filestruct * fileptr);
|
||||
int do_exit(void);
|
||||
int do_spell(void);
|
||||
int do_mark(void);
|
||||
int do_delete(void);
|
||||
int do_backspace(void);
|
||||
int do_tab(void);
|
||||
int do_justify(void);
|
||||
int do_enter(void);
|
||||
int do_wrap(filestruct *inptr);
|
||||
void signal_init(void);
|
||||
void handle_sigwinch(int s);
|
||||
void die_save_file(const char *die_filename);
|
||||
size_t indent_length(const char *line);
|
||||
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
void unlink_opennode(openfilestruct * fileptr);
|
||||
filestruct *copy_node(const filestruct *src);
|
||||
filestruct *copy_filestruct(const filestruct *src);
|
||||
filestruct *make_new_node(filestruct *prevnode);
|
||||
#ifndef DISABLE_HELP
|
||||
void help_init(void);
|
||||
#endif
|
||||
|
||||
void cut_marked_segment(filestruct * top, int top_x, filestruct * bot,
|
||||
int bot_x, int destructive);
|
||||
|
||||
/* Public functions in rcfile.c */
|
||||
#ifdef ENABLE_NANORC
|
||||
void do_rcfile(void);
|
||||
#endif
|
||||
|
||||
/* Public functions in search.c */
|
||||
int do_gotoline(int line, int save_pos);
|
||||
int is_whole_word(int curr_pos, const char *datastr, const char *searchword);
|
||||
int do_replace_loop(const char *prevanswer, const filestruct *begin,
|
||||
int *beginx, int wholewords, int *i);
|
||||
int do_find_bracket(void);
|
||||
#if defined (ENABLE_MULTIBUFFER) || !defined (DISABLE_SPELLER)
|
||||
void do_gotopos(int line, int pos_x, int pos_y, int pos_placewewant);
|
||||
#endif
|
||||
void search_init_globals(void);
|
||||
void replace_abort(void);
|
||||
int do_gotoline_void(void);
|
||||
int do_search(void);
|
||||
int do_replace(void);
|
||||
filestruct *findnextstr(int quiet, int bracket_mode, const filestruct *begin,
|
||||
int beginx, const char *needle);
|
||||
|
||||
/* Public functions in utils.c */
|
||||
const char *stristr(const char *haystack, const char *needle);
|
||||
const char *strstrwrapper(const char *haystack, const char *needle,
|
||||
const char *rev_start, int line_pos);
|
||||
int num_of_digits(int n);
|
||||
int check_wildcard_match(const char *text, const char *pattern);
|
||||
void align(char **strp);
|
||||
void null_at(char **data, size_t index);
|
||||
void unsunder(char *str, size_t true_len);
|
||||
void sunder(char *str);
|
||||
void nperror(const char *s);
|
||||
char *mallocstrcpy(char *dest, const char *src);
|
||||
void *nmalloc(size_t howmuch);
|
||||
void *nrealloc(void *ptr, size_t howmuch);
|
||||
void new_magicline(void);
|
||||
char *charalloc(size_t howmuch);
|
||||
|
||||
/* Public functions in winio.c */
|
||||
int do_yesno(int all, int leavecursor, const char *msg, ...);
|
||||
int statusq(int allowtabs, const shortcut *s, const char *def,
|
||||
const char *msg, ...);
|
||||
void do_replace_highlight(int highlight_flag, const char *word);
|
||||
void edit_refresh(void);
|
||||
void edit_refresh_clearok(void);
|
||||
void edit_update(filestruct *fileptr, topmidbotnone location);
|
||||
void update_cursor(void);
|
||||
#ifdef DEBUG
|
||||
void dump_buffer(const filestruct *inptr);
|
||||
void dump_buffer_reverse(void);
|
||||
#endif
|
||||
void update_line(filestruct *fileptr, int index);
|
||||
void fix_editbot(void);
|
||||
void statusbar(const char *msg, ...);
|
||||
void center_cursor(void);
|
||||
void display_main_list(void);
|
||||
#ifdef NANO_EXTRA
|
||||
void do_credits(void);
|
||||
#endif
|
||||
|
||||
int do_writeout_void(void), do_exit(void), do_gotoline_void(void);
|
||||
int do_insertfile_void(void), do_search(void);
|
||||
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
int load_open_file(void), close_open_file(void);
|
||||
#endif
|
||||
|
||||
int do_page_up(void), do_page_down(void);
|
||||
int do_cursorpos(int constant), do_cursorpos_void(void), do_spell(void);
|
||||
int do_home(void), do_end(void), total_refresh(void), do_mark(void);
|
||||
int do_delete(void), do_backspace(void), do_tab(void), do_justify(void);
|
||||
int do_first_line(void), do_last_line(void);
|
||||
int do_replace(void), do_help(void), do_enter_void(void);
|
||||
int keypad_on(WINDOW * win, int newval);
|
||||
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
int open_prevfile(int closing_file), open_nextfile(int closing_file);
|
||||
int open_prevfile_void(void), open_nextfile_void(void);
|
||||
#endif
|
||||
|
||||
char *charalloc (size_t howmuch);
|
||||
char *get_next_filename(const char *name);
|
||||
|
||||
#if !defined (DISABLE_SPELLER) || !defined (DISABLE_OPERATINGDIR)
|
||||
char *get_full_path(const char *origpath);
|
||||
#endif
|
||||
|
||||
#ifndef DISABLE_SPELLER
|
||||
char *check_writable_directory(const char *path);
|
||||
char *safe_tempnam(const char *dirname, const char *filename_prefix);
|
||||
#endif
|
||||
|
||||
#ifndef DISABLE_BROWSER
|
||||
char *do_browser(char *path);
|
||||
struct stat filestat(const char *path);
|
||||
char *do_browse_from(char *inpath);
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
int do_colorinit(void);
|
||||
void color_on(WINDOW *win, int whatever);
|
||||
void color_off(WINDOW *win, int whatever);
|
||||
void update_color(void);
|
||||
|
||||
extern colorstruct colors[NUM_NCOLORS];
|
||||
#endif /* ENABLE_COLOR */
|
||||
|
||||
RETSIGTYPE main_loop (int junk);
|
||||
|
||||
filestruct *copy_node(filestruct * src);
|
||||
filestruct *copy_filestruct(filestruct * src);
|
||||
filestruct *make_new_node(filestruct * prevnode);
|
||||
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
openfilestruct *make_new_opennode(openfilestruct * prevnode);
|
||||
#endif
|
||||
|
||||
filestruct *findnextstr(int quiet, int bracket_mode, filestruct * begin,
|
||||
int beginx, char *needle);
|
||||
|
||||
#ifndef DISABLE_HELP
|
||||
void help_init(void);
|
||||
#endif
|
||||
int do_cursorpos(int constant);
|
||||
int do_cursorpos_void(void);
|
||||
int total_refresh(void);
|
||||
int do_help(void);
|
||||
int keypad_on(WINDOW *win, int newval);
|
||||
|
387
rcfile.c
387
rcfile.c
@ -29,6 +29,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
#include "config.h"
|
||||
#include "proto.h"
|
||||
#include "nano.h"
|
||||
@ -43,7 +44,7 @@
|
||||
#endif
|
||||
|
||||
/* Static stuff for the nanorc file */
|
||||
rcoption rcopts[] = {
|
||||
static rcoption rcopts[] = {
|
||||
#ifndef NANO_SMALL
|
||||
{"autoindent", AUTOINDENT},
|
||||
{"backup", BACKUP_FILE},
|
||||
@ -52,7 +53,9 @@ rcoption rcopts[] = {
|
||||
#ifndef NANO_SMALL
|
||||
{"cut", CUT_TO_END},
|
||||
#endif
|
||||
#ifndef DISABLE_WRAPJUSTIFY
|
||||
{"fill", 0},
|
||||
#endif
|
||||
{"keypad", ALT_KEYPAD},
|
||||
#ifndef DISABLE_MOUSE
|
||||
{"mouse", USE_MOUSE},
|
||||
@ -65,7 +68,9 @@ rcoption rcopts[] = {
|
||||
#endif
|
||||
{"nofollow", FOLLOW_SYMLINKS},
|
||||
{"nohelp", NO_HELP},
|
||||
#ifndef DISABLE_WRAPPING
|
||||
{"nowrap", NO_WRAP},
|
||||
#endif
|
||||
#ifndef DISABLE_OPERATINGDIR
|
||||
{"operatingdir", 0},
|
||||
#endif
|
||||
@ -94,8 +99,8 @@ static int lineno = 0;
|
||||
static char *nanorc;
|
||||
|
||||
/* We have an error in some part of the rcfile; put it on stderr and
|
||||
make the user hit return to continue starting up nano */
|
||||
void rcfile_error(char *msg, ...)
|
||||
make the user hit return to continue starting up nano. */
|
||||
static void rcfile_error(const char *msg, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
@ -109,11 +114,10 @@ void rcfile_error(char *msg, ...)
|
||||
fprintf(stderr, _("\nPress return to continue starting nano\n"));
|
||||
|
||||
while (getchar() != '\n');
|
||||
|
||||
}
|
||||
|
||||
/* Just print the error (one of many, perhaps) but don't abort, yet */
|
||||
void rcfile_msg(char *msg, ...)
|
||||
/* Just print the error (one of many, perhaps) but don't abort, yet. */
|
||||
static void rcfile_msg(const char *msg, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
@ -125,11 +129,10 @@ void rcfile_msg(char *msg, ...)
|
||||
vfprintf(stderr, msg, ap);
|
||||
va_end(ap);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
}
|
||||
|
||||
/* Parse the next word from the string. Returns NULL if we hit EOL */
|
||||
char *parse_next_word(char *ptr)
|
||||
/* Parse the next word from the string. Returns NULL if we hit EOL. */
|
||||
static char *parse_next_word(char *ptr)
|
||||
{
|
||||
while (*ptr != ' ' && *ptr != '\t' && *ptr != '\n' && *ptr != '\0')
|
||||
ptr++;
|
||||
@ -140,15 +143,54 @@ char *parse_next_word(char *ptr)
|
||||
/* Null terminate and advance ptr */
|
||||
*ptr++ = 0;
|
||||
|
||||
while ((*ptr == ' ' || *ptr == '\t') && *ptr != '\0')
|
||||
while (*ptr == ' ' || *ptr == '\t')
|
||||
ptr++;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
char *parse_next_regex(char *ptr)
|
||||
/* The keywords operatingdir, fill, tabsize, speller, and quotestr take
|
||||
* an argument when set. Among these, operatingdir, speller, and
|
||||
* quotestr have to allow tabs and spaces in the argument. Thus, if the
|
||||
* next word starts with a ", we say it ends with the last " of the line.
|
||||
* Otherwise, the word is interpreted as usual. That is so the arguments
|
||||
* can contain "s too. */
|
||||
static char *parse_argument(char *ptr) {
|
||||
const char *ptr_bak = ptr;
|
||||
char *last_quote = NULL;
|
||||
|
||||
assert(ptr != NULL);
|
||||
|
||||
if (*ptr != '"')
|
||||
return parse_next_word(ptr);
|
||||
|
||||
do {
|
||||
ptr++;
|
||||
if (*ptr == '"')
|
||||
last_quote = ptr;
|
||||
} while (*ptr != '\n' && *ptr != '\0');
|
||||
|
||||
if (last_quote == NULL) {
|
||||
if (*ptr == '\0')
|
||||
ptr = NULL;
|
||||
else
|
||||
*ptr++ = '\0';
|
||||
rcfile_error(_("argument %s has unterminated \""), ptr_bak);
|
||||
} else {
|
||||
*last_quote = '\0';
|
||||
ptr = last_quote + 1;
|
||||
}
|
||||
if (ptr != NULL)
|
||||
while (*ptr == ' ' || *ptr == '\t')
|
||||
ptr++;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
|
||||
static char *parse_next_regex(char *ptr)
|
||||
{
|
||||
while ((*ptr != '"' || (*(ptr+1) != ' ' && *(ptr+1) != '\n'))
|
||||
while ((*ptr != '"' || (*(ptr + 1) != ' ' && *(ptr + 1) != '\n'))
|
||||
&& *ptr != '\n' && *ptr != '\0')
|
||||
ptr++;
|
||||
|
||||
@ -156,45 +198,42 @@ char *parse_next_regex(char *ptr)
|
||||
return NULL;
|
||||
|
||||
/* Null terminate and advance ptr */
|
||||
*ptr++ = 0;
|
||||
*ptr++ = '\0';
|
||||
|
||||
while ((*ptr == ' ' || *ptr == '\t') && *ptr != '\0')
|
||||
while (*ptr == ' ' || *ptr == '\t')
|
||||
ptr++;
|
||||
|
||||
return ptr;
|
||||
|
||||
}
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
|
||||
int colortoint(char *colorname, int *bright)
|
||||
static int colortoint(const char *colorname, int *bright)
|
||||
{
|
||||
int mcolor = 0;
|
||||
|
||||
if (colorname == NULL)
|
||||
return -1;
|
||||
|
||||
if (stristr(colorname, "bright")) {
|
||||
if (!strncasecmp(colorname, "bright", 6)) {
|
||||
*bright = 1;
|
||||
colorname += 6;
|
||||
}
|
||||
|
||||
if (!strcasecmp(colorname, "green"))
|
||||
mcolor += COLOR_GREEN;
|
||||
mcolor = COLOR_GREEN;
|
||||
else if (!strcasecmp(colorname, "red"))
|
||||
mcolor += COLOR_RED;
|
||||
mcolor = COLOR_RED;
|
||||
else if (!strcasecmp(colorname, "blue"))
|
||||
mcolor += COLOR_BLUE;
|
||||
mcolor = COLOR_BLUE;
|
||||
else if (!strcasecmp(colorname, "white"))
|
||||
mcolor += COLOR_WHITE;
|
||||
mcolor = COLOR_WHITE;
|
||||
else if (!strcasecmp(colorname, "yellow"))
|
||||
mcolor += COLOR_YELLOW;
|
||||
mcolor = COLOR_YELLOW;
|
||||
else if (!strcasecmp(colorname, "cyan"))
|
||||
mcolor += COLOR_CYAN;
|
||||
mcolor = COLOR_CYAN;
|
||||
else if (!strcasecmp(colorname, "magenta"))
|
||||
mcolor += COLOR_MAGENTA;
|
||||
mcolor = COLOR_MAGENTA;
|
||||
else if (!strcasecmp(colorname, "black"))
|
||||
mcolor += COLOR_BLACK;
|
||||
mcolor = COLOR_BLACK;
|
||||
else {
|
||||
rcfile_error(_("color %s not understood.\n"
|
||||
"Valid colors are \"green\", \"red\", \"blue\", \n"
|
||||
@ -206,10 +245,10 @@ int colortoint(char *colorname, int *bright)
|
||||
return mcolor;
|
||||
}
|
||||
|
||||
void parse_syntax(FILE * rcstream, char *buf, char *ptr)
|
||||
static void parse_syntax(char *ptr)
|
||||
{
|
||||
syntaxtype *tmpsyntax = NULL;
|
||||
char *fileregptr = NULL, *nameptr = NULL;
|
||||
const char *fileregptr = NULL, *nameptr = NULL;
|
||||
exttype *exttmp = NULL;
|
||||
|
||||
while (*ptr == ' ')
|
||||
@ -232,39 +271,30 @@ void parse_syntax(FILE * rcstream, char *buf, char *ptr)
|
||||
return;
|
||||
}
|
||||
|
||||
if (syntaxes == NULL) {
|
||||
syntaxes = nmalloc(sizeof(syntaxtype));
|
||||
syntaxes->desc = NULL;
|
||||
syntaxes->desc = mallocstrcpy(syntaxes->desc, nameptr);
|
||||
syntaxes->color = NULL;
|
||||
syntaxes->extensions = NULL;
|
||||
syntaxes->next = NULL;
|
||||
tmpsyntax = syntaxes;
|
||||
if (syntaxes == NULL) {
|
||||
syntaxes = (syntaxtype *)nmalloc(sizeof(syntaxtype));
|
||||
tmpsyntax = syntaxes;
|
||||
} else {
|
||||
for (tmpsyntax = syntaxes; tmpsyntax->next != NULL;
|
||||
tmpsyntax = tmpsyntax->next)
|
||||
;
|
||||
tmpsyntax->next = (syntaxtype *)nmalloc(sizeof(syntaxtype));
|
||||
tmpsyntax = tmpsyntax->next;
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr,
|
||||
_("Starting a new syntax type\n"));
|
||||
fprintf(stderr, "string val=%s\n", nameptr);
|
||||
fprintf(stderr, _("Adding new syntax after 1st\n"));
|
||||
#endif
|
||||
|
||||
} else {
|
||||
for (tmpsyntax = syntaxes;
|
||||
tmpsyntax->next != NULL; tmpsyntax = tmpsyntax->next);
|
||||
}
|
||||
tmpsyntax->desc = mallocstrcpy(NULL, nameptr);
|
||||
tmpsyntax->color = NULL;
|
||||
tmpsyntax->extensions = NULL;
|
||||
tmpsyntax->next = NULL;
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, _("Adding new syntax after 1st\n"));
|
||||
fprintf(stderr, _("Starting a new syntax type\n"));
|
||||
fprintf(stderr, "string val=%s\n", nameptr);
|
||||
#endif
|
||||
|
||||
tmpsyntax->next = nmalloc(sizeof(syntaxtype));
|
||||
tmpsyntax->next->desc = NULL;
|
||||
tmpsyntax->next->desc = mallocstrcpy(tmpsyntax->next->desc, nameptr);
|
||||
tmpsyntax->next->color = NULL;
|
||||
tmpsyntax->next->extensions = NULL;
|
||||
tmpsyntax->next->next = NULL;
|
||||
tmpsyntax = tmpsyntax->next;
|
||||
}
|
||||
|
||||
/* Now load in the extensions to their part of the struct */
|
||||
while (*ptr != '\n' && *ptr != '\0') {
|
||||
|
||||
while (*ptr != '"' && *ptr != '\n' && *ptr != '\0')
|
||||
ptr++;
|
||||
|
||||
@ -276,28 +306,25 @@ void parse_syntax(FILE * rcstream, char *buf, char *ptr)
|
||||
ptr = parse_next_regex(ptr);
|
||||
|
||||
if (tmpsyntax->extensions == NULL) {
|
||||
tmpsyntax->extensions = nmalloc(sizeof(exttype));
|
||||
tmpsyntax->extensions->val = NULL;
|
||||
tmpsyntax->extensions->val = mallocstrcpy(tmpsyntax->extensions->val, fileregptr);
|
||||
tmpsyntax->extensions->next = NULL;
|
||||
}
|
||||
else {
|
||||
tmpsyntax->extensions = (exttype *)nmalloc(sizeof(exttype));
|
||||
exttmp = tmpsyntax->extensions;
|
||||
} else {
|
||||
for (exttmp = tmpsyntax->extensions; exttmp->next != NULL;
|
||||
exttmp = exttmp->next);
|
||||
exttmp->next = nmalloc(sizeof(exttype));
|
||||
exttmp->next->val = NULL;
|
||||
exttmp->next->val = mallocstrcpy(exttmp->next->val, fileregptr);
|
||||
exttmp->next->next = NULL;
|
||||
exttmp->next = (exttype *)nmalloc(sizeof(exttype));
|
||||
exttmp = exttmp->next;
|
||||
}
|
||||
exttmp->val = mallocstrcpy(NULL, fileregptr);
|
||||
exttmp->next = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse the color stuff into the colorstrings array */
|
||||
void parse_colors(FILE * rcstream, char *buf, char *ptr)
|
||||
static void parse_colors(char *ptr)
|
||||
{
|
||||
int fg, bg, bright = 0;
|
||||
int expectend = 0; /* Do we expect an end= line? */
|
||||
char *tmp = NULL, *beginning, *fgstr, *bgstr;
|
||||
char *fgstr;
|
||||
colortype *tmpcolor = NULL;
|
||||
syntaxtype *tmpsyntax = NULL;
|
||||
|
||||
@ -311,12 +338,11 @@ void parse_colors(FILE * rcstream, char *buf, char *ptr)
|
||||
|
||||
if (strstr(fgstr, ",")) {
|
||||
strtok(fgstr, ",");
|
||||
bgstr = strtok(NULL, ",");
|
||||
bg = colortoint(strtok(NULL, ","), &bright);
|
||||
} else
|
||||
bgstr = NULL;
|
||||
bg = -1;
|
||||
|
||||
fg = colortoint(fgstr, &bright);
|
||||
bg = colortoint(bgstr, &bright);
|
||||
|
||||
if (syntaxes == NULL) {
|
||||
rcfile_error(_("Cannot add a color directive without a syntax line"));
|
||||
@ -331,7 +357,6 @@ void parse_colors(FILE * rcstream, char *buf, char *ptr)
|
||||
in the colorstrings array, woo! */
|
||||
|
||||
while (*ptr != '\0') {
|
||||
|
||||
while (*ptr == ' ')
|
||||
ptr++;
|
||||
|
||||
@ -349,45 +374,37 @@ void parse_colors(FILE * rcstream, char *buf, char *ptr)
|
||||
}
|
||||
ptr++;
|
||||
|
||||
beginning = ptr;
|
||||
ptr = parse_next_regex(ptr);
|
||||
|
||||
tmp = NULL;
|
||||
tmp = mallocstrcpy(tmp, beginning);
|
||||
|
||||
if (tmpsyntax->color == NULL) {
|
||||
tmpsyntax->color = nmalloc(sizeof(colortype));
|
||||
tmpsyntax->color->fg = fg;
|
||||
tmpsyntax->color->bg = bg;
|
||||
tmpsyntax->color->bright = bright;
|
||||
tmpsyntax->color->start = tmp;
|
||||
tmpsyntax->color->next = NULL;
|
||||
tmpcolor = tmpsyntax->color;
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr,
|
||||
_("Starting a new colorstring for fg %d bg %d\n"),
|
||||
fprintf(stderr, _("Starting a new colorstring for fg %d bg %d\n"),
|
||||
fg, bg);
|
||||
fprintf(stderr, _("string val=%s\n"), tmp);
|
||||
#endif
|
||||
|
||||
} else {
|
||||
for (tmpcolor = tmpsyntax->color;
|
||||
tmpcolor->next != NULL; tmpcolor = tmpcolor->next);
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, _("Adding new entry for fg %d bg %d\n"), fg, bg);
|
||||
fprintf(stderr, _("string val=%s\n"), tmp);
|
||||
#endif
|
||||
|
||||
tmpcolor->next = nmalloc(sizeof(colortype));
|
||||
tmpcolor->next->fg = fg;
|
||||
tmpcolor->next->bg = bg;
|
||||
tmpcolor->next->bright = bright;
|
||||
tmpcolor->next->start = tmp;
|
||||
tmpcolor->next->next = NULL;
|
||||
tmpcolor = tmpcolor->next;
|
||||
}
|
||||
tmpcolor->fg = fg;
|
||||
tmpcolor->bg = bg;
|
||||
tmpcolor->bright = bright;
|
||||
tmpcolor->next = NULL;
|
||||
|
||||
if (expectend) {
|
||||
tmpcolor->start = ptr;
|
||||
ptr = parse_next_regex(ptr);
|
||||
tmpcolor->start = mallocstrcpy(NULL, tmpcolor->start);
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, _("string val=%s\n"), tmpcolor->start);
|
||||
#endif
|
||||
|
||||
if (!expectend)
|
||||
tmpcolor->end = NULL;
|
||||
else {
|
||||
if (ptr == NULL || strncasecmp(ptr, "end=", 4)) {
|
||||
rcfile_error(_
|
||||
("\n\t\"start=\" requires a corresponding \"end=\""));
|
||||
@ -403,37 +420,30 @@ void parse_colors(FILE * rcstream, char *buf, char *ptr)
|
||||
}
|
||||
ptr++;
|
||||
|
||||
|
||||
beginning = ptr;
|
||||
tmpcolor->end = ptr;
|
||||
ptr = parse_next_regex(ptr);
|
||||
tmpcolor->end = mallocstrcpy(NULL, tmpcolor->end);
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, _("For end part, beginning = \"%s\"\n"),
|
||||
beginning);
|
||||
tmpcolor->end);
|
||||
#endif
|
||||
tmp = NULL;
|
||||
tmp = mallocstrcpy(tmp, beginning);
|
||||
tmpcolor->end = tmp;
|
||||
|
||||
} else
|
||||
tmpcolor->end = NULL;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* ENABLE_COLOR */
|
||||
|
||||
/* Parse the RC file, once it has been opened successfully */
|
||||
void parse_rcfile(FILE * rcstream)
|
||||
static void parse_rcfile(FILE *rcstream)
|
||||
{
|
||||
char *buf, *ptr, *keyword, *option;
|
||||
int set = 0, i, j;
|
||||
|
||||
buf = charalloc(1024);
|
||||
while (fgets(buf, 1023, rcstream) > 0) {
|
||||
while (fgets(buf, 1023, rcstream) != 0) {
|
||||
lineno++;
|
||||
ptr = buf;
|
||||
while ((*ptr == ' ' || *ptr == '\t') &&
|
||||
(*ptr != '\n' && *ptr != '\0'))
|
||||
while (*ptr == ' ' || *ptr == '\t')
|
||||
ptr++;
|
||||
|
||||
if (*ptr == '\n' || *ptr == '\0')
|
||||
@ -459,9 +469,9 @@ void parse_rcfile(FILE * rcstream)
|
||||
set = -1;
|
||||
#ifdef ENABLE_COLOR
|
||||
else if (!strcasecmp(keyword, "syntax"))
|
||||
parse_syntax(rcstream, buf, ptr);
|
||||
parse_syntax(ptr);
|
||||
else if (!strcasecmp(keyword, "color"))
|
||||
parse_colors(rcstream, buf, ptr);
|
||||
parse_colors(ptr);
|
||||
#endif /* ENABLE_COLOR */
|
||||
else {
|
||||
rcfile_msg(_("command %s not understood"), keyword);
|
||||
@ -480,21 +490,20 @@ void parse_rcfile(FILE * rcstream)
|
||||
rcopts[i].name);
|
||||
#endif
|
||||
if (set == 1 || rcopts[i].flag == FOLLOW_SYMLINKS) {
|
||||
if (!strcasecmp(rcopts[i].name, "operatingdir") ||
|
||||
!strcasecmp(rcopts[i].name, "tabsize") ||
|
||||
if (!strcasecmp(rcopts[i].name, "tabsize")
|
||||
#ifndef DISABLE_OPERATINGDIR
|
||||
|| !strcasecmp(rcopts[i].name, "operatingdir")
|
||||
#endif
|
||||
#ifndef DISABLE_WRAPJUSTIFY
|
||||
!strcasecmp(rcopts[i].name, "fill") ||
|
||||
|| !strcasecmp(rcopts[i].name, "fill")
|
||||
#endif
|
||||
#ifndef DISABLE_JUSTIFY
|
||||
!strcasecmp(rcopts[i].name, "quotestr") ||
|
||||
|| !strcasecmp(rcopts[i].name, "quotestr")
|
||||
#endif
|
||||
#ifndef DISABLE_SPELLER
|
||||
!strcasecmp(rcopts[i].name, "speller")
|
||||
#else
|
||||
0
|
||||
|| !strcasecmp(rcopts[i].name, "speller")
|
||||
#endif
|
||||
) {
|
||||
|
||||
) {
|
||||
if (*ptr == '\n' || *ptr == '\0') {
|
||||
rcfile_error(_
|
||||
("option %s requires an argument"),
|
||||
@ -502,42 +511,54 @@ void parse_rcfile(FILE * rcstream)
|
||||
continue;
|
||||
}
|
||||
option = ptr;
|
||||
ptr = parse_next_word(ptr);
|
||||
if (!strcasecmp(rcopts[i].name, "fill")) {
|
||||
if (*option == '"')
|
||||
option++;
|
||||
ptr = parse_argument(ptr);
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "option = %s\n", option);
|
||||
#endif
|
||||
#ifndef DISABLE_OPERATINGDIR
|
||||
if (!strcasecmp(rcopts[i].name, "operatingdir"))
|
||||
operating_dir = mallocstrcpy(NULL, option);
|
||||
else
|
||||
#endif
|
||||
#ifndef DISABLE_WRAPJUSTIFY
|
||||
if (!strcasecmp(rcopts[i].name, "fill")) {
|
||||
char *first_error;
|
||||
|
||||
if ((j = atoi(option)) < MIN_FILL_LENGTH) {
|
||||
rcfile_error(_
|
||||
("requested fill size %d too small"),
|
||||
/* Using strtol instead of atoi lets us
|
||||
* accept 0 while checking other
|
||||
* errors. */
|
||||
j = (int)strtol(option, &first_error, 10);
|
||||
if (errno == ERANGE || *option == '\0' || *first_error != '\0')
|
||||
rcfile_error(_("requested fill size %d invalid"),
|
||||
j);
|
||||
} else
|
||||
fill = j;
|
||||
#endif
|
||||
else
|
||||
wrap_at = j;
|
||||
} else
|
||||
if (!strcasecmp(rcopts[i].name, "tabsize"))
|
||||
{
|
||||
if ((j = atoi(option)) <= 0) {
|
||||
rcfile_error(_
|
||||
("requested tab size %d too small"),
|
||||
j);
|
||||
} else {
|
||||
tabsize = j;
|
||||
}
|
||||
#endif
|
||||
#ifndef DISABLE_JUSTIFY
|
||||
} else
|
||||
if (!strcasecmp(rcopts[i].name, "quotestr"))
|
||||
{
|
||||
quotestr = NULL;
|
||||
quotestr =
|
||||
charalloc(strlen(option) + 1);
|
||||
strcpy(quotestr, option);
|
||||
if (!strcasecmp(rcopts[i].name, "quotestr"))
|
||||
quotestr = mallocstrcpy(NULL, option);
|
||||
else
|
||||
#endif
|
||||
} else {
|
||||
#ifndef DISABLE_SPELLER
|
||||
alt_speller =
|
||||
charalloc(strlen(option) + 1);
|
||||
strcpy(alt_speller, option);
|
||||
if (!strcasecmp(rcopts[i].name, "speller"))
|
||||
alt_speller = mallocstrcpy(NULL, option);
|
||||
else
|
||||
#endif
|
||||
{
|
||||
char *first_error;
|
||||
|
||||
/* Using strtol instead of atoi lets us
|
||||
* accept 0 while checking other
|
||||
* errors. */
|
||||
j = (int)strtol(option, &first_error, 10);
|
||||
if (errno == ERANGE || *option == '\0' || *first_error != '\0')
|
||||
rcfile_error(_("requested tab size %d invalid"),
|
||||
j);
|
||||
else
|
||||
tabsize = j;
|
||||
}
|
||||
} else
|
||||
SET(rcopts[i].flag);
|
||||
@ -555,8 +576,8 @@ void parse_rcfile(FILE * rcstream)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
free(buf);
|
||||
if (errors)
|
||||
rcfile_error(_("Errors found in .nanorc file"));
|
||||
|
||||
@ -566,56 +587,48 @@ void parse_rcfile(FILE * rcstream)
|
||||
/* The main rc file function, tries to open the rc file */
|
||||
void do_rcfile(void)
|
||||
{
|
||||
char *unable = _("Unable to open ~/.nanorc file, %s");
|
||||
struct stat fileinfo;
|
||||
FILE *rcstream;
|
||||
struct passwd *userage;
|
||||
const struct passwd *userage;
|
||||
uid_t euid = geteuid();
|
||||
|
||||
nanorc = charalloc(strlen(SYSCONFDIR) + 10);
|
||||
#ifdef SYSCONFDIR
|
||||
assert(sizeof(SYSCONFDIR) == strlen(SYSCONFDIR) + 1);
|
||||
nanorc = charalloc(sizeof(SYSCONFDIR) + 7);
|
||||
sprintf(nanorc, "%s/nanorc", SYSCONFDIR);
|
||||
|
||||
/* Try to open system nanorc */
|
||||
if (stat(nanorc, &fileinfo) != -1)
|
||||
if ((rcstream = fopen(nanorc, "r")) != NULL) {
|
||||
if ((rcstream = fopen(nanorc, "r")) != NULL) {
|
||||
/* Parse it! */
|
||||
parse_rcfile(rcstream);
|
||||
fclose(rcstream);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Parse it! */
|
||||
parse_rcfile(rcstream);
|
||||
fclose(rcstream);
|
||||
}
|
||||
/* Determine home directory using getpwent(), don't rely on $HOME */
|
||||
do {
|
||||
userage = getpwent();
|
||||
} while (userage != NULL && userage->pw_uid != euid);
|
||||
endpwent();
|
||||
|
||||
lineno = 0;
|
||||
|
||||
/* Determine home directory using getpwent(), don't rely on $HOME */
|
||||
for (userage = getpwent(); userage != NULL
|
||||
&& userage->pw_uid != geteuid(); userage = getpwent())
|
||||
;
|
||||
|
||||
if (userage == NULL) {
|
||||
if (userage == NULL)
|
||||
rcfile_error(_("I can't find my home directory! Wah!"));
|
||||
return;
|
||||
else {
|
||||
nanorc = nrealloc(nanorc, strlen(userage->pw_dir) + 9);
|
||||
sprintf(nanorc, "%s/.nanorc", userage->pw_dir);
|
||||
|
||||
if ((rcstream = fopen(nanorc, "r")) == NULL) {
|
||||
/* Don't complain about the file not existing */
|
||||
if (errno != ENOENT)
|
||||
rcfile_error(_("Unable to open ~/.nanorc file, %s"),
|
||||
strerror(errno));
|
||||
} else {
|
||||
parse_rcfile(rcstream);
|
||||
fclose(rcstream);
|
||||
}
|
||||
}
|
||||
|
||||
nanorc = charalloc(strlen(userage->pw_dir) + 10);
|
||||
sprintf(nanorc, "%s/.nanorc", userage->pw_dir);
|
||||
|
||||
if (stat(nanorc, &fileinfo) == -1) {
|
||||
|
||||
/* Abort if the file doesn't exist and there's some other kind
|
||||
of error stat()ing it */
|
||||
if (errno != ENOENT)
|
||||
rcfile_error(unable, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
if ((rcstream = fopen(nanorc, "r")) == NULL) {
|
||||
rcfile_error(unable, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
parse_rcfile(rcstream);
|
||||
fclose(rcstream);
|
||||
|
||||
free(nanorc);
|
||||
}
|
||||
|
||||
#endif /* ENABLE_NANORC */
|
||||
|
303
search.c
303
search.c
@ -26,6 +26,7 @@
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include "proto.h"
|
||||
#include "nano.h"
|
||||
|
||||
@ -70,7 +71,7 @@ void search_init_globals(void)
|
||||
|
||||
replacing = 1 if we call from do_replace, 0 if called from do_search func.
|
||||
*/
|
||||
int search_init(int replacing)
|
||||
static int search_init(int replacing)
|
||||
{
|
||||
int i = 0;
|
||||
char *buf;
|
||||
@ -78,10 +79,6 @@ int search_init(int replacing)
|
||||
|
||||
search_init_globals();
|
||||
|
||||
buf = charalloc(strlen(last_search) + 5);
|
||||
buf[0] = '\0';
|
||||
|
||||
|
||||
/* Clear the backupstring if we've changed from Pico mode to regular
|
||||
mode */
|
||||
if (ISSET(CLEAR_BACKUPSTRING)) {
|
||||
@ -96,7 +93,7 @@ int search_init(int replacing)
|
||||
old string back up as editable if it's not the same as last_search.
|
||||
|
||||
Otherwise, if we don't already have a backupstring, set it to
|
||||
last_search. */
|
||||
last_search. */
|
||||
|
||||
if (ISSET(PICO_MODE)) {
|
||||
if (backupstring == NULL || !strcmp(backupstring, last_search))
|
||||
@ -106,21 +103,20 @@ int search_init(int replacing)
|
||||
backupstring = mallocstrcpy(backupstring, last_search);
|
||||
|
||||
/* If using Pico messages, we do things the old fashioned way... */
|
||||
if (ISSET(PICO_MODE)) {
|
||||
if (last_search[0]) {
|
||||
if (ISSET(PICO_MODE) && last_search[0]) {
|
||||
size_t last_search_len = strlen(last_search);
|
||||
|
||||
/* We use COLS / 3 here because we need to see more on the line */
|
||||
if (strlen(last_search) > COLS / 3) {
|
||||
snprintf(buf, COLS / 3 + 3, " [%s", last_search);
|
||||
sprintf(&buf[COLS / 3 + 2], "...]");
|
||||
} else
|
||||
sprintf(buf, " [%s]", last_search);
|
||||
} else {
|
||||
buf[0] = '\0';
|
||||
}
|
||||
}
|
||||
else
|
||||
buf = charalloc(last_search_len > COLS / 3 ?
|
||||
COLS / 3 + 7 : last_search_len + 4);
|
||||
/* We use COLS / 3 here because we need to see more on the line */
|
||||
if (last_search_len > COLS / 3)
|
||||
snprintf(buf, COLS / 3 + 7, " [%s...]", last_search);
|
||||
else
|
||||
sprintf(buf, " [%s]", last_search);
|
||||
} else {
|
||||
buf = charalloc(1);
|
||||
buf[0] = '\0';
|
||||
}
|
||||
|
||||
/* This is now one simple call. It just does a lot */
|
||||
i = statusq(0, replacing ? replace_list : whereis_list, backupstring,
|
||||
@ -146,120 +142,107 @@ int search_init(int replacing)
|
||||
free(buf);
|
||||
|
||||
/* Cancel any search, or just return with no previous search */
|
||||
if ((i == -1) || (i < 0 && !last_search[0])) {
|
||||
if (i == -1 || (i < 0 && last_search[0] == '\0')) {
|
||||
statusbar(_("Search Cancelled"));
|
||||
reset_cursor();
|
||||
free(backupstring);
|
||||
backupstring = NULL;
|
||||
return -1;
|
||||
} else
|
||||
switch (i) {
|
||||
|
||||
case -2: /* Same string */
|
||||
} else {
|
||||
switch (i) {
|
||||
case -2: /* Same string */
|
||||
#ifdef HAVE_REGEX_H
|
||||
if (ISSET(USE_REGEXP)) {
|
||||
|
||||
/* If we're in pico mode, answer is "", use last_search! */
|
||||
if (ISSET(PICO_MODE))
|
||||
regexp_init(last_search);
|
||||
else
|
||||
if (ISSET(USE_REGEXP))
|
||||
/* If we're in Pico mode, and answer is "", use
|
||||
last_search! */
|
||||
regexp_init(ISSET(PICO_MODE) ? last_search : answer);
|
||||
#endif
|
||||
break;
|
||||
case 0: /* They entered something new */
|
||||
#ifdef HAVE_REGEX_H
|
||||
if (ISSET(USE_REGEXP))
|
||||
regexp_init(answer);
|
||||
#endif
|
||||
free(backupstring);
|
||||
backupstring = NULL;
|
||||
last_replace[0] = '\0';
|
||||
break;
|
||||
#ifndef NANO_SMALL
|
||||
case TOGGLE_CASE_KEY:
|
||||
TOGGLE(CASE_SENSITIVE);
|
||||
backupstring = mallocstrcpy(backupstring, answer);
|
||||
return 1;
|
||||
case TOGGLE_BACKWARDS_KEY:
|
||||
TOGGLE(REVERSE_SEARCH);
|
||||
backupstring = mallocstrcpy(backupstring, answer);
|
||||
return 1;
|
||||
#ifdef HAVE_REGEX_H
|
||||
case TOGGLE_REGEXP_KEY:
|
||||
TOGGLE(USE_REGEXP);
|
||||
backupstring = mallocstrcpy(backupstring, answer);
|
||||
return 1;
|
||||
#endif
|
||||
#endif /* !NANO_SMALL */
|
||||
case NANO_OTHERSEARCH_KEY:
|
||||
backupstring = mallocstrcpy(backupstring, answer);
|
||||
return -2; /* Call the opposite search function */
|
||||
case NANO_FROMSEARCHTOGOTO_KEY:
|
||||
free(backupstring);
|
||||
backupstring = NULL;
|
||||
do_gotoline_void();
|
||||
return -3;
|
||||
default:
|
||||
do_early_abort();
|
||||
free(backupstring);
|
||||
backupstring = NULL;
|
||||
return -3;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case 0: /* They entered something new */
|
||||
#ifdef HAVE_REGEX_H
|
||||
if (ISSET(USE_REGEXP))
|
||||
regexp_init(answer);
|
||||
#endif
|
||||
free(backupstring);
|
||||
backupstring = NULL;
|
||||
last_replace[0] = '\0';
|
||||
break;
|
||||
case TOGGLE_CASE_KEY:
|
||||
TOGGLE(CASE_SENSITIVE);
|
||||
goto string_reinit;
|
||||
case TOGGLE_BACKWARDS_KEY:
|
||||
TOGGLE(REVERSE_SEARCH);
|
||||
goto string_reinit;
|
||||
#ifdef HAVE_REGEX_H
|
||||
case TOGGLE_REGEXP_KEY:
|
||||
TOGGLE(USE_REGEXP);
|
||||
#endif
|
||||
string_reinit:
|
||||
free(backupstring);
|
||||
backupstring = NULL;
|
||||
backupstring = mallocstrcpy(backupstring, answer);
|
||||
return 1;
|
||||
case NANO_OTHERSEARCH_KEY:
|
||||
backupstring = mallocstrcpy(backupstring, answer);
|
||||
return -2; /* Call the opposite search function */
|
||||
case NANO_FROMSEARCHTOGOTO_KEY:
|
||||
free(backupstring);
|
||||
backupstring = NULL;
|
||||
do_gotoline_void();
|
||||
return -3;
|
||||
default:
|
||||
do_early_abort();
|
||||
free(backupstring);
|
||||
backupstring = NULL;
|
||||
return -3;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void not_found_msg(char *str)
|
||||
void not_found_msg(const char *str)
|
||||
{
|
||||
if (strlen(str) <= COLS / 2)
|
||||
statusbar(_("\"%s\" not found"), str);
|
||||
else {
|
||||
char *foo = NULL;
|
||||
char *foo = mallocstrcpy(NULL, str);
|
||||
|
||||
foo = mallocstrcpy(foo, str);
|
||||
foo[COLS / 2] = '\0';
|
||||
statusbar(_("\"%s...\" not found"), foo);
|
||||
|
||||
free(foo);
|
||||
}
|
||||
}
|
||||
|
||||
int is_whole_word(int curr_pos, filestruct *fileptr, char *searchword)
|
||||
int is_whole_word(int curr_pos, const char *datastr, const char *searchword)
|
||||
{
|
||||
/* start of line or previous character not a letter */
|
||||
if ((curr_pos < 1) || (!isalpha((int) fileptr->data[curr_pos-1])))
|
||||
size_t sln = curr_pos + strlen(searchword);
|
||||
|
||||
/* end of line or next character not a letter */
|
||||
if (((curr_pos + strlen(searchword)) == strlen(fileptr->data))
|
||||
|| (!isalpha((int) fileptr->data[curr_pos + strlen(searchword)])))
|
||||
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
/* start of line or previous character not a letter and end of line
|
||||
* or next character not a letter */
|
||||
return (curr_pos < 1 || !isalpha((int) datastr[curr_pos - 1])) &&
|
||||
(sln == strlen(datastr) || !isalpha((int) datastr[sln]));
|
||||
}
|
||||
|
||||
int past_editbuff; /* findnextstr() is now searching lines not displayed */
|
||||
static int past_editbuff;
|
||||
/* findnextstr() is now searching lines not displayed */
|
||||
|
||||
filestruct *findnextstr(int quiet, int bracket_mode, filestruct * begin, int beginx,
|
||||
char *needle)
|
||||
filestruct *findnextstr(int quiet, int bracket_mode,
|
||||
const filestruct *begin, int beginx, const char *needle)
|
||||
{
|
||||
filestruct *fileptr = current;
|
||||
char *searchstr, *rev_start = NULL, *found = NULL;
|
||||
const char *searchstr, *rev_start = NULL, *found = NULL;
|
||||
int current_x_find = 0;
|
||||
|
||||
past_editbuff = 0;
|
||||
|
||||
if (!ISSET(REVERSE_SEARCH)) { /* forward search */
|
||||
|
||||
current_x_find = current_x + 1;
|
||||
#if 0
|
||||
/* Are we now back to the place where the search started) */
|
||||
if ((fileptr == begin) && (beginx > current_x_find))
|
||||
search_last_line = 1;
|
||||
#endif
|
||||
/* Make sure we haven't passed the end of the string */
|
||||
if (strlen(fileptr->data) < current_x_find)
|
||||
current_x_find--;
|
||||
/* Argh, current_x is set to -1 by nano.c:do_int_spell_fix(), and
|
||||
* strlen returns size_t, which is unsigned. */
|
||||
assert(current_x < 0 || current_x <= strlen(fileptr->data));
|
||||
current_x_find = current_x;
|
||||
if (current_x_find < 0 || fileptr->data[current_x_find] != '\0')
|
||||
current_x_find++;
|
||||
|
||||
searchstr = &fileptr->data[current_x_find];
|
||||
|
||||
@ -306,35 +289,22 @@ filestruct *findnextstr(int quiet, int bracket_mode, filestruct * begin, int beg
|
||||
|
||||
/* We found an instance */
|
||||
current_x_find = found - fileptr->data;
|
||||
#if 1
|
||||
/* Ensure we haven't wrapped around again! */
|
||||
if ((search_last_line) && (current_x_find > beginx)) {
|
||||
if (!quiet)
|
||||
not_found_msg(needle);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#ifndef NANO_SMALL
|
||||
else { /* reverse search */
|
||||
|
||||
current_x_find = current_x - 1;
|
||||
#if 0
|
||||
/* Are we now back to the place where the search started) */
|
||||
if ((fileptr == begin) && (current_x_find > beginx))
|
||||
search_last_line = 1;
|
||||
#endif
|
||||
/* Make sure we haven't passed the begining of the string */
|
||||
#if 0 /* Is this required here ? */
|
||||
if (!(&fileptr->data[current_x_find] - fileptr->data))
|
||||
current_x_find++;
|
||||
#endif
|
||||
rev_start = &fileptr->data[current_x_find];
|
||||
searchstr = fileptr->data;
|
||||
|
||||
/* Look for needle in searchstr */
|
||||
while ((found = strstrwrapper(searchstr, needle, rev_start, current_x_find)) == NULL) {
|
||||
|
||||
/* finished processing file, get out */
|
||||
if (search_last_line) {
|
||||
if (!quiet)
|
||||
@ -363,7 +333,6 @@ filestruct *findnextstr(int quiet, int bracket_mode, filestruct * begin, int beg
|
||||
SET(DISABLE_CURPOS);
|
||||
}
|
||||
}
|
||||
|
||||
/* Original start line reached */
|
||||
if (fileptr == begin)
|
||||
search_last_line = 1;
|
||||
@ -374,16 +343,14 @@ filestruct *findnextstr(int quiet, int bracket_mode, filestruct * begin, int beg
|
||||
|
||||
/* We found an instance */
|
||||
current_x_find = found - fileptr->data;
|
||||
#if 1
|
||||
/* Ensure we haven't wrapped around again! */
|
||||
if ((search_last_line) && (current_x_find < beginx)) {
|
||||
if (!quiet)
|
||||
not_found_msg(needle);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif /* NANO_SMALL */
|
||||
#endif /* !NANO_SMALL */
|
||||
|
||||
/* Set globals now that we are sure we found something */
|
||||
current = fileptr;
|
||||
@ -398,7 +365,6 @@ filestruct *findnextstr(int quiet, int bracket_mode, filestruct * begin, int beg
|
||||
placewewant = xplustabs();
|
||||
reset_cursor();
|
||||
}
|
||||
|
||||
return fileptr;
|
||||
}
|
||||
|
||||
@ -416,7 +382,7 @@ void search_abort(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Search for a string */
|
||||
/* Search for a string. */
|
||||
int do_search(void)
|
||||
{
|
||||
int i;
|
||||
@ -499,8 +465,8 @@ int replace_regexp(char *string, int create_flag)
|
||||
|
||||
new_size -= search_match_count;
|
||||
|
||||
/* Iterate through the replacement text to handle
|
||||
* subexpression replacement using \1, \2, \3, etc */
|
||||
/* Iterate through the replacement text to handle subexpression
|
||||
* replacement using \1, \2, \3, etc. */
|
||||
|
||||
c = last_replace;
|
||||
while (*c) {
|
||||
@ -517,7 +483,7 @@ int replace_regexp(char *string, int create_flag)
|
||||
|
||||
if (num > search_regexp.re_nsub) {
|
||||
/* Ugh, they specified a subexpression that doesn't
|
||||
exist. */
|
||||
exist. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -588,12 +554,12 @@ char *replace_line(void)
|
||||
#endif
|
||||
|
||||
/* The tail of the original line */
|
||||
/* This may expose other bugs, because it no longer
|
||||
goes through each character in the string
|
||||
and tests for string goodness. But because
|
||||
we can assume the invariant that current->data
|
||||
is less than current_x + strlen(last_search) long,
|
||||
this should be safe. Or it will expose bugs ;-) */
|
||||
|
||||
/* This may expose other bugs, because it no longer goes through
|
||||
* each character in the string and tests for string goodness. But
|
||||
* because we can assume the invariant that current->data is less
|
||||
* than current_x + strlen(last_search) long, this should be safe.
|
||||
* Or it will expose bugs ;-) */
|
||||
tmp = current->data + current_x + search_match_count;
|
||||
strcat(copy, tmp);
|
||||
|
||||
@ -601,8 +567,8 @@ char *replace_line(void)
|
||||
}
|
||||
|
||||
/* step through each replace word and prompt user before replacing word */
|
||||
int do_replace_loop(char *prevanswer, filestruct *begin, int *beginx,
|
||||
int wholewords, int *i)
|
||||
int do_replace_loop(const char *prevanswer, const filestruct *begin,
|
||||
int *beginx, int wholewords, int *i)
|
||||
{
|
||||
int replaceall = 0, numreplaced = 0;
|
||||
|
||||
@ -610,7 +576,7 @@ int do_replace_loop(char *prevanswer, filestruct *begin, int *beginx,
|
||||
char *copy;
|
||||
|
||||
switch (*i) {
|
||||
case -1: /* Aborted enter */
|
||||
case -1: /* Aborted enter */
|
||||
if (last_replace[0] != '\0')
|
||||
answer = mallocstrcpy(answer, last_replace);
|
||||
statusbar(_("Replace Cancelled"));
|
||||
@ -619,8 +585,8 @@ int do_replace_loop(char *prevanswer, filestruct *begin, int *beginx,
|
||||
case 0: /* They actually entered something */
|
||||
break;
|
||||
default:
|
||||
if (*i != -2) { /* First page, last page, for example
|
||||
could get here */
|
||||
if (*i != -2) { /* First page, last page, for example, could
|
||||
get here */
|
||||
do_early_abort();
|
||||
replace_abort();
|
||||
return 0;
|
||||
@ -632,28 +598,20 @@ int do_replace_loop(char *prevanswer, filestruct *begin, int *beginx,
|
||||
|
||||
last_replace = mallocstrcpy(last_replace, answer);
|
||||
while (1) {
|
||||
|
||||
/* Sweet optimization by Rocco here */
|
||||
#if 0
|
||||
fileptr = findnextstr(replaceall, FALSE, begin, *beginx, prevanswer);
|
||||
#else
|
||||
if (fileptr != 0)
|
||||
fileptr = findnextstr(1, FALSE, begin, *beginx, prevanswer);
|
||||
else
|
||||
fileptr = findnextstr(replaceall || (search_last_line ? 1 : 0), FALSE, begin, *beginx, prevanswer);
|
||||
#endif
|
||||
fileptr = findnextstr(fileptr || replaceall || search_last_line,
|
||||
FALSE, begin, *beginx, prevanswer);
|
||||
|
||||
/* No more matches. Done! */
|
||||
if (!fileptr)
|
||||
break;
|
||||
|
||||
/* Make sure only whole words are found */
|
||||
if ((wholewords) && (!is_whole_word(current_x, fileptr, prevanswer)))
|
||||
if (wholewords && !is_whole_word(current_x, fileptr->data, prevanswer))
|
||||
continue;
|
||||
|
||||
/* If we're here, we've found the search string */
|
||||
if (!replaceall) {
|
||||
|
||||
curs_set(0);
|
||||
do_replace_highlight(TRUE, prevanswer);
|
||||
|
||||
@ -681,7 +639,8 @@ int do_replace_loop(char *prevanswer, filestruct *begin, int *beginx,
|
||||
totsize += strlen(current->data);
|
||||
|
||||
if (!ISSET(REVERSE_SEARCH)) {
|
||||
/* Stop bug where we replace a substring of the replacement text */
|
||||
/* Stop bug where we replace a substring of the
|
||||
replacement text */
|
||||
current_x += strlen(last_replace) - 1;
|
||||
|
||||
/* Adjust the original cursor position - COULD BE IMPROVED */
|
||||
@ -689,6 +648,7 @@ int do_replace_loop(char *prevanswer, filestruct *begin, int *beginx,
|
||||
*beginx += strlen(last_replace) - strlen(last_search);
|
||||
|
||||
/* For strings that cross the search start/end boundary */
|
||||
|
||||
/* Don't go outside of allocated memory */
|
||||
if (*beginx < 1)
|
||||
*beginx = 1;
|
||||
@ -708,7 +668,8 @@ int do_replace_loop(char *prevanswer, filestruct *begin, int *beginx,
|
||||
edit_refresh();
|
||||
set_modified();
|
||||
numreplaced++;
|
||||
} else if (*i == -1) /* Abort, else do nothing and continue loop */
|
||||
} else if (*i == -1) /* Abort, else do nothing and continue
|
||||
loop */
|
||||
break;
|
||||
}
|
||||
|
||||
@ -720,7 +681,7 @@ int do_replace(void)
|
||||
{
|
||||
int i, numreplaced, beginx;
|
||||
filestruct *begin;
|
||||
char *prevanswer = NULL, *buf = NULL;
|
||||
char *prevanswer = NULL;
|
||||
|
||||
if (ISSET(VIEW_MODE)) {
|
||||
print_view_warning();
|
||||
@ -754,53 +715,37 @@ int do_replace(void)
|
||||
|
||||
/* If answer is now == "", then PICO_MODE is set. So, copy
|
||||
last_search into answer (and prevanswer)... */
|
||||
if (answer[0] == '\0') {
|
||||
if (answer[0] == '\0')
|
||||
answer = mallocstrcpy(answer, last_search);
|
||||
prevanswer = mallocstrcpy(prevanswer, last_search);
|
||||
} else {
|
||||
last_search = mallocstrcpy(last_search, answer);
|
||||
prevanswer = mallocstrcpy(prevanswer, answer);
|
||||
}
|
||||
|
||||
if (ISSET(PICO_MODE)) {
|
||||
buf = charalloc(strlen(last_replace) + 5);
|
||||
if (last_replace[0] != '\0') {
|
||||
if (strlen(last_replace) > (COLS / 3)) {
|
||||
strncpy(buf, last_replace, COLS / 3);
|
||||
sprintf(&buf[COLS / 3 - 1], "...");
|
||||
} else
|
||||
sprintf(buf, "%s", last_replace);
|
||||
|
||||
i = statusq(0, replace_list_2, "",
|
||||
_("Replace with [%s]"), buf);
|
||||
}
|
||||
else
|
||||
i = statusq(0, replace_list_2, "",
|
||||
_("Replace with"));
|
||||
}
|
||||
else
|
||||
i = statusq(0, replace_list_2, last_replace,
|
||||
_("Replace with"));
|
||||
last_search = mallocstrcpy(last_search, answer);
|
||||
prevanswer = mallocstrcpy(prevanswer, last_search);
|
||||
|
||||
if (ISSET(PICO_MODE) && last_replace[0] != '\0') {
|
||||
if (strlen(last_replace) > COLS / 3) {
|
||||
char *buf = charalloc(COLS / 3 + 3);
|
||||
|
||||
strncpy(buf, last_replace, COLS / 3 - 1);
|
||||
strcpy(buf + COLS / 3 - 1, "...");
|
||||
i = statusq(0, replace_list_2, "", _("Replace with [%s]"),
|
||||
buf);
|
||||
free(buf);
|
||||
} else
|
||||
i = statusq(0, replace_list_2, "", _("Replace with [%s]"),
|
||||
last_replace);
|
||||
} else
|
||||
i = statusq(0, replace_list_2, last_replace, _("Replace with"));
|
||||
|
||||
/* save where we are */
|
||||
begin = current;
|
||||
#if 0
|
||||
/* why + 1 ? isn't this taken care of in findnextstr() ? */
|
||||
beginx = current_x + 1;
|
||||
#else
|
||||
beginx = current_x;
|
||||
#endif
|
||||
search_last_line = 0;
|
||||
|
||||
numreplaced = do_replace_loop(prevanswer, begin, &beginx, FALSE, &i);
|
||||
|
||||
/* restore where we were */
|
||||
current = begin;
|
||||
#if 0
|
||||
current_x = beginx - 1;
|
||||
#else
|
||||
current_x = beginx;
|
||||
#endif
|
||||
renumber_all();
|
||||
edit_update(current, CENTER);
|
||||
print_replaced(numreplaced);
|
||||
|
164
utils.c
164
utils.c
@ -24,6 +24,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include "config.h"
|
||||
#include "proto.h"
|
||||
#include "nano.h"
|
||||
@ -50,75 +51,75 @@ int num_of_digits(int n)
|
||||
return i;
|
||||
}
|
||||
|
||||
/* For non-null-terminated lines. A line, by definition, shouldn't
|
||||
normally have newlines in it, so encode its nulls as newlines. */
|
||||
void unsunder(char *str, int true_len)
|
||||
/* Fix the memory allocation for a string. */
|
||||
void align(char **strp)
|
||||
{
|
||||
int i;
|
||||
if (strlen(str) < true_len) {
|
||||
for (i = 0; i < true_len; i++) {
|
||||
if (str[i] == '\0')
|
||||
str[i] = '\n';
|
||||
}
|
||||
}
|
||||
assert(strp != NULL);
|
||||
*strp = nrealloc(*strp, strlen(*strp) + 1);
|
||||
}
|
||||
|
||||
/* Null a string at a certain index and align it. */
|
||||
void null_at(char **data, size_t index)
|
||||
{
|
||||
assert(data != NULL);
|
||||
*data = (char *)nrealloc(*data, sizeof(char) * (index + 1));
|
||||
(*data)[index] = '\0';
|
||||
}
|
||||
|
||||
/* For non-null-terminated lines. A line, by definition, shouldn't
|
||||
normally have newlines in it, so decode its newlines into nulls. */
|
||||
* normally have newlines in it, so encode its nulls as newlines. */
|
||||
void unsunder(char *str, size_t true_len)
|
||||
{
|
||||
assert(str != NULL);
|
||||
for(; true_len > 0; true_len--, str++)
|
||||
if (*str == '\0')
|
||||
*str = '\n';
|
||||
}
|
||||
|
||||
/* For non-null-terminated lines. A line, by definition, shouldn't
|
||||
* normally have newlines in it, so decode its newlines into nulls. */
|
||||
void sunder(char *str)
|
||||
{
|
||||
int i, true_len = strlen(str);
|
||||
if (strchr(str, '\n')) {
|
||||
for (i = 0; i < true_len; i++) {
|
||||
if (str[i] == '\n')
|
||||
str[i] = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Lower case a string - must be null terminated */
|
||||
void lowercase(char *src)
|
||||
{
|
||||
long i = 0;
|
||||
|
||||
while (src[i] != 0) {
|
||||
src[i] = (char) tolower(src[i]);
|
||||
i++;
|
||||
}
|
||||
assert(str != NULL);
|
||||
for(; *str != '\0'; str++)
|
||||
if (*str == '\n')
|
||||
*str = '\0';
|
||||
}
|
||||
|
||||
/* None of this is needed if we're using NANO_SMALL! */
|
||||
#ifndef NANO_SMALL
|
||||
char *revstrstr(char *haystack, char *needle, char *rev_start)
|
||||
static const char *revstrstr(const char *haystack, const char *needle,
|
||||
const char *rev_start)
|
||||
{
|
||||
char *p, *q, *r;
|
||||
for(; rev_start >= haystack ; rev_start--) {
|
||||
const char *r, *q;
|
||||
|
||||
for(p = rev_start ; p >= haystack ; --p) {
|
||||
for (r = p, q = needle ; (*q == *r) && (*q != '\0') ; r++, q++)
|
||||
for (r = rev_start, q = needle ; *q == *r && *q != '\0'; r++, q++)
|
||||
;
|
||||
if (*q == '\0')
|
||||
return p;
|
||||
return rev_start;
|
||||
}
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *revstristr(char *haystack, char *needle, char *rev_start)
|
||||
static const char *revstristr(const char *haystack, const char *needle,
|
||||
const char *rev_start)
|
||||
{
|
||||
char *p, *q, *r;
|
||||
for (; rev_start >= haystack; rev_start--) {
|
||||
const char *r = rev_start, *q = needle;
|
||||
|
||||
for(p = rev_start ; p >= haystack ; --p) {
|
||||
for (r = p, q = needle ; (tolower(*q) == tolower(*r)) && (*q != '\0') ; r++, q++)
|
||||
for (; (tolower(*q) == tolower(*r)) && (*q != '\0') ; r++, q++)
|
||||
;
|
||||
if (*q == '\0')
|
||||
return p;
|
||||
return rev_start;
|
||||
}
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
#endif /* NANO_SMALL */
|
||||
#endif /* !NANO_SMALL */
|
||||
|
||||
/* This is now mutt's version (called mutt_stristr) because it doesn't
|
||||
use memory allocation to do a simple search (yuck). */
|
||||
char *stristr(char *haystack, char *needle)
|
||||
const char *stristr(const char *haystack, const char *needle)
|
||||
{
|
||||
const char *p, *q;
|
||||
|
||||
@ -128,43 +129,41 @@ char *stristr(char *haystack, char *needle)
|
||||
return (haystack);
|
||||
|
||||
while (*(p = haystack)) {
|
||||
for (q = needle; *p && *q && tolower (*p) == tolower (*q); p++, q++)
|
||||
for (q = needle; *p && *q && tolower(*p) == tolower(*q); p++, q++)
|
||||
;
|
||||
if (!*q)
|
||||
return (haystack);
|
||||
return haystack;
|
||||
haystack++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *strstrwrapper(char *haystack, char *needle, char *rev_start, int line_pos)
|
||||
const char *strstrwrapper(const char *haystack, const char *needle,
|
||||
const char *rev_start, int line_pos)
|
||||
{
|
||||
|
||||
#ifdef HAVE_REGEX_H
|
||||
int result;
|
||||
|
||||
if (ISSET(USE_REGEXP)) {
|
||||
if (!ISSET(REVERSE_SEARCH)) {
|
||||
result = regexec(&search_regexp, haystack, 10, regmatches, (line_pos > 0) ? REG_NOTBOL : 0);
|
||||
if (!result)
|
||||
if (!regexec(&search_regexp, haystack, 10, regmatches, (line_pos > 0) ? REG_NOTBOL : 0))
|
||||
return haystack + regmatches[0].rm_so;
|
||||
}
|
||||
#ifndef NANO_SMALL
|
||||
} else {
|
||||
char *i, *j;
|
||||
else {
|
||||
const char *i, *j;
|
||||
|
||||
/* do a quick search forward first */
|
||||
if (!(regexec(&search_regexp, haystack, 10, regmatches, 0))) {
|
||||
if (!regexec(&search_regexp, haystack, 10, regmatches, 0)) {
|
||||
/* there's a match somewhere in the line - now search for it backwards, much slower */
|
||||
for (i = rev_start; i >= haystack; --i) {
|
||||
if (!(result = regexec(&search_regexp, i, 10, regmatches, (i > haystack) ? REG_NOTBOL : 0))) {
|
||||
if (!regexec(&search_regexp, i, 10, regmatches, (i > haystack) ? REG_NOTBOL : 0)) {
|
||||
j = i + regmatches[0].rm_so;
|
||||
if (j <= rev_start)
|
||||
return j;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@ -174,7 +173,6 @@ char *strstrwrapper(char *haystack, char *needle, char *rev_start, int line_pos)
|
||||
return revstrstr(haystack, needle, rev_start);
|
||||
else
|
||||
return strstr(haystack, needle);
|
||||
|
||||
} else {
|
||||
if (ISSET(REVERSE_SEARCH))
|
||||
return revstristr(haystack, needle, rev_start);
|
||||
@ -188,8 +186,7 @@ char *strstrwrapper(char *haystack, char *needle, char *rev_start, int line_pos)
|
||||
|
||||
/* This is a wrapper for the perror function. The wrapper takes care of
|
||||
* ncurses, calls perror (which writes to STDERR), then refreshes the
|
||||
* screen. Note that nperror causes the window to flicker once.
|
||||
*/
|
||||
* screen. Note that nperror causes the window to flicker once. */
|
||||
void nperror(const char *s) {
|
||||
/* leave ncurses mode, go to the terminal */
|
||||
if (endwin() != ERR) {
|
||||
@ -212,17 +209,17 @@ void *nmalloc(size_t howmuch)
|
||||
}
|
||||
|
||||
/* We're going to need this too - Hopefully this will minimize
|
||||
the transition cost of moving to the apropriate function. */
|
||||
the transition cost of moving to the appropriate function. */
|
||||
char *charalloc(size_t howmuch)
|
||||
{
|
||||
void *r;
|
||||
char *r;
|
||||
|
||||
/* Panic save? */
|
||||
|
||||
if (!(r = calloc(howmuch, sizeof (char))))
|
||||
if (!(r = (char *)calloc(howmuch, sizeof (char))))
|
||||
die(_("nano: calloc: out of memory!"));
|
||||
|
||||
return (char *) r;
|
||||
return r;
|
||||
}
|
||||
|
||||
void *nrealloc(void *ptr, size_t howmuch)
|
||||
@ -235,24 +232,18 @@ void *nrealloc(void *ptr, size_t howmuch)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Copy one malloc()ed string to another pointer.
|
||||
|
||||
Should be used as dest = mallocstrcpy(dest, src);
|
||||
*/
|
||||
void *mallocstrcpy(char *dest, char *src)
|
||||
/* Copy one malloc()ed string to another pointer. Should be used as:
|
||||
* dest = mallocstrcpy(dest, src); */
|
||||
char *mallocstrcpy(char *dest, const char *src)
|
||||
{
|
||||
|
||||
|
||||
if (src == dest)
|
||||
return src;
|
||||
return dest;
|
||||
|
||||
if (dest != NULL)
|
||||
if (dest)
|
||||
free(dest);
|
||||
|
||||
if (src == NULL) {
|
||||
dest = NULL;
|
||||
return(dest);
|
||||
}
|
||||
if (!src)
|
||||
return NULL;
|
||||
|
||||
dest = charalloc(strlen(src) + 1);
|
||||
strcpy(dest, src);
|
||||
@ -260,8 +251,7 @@ void *mallocstrcpy(char *dest, char *src)
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
||||
/* Append a new magic-line to filebot */
|
||||
/* Append a new magic-line to filebot. */
|
||||
void new_magicline(void)
|
||||
{
|
||||
filebot->next = nmalloc(sizeof(filestruct));
|
||||
@ -292,22 +282,22 @@ void new_magicline(void)
|
||||
*/
|
||||
int check_wildcard_match(const char *text, const char *pattern)
|
||||
{
|
||||
const char *retryPat;
|
||||
const char *retryText;
|
||||
const char *retrypat;
|
||||
const char *retrytext;
|
||||
int ch;
|
||||
int found;
|
||||
int len;
|
||||
|
||||
retryPat = NULL;
|
||||
retryText = NULL;
|
||||
retrypat = NULL;
|
||||
retrytext = NULL;
|
||||
|
||||
while (*text || *pattern) {
|
||||
ch = *pattern++;
|
||||
|
||||
switch (ch) {
|
||||
case '*':
|
||||
retryPat = pattern;
|
||||
retryText = text;
|
||||
retrypat = pattern;
|
||||
retrytext = text;
|
||||
break;
|
||||
|
||||
case '[':
|
||||
@ -361,15 +351,15 @@ int check_wildcard_match(const char *text, const char *pattern)
|
||||
}
|
||||
|
||||
if (*text) {
|
||||
pattern = retryPat;
|
||||
text = ++retryText;
|
||||
pattern = retrypat;
|
||||
text = ++retrytext;
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (pattern == NULL)
|
||||
if (!pattern)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
782
winio.c
782
winio.c
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Загрузка…
Ссылка в новой задаче
Block a user