Compare commits
55 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d2780eca94 | ||
|
|
80ea9c5de9 | ||
|
|
b08b38680d | ||
|
|
5c27d723c9 | ||
|
|
447f1b4b75 | ||
|
|
6f681c1be2 | ||
|
|
a50d0e35f7 | ||
|
|
599c559b3c | ||
|
|
ea577874ef | ||
|
|
14c8620e0b | ||
|
|
3c1131a5b3 | ||
|
|
015c74093a | ||
|
|
d31ddb789f | ||
|
|
8f76112084 | ||
|
|
1f37c4514d | ||
|
|
91a1862eed | ||
|
|
e418b694b6 | ||
|
|
12dc8cae80 | ||
|
|
0b499d465b | ||
|
|
fa406949ec | ||
|
|
70859f4a5b | ||
|
|
9fb13fb8f0 | ||
|
|
274142cb10 | ||
|
|
b8576780bf | ||
|
|
a9dea9859d | ||
|
|
a855fa2acc | ||
|
|
09b8124859 | ||
|
|
07fcc4c973 | ||
|
|
1347f22c95 | ||
|
|
9015f187a5 | ||
|
|
2c367bff01 | ||
|
|
47a7ac2313 | ||
|
|
fb41a0780d | ||
|
|
1b6ed07543 | ||
|
|
1371fb6326 | ||
|
|
3daeeebf91 | ||
|
|
8b6461fc80 | ||
|
|
506af6fbfb | ||
|
|
f9cf36264c | ||
|
|
e67bf806bd | ||
|
|
ed505f5893 | ||
|
|
deb34f2779 | ||
|
|
c73d07102b | ||
|
|
9eb7fc6762 | ||
|
|
9ba66065da | ||
|
|
33a8b4e9ae | ||
|
|
2cca48380d | ||
|
|
b04248c548 | ||
|
|
8a59f254ea | ||
|
|
cc60c3a767 | ||
|
|
2ea0b8fa03 | ||
|
|
dcd19c955f | ||
|
|
90ee8ee494 | ||
|
|
690e7df997 | ||
|
|
a1941d2a70 |
102
ChangeLog
102
ChangeLog
@@ -1,7 +1,105 @@
|
||||
GNU nano 2.1.4 - 2008.08.09
|
||||
2008-08-08 Chris Allegretta <chrisa@asty.org>
|
||||
* files.c (write_file): Do not go on and attempt to write the main file if writing the backup file failed,
|
||||
related to Savannah bug 24000.
|
||||
* text.c (do_redo): Fix improperly restoring the text when redoing a line split.
|
||||
* text.c (add_undo): Fix check for multi-line cut check skips adding other new legit events.
|
||||
|
||||
2008-07-23 Chris Allegretta <chrisa@asty.org>
|
||||
* text.c: Reset openfile-> to OTHER after an undo or redo so we don't mistakenly
|
||||
mistakenly think this is an update when it's really an add. Also
|
||||
Fix an extra ; after an if statement which makes nano try to free a struct which
|
||||
may be NULL
|
||||
|
||||
GNU nano 2.1.3 - 2008.08.04
|
||||
2008-07-23 Chris Allegretta <chrisa@asty.org>
|
||||
* configure.ac: Add ncursesw dir to include path if lib detected
|
||||
|
||||
2008-07-11 Mike Frysinger <vapier@gentoo.org>
|
||||
* doc/nanorc.sample.in: Include the updates files in the default sample nanorc.
|
||||
|
||||
2008-07-11 Fabian Groffen <grobian@gentoo.org>
|
||||
* nano.c: Don't include langinfo.h if not using ENABLE_UTF8
|
||||
(Savannah patch 6565)
|
||||
|
||||
2008-07-11 Mitsuya Shibata <mty.shibata@gmail.com>
|
||||
* text.c: Fix crashing in help menu when using certain locales
|
||||
(Savannah bug 23751)
|
||||
|
||||
2008-07-09 Chris Allegretta <chrisa@asty.org>
|
||||
* nano.c/nano.h/global.c/text.c: New generalized undo code, currently
|
||||
just works for adding and deleting text and splitting and unsplitting lines.
|
||||
|
||||
2008-06-29 Chris Allegretta <chrisa@asty.org>
|
||||
* global.c: Fix for not having search history when --disable-justify is used
|
||||
(Savannah bug 23733)
|
||||
|
||||
|
||||
GNU nano 2.1.2 - 2008.06.24
|
||||
2008-06-24 Chris Allegretta <chrisa@asty.org>
|
||||
* rcfile.c: Added function check_bad_binding() to look for sequences which
|
||||
shouldn't be bound, per Savannah bug 22674.
|
||||
|
||||
2008-05-31 Chris Allegretta <chrisa@asty.org>
|
||||
* prompt.c,search.c,global.c: Tentative fix for bug #23144: using arrow
|
||||
keys in search buffer affects main window (by Mike Frysinger)
|
||||
|
||||
2008-05-31 Chris Allegretta <chrisa@asty.org>
|
||||
* global.c: Fix for Savannah bug #23442: left/right arrow keys
|
||||
do not work with --enable-tiny (by Mike Frysinger)
|
||||
|
||||
2008-05-31 Chris Allegretta <chrisa@asty.org>
|
||||
* files.c,proto.h,text.c: Fix for conflicts with AIX curses
|
||||
variables, from William Jojo <jojowil@hvcc.edu>
|
||||
|
||||
2008-05-31 Chris Allegretta <chrisa@asty.org>
|
||||
* global.c: Fix for compile error when --disable-speller is used
|
||||
(Savannah bug 23227 by Mike Frysinger)
|
||||
|
||||
2008-05-31 Chris Allegretta <chrisa@asty.org>
|
||||
* Fix for seg fault when window size too small, by
|
||||
Andreas Amann <andreas.amann@tyndall.ie>
|
||||
|
||||
GNU nano 2.1.1 - 2008.04.01
|
||||
2008-05-31 Chris Allegretta <chrisa@asty.org>
|
||||
* Added the following contributed files, by owner:
|
||||
Donnie Berkholz <dberkholz@gentoo.org>
|
||||
* Sample awk.nanorc
|
||||
Simon Rupf <simon.rupf@int-ag.ch>
|
||||
* Sample css.nanorc
|
||||
Josef 'Jupp' Schugt <jupp@rubyforge.org>
|
||||
* sample ruby.nanorc
|
||||
|
||||
2008-03-31 Chris Allegretta <chrisa@asty.org>
|
||||
* global.c: Fix for issues compiling with --enable-tiny and
|
||||
--enable-multibuffer, as reported by Mike Frysinger.
|
||||
* files.c: Fix the fact that the insert file prompt text did not
|
||||
properly appears in tiny mode.
|
||||
|
||||
2008-03-19 Benno Schulenberg <bensberg@justemail.net>
|
||||
* help.c, nano.c: Fix toggle help not being translated, fix allocation
|
||||
issue.
|
||||
|
||||
2008-03-19 Chris Allegretta <chrisa@asty.org>
|
||||
* gloabl.c: Fix bracket matching sequence to be M-] not M-[, as reported
|
||||
Nick Warne <nick@ukfsn.org>.
|
||||
* doc/syntax/Makefile.am - Actually include new syntaxes from Mike, etc
|
||||
* debian.nanorc - New debian sources.list config since we're including
|
||||
gentoo, adapted from Milian Wolff <mail@milianw.de>
|
||||
|
||||
2008-03-18 Mike Frysinger <vapier@gentoo.org>
|
||||
* winio.c: Remove unneeded variable in parse_kbinput()
|
||||
* rcfile.c: relocate check_vitals_mapped() function to just above
|
||||
where it actually gets used and declare it "static void" in the process
|
||||
* global.c: only declare nano_justify_msg when justify support is enabled
|
||||
* php.nanorc: Php syntax highlighting config
|
||||
* tcl.nanorc: Tcl syntax highlighting config
|
||||
* gentoo.nanorc: Gentoo syntax highlighting config
|
||||
|
||||
2008-03-17 Benno Schulenberg <bensberg@justemail.net>
|
||||
* global.c - Fix incorrect first line jump messsage, fix
|
||||
* global.c: Fix incorrect first line jump messsage, fix
|
||||
more comments to assist translators
|
||||
* winio.c - Fix shortcut labels not being translated.
|
||||
* winio.c: Fix shortcut labels not being translated.
|
||||
|
||||
2008-03-17 Mike Frysinger <vapier@gentoo.org>
|
||||
* */.gitignore: Git ignore files for those running a local git
|
||||
|
||||
48
NEWS
48
NEWS
@@ -1,4 +1,44 @@
|
||||
2008/03/18 - GNU nano 2.1.0 "under old mismanagement" is released.
|
||||
2008.08.09 - GNU nano 2.1.4 "I told you so!" is released. This release
|
||||
includes fixes for several severe issues with the new
|
||||
undo/redo code. Also the behavior of writing
|
||||
files when using backup mode has changed as well: if writing
|
||||
the backup file fails, nano will not attempt to write the
|
||||
current file. This should help folks who enjoy "extreme
|
||||
text editing" i.e. editing files on file systems which
|
||||
are likely to run out of space; see Savannah bug 24000.
|
||||
Have fun with it!
|
||||
|
||||
2008.08.04 - GNY nano 2.1.3 "least stable version ever" is released. This
|
||||
release includes new (and experimental) undo and redo
|
||||
functionality for most text operations. The default
|
||||
key bindings are Meta-U for undo and Meta-E for redo, but
|
||||
these can be remapped using the new 2.1 keybinding code.
|
||||
Also included are some fixes for configuring using wide
|
||||
curses, crashing when invoking the help menu with
|
||||
certain locales, and not saving the search history when
|
||||
compiled with configure options.
|
||||
|
||||
2008.04.24 - GNU nano 2.1.2 "New York City" is released. This release
|
||||
contains fixes for binding bad keys, some
|
||||
configure-specific compilation failures, and more issues
|
||||
with the new input back end and in particular the status
|
||||
bar. Also fixed are some long standing issues with
|
||||
compiling on AIX, and a segfault when making the terminal
|
||||
window too small. Rest in Peace Tim and George!
|
||||
|
||||
2008.04.01 - GNU nano 2.1.1 wont get fooled again. This release contains
|
||||
fixes for the new user-rebindable keys (in particular
|
||||
bracket match which was mis-bound), and various
|
||||
problems with translations and configure-related
|
||||
compilation problems are now fixed as well.
|
||||
It also contains new syntax highlighting
|
||||
definitions for TCL, PHP, Gentoo and Debian-related
|
||||
files, and some documentation updates as well.
|
||||
Please continue to send reports with the key
|
||||
binding code to the Savannah page
|
||||
(https://savannah.gnu.org/bugs/?group=nano).
|
||||
|
||||
2008.03.18 - GNU nano 2.1.0 "under old mismanagement" is released.
|
||||
This first release in the 2.1 development series
|
||||
introduces rebinadble keys for most actions inside
|
||||
the editor. Please see the nanorc(5) page for
|
||||
@@ -8,7 +48,7 @@
|
||||
https://savannah.gnu.org/bugs/?group=nano and
|
||||
thanks for sticking with us!
|
||||
|
||||
2007/12/20 - GNU nano 2.0.7 keeps its balance. This release fixes
|
||||
2007.12.20- GNU nano 2.0.7 keeps its balance. This release fixes
|
||||
several bugs, among others: a segfault and several
|
||||
cursor positioning problems when uncutting text or
|
||||
inserting files into the current buffer; a problem where
|
||||
@@ -30,12 +70,12 @@
|
||||
under the GNU GPL version 3 or later and the GNU FDL
|
||||
version 1.2 or later. Have fun.
|
||||
|
||||
2007/04/26 - GNU nano 2.0.6 "that was quick" is released. This release
|
||||
2007.04.26- GNU nano 2.0.6 "that was quick" is released. This release
|
||||
fixes a potential segfault after justifying text marked
|
||||
from the bottom up. It also adds one more minor
|
||||
documentation update. Enjoy.
|
||||
|
||||
2007/04/22 - GNU nano 2.0.5 braces for impact. Among other things, this
|
||||
2007.04.22- GNU nano 2.0.5 braces for impact. Among other things, this
|
||||
release fixes various problems (including a segfault)
|
||||
when trying to open or save a file in a directory
|
||||
beginning with "~" that isn't a home directory; fixes a
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#
|
||||
# $Id$
|
||||
|
||||
AC_INIT([GNU nano], [2.1.0], [nano-devel@gnu.org], [nano])
|
||||
AC_INIT([GNU nano], [2.1.4], [nano-devel@gnu.org], [nano])
|
||||
AC_CONFIG_SRCDIR([src/nano.c])
|
||||
AC_CANONICAL_TARGET([])
|
||||
AM_INIT_AUTOMAKE
|
||||
@@ -417,7 +417,7 @@ if eval "test x$CURSES_LIB_NAME = x"; then
|
||||
AC_CHECK_HEADERS(ncurses.h)
|
||||
|
||||
if test x$enable_utf8 != xno; then
|
||||
AC_CHECK_LIB(ncursesw, get_wch, [CURSES_LIB="-lncursesw" CURSES_LIB_NAME=ncursesw CURSES_LIB_WIDE=yes])
|
||||
AC_CHECK_LIB(ncursesw, get_wch, [CURSES_LIB="-lncursesw" CPPFLAGS="-I/usr/include/ncursesw $CPPFLAGS" CURSES_LIB_NAME=ncursesw CURSES_LIB_WIDE=yes])
|
||||
fi
|
||||
|
||||
if eval "test x$CURSES_LIB_NAME = x"; then
|
||||
|
||||
@@ -396,6 +396,12 @@ Count the number of words in the current buffer.
|
||||
.B refresh
|
||||
Refresh the screen.
|
||||
.TP
|
||||
.B undo
|
||||
Undo the text action peformed (add text, delete text, etc).
|
||||
.TP
|
||||
.B suspend
|
||||
Redo the last action which was undone.
|
||||
.TP
|
||||
.B suspend
|
||||
Suspend the editor (if the suspend function is enabled, see the
|
||||
"suspendenable" entry below).
|
||||
|
||||
@@ -222,6 +222,9 @@
|
||||
# bind M-A casesens search
|
||||
# bind ^S research main
|
||||
|
||||
## Set this if your backspace key sends delete most of the time (2.1.3+)
|
||||
# bind kdel backspace all
|
||||
|
||||
|
||||
## Nanorc files
|
||||
# include "@PKGDATADIR@/nanorc.nanorc"
|
||||
@@ -229,9 +232,24 @@
|
||||
## C/C++
|
||||
# include "@PKGDATADIR@/c.nanorc"
|
||||
|
||||
## Cascading Style Sheets
|
||||
# include "@PKGDATADIR@/css.nanorc"
|
||||
|
||||
## Debian files
|
||||
# include "@PKGDATADIR@/debian.nanorc"
|
||||
|
||||
## Gentoo files
|
||||
# include "@PKGDATADIR@/gentoo.nanorc"
|
||||
|
||||
## HTML
|
||||
# include "@PKGDATADIR@/html.nanorc"
|
||||
|
||||
## PHP
|
||||
# include "@PKGDATADIR@/php.nanorc"
|
||||
|
||||
## TCL
|
||||
# include "@PKGDATADIR@/tcl.nanorc"
|
||||
|
||||
## TeX
|
||||
# include "@PKGDATADIR@/tex.nanorc"
|
||||
|
||||
@@ -259,6 +277,9 @@
|
||||
## Java
|
||||
# include "@PKGDATADIR@/java.nanorc"
|
||||
|
||||
## AWK
|
||||
# include "@PKGDATADIR@/awk.nanorc"
|
||||
|
||||
## Assembler
|
||||
# include "@PKGDATADIR@/asm.nanorc"
|
||||
|
||||
@@ -267,3 +288,6 @@
|
||||
|
||||
## POV-Ray
|
||||
# include "@PKGDATADIR@/pov.nanorc"
|
||||
|
||||
## XML-type files
|
||||
# include "@PKGDATADIR@/xml.nanorc"
|
||||
|
||||
@@ -12,6 +12,13 @@ pkgdata_DATA = asm.nanorc \
|
||||
python.nanorc \
|
||||
ruby.nanorc \
|
||||
sh.nanorc \
|
||||
tex.nanorc
|
||||
tex.nanorc \
|
||||
tcl.nanorc \
|
||||
php.nanorc \
|
||||
gentoo.nanorc \
|
||||
debian.nanorc \
|
||||
awk.nanorc \
|
||||
css.nanorc \
|
||||
xml.nanorc
|
||||
|
||||
EXTRA_DIST = $(pkgdata_DATA)
|
||||
|
||||
38
doc/syntax/awk.nanorc
Normal file
38
doc/syntax/awk.nanorc
Normal file
@@ -0,0 +1,38 @@
|
||||
## Here is an example for awk.
|
||||
##
|
||||
syntax "awk" "\.awk$"
|
||||
## records
|
||||
icolor brightred "\$[0-9A-Z_!@#$*?-]+"
|
||||
## awk-set variables
|
||||
color red "\<(ARGC|ARGIND|ARGV|BINMODE|CONVFMT|ENVIRON|ERRNO|FIELDWIDTHS)\>"
|
||||
color red "\<(FILENAME|FNR|FS|IGNORECASE|LINT|NF|NR|OFMT|OFS|ORS)\>"
|
||||
color red "\<(PROCINFO|RS|RT|RSTART|RLENGTH|SUBSEP|TEXTDOMAIN)\>"
|
||||
## function declarations and special patterns
|
||||
color brightgreen "\<(function|extension|BEGIN|END)\>"
|
||||
## operators
|
||||
color green "(\{|\}|\(|\)|\;|\]|\[|\\|<|>|!|=|&|\+|-|\*|%|/|\?:|\^|\|)"
|
||||
## flow control
|
||||
color brightyellow "\<(for|if|while|do|else|in|delete|exit)\>"
|
||||
color brightyellow "\<(break|continue|return)\>"
|
||||
## I/O statements
|
||||
color brightgreen "\<(close|getline|next|nextfile|print|printf)\>"
|
||||
color brightgreen "\<(system|fflush)\>"
|
||||
## standard functions
|
||||
color magenta "\<(atan2|cos|exp|int|log|rand|sin|sqrt|srand)\>"
|
||||
color magenta "\<(asort|asorti|gensub|gsub|index|length|match)\>"
|
||||
color magenta "\<(split|sprintf|strtonum|sub|substr|tolower|toupper)\>"
|
||||
color magenta "\<(mktime|strftime|systime)\>"
|
||||
color magenta "\<(and|compl|lshift|or|rshift|xor)\>"
|
||||
color magenta "\<(bindtextdomain|dcgettext|dcngettext)\>"
|
||||
|
||||
##
|
||||
## String highlighting. You will in general want your comments and
|
||||
## strings to come last, because syntax highlighting rules will be
|
||||
## applied in the order they are read in.
|
||||
color brightyellow "<[^= ]*>" ""(\\.|[^"])*""
|
||||
|
||||
## Comment highlighting
|
||||
color brightblue "(^|[[:space:]])#.*$"
|
||||
|
||||
## Trailing whitespace
|
||||
color ,green "[[:space:]]+$"
|
||||
9
doc/syntax/css.nanorc
Normal file
9
doc/syntax/css.nanorc
Normal file
@@ -0,0 +1,9 @@
|
||||
## Here is an example for css files.
|
||||
##
|
||||
syntax "css" "\.css$"
|
||||
color brightred "."
|
||||
color brightyellow start="\{" end="\}"
|
||||
color brightwhite start=":" end="([;^\{]|$)"
|
||||
color brightblue ":active|:focus|:hover|:link|:visited|:link|:after|:before|$"
|
||||
color brightblue start="\/\*" end="\\*/"
|
||||
color green ";|:|\{|\}"
|
||||
20
doc/syntax/debian.nanorc
Normal file
20
doc/syntax/debian.nanorc
Normal file
@@ -0,0 +1,20 @@
|
||||
## Here is an exmaple for apt's sources.list
|
||||
## Adapted from http://milianw.de/blog/Syntax-Highlighting-in-Nano
|
||||
## (mail@milianw.de).
|
||||
##
|
||||
syntax "apt/sources.list" "sources\.list(\.old|~)?$"
|
||||
# component
|
||||
color brightmagenta "^deb(-src)? ((http|file|ftp):/[^ ]+|cdrom:\[[^\]]+\]/|cdrom:\[[-a-zA-Z0-9\._\(\) ]+\]/) [^ ]+ .+$"
|
||||
# distribution
|
||||
color brightred "^deb(-src)? ((http|file|ftp):/[^ ]+|cdrom:\[[^\]]+\]/|cdrom:\[[-a-zA-Z0-9\._\(\) ]+\]/) [^ ]+"
|
||||
# URI
|
||||
color brightgreen "(http|file|ftp):/[^ ]+"
|
||||
# cdroms
|
||||
# [^\]] does not work...
|
||||
color brightgreen "cdrom:\[[-a-zA-Z0-9\._\(\) ]+\]/"
|
||||
# deb / deb-src
|
||||
color yellow "^deb"
|
||||
color yellow "^deb-src"
|
||||
# comments
|
||||
color brightblue "#.*"
|
||||
|
||||
50
doc/syntax/gentoo.nanorc
Normal file
50
doc/syntax/gentoo.nanorc
Normal file
@@ -0,0 +1,50 @@
|
||||
## Here is an example for Gentoo ebuilds/eclasses
|
||||
##
|
||||
syntax "ebuild" "\.e(build|class)$"
|
||||
## All the standard portage functions
|
||||
color brightgreen "^src_(unpack|compile|install|test)" "^pkg_(config|nofetch|setup|(pre|post)(inst|rm))"
|
||||
## Highlight bash related syntax
|
||||
color green "\<(case|do|done|elif|else|esac|exit|fi|for|function|if|in|local|read|return|select|shift|then|time|until|while|continue|break)\>"
|
||||
color green "(\{|\}|\(|\)|\;|\]|\[|`|\\|\$|<|>|!|=|&|\|)"
|
||||
color green "-(e|d|f|r|g|u|w|x|L)\>"
|
||||
color green "-(eq|ne|gt|lt|ge|le|s|n|z)\>"
|
||||
## Highlight variables ... official portage ones in red, all others in bright red
|
||||
color brightred "\$\{?[a-zA-Z_0-9]+\}?"
|
||||
color red "\<(ARCH|HOMEPAGE|DESCRIPTION|IUSE|SRC_URI|LICENSE|SLOT|KEYWORDS|FILESDIR|WORKDIR|(P|R)?DEPEND|PROVIDE|DISTDIR|RESTRICT|USERLAND)\>"
|
||||
color red "\<(S|D|T|PV|PF|P|PN|A)\>" "\<C(XX)?FLAGS\>" "\<LDFLAGS\>" "\<C(HOST|TARGET|BUILD)\>"
|
||||
## Highlight portage commands
|
||||
color magenta "\<use(_(with|enable))?\> [!a-zA-Z0-9_+ -]*" "inherit.*"
|
||||
color brightblue "\<e(begin|end|conf|install|make|warn|infon?|error|log|patch|new(group|user))\>"
|
||||
color brightblue "\<die\>" "\<use(_(with|enable))?\>" "\<inherit\>" "\<has\>" "\<(has|best)_version\>" "\<unpack\>"
|
||||
color brightblue "\<(do|new)(ins|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)"
|
||||
color brightblue "\<(|doc|ins|exe)into\>" "\<f(owners|perms)\>" "\<(exe|ins|dir)opts\>"
|
||||
## Highlight common commands used in ebuilds
|
||||
color blue "\<make\>" "\<(cat|cd|chmod|chown|cp|echo|env|export|grep|let|ln|mkdir|mv|rm|sed|set|tar|touch|unset)\>"
|
||||
## Highlight comments (doesnt work that well)
|
||||
color yellow "#.*$"
|
||||
## Highlight strings (doesnt work that well)
|
||||
color brightyellow ""(\\.|[^\"])*"" "'(\\.|[^'])*'"
|
||||
## Trailing space is bad!
|
||||
color ,green "[[:space:]]+$"
|
||||
|
||||
## Here is an example for Portage control files
|
||||
##
|
||||
syntax "/etc/portage" "\.(keywords|mask|unmask|use)$"
|
||||
## Base text:
|
||||
color green "^.+$"
|
||||
## Use flags:
|
||||
color brightred "[[:space:]]+\+?[a-zA-Z0-9_-]+"
|
||||
color brightblue "[[:space:]]+-[a-zA-Z0-9_-]+"
|
||||
## Likely version numbers:
|
||||
color magenta "-[[:digit:]].*([[:space:]]|$)"
|
||||
## Accepted arches:
|
||||
color white "[~-]?\<(alpha|amd64|arm|hppa|ia64|mips|ppc|ppc64|s390|sh|sparc|x86|x86-fbsd)\>"
|
||||
color white "[[:space:]][~-]?\*"
|
||||
## Categories:
|
||||
color cyan "^[[:space:]]*.*/"
|
||||
## Masking regulators:
|
||||
color brightmagenta "^[[:space:]]*(=|~|<|<=|=<|>|>=|=>)"
|
||||
## Comments:
|
||||
color yellow "#.*$"
|
||||
30
doc/syntax/php.nanorc
Normal file
30
doc/syntax/php.nanorc
Normal file
@@ -0,0 +1,30 @@
|
||||
## Here is an example for PHP
|
||||
##
|
||||
syntax "php" "\.php[2345s~]?$"
|
||||
|
||||
## php markings
|
||||
color brightgreen "(<\?(php)?|\?>)"
|
||||
|
||||
## functions
|
||||
color white "\<[a-z_]*\("
|
||||
|
||||
## types
|
||||
color green "\<(var|float|global|double|bool|char|int|enum|const)\>"
|
||||
|
||||
## structure
|
||||
color brightyellow "\<(class|new|private|public|function|for|foreach|if|while|do|else|elseif|case|default|switch)\>"
|
||||
|
||||
## control flow
|
||||
color magenta "\<(goto|continue|break|return)\>"
|
||||
|
||||
## strings
|
||||
color brightyellow "<[^= ]*>" ""(\.|[^"])*""
|
||||
|
||||
## comments
|
||||
color brightblue "//.*"
|
||||
color brightblue start="/\*" end="\*/"
|
||||
#color blue start="<" end=">"
|
||||
#color red "&[^;[[:space:]]]*;"
|
||||
|
||||
## Trailing whitespace
|
||||
color ,green "[[:space:]]+$"
|
||||
16
doc/syntax/tcl.nanorc
Normal file
16
doc/syntax/tcl.nanorc
Normal file
@@ -0,0 +1,16 @@
|
||||
syntax "tcl" "\.tcl$"
|
||||
|
||||
## Standard Tcl [info commands]
|
||||
color green "\<(after|append|array|auto_execok|auto_import|auto_load|auto_load_index|auto_qualify|binary|break|case|catch|cd|clock|close|concat|continue|encoding|eof|error|eval|exec|exit|expr|fblocked|fconfigure|fcopy|file|fileevent|flush|for|foreach|format|gets|glob|global|history|if|incr|info|interp|join|lappend|lindex|linsert|list|llength|load|lrange|lreplace|lsearch|lset|lsort|namespace|open|package|pid|puts|pwd|read|regexp|regsub|rename|return|scan|seek|set|socket|source|split|string|subst|switch|tclLog|tell|time|trace|unknown|unset|update|uplevel|upvar|variable|vwait|while)\>"
|
||||
## Basic Tcl sub commands.
|
||||
color green "\<(array anymore|array donesearch|array exists|array get|array names|array nextelement|array set|array size|array startsearch|array statistics|array unset)\>"
|
||||
color green "\<(string bytelength|string compare|string equal|string first|string index|string is|string last|string length|string map|string match|string range|string repeat|string replace|string to|string tolower|string totitle|string toupper|string trim|string trimleft|string trimright|string will|string wordend|string wordstart)\>"
|
||||
## Extended TclX [info commands]
|
||||
color green "\<(alarm|auto_load_pkg|bsearch|catclose|catgets|catopen|ccollate|cconcat|cequal|chgrp|chmod|chown|chroot|cindex|clength|cmdtrace|commandloop|crange|csubstr|ctoken|ctype|dup|echo|execl|fcntl|flock|fork|fstat|ftruncate|funlock|host_info|id|infox|keyldel|keylget|keylkeys|keylset|kill|lassign|lcontain|lempty|lgets|link|lmatch|loadlibindex|loop|lvarcat|lvarpop|lvarpush|max|min|nice|pipe|profile|random|readdir|replicate|scancontext|scanfile|scanmatch|select|server_accept|server_create|signal|sleep|sync|system|tclx_findinit|tclx_fork|tclx_load_tndxs|tclx_sleep|tclx_system|tclx_wait|times|translit|try_eval|umask|wait)\>"
|
||||
## Syntax.
|
||||
color brightblue "proc[[:space:]]" "(\{|\})"
|
||||
color green "(\(|\)|\;|`|\\|\$|<|>|!|=|&|\|)"
|
||||
color brightyellow ""(\\.|[^"])*"" "'(\\.|[^'])*'"
|
||||
icolor brightred "\$\{?[0-9A-Z_!@#$*?-]+\}?"
|
||||
color ,green "[[:space:]]+$"
|
||||
color ,magenta "^([[:space:]]+|)#.*"
|
||||
9
doc/syntax/xml.nanorc
Normal file
9
doc/syntax/xml.nanorc
Normal file
@@ -0,0 +1,9 @@
|
||||
## Here is an example for xml files.
|
||||
##
|
||||
syntax "xml" "\.([jrs]html?|sgml?|xml|xslt?)$"
|
||||
color green start="<" end=">"
|
||||
color cyan "<[^> ]+"
|
||||
color cyan ">"
|
||||
color yellow start="<!DOCTYPE" end="[/]?>"
|
||||
color yellow start="<!--" end="-->"
|
||||
color red "&[^;]*;"
|
||||
2646
po/nano.pot
2646
po/nano.pot
File diff suppressed because it is too large
Load Diff
1311
po/pt_BR.po
1311
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
1283
po/zh_CN.po
1283
po/zh_CN.po
File diff suppressed because it is too large
Load Diff
2176
po/zh_TW.po
2176
po/zh_TW.po
File diff suppressed because it is too large
Load Diff
20
src/cut.c
20
src/cut.c
@@ -28,7 +28,6 @@
|
||||
|
||||
static bool keep_cutbuffer = FALSE;
|
||||
/* Should we keep the contents of the cutbuffer? */
|
||||
static filestruct *cutbottom = NULL;
|
||||
/* Pointer to the end of the cutbuffer. */
|
||||
|
||||
/* Indicate that we should no longer keep the contents of the
|
||||
@@ -114,7 +113,7 @@ void cut_to_eof(void)
|
||||
* position to the end of the file into the cutbuffer. */
|
||||
void do_cut_text(
|
||||
#ifndef NANO_TINY
|
||||
bool copy_text, bool cut_till_end
|
||||
bool copy_text, bool cut_till_end, bool undoing
|
||||
#else
|
||||
void
|
||||
#endif
|
||||
@@ -163,6 +162,7 @@ void do_cut_text(
|
||||
keep_cutbuffer = TRUE;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
|
||||
if (cut_till_end) {
|
||||
/* If cut_till_end is TRUE, move all text up to the end of the
|
||||
* file into the cutbuffer. */
|
||||
@@ -204,12 +204,14 @@ void do_cut_text(
|
||||
* disturbing the text. */
|
||||
if (!old_no_newlines)
|
||||
UNSET(NO_NEWLINES);
|
||||
} else
|
||||
} else if (!undoing)
|
||||
update_undo(CUT);
|
||||
#endif
|
||||
/* Leave the text in the cutbuffer, and mark the file as
|
||||
* modified. */
|
||||
set_modified();
|
||||
|
||||
|
||||
/* Update the screen. */
|
||||
edit_refresh();
|
||||
|
||||
@@ -221,9 +223,12 @@ void do_cut_text(
|
||||
/* Move text from the current filestruct into the cutbuffer. */
|
||||
void do_cut_text_void(void)
|
||||
{
|
||||
#ifndef NANO_TINY
|
||||
add_undo(CUT);
|
||||
#endif
|
||||
do_cut_text(
|
||||
#ifndef NANO_TINY
|
||||
FALSE, FALSE
|
||||
FALSE, FALSE, FALSE
|
||||
#endif
|
||||
);
|
||||
}
|
||||
@@ -233,13 +238,16 @@ void do_cut_text_void(void)
|
||||
* back into the filestruct afterward. */
|
||||
void do_copy_text(void)
|
||||
{
|
||||
do_cut_text(TRUE, FALSE);
|
||||
do_cut_text(TRUE, FALSE, FALSE);
|
||||
}
|
||||
|
||||
/* Cut from the current cursor position to the end of the file. */
|
||||
void do_cut_till_end(void)
|
||||
{
|
||||
do_cut_text(FALSE, TRUE);
|
||||
#ifndef NANO_TINY
|
||||
add_undo(CUTTOEND);
|
||||
#endif
|
||||
do_cut_text(FALSE, TRUE, FALSE);
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
|
||||
74
src/files.c
74
src/files.c
@@ -75,6 +75,8 @@ void initialize_buffer(void)
|
||||
openfile->fmt = NIX_FILE;
|
||||
|
||||
openfile->current_stat = NULL;
|
||||
openfile->undotop = NULL;
|
||||
openfile->current_undo = NULL;
|
||||
#endif
|
||||
#ifdef ENABLE_COLOR
|
||||
openfile->colorstrings = NULL;
|
||||
@@ -99,7 +101,7 @@ void initialize_buffer_text(void)
|
||||
|
||||
/* If it's not "", filename is a file to open. We make a new buffer, if
|
||||
* necessary, and then open and read the file, if applicable. */
|
||||
void open_buffer(const char *filename)
|
||||
void open_buffer(const char *filename, bool undoable)
|
||||
{
|
||||
bool new_buffer = (openfile == NULL
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
@@ -140,7 +142,7 @@ void open_buffer(const char *filename)
|
||||
/* 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);
|
||||
read_file(f, filename, undoable);
|
||||
#ifndef NANO_TINY
|
||||
if (openfile->current_stat == NULL) {
|
||||
openfile->current_stat =
|
||||
@@ -190,7 +192,7 @@ void replace_buffer(const char *filename)
|
||||
|
||||
/* If we have a non-new file, read it in. */
|
||||
if (rc == 0)
|
||||
read_file(f, filename);
|
||||
read_file(f, filename, FALSE);
|
||||
|
||||
/* Move back to the beginning of the first line of the buffer. */
|
||||
openfile->current = openfile->fileage;
|
||||
@@ -337,8 +339,9 @@ 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. */
|
||||
void read_file(FILE *f, const char *filename)
|
||||
* 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)
|
||||
{
|
||||
size_t num_lines = 0;
|
||||
/* The number of lines in the file. */
|
||||
@@ -369,6 +372,11 @@ void read_file(FILE *f, const char *filename)
|
||||
buf = charalloc(bufx);
|
||||
buf[0] = '\0';
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (undoable)
|
||||
add_undo(INSERT);
|
||||
#endif
|
||||
|
||||
if (openfile->current == openfile->fileage)
|
||||
first_line_ins = TRUE;
|
||||
else
|
||||
@@ -487,7 +495,7 @@ void read_file(FILE *f, const char *filename)
|
||||
/* If we didn't get a file and we don't already have one, open a
|
||||
* blank buffer. */
|
||||
if (fileptr == NULL)
|
||||
open_buffer("");
|
||||
open_buffer("", FALSE);
|
||||
|
||||
/* Attach the file we got to the filestruct. If we got a file of
|
||||
* zero bytes, don't do anything. */
|
||||
@@ -559,6 +567,9 @@ void read_file(FILE *f, const char *filename)
|
||||
openfile->placewewant = xplustabs();
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (undoable)
|
||||
update_undo(INSERT);
|
||||
|
||||
if (format == 3)
|
||||
statusbar(
|
||||
P_("Read %lu line (Converted from DOS and Mac format)",
|
||||
@@ -738,7 +749,9 @@ void do_insertfile(
|
||||
#endif
|
||||
MINSERTFILE, ans,
|
||||
&meta_key, &func_key,
|
||||
#ifndef NANO_TINY
|
||||
NULL,
|
||||
#endif
|
||||
edit_refresh, msg,
|
||||
#ifndef DISABLE_OPERATINGDIR
|
||||
operating_dir != NULL && strcmp(operating_dir,
|
||||
@@ -849,7 +862,7 @@ void do_insertfile(
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
if (ISSET(MULTIBUFFER))
|
||||
/* Open a blank buffer. */
|
||||
open_buffer("");
|
||||
open_buffer("", FALSE);
|
||||
#endif
|
||||
|
||||
/* Save the command's output in the current buffer. */
|
||||
@@ -873,7 +886,7 @@ void do_insertfile(
|
||||
|
||||
/* Save the file specified in answer in the current
|
||||
* buffer. */
|
||||
open_buffer(answer);
|
||||
open_buffer(answer, TRUE);
|
||||
#ifndef NANO_TINY
|
||||
}
|
||||
#endif
|
||||
@@ -1461,14 +1474,15 @@ bool write_file(const char *name, FILE *f_open, bool tmp, append_type
|
||||
free(backuptemp);
|
||||
backuptemp = get_next_filename(backupname, "~");
|
||||
if (*backuptemp == '\0') {
|
||||
statusbar(_("Error writing %s: %s"), backupname,
|
||||
statusbar(_("Error writing backup file %s: %s"), backupname,
|
||||
_("Too many backup files?"));
|
||||
free(backuptemp);
|
||||
free(backupname);
|
||||
/* If we can't write to the backup, go on, since only
|
||||
* saving the original file is better than saving
|
||||
* nothing. */
|
||||
goto skip_backup;
|
||||
/* If we can't write to the backup, DONT go on, since
|
||||
whatever caused the backup file to fail (e.g. disk
|
||||
full may well cause the real file write to fail, which
|
||||
means we could lose both the backup and the original! */
|
||||
goto cleanup_and_exit;
|
||||
} else {
|
||||
free(backupname);
|
||||
backupname = backuptemp;
|
||||
@@ -1485,14 +1499,16 @@ bool write_file(const char *name, FILE *f_open, bool tmp, append_type
|
||||
|
||||
if (backup_file == NULL || chmod(backupname,
|
||||
openfile->current_stat->st_mode) == -1) {
|
||||
statusbar(_("Error writing %s: %s"), backupname,
|
||||
statusbar(_("Error writing backup file %s: %s"), backupname,
|
||||
strerror(errno));
|
||||
free(backupname);
|
||||
if (backup_file != NULL)
|
||||
fclose(backup_file);
|
||||
/* If we can't write to the backup, go on, since only saving
|
||||
* the original file is better than saving nothing. */
|
||||
goto skip_backup;
|
||||
/* If we can't write to the backup, DONT go on, since
|
||||
whatever caused the backup file to fail (e.g. disk
|
||||
full may well cause the real file write to fail, which
|
||||
means we could lose both the backup and the original! */
|
||||
goto cleanup_and_exit;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
@@ -1512,17 +1528,19 @@ bool write_file(const char *name, FILE *f_open, bool tmp, append_type
|
||||
strerror(errno));
|
||||
beep();
|
||||
} else
|
||||
statusbar(_("Error writing %s: %s"), backupname,
|
||||
statusbar(_("Error writing backup file %s: %s"), backupname,
|
||||
strerror(errno));
|
||||
/* If we can't read from or write to the backup, go on,
|
||||
* since only saving the original file is better than saving
|
||||
* nothing. */
|
||||
/* If we can't write to the backup, DONT go on, since
|
||||
whatever caused the backup file to fail (e.g. disk
|
||||
full may well cause the real file write to fail, which
|
||||
means we could lose both the backup and the original! */
|
||||
goto cleanup_and_exit;
|
||||
}
|
||||
|
||||
free(backupname);
|
||||
}
|
||||
|
||||
skip_backup:
|
||||
skip_backup:
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
/* If NOFOLLOW_SYMLINKS is set and the file is a link, we aren't
|
||||
@@ -2393,7 +2411,7 @@ char *input_tab(char *buf, bool allow_files, size_t *place, bool
|
||||
} else if (!*lastwastab || num_matches < 2)
|
||||
*lastwastab = TRUE;
|
||||
else {
|
||||
int longest_name = 0, columns, editline = 0;
|
||||
int longest_name = 0, ncols, editline = 0;
|
||||
|
||||
/* Now we show a list of the available choices. */
|
||||
assert(num_matches > 1);
|
||||
@@ -2418,7 +2436,7 @@ char *input_tab(char *buf, bool allow_files, size_t *place, bool
|
||||
/* Each column will be (longest_name + 2) columns wide, i.e.
|
||||
* two spaces between columns, except that there will be
|
||||
* only one space after the last column. */
|
||||
columns = (COLS + 1) / (longest_name + 2);
|
||||
ncols = (COLS + 1) / (longest_name + 2);
|
||||
|
||||
/* Blank the edit window, and print the matches out
|
||||
* there. */
|
||||
@@ -2432,11 +2450,11 @@ char *input_tab(char *buf, bool allow_files, size_t *place, bool
|
||||
char *disp;
|
||||
|
||||
wmove(edit, editline, (longest_name + 2) *
|
||||
(match % columns));
|
||||
(match % ncols));
|
||||
|
||||
if (match % columns == 0 &&
|
||||
if (match % ncols == 0 &&
|
||||
editline == editwinrows - 1 &&
|
||||
num_matches - match > columns) {
|
||||
num_matches - match > ncols) {
|
||||
waddstr(edit, _("(more)"));
|
||||
break;
|
||||
}
|
||||
@@ -2446,7 +2464,7 @@ char *input_tab(char *buf, bool allow_files, size_t *place, bool
|
||||
waddstr(edit, disp);
|
||||
free(disp);
|
||||
|
||||
if ((match + 1) % columns == 0)
|
||||
if ((match + 1) % ncols == 0)
|
||||
editline++;
|
||||
}
|
||||
|
||||
|
||||
74
src/global.c
74
src/global.c
@@ -1,5 +1,4 @@
|
||||
/* $Id$
|
||||
*/
|
||||
/* $Id$ */
|
||||
/**************************************************************************
|
||||
* global.c *
|
||||
* *
|
||||
@@ -22,11 +21,12 @@
|
||||
* *
|
||||
**************************************************************************/
|
||||
|
||||
#include "proto.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include "assert.h"
|
||||
#include "proto.h"
|
||||
|
||||
/* Global variables. */
|
||||
#ifndef NANO_TINY
|
||||
@@ -69,6 +69,7 @@ int editwinrows = 0;
|
||||
|
||||
filestruct *cutbuffer = NULL;
|
||||
/* The buffer where we store cut text. */
|
||||
filestruct *cutbottom = NULL;
|
||||
#ifndef DISABLE_JUSTIFY
|
||||
filestruct *jusbuffer = NULL;
|
||||
/* The buffer where we store unjustified text. */
|
||||
@@ -150,11 +151,6 @@ const shortcut *currshortcut;
|
||||
int currmenu;
|
||||
/* The currently loaded menu */
|
||||
|
||||
#ifndef NANO_TINY
|
||||
toggle *toggles = NULL;
|
||||
/* The global toggle list. */
|
||||
#endif
|
||||
|
||||
sc *sclist = NULL;
|
||||
/* New shortcut key struct */
|
||||
subnfunc *allfuncs = NULL;
|
||||
@@ -501,7 +497,9 @@ void shortcut_init(bool unjustify)
|
||||
;
|
||||
const char *nano_writeout_msg =
|
||||
N_("Write the current file to disk");
|
||||
#ifndef DISABLE_JUSTIFY
|
||||
const char *nano_justify_msg = N_("Justify the current paragraph");
|
||||
#endif
|
||||
const char *nano_insert_msg =
|
||||
N_("Insert another file into the current one");
|
||||
const char *nano_whereis_msg =
|
||||
@@ -526,6 +524,8 @@ void shortcut_init(bool unjustify)
|
||||
N_("Copy the current line and store it in the cutbuffer");
|
||||
const char *nano_indent_msg = N_("Indent the current line");
|
||||
const char *nano_unindent_msg = N_("Unindent the current line");
|
||||
const char *nano_undo_msg = N_("Undo the last operation");
|
||||
const char *nano_redo_msg = N_("Redo the last undone operation");
|
||||
#endif
|
||||
const char *nano_forward_msg = N_("Go forward one character");
|
||||
const char *nano_back_msg = N_("Go back one character");
|
||||
@@ -658,7 +658,11 @@ void shortcut_init(bool unjustify)
|
||||
#endif
|
||||
exit_msg, IFSCHELP(nano_exit_msg), FALSE, VIEW);
|
||||
|
||||
add_to_funcs(do_exit, MBROWSER|MHELP, exit_msg, IFSCHELP(nano_exit_msg), FALSE, VIEW);
|
||||
add_to_funcs(do_exit, MHELP, exit_msg, IFSCHELP(nano_exit_msg), FALSE, VIEW);
|
||||
|
||||
#ifndef DISABLE_BROWSER
|
||||
add_to_funcs(do_exit, MBROWSER, exit_msg, IFSCHELP(nano_exitbrowser_msg), FALSE, VIEW);
|
||||
#endif
|
||||
|
||||
/* TRANSLATORS: Try to keep this at most 10 characters. */
|
||||
add_to_funcs(do_writeout_void, MMAIN, N_("WriteOut"),
|
||||
@@ -692,6 +696,7 @@ void shortcut_init(bool unjustify)
|
||||
add_to_funcs(do_page_down, MMAIN|MHELP,
|
||||
next_page_msg, IFSCHELP(nano_nextpage_msg), TRUE, VIEW);
|
||||
|
||||
|
||||
/* TRANSLATORS: Try to keep this at most 10 characters. */
|
||||
add_to_funcs(do_cut_text_void, MMAIN, N_("Cut Text"), IFSCHELP(nano_cut_msg),
|
||||
FALSE, NOVIEW);
|
||||
@@ -765,7 +770,13 @@ void shortcut_init(bool unjustify)
|
||||
nano_indent_msg, FALSE, NOVIEW);
|
||||
|
||||
add_to_funcs(do_unindent, MMAIN, N_("Unindent Text"),
|
||||
nano_unindent_msg, TRUE, NOVIEW);
|
||||
nano_unindent_msg, FALSE, NOVIEW);
|
||||
|
||||
add_to_funcs(do_undo, MMAIN, N_("Undo"),
|
||||
nano_undo_msg, FALSE, NOVIEW);
|
||||
|
||||
add_to_funcs(do_redo, MMAIN, N_("Redo"),
|
||||
nano_redo_msg, TRUE, NOVIEW);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -824,9 +835,9 @@ void shortcut_init(bool unjustify)
|
||||
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
add_to_funcs(switch_to_prev_buffer_void, MMAIN, _("Previous File"),
|
||||
nano_prevfile_msg, FALSE, VIEW);
|
||||
IFSCHELP(nano_prevfile_msg), FALSE, VIEW);
|
||||
add_to_funcs(switch_to_next_buffer_void, MMAIN, N_("Next File"),
|
||||
nano_nextfile_msg, TRUE, VIEW);
|
||||
IFSCHELP(nano_nextfile_msg), TRUE, VIEW);
|
||||
#endif
|
||||
|
||||
add_to_funcs(do_verbatim_input, MMAIN, N_("Verbatim Input"),
|
||||
@@ -1026,7 +1037,7 @@ void shortcut_init(bool unjustify)
|
||||
add_to_sclist(MMAIN, "F10", do_uncut_text, 0, TRUE);
|
||||
add_to_sclist(MMAIN, "^C", do_cursorpos_void, 0, TRUE);
|
||||
add_to_sclist(MMAIN, "F11", do_cursorpos_void, 0, TRUE);
|
||||
#ifndef NANO_TINY
|
||||
#ifndef DISABLE_SPELLER
|
||||
add_to_sclist(MMAIN, "^T", do_spell, 0, TRUE);
|
||||
add_to_sclist(MMAIN, "F12", do_spell, 0, TRUE);
|
||||
#endif
|
||||
@@ -1049,23 +1060,31 @@ 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);
|
||||
add_to_sclist(MALL, "^F", do_right, 0, TRUE);
|
||||
add_to_sclist(MALL, "kright", do_right, 0, TRUE);
|
||||
add_to_sclist(MALL, "^B", do_left, 0, TRUE);
|
||||
add_to_sclist(MALL, "kleft", do_left, 0, TRUE);
|
||||
add_to_sclist(MMAIN, "^Space", do_next_word_void, 0, TRUE);
|
||||
add_to_sclist(MMAIN, "M-Space", do_prev_word_void, 0, TRUE);
|
||||
#endif
|
||||
add_to_sclist(MALL, "kright", do_right, 0, TRUE);
|
||||
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(MALL, "^P", do_up_void, 0, TRUE);
|
||||
add_to_sclist(MALL, "kup", do_up_void, 0, TRUE);
|
||||
add_to_sclist(MALL, "^N", do_down_void, 0, TRUE);
|
||||
add_to_sclist(MALL, "kdown", do_down_void, 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(MALL, "^A", do_home, 0, TRUE);
|
||||
add_to_sclist(MALL, "khome", do_home, 0, TRUE);
|
||||
add_to_sclist(MALL, "^E", do_end, 0, TRUE);
|
||||
add_to_sclist(MALL, "kend", do_end, 0, TRUE);
|
||||
#ifndef NANO_TINY
|
||||
add_to_sclist(MWHEREIS|MREPLACE|MREPLACE2|MWHEREISFILE, "^P", (void *) prev_history_msg, 0, FALSE);
|
||||
add_to_sclist(MWHEREIS|MREPLACE|MREPLACE2|MWHEREISFILE, "kup", (void *) prev_history_msg, 0, FALSE);
|
||||
add_to_sclist(MWHEREIS|MREPLACE|MREPLACE2|MWHEREISFILE, "^N", (void *) next_history_msg, 0, FALSE);
|
||||
add_to_sclist(MWHEREIS|MREPLACE|MREPLACE2|MWHEREISFILE, "kdown", (void *) next_history_msg, 0, FALSE);
|
||||
#endif
|
||||
#ifndef DISABLE_JUSTIFY
|
||||
add_to_sclist(MWHEREIS|MREPLACE|MREPLACE2,
|
||||
"^W", do_para_begin_void, 0, TRUE);
|
||||
@@ -1101,7 +1120,7 @@ void shortcut_init(bool unjustify)
|
||||
add_to_sclist(MBROWSER|MWHEREISFILE, "M-/", (void *) last_file_msg, 0, TRUE);
|
||||
add_to_sclist(MBROWSER|MWHEREISFILE, "M-?", (void *) last_file_msg, 0, TRUE);
|
||||
#ifndef NANO_TINY
|
||||
add_to_sclist(MMAIN, "M-[", do_find_bracket, 0, TRUE);
|
||||
add_to_sclist(MMAIN, "M-]", do_find_bracket, 0, TRUE);
|
||||
add_to_sclist(MMAIN, "M--", do_scroll_up, 0, TRUE);
|
||||
add_to_sclist(MMAIN, "M-_", do_scroll_up, 0, TRUE);
|
||||
add_to_sclist(MMAIN, "M-+", do_scroll_down, 0, TRUE);
|
||||
@@ -1321,6 +1340,10 @@ sc *strtosc(int menu, char *input)
|
||||
s->scfunc = do_find_bracket;
|
||||
else if (!strcasecmp(input, "wordcount"))
|
||||
s->scfunc = do_wordlinechar_count;
|
||||
else if (!strcasecmp(input, "undo"))
|
||||
s->scfunc = do_undo;
|
||||
else if (!strcasecmp(input, "redo"))
|
||||
s->scfunc = do_redo;
|
||||
else if (!strcasecmp(input, "prevhistory")) {
|
||||
s->scfunc = (void *) prev_history_msg;
|
||||
s->execute = FALSE;
|
||||
@@ -1424,6 +1447,8 @@ sc *strtosc(int menu, char *input)
|
||||
s->scfunc = do_enter;
|
||||
else if (!strcasecmp(input, "delete"))
|
||||
s->scfunc = do_delete;
|
||||
else if (!strcasecmp(input, "backspace"))
|
||||
s->scfunc = do_backspace;
|
||||
else if (!strcasecmp(input, "refresh"))
|
||||
s->scfunc = total_refresh;
|
||||
else if (!strcasecmp(input, "casesens")) {
|
||||
@@ -1564,15 +1589,6 @@ void thanks_for_all_the_fish(void)
|
||||
#ifndef DISABLE_JUSTIFY
|
||||
if (jusbuffer != NULL)
|
||||
free_filestruct(jusbuffer);
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
/* Free the memory associated with each toggle. */
|
||||
while (toggles != NULL) {
|
||||
toggle *t = toggles;
|
||||
|
||||
toggles = toggles->next;
|
||||
free(t);
|
||||
}
|
||||
#endif
|
||||
/* Free the memory associated with each open file buffer. */
|
||||
if (openfile != NULL)
|
||||
|
||||
@@ -414,7 +414,7 @@ void help_init(void)
|
||||
|
||||
for (s = sclist; s != NULL; s = s->next)
|
||||
if (s->scfunc == (void *) do_toggle)
|
||||
allocsize += strlen(flagtostr(s->toggle)) + endis_len + 9;
|
||||
allocsize += strlen(_(flagtostr(s->toggle))) + endis_len + 9;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
20
src/nano.c
20
src/nano.c
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $Id$ */
|
||||
/**************************************************************************
|
||||
* nano.c *
|
||||
* *
|
||||
@@ -32,7 +32,9 @@
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <locale.h>
|
||||
#ifdef ENABLE_UTF8
|
||||
#include <langinfo.h>
|
||||
#endif
|
||||
#include <termios.h>
|
||||
#ifdef HAVE_GETOPT_H
|
||||
#include <getopt.h>
|
||||
@@ -502,6 +504,9 @@ openfilestruct *make_new_opennode(void)
|
||||
newnode->filebot = NULL;
|
||||
newnode->edittop = NULL;
|
||||
newnode->current = NULL;
|
||||
#ifndef NANO_TINY
|
||||
newnode->last_action = OTHER;
|
||||
#endif
|
||||
|
||||
return newnode;
|
||||
}
|
||||
@@ -611,7 +616,7 @@ void die(const char *msg, ...)
|
||||
va_end(ap);
|
||||
|
||||
/* Save the current file buffer if it's been modified. */
|
||||
if (openfile->modified) {
|
||||
if (openfile && openfile->modified) {
|
||||
/* If we've partitioned the filestruct, unpartition it now. */
|
||||
if (filepart != NULL)
|
||||
unpartition_filestruct(&filepart);
|
||||
@@ -1250,7 +1255,7 @@ void do_toggle(int flag)
|
||||
)
|
||||
enabled = !enabled;
|
||||
|
||||
desc = flagtostr(flag);
|
||||
desc = _(flagtostr(flag));
|
||||
statusbar("%s %s", desc, enabled ? _("enabled") :
|
||||
_("disabled"));
|
||||
}
|
||||
@@ -1642,6 +1647,9 @@ void do_output(char *output, size_t output_len, bool allow_cntrls)
|
||||
set_modified();
|
||||
|
||||
#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 <
|
||||
@@ -2224,7 +2232,7 @@ int main(int argc, char **argv)
|
||||
icol == 1)
|
||||
parse_line_column(&argv[i][1], &iline, &icol);
|
||||
else {
|
||||
open_buffer(argv[i]);
|
||||
open_buffer(argv[i], FALSE);
|
||||
|
||||
if (iline > 1 || icol > 1) {
|
||||
do_gotolinecolumn(iline, icol, FALSE, FALSE, FALSE,
|
||||
@@ -2241,14 +2249,14 @@ int main(int argc, char **argv)
|
||||
* buffer or a new buffer, depending on whether multibuffer mode is
|
||||
* enabled. */
|
||||
if (optind < argc)
|
||||
open_buffer(argv[optind]);
|
||||
open_buffer(argv[optind], FALSE);
|
||||
|
||||
/* We didn't open any files if all the command line arguments were
|
||||
* invalid files like directories or if there were no command line
|
||||
* arguments given. In this case, we have to load a blank buffer.
|
||||
* Also, we unset view mode to allow editing. */
|
||||
if (openfile == NULL) {
|
||||
open_buffer("");
|
||||
open_buffer("", FALSE);
|
||||
UNSET(VIEW_MODE);
|
||||
}
|
||||
|
||||
|
||||
67
src/nano.h
67
src/nano.h
@@ -169,6 +169,10 @@ typedef enum {
|
||||
CONTROL, META, FKEY, RAW
|
||||
} function_type;
|
||||
|
||||
typedef enum {
|
||||
ADD, DEL, REPLACE, SPLIT, UNSPLIT, CUT, CUTTOEND, UNCUT, INSERT, OTHER
|
||||
} undo_type;
|
||||
|
||||
/* Structure types. */
|
||||
typedef struct filestruct {
|
||||
char *data;
|
||||
@@ -245,6 +249,40 @@ typedef struct syntaxtype {
|
||||
} syntaxtype;
|
||||
#endif /* ENABLE_COLOR */
|
||||
|
||||
#ifndef NANO_TINY
|
||||
typedef struct undo {
|
||||
ssize_t lineno;
|
||||
undo_type type;
|
||||
/* What type of undo was this */
|
||||
int begin;
|
||||
/* Where did this action begin or end */
|
||||
char *strdata;
|
||||
/* String type data we will use for ccopying the affected line back */
|
||||
int xflags;
|
||||
/* Some flag data we need */
|
||||
|
||||
/* Cut specific stuff we need */
|
||||
filestruct *cutbuffer;
|
||||
/* Copy of the cutbuffer */
|
||||
filestruct *cutbottom;
|
||||
/* Copy of cutbottom */
|
||||
bool mark_set;
|
||||
/* was the marker set when we cut */
|
||||
bool to_end;
|
||||
/* was this a cut to end */
|
||||
ssize_t mark_begin_lineno;
|
||||
/* copy copy copy */
|
||||
ssize_t mark_begin_x;
|
||||
/* Another shadow variable */
|
||||
ssize_t linescut;
|
||||
/* How many lines we cut on a straight non-marked non-to-end cut */
|
||||
struct undo *next;
|
||||
} undo;
|
||||
|
||||
|
||||
#endif /* NANO_TINY */
|
||||
|
||||
|
||||
typedef struct openfilestruct {
|
||||
char *filename;
|
||||
/* The current file's name. */
|
||||
@@ -278,6 +316,11 @@ typedef struct openfilestruct {
|
||||
/* The current file's format. */
|
||||
struct stat *current_stat;
|
||||
/* The current file's stat. */
|
||||
undo *undotop;
|
||||
/* Top of the undo list */
|
||||
undo *current_undo;
|
||||
/* The current (i.e. n ext) level of undo */
|
||||
undo_type last_action;
|
||||
#endif
|
||||
#ifdef ENABLE_COLOR
|
||||
colortype *colorstrings;
|
||||
@@ -318,25 +361,6 @@ typedef struct shortcut {
|
||||
/* Next shortcut. */
|
||||
} shortcut;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
typedef struct toggle {
|
||||
int val;
|
||||
/* The sequence to toggle the key. We should only need one. */
|
||||
const char *desc;
|
||||
/* The description of the toggle, e.g. "Cut to end"; we'll
|
||||
* append Enabled or Disabled to it. */
|
||||
#ifndef DISABLE_HELP
|
||||
bool blank_after;
|
||||
/* Whether there should be a blank line after the description of
|
||||
* the toggle. */
|
||||
#endif
|
||||
long flag;
|
||||
/* Which flag actually gets toggled. */
|
||||
struct toggle *next;
|
||||
/* Next toggle. */
|
||||
} toggle;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_NANORC
|
||||
typedef struct rcoption {
|
||||
const char *name;
|
||||
@@ -667,6 +691,11 @@ typedef struct subnfunc {
|
||||
#define TOGGLE_BACKWARDS_KEY NANO_META_B
|
||||
#define TOGGLE_DOS_KEY NANO_META_D
|
||||
#define TOGGLE_MAC_KEY NANO_META_M
|
||||
|
||||
/* Extra bits for the undo function */
|
||||
#define UNDO_DEL_DEL (1<<0)
|
||||
#define UNDO_DEL_BACKSPACE (1<<1)
|
||||
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
#define VIEW TRUE
|
||||
|
||||
@@ -1010,7 +1010,7 @@ fprintf(stderr, "get_prompt_string: answer = \"%s\", statusbar_x = %d\n", answer
|
||||
} else
|
||||
#endif /* !DISABLE_TABCOMP */
|
||||
#ifndef NANO_TINY
|
||||
if (s && s->scfunc == do_up_void) {
|
||||
if (s && s->scfunc == (void *) prev_history_msg) {
|
||||
if (history_list != NULL) {
|
||||
/* If we're scrolling up at the bottom of the
|
||||
* history list and answer isn't blank, save answer
|
||||
@@ -1038,7 +1038,7 @@ fprintf(stderr, "get_prompt_string: answer = \"%s\", statusbar_x = %d\n", answer
|
||||
* statusbar prompt. */
|
||||
finished = FALSE;
|
||||
}
|
||||
} else if (s && s->scfunc == do_down_void) {
|
||||
} else if (s && s->scfunc == (void *) next_history_msg) {
|
||||
if (history_list != NULL) {
|
||||
/* Get the newer search from the history list and
|
||||
* save it in answer. If there is no newer search,
|
||||
|
||||
23
src/proto.h
23
src/proto.h
@@ -47,6 +47,7 @@ extern WINDOW *bottomwin;
|
||||
extern int editwinrows;
|
||||
|
||||
extern filestruct *cutbuffer;
|
||||
extern filestruct *cutbottom;
|
||||
#ifndef DISABLE_JUSTIFY
|
||||
extern filestruct *jusbuffer;
|
||||
#endif
|
||||
@@ -60,6 +61,7 @@ extern char *matchbrackets;
|
||||
#if !defined(NANO_TINY) && defined(ENABLE_NANORC)
|
||||
extern char *whitespace;
|
||||
extern int whitespace_len[2];
|
||||
extern undo_type last_action;
|
||||
#endif
|
||||
|
||||
#ifndef DISABLE_JUSTIFY
|
||||
@@ -100,9 +102,6 @@ extern char *syntaxstr;
|
||||
|
||||
extern const shortcut *currshortcut;
|
||||
extern int currmenu;
|
||||
#ifndef NANO_TINY
|
||||
extern toggle *toggles;
|
||||
#endif
|
||||
|
||||
#ifndef NANO_TINY
|
||||
extern filestruct *search_history;
|
||||
@@ -240,7 +239,7 @@ void cut_to_eof(void);
|
||||
#endif
|
||||
void do_cut_text(
|
||||
#ifndef NANO_TINY
|
||||
bool copy_text, bool cut_till_end
|
||||
bool copy_text, bool cut_till_end, bool undoing
|
||||
#else
|
||||
void
|
||||
#endif
|
||||
@@ -256,7 +255,7 @@ void do_uncut_text(void);
|
||||
void make_new_buffer(void);
|
||||
void initialize_buffer(void);
|
||||
void initialize_buffer_text(void);
|
||||
void open_buffer(const char *filename);
|
||||
void open_buffer(const char *filename, bool undoable);
|
||||
#ifndef DISABLE_SPELLER
|
||||
void replace_buffer(const char *filename);
|
||||
#endif
|
||||
@@ -269,7 +268,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);
|
||||
void read_file(FILE *f, 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(
|
||||
@@ -619,6 +618,8 @@ void do_tab(void);
|
||||
void do_indent(ssize_t cols);
|
||||
void do_indent_void(void);
|
||||
void do_unindent(void);
|
||||
void do_undo(void);
|
||||
void do_redo(void);
|
||||
#endif
|
||||
void do_enter(void);
|
||||
#ifndef NANO_TINY
|
||||
@@ -632,7 +633,7 @@ bool do_wrap(filestruct *line);
|
||||
#if !defined(DISABLE_HELP) || !defined(DISABLE_WRAPJUSTIFY)
|
||||
ssize_t break_line(const char *line, ssize_t goal
|
||||
#ifndef DISABLE_HELP
|
||||
, bool newline
|
||||
, bool newln
|
||||
#endif
|
||||
);
|
||||
#endif
|
||||
@@ -706,8 +707,11 @@ void new_magicline(void);
|
||||
void remove_magicline(void);
|
||||
void mark_order(const filestruct **top, size_t *top_x, const filestruct
|
||||
**bot, size_t *bot_x, bool *right_side_up);
|
||||
void add_undo(undo_type current_action);
|
||||
void update_undo(undo_type action);
|
||||
#endif
|
||||
size_t get_totsize(const filestruct *begin, const filestruct *end);
|
||||
filestruct *fsfromline(ssize_t lineno);
|
||||
#ifdef DEBUG
|
||||
void dump_filestruct(const filestruct *inptr);
|
||||
void dump_filestruct_reverse(void);
|
||||
@@ -739,9 +743,6 @@ int get_mouseinput(int *mouse_x, int *mouse_y, bool allow_shortcuts);
|
||||
const sc *get_shortcut(int menu, int *kbinput, bool
|
||||
*meta_key, bool *func_key);
|
||||
const sc *first_sc_for(int menu, void *func);
|
||||
#ifndef NANO_TINY
|
||||
const toggle *get_toggle(int kbinput, bool meta_key);
|
||||
#endif
|
||||
void blank_line(WINDOW *win, int y, int x, int n);
|
||||
void blank_titlebar(void);
|
||||
void blank_topbar(void);
|
||||
@@ -788,6 +789,8 @@ const char *cancel_msg;
|
||||
#ifndef NANO_TINY
|
||||
const char *case_sens_msg;
|
||||
const char *backwards_msg;
|
||||
const char *prev_history_msg;
|
||||
const char *next_history_msg;
|
||||
#endif
|
||||
const char *replace_msg;
|
||||
const char *no_replace_msg;
|
||||
|
||||
87
src/rcfile.c
87
src/rcfile.c
@@ -347,6 +347,20 @@ void parse_syntax(char *ptr)
|
||||
}
|
||||
}
|
||||
|
||||
int check_bad_binding(sc *s)
|
||||
{
|
||||
#define BADLISTLEN 1
|
||||
int badtypes[BADLISTLEN] = {META};
|
||||
int badseqs[BADLISTLEN] = { 91 };
|
||||
int i;
|
||||
|
||||
for (i = 0; i < BADLISTLEN; i++)
|
||||
if (s->type == badtypes[i] && s->seq == badseqs[i])
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void parse_keybinding(char *ptr)
|
||||
{
|
||||
char *keyptr = NULL, *keycopy = NULL, *funcptr = NULL, *menuptr = NULL;
|
||||
@@ -366,7 +380,7 @@ void parse_keybinding(char *ptr)
|
||||
for (i = 0; i < strlen(keycopy); i++)
|
||||
keycopy[i] = toupper(keycopy[i]);
|
||||
|
||||
if (keycopy[0] != 'M' && keycopy[0] != '^' && keycopy[0] != 'F') {
|
||||
if (keycopy[0] != 'M' && keycopy[0] != '^' && keycopy[0] != 'F' && keycopy[0] != 'K') {
|
||||
rcfile_error(
|
||||
N_("keybindings must begin with \"^\", \"M\", or \"F\"\n"));
|
||||
return;
|
||||
@@ -405,9 +419,11 @@ void parse_keybinding(char *ptr)
|
||||
N_("Could not map name \"%s\" to a function\n"), funcptr);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "newsc now address %d, menu func assigned = %d, menu = %d\n",
|
||||
(int) newsc, (int) newsc->scfunc, menu);
|
||||
&newsc, &newsc->scfunc, menu);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -420,6 +436,13 @@ void parse_keybinding(char *ptr)
|
||||
fprintf(stderr, "s->seq = \"%d\"\n", newsc->seq);
|
||||
#endif
|
||||
|
||||
if (check_bad_binding(newsc)) {
|
||||
rcfile_error(
|
||||
N_("Sorry, keystr \"%s\" is an illegal binding\n"), 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 */
|
||||
@@ -478,6 +501,10 @@ void parse_include(char *ptr)
|
||||
nanorc = full_option;
|
||||
lineno = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Parsing file \"%s\"\n", full_option);
|
||||
#endif
|
||||
|
||||
parse_rcfile(rcstream
|
||||
#ifdef ENABLE_COLOR
|
||||
, TRUE
|
||||
@@ -690,6 +717,32 @@ void parse_colors(char *ptr, bool icase)
|
||||
}
|
||||
#endif /* ENABLE_COLOR */
|
||||
|
||||
/* Check whether the user has unmapped every shortcut for a
|
||||
sequence we consider 'vital', like the exit function */
|
||||
static void check_vitals_mapped(void)
|
||||
{
|
||||
subnfunc *f;
|
||||
int v;
|
||||
#define VITALS 5
|
||||
void *vitals[VITALS] = { do_exit, do_exit, (void *) cancel_msg, (void *) cancel_msg, (void *) cancel_msg };
|
||||
int inmenus[VITALS] = { MMAIN, MHELP, MWHEREIS, MREPLACE, MGOTOLINE };
|
||||
|
||||
for (v = 0; v < VITALS; v++) {
|
||||
for (f = allfuncs; f != NULL; f = f->next) {
|
||||
if (f->scfunc == vitals[v] && f->menus & inmenus[v]) {
|
||||
const sc *s = first_sc_for(inmenus[v], f->scfunc);
|
||||
if (!s) {
|
||||
rcfile_error(N_("Fatal error: no keys mapped for function \"%s\""),
|
||||
f->desc);
|
||||
fprintf(stderr, N_("Exiting. Please use nano with the -I option if needed to adjust your nanorc settings\n"));
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse the rcfile, once it has been opened successfully at rcstream,
|
||||
* and close it afterwards. If syntax_only is TRUE, only allow the file
|
||||
* to contain color syntax commands: syntax, color, and icolor. */
|
||||
@@ -965,6 +1018,10 @@ void do_rcfile(void)
|
||||
_("\"%s\" is a device file"), nanorc);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Parsing file \"%s\"\n", nanorc);
|
||||
#endif
|
||||
|
||||
/* Try to open the system-wide nanorc. */
|
||||
rcstream = fopen(nanorc, "rb");
|
||||
if (rcstream != NULL)
|
||||
@@ -1022,30 +1079,4 @@ void do_rcfile(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Check whether the user has unmapped every shortcut for a
|
||||
sequence we consider 'vital', like the exit function */
|
||||
int check_vitals_mapped(void)
|
||||
{
|
||||
subnfunc *f;
|
||||
int v;
|
||||
#define VITALS 5
|
||||
void *vitals[VITALS] = { do_exit, do_exit, (void *) cancel_msg, (void *) cancel_msg, (void *) cancel_msg };
|
||||
int inmenus[VITALS] = { MMAIN, MHELP, MWHEREIS, MREPLACE, MGOTOLINE };
|
||||
|
||||
for (v = 0; v < VITALS; v++) {
|
||||
for (f = allfuncs; f != NULL; f = f->next) {
|
||||
if (f->scfunc == vitals[v] && f->menus & inmenus[v]) {
|
||||
const sc *s = first_sc_for(inmenus[v], f->scfunc);
|
||||
if (!s) {
|
||||
rcfile_error(N_("Fatal error: no keys mapped for function \"%s\""),
|
||||
f->desc);
|
||||
fprintf(stderr, N_("Exiting. Please use nano with the -I option if needed to adjust your nanorc settings\n"));
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* ENABLE_NANORC */
|
||||
|
||||
@@ -788,6 +788,9 @@ ssize_t do_replace_loop(
|
||||
char *copy;
|
||||
size_t length_change;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
update_undo(REPLACE);
|
||||
#endif
|
||||
if (i == 2)
|
||||
replaceall = TRUE;
|
||||
|
||||
|
||||
538
src/text.c
538
src/text.c
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $Id$ */
|
||||
/**************************************************************************
|
||||
* text.c *
|
||||
* *
|
||||
@@ -70,6 +70,10 @@ void do_delete(void)
|
||||
/* Do we have to call edit_refresh(), or can we get away with
|
||||
* just update_line()? */
|
||||
|
||||
#ifndef NANO_TINY
|
||||
update_undo(DEL);
|
||||
#endif
|
||||
|
||||
assert(openfile->current != NULL && openfile->current->data != NULL && openfile->current_x <= strlen(openfile->current->data));
|
||||
|
||||
openfile->placewewant = xplustabs();
|
||||
@@ -359,6 +363,284 @@ void do_unindent(void)
|
||||
{
|
||||
do_indent(-tabsize);
|
||||
}
|
||||
|
||||
/* Undo the last thing(s) we did */
|
||||
void do_undo(void)
|
||||
{
|
||||
undo *u = openfile->current_undo;
|
||||
filestruct *f = openfile->current, *t;
|
||||
int len = 0;
|
||||
char *undidmsg, *data;
|
||||
filestruct *oldcutbuffer = cutbuffer, *oldcutbottom = cutbottom;
|
||||
|
||||
if (!u) {
|
||||
statusbar(_("Nothing in undo buffer!"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (u->lineno <= f->lineno)
|
||||
for (; f->prev != NULL && f->lineno != u->lineno; f = f->prev)
|
||||
;
|
||||
else
|
||||
for (; f->next != NULL && f->lineno != u->lineno; f = f->next)
|
||||
;
|
||||
if (f->lineno != u->lineno) {
|
||||
statusbar(_("Couldnt match current undo line"));
|
||||
return;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "data we're about to undo = \"%s\"\n", f->data);
|
||||
fprintf(stderr, "Undo running for type %d\n", u->type);
|
||||
#endif
|
||||
|
||||
openfile->current_x = u->begin;
|
||||
switch(u->type) {
|
||||
case ADD:
|
||||
undidmsg = _("text add");
|
||||
len = strlen(f->data) - strlen(u->strdata) + 1;
|
||||
data = charalloc(len);
|
||||
strncpy(data, f->data, u->begin);
|
||||
strcpy(&data[u->begin], &f->data[u->begin + strlen(u->strdata)]);
|
||||
free(f->data);
|
||||
f->data = data;
|
||||
break;
|
||||
case DEL:
|
||||
undidmsg = _("text delete");
|
||||
len = strlen(f->data) + strlen(u->strdata) + 1;
|
||||
data = charalloc(len);
|
||||
|
||||
strncpy(data, f->data, u->begin);
|
||||
strcpy(&data[u->begin], u->strdata);
|
||||
strcpy(&data[u->begin + strlen(u->strdata)], &f->data[u->begin]);
|
||||
free(f->data);
|
||||
f->data = data;
|
||||
if (u->xflags == UNDO_DEL_BACKSPACE)
|
||||
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);
|
||||
}
|
||||
renumber(f);
|
||||
break;
|
||||
case UNSPLIT:
|
||||
undidmsg = _("line join");
|
||||
t = make_new_node(f);
|
||||
t->data = mallocstrcpy(NULL, u->strdata);
|
||||
data = mallocstrncpy(NULL, f->data, u->begin);
|
||||
data[u->begin] = '\0';
|
||||
free(f->data);
|
||||
f->data = data;
|
||||
splice_node(f, t, f->next);
|
||||
renumber(f);
|
||||
break;
|
||||
case CUT:
|
||||
case CUTTOEND:
|
||||
undidmsg = _("text cut");
|
||||
cutbuffer = copy_filestruct(u->cutbuffer);
|
||||
|
||||
/* Compute cutbottom for the uncut using out copy */
|
||||
for (cutbottom = cutbuffer; cutbottom->next != NULL; cutbottom = cutbottom->next)
|
||||
;
|
||||
|
||||
/* 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);
|
||||
|
||||
do_uncut_text();
|
||||
free_filestruct(cutbuffer);
|
||||
cutbuffer = NULL;
|
||||
break;
|
||||
case INSERT:
|
||||
undidmsg = _("text insert");
|
||||
cutbuffer = NULL;
|
||||
cutbottom = NULL;
|
||||
/* When we updated mark_begin_lineno in update_undo, it was effectively how many line
|
||||
were inserted due to being partitioned before read_file was called. So we
|
||||
add its value here */
|
||||
openfile->mark_begin = fsfromline(u->lineno + u->mark_begin_lineno - 1);
|
||||
openfile->mark_begin_x = 0;
|
||||
openfile->mark_set = TRUE;
|
||||
do_gotolinecolumn(u->lineno, u->begin+1, FALSE, FALSE, FALSE, FALSE);
|
||||
cut_marked();
|
||||
u->cutbuffer = cutbuffer;
|
||||
u->cutbottom = cutbottom;
|
||||
cutbuffer = oldcutbuffer;
|
||||
cutbottom = oldcutbottom;
|
||||
openfile->mark_set = FALSE;
|
||||
break;
|
||||
case REPLACE:
|
||||
undidmsg = _("text replace");
|
||||
data = u->strdata;
|
||||
u->strdata = f->data;
|
||||
f->data = data;
|
||||
break;
|
||||
default:
|
||||
undidmsg = _("wtf?");
|
||||
break;
|
||||
|
||||
}
|
||||
do_gotolinecolumn(u->lineno, u->begin, FALSE, FALSE, FALSE, TRUE);
|
||||
statusbar(_("Undid action (%s)"), undidmsg);
|
||||
openfile->current_undo = openfile->current_undo->next;
|
||||
openfile->last_action = OTHER;
|
||||
}
|
||||
|
||||
void do_redo(void)
|
||||
{
|
||||
undo *u = openfile->undotop;
|
||||
filestruct *f = openfile->current, *t;
|
||||
filestruct *oldcutbuffer = cutbuffer, *oldcutbottom = cutbottom;
|
||||
int len = 0, i;
|
||||
char *undidmsg, *data;
|
||||
|
||||
for (; u != NULL && u->next != openfile->current_undo; u = u->next)
|
||||
;
|
||||
if (!u) {
|
||||
statusbar(_("Nothing to re-do!"));
|
||||
return;
|
||||
}
|
||||
if (u->next != openfile->current_undo) {
|
||||
statusbar(_("Can't find previous undo to re-do, argh"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (u->lineno <= f->lineno)
|
||||
for (; f->prev != NULL && f->lineno != u->lineno; f = f->prev)
|
||||
;
|
||||
else
|
||||
for (; f->next != NULL && f->lineno != u->lineno; f = f->next)
|
||||
;
|
||||
if (f->lineno != u->lineno) {
|
||||
statusbar(_("Couldnt match current undo line"));
|
||||
return;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "data we're about to redo = \"%s\"\n", f->data);
|
||||
fprintf(stderr, "Redo running for type %d\n", u->type);
|
||||
#endif
|
||||
|
||||
switch(u->type) {
|
||||
case ADD:
|
||||
undidmsg = _("text add");
|
||||
len = strlen(f->data) + strlen(u->strdata) + 1;
|
||||
data = charalloc(len);
|
||||
strncpy(data, f->data, u->begin);
|
||||
strcpy(&data[u->begin], u->strdata);
|
||||
strcpy(&data[u->begin + strlen(u->strdata)], &f->data[u->begin]);
|
||||
free(f->data);
|
||||
f->data = data;
|
||||
break;
|
||||
case DEL:
|
||||
undidmsg = _("text delete");
|
||||
len = strlen(f->data) + strlen(u->strdata) + 1;
|
||||
data = charalloc(len);
|
||||
strncpy(data, f->data, u->begin);
|
||||
strcpy(&data[u->begin], &f->data[u->begin + strlen(u->strdata)]);
|
||||
free(f->data);
|
||||
f->data = data;
|
||||
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);
|
||||
renumber(f);
|
||||
break;
|
||||
case UNSPLIT:
|
||||
undidmsg = _("line join");
|
||||
len = strlen(f->data) + strlen(u->strdata + 1);
|
||||
data = charalloc(len);
|
||||
strcpy(data, f->data);
|
||||
strcat(data, u->strdata);
|
||||
free(f->data);
|
||||
f->data = data;
|
||||
if (f->next != NULL) {
|
||||
filestruct *tmp = f->next;
|
||||
unlink_node(tmp);
|
||||
delete_node(tmp);
|
||||
}
|
||||
renumber(f);
|
||||
break;
|
||||
case CUT:
|
||||
case CUTTOEND:
|
||||
undidmsg = _("line cut");
|
||||
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 */
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Undoing multi-^K cut, u->linescut = %d\n", u->linescut);
|
||||
#endif
|
||||
for (i = 0, t = openfile->current; i < u->linescut; i++) {
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Advancing, lineno = %d, data = \"%s\"\n", t->lineno, t->data);
|
||||
#endif
|
||||
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();
|
||||
break;
|
||||
case REPLACE:
|
||||
undidmsg = _("text replace");
|
||||
data = u->strdata;
|
||||
u->strdata = f->data;
|
||||
f->data = data;
|
||||
break;
|
||||
case INSERT:
|
||||
undidmsg = _("text insert");
|
||||
cutbuffer = u->cutbuffer;
|
||||
cutbottom = u->cutbottom;
|
||||
do_gotolinecolumn(u->lineno, u->begin+1, FALSE, FALSE, FALSE, FALSE);
|
||||
do_uncut_text();
|
||||
cutbuffer = oldcutbuffer;
|
||||
cutbottom = oldcutbottom;
|
||||
break;
|
||||
default:
|
||||
undidmsg = _("wtf?");
|
||||
break;
|
||||
|
||||
}
|
||||
do_gotolinecolumn(u->lineno, u->begin, FALSE, FALSE, FALSE, TRUE);
|
||||
statusbar(_("Redid action (%s)"), undidmsg);
|
||||
|
||||
openfile->current_undo = u;
|
||||
openfile->last_action = OTHER;
|
||||
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
/* Someone hits Enter *gasp!* */
|
||||
@@ -367,9 +649,12 @@ void do_enter(void)
|
||||
filestruct *newnode = make_new_node(openfile->current);
|
||||
size_t extra = 0;
|
||||
|
||||
assert(openfile->current != NULL && openfile->current->data != NULL);
|
||||
assert(openfile->current != NULL && xopenfile->current->data != NULL);
|
||||
|
||||
#ifndef NANO_TINY
|
||||
update_undo(SPLIT);
|
||||
|
||||
|
||||
/* Do auto-indenting, like the neolithic Turbo Pascal editor. */
|
||||
if (ISSET(AUTOINDENT)) {
|
||||
/* If we are breaking the line in the indentation, the new
|
||||
@@ -495,7 +780,7 @@ bool execute_command(const char *command)
|
||||
if (f == NULL)
|
||||
nperror("fdopen");
|
||||
|
||||
read_file(f, "stdin");
|
||||
read_file(f, "stdin", TRUE);
|
||||
|
||||
if (wait(NULL) == -1)
|
||||
nperror("wait");
|
||||
@@ -510,6 +795,223 @@ bool execute_command(const char *command)
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Add a new undo struct to the top of the current pile */
|
||||
void add_undo(undo_type current_action)
|
||||
{
|
||||
undo *u;
|
||||
char *data;
|
||||
openfilestruct *fs = openfile;
|
||||
|
||||
/* Ugh, if we were called while cutting not-to-end, non-marked and on the same lineno,
|
||||
we need to abort here */
|
||||
u = fs->current_undo;
|
||||
if (current_action == CUT && u && u->type == CUT
|
||||
&& !u->mark_set && u->lineno == fs->current->lineno)
|
||||
return;
|
||||
|
||||
/* Blow away the old undo stack if we are starting from the middle */
|
||||
while (fs->undotop != NULL && fs->undotop != fs->current_undo) {
|
||||
undo *u2 = fs->undotop;
|
||||
fs->undotop = fs->undotop->next;
|
||||
if (u2->strdata != NULL)
|
||||
free(u2->strdata);
|
||||
if (u2->cutbuffer)
|
||||
free_filestruct(u2->cutbuffer);
|
||||
free(u2);
|
||||
}
|
||||
|
||||
/* Allocate and initialize a new undo type */
|
||||
u = nmalloc(sizeof(undo));
|
||||
u->type = current_action;
|
||||
u->lineno = fs->current->lineno;
|
||||
u->begin = fs->current_x;
|
||||
u->next = fs->undotop;
|
||||
fs->undotop = u;
|
||||
fs->current_undo = u;
|
||||
u->strdata = NULL;
|
||||
u->cutbuffer = NULL;
|
||||
u->cutbottom = NULL;
|
||||
u->mark_begin_lineno = 0;
|
||||
u->mark_begin_x = 0;
|
||||
u->linescut = 0;
|
||||
u->xflags = 0;
|
||||
|
||||
switch (u->type) {
|
||||
/* We need to start copying data into the undo buffer or we wont be able
|
||||
to restore it later */
|
||||
case ADD:
|
||||
data = charalloc(2);
|
||||
data[0] = fs->current->data[fs->current_x];
|
||||
data[1] = '\0';
|
||||
u->strdata = data;
|
||||
break;
|
||||
case DEL:
|
||||
if (u->begin != strlen(fs->current->data)) {
|
||||
data = mallocstrncpy(NULL, &fs->current->data[u->begin], 2);
|
||||
data[1] = '\0';
|
||||
u->strdata = data;
|
||||
break;
|
||||
}
|
||||
/* Else purposely fall into unsplit code */
|
||||
current_action = u->type = UNSPLIT;
|
||||
case UNSPLIT:
|
||||
if (fs->current->next) {
|
||||
data = mallocstrcpy(NULL, fs->current->next->data);
|
||||
u->strdata = data;
|
||||
}
|
||||
break;
|
||||
case INSERT:
|
||||
case SPLIT:
|
||||
case REPLACE:
|
||||
data = mallocstrcpy(NULL, fs->current->data);
|
||||
u->strdata = data;
|
||||
break;
|
||||
case CUT:
|
||||
case CUTTOEND:
|
||||
u->mark_set = openfile->mark_set;
|
||||
if (u->mark_set) {
|
||||
u->mark_begin_lineno = openfile->mark_begin->lineno;
|
||||
u->mark_begin_x = openfile->mark_begin_x;
|
||||
}
|
||||
u->to_end = (current_action == CUTTOEND);
|
||||
break;
|
||||
case UNCUT:
|
||||
break;
|
||||
case OTHER:
|
||||
statusbar(_("OOPS. Tried to add unknown thing to undo struct, I'd 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");
|
||||
#endif
|
||||
fs->last_action = current_action;
|
||||
}
|
||||
|
||||
/* Update an undo item, or determine whether a new one
|
||||
is really needed and bounce the data to add_undo
|
||||
instead. The latter functionality just feels
|
||||
gimmicky and may just be more hassle than
|
||||
it's worth, so it should be axed if needed. */
|
||||
void update_undo(undo_type action)
|
||||
{
|
||||
undo *u;
|
||||
char *data;
|
||||
int len = 0;
|
||||
openfilestruct *fs = openfile;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "action = %d, fs->last_action = %d, openfile->current->lineno = %d",
|
||||
action, fs->last_action, openfile->current->lineno);
|
||||
if (fs->current_undo)
|
||||
fprintf(stderr, "fs->current_undo->lineno = %d\n", fs->current_undo->lineno);
|
||||
else
|
||||
fprintf(stderr, "\n");
|
||||
#endif
|
||||
|
||||
/* 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 != CUTTOEND && action != INSERT
|
||||
&& openfile->current->lineno != fs->current_undo->lineno)) {
|
||||
add_undo(action);
|
||||
return;
|
||||
}
|
||||
|
||||
assert(fs->undotop != NULL);
|
||||
u = fs->undotop;
|
||||
|
||||
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);
|
||||
#endif
|
||||
len = strlen(u->strdata) + 2;
|
||||
data = nrealloc((void *) u->strdata, len * sizeof(char *));
|
||||
data[len-2] = fs->current->data[fs->current_x];
|
||||
data[len-1] = '\0';
|
||||
u->strdata = (char *) data;
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "current undo data now \"%s\"\n", u->strdata);
|
||||
#endif
|
||||
break;
|
||||
case DEL:
|
||||
len = strlen(u->strdata) + 2;
|
||||
assert(len > 2);
|
||||
if (fs->current_x == u->begin) {
|
||||
/* They're deleting */
|
||||
if (!u->xflags)
|
||||
u->xflags = UNDO_DEL_DEL;
|
||||
else if (u->xflags != UNDO_DEL_DEL) {
|
||||
add_undo(action);
|
||||
return;
|
||||
}
|
||||
data = charalloc(len);
|
||||
strcpy(data, u->strdata);
|
||||
data[len-2] = fs->current->data[fs->current_x];;
|
||||
data[len-1] = '\0';
|
||||
free(u->strdata);
|
||||
u->strdata = data;
|
||||
} else if (fs->current_x == u->begin - 1) {
|
||||
/* They're backspacing */
|
||||
if (!u->xflags)
|
||||
u->xflags = UNDO_DEL_BACKSPACE;
|
||||
else if (u->xflags != UNDO_DEL_BACKSPACE) {
|
||||
add_undo(action);
|
||||
return;
|
||||
}
|
||||
data = charalloc(len);
|
||||
data[0] = fs->current->data[fs->current_x];
|
||||
strcpy(&data[1], u->strdata);
|
||||
free(u->strdata);
|
||||
u->strdata = data;
|
||||
u->begin--;
|
||||
} else {
|
||||
/* They deleted something else on the line */
|
||||
add_undo(DEL);
|
||||
return;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "current undo data now \"%s\"\nu->begin = %d\n", u->strdata, u->begin);
|
||||
#endif
|
||||
break;
|
||||
case CUT:
|
||||
case CUTTOEND:
|
||||
case UNCUT:
|
||||
if (u->cutbuffer)
|
||||
free(u->cutbuffer);
|
||||
u->cutbuffer = copy_filestruct(cutbuffer);
|
||||
u->cutbottom = cutbottom;
|
||||
u->linescut++;
|
||||
break;
|
||||
case REPLACE:
|
||||
add_undo(action);
|
||||
break;
|
||||
case INSERT:
|
||||
u->mark_begin_lineno = openfile->current->lineno;
|
||||
case SPLIT:
|
||||
case UNSPLIT:
|
||||
/* These cases are handled by the earlier check for a new line and action */
|
||||
case OTHER:
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Done in udpate_undo (type was %d)\n", action);
|
||||
#endif
|
||||
if (fs->last_action != action) {
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Starting add_undo for new action as it does not match last_action\n");
|
||||
#endif
|
||||
add_undo(action);
|
||||
}
|
||||
fs->last_action = action;
|
||||
}
|
||||
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
#ifndef DISABLE_WRAPPING
|
||||
@@ -761,7 +1263,7 @@ bool do_wrap(filestruct *line)
|
||||
* blank, as does a '\n' if newline is TRUE. */
|
||||
ssize_t break_line(const char *line, ssize_t goal
|
||||
#ifndef DISABLE_HELP
|
||||
, bool newline
|
||||
, bool newln
|
||||
#endif
|
||||
)
|
||||
{
|
||||
@@ -781,13 +1283,13 @@ ssize_t break_line(const char *line, ssize_t goal
|
||||
|
||||
if (is_blank_mbchar(line)
|
||||
#ifndef DISABLE_HELP
|
||||
|| (newline && *line == '\n')
|
||||
|| (newln && *line == '\n')
|
||||
#endif
|
||||
) {
|
||||
blank_loc = cur_loc;
|
||||
|
||||
#ifndef DISABLE_HELP
|
||||
if (newline && *line == '\n')
|
||||
if (newln && *line == '\n')
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
@@ -800,6 +1302,15 @@ ssize_t break_line(const char *line, ssize_t goal
|
||||
/* In fact, the whole line displays shorter than goal. */
|
||||
return cur_loc;
|
||||
|
||||
#ifndef DISABLE_HELP
|
||||
if (newln && blank_loc <= 0) {
|
||||
/* If blank was not found or was found only first character,
|
||||
* force line break. */
|
||||
cur_loc -= line_len;
|
||||
return cur_loc;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (blank_loc == -1) {
|
||||
/* No blank was found that was short enough. */
|
||||
bool found_blank = FALSE;
|
||||
@@ -810,7 +1321,7 @@ ssize_t break_line(const char *line, ssize_t goal
|
||||
|
||||
if (is_blank_mbchar(line)
|
||||
#ifndef DISABLE_HELP
|
||||
|| (newline && *line == '\n')
|
||||
|| (newln && *line == '\n')
|
||||
#endif
|
||||
) {
|
||||
if (!found_blank)
|
||||
@@ -834,11 +1345,11 @@ ssize_t break_line(const char *line, ssize_t goal
|
||||
|
||||
while (*line != '\0' && (is_blank_mbchar(line)
|
||||
#ifndef DISABLE_HELP
|
||||
|| (newline && *line == '\n')
|
||||
|| (newln && *line == '\n')
|
||||
#endif
|
||||
)) {
|
||||
#ifndef DISABLE_HELP
|
||||
if (newline && *line == '\n')
|
||||
if (newln && *line == '\n')
|
||||
break;
|
||||
#endif
|
||||
|
||||
@@ -2365,7 +2876,7 @@ void do_spell(void)
|
||||
void do_wordlinechar_count(void)
|
||||
{
|
||||
size_t words = 0, chars = 0;
|
||||
ssize_t lines = 0;
|
||||
ssize_t nlines = 0;
|
||||
size_t current_x_save = openfile->current_x;
|
||||
size_t pww_save = openfile->placewewant;
|
||||
filestruct *current_save = openfile->current;
|
||||
@@ -2400,7 +2911,7 @@ void do_wordlinechar_count(void)
|
||||
/* Get the total line and character counts, as "wc -l" and "wc -c"
|
||||
* do, but get the latter in multibyte characters. */
|
||||
if (old_mark_set) {
|
||||
lines = openfile->filebot->lineno -
|
||||
nlines = openfile->filebot->lineno -
|
||||
openfile->fileage->lineno + 1;
|
||||
chars = get_totsize(openfile->fileage, openfile->filebot);
|
||||
|
||||
@@ -2409,7 +2920,7 @@ void do_wordlinechar_count(void)
|
||||
unpartition_filestruct(&filepart);
|
||||
openfile->mark_set = TRUE;
|
||||
} else {
|
||||
lines = openfile->filebot->lineno;
|
||||
nlines = openfile->filebot->lineno;
|
||||
chars = openfile->totsize;
|
||||
}
|
||||
|
||||
@@ -2421,7 +2932,7 @@ void do_wordlinechar_count(void)
|
||||
/* Display the total word, line, and character counts on the
|
||||
* statusbar. */
|
||||
statusbar(_("%sWords: %lu Lines: %ld Chars: %lu"), old_mark_set ?
|
||||
_("In Selection: ") : "", (unsigned long)words, (long)lines,
|
||||
_("In Selection: ") : "", (unsigned long)words, (long)nlines,
|
||||
(unsigned long)chars);
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
@@ -2464,3 +2975,4 @@ void do_verbatim_input(void)
|
||||
|
||||
free(output);
|
||||
}
|
||||
|
||||
|
||||
17
src/utils.c
17
src/utils.c
@@ -586,6 +586,23 @@ size_t get_totsize(const filestruct *begin, const filestruct *end)
|
||||
return totsize;
|
||||
}
|
||||
|
||||
/* Get back a pointer given a line number in the current openfilestruct */
|
||||
filestruct *fsfromline(ssize_t lineno)
|
||||
{
|
||||
filestruct *f = openfile->current;
|
||||
|
||||
if (lineno <= openfile->current->lineno)
|
||||
for (; f->lineno != lineno && f != openfile->fileage; f = f->prev)
|
||||
;
|
||||
else
|
||||
for (; f->lineno != lineno && f->next != NULL; f = f->next)
|
||||
;
|
||||
|
||||
if (f->lineno != lineno)
|
||||
f = NULL;
|
||||
return f;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
/* Dump the filestruct inptr to stderr. */
|
||||
void dump_filestruct(const filestruct *inptr)
|
||||
|
||||
@@ -329,7 +329,6 @@ int parse_kbinput(WINDOW *win, bool *meta_key, bool *func_key)
|
||||
|
||||
*meta_key = FALSE;
|
||||
*func_key = FALSE;
|
||||
const sc *s;
|
||||
|
||||
/* Read in a character. */
|
||||
while ((kbinput = get_input(win, 1)) == NULL);
|
||||
|
||||
Reference in New Issue
Block a user