DLR and DB fixes mega-merge

git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@1235 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
This commit is contained in:
Chris Allegretta 2002-07-19 01:08:59 +00:00
parent cf2f6563ca
commit 6df90f5787
22 changed files with 2610 additions and 2722 deletions

2
BUGS
View File

@ -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
View File

@ -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
View File

@ -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
View File

@ -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
View File

@ -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 */

View File

@ -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
View File

@ -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, &current->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;
}

View File

@ -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
View File

@ -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
View File

@ -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)