Compare commits
61 Commits
v2.1.8
...
v2.1.99pre
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6c3d886424 | ||
|
|
879dfbaf40 | ||
|
|
e9dee887a9 | ||
|
|
123110c5dc | ||
|
|
cbba77558e | ||
|
|
e350d7a52a | ||
|
|
16e07d5878 | ||
|
|
8c1edd17e3 | ||
|
|
fc48347fb8 | ||
|
|
2cd2d4b9ae | ||
|
|
533b9fa827 | ||
|
|
f9d4fd3755 | ||
|
|
f55ada727e | ||
|
|
99c8d40db1 | ||
|
|
6f08332741 | ||
|
|
a60910cc54 | ||
|
|
7be32046b0 | ||
|
|
795be590d5 | ||
|
|
3aad8ab9aa | ||
|
|
1d461475ce | ||
|
|
a535cecd77 | ||
|
|
d233e7e240 | ||
|
|
1f218fa859 | ||
|
|
91e05e64a0 | ||
|
|
35afab5eba | ||
|
|
bce7d404d9 | ||
|
|
f8f9027295 | ||
|
|
5687c3dfa6 | ||
|
|
139934a236 | ||
|
|
3de025f8f4 | ||
|
|
308a7b029d | ||
|
|
05417a2444 | ||
|
|
13dde2bda4 | ||
|
|
a48507d32a | ||
|
|
7f38820fba | ||
|
|
42726f74cc | ||
|
|
0a10e20eec | ||
|
|
ad37e67dd2 | ||
|
|
a4c2b99e40 | ||
|
|
8b9fb360c2 | ||
|
|
e061a0d604 | ||
|
|
b843a51b79 | ||
|
|
df543e78df | ||
|
|
12ba55732f | ||
|
|
55ca1028ac | ||
|
|
5a3464b57b | ||
|
|
fb6446d826 | ||
|
|
f86fa86089 | ||
|
|
5ba7a93b1a | ||
|
|
fbdc8b9b92 | ||
|
|
97ba02d4f1 | ||
|
|
86988b5026 | ||
|
|
b71cf301da | ||
|
|
9555e1d118 | ||
|
|
7aec392993 | ||
|
|
e027fc2edd | ||
|
|
8257bf145e | ||
|
|
a30eb78006 | ||
|
|
35686daf9d | ||
|
|
04fbfaae51 | ||
|
|
5b695cef46 |
169
ChangeLog
169
ChangeLog
@@ -1,3 +1,172 @@
|
||||
GNU nano 2.1.99pre2 - 2009.11.21
|
||||
2009-11-21 Chris Allegretta <chrisa@asty.org>
|
||||
* rcfile.c: Add unbinding keyword, fixes Savannah bug 22852 reported by frankd.
|
||||
* prompt.c (update_statusbar_line): Set statusbar_pww when updating the line.
|
||||
Fixes Savannah bug 24957 by Mike Frysinger.
|
||||
|
||||
2009-11-19 Chris Allegretta <chrisa@asty.org>
|
||||
* nano.c (die_save_file) Try nd match the permissions of the file we were
|
||||
editing but only make a minimal effort to do so. Fixes Savannah bug 27273
|
||||
reported by Mike Frysinger.
|
||||
|
||||
2009-11-18 Adrian Bunk <bunk via Savannah>
|
||||
* nano.c (main): Allow --fill and --nowrap to override nanorc entries and each other
|
||||
on the command line.
|
||||
|
||||
2009-11-15 Chris Allegretta <chrisa@asty.org>
|
||||
* winio.c (edit_refresh): Always computer maxsize regardless of whether smooth scrolling
|
||||
is enabled. Fixes Savannah bug 28024 by Mike Frysinger.
|
||||
|
||||
GNU nano 2.1.99pre1 - 2009.11.15
|
||||
2009-11-14 Chris Allegretta <chrisa@asty.org>
|
||||
* move.c (do_first_line, do_last_line): Just set edit_refresh_needed rather than
|
||||
get messy.
|
||||
* files.c (do_writeout) - Only mention file modification if we're writing the same
|
||||
file we originally opened.
|
||||
|
||||
2009-11-13 Chris Allegretta <chrisa@asty.org>
|
||||
* winio.c: Add new static maxsize to be able to easier calculation with
|
||||
softwrap.
|
||||
* nano.c (do_mouse): Fix mouse support not working with soft wrapping. Fixes
|
||||
Savannah bug 27549 reported by Hannes Schueller.
|
||||
|
||||
2009-11-11 Chris Allegretta <chrisa@asty.org>
|
||||
* winio.c: Large tweaking of cursor and text display based on COLS not COLS - 1,
|
||||
due to finally understanding that display_string wasn't being called properly
|
||||
when softwrap was enabled. Fixes Savnnah bug 27603, Return key doesn't scroll
|
||||
viewport reported by Hannes Schueller.
|
||||
* - Fix size_t formatting issues with -pedantic
|
||||
|
||||
2009-11-09 Chris Allegretta <chrisa@asty.org>
|
||||
* files.c (read_file): - Remove debugging messages from file load. Fixes
|
||||
Savannah bug 27838.
|
||||
|
||||
2009-11-07 Chris Allegretta <chrisa@asty.org>
|
||||
* nano.h - Add bogus value at begin of flags enumeration because it
|
||||
causes casesens rcfile option to misbehave, reported by Helmut
|
||||
Jarausch <jarausch@igpm.rwth-aachen.de>
|
||||
|
||||
2009-11-03 Chris Allegretta <chrisa@asty.org>
|
||||
* nano.h - Fix comma at end of enumerator list which angers -pedantic.
|
||||
* rcfile.c - Add in specific check for UNDOABLE and fix declaration as
|
||||
to what flag it toggles. Fixes undo mode being able to be called from
|
||||
the rc file, reported by Helmut Jarausch <jarausch@igpm.rwth-aachen.de>
|
||||
|
||||
2009-11-03 Mike Frysinger <vapier@gentoo.org>
|
||||
* files.c - Move up is_file_writable() to stop implicit definition complaints.
|
||||
|
||||
2009-10-27 Chris Allegretta <chrisa@asty.org>
|
||||
* browser.c (browser_init): Set column width to something sane when
|
||||
initializing in a directory with no file entries. Fixes Savannah
|
||||
bug 24163 found (and initial patch) by Paul Wise.
|
||||
|
||||
2009-09-15 Chris Allegretta <chrisa@asty.org>
|
||||
* winio.c: Clean up some unused variables from the soft wrapping code.
|
||||
|
||||
GNU nano 2.1.11 - 2009.09.14
|
||||
2009-09-12 Chris Allegretta <chrisa@asty.org>
|
||||
* winio.c (edit_update) - properly update edittop when using soft wrapping.
|
||||
Fixes lack of centering for searching for off-screen answers, found by
|
||||
Hannes <mr_creosote@mutantwatch.de>.
|
||||
|
||||
2009-09-03 Chris Allegretta <chrisa@asty.org>
|
||||
* global.c (shortcut_init): Fix up/down keys not responding in the file browser,
|
||||
discovered by Hannes <mr_creosote@mutantwatch.de>.
|
||||
* move.c (do_up) - Fix another scrolling issue with softwrap when the
|
||||
cursor is beyond COLS, discovered by Hannes <mr_creosote@mutantwatch.de>.
|
||||
|
||||
2009-09-02 Chris Allegretta <chrisa@asty.org>
|
||||
* Attempt to check file writability and emit a warning on the status bar
|
||||
if nano doesn't think the file can be written to. Feature originally
|
||||
requested by Damien Jolders <madamien@skullsquad.com> et al.
|
||||
|
||||
2009-08-29 Chris Allegretta <chrisa@asty.org>
|
||||
* Fix more soft wrapping issues, particularly with scrolling,
|
||||
discovered by Hannes <mr_creosote@mutantwatch.de>.
|
||||
|
||||
2009-08-19 Chris Allegretta <chrisa@asty.org>
|
||||
* Fix issue with soft wrapping not displaying the last character of each line,
|
||||
fixed bug discovered by Hannes <mr_creosote@mutantwatch.de>.
|
||||
|
||||
2009-08-17 Mike Frysinger <vapier@gentoo.org>
|
||||
* doc/syntax/(gentoo|sh|tcl).nanorc: Fix problems with empty regexes on POSIX.
|
||||
Fixes Savannah bug 27175.
|
||||
|
||||
2009-08-17 Chris Allegretta <chrisa@asty.org>
|
||||
* Initial soft line wrapping implementation. Command line flags
|
||||
-$ or --softwrap.
|
||||
* nano.c, text.c: Clean up some fprintf warnings in debug mode due to printing
|
||||
a size_t without using the zd specifier.
|
||||
2009-08-13 Chris Allegretta <chrisa@asty.org>
|
||||
* New global flag implementation courtesy of Adam Wysocki <gophi@arcabit.pl>, allows
|
||||
previous undo flag to be implemented consistent with other flags.
|
||||
|
||||
GNU nano 2.1.10 - 2009.07.28
|
||||
2009-07-27 Chris Allegretta <chrisa@asty.org>
|
||||
* text.c (undo_cut, redo_cut): Don't actually try and undo/redo an empty cut, i.e. the magicline.
|
||||
Fixes crash on cutting last line discovered by Eitan Adler <eitanadlerlist@gmail.com>.
|
||||
|
||||
2009-07-11 Chris Allegretta <chrisa@asty.org>
|
||||
* nano-regress: Small tweaks
|
||||
* Change undo code to off unless unabled via a command line option (-u/--undo). Until this code
|
||||
stabilizes this is the only responsible way to treat it.
|
||||
|
||||
2009-03-08 Chris Allegretta <chrisa@asty.org>
|
||||
* TODO - Break out some targets for various features into 2.2
|
||||
and 2.4 series for things which are feasible.
|
||||
|
||||
2009-02-28 Chris Allegretta <chrisa@asty.org>
|
||||
* configure.ac: Add check for whether _XOPEN_SOURCE_EXTENDED is needed for
|
||||
curses to work w/color. Fixes compilation on HP-UX with older GCC,
|
||||
reported by jay.krell@cornell.edu.
|
||||
|
||||
2009-02-23 Eitan Adler <eitanadlerlist@gmail.com>
|
||||
* doc/man/Makefile.am: Fix make variable substitution to be more portable
|
||||
|
||||
2009-02-23 Chris Allegretta <chrisa@asty.org>
|
||||
* rcfile.c (parse_keybinding) - Define a var before tryung to use it. Whoops!
|
||||
* fix some redefinitions causing compiler warnings, from Eitan Adler. Other
|
||||
(hopefully) fixes for uncasted malloc()s, reported by the same.
|
||||
* doc/man/fr/Makefile.am: Add groff check fix to fr files.
|
||||
|
||||
GNU nano 2.1.9 - 2009.02.16
|
||||
2009-02-16 Chris Allegretta <chrisa@asty.org>
|
||||
* Add new argument to reset_multis for force redraws without attempting to
|
||||
guess whether we need to, for functions that we don't have good info about
|
||||
the text state. New utility function color.c:reset_multis_for_id().
|
||||
|
||||
2009-02-15 Chris Allegretta <chrisa@asty.org>
|
||||
* configure.ac, doc/man/Makefile.am - Add check for HTML output support in GNU
|
||||
groff. Fixes Savannah bug #24461: build traps on groff. Also, add installation
|
||||
of html-ized man pages to $datadir/nano/man-html, since we should probably
|
||||
install files we went to all the trouble of generating.
|
||||
|
||||
2009-02-14 Chris Allegretta <chrisa@asty.org>
|
||||
* nano.c (precalc_multicolorinfo) - Add debugging so we have a better clue if further
|
||||
issues arise. Also start at the beginning of later lines when trying to match the
|
||||
end of a multi-line regex. Fixes more overly aggressive highlighting found by
|
||||
Mike Frysinger. Finally, advance to the match end for performance.
|
||||
|
||||
2009-02-11 Chris Allegretta <chrisa@asty.org>
|
||||
* nanorc.c (parse_include): Do call real_dir_from_tilde() on included
|
||||
files in .nanorc, but still avoiding bug #25297. Fixes ~ and ~user
|
||||
specifications for nanorc include files, as reported by Eitan Adler.
|
||||
|
||||
2009-02-09 Chris Allegretta <chrisa@asty.org>
|
||||
* New option -q, --quiet, rcfile option "quiet" implemented. Skips printing
|
||||
errors about the rcfile and asking user to press enter. Also, nano should
|
||||
now only ask for one enter press when there is an error when not using -q.
|
||||
Based on discussion between Eitan Adler and Mike Frysinger.
|
||||
* rcfile.c (parse_keybinding) - Significant cleanups and fixes for
|
||||
detecting and reporting errors in key bindings code.
|
||||
|
||||
2009-02-08 Chris Allegretta <chrisa@asty.org>
|
||||
* Make reset_multidata reset more lines, since contrary to previous problems the
|
||||
syntax highlting is now too *un*ambitious, causing display glitches when
|
||||
deleting a regex boundary.
|
||||
* Add more multidata initliazers for new buffers and 'magic lines'. Fixes segfaults
|
||||
with syntax highlighting in new buffers, initially reported by Mike Frysinger.
|
||||
|
||||
GNU nano 2.1.8 - 2009.02.07
|
||||
2009-02-06 Chris Allegretta <chrisa@asty.org>
|
||||
* rcfile.c (parse_include): Abort on being unable to open an included rcfile. Fixes
|
||||
|
||||
64
NEWS
64
NEWS
@@ -1,3 +1,67 @@
|
||||
2009.11.21 - GNU nano 2.1.99pre2 is available for a special pre-Black
|
||||
Friday discount. Included are some (hopefully
|
||||
final) fixes for issues with last page display
|
||||
caused by the soft wrapping code, and a fix for
|
||||
a long standing issue with hittig the home key when
|
||||
going through the search history. On the features
|
||||
front, nano will now attempt to retain the proper
|
||||
ownership and permissions when trying to create a
|
||||
.save file due to receiving a signal. Nano can also
|
||||
now unbind keys from one or more menus via the 'unbind'
|
||||
keyword. Finally, passing --fill or --nowrap on
|
||||
the command line will now override any related
|
||||
.nanorc entries. Speak now or forever hold your bugs!
|
||||
|
||||
2009.11.15 - GNU nano 2.1.99pre1 "take a bow" is out there, man, it's
|
||||
out there all right. This release contains mainly
|
||||
bugfixes, underscoring that we are preparing for the
|
||||
next stable series release. Included are many fixes
|
||||
for the new soft wrapping code, compiler warning tweaks,
|
||||
and the modification time warning no longer triggers
|
||||
when saving a file as a new name. Also include are
|
||||
some fixes for various nanorc options, and there are
|
||||
surely more bugs to find before we call the code base
|
||||
stable, so please keep those reports coming!
|
||||
|
||||
2009.09.14 - GNU nano 2.1.11 is on very thin ice, very thin ice, very thin
|
||||
ice. This release includes two new features: first, nano
|
||||
will check whether the current file is writable when it
|
||||
is opened, and warn if it is not on the status bar. Secondly,
|
||||
a new soft-wrapping (AKA full line display) option is
|
||||
available, which will attempt to fully display the contents
|
||||
of lines longer than the width of the screen without the
|
||||
usual truncation and a '$' symbol at the end of the line.
|
||||
It can be enabled via Meta-$ inside the editor, via the
|
||||
-$ or --softwrap command line flags, or "set softwrap"
|
||||
in your .nanorc). As always please report any bugs to the
|
||||
nano Savannah project page
|
||||
(http://savannah.gnu.org/bugs/?func=additem&group=nano)
|
||||
Remember: data loss happens, back up your files.
|
||||
|
||||
2009.07.28 - GNU nano 2.1.10 "Ellie" is released. This version includes
|
||||
various fixes for portability including some older HP-UX
|
||||
compiler combos, various compiler warnings, and some crash
|
||||
fixes in the undo code. On the topic of the latter item,
|
||||
the undo code is now marked as experimental since it can
|
||||
cause severe stability and memory issues, and thus now
|
||||
requires a flag (-u, --undo) in order to enable it.
|
||||
Please feel free to continue to test the undo code and
|
||||
thanks again for using nano for your text editing needs.
|
||||
Go team Nano!
|
||||
|
||||
2009.02.16 - GNU nano 2.1.9 wonders what all that glass is doing on the
|
||||
floor! This release is primarily meant as a less buggy
|
||||
version of 2.1.8, particularly for issues with the new
|
||||
sped-up syntax highlighting code. Other fixes include
|
||||
configure-time detection of groff HTML support before
|
||||
attempting to generate the HTML version of man pages,
|
||||
and using ~ or ~username syntax in .nanorc should now
|
||||
work again. Also, nano will now only ask for one
|
||||
acknowledgement of errors it encounters when parsing
|
||||
nanorc files, and a new flag -q (--quiet) will silence
|
||||
these messages altogether. Give it a go, and happy
|
||||
birthday lenny!
|
||||
|
||||
2009.02.07 - GNU nano 2.1.8 "unsafe at any speed" is released. This
|
||||
release include some long overdue performance
|
||||
improvements in syntax color highlighting, the ability
|
||||
|
||||
50
TODO
50
TODO
@@ -1,9 +1,9 @@
|
||||
TODO file (? means the feature may be implemented, but not definitely)
|
||||
------------------------------------------------------------------------
|
||||
|
||||
For the next version:
|
||||
- Undo/Redo keys (M-U and M-E)?
|
||||
- Rebindable keys?
|
||||
For the future (no targeted version, catch-all)
|
||||
- Compatibility with vi/emacs status files so we can let other editors
|
||||
know we're in a file?
|
||||
- FriBidi support?
|
||||
- Port to DJGPP?
|
||||
- Make matching bracket searches sophisticated enough to skip over
|
||||
@@ -11,37 +11,43 @@ For the next version:
|
||||
- Allow indentation of marked text by spaces as well as tabs?
|
||||
- Allow indentation to add just enough columns to reach the nearest
|
||||
multiple of tabsize, rather than always adding tabsize columns?
|
||||
- Allow piping marked text to an external command and replacing it with
|
||||
the command's output (as the internal spell checker already does with
|
||||
the "spell" command)?
|
||||
- Rewrite the nano FAQ in SGML.
|
||||
- Allow conversion between different character sets. Maybe use glib's
|
||||
iconv() if the system's iconv() is inadequate, since we already use
|
||||
glib's vsnprintf() if the system lacks vsnprintf()?
|
||||
- Handle window resizes better. After we resize, we should stay
|
||||
wherever we were before we resized, as Pico does.
|
||||
- Fix problems with color syntaxes' highlighting lines too aggressively.
|
||||
- Allow color syntaxes to apply to more than just color, so that we can
|
||||
e.g. specify a different alternate spell checker depending on which
|
||||
file type we have open.
|
||||
- Allow color syntaxes to be selected based on more than just filename
|
||||
extension, e.g. through libmagic?
|
||||
- Allow text searches in the help browser.
|
||||
- Allow even better file type detection than we have currently, e.g.
|
||||
through libmagic?
|
||||
- Allow setting marks (saved positions, not to be confused with the mark
|
||||
set via Ctrl-^) at various lines and/or columns in the buffer, and
|
||||
allow movement between them with a single keystroke.
|
||||
- Add the ability to move to different lines of the screen with a single
|
||||
keystroke, e.g. M-` (M-~) to go to the top line, M-& (M-7) to go to
|
||||
the center line, and M-' (M-") to go to the last line.
|
||||
allow movement between them with a single keystroke? (we're running
|
||||
out of keystrokes)
|
||||
- Allow searching for and replacing newlines.
|
||||
- Allow soft wrapping as well as hard wrapping?
|
||||
- Detect when we're pasting text, so that we can handle it differently
|
||||
from normal typing?
|
||||
- Make pasting text work as fast as it does in Pico.
|
||||
- Fix handling of bad/incomplete UTF-8 sequences to display one Unicode
|
||||
FFFD (Replacement Character) per sequence instead of one per byte.
|
||||
|
||||
Old requests:
|
||||
For version 2.4:
|
||||
- Allow text searches in the help browser.
|
||||
- Handle window resizes better. After we resize, we should stay
|
||||
wherever we were before we resized, as Pico does.
|
||||
- Add the ability to move to different lines of the screen with a single
|
||||
keystroke, e.g. M-` (M-~) to go to the top line, M-& (M-7) to go to
|
||||
the center line, and M-' (M-") to go to the last line.
|
||||
- Detect when we're pasting text, so that we can handle it differently
|
||||
(i.e. faster than currently with screen redraws)
|
||||
- Allow piping marked text to an external command and replacing it with
|
||||
the command's output (as the internal spell checker already does with
|
||||
the "spell" command)?
|
||||
|
||||
For version 2.2:
|
||||
- Rebindable keys? [DONE]
|
||||
- Undo/Redo keys (M-U and M-E)? [DONE]
|
||||
- Fix problems with color syntaxes' highlighting lines too aggressively [DONE]
|
||||
- Allow nano to work like a pager (read from stdin) [DONE]
|
||||
- Allow color syntaxes to be selected based on more than just filename
|
||||
extension, [DONE]
|
||||
- Allow soft wrapping as well as hard wrapping? [DONE]
|
||||
|
||||
For version 2.0:
|
||||
- UTF-8 support. [DONE]
|
||||
|
||||
107
configure.ac
107
configure.ac
@@ -20,7 +20,7 @@
|
||||
#
|
||||
# $Id$
|
||||
|
||||
AC_INIT([GNU nano], [2.1.8], [nano-devel@gnu.org], [nano])
|
||||
AC_INIT([GNU nano], [2.1.99pre2], [nano-devel@gnu.org], [nano])
|
||||
AC_CONFIG_SRCDIR([src/nano.c])
|
||||
AC_CANONICAL_TARGET([])
|
||||
AM_INIT_AUTOMAKE
|
||||
@@ -50,7 +50,7 @@ AC_DEFINE_DIR([PKGDATADIR], [pkgdatadir], [Where data are placed to.])
|
||||
dnl Checks for header files.
|
||||
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS(getopt.h libintl.h limits.h regex.h sys/param.h wchar.h wctype.h)
|
||||
AC_CHECK_HEADERS(getopt.h libintl.h limits.h regex.h sys/param.h wchar.h wctype.h stdarg.h)
|
||||
|
||||
dnl Checks for options.
|
||||
|
||||
@@ -144,7 +144,7 @@ fi])
|
||||
|
||||
AC_ARG_ENABLE(color,
|
||||
[ --disable-color Disable color and syntax highlighting],
|
||||
[if test x$enableval != xno; then
|
||||
if test x$enableval != xno; then
|
||||
if test x$ac_cv_header_regex_h = xyes; then
|
||||
AC_DEFINE(ENABLE_NANORC, 1, [Define this to use .nanorc files.]) nanorc_support=yes
|
||||
AC_DEFINE(ENABLE_COLOR, 1, [Define this to have syntax highlighting, requires regex.h and ENABLE_NANORC too!]) color_support=yes
|
||||
@@ -155,7 +155,7 @@ AC_ARG_ENABLE(color,
|
||||
*** libraries that include the regex.h file or call the configure
|
||||
*** script with --disable-color.])
|
||||
fi
|
||||
fi], [
|
||||
fi,
|
||||
if test x$enable_tiny != xyes; then
|
||||
if test x$ac_cv_header_regex_h = xyes; then
|
||||
AC_DEFINE(ENABLE_NANORC, 1, [Define this to use .nanorc files.]) nanorc_support=yes
|
||||
@@ -168,7 +168,7 @@ fi], [
|
||||
*** script with --disable-color.])
|
||||
fi
|
||||
fi
|
||||
])
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE(multibuffer,
|
||||
[ --disable-multibuffer Disable multiple file buffers],
|
||||
@@ -194,34 +194,6 @@ AC_ARG_ENABLE(all,
|
||||
echo "--enable-all option no longer needed, ignoring for compatiblity"
|
||||
fi])
|
||||
|
||||
if test x$color_support = xyes; then
|
||||
# now check for the end of word boundary support (/< and />)
|
||||
AC_MSG_CHECKING([for GNU-style word boundary regex support])
|
||||
AC_TRY_RUN([
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#include <regex.h>
|
||||
int main(void)
|
||||
{
|
||||
regex_t r;
|
||||
size_t nmatch;
|
||||
regmatch_t pmatch;
|
||||
|
||||
if (regcomp(&r, "\\\\>", REG_EXTENDED|REG_NOSUB))
|
||||
return 1;
|
||||
if (regexec(&r, "word boundary", nmatch, &pmatch, 0))
|
||||
return 1;
|
||||
return 0;
|
||||
}],
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(GNU_WORDBOUNDS, 1, [Define if the system supports GNU-style word boundaries in regexes.]) gnu_wordbounds=yes,
|
||||
AC_MSG_RESULT(no),
|
||||
AC_MSG_WARN([*** Can't check for gnu word boundary support when cross-compiling])
|
||||
)
|
||||
fi
|
||||
|
||||
|
||||
AC_MSG_CHECKING([whether to enable UTF-8 support])
|
||||
AC_ARG_ENABLE(utf8,
|
||||
[ --enable-utf8 Enable UTF-8 support],
|
||||
@@ -464,7 +436,6 @@ dnl Checks for library functions.
|
||||
AC_TYPE_SIGNAL
|
||||
AC_FUNC_VPRINTF
|
||||
AC_CHECK_FUNCS(getopt_long)
|
||||
|
||||
dnl Checks for libraries.
|
||||
|
||||
if eval "test x$CURSES_LIB_NAME = x"; then
|
||||
@@ -545,6 +516,74 @@ else
|
||||
fi
|
||||
fi
|
||||
|
||||
if test x$color_support = xyes; then
|
||||
# now check for the end of word boundary support (/< and />)
|
||||
AC_MSG_CHECKING([for GNU-style word boundary regex support])
|
||||
AC_TRY_RUN([
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#include <regex.h>
|
||||
int main(void)
|
||||
{
|
||||
regex_t r;
|
||||
size_t nmatch;
|
||||
regmatch_t pmatch;
|
||||
|
||||
if (regcomp(&r, "\\\\>", REG_EXTENDED|REG_NOSUB))
|
||||
return 1;
|
||||
if (regexec(&r, "word boundary", nmatch, &pmatch, 0))
|
||||
return 1;
|
||||
return 0;
|
||||
}],
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(GNU_WORDBOUNDS, 1, [Define if the system supports GNU-style word boundaries in regexes.]) gnu_wordbounds=yes,
|
||||
AC_MSG_RESULT(no),
|
||||
AC_MSG_WARN([*** Can't check for GNU-style word boundary support when cross-compiling])
|
||||
)
|
||||
# if test x$CURSES_LIB_NAME = xcurses; then
|
||||
AC_MSG_CHECKING([whether _XOPEN_SOURCE_EXTENDED is needed])
|
||||
AC_TRY_RUN([
|
||||
#include <curses.h>
|
||||
int main(void)
|
||||
{
|
||||
int testcolor = COLOR_WHITE;
|
||||
return 0;
|
||||
}], AC_MSG_RESULT(no),
|
||||
AC_TRY_RUN([
|
||||
#ifndef _XOPEN_SOURCE_EXTENDED
|
||||
#define _XOPEN_SOURCE_EXTENDED 1
|
||||
#endif
|
||||
#include <curses.h>
|
||||
int main(void)
|
||||
{
|
||||
int testcolor = COLOR_WHITE;
|
||||
return 0;
|
||||
}],
|
||||
AC_DEFINE(NEED_XOPEN_SOURCE_EXTENDED, 1, [Define this if you need the _XOPEN_SOURCE_EXTENDED macro for color support])
|
||||
AC_MSG_RESULT(yes),
|
||||
AC_MSG_RESULT(not sure)
|
||||
AC_MSG_WARN([*** Couldn't successfully compile basic color test with or without _XOPEN_SOURCE_EXTENDED])
|
||||
AC_MSG_WARN([*** This build may not compile. Consider configuring with --disable-color or installing ncurses])),
|
||||
AC_MSG_WARN([*** Can't check need for _XOPEN_SOURCE_EXTENDED when cross-compiling]))
|
||||
fi
|
||||
#fi
|
||||
|
||||
# Check for groff html support
|
||||
AC_MSG_CHECKING([for HTML support in groff])
|
||||
groff -t -mandoc -Thtml </dev/null >/dev/null
|
||||
if test $? -ne 0 ; then
|
||||
echo "no"
|
||||
echo "*** Will not generate HTML version of man pages ***"
|
||||
echo "*** Consider installing a newer version of groff with HTML support ***"
|
||||
groff_html_support=no
|
||||
else
|
||||
echo "yes"
|
||||
groff_html_support=yes
|
||||
fi
|
||||
AM_CONDITIONAL(GROFF_HTML, test x$groff_html_support = xyes)
|
||||
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
doc/Makefile
|
||||
|
||||
@@ -116,7 +116,7 @@
|
||||
<blockquote><p>For the 'bleeding edge' current version of nano, you can use subversion to download the current source code. <b>Note:</b> believe it or not, by downloading code that has not yet stabilized into an official release, there could quite possibly be bugs, in fact the code may not even compile! Anyway, see <a href="http://svn.savannah.gnu.org/viewvc/trunk/nano/README.SVN?root=nano&view=markup">the nano SVN document</a> for info on anonymous SVN access to the nano source.</p></blockquote>
|
||||
<hr width="100%">
|
||||
<h1><a name="3"></a>3. Installation and Configuration</h1>
|
||||
<h2><a name="3.1"></a>3.1. How do install the RPM or DEB package?</h2>
|
||||
<h2><a name="3.1"></a>3.1. How do I install the RPM or DEB package?</h2>
|
||||
<blockquote><p>It's simple really! As root, type <b>rpm -Uvh nano-x.y.z-1.i386.rpm</b> if you have a RedHat-ish system or <b>dpkg -i nano_x.y.z-1.deb</b> if you have a Debian-ish system, where <b>x.y.z</b> is the release of nano. There are other programs to install packages, and if you wish to use those, knock yourself out.</p></blockquote>
|
||||
<h2><a name="3.2"></a>3.2. Compiling from source: WHAT THE HECK DO I DO NOW?</h2>
|
||||
<blockquote><p>Okay, take a deep breath, this really isn't hard. Unpack the nano source with a command like:</p>
|
||||
|
||||
@@ -6,20 +6,30 @@ endif
|
||||
|
||||
if USE_NANORC
|
||||
man_MANS = nano.1 nanorc.5 rnano.1
|
||||
if GROFF_HTML
|
||||
BUILT_SOURCES = nano.1.html nanorc.5.html rnano.1.html
|
||||
endif
|
||||
else
|
||||
man_MANS = nano.1 rnano.1
|
||||
if GROFF_HTML
|
||||
BUILT_SOURCES = nano.1.html rnano.1.html
|
||||
endif
|
||||
endif
|
||||
|
||||
nano_man_mans = nano.1 nanorc.5 rnano.1
|
||||
if GROFF_HTML
|
||||
htmlman_DATA = nano.1.html nanorc.5.html rnano.1.html
|
||||
htmlmandir = $(datadir)/nano/man-html
|
||||
nano_built_sources = nano.1.html nanorc.5.html rnano.1.html
|
||||
|
||||
nano.1.html: nano.1
|
||||
groff -t -mandoc -Thtml < $< > $@
|
||||
groff -t -mandoc -Thtml < $? > $@
|
||||
nanorc.5.html: nanorc.5
|
||||
groff -t -mandoc -Thtml < $< > $@
|
||||
groff -t -mandoc -Thtml < $? > $@
|
||||
rnano.1.html: rnano.1
|
||||
groff -t -mandoc -Thtml < $< > $@
|
||||
groff -t -mandoc -Thtml < $? > $@
|
||||
|
||||
EXTRA_DIST = $(nano_man_mans) $(nano_built_sources)
|
||||
else
|
||||
EXTRA_DIST = $(nano_man_mans)
|
||||
endif
|
||||
|
||||
@@ -2,20 +2,32 @@ mandir = @mandir@/fr
|
||||
|
||||
if USE_NANORC
|
||||
man_MANS = nano.1 nanorc.5 rnano.1
|
||||
if GROFF_HTML
|
||||
BUILT_SOURCES = nano.1.html nanorc.5.html rnano.1.html
|
||||
endif
|
||||
else
|
||||
man_MANS = nano.1 rnano.1
|
||||
if GROFF_HTML
|
||||
BUILT_SOURCES = nano.1.html rnano.1.html
|
||||
endif
|
||||
endif
|
||||
|
||||
nano_man_mans = nano.1 nanorc.5 rnano.1
|
||||
if GROFF_HTML
|
||||
htmlman_DATA = nano.1.html nanorc.5.html rnano.1.html
|
||||
htmlmandir = $(datadir)/nano/man-html/fr
|
||||
|
||||
nano_built_sources = nano.1.html nanorc.5.html rnano.1.html
|
||||
|
||||
nano.1.html: nano.1
|
||||
groff -t -mandoc -Thtml < $< > $@
|
||||
groff -t -mandoc -Thtml < $? > $@
|
||||
nanorc.5.html: nanorc.5
|
||||
groff -t -mandoc -Thtml < $< > $@
|
||||
groff -t -mandoc -Thtml < $? > $@
|
||||
rnano.1.html: rnano.1
|
||||
groff -t -mandoc -Thtml < $< > $@
|
||||
groff -t -mandoc -Thtml < $? > $@
|
||||
|
||||
EXTRA_DIST = $(nano_man_mans) $(nano_built_sources)
|
||||
else
|
||||
EXTRA_DIST = $(nano_man_mans)
|
||||
endif
|
||||
|
||||
|
||||
@@ -172,6 +172,10 @@ chroot.
|
||||
Preserve the XON and XOFF sequences (^Q and ^S) so they will be caught
|
||||
by the terminal.
|
||||
.TP
|
||||
.B \-q (\-\-quiet)
|
||||
Do not report errors in the nanorc file and ask them to
|
||||
be acknowledged by pressing enter at startup.
|
||||
.TP
|
||||
.B \-r \fIcols\fP (\-\-fill=\fIcols\fP)
|
||||
Wrap lines at column \fIcols\fP. If this value is 0 or less, wrapping
|
||||
will occur at the width of the screen less \fIcols\fP columns, allowing
|
||||
@@ -185,6 +189,10 @@ Enable alternative spell checker command.
|
||||
Always save changed buffer without prompting. Same as Pico's \fB-t\fP
|
||||
option.
|
||||
.TP
|
||||
.B \-u (\-\-undo)
|
||||
Enable experimental generic-purpose undo code. By default, the undo and redo
|
||||
shortcuts are Meta-U and Meta-E, respectively.
|
||||
.TP
|
||||
.B \-v (\-\-view)
|
||||
View file (read only) mode.
|
||||
.TP
|
||||
@@ -197,6 +205,13 @@ Disable help screen at bottom of editor.
|
||||
.B \-z (\-\-suspend)
|
||||
Enable suspend ability.
|
||||
.TP
|
||||
.B \-$ (\-\-softwrap)
|
||||
Enable 'soft wrapping'. Nano will attempt to display lines the entire
|
||||
contents of a line, even if it is longer than the screen width.
|
||||
Since '$' normally refers to a variable in the Unix shell, you should
|
||||
specify this option last when using other options (e.g. 'nano -wS$')
|
||||
or pass it separately (e.g. 'nano -wS -$').
|
||||
.TP
|
||||
.B \-a, \-b, \-e, \-f, \-g, \-j
|
||||
Ignored, for compatibility with Pico.
|
||||
|
||||
|
||||
@@ -145,6 +145,11 @@ paragraphs. They cannot contain blank characters. Only closing
|
||||
punctuation, optionally followed by closing brackets, can end sentences.
|
||||
The default value is "\fI!.?\fP".
|
||||
.TP
|
||||
.B set/unset quiet
|
||||
\fBnano\fP will not report errors in the nanorc file and ask them to
|
||||
be acknowledged by pressing enter at startup. If this is used it should
|
||||
be placed at the top of the file to be fully effective.
|
||||
.TP
|
||||
.B set/unset quickblank
|
||||
Do quick statusbar blanking. Statusbar messages will disappear after 1
|
||||
keystroke instead of 25.
|
||||
@@ -180,6 +185,9 @@ line.
|
||||
.B set/unset smooth
|
||||
Use smooth scrolling by default.
|
||||
.TP
|
||||
.B set/unset softwrap
|
||||
Enable soft line wrapping for easier viewing of very long lones.
|
||||
.TP
|
||||
.B set speller "\fIspellprog\fP"
|
||||
Use spelling checker \fIspellprog\fP instead of the built-in one, which
|
||||
calls \fIspell\fP.
|
||||
@@ -197,9 +205,15 @@ Convert typed tabs to spaces.
|
||||
.B set/unset tempfile
|
||||
Save automatically on exit, don't prompt.
|
||||
.TP
|
||||
.B set/unset undo
|
||||
Enable experimental generic-purpose undo code.
|
||||
.TP
|
||||
.B set/unset view
|
||||
Disallow file modification.
|
||||
.TP
|
||||
.B set/unset softwrap
|
||||
Enable soft line wrapping for easier viewing of very long lones.
|
||||
.TP
|
||||
.B set whitespace "\fIstring\fP"
|
||||
Set the two characters used to display the first characters of tabs and
|
||||
spaces. They must be single-column characters.
|
||||
@@ -520,6 +534,13 @@ The 'go to directory' menu.
|
||||
.TP
|
||||
.B all
|
||||
A special name meaning: apply to all menus where this function exists.
|
||||
|
||||
.TP
|
||||
.B unbind \fIkey\fP \fImenu\fP
|
||||
Unbind the key \fIkey\fP from the menu named \fImenu\fP or from all
|
||||
menus by using \fIall\fP. Same key syntax as for binding.
|
||||
Rebinds the key \fIkey\fP to a new function named \fIfunction\fP in the
|
||||
context of menu \fImenu\fP. The format of \fIkey\fP should be one of:
|
||||
.SH FILES
|
||||
.TP
|
||||
.I SYSCONFDIR/nanorc
|
||||
|
||||
@@ -170,6 +170,12 @@
|
||||
## characters as parts of words.
|
||||
# set wordbounds
|
||||
|
||||
## Enable the new (EXPERIMENTAL) generic undo code, not just for line cuts
|
||||
# set undo
|
||||
|
||||
## Enable soft line wrapping (AKA full line display)
|
||||
# set softwrap
|
||||
|
||||
|
||||
## Color setup
|
||||
##
|
||||
|
||||
@@ -20,10 +20,10 @@ color brightblue "\<e(begin|end|conf|install|make|qmake[34]|ant|(qa)?warn|infon?
|
||||
color brightblue "\<e(pause|beep|mktemp|(cvs|svn)_clean|punt_cxx)\>" "\<e(aclocal|auto(reconf|header|conf|make))\>"
|
||||
color brightblue "\<built_with_use\>" "\<make_desktop_entry\>" "\<unpack(_(makeself|pdv))?\>"
|
||||
color brightblue "\<die\>" "\<use(_(with|enable))?\>" "\<inherit\>" "\<has\>" "\<(has|best)_version\>"
|
||||
color brightblue "\<(do|new)(ins|(games)?s?bin|doc|lib(|\.so|\.a)|man|info|exe|initd|confd|envd|pam|menu|icon)\>"
|
||||
color brightblue "\<(do|new)(ins|(games)?s?bin|doc|lib(\.so|\.a)?|man|info|exe|initd|confd|envd|pam|menu|icon)\>"
|
||||
color brightblue "\<do(python|sed|dir|hard|sym|html|jar|mo)\>" "\<keepdir\>"
|
||||
color brightblue "prepall(|docs|info|man|strip)" "prep(info|lib|lib\.(so|a)|man|strip|gamesdirs)"
|
||||
color brightblue "\<(|doc|ins|exe)into\>" "\<(f|games)(owners|perms)\>" "\<(exe|ins|dir)opts\>"
|
||||
color brightblue "prepall(docs|info|man|strip)?" "prep(info|lib|lib\.(so|a)|man|strip|gamesdirs)"
|
||||
color brightblue "\<(doc|ins|exe)?into\>" "\<(f|games)(owners|perms)\>" "\<(exe|ins|dir)opts\>"
|
||||
## Highlight common commands used in ebuilds
|
||||
color blue "\<make\>" "\<(awk|cat|cd|chmod|chown|cp|echo|env|export|find|e?grep|ln|mkdir|mv|rm|sed|set|tar|touch|unset|xargs)\>"
|
||||
## Highlight comments (doesnt work that well)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
## Here is an example for Bourne shell scripts.
|
||||
##
|
||||
syntax "sh" "\.sh$"
|
||||
header "^#!.*/(ba|k|pdk|)sh[-0-9_]*"
|
||||
header "^#!.*/(ba|k|pdk)?sh[-0-9_]*"
|
||||
icolor brightgreen "^[0-9A-Z_]+\(\)"
|
||||
color green "\<(case|do|done|elif|else|esac|exit|fi|for|function|if|in|local|read|return|select|shift|then|time|until|while)\>"
|
||||
color green "(\{|\}|\(|\)|\;|\]|\[|`|\\|\$|<|>|!|=|&|\|)"
|
||||
|
||||
@@ -13,4 +13,4 @@ color green "(\(|\)|\;|`|\\|\$|<|>|!|=|&|\|)"
|
||||
color brightyellow ""(\\.|[^"])*"" "'(\\.|[^'])*'"
|
||||
icolor brightred "\$\{?[0-9A-Z_!@#$*?-]+\}?"
|
||||
color ,green "[[:space:]]+$"
|
||||
color ,magenta "^([[:space:]]+|)#.*"
|
||||
color ,magenta "^[[:space:]]*#.*"
|
||||
|
||||
@@ -16,9 +16,11 @@ foreach my $name (@combos) {
|
||||
my @args = @$name;
|
||||
my $pct = $i / $#combos * 100;
|
||||
printf "Trying with options: @args, %d%% done...\n", $pct;
|
||||
if (system "(./configure @args && make clean all) >/dev/null 2>&1") {
|
||||
my $cmd = "./configure @args && make clean all";
|
||||
system("($cmd) >/dev/null 2>&1");
|
||||
if ($? != 0) {
|
||||
print "Build failed for args: @args\n";
|
||||
print "Try running make to reproduce\n";
|
||||
print "To reproduce, run:\n $cmd\n";
|
||||
exit(1);
|
||||
}
|
||||
$i++;
|
||||
|
||||
832
po/nano.pot
832
po/nano.pot
File diff suppressed because it is too large
Load Diff
1690
po/pt_BR.po
1690
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
1208
po/zh_CN.po
1208
po/zh_CN.po
File diff suppressed because it is too large
Load Diff
793
po/zh_TW.po
793
po/zh_TW.po
File diff suppressed because it is too large
Load Diff
@@ -534,9 +534,9 @@ void browser_init(const char *path, DIR *dir)
|
||||
}
|
||||
|
||||
/* If width isn't initialized yet, and we've taken up only one line,
|
||||
* it means that width is equal to (COLS % longest). */
|
||||
* it means that width is equal to longest. */
|
||||
if (width == 0)
|
||||
width = COLS % longest;
|
||||
width = longest;
|
||||
}
|
||||
|
||||
/* Determine the shortcut key corresponding to the values of kbinput
|
||||
|
||||
48
src/color.c
48
src/color.c
@@ -268,6 +268,16 @@ void reset_multis_after(filestruct *fileptr, int mindex)
|
||||
else
|
||||
break;
|
||||
}
|
||||
for (; oof != NULL; oof = oof->next) {
|
||||
alloc_multidata_if_needed(oof);
|
||||
if (oof->multidata == NULL)
|
||||
continue;
|
||||
if (oof->multidata[mindex] == CNONE)
|
||||
oof->multidata[mindex] = -1;
|
||||
else
|
||||
break;
|
||||
}
|
||||
edit_refresh_needed = TRUE;
|
||||
}
|
||||
|
||||
void reset_multis_before(filestruct *fileptr, int mindex)
|
||||
@@ -282,11 +292,31 @@ void reset_multis_before(filestruct *fileptr, int mindex)
|
||||
else
|
||||
break;
|
||||
}
|
||||
for (; oof != NULL; oof = oof->prev) {
|
||||
alloc_multidata_if_needed(oof);
|
||||
if (oof->multidata == NULL)
|
||||
continue;
|
||||
if (oof->multidata[mindex] == CNONE)
|
||||
oof->multidata[mindex] = -1;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
edit_refresh_needed = TRUE;
|
||||
}
|
||||
|
||||
/* Reset one multiline regex info */
|
||||
void reset_multis_for_id(filestruct *fileptr, int num)
|
||||
{
|
||||
reset_multis_before(fileptr, num);
|
||||
reset_multis_after(fileptr, num);
|
||||
fileptr->multidata[num] = -1;
|
||||
}
|
||||
|
||||
/* Reset multi line strings around a filestruct ptr, trying to be smart about stopping */
|
||||
void reset_multis(filestruct *fileptr)
|
||||
/* Reset multi line strings around a filestruct ptr, trying to be smart about stopping
|
||||
force = reset everything regardless, useful when we don't know how much screen state
|
||||
has changed */
|
||||
void reset_multis(filestruct *fileptr, bool force)
|
||||
{
|
||||
int nobegin, noend;
|
||||
regmatch_t startmatch, endmatch;
|
||||
@@ -302,6 +332,11 @@ void reset_multis(filestruct *fileptr)
|
||||
continue;
|
||||
|
||||
alloc_multidata_if_needed(fileptr);
|
||||
if (force == TRUE) {
|
||||
reset_multis_for_id(fileptr, tmpcolor->id);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Figure out where the first begin and end are to determine if
|
||||
things changed drastically for the precalculated multi values */
|
||||
nobegin = regexec(tmpcolor->start, fileptr->data, 1, &startmatch, 0);
|
||||
@@ -309,16 +344,17 @@ void reset_multis(filestruct *fileptr)
|
||||
if (fileptr->multidata[tmpcolor->id] == CWHOLELINE) {
|
||||
if (nobegin && noend)
|
||||
continue;
|
||||
} else if (fileptr->multidata[tmpcolor->id] & CBEGINBEFORE && !noend
|
||||
} else if (fileptr->multidata[tmpcolor->id] == CNONE) {
|
||||
if (nobegin && noend)
|
||||
continue;
|
||||
} else if (fileptr->multidata[tmpcolor->id] & CBEGINBEFORE && !noend
|
||||
&& (nobegin || endmatch.rm_eo > startmatch.rm_eo)) {
|
||||
reset_multis_after(fileptr, tmpcolor->id);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If we got here assume the worst */
|
||||
reset_multis_before(fileptr, tmpcolor->id);
|
||||
reset_multis_after(fileptr, tmpcolor->id);
|
||||
fileptr->multidata[tmpcolor->id] = -1;
|
||||
reset_multis_for_id(fileptr, tmpcolor->id);
|
||||
}
|
||||
}
|
||||
#endif /* ENABLE_COLOR */
|
||||
|
||||
13
src/cut.c
13
src/cut.c
@@ -211,9 +211,12 @@ void do_cut_text(
|
||||
* modified. */
|
||||
set_modified();
|
||||
|
||||
|
||||
/* Update the screen. */
|
||||
edit_refresh();
|
||||
edit_refresh_needed = TRUE;
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
reset_multis(openfile->current, FALSE);
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
dump_filestruct(cutbuffer);
|
||||
@@ -276,7 +279,11 @@ void do_uncut_text(void)
|
||||
set_modified();
|
||||
|
||||
/* Update the screen. */
|
||||
edit_refresh();
|
||||
edit_refresh_needed = TRUE;
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
reset_multis(openfile->current, FALSE);
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
dump_filestruct_reverse();
|
||||
|
||||
108
src/files.c
108
src/files.c
@@ -96,6 +96,10 @@ void initialize_buffer_text(void)
|
||||
openfile->edittop = openfile->fileage;
|
||||
openfile->current = openfile->fileage;
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
openfile->fileage->multidata = NULL;
|
||||
#endif
|
||||
|
||||
openfile->totsize = 0;
|
||||
}
|
||||
|
||||
@@ -141,8 +145,8 @@ void open_buffer(const char *filename, bool undoable)
|
||||
|
||||
/* If we have a non-new file, read it in. Then, if the buffer has
|
||||
* no stat, update the stat, if applicable. */
|
||||
if (rc == 0) {
|
||||
read_file(f, filename, undoable);
|
||||
if (rc > 0) {
|
||||
read_file(f, rc, filename, undoable);
|
||||
#ifndef NANO_TINY
|
||||
if (openfile->current_stat == NULL) {
|
||||
openfile->current_stat =
|
||||
@@ -191,8 +195,8 @@ void replace_buffer(const char *filename)
|
||||
initialize_buffer_text();
|
||||
|
||||
/* If we have a non-new file, read it in. */
|
||||
if (rc == 0)
|
||||
read_file(f, filename, FALSE);
|
||||
if (rc > 0)
|
||||
read_file(f, rc, filename, FALSE);
|
||||
|
||||
/* Move back to the beginning of the first line of the buffer. */
|
||||
openfile->current = openfile->fileage;
|
||||
@@ -287,6 +291,47 @@ bool close_buffer(void)
|
||||
}
|
||||
#endif /* ENABLE_MULTIBUFFER */
|
||||
|
||||
/* A bit of a copy and paste from open_file(), is_file_writable()
|
||||
* just checks whether the file is appendable as a quick
|
||||
* permissions check, and we tend to err on the side of permissiveness
|
||||
* (reporting TRUE when it might be wrong) to not fluster users
|
||||
* editing on odd filesystems by printing incorrect warnings.
|
||||
*/
|
||||
int is_file_writable(const char *filename)
|
||||
{
|
||||
struct stat fileinfo, fileinfo2;
|
||||
int fd;
|
||||
FILE *f;
|
||||
char *full_filename;
|
||||
bool ans = TRUE;
|
||||
|
||||
|
||||
if (ISSET(VIEW_MODE))
|
||||
return TRUE;
|
||||
|
||||
assert(filename != NULL && f != NULL);
|
||||
|
||||
/* Get the specified file's full path. */
|
||||
full_filename = get_full_path(filename);
|
||||
|
||||
/* Okay, if we can't stat the path due to a component's
|
||||
permissions, just try the relative one */
|
||||
if (full_filename == NULL
|
||||
|| (stat(full_filename, &fileinfo) == -1 && stat(filename, &fileinfo2) != -1))
|
||||
full_filename = mallocstrcpy(NULL, filename);
|
||||
|
||||
if ((fd = open(full_filename, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR |
|
||||
S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)) == -1
|
||||
|| (f = fdopen(fd, "a")) == NULL)
|
||||
ans = FALSE;
|
||||
else
|
||||
fclose(f);
|
||||
close(fd);
|
||||
|
||||
free(full_filename);
|
||||
return ans;
|
||||
}
|
||||
|
||||
/* We make a new line of text from buf. buf is length buf_len. If
|
||||
* first_line_ins is TRUE, then we put the new line at the top of the
|
||||
* file. Otherwise, we assume prevnode is the last line of the file,
|
||||
@@ -344,8 +389,10 @@ filestruct *read_line(char *buf, filestruct *prevnode, bool
|
||||
|
||||
/* Read an open file into the current buffer. f should be set to the
|
||||
* open file, and filename should be set to the name of the file.
|
||||
undoable means do we want to create undo records to try and undo this */
|
||||
void read_file(FILE *f, const char *filename, bool undoable)
|
||||
* undoable means do we want to create undo records to try and undo this.
|
||||
* Will also attempt to check file writability if fd > 0
|
||||
*/
|
||||
void read_file(FILE *f, int fd, const char *filename, bool undoable)
|
||||
{
|
||||
size_t num_lines = 0;
|
||||
/* The number of lines in the file. */
|
||||
@@ -366,6 +413,8 @@ void read_file(FILE *f, const char *filename, bool undoable)
|
||||
int input_int;
|
||||
/* The current value we read from the file, whether an input
|
||||
* character or EOF. */
|
||||
bool writable = TRUE;
|
||||
/* Is the file writable (if we care) */
|
||||
#ifndef NANO_TINY
|
||||
int format = 0;
|
||||
/* 0 = *nix, 1 = DOS, 2 = Mac, 3 = both DOS and Mac. */
|
||||
@@ -465,6 +514,10 @@ void read_file(FILE *f, const char *filename, bool undoable)
|
||||
if (ferror(f))
|
||||
nperror(filename);
|
||||
fclose(f);
|
||||
if (fd > 0) {
|
||||
close(fd);
|
||||
writable = is_file_writable(filename);
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* If file conversion isn't disabled and the last character in this
|
||||
@@ -574,24 +627,45 @@ void read_file(FILE *f, const char *filename, bool undoable)
|
||||
if (undoable)
|
||||
update_undo(INSERT);
|
||||
|
||||
if (format == 3)
|
||||
statusbar(
|
||||
if (format == 3) {
|
||||
if (writable)
|
||||
statusbar(
|
||||
P_("Read %lu line (Converted from DOS and Mac format)",
|
||||
"Read %lu lines (Converted from DOS and Mac format)",
|
||||
(unsigned long)num_lines), (unsigned long)num_lines);
|
||||
else if (format == 2) {
|
||||
else
|
||||
statusbar(
|
||||
P_("Read %lu line (Converted from DOS and Mac format - Warning: No write permission)",
|
||||
"Read %lu lines (Converted from DOS and Mac format - Warning: No write permission)",
|
||||
(unsigned long)num_lines), (unsigned long)num_lines);
|
||||
} else if (format == 2) {
|
||||
openfile->fmt = MAC_FILE;
|
||||
statusbar(P_("Read %lu line (Converted from Mac format)",
|
||||
if (writable)
|
||||
statusbar(P_("Read %lu line (Converted from Mac format)",
|
||||
"Read %lu lines (Converted from Mac format)",
|
||||
(unsigned long)num_lines), (unsigned long)num_lines);
|
||||
else
|
||||
statusbar(P_("Read %lu line (Converted from Mac format - Warning: No write permission)",
|
||||
"Read %lu lines (Converted from Mac format - Warning: No write permission)",
|
||||
(unsigned long)num_lines), (unsigned long)num_lines);
|
||||
} else if (format == 1) {
|
||||
openfile->fmt = DOS_FILE;
|
||||
statusbar(P_("Read %lu line (Converted from DOS format)",
|
||||
if (writable)
|
||||
statusbar(P_("Read %lu line (Converted from DOS format)",
|
||||
"Read %lu lines (Converted from DOS format)",
|
||||
(unsigned long)num_lines), (unsigned long)num_lines);
|
||||
else
|
||||
statusbar(P_("Read %lu line (Converted from DOS format - Warning: No write permission)",
|
||||
"Read %lu lines (Converted from DOS format - Warning: No write permission)",
|
||||
(unsigned long)num_lines), (unsigned long)num_lines);
|
||||
} else
|
||||
#endif
|
||||
statusbar(P_("Read %lu line", "Read %lu lines",
|
||||
if (writable)
|
||||
statusbar(P_("Read %lu line", "Read %lu lines",
|
||||
(unsigned long)num_lines), (unsigned long)num_lines);
|
||||
else
|
||||
statusbar(P_("Read %lu line ( Warning: No write permission)",
|
||||
"Read %lu lines (Warning: No write permission)",
|
||||
(unsigned long)num_lines), (unsigned long)num_lines);
|
||||
}
|
||||
|
||||
@@ -599,9 +673,9 @@ void read_file(FILE *f, const char *filename, bool undoable)
|
||||
* "New File" if the file is missing. Otherwise, say "[filename] not
|
||||
* found".
|
||||
*
|
||||
* Return -2 if we say "New File", -1 if the file isn't opened, and 0
|
||||
* otherwise. The file might still have an error while reading with a 0
|
||||
* return value. *f is set to the opened file. */
|
||||
* Return -2 if we say "New File", -1 if the file isn't opened, and the
|
||||
* fd opened otherwise. The file might still have an error while reading
|
||||
* with a 0 return value. *f is set to the opened file. */
|
||||
int open_file(const char *filename, bool newfie, FILE **f)
|
||||
{
|
||||
struct stat fileinfo, fileinfo2;
|
||||
@@ -664,7 +738,7 @@ int open_file(const char *filename, bool newfie, FILE **f)
|
||||
|
||||
free(full_filename);
|
||||
|
||||
return 0;
|
||||
return fd;
|
||||
}
|
||||
|
||||
/* This function will return the name of the first available extension
|
||||
@@ -2044,7 +2118,7 @@ bool do_writeout(bool exiting)
|
||||
}
|
||||
}
|
||||
#ifndef NANO_TINY
|
||||
if (openfile->current_stat && openfile->current_stat->st_mtime < st.st_mtime) {
|
||||
if (name_exists && openfile->current_stat && openfile->current_stat->st_mtime < st.st_mtime) {
|
||||
i = do_yesno_prompt(FALSE,
|
||||
_("File was modified since you opened it, continue saving ? "));
|
||||
if (i == 0 || i == -1)
|
||||
|
||||
39
src/global.c
39
src/global.c
@@ -52,7 +52,7 @@ char *last_search = NULL;
|
||||
char *last_replace = NULL;
|
||||
/* The last replacement string we searched for. */
|
||||
|
||||
long flags = 0;
|
||||
unsigned flags[4] = {0, 0, 0, 0};
|
||||
/* Our flag containing the states of all global options. */
|
||||
WINDOW *topwin;
|
||||
/* The top portion of the window, where we display the version
|
||||
@@ -66,6 +66,8 @@ WINDOW *bottomwin;
|
||||
* messages, the statusbar prompt, and a list of shortcuts. */
|
||||
int editwinrows = 0;
|
||||
/* How many rows does the edit window take up? */
|
||||
int maxrows = 0;
|
||||
/* How many usable lines are there (due to soft wrapping) */
|
||||
|
||||
filestruct *cutbuffer = NULL;
|
||||
/* The buffer where we store cut text. */
|
||||
@@ -232,7 +234,7 @@ void add_to_funcs(short func, int menus, const char *desc, const char *help,
|
||||
subnfunc *f;
|
||||
|
||||
if (allfuncs == NULL) {
|
||||
allfuncs = nmalloc(sizeof(subnfunc));
|
||||
allfuncs = (subnfunc *) nmalloc(sizeof(subnfunc));
|
||||
f = allfuncs;
|
||||
} else {
|
||||
for (f = allfuncs; f->next != NULL; f = f->next)
|
||||
@@ -292,7 +294,7 @@ void add_to_sclist(int menu, char *scstring, short func, int toggle, int execute
|
||||
sc *s;
|
||||
|
||||
if (sclist == NULL) {
|
||||
sclist = nmalloc(sizeof(sc));
|
||||
sclist = (sc *) nmalloc(sizeof(sc));
|
||||
s = sclist;
|
||||
s->next = NULL;
|
||||
} else {
|
||||
@@ -778,11 +780,13 @@ void shortcut_init(bool unjustify)
|
||||
add_to_funcs(DO_UNINDENT, MMAIN, N_("Unindent Text"),
|
||||
IFSCHELP(nano_unindent_msg), FALSE, NOVIEW);
|
||||
|
||||
add_to_funcs(DO_UNDO, MMAIN, N_("Undo"),
|
||||
IFSCHELP(nano_undo_msg), FALSE, NOVIEW);
|
||||
if (ISSET(UNDOABLE)) {
|
||||
add_to_funcs(DO_UNDO, MMAIN, N_("Undo"),
|
||||
IFSCHELP(nano_undo_msg), FALSE, NOVIEW);
|
||||
|
||||
add_to_funcs(DO_REDO, MMAIN, N_("Redo"),
|
||||
IFSCHELP(nano_redo_msg), TRUE, NOVIEW);
|
||||
add_to_funcs(DO_REDO, MMAIN, N_("Redo"),
|
||||
IFSCHELP(nano_redo_msg), TRUE, NOVIEW);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1064,8 +1068,10 @@ void shortcut_init(bool unjustify)
|
||||
add_to_sclist(MMAIN, "M-6", DO_COPY_TEXT, 0, TRUE);
|
||||
add_to_sclist(MMAIN, "M-}", DO_INDENT_VOID, 0, TRUE);
|
||||
add_to_sclist(MMAIN, "M-{", DO_UNINDENT, 0, TRUE);
|
||||
add_to_sclist(MMAIN, "M-U", DO_UNDO, 0, TRUE);
|
||||
add_to_sclist(MMAIN, "M-E", DO_REDO, 0, TRUE);
|
||||
if (ISSET(UNDOABLE)) {
|
||||
add_to_sclist(MMAIN, "M-U", DO_UNDO, 0, TRUE);
|
||||
add_to_sclist(MMAIN, "M-E", DO_REDO, 0, TRUE);
|
||||
}
|
||||
add_to_sclist(MALL, "^F", DO_RIGHT, 0, TRUE);
|
||||
add_to_sclist(MALL, "^B", DO_LEFT, 0, TRUE);
|
||||
add_to_sclist(MMAIN, "^Space", DO_NEXT_WORD_VOID, 0, TRUE);
|
||||
@@ -1075,10 +1081,10 @@ void shortcut_init(bool unjustify)
|
||||
add_to_sclist(MALL, "kleft", DO_LEFT, 0, TRUE);
|
||||
add_to_sclist(MMAIN, "^Q", XON_COMPLAINT, 0, TRUE);
|
||||
add_to_sclist(MMAIN, "^S", XOFF_COMPLAINT, 0, TRUE);
|
||||
add_to_sclist(MMAIN, "^P", DO_UP_VOID, 0, TRUE);
|
||||
add_to_sclist(MMAIN, "kup", DO_UP_VOID, 0, TRUE);
|
||||
add_to_sclist(MMAIN, "^N", DO_DOWN_VOID, 0, TRUE);
|
||||
add_to_sclist(MMAIN, "kdown", DO_DOWN_VOID, 0, TRUE);
|
||||
add_to_sclist(MMAIN|MBROWSER, "^P", DO_UP_VOID, 0, TRUE);
|
||||
add_to_sclist(MMAIN|MBROWSER, "kup", DO_UP_VOID, 0, TRUE);
|
||||
add_to_sclist(MMAIN|MBROWSER, "^N", DO_DOWN_VOID, 0, TRUE);
|
||||
add_to_sclist(MMAIN|MBROWSER, "kdown", DO_DOWN_VOID, 0, TRUE);
|
||||
add_to_sclist(MALL, "^A", DO_HOME, 0, TRUE);
|
||||
add_to_sclist(MALL, "khome", DO_HOME, 0, TRUE);
|
||||
add_to_sclist(MALL, "^E", DO_END, 0, TRUE);
|
||||
@@ -1160,6 +1166,7 @@ void shortcut_init(bool unjustify)
|
||||
add_to_sclist(MMAIN, "M-M", DO_TOGGLE, USE_MOUSE, TRUE);
|
||||
add_to_sclist(MMAIN, "M-N", DO_TOGGLE, NO_CONVERT, TRUE);
|
||||
add_to_sclist(MMAIN, "M-Z", DO_TOGGLE, SUSPEND, TRUE);
|
||||
add_to_sclist(MMAIN, "M-$", DO_TOGGLE, SOFTWRAP, TRUE);
|
||||
#endif
|
||||
add_to_sclist(MGOTOLINE, "^T", GOTOTEXT_MSG, 0, FALSE);
|
||||
add_to_sclist(MINSERTFILE|MEXTCMD, "M-F", NEW_BUFFER_MSG, 0, FALSE);
|
||||
@@ -1214,7 +1221,7 @@ void iso_me_harder_funcmap(short func)
|
||||
else if (func == DO_RIGHT)
|
||||
do_right();
|
||||
else if (func == DO_ENTER)
|
||||
do_enter();
|
||||
do_enter(FALSE);
|
||||
else if (func == DO_EXIT)
|
||||
do_exit();
|
||||
else if (func == DO_FIRST_LINE)
|
||||
@@ -1372,6 +1379,8 @@ char *flagtostr(int flag)
|
||||
return N_("No conversion from DOS/Mac format");
|
||||
case SUSPEND:
|
||||
return N_("Suspension");
|
||||
case SOFTWRAP:
|
||||
return N_("Soft line wrapping");
|
||||
default:
|
||||
return "?????";
|
||||
}
|
||||
@@ -1715,9 +1724,11 @@ void thanks_for_all_the_fish(void)
|
||||
if (jusbuffer != NULL)
|
||||
free_filestruct(jusbuffer);
|
||||
#endif
|
||||
#ifdef DEBUG
|
||||
/* Free the memory associated with each open file buffer. */
|
||||
if (openfile != NULL)
|
||||
free_openfilestruct(openfile);
|
||||
#endif
|
||||
#ifdef ENABLE_COLOR
|
||||
if (syntaxstr != NULL)
|
||||
free(syntaxstr);
|
||||
|
||||
57
src/move.c
57
src/move.c
@@ -29,28 +29,22 @@
|
||||
/* Move to the first line of the file. */
|
||||
void do_first_line(void)
|
||||
{
|
||||
filestruct *current_save = openfile->current;
|
||||
size_t pww_save = openfile->placewewant;
|
||||
|
||||
openfile->current = openfile->fileage;
|
||||
openfile->current = openfile->edittop = openfile->fileage;
|
||||
openfile->current_x = 0;
|
||||
openfile->placewewant = 0;
|
||||
|
||||
edit_redraw(current_save, pww_save);
|
||||
edit_refresh_needed = 1;
|
||||
}
|
||||
|
||||
/* Move to the last line of the file. */
|
||||
void do_last_line(void)
|
||||
{
|
||||
filestruct *current_save = openfile->current;
|
||||
size_t pww_save = openfile->placewewant;
|
||||
|
||||
openfile->current = openfile->filebot;
|
||||
openfile->current_x = strlen(openfile->filebot->data);
|
||||
openfile->placewewant = xplustabs();
|
||||
openfile->current_y = editwinrows - 1;
|
||||
|
||||
edit_redraw(current_save, pww_save);
|
||||
edit_refresh_needed = 1;
|
||||
}
|
||||
|
||||
/* Move up one page. */
|
||||
@@ -96,7 +90,7 @@ void do_page_down(void)
|
||||
/* If there's less than a page of text left on the screen, put the
|
||||
* cursor at the beginning of the last line of the file, and then
|
||||
* update the edit window. */
|
||||
if (openfile->current->lineno + editwinrows - 2 >=
|
||||
if (openfile->current->lineno + maxrows - 2 >=
|
||||
openfile->filebot->lineno) {
|
||||
do_last_line();
|
||||
return;
|
||||
@@ -113,15 +107,24 @@ void do_page_down(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = editwinrows - 2; i > 0 && openfile->current !=
|
||||
openfile->filebot; i--)
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "do_page_down: maxrows = %d\n", maxrows);
|
||||
#endif
|
||||
|
||||
for (i = maxrows - 2; i > 0 && openfile->current !=
|
||||
openfile->filebot; i--) {
|
||||
openfile->current = openfile->current->next;
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "do_page_down: moving to line %d\n", openfile->current->lineno);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
openfile->current_x = actual_x(openfile->current->data,
|
||||
openfile->placewewant);
|
||||
|
||||
/* Scroll the edit window down a page. */
|
||||
edit_scroll(DOWN_DIR, editwinrows - 2);
|
||||
edit_scroll(DOWN_DIR, maxrows - 2);
|
||||
}
|
||||
|
||||
#ifndef DISABLE_JUSTIFY
|
||||
@@ -488,7 +491,7 @@ void do_up(
|
||||
)
|
||||
return;
|
||||
|
||||
assert(openfile->current_y == openfile->current->lineno - openfile->edittop->lineno);
|
||||
assert(ISSET(SOFTWRAP) || openfile->current_y == openfile->current->lineno - openfile->edittop->lineno);
|
||||
|
||||
/* Move the current line of the edit window up. */
|
||||
openfile->current = openfile->current->prev;
|
||||
@@ -500,7 +503,7 @@ void do_up(
|
||||
* smooth scrolling mode, or up half a page if we're not. If
|
||||
* scroll_only is TRUE, scroll the edit window up one line
|
||||
* unconditionally. */
|
||||
if (openfile->current_y == 0
|
||||
if (openfile->current_y == 0 || (ISSET(SOFTWRAP) && openfile->edittop->lineno == openfile->current->next->lineno)
|
||||
#ifndef NANO_TINY
|
||||
|| scroll_only
|
||||
#endif
|
||||
@@ -550,23 +553,41 @@ void do_down(
|
||||
#endif
|
||||
)
|
||||
{
|
||||
bool onlastline = FALSE;
|
||||
|
||||
/* If we're at the bottom of the file, get out. */
|
||||
if (openfile->current == openfile->filebot)
|
||||
return;
|
||||
|
||||
assert(openfile->current_y == openfile->current->lineno - openfile->edittop->lineno);
|
||||
|
||||
assert(ISSET(SOFTWRAP) || openfile->current_y == openfile->current->lineno - openfile->edittop->lineno);
|
||||
|
||||
/* Move the current line of the edit window down. */
|
||||
openfile->current = openfile->current->next;
|
||||
openfile->current_x = actual_x(openfile->current->data,
|
||||
openfile->placewewant);
|
||||
|
||||
if (ISSET(SOFTWRAP)) {
|
||||
filestruct *foo;
|
||||
ssize_t extracuzsoft = 0;
|
||||
|
||||
for (foo = openfile->edittop; foo
|
||||
&& foo->lineno - openfile->edittop->lineno + extracuzsoft < editwinrows;
|
||||
foo = foo->next) {
|
||||
extracuzsoft += strlenpt(foo->data) / (COLS - 1);
|
||||
if (foo == openfile->current)
|
||||
break;
|
||||
}
|
||||
if (foo && foo->lineno - openfile->edittop->lineno + extracuzsoft >= editwinrows)
|
||||
onlastline = TRUE;
|
||||
}
|
||||
|
||||
/* If scroll_only is FALSE and if we're on the first line of the
|
||||
* edit window, scroll the edit window down one line if we're in
|
||||
* smooth scrolling mode, or down half a page if we're not. If
|
||||
* scroll_only is TRUE, scroll the edit window down one line
|
||||
* unconditionally. */
|
||||
if (openfile->current_y == editwinrows - 1
|
||||
if (onlastline || openfile->current_y == editwinrows - 1
|
||||
#ifndef NANO_TINY
|
||||
|| scroll_only
|
||||
#endif
|
||||
@@ -581,7 +602,7 @@ void do_down(
|
||||
* we were on before and the line we're on now. The former needs to
|
||||
* be redrawn if we're not on the first page, and the latter needs
|
||||
* to be drawn unconditionally. */
|
||||
if (openfile->current_y < editwinrows - 1) {
|
||||
if (ISSET(SOFTWRAP) || openfile->current_y < editwinrows - 1) {
|
||||
if (need_vertical_update(0))
|
||||
update_line(openfile->current->prev, 0);
|
||||
update_line(openfile->current, openfile->current_x);
|
||||
|
||||
207
src/nano.c
207
src/nano.c
@@ -638,7 +638,7 @@ void die(const char *msg, ...)
|
||||
if (filepart != NULL)
|
||||
unpartition_filestruct(&filepart);
|
||||
|
||||
die_save_file(openfile->filename);
|
||||
die_save_file(openfile->filename, openfile->current_stat);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
@@ -651,7 +651,7 @@ void die(const char *msg, ...)
|
||||
|
||||
/* Save the current file buffer if it's been modified. */
|
||||
if (openfile->modified)
|
||||
die_save_file(openfile->filename);
|
||||
die_save_file(openfile->filename, openfile->current_stat);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -662,7 +662,7 @@ void die(const char *msg, ...)
|
||||
|
||||
/* Save the current file under the name spacified in die_filename, which
|
||||
* is modified to be unique if necessary. */
|
||||
void die_save_file(const char *die_filename)
|
||||
void die_save_file(const char *die_filename, struct stat *die_stat)
|
||||
{
|
||||
char *retval;
|
||||
bool failed = TRUE;
|
||||
@@ -691,6 +691,15 @@ void die_save_file(const char *die_filename)
|
||||
fprintf(stderr, _("\nBuffer not written: %s\n"),
|
||||
_("Too many backup files?"));
|
||||
|
||||
/* Try and chmod/chown the save file to the values of the original file, but
|
||||
dont worry if it fails because we're supposed to be bailing as fast
|
||||
as possible. */
|
||||
if (die_stat) {
|
||||
int shush;
|
||||
shush = chmod(retval, die_stat->st_mode);
|
||||
shush = chown(retval, die_stat->st_uid, die_stat->st_gid);
|
||||
}
|
||||
|
||||
free(retval);
|
||||
}
|
||||
|
||||
@@ -879,6 +888,8 @@ void usage(void)
|
||||
#endif
|
||||
print_opt("-p", "--preserve",
|
||||
N_("Preserve XON (^Q) and XOFF (^S) keys"));
|
||||
print_opt("-q", "--quiet",
|
||||
N_("Silently ignore startup issues like rc file errors"));
|
||||
#ifndef DISABLE_WRAPJUSTIFY
|
||||
print_opt(_("-r <#cols>"), _("--fill=<#cols>"),
|
||||
N_("Set wrapping point at column #cols"));
|
||||
@@ -889,12 +900,17 @@ void usage(void)
|
||||
#endif
|
||||
print_opt("-t", "--tempfile",
|
||||
N_("Auto save on exit, don't prompt"));
|
||||
#ifndef NANO_TINY
|
||||
print_opt("-u", "--undo", N_("Allow generic undo [EXPERIMENTAL]"));
|
||||
#endif
|
||||
|
||||
print_opt("-v", "--view", N_("View mode (read-only)"));
|
||||
#ifndef DISABLE_WRAPPING
|
||||
print_opt("-w", "--nowrap", N_("Don't wrap long lines"));
|
||||
#endif
|
||||
print_opt("-x", "--nohelp", N_("Don't show the two help lines"));
|
||||
print_opt("-z", "--suspend", N_("Enable suspension"));
|
||||
print_opt("-$", "--softwrap", N_("Enable soft line wrapping"));
|
||||
|
||||
/* This is a special case. */
|
||||
print_opt("-a, -b, -e,", "", NULL);
|
||||
@@ -1053,7 +1069,7 @@ void finish_stdin_pager(void)
|
||||
if (f == NULL)
|
||||
nperror("fopen");
|
||||
|
||||
read_file(f, "stdin", TRUE);
|
||||
read_file(f, 0, "stdin", TRUE);
|
||||
ttystdin = open("/dev/tty", O_RDONLY);
|
||||
if (!ttystdin)
|
||||
die(_("Couldn't reopen stdin from keyboard, sorry\n"));
|
||||
@@ -1327,6 +1343,9 @@ void do_toggle(int flag)
|
||||
edit_refresh();
|
||||
break;
|
||||
#endif
|
||||
case SOFTWRAP:
|
||||
total_refresh();
|
||||
break;
|
||||
}
|
||||
|
||||
enabled = ISSET(flag);
|
||||
@@ -1588,27 +1607,32 @@ int do_input(bool *meta_key, bool *func_key, bool *s_or_t, bool
|
||||
*ran_func = TRUE;
|
||||
if (ISSET(VIEW_MODE) && f && !f->viewok)
|
||||
print_view_warning();
|
||||
else
|
||||
else {
|
||||
#ifndef NANO_TINY
|
||||
if (s->scfunc == DO_TOGGLE)
|
||||
do_toggle(s->toggle);
|
||||
else {
|
||||
#else
|
||||
{
|
||||
#endif
|
||||
iso_me_harder_funcmap(s->scfunc);
|
||||
#ifdef ENABLE_COLOR
|
||||
if (!f->viewok && openfile->syntax != NULL
|
||||
&& openfile->current->multidata && openfile->syntax->nmultis > 0) {
|
||||
reset_multis(openfile->current);
|
||||
if (!f->viewok && openfile->syntax != NULL
|
||||
&& openfile->syntax->nmultis > 0) {
|
||||
reset_multis(openfile->current, FALSE);
|
||||
}
|
||||
if (edit_refresh_needed) {
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "running edit_refresh() as edit_refresh_needed is true\n");
|
||||
#endif
|
||||
edit_refresh();
|
||||
edit_refresh_needed = FALSE;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
#ifndef NANO_TINY
|
||||
}
|
||||
}
|
||||
#endif
|
||||
*finished = TRUE;
|
||||
break;
|
||||
}
|
||||
@@ -1652,17 +1676,53 @@ int do_mouse(void)
|
||||
|
||||
sameline = (mouse_y == openfile->current_y);
|
||||
|
||||
/* Move to where the click occurred. */
|
||||
for (; openfile->current_y < mouse_y && openfile->current !=
|
||||
openfile->filebot; openfile->current_y++)
|
||||
openfile->current = openfile->current->next;
|
||||
for (; openfile->current_y > mouse_y && openfile->current !=
|
||||
openfile->fileage; openfile->current_y--)
|
||||
openfile->current = openfile->current->prev;
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "mouse_y = %d, current_y = %d\n", mouse_y, openfile->current_y);
|
||||
#endif
|
||||
|
||||
openfile->current_x = actual_x(openfile->current->data,
|
||||
if (ISSET(SOFTWRAP)) {
|
||||
int i = 0;
|
||||
for (openfile->current = openfile->edittop;
|
||||
openfile->current->next && i < mouse_y;
|
||||
openfile->current = openfile->current->next, i++) {
|
||||
openfile->current_y = i;
|
||||
i += strlenpt(openfile->current->data) / COLS;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "do_mouse(): moving to current_y = %d, i %d\n", openfile->current_y, i);
|
||||
fprintf(stderr, " openfile->current->data = \"%s\"\n", openfile->current->data);
|
||||
#endif
|
||||
|
||||
if (i > mouse_y) {
|
||||
openfile->current = openfile->current->prev;
|
||||
openfile->current_x = actual_x(openfile->current->data, mouse_x + (mouse_y - openfile->current_y) * COLS);
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "do_mouse(): i > mouse_y, mouse_x = %d, current_x to = %d\n", mouse_x, openfile->current_x);
|
||||
#endif
|
||||
} else {
|
||||
openfile->current_x = actual_x(openfile->current->data, mouse_x);
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "do_mouse(): i <= mouse_y, mouse_x = %d, setting current_x to = %d\n", mouse_x, openfile->current_x);
|
||||
#endif
|
||||
}
|
||||
|
||||
openfile->placewewant = xplustabs();
|
||||
|
||||
} else {
|
||||
/* Move to where the click occurred. */
|
||||
for (; openfile->current_y < mouse_y && openfile->current !=
|
||||
openfile->filebot; openfile->current_y++)
|
||||
openfile->current = openfile->current->next;
|
||||
for (; openfile->current_y > mouse_y && openfile->current !=
|
||||
openfile->fileage; openfile->current_y--)
|
||||
openfile->current = openfile->current->prev;
|
||||
|
||||
openfile->current_x = actual_x(openfile->current->data,
|
||||
get_page_start(xplustabs()) + mouse_x);
|
||||
openfile->placewewant = xplustabs();
|
||||
|
||||
openfile->placewewant = xplustabs();
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Clicking where the cursor is toggles the mark, as does
|
||||
@@ -1690,6 +1750,9 @@ void alloc_multidata_if_needed(filestruct *fileptr)
|
||||
rendering (with any hope at all...) */
|
||||
void precalc_multicolorinfo(void)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "entering precalc_multicolorinfo()\n");
|
||||
#endif
|
||||
if (openfile->colorstrings != NULL && !ISSET(NO_COLOR_SYNTAX)) {
|
||||
const colortype *tmpcolor = openfile->colorstrings;
|
||||
regmatch_t startmatch, endmatch;
|
||||
@@ -1708,9 +1771,19 @@ void precalc_multicolorinfo(void)
|
||||
/* If it's not a multi-line regex, amscray */
|
||||
if (tmpcolor->end == NULL)
|
||||
continue;
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "working on color id %d\n", tmpcolor->id);
|
||||
#endif
|
||||
|
||||
|
||||
for (fileptr = openfile->fileage; fileptr != NULL; fileptr = fileptr->next) {
|
||||
int startx = 0;
|
||||
int nostart = 0;
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "working on lineno %lu\n", (unsigned long) fileptr->lineno);
|
||||
#endif
|
||||
|
||||
alloc_multidata_if_needed(fileptr);
|
||||
|
||||
@@ -1720,44 +1793,84 @@ void precalc_multicolorinfo(void)
|
||||
goto precalc_cleanup;
|
||||
}
|
||||
|
||||
fileptr->multidata[tmpcolor->id] = CNONE;
|
||||
while (regexec(tmpcolor->start, &fileptr->data[startx], 1, &startmatch, 0) == 0) {
|
||||
while ((nostart = regexec(tmpcolor->start, &fileptr->data[startx], 1, &startmatch, 0)) == 0) {
|
||||
/* Look for end and start marking how many lines are encompassed
|
||||
whcih should speed up rendering later */
|
||||
startx += startmatch.rm_eo;
|
||||
startx += startmatch.rm_eo;
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "match found at pos %d...", startx);
|
||||
#endif
|
||||
|
||||
/* Look on this line first for end */
|
||||
if (regexec(tmpcolor->end, &fileptr->data[startx], 1, &endmatch, 0) == 0) {
|
||||
startx += endmatch.rm_eo;
|
||||
fileptr->multidata[tmpcolor->id] |= CSTARTENDHERE;
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "end found on this line\n");
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Nice, we didn't find the end regex on this line. Let's start looking for it */
|
||||
for (endptr = fileptr->next; endptr != NULL; endptr = endptr->next) {
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "advancing to line %lu to find end...\n", (unsigned long) endptr->lineno);
|
||||
#endif
|
||||
/* Check for keyboard input again */
|
||||
if ((cur_check = time(NULL)) - last_check > 1) {
|
||||
last_check = cur_check;
|
||||
if (wgetch(edit) != ERR)
|
||||
goto precalc_cleanup;
|
||||
}
|
||||
if (regexec(tmpcolor->end, &endptr->data[startx], 1, &endmatch, 0) == 0)
|
||||
if (regexec(tmpcolor->end, endptr->data, 1, &endmatch, 0) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (endptr == NULL)
|
||||
if (endptr == NULL) {
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "no end found, breaking out\n");
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "end found\n");
|
||||
#endif
|
||||
|
||||
/* We found it, we found it, la la la la la. Mark all the
|
||||
lines in between and the ends properly */
|
||||
fileptr->multidata[tmpcolor->id] |= CENDAFTER;
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "marking line %lu as CENDAFTER\n", (unsigned long) fileptr->lineno);
|
||||
#endif
|
||||
for (fileptr = fileptr->next; fileptr != endptr; fileptr = fileptr->next) {
|
||||
alloc_multidata_if_needed(fileptr);
|
||||
fileptr->multidata[tmpcolor->id] = CWHOLELINE;
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "marking intermediary line %lu as CWHOLELINE\n", (unsigned long) fileptr->lineno);
|
||||
#endif
|
||||
}
|
||||
alloc_multidata_if_needed(endptr);
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "marking line %lu as BEGINBEFORE\n", (unsigned long) fileptr->lineno);
|
||||
#endif
|
||||
endptr->multidata[tmpcolor->id] |= CBEGINBEFORE;
|
||||
/* We should be able to skip all the way to the line of the match.
|
||||
This may introduce more bugs but it's the Right Thing to do */
|
||||
fileptr = endptr;
|
||||
startx = endmatch.rm_eo;
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "jumping to line %lu pos %d to continue\n", (unsigned long) endptr->lineno, startx);
|
||||
#endif
|
||||
}
|
||||
if (nostart && startx == 0) {
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "no start found on line %lu, continuing\n", (unsigned long) fileptr->lineno);
|
||||
#endif
|
||||
fileptr->multidata[tmpcolor->id] = CNONE;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1793,7 +1906,7 @@ void do_output(char *output, size_t output_len, bool allow_cntrls)
|
||||
output[i] = '\n';
|
||||
/* Newline to Enter, if needed. */
|
||||
else if (output[i] == '\n') {
|
||||
do_enter();
|
||||
do_enter(FALSE);
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
@@ -1835,7 +1948,6 @@ void do_output(char *output, size_t output_len, bool allow_cntrls)
|
||||
#ifndef NANO_TINY
|
||||
update_undo(ADD);
|
||||
|
||||
|
||||
/* Note that current_x has not yet been incremented. */
|
||||
if (openfile->mark_set && openfile->current ==
|
||||
openfile->mark_begin && openfile->current_x <
|
||||
@@ -1850,7 +1962,7 @@ void do_output(char *output, size_t output_len, bool allow_cntrls)
|
||||
if (!ISSET(NO_WRAP)) {
|
||||
bool do_refresh_save = do_refresh;
|
||||
|
||||
do_refresh = do_wrap(openfile->current);
|
||||
do_refresh = do_wrap(openfile->current, FALSE);
|
||||
|
||||
/* If we needed to call edit_refresh() before this, we'll
|
||||
* still need to after this. */
|
||||
@@ -1873,7 +1985,7 @@ void do_output(char *output, size_t output_len, bool allow_cntrls)
|
||||
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
reset_multis(openfile->current);
|
||||
reset_multis(openfile->current, FALSE);
|
||||
#endif
|
||||
if (do_refresh) {
|
||||
edit_refresh();
|
||||
@@ -1930,6 +2042,7 @@ int main(int argc, char **argv)
|
||||
{"operatingdir", 1, NULL, 'o'},
|
||||
#endif
|
||||
{"preserve", 0, NULL, 'p'},
|
||||
{"quiet", 0, NULL, 'q'},
|
||||
#ifndef DISABLE_WRAPJUSTIFY
|
||||
{"fill", 1, NULL, 'r'},
|
||||
#endif
|
||||
@@ -1952,9 +2065,11 @@ int main(int argc, char **argv)
|
||||
{"noconvert", 0, NULL, 'N'},
|
||||
{"smooth", 0, NULL, 'S'},
|
||||
{"quickblank", 0, NULL, 'U'},
|
||||
{"undo", 0, NULL, 'u'},
|
||||
{"wordbounds", 0, NULL, 'W'},
|
||||
{"autoindent", 0, NULL, 'i'},
|
||||
{"cut", 0, NULL, 'k'},
|
||||
{"softwrap", 0, NULL, '$'},
|
||||
#endif
|
||||
{NULL, 0, NULL, 0}
|
||||
};
|
||||
@@ -1993,11 +2108,11 @@ int main(int argc, char **argv)
|
||||
while ((optchr =
|
||||
#ifdef HAVE_GETOPT_LONG
|
||||
getopt_long(argc, argv,
|
||||
"h?ABC:DEFHIKLNOQ:RST:UVWY:abcdefgijklmo:pr:s:tvwxz",
|
||||
"h?ABC:DEFHIKLNOQ:RST:UVWY:abcdefgijklmo:pqr:s:tuvwxz$",
|
||||
long_options, NULL)
|
||||
#else
|
||||
getopt(argc, argv,
|
||||
"h?ABC:DEFHIKLNOQ:RST:UVWY:abcdefgijklmo:pr:s:tvwxz")
|
||||
"h?ABC:DEFHIKLNOQ:RST:UVWY:abcdefgijklmo:pqr:s:tuvwxz$")
|
||||
#endif
|
||||
) != -1) {
|
||||
switch (optchr) {
|
||||
@@ -2125,6 +2240,9 @@ int main(int argc, char **argv)
|
||||
case 'p':
|
||||
SET(PRESERVE);
|
||||
break;
|
||||
case 'q':
|
||||
SET(QUIET);
|
||||
break;
|
||||
#ifndef DISABLE_WRAPJUSTIFY
|
||||
case 'r':
|
||||
if (!parse_num(optarg, &wrap_at)) {
|
||||
@@ -2143,12 +2261,22 @@ int main(int argc, char **argv)
|
||||
case 't':
|
||||
SET(TEMP_FILE);
|
||||
break;
|
||||
#ifndef NANO_TINY
|
||||
case 'u':
|
||||
SET(UNDOABLE);
|
||||
break;
|
||||
#endif
|
||||
case 'v':
|
||||
SET(VIEW_MODE);
|
||||
break;
|
||||
#ifndef DISABLE_WRAPPING
|
||||
case 'w':
|
||||
SET(NO_WRAP);
|
||||
|
||||
/* If both --fill and --nowrap are given on the command line,
|
||||
the last option wins, */
|
||||
fill_used = FALSE;
|
||||
|
||||
break;
|
||||
#endif
|
||||
case 'x':
|
||||
@@ -2157,6 +2285,11 @@ int main(int argc, char **argv)
|
||||
case 'z':
|
||||
SET(SUSPEND);
|
||||
break;
|
||||
#ifndef NANO_TINY
|
||||
case '$':
|
||||
SET(SOFTWRAP);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
@@ -2204,7 +2337,10 @@ int main(int argc, char **argv)
|
||||
char *alt_speller_cpy = alt_speller;
|
||||
#endif
|
||||
ssize_t tabsize_cpy = tabsize;
|
||||
long flags_cpy = flags;
|
||||
unsigned flags_cpy[sizeof(flags) / sizeof(flags[0])];
|
||||
size_t i;
|
||||
|
||||
memcpy(flags_cpy, flags, sizeof(flags_cpy));
|
||||
|
||||
#ifndef DISABLE_OPERATINGDIR
|
||||
operating_dir = NULL;
|
||||
@@ -2256,7 +2392,9 @@ int main(int argc, char **argv)
|
||||
#endif
|
||||
if (tabsize_cpy != -1)
|
||||
tabsize = tabsize_cpy;
|
||||
flags |= flags_cpy;
|
||||
|
||||
for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++)
|
||||
flags[i] |= flags_cpy[i];
|
||||
}
|
||||
#ifdef DISABLE_ROOTWRAPPING
|
||||
/* If we don't have any rcfiles, --disable-wrapping-as-root is used,
|
||||
@@ -2266,6 +2404,11 @@ int main(int argc, char **argv)
|
||||
#endif
|
||||
#endif /* ENABLE_NANORC */
|
||||
|
||||
/* Overwrite an rcfile "set nowrap" or --disable-wrapping-as-root
|
||||
if a --fill option was given on the command line. */
|
||||
if (fill_used)
|
||||
UNSET(NO_WRAP);
|
||||
|
||||
/* If we're using bold text instead of reverse video text, set it up
|
||||
* now. */
|
||||
if (ISSET(BOLD_TEXT))
|
||||
|
||||
99
src/nano.h
99
src/nano.h
@@ -28,6 +28,12 @@
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef NEED_XOPEN_SOURCE_EXTENDED
|
||||
#ifndef _XOPEN_SOURCE_EXTENDED
|
||||
#define _XOPEN_SOURCE_EXTENDED 1
|
||||
#endif /* _XOPEN_SOURCE_EXTENDED */
|
||||
#endif /* NEED_XOPEN_SOURCE_EXTENDED */
|
||||
|
||||
#ifdef __TANDEM
|
||||
/* Tandem NonStop Kernel support. */
|
||||
#include <floss.h>
|
||||
@@ -44,11 +50,18 @@
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDARG_H
|
||||
#include <stdarg.h>
|
||||
#endif
|
||||
|
||||
/* Macros for flags. */
|
||||
#define SET(bit) flags |= bit
|
||||
#define UNSET(bit) flags &= ~bit
|
||||
#define ISSET(bit) ((flags & bit) != 0)
|
||||
#define TOGGLE(bit) flags ^= bit
|
||||
#define FLAGOFF(flag) ((flag) / (sizeof(unsigned) * 8))
|
||||
#define FLAGMASK(flag) (1 << ((flag) % (sizeof(unsigned) * 8)))
|
||||
#define FLAGS(flag) flags[FLAGOFF(flag)]
|
||||
#define SET(flag) FLAGS(flag) |= FLAGMASK(flag)
|
||||
#define UNSET(flag) FLAGS(flag) &= ~FLAGMASK(flag)
|
||||
#define ISSET(flag) ((FLAGS(flag) & FLAGMASK(flag)) != 0)
|
||||
#define TOGGLE(flag) FLAGS(flag) ^= FLAGMASK(flag)
|
||||
|
||||
/* Macros for character allocation and more. */
|
||||
#define charalloc(howmuch) (char *)nmalloc((howmuch) * sizeof(char))
|
||||
@@ -170,7 +183,7 @@ typedef enum {
|
||||
} function_type;
|
||||
|
||||
typedef enum {
|
||||
ADD, DEL, REPLACE, SPLIT, UNSPLIT, CUT, UNCUT, INSERT, OTHER
|
||||
ADD, DEL, REPLACE, SPLIT, UNSPLIT, CUT, UNCUT, ENTER, INSERT, OTHER
|
||||
} undo_type;
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
@@ -282,6 +295,8 @@ typedef struct undo {
|
||||
/* Where did this action begin or end */
|
||||
char *strdata;
|
||||
/* String type data we will use for ccopying the affected line back */
|
||||
char *strdata2;
|
||||
/* Sigh, need this too it looks like */
|
||||
int xflags;
|
||||
/* Some flag data we need */
|
||||
|
||||
@@ -438,39 +453,46 @@ typedef struct subnfunc {
|
||||
} subnfunc;
|
||||
|
||||
|
||||
/* Bitwise flags so that we can save space (or, more correctly, not
|
||||
* waste it). */
|
||||
#define CASE_SENSITIVE (1<<0)
|
||||
#define CONST_UPDATE (1<<1)
|
||||
#define NO_HELP (1<<2)
|
||||
#define NOFOLLOW_SYMLINKS (1<<3)
|
||||
#define SUSPEND (1<<4)
|
||||
#define NO_WRAP (1<<5)
|
||||
#define AUTOINDENT (1<<6)
|
||||
#define VIEW_MODE (1<<7)
|
||||
#define USE_MOUSE (1<<8)
|
||||
#define USE_REGEXP (1<<9)
|
||||
#define TEMP_FILE (1<<10)
|
||||
#define CUT_TO_END (1<<11)
|
||||
#define BACKWARDS_SEARCH (1<<12)
|
||||
#define MULTIBUFFER (1<<13)
|
||||
#define SMOOTH_SCROLL (1<<14)
|
||||
#define REBIND_DELETE (1<<15)
|
||||
#define REBIND_KEYPAD (1<<16)
|
||||
#define NO_CONVERT (1<<17)
|
||||
#define BACKUP_FILE (1<<18)
|
||||
#define NO_COLOR_SYNTAX (1<<19)
|
||||
#define PRESERVE (1<<20)
|
||||
#define HISTORYLOG (1<<21)
|
||||
#define RESTRICTED (1<<22)
|
||||
#define SMART_HOME (1<<23)
|
||||
#define WHITESPACE_DISPLAY (1<<24)
|
||||
#define MORE_SPACE (1<<25)
|
||||
#define TABS_TO_SPACES (1<<26)
|
||||
#define QUICK_BLANK (1<<27)
|
||||
#define WORD_BOUNDS (1<<28)
|
||||
#define NO_NEWLINES (1<<29)
|
||||
#define BOLD_TEXT (1<<30)
|
||||
/* Enumeration to be used in flags table. See FLAGBIT and FLAGOFF
|
||||
* definitions. */
|
||||
enum
|
||||
{
|
||||
DONTUSE,
|
||||
CASE_SENSITIVE,
|
||||
CONST_UPDATE,
|
||||
NO_HELP,
|
||||
NOFOLLOW_SYMLINKS,
|
||||
SUSPEND,
|
||||
NO_WRAP,
|
||||
AUTOINDENT,
|
||||
VIEW_MODE,
|
||||
USE_MOUSE,
|
||||
USE_REGEXP,
|
||||
TEMP_FILE,
|
||||
CUT_TO_END,
|
||||
BACKWARDS_SEARCH,
|
||||
MULTIBUFFER,
|
||||
SMOOTH_SCROLL,
|
||||
REBIND_DELETE,
|
||||
REBIND_KEYPAD,
|
||||
NO_CONVERT,
|
||||
BACKUP_FILE,
|
||||
NO_COLOR_SYNTAX,
|
||||
PRESERVE,
|
||||
HISTORYLOG,
|
||||
RESTRICTED,
|
||||
SMART_HOME,
|
||||
WHITESPACE_DISPLAY,
|
||||
MORE_SPACE,
|
||||
TABS_TO_SPACES,
|
||||
QUICK_BLANK,
|
||||
WORD_BOUNDS,
|
||||
NO_NEWLINES,
|
||||
BOLD_TEXT,
|
||||
QUIET,
|
||||
UNDOABLE,
|
||||
SOFTWRAP
|
||||
};
|
||||
|
||||
/* Flags for which menus in which a given function should be present */
|
||||
#define MMAIN (1<<0)
|
||||
@@ -719,6 +741,7 @@ typedef struct subnfunc {
|
||||
/* Extra bits for the undo function */
|
||||
#define UNDO_DEL_DEL (1<<0)
|
||||
#define UNDO_DEL_BACKSPACE (1<<1)
|
||||
#define UNDO_SPLIT_MADENEW (1<<2)
|
||||
|
||||
/* Since in ISO C you can't pass around function pointers anymore,
|
||||
let's make some integer macros for function names, and then I
|
||||
|
||||
@@ -868,7 +868,7 @@ void update_statusbar_line(const char *curranswer, size_t index)
|
||||
free(expanded);
|
||||
|
||||
wattroff(bottomwin, reverse_attr);
|
||||
|
||||
statusbar_pww = statusbar_xplustabs();
|
||||
reset_statusbar_cursor();
|
||||
wnoutrefresh(bottomwin);
|
||||
}
|
||||
@@ -956,7 +956,7 @@ const sc *get_prompt_string(int *actual, bool allow_tabs,
|
||||
currmenu = menu;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "get_prompt_string: answer = \"%s\", statusbar_x = %d\n", answer, statusbar_x);
|
||||
fprintf(stderr, "get_prompt_string: answer = \"%s\", statusbar_x = %lu\n", answer, (unsigned long) statusbar_x);
|
||||
#endif
|
||||
|
||||
update_statusbar_line(answer, statusbar_x);
|
||||
|
||||
23
src/proto.h
23
src/proto.h
@@ -30,6 +30,7 @@
|
||||
#ifndef NANO_TINY
|
||||
extern sigjmp_buf jump_buf;
|
||||
extern bool jump_buf_main;
|
||||
extern bool use_undo;
|
||||
#endif
|
||||
|
||||
#ifndef DISABLE_WRAPJUSTIFY
|
||||
@@ -40,11 +41,12 @@ extern ssize_t wrap_at;
|
||||
extern char *last_search;
|
||||
extern char *last_replace;
|
||||
|
||||
extern long flags;
|
||||
extern unsigned flags[4];
|
||||
extern WINDOW *topwin;
|
||||
extern WINDOW *edit;
|
||||
extern WINDOW *bottomwin;
|
||||
extern int editwinrows;
|
||||
extern int maxrows;
|
||||
|
||||
extern filestruct *cutbuffer;
|
||||
extern filestruct *cutbottom;
|
||||
@@ -76,7 +78,7 @@ extern char *quoteerr;
|
||||
extern size_t quotelen;
|
||||
#endif
|
||||
#endif
|
||||
bool nodelay_mode;
|
||||
extern bool nodelay_mode;
|
||||
extern char *answer;
|
||||
|
||||
extern ssize_t tabsize;
|
||||
@@ -269,7 +271,7 @@ bool close_buffer(void);
|
||||
#endif
|
||||
filestruct *read_line(char *buf, filestruct *prevnode, bool
|
||||
*first_line_ins, size_t buf_len);
|
||||
void read_file(FILE *f, const char *filename, bool undoable);
|
||||
void read_file(FILE *f, int fd, const char *filename, bool undoable);
|
||||
int open_file(const char *filename, bool newfie, FILE **f);
|
||||
char *get_next_filename(const char *name, const char *suffix);
|
||||
void do_insertfile(
|
||||
@@ -426,7 +428,7 @@ void free_openfilestruct(openfilestruct *src);
|
||||
void print_view_warning(void);
|
||||
void finish(void);
|
||||
void die(const char *msg, ...);
|
||||
void die_save_file(const char *die_filename);
|
||||
void die_save_file(const char *die_filename, struct stat *die_stat);
|
||||
void window_init(void);
|
||||
#ifndef DISABLE_MOUSE
|
||||
void disable_mouse_support(void);
|
||||
@@ -543,7 +545,7 @@ void parse_syntax(char *ptr);
|
||||
void parse_include(char *ptr);
|
||||
short color_to_short(const char *colorname, bool *bright);
|
||||
void parse_colors(char *ptr, bool icase);
|
||||
void reset_multis(filestruct *fileptr);
|
||||
void reset_multis(filestruct *fileptr, bool force);
|
||||
void alloc_multidata_if_needed(filestruct *fileptr);
|
||||
#endif
|
||||
void parse_rcfile(FILE *rcstream
|
||||
@@ -624,14 +626,14 @@ void do_unindent(void);
|
||||
void do_undo(void);
|
||||
void do_redo(void);
|
||||
#endif
|
||||
void do_enter(void);
|
||||
void do_enter(bool undoing);
|
||||
#ifndef NANO_TINY
|
||||
RETSIGTYPE cancel_command(int signal);
|
||||
bool execute_command(const char *command);
|
||||
#endif
|
||||
#ifndef DISABLE_WRAPPING
|
||||
void wrap_reset(void);
|
||||
bool do_wrap(filestruct *line);
|
||||
bool do_wrap(filestruct *line, bool undoing);
|
||||
#endif
|
||||
#if !defined(DISABLE_HELP) || !defined(DISABLE_WRAPJUSTIFY)
|
||||
ssize_t break_line(const char *line, ssize_t goal
|
||||
@@ -764,7 +766,7 @@ void onekey(const char *keystroke, const char *desc, size_t len);
|
||||
void reset_cursor(void);
|
||||
void edit_draw(filestruct *fileptr, const char *converted, int
|
||||
line, size_t start);
|
||||
void update_line(filestruct *fileptr, size_t index);
|
||||
int update_line(filestruct *fileptr, size_t index);
|
||||
bool need_horizontal_update(size_t pww_save);
|
||||
bool need_vertical_update(size_t pww_save);
|
||||
void edit_scroll(scroll_dir direction, ssize_t nlines);
|
||||
@@ -811,11 +813,6 @@ const char *mac_format_msg;
|
||||
const char *append_msg;
|
||||
const char *prepend_msg;
|
||||
const char *backup_file_msg;
|
||||
const char *dos_format_msg;
|
||||
const char *mac_format_msg;
|
||||
const char *append_msg;
|
||||
const char *prepend_msg;
|
||||
const char *backup_file_msg;
|
||||
const char *gototext_msg;
|
||||
const char *new_buffer_msg;
|
||||
void iso_me_harder_funcmap(short func);
|
||||
|
||||
131
src/rcfile.c
131
src/rcfile.c
@@ -84,12 +84,15 @@ static const rcoption rcopts[] = {
|
||||
{"historylog", HISTORYLOG},
|
||||
{"matchbrackets", 0},
|
||||
{"noconvert", NO_CONVERT},
|
||||
{"quiet", QUIET},
|
||||
{"quickblank", QUICK_BLANK},
|
||||
{"smarthome", SMART_HOME},
|
||||
{"smooth", SMOOTH_SCROLL},
|
||||
{"tabstospaces", TABS_TO_SPACES},
|
||||
{"undo", UNDOABLE},
|
||||
{"whitespace", 0},
|
||||
{"wordbounds", WORD_BOUNDS},
|
||||
{"softwrap", SOFTWRAP},
|
||||
#endif
|
||||
{NULL, 0}
|
||||
};
|
||||
@@ -117,6 +120,9 @@ void rcfile_error(const char *msg, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (ISSET(QUIET))
|
||||
return;
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
if (lineno > 0) {
|
||||
errors = TRUE;
|
||||
@@ -388,41 +394,41 @@ void parse_keybinding(char *ptr)
|
||||
|
||||
if (keycopy[0] != 'M' && keycopy[0] != '^' && keycopy[0] != 'F' && keycopy[0] != 'K') {
|
||||
rcfile_error(
|
||||
N_("keybindings must begin with \"^\", \"M\", or \"F\"\n"));
|
||||
N_("keybindings must begin with \"^\", \"M\", or \"F\""));
|
||||
return;
|
||||
}
|
||||
|
||||
funcptr = ptr;
|
||||
ptr = parse_next_word(ptr);
|
||||
|
||||
if (funcptr == NULL) {
|
||||
if (!strcmp(funcptr, "")) {
|
||||
rcfile_error(
|
||||
N_("Must specify function to bind key to\n"));
|
||||
N_("Must specify function to bind key to"));
|
||||
return;
|
||||
}
|
||||
|
||||
menuptr = ptr;
|
||||
ptr = parse_next_word(ptr);
|
||||
|
||||
if (menuptr == NULL) {
|
||||
if (!strcmp(menuptr, "")) {
|
||||
rcfile_error(
|
||||
/* Note to translators, do not translate the word "all"
|
||||
in the sentence below, everything else is fine */
|
||||
N_("Must specify menu bind key to (or \"all\")\n"));
|
||||
N_("Must specify menu to bind key to (or \"all\")"));
|
||||
return;
|
||||
}
|
||||
|
||||
menu = strtomenu(menuptr);
|
||||
if (menu < 1) {
|
||||
rcfile_error(
|
||||
N_("Could not map name \"%s\" to a menu\n"), menuptr);
|
||||
return;
|
||||
}
|
||||
|
||||
newsc = strtosc(menu, funcptr);
|
||||
if (newsc == NULL) {
|
||||
rcfile_error(
|
||||
N_("Could not map name \"%s\" to a function\n"), funcptr);
|
||||
N_("Could not map name \"%s\" to a function"), funcptr);
|
||||
return;
|
||||
}
|
||||
|
||||
if (menu < 1) {
|
||||
rcfile_error(
|
||||
N_("Could not map name \"%s\" to a menu"), menuptr);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -444,11 +450,10 @@ void parse_keybinding(char *ptr)
|
||||
|
||||
if (check_bad_binding(newsc)) {
|
||||
rcfile_error(
|
||||
N_("Sorry, keystr \"%s\" is an illegal binding\n"), newsc->keystr);
|
||||
N_("Sorry, keystr \"%s\" is an illegal binding"), newsc->keystr);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* now let's have some fun. Try and delete the other entries
|
||||
we found for the same menu, then make this new new
|
||||
beginning */
|
||||
@@ -464,13 +469,77 @@ void parse_keybinding(char *ptr)
|
||||
sclist = newsc;
|
||||
}
|
||||
|
||||
/* Let user unbind a sequence from a given (or all) menus */
|
||||
void parse_unbinding(char *ptr)
|
||||
{
|
||||
char *keyptr = NULL, *keycopy = NULL, *menuptr = NULL;
|
||||
sc *s;
|
||||
int i, menu;
|
||||
|
||||
assert(ptr != NULL);
|
||||
|
||||
if (*ptr == '\0') {
|
||||
rcfile_error(N_("Missing key name"));
|
||||
return;
|
||||
}
|
||||
|
||||
keyptr = ptr;
|
||||
ptr = parse_next_word(ptr);
|
||||
keycopy = mallocstrcpy(NULL, keyptr);
|
||||
for (i = 0; i < strlen(keycopy); i++)
|
||||
keycopy[i] = toupper(keycopy[i]);
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Starting unbinding code");
|
||||
#endif
|
||||
|
||||
if (keycopy[0] != 'M' && keycopy[0] != '^' && keycopy[0] != 'F' && keycopy[0] != 'K') {
|
||||
rcfile_error(
|
||||
N_("keybindings must begin with \"^\", \"M\", or \"F\""));
|
||||
return;
|
||||
}
|
||||
|
||||
menuptr = ptr;
|
||||
ptr = parse_next_word(ptr);
|
||||
|
||||
if (!strcmp(menuptr, "")) {
|
||||
rcfile_error(
|
||||
/* Note to translators, do not translate the word "all"
|
||||
in the sentence below, everything else is fine */
|
||||
N_("Must specify menu to bind key to (or \"all\")"));
|
||||
return;
|
||||
}
|
||||
|
||||
menu = strtomenu(menuptr);
|
||||
if (menu < 1) {
|
||||
rcfile_error(
|
||||
N_("Could not map name \"%s\" to a menu"), menuptr);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "unbinding \"%s\" from menu = %d\n", keycopy, menu);
|
||||
#endif
|
||||
|
||||
/* Now find the apropriate entries in the menu to delete */
|
||||
for (s = sclist; s != NULL; s = s->next) {
|
||||
if (((s->menu & menu)) && !strcmp(s->keystr,keycopy)) {
|
||||
s->menu &= ~menu;
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "deleted menu entry %d\n", s->menu);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Read and parse additional syntax files. */
|
||||
void parse_include(char *ptr)
|
||||
{
|
||||
struct stat rcinfo;
|
||||
FILE *rcstream;
|
||||
char *option, *nanorc_save = nanorc;
|
||||
char *option, *nanorc_save = nanorc, *expanded;
|
||||
size_t lineno_save = lineno;
|
||||
|
||||
option = ptr;
|
||||
@@ -491,20 +560,22 @@ void parse_include(char *ptr)
|
||||
}
|
||||
}
|
||||
|
||||
expanded = real_dir_from_tilde(option);
|
||||
|
||||
/* Open the new syntax file. */
|
||||
if ((rcstream = fopen(option, "rb")) == NULL) {
|
||||
rcfile_error(_("Error reading %s: %s"), option,
|
||||
if ((rcstream = fopen(expanded, "rb")) == NULL) {
|
||||
rcfile_error(_("Error reading %s: %s"), expanded,
|
||||
strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Use the name and line number position of the new syntax file
|
||||
* while parsing it, so we can know where any errors in it are. */
|
||||
nanorc = option;
|
||||
nanorc = expanded;
|
||||
lineno = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Parsing file \"%s\"\n", option);
|
||||
fprintf(stderr, "Parsing file \"%s\" (expanded from \"%s\")\n", expanded, option);
|
||||
#endif
|
||||
|
||||
parse_rcfile(rcstream
|
||||
@@ -887,6 +958,8 @@ void parse_rcfile(FILE *rcstream
|
||||
parse_colors(ptr, TRUE);
|
||||
else if (strcasecmp(keyword, "bind") == 0)
|
||||
parse_keybinding(ptr);
|
||||
else if (strcasecmp(keyword, "unbind") == 0)
|
||||
parse_unbinding(ptr);
|
||||
#endif /* ENABLE_COLOR */
|
||||
else
|
||||
rcfile_error(N_("Command \"%s\" not understood"), keyword);
|
||||
@@ -1039,6 +1112,9 @@ void parse_rcfile(FILE *rcstream
|
||||
else
|
||||
rcfile_error(N_("Cannot unset flag \"%s\""),
|
||||
rcopts[i].name);
|
||||
/* Looks like we still need this specific hack for undo */
|
||||
if (strcasecmp(rcopts[i].name, "undo") == 0)
|
||||
shortcut_init(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1057,15 +1133,6 @@ void parse_rcfile(FILE *rcstream
|
||||
lineno = 0;
|
||||
|
||||
check_vitals_mapped();
|
||||
|
||||
if (errors) {
|
||||
errors = FALSE;
|
||||
fprintf(stderr,
|
||||
_("\nPress Enter to continue starting nano.\n"));
|
||||
while (getchar() != '\n')
|
||||
;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1146,6 +1213,14 @@ void do_rcfile(void)
|
||||
free(nanorc);
|
||||
nanorc = NULL;
|
||||
|
||||
if (errors && !ISSET(QUIET)) {
|
||||
errors = FALSE;
|
||||
fprintf(stderr,
|
||||
_("\nPress Enter to continue starting nano.\n"));
|
||||
while (getchar() != '\n')
|
||||
;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
set_colorpairs();
|
||||
#endif
|
||||
|
||||
@@ -719,6 +719,9 @@ ssize_t do_replace_loop(
|
||||
filepart = partition_filestruct(top, top_x, bot, bot_x);
|
||||
openfile->edittop = openfile->fileage;
|
||||
openfile->mark_set = FALSE;
|
||||
#ifdef ENABLE_COLOR
|
||||
reset_multis(openfile->current, TRUE);
|
||||
#endif
|
||||
edit_refresh();
|
||||
}
|
||||
#endif
|
||||
@@ -863,6 +866,10 @@ ssize_t do_replace_loop(
|
||||
free(openfile->current->data);
|
||||
openfile->current->data = copy;
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
reset_multis(openfile->current, TRUE);
|
||||
#endif
|
||||
edit_refresh();
|
||||
if (!replaceall) {
|
||||
#ifdef ENABLE_COLOR
|
||||
/* If color syntaxes are available and turned on, we
|
||||
|
||||
206
src/text.c
206
src/text.c
@@ -140,13 +140,6 @@ void do_delete(void)
|
||||
|
||||
set_modified();
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
/* If color syntaxes are available and turned on, we need to call
|
||||
* edit_refresh(). */
|
||||
if (openfile->colorstrings != NULL && !ISSET(NO_COLOR_SYNTAX))
|
||||
do_refresh = TRUE;
|
||||
#endif
|
||||
|
||||
if (do_refresh)
|
||||
edit_refresh_needed = TRUE;
|
||||
else
|
||||
@@ -367,21 +360,25 @@ void do_unindent(void)
|
||||
/* undo a cut, or re-do an uncut */
|
||||
void undo_cut(undo *u)
|
||||
{
|
||||
cutbuffer = copy_filestruct(u->cutbuffer);
|
||||
/* If we cut the magicline may was well not crash :/ */
|
||||
if (!u->cutbuffer)
|
||||
return;
|
||||
|
||||
/* Compute cutbottom for the uncut using out copy */
|
||||
for (cutbottom = cutbuffer; cutbottom->next != NULL; cutbottom = cutbottom->next)
|
||||
;
|
||||
cutbuffer = copy_filestruct(u->cutbuffer);
|
||||
|
||||
/* Get to where we need to uncut from */
|
||||
if (u->mark_set && u->mark_begin_lineno < u->lineno)
|
||||
do_gotolinecolumn(u->mark_begin_lineno, u->mark_begin_x+1, FALSE, FALSE, FALSE, FALSE);
|
||||
else
|
||||
do_gotolinecolumn(u->lineno, u->begin+1, FALSE, FALSE, FALSE, FALSE);
|
||||
/* Compute cutbottom for the uncut using out copy */
|
||||
for (cutbottom = cutbuffer; cutbottom->next != NULL; cutbottom = cutbottom->next)
|
||||
;
|
||||
|
||||
copy_from_filestruct(cutbuffer, cutbottom);
|
||||
free_filestruct(cutbuffer);
|
||||
cutbuffer = NULL;
|
||||
/* Get to where we need to uncut from */
|
||||
if (u->mark_set && u->mark_begin_lineno < u->lineno)
|
||||
do_gotolinecolumn(u->mark_begin_lineno, u->mark_begin_x+1, FALSE, FALSE, FALSE, FALSE);
|
||||
else
|
||||
do_gotolinecolumn(u->lineno, u->begin+1, FALSE, FALSE, FALSE, FALSE);
|
||||
|
||||
copy_from_filestruct(cutbuffer, cutbottom);
|
||||
free_filestruct(cutbuffer);
|
||||
cutbuffer = NULL;
|
||||
|
||||
}
|
||||
|
||||
@@ -390,40 +387,44 @@ void redo_cut(undo *u) {
|
||||
int i;
|
||||
filestruct *t, *c;
|
||||
|
||||
do_gotolinecolumn(u->lineno, u->begin+1, FALSE, FALSE, FALSE, FALSE);
|
||||
openfile->mark_set = u->mark_set;
|
||||
if (cutbuffer)
|
||||
free(cutbuffer);
|
||||
cutbuffer = NULL;
|
||||
/* If we cut the magicline may was well not crash :/ */
|
||||
if (!u->cutbuffer)
|
||||
return;
|
||||
|
||||
/* Move ahead the same # lines we had if a marked cut */
|
||||
if (u->mark_set) {
|
||||
for (i = 1, t = openfile->fileage; i != u->mark_begin_lineno; i++)
|
||||
t = t->next;
|
||||
openfile->mark_begin = t;
|
||||
} else if (!u->to_end) {
|
||||
/* Here we have a regular old potentially multi-line ^K cut. We'll
|
||||
need to trick nano into thinking it's a marked cut to cut more
|
||||
than one line again */
|
||||
for (c = u->cutbuffer, t = openfile->current; c->next != NULL && t->next != NULL; ) {
|
||||
do_gotolinecolumn(u->lineno, u->begin+1, FALSE, FALSE, FALSE, FALSE);
|
||||
openfile->mark_set = u->mark_set;
|
||||
if (cutbuffer)
|
||||
free(cutbuffer);
|
||||
cutbuffer = NULL;
|
||||
|
||||
/* Move ahead the same # lines we had if a marked cut */
|
||||
if (u->mark_set) {
|
||||
for (i = 1, t = openfile->fileage; i != u->mark_begin_lineno; i++)
|
||||
t = t->next;
|
||||
openfile->mark_begin = t;
|
||||
} else if (!u->to_end) {
|
||||
/* Here we have a regular old potentially multi-line ^K cut. We'll
|
||||
need to trick nano into thinking it's a marked cut to cut more
|
||||
than one line again */
|
||||
for (c = u->cutbuffer, t = openfile->current; c->next != NULL && t->next != NULL; ) {
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Advancing, lineno = %d, data = \"%s\"\n", t->lineno, t->data);
|
||||
fprintf(stderr, "Advancing, lineno = %lu, data = \"%s\"\n", (unsigned long) t->lineno, t->data);
|
||||
#endif
|
||||
c = c->next;
|
||||
t = t->next;
|
||||
}
|
||||
openfile->mark_begin = t;
|
||||
openfile->mark_begin_x = 0;
|
||||
openfile->mark_set = TRUE;
|
||||
}
|
||||
c = c->next;
|
||||
t = t->next;
|
||||
}
|
||||
openfile->mark_begin = t;
|
||||
openfile->mark_begin_x = 0;
|
||||
openfile->mark_set = TRUE;
|
||||
}
|
||||
|
||||
openfile->mark_begin_x = u->mark_begin_x;
|
||||
do_cut_text(FALSE, u->to_end, TRUE);
|
||||
openfile->mark_set = FALSE;
|
||||
openfile->mark_begin = NULL;
|
||||
openfile->mark_begin_x = 0;
|
||||
edit_refresh_needed = TRUE;
|
||||
openfile->mark_begin_x = u->mark_begin_x;
|
||||
do_cut_text(FALSE, u->to_end, TRUE);
|
||||
openfile->mark_set = FALSE;
|
||||
openfile->mark_begin = NULL;
|
||||
openfile->mark_begin_x = 0;
|
||||
edit_refresh_needed = TRUE;
|
||||
}
|
||||
|
||||
/* Undo the last thing(s) we did */
|
||||
@@ -481,13 +482,15 @@ void do_undo(void)
|
||||
openfile->current_x += strlen(u->strdata);
|
||||
break;
|
||||
case SPLIT:
|
||||
undidmsg = _("line split");
|
||||
free(f->data);
|
||||
f->data = mallocstrcpy(NULL, u->strdata);
|
||||
if (f->next != NULL) {
|
||||
filestruct *tmp = f->next;
|
||||
unlink_node(tmp);
|
||||
delete_node(tmp);
|
||||
undidmsg = _("line wrap");
|
||||
f->data = nrealloc(f->data, strlen(f->data) + strlen(u->strdata) + 1);
|
||||
strcpy(&f->data[strlen(f->data) - 1], u->strdata);
|
||||
if (u->strdata2 != NULL)
|
||||
f->next->data = mallocstrcpy(f->next->data, u->strdata2);
|
||||
else {
|
||||
filestruct *foo = openfile->current->next;
|
||||
unlink_node(foo);
|
||||
delete_node(foo);
|
||||
}
|
||||
renumber(f);
|
||||
break;
|
||||
@@ -510,6 +513,16 @@ void do_undo(void)
|
||||
undidmsg = _("text uncut");
|
||||
redo_cut(u);
|
||||
break;
|
||||
case ENTER:
|
||||
undidmsg = _("line break");
|
||||
if (f->next) {
|
||||
filestruct *foo = f->next;
|
||||
f->data = nrealloc(f->data, strlen(f->data) + strlen(f->next->data) + 1);
|
||||
strcat(f->data, f->next->data);
|
||||
unlink_node(foo);
|
||||
delete_node(foo);
|
||||
}
|
||||
break;
|
||||
case INSERT:
|
||||
undidmsg = _("text insert");
|
||||
cutbuffer = NULL;
|
||||
@@ -534,11 +547,13 @@ void do_undo(void)
|
||||
u->strdata = f->data;
|
||||
f->data = data;
|
||||
break;
|
||||
|
||||
default:
|
||||
undidmsg = _("Internal error: unknown type. Please save your work");
|
||||
break;
|
||||
|
||||
}
|
||||
renumber(f);
|
||||
do_gotolinecolumn(u->lineno, u->begin, FALSE, FALSE, FALSE, TRUE);
|
||||
statusbar(_("Undid action (%s)"), undidmsg);
|
||||
openfile->current_undo = openfile->current_undo->next;
|
||||
@@ -548,7 +563,7 @@ void do_undo(void)
|
||||
void do_redo(void)
|
||||
{
|
||||
undo *u = openfile->undotop;
|
||||
filestruct *f = openfile->current, *t;
|
||||
filestruct *f = openfile->current;
|
||||
int len = 0;
|
||||
char *undidmsg, *data;
|
||||
|
||||
@@ -598,15 +613,16 @@ void do_redo(void)
|
||||
free(f->data);
|
||||
f->data = data;
|
||||
break;
|
||||
case ENTER:
|
||||
undidmsg = _("line break");
|
||||
do_gotolinecolumn(u->lineno, u->begin+1, FALSE, FALSE, FALSE, FALSE);
|
||||
do_enter(TRUE);
|
||||
break;
|
||||
case SPLIT:
|
||||
undidmsg = _("line split");
|
||||
t = make_new_node(f);
|
||||
t->data = mallocstrcpy(NULL, &u->strdata[u->begin]);
|
||||
data = mallocstrncpy(NULL, f->data, u->begin);
|
||||
data[u->begin] = '\0';
|
||||
free(f->data);
|
||||
f->data = data;
|
||||
splice_node(f, t, f->next);
|
||||
undidmsg = _("line wrap");
|
||||
if (u->xflags & UNDO_SPLIT_MADENEW)
|
||||
prepend_wrap = TRUE;
|
||||
do_wrap(f, TRUE);
|
||||
renumber(f);
|
||||
break;
|
||||
case UNSPLIT:
|
||||
@@ -659,7 +675,7 @@ void do_redo(void)
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
/* Someone hits Enter *gasp!* */
|
||||
void do_enter(void)
|
||||
void do_enter(bool undoing)
|
||||
{
|
||||
filestruct *newnode = make_new_node(openfile->current);
|
||||
size_t extra = 0;
|
||||
@@ -667,7 +683,8 @@ void do_enter(void)
|
||||
assert(openfile->current != NULL && openfile->current->data != NULL);
|
||||
|
||||
#ifndef NANO_TINY
|
||||
update_undo(SPLIT);
|
||||
if (!undoing)
|
||||
add_undo(ENTER);
|
||||
|
||||
|
||||
/* Do auto-indenting, like the neolithic Turbo Pascal editor. */
|
||||
@@ -795,7 +812,7 @@ bool execute_command(const char *command)
|
||||
if (f == NULL)
|
||||
nperror("fdopen");
|
||||
|
||||
read_file(f, "stdin", TRUE);
|
||||
read_file(f, 0, "stdin", TRUE);
|
||||
|
||||
if (wait(NULL) == -1)
|
||||
nperror("wait");
|
||||
@@ -818,6 +835,10 @@ void add_undo(undo_type current_action)
|
||||
char *data;
|
||||
openfilestruct *fs = openfile;
|
||||
static undo *last_cutu = NULL; /* Last thing we cut to set up the undo for uncut */
|
||||
ssize_t wrap_loc; /* For calculating split beginning */
|
||||
|
||||
if (!ISSET(UNDOABLE))
|
||||
return;
|
||||
|
||||
/* Ugh, if we were called while cutting not-to-end, non-marked and on the same lineno,
|
||||
we need to abort here */
|
||||
@@ -846,6 +867,7 @@ void add_undo(undo_type current_action)
|
||||
fs->undotop = u;
|
||||
fs->current_undo = u;
|
||||
u->strdata = NULL;
|
||||
u->strdata2 = NULL;
|
||||
u->cutbuffer = NULL;
|
||||
u->cutbottom = NULL;
|
||||
u->mark_set = 0;
|
||||
@@ -878,8 +900,20 @@ void add_undo(undo_type current_action)
|
||||
u->strdata = data;
|
||||
}
|
||||
break;
|
||||
case INSERT:
|
||||
case SPLIT:
|
||||
wrap_loc = break_line(openfile->current->data, fill
|
||||
#ifndef DISABLE_HELP
|
||||
, FALSE
|
||||
#endif
|
||||
);
|
||||
u->strdata = mallocstrcpy(NULL, &openfile->current->data[wrap_loc]);
|
||||
/* Don't both saving the next line if we're not prepending as a new line
|
||||
will be created */
|
||||
if (prepend_wrap)
|
||||
u->strdata2 = mallocstrcpy(NULL, fs->current->next->data);
|
||||
u->begin = wrap_loc;
|
||||
break;
|
||||
case INSERT:
|
||||
case REPLACE:
|
||||
data = mallocstrcpy(NULL, fs->current->data);
|
||||
u->strdata = data;
|
||||
@@ -901,15 +935,17 @@ void add_undo(undo_type current_action)
|
||||
u->cutbottom = last_cutu->cutbottom;
|
||||
}
|
||||
break;
|
||||
case ENTER:
|
||||
break;
|
||||
case OTHER:
|
||||
statusbar(_("Internal error: unknown type. Please save your work."));
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "fs->current->data = \"%s\", current_x = %d, u->begin = %d, type = %d\n",
|
||||
fs->current->data, fs->current_x, u->begin, current_action);
|
||||
fprintf(stderr, "left update_add...\n");
|
||||
fprintf(stderr, "fs->current->data = \"%s\", current_x = %lu, u->begin = %d, type = %d\n",
|
||||
fs->current->data, (unsigned long) fs->current_x, u->begin, current_action);
|
||||
fprintf(stderr, "left add_undo...\n");
|
||||
#endif
|
||||
fs->last_action = current_action;
|
||||
}
|
||||
@@ -926,11 +962,14 @@ void update_undo(undo_type action)
|
||||
int len = 0;
|
||||
openfilestruct *fs = openfile;
|
||||
|
||||
if (!ISSET(UNDOABLE))
|
||||
return;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "action = %d, fs->last_action = %d, openfile->current->lineno = %d",
|
||||
action, fs->last_action, openfile->current->lineno);
|
||||
fprintf(stderr, "action = %d, fs->last_action = %d, openfile->current->lineno = %lu",
|
||||
action, fs->last_action, (unsigned long) openfile->current->lineno);
|
||||
if (fs->current_undo)
|
||||
fprintf(stderr, "fs->current_undo->lineno = %d\n", fs->current_undo->lineno);
|
||||
fprintf(stderr, "fs->current_undo->lineno = %lu\n", (unsigned long) fs->current_undo->lineno);
|
||||
else
|
||||
fprintf(stderr, "\n");
|
||||
#endif
|
||||
@@ -938,7 +977,7 @@ void update_undo(undo_type action)
|
||||
/* Change to an add if we're not using the same undo struct
|
||||
that we should be using */
|
||||
if (action != fs->last_action
|
||||
|| (action != CUT && action != INSERT
|
||||
|| (action != CUT && action != INSERT && action != SPLIT
|
||||
&& openfile->current->lineno != fs->current_undo->lineno)) {
|
||||
add_undo(action);
|
||||
return;
|
||||
@@ -950,8 +989,8 @@ void update_undo(undo_type action)
|
||||
switch (u->type) {
|
||||
case ADD:
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "fs->current->data = \"%s\", current_x = %d, u->begin = %d\n",
|
||||
fs->current->data, fs->current_x, u->begin);
|
||||
fprintf(stderr, "fs->current->data = \"%s\", current_x = %lu, u->begin = %d\n",
|
||||
fs->current->data, (unsigned long) fs->current_x, u->begin);
|
||||
#endif
|
||||
len = strlen(u->strdata) + 2;
|
||||
data = nrealloc((void *) u->strdata, len * sizeof(char *));
|
||||
@@ -1018,9 +1057,15 @@ void update_undo(undo_type action)
|
||||
break;
|
||||
case INSERT:
|
||||
u->mark_begin_lineno = openfile->current->lineno;
|
||||
break;
|
||||
case SPLIT:
|
||||
/* This will only be called if we made a completely new line,
|
||||
and as such we should note that so we can destroy it later */
|
||||
u->xflags = UNDO_SPLIT_MADENEW;
|
||||
break;
|
||||
case UNSPLIT:
|
||||
/* These cases are handled by the earlier check for a new line and action */
|
||||
case ENTER:
|
||||
case OTHER:
|
||||
break;
|
||||
}
|
||||
@@ -1050,7 +1095,7 @@ void wrap_reset(void)
|
||||
/* We wrap the given line. Precondition: we assume the cursor has been
|
||||
* moved forward since the last typed character. Return TRUE if we
|
||||
* wrapped, and FALSE otherwise. */
|
||||
bool do_wrap(filestruct *line)
|
||||
bool do_wrap(filestruct *line, bool undoing)
|
||||
{
|
||||
size_t line_len;
|
||||
/* The length of the line we wrap. */
|
||||
@@ -1115,6 +1160,9 @@ bool do_wrap(filestruct *line)
|
||||
return FALSE;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (!undoing)
|
||||
add_undo(SPLIT);
|
||||
|
||||
/* If autoindent is turned on, and we're on the character just after
|
||||
* the indentation, we don't wrap. */
|
||||
if (ISSET(AUTOINDENT)) {
|
||||
@@ -1209,6 +1257,8 @@ bool do_wrap(filestruct *line)
|
||||
null_at(&line->data, wrap_loc);
|
||||
|
||||
if (prepending) {
|
||||
if (!undoing)
|
||||
update_undo(SPLIT);
|
||||
/* If we're prepending, copy the text from the next line, minus
|
||||
* the indentation that we already copied above. */
|
||||
strcat(new_line, next_line);
|
||||
|
||||
@@ -542,6 +542,9 @@ void new_magicline(void)
|
||||
openfile->filebot->next->prev = openfile->filebot;
|
||||
openfile->filebot->next->next = NULL;
|
||||
openfile->filebot->next->lineno = openfile->filebot->lineno + 1;
|
||||
#ifdef ENABLE_COLOR
|
||||
openfile->filebot->next->multidata = NULL;
|
||||
#endif
|
||||
openfile->filebot = openfile->filebot->next;
|
||||
openfile->totsize++;
|
||||
}
|
||||
|
||||
201
src/winio.c
201
src/winio.c
@@ -2426,6 +2426,7 @@ void onekey(const char *keystroke, const char *desc, size_t len)
|
||||
* in the edit window at (current_y, current_x). */
|
||||
void reset_cursor(void)
|
||||
{
|
||||
size_t xpt;
|
||||
/* If we haven't opened any files yet, put the cursor in the top
|
||||
* left corner of the edit window and get out. */
|
||||
if (openfile == NULL) {
|
||||
@@ -2433,13 +2434,25 @@ void reset_cursor(void)
|
||||
return;
|
||||
}
|
||||
|
||||
openfile->current_y = openfile->current->lineno -
|
||||
openfile->edittop->lineno;
|
||||
if (openfile->current_y < editwinrows) {
|
||||
size_t xpt = xplustabs();
|
||||
xpt = xplustabs();
|
||||
|
||||
wmove(edit, openfile->current_y, xpt - get_page_start(xpt));
|
||||
}
|
||||
if (ISSET(SOFTWRAP)) {
|
||||
filestruct *tmp;
|
||||
openfile->current_y = 0;
|
||||
|
||||
for (tmp = openfile->edittop; tmp && tmp != openfile->current; tmp = tmp->next)
|
||||
openfile->current_y += 1 + strlenpt(tmp->data) / COLS;
|
||||
|
||||
openfile->current_y += xplustabs() / COLS;
|
||||
if (openfile->current_y < editwinrows)
|
||||
wmove(edit, openfile->current_y, xpt % COLS);
|
||||
} else {
|
||||
openfile->current_y = openfile->current->lineno -
|
||||
openfile->edittop->lineno;
|
||||
|
||||
if (openfile->current_y < editwinrows)
|
||||
wmove(edit, openfile->current_y, xpt - get_page_start(xpt));
|
||||
}
|
||||
}
|
||||
|
||||
/* edit_draw() takes care of the job of actually painting a line into
|
||||
@@ -2813,43 +2826,86 @@ void edit_draw(filestruct *fileptr, const char *converted, int
|
||||
|
||||
/* Just update one line in the edit buffer. This is basically a wrapper
|
||||
* for edit_draw(). The line will be displayed starting with
|
||||
* fileptr->data[index]. Likely arguments are current_x or zero. */
|
||||
void update_line(filestruct *fileptr, size_t index)
|
||||
* fileptr->data[index]. Likely arguments are current_x or zero.
|
||||
* Returns: Number of additiona lines consumed (needed for SOFTWRAP)
|
||||
*/
|
||||
int update_line(filestruct *fileptr, size_t index)
|
||||
{
|
||||
int line;
|
||||
int line = 0;
|
||||
int extralinesused = 0;
|
||||
/* The line in the edit window that we want to update. */
|
||||
char *converted;
|
||||
/* fileptr->data converted to have tabs and control characters
|
||||
* expanded. */
|
||||
size_t page_start;
|
||||
filestruct *tmp;
|
||||
|
||||
assert(fileptr != NULL);
|
||||
|
||||
line = fileptr->lineno - openfile->edittop->lineno;
|
||||
if (ISSET(SOFTWRAP)) {
|
||||
for (tmp = openfile->edittop; tmp && tmp != fileptr; tmp = tmp->next) {
|
||||
line += 1 + (strlenpt(tmp->data) / COLS);
|
||||
}
|
||||
} else
|
||||
line = fileptr->lineno - openfile->edittop->lineno;
|
||||
|
||||
if (line < 0 || line >= editwinrows)
|
||||
return;
|
||||
return 1;
|
||||
|
||||
/* First, blank out the line. */
|
||||
blank_line(edit, line, 0, COLS);
|
||||
|
||||
/* Next, convert variables that index the line to their equivalent
|
||||
* positions in the expanded line. */
|
||||
index = strnlenpt(fileptr->data, index);
|
||||
if (ISSET(SOFTWRAP))
|
||||
index = 0;
|
||||
else
|
||||
index = strnlenpt(fileptr->data, index);
|
||||
page_start = get_page_start(index);
|
||||
|
||||
/* Expand the line, replacing tabs with spaces, and control
|
||||
* characters with their displayed forms. */
|
||||
converted = display_string(fileptr->data, page_start, COLS, TRUE);
|
||||
converted = display_string(fileptr->data, page_start, COLS, !ISSET(SOFTWRAP));
|
||||
|
||||
#ifdef DEBUG
|
||||
if (ISSET(SOFTWRAP) && strlen(converted) >= COLS - 2)
|
||||
fprintf(stderr, "update_line(): converted(1) line = %s\n", converted);
|
||||
#endif
|
||||
|
||||
|
||||
/* Paint the line. */
|
||||
edit_draw(fileptr, converted, line, page_start);
|
||||
free(converted);
|
||||
|
||||
if (page_start > 0)
|
||||
mvwaddch(edit, line, 0, '$');
|
||||
if (strlenpt(fileptr->data) > page_start + COLS)
|
||||
mvwaddch(edit, line, COLS - 1, '$');
|
||||
if (!ISSET(SOFTWRAP)) {
|
||||
if (page_start > 0)
|
||||
mvwaddch(edit, line, 0, '$');
|
||||
if (strlenpt(fileptr->data) > page_start + COLS)
|
||||
mvwaddch(edit, line, COLS - 1, '$');
|
||||
} else {
|
||||
int full_length = strlenpt(fileptr->data);
|
||||
for (index += COLS; index <= full_length && line < editwinrows; index += COLS) {
|
||||
line++;
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "update_line(): Softwrap code, moving to %d index %lu\n", line, (unsigned long) index);
|
||||
#endif
|
||||
blank_line(edit, line, 0, COLS);
|
||||
|
||||
/* Expand the line, replacing tabs with spaces, and control
|
||||
* characters with their displayed forms. */
|
||||
converted = display_string(fileptr->data, index, COLS, !ISSET(SOFTWRAP));
|
||||
#ifdef DEBUG
|
||||
if (ISSET(SOFTWRAP) && strlen(converted) >= COLS - 2)
|
||||
fprintf(stderr, "update_line(): converted(2) line = %s\n", converted);
|
||||
#endif
|
||||
|
||||
/* Paint the line. */
|
||||
edit_draw(fileptr, converted, line, index);
|
||||
free(converted);
|
||||
extralinesused++;
|
||||
}
|
||||
}
|
||||
return extralinesused;
|
||||
}
|
||||
|
||||
/* Return TRUE if we need an update after moving horizontally, and FALSE
|
||||
@@ -2878,6 +2934,33 @@ bool need_vertical_update(size_t pww_save)
|
||||
get_page_start(openfile->placewewant);
|
||||
}
|
||||
|
||||
/* When edittop changes, try and figure out how many lines
|
||||
* we really have to work with (i.e. set maxrows)
|
||||
*/
|
||||
void compute_maxrows(void)
|
||||
{
|
||||
int n;
|
||||
filestruct *foo = openfile->edittop;
|
||||
|
||||
if (!ISSET(SOFTWRAP)) {
|
||||
maxrows = editwinrows;
|
||||
return;
|
||||
}
|
||||
|
||||
maxrows = 0;
|
||||
for (n = 0; n < editwinrows && foo; n++) {
|
||||
maxrows += 1 - strlenpt(foo->data) / COLS;
|
||||
foo = foo->next;
|
||||
}
|
||||
|
||||
if (n < editwinrows)
|
||||
maxrows += editwinrows - n;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "compute_maxrows(): maxrows = %ld\n", maxrows);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Scroll the edit window in the given direction and the given number
|
||||
* of lines, and draw new lines on the blank lines left after the
|
||||
* scrolling. direction is the direction to scroll, either UP_DIR or
|
||||
@@ -2886,14 +2969,58 @@ bool need_vertical_update(size_t pww_save)
|
||||
* also assume that scrollok(edit) is FALSE. */
|
||||
void edit_scroll(scroll_dir direction, ssize_t nlines)
|
||||
{
|
||||
bool do_redraw = need_vertical_update(0);
|
||||
filestruct *foo;
|
||||
ssize_t i;
|
||||
ssize_t i, extracuzsoft = 0;
|
||||
bool do_redraw = FALSE;
|
||||
|
||||
/* Don't bother scrolling less than one line. */
|
||||
if (nlines < 1)
|
||||
return;
|
||||
|
||||
if (need_vertical_update(0))
|
||||
do_redraw = TRUE;
|
||||
|
||||
|
||||
/* If using soft wrapping, we want to scroll down enough to display the entire next
|
||||
line, if possible... */
|
||||
if (ISSET(SOFTWRAP) && direction == DOWN_DIR) {
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Softwrap: Entering check for extracuzsoft\n");
|
||||
#endif
|
||||
for (i = editwinrows, foo = openfile->edittop; foo && i > 0; i--, foo = foo->next) {
|
||||
ssize_t len = strlenpt(foo->data) / COLS;
|
||||
if (len > 0)
|
||||
do_redraw = TRUE;
|
||||
i -= len;
|
||||
}
|
||||
if (foo) {
|
||||
extracuzsoft += strlenpt(foo->data) / COLS;
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Setting extracuzsoft to %lu due to strlen %lu of line %lu\n", (unsigned long) extracuzsoft,
|
||||
(unsigned long) strlenpt(foo->data), (unsigned long) foo->lineno);
|
||||
#endif
|
||||
|
||||
|
||||
/* Now account for whether the edittop line itself is >COLS, if scrolling down */
|
||||
for (foo = openfile->edittop; foo && extracuzsoft > 0; nlines++) {
|
||||
extracuzsoft -= 1 + strlenpt(foo->data) / COLS;
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Edittop adjustment, setting nlines to %lu\n", (unsigned long) nlines);
|
||||
#endif
|
||||
if (foo == openfile->filebot)
|
||||
break;
|
||||
foo = foo->next;
|
||||
}
|
||||
}
|
||||
} else if (ISSET(SOFTWRAP) && direction == UP_DIR) {
|
||||
for (foo = openfile->edittop, i = editwinrows; foo && i > 0; i--, foo = foo->prev) {
|
||||
if (strlenpt(foo->data) / COLS > 0) {
|
||||
do_redraw = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Part 1: nlines is the number of lines we're going to scroll the
|
||||
* text of the edit window. */
|
||||
|
||||
@@ -2912,13 +3039,14 @@ void edit_scroll(scroll_dir direction, ssize_t nlines)
|
||||
}
|
||||
}
|
||||
|
||||
compute_maxrows();
|
||||
/* Limit nlines to the number of lines we could scroll. */
|
||||
nlines -= i;
|
||||
|
||||
/* Don't bother scrolling zero lines or more than the number of
|
||||
* lines in the edit window minus one; in both cases, get out, and
|
||||
* call edit_refresh() beforehand if we need to. */
|
||||
if (nlines == 0 || nlines >= editwinrows) {
|
||||
if (nlines == 0 || do_redraw || nlines >= editwinrows) {
|
||||
if (do_redraw || nlines >= editwinrows)
|
||||
edit_refresh();
|
||||
return;
|
||||
@@ -2992,9 +3120,10 @@ void edit_redraw(filestruct *old_current, size_t pww_save)
|
||||
* window until it's onscreen and get out. */
|
||||
if (old_current->lineno < openfile->edittop->lineno ||
|
||||
old_current->lineno >= openfile->edittop->lineno +
|
||||
editwinrows || openfile->current->lineno <
|
||||
maxrows || openfile->current->lineno <
|
||||
openfile->edittop->lineno || openfile->current->lineno >=
|
||||
openfile->edittop->lineno + editwinrows) {
|
||||
openfile->edittop->lineno + maxrows) {
|
||||
|
||||
filestruct *old_edittop = openfile->edittop;
|
||||
ssize_t nlines;
|
||||
|
||||
@@ -3008,7 +3137,7 @@ void edit_redraw(filestruct *old_current, size_t pww_save)
|
||||
if (old_edittop->lineno < openfile->edittop->lineno)
|
||||
old_lineno = old_edittop->lineno;
|
||||
else
|
||||
old_lineno = (old_edittop->lineno + editwinrows <=
|
||||
old_lineno = (old_edittop->lineno + maxrows <=
|
||||
openfile->filebot->lineno) ?
|
||||
old_edittop->lineno + editwinrows :
|
||||
openfile->filebot->lineno;
|
||||
@@ -3097,9 +3226,17 @@ void edit_refresh(void)
|
||||
filestruct *foo;
|
||||
int nlines;
|
||||
|
||||
/* Figure out what maxrows should really be */
|
||||
compute_maxrows();
|
||||
|
||||
if (openfile->current->lineno < openfile->edittop->lineno ||
|
||||
openfile->current->lineno >= openfile->edittop->lineno +
|
||||
editwinrows)
|
||||
maxrows) {
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "edit_refresh(): line = %d, edittop %d + maxrows %d\n", openfile->current->lineno, openfile->edittop->lineno, maxrows);
|
||||
#endif
|
||||
|
||||
/* Put the top line of the edit window in range of the current
|
||||
* line. */
|
||||
edit_update(
|
||||
@@ -3107,6 +3244,7 @@ void edit_refresh(void)
|
||||
ISSET(SMOOTH_SCROLL) ? NONE :
|
||||
#endif
|
||||
CENTER);
|
||||
}
|
||||
|
||||
foo = openfile->edittop;
|
||||
|
||||
@@ -3115,7 +3253,7 @@ void edit_refresh(void)
|
||||
#endif
|
||||
|
||||
for (nlines = 0; nlines < editwinrows && foo != NULL; nlines++) {
|
||||
update_line(foo, (foo == openfile->current) ?
|
||||
nlines += update_line(foo, (foo == openfile->current) ?
|
||||
openfile->current_x : 0);
|
||||
foo = foo->next;
|
||||
}
|
||||
@@ -3145,19 +3283,22 @@ void edit_update(update_type location)
|
||||
* screen as before, or at the top or bottom of the screen if
|
||||
* edittop is beyond either. */
|
||||
if (location == CENTER)
|
||||
goal = editwinrows / 2;
|
||||
goal = maxrows / 2;
|
||||
else {
|
||||
goal = openfile->current_y;
|
||||
|
||||
/* Limit goal to (editwinrows - 1) lines maximum. */
|
||||
if (goal > editwinrows - 1)
|
||||
goal = editwinrows - 1;
|
||||
if (goal > maxrows - 1)
|
||||
goal = maxrows - 1;
|
||||
}
|
||||
|
||||
for (; goal > 0 && foo->prev != NULL; goal--)
|
||||
for (; goal > 0 && foo->prev != NULL; goal--) {
|
||||
if (ISSET(SOFTWRAP))
|
||||
goal -= 1 + strlenpt(foo->data) / COLS;
|
||||
foo = foo->prev;
|
||||
|
||||
}
|
||||
openfile->edittop = foo;
|
||||
compute_maxrows();
|
||||
}
|
||||
|
||||
/* Unconditionally redraw the entire screen. */
|
||||
|
||||
Reference in New Issue
Block a user