Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1658d4d14f | ||
|
|
5cf95c45d3 | ||
|
|
56a295bc90 | ||
|
|
803379c52c | ||
|
|
4522ca2d1b | ||
|
|
fd265af15a | ||
|
|
58a802fa63 | ||
|
|
364763f4d1 | ||
|
|
ecc245ccca | ||
|
|
61f5c55f7b | ||
|
|
30f278f4a8 | ||
|
|
75dfa8ad42 | ||
|
|
b0f0b7f471 | ||
|
|
25d459aa64 | ||
|
|
2d90cf324e | ||
|
|
2d1bdd0dd6 | ||
|
|
2823c99e72 | ||
|
|
019998a877 | ||
|
|
d47d8cd450 | ||
|
|
0dc26dcd09 | ||
|
|
a117163a4c | ||
|
|
4630102f5b |
4
BUGS
4
BUGS
@@ -1,6 +1,5 @@
|
||||
** Open BUGS **
|
||||
- Cutting the line at the top of the screen recenters to center (71)
|
||||
- Many menu items are probably missing from the new backend (73)
|
||||
|
||||
** Fixed BUGS **
|
||||
- Marked cutting sometimes leaves a newline in the file unintelligently,
|
||||
@@ -143,6 +142,7 @@
|
||||
- Trying to insert a file of 0 bytes will hang nano (70) [FIXED].
|
||||
- Meta-space and ^Space are not yet handled in new backend code (77) [FIXED]
|
||||
- F-keys do not work with new shortcut backend (72) [FIXED]
|
||||
- Many menu items are probably missing from the new backend (73) [FIXED]
|
||||
- Need a 'check-vitals-mapped' function to check that the end used didn't
|
||||
unbind all the keys for exit or cancel before starting up the editor (74) [FIXED]
|
||||
- Browser and prompt code still implement old switch on raw key input instead
|
||||
@@ -154,6 +154,8 @@
|
||||
page up/down, insert, and unbinds all other control and F keys for it,
|
||||
nano will do the wrong thing when reading the key which is normally
|
||||
assigned to it (79 - may not be worth fixing) [FIXED]
|
||||
- Segfault editing at COLS presumably due to new color syntax
|
||||
highlighting (80) [FIXED]
|
||||
|
||||
|
||||
$Id$
|
||||
|
||||
45
ChangeLog
45
ChangeLog
@@ -1,3 +1,48 @@
|
||||
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
|
||||
Savannah bug 25490, nanorc: "include"ing a file which doesn't exist causes nano to segfault.
|
||||
|
||||
2009-02-05 Chris Allegretta <chrisa@asty.org>
|
||||
* More color syntax speedups: Determine in reset_multis() whether we really need to call
|
||||
edit_refresh(). Additional global var edit_refresh_needed() to hopefully reduce
|
||||
repeated calls to the function. New helper funcs reset_multis_before() and
|
||||
reset_multis_after().
|
||||
|
||||
2009-02-02 Chris Allegretta <chrisa@asty.org>
|
||||
* New color precalculation code for mult-line regexes. New function precalc_multicolorinfo(),
|
||||
new structure multidata for keeping track of where regexes start/stop. More
|
||||
performance improvements forthcoming.
|
||||
|
||||
2009-01-29 Chris Allegretta <chrisa@asty.org>
|
||||
* nano.c (move_to_filestruct) - properky initialize new fileage for multiswatching, sigh.
|
||||
Fix cut sefaults discovered by Mike Frysinger.
|
||||
|
||||
2009-01-29 Chris Allegretta <chrisa@asty.org>
|
||||
* nano.c (main): Add support for nano acting like a pager when invoked with - as first
|
||||
file argument.
|
||||
|
||||
2009-01-28 Davide Pesavento <davidepesa@gmail.com>
|
||||
* doc/syntax/gentoo.nanorc: Updates from David and Mike Frysinger.
|
||||
|
||||
2009-01-25 Chris Allegretta <chrisa@asty.org>
|
||||
* files.c (open_file), nanorc.c (parse_include): Don't get_full_path on
|
||||
included rc files, due to it potentially impacting the ability
|
||||
to read files in nano's cwd(). Fixes Savnanah bug #25297 reported by Mike
|
||||
Frysinger)
|
||||
|
||||
2009-01-24 Chris Allegretta <chrisa@asty.org>
|
||||
* First pass at some caching of caching color info. Right now it's only for
|
||||
multi-line regexes but this may not be enough to increase performance.
|
||||
* Add interruptability to search functions. New functions enable_nodelay and
|
||||
disable_nodelay and changes to the routines to handle checking for pending
|
||||
searches. Fixes Savnnah bug 24946: Need interrrupt for search.
|
||||
|
||||
2009-01-19 Chris Allegretta <chrisa@asty.org>
|
||||
* Change function definitions to shorts instead of (void *)s. New mapping function
|
||||
iso_me_harder_funcmap(). Fixes compilation complaints with -pedantic,
|
||||
reported by Eitan Adler <eitanadlerlist@gmail.com>.
|
||||
|
||||
GNU nano 2.1.7 - 2008.11.10
|
||||
2008-10-20 Chris Allegretta <chrisa@asty.org>
|
||||
* files.c (do_writeout): Add check for file modification when saving
|
||||
|
||||
16
NEWS
16
NEWS
@@ -1,3 +1,19 @@
|
||||
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
|
||||
to abort running searches (useful mainly when
|
||||
editing very large files) and the ability to use nano
|
||||
like a pager for viewing standard input (i.e. "nano -").
|
||||
Additionally, there are gentoo syntax highlighting
|
||||
updates and fixes for issues with reading files
|
||||
in a directory with strange parent directory permissions.
|
||||
The key bindings code was also substantially changed
|
||||
in order to be more ISO-C compatible. Be sure to use
|
||||
the Savannah page not only for bug reports but for any
|
||||
features you would like to see before the next stable
|
||||
series is released. Have fun with it!
|
||||
|
||||
|
||||
2008.11.10 - GNU nano 2.1.7 "Effingham" is ready to make good on those
|
||||
campaign promises of lower bug rates and 50% more pie.
|
||||
This release includes a new check for external
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#
|
||||
# $Id$
|
||||
|
||||
AC_INIT([GNU nano], [2.1.7], [nano-devel@gnu.org], [nano])
|
||||
AC_INIT([GNU nano], [2.1.8], [nano-devel@gnu.org], [nano])
|
||||
AC_CONFIG_SRCDIR([src/nano.c])
|
||||
AC_CANONICAL_TARGET([])
|
||||
AM_INIT_AUTOMAKE
|
||||
|
||||
@@ -2,26 +2,30 @@
|
||||
##
|
||||
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))"
|
||||
color brightgreen "^src_(unpack|prepare|configure|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 "\<(declare|eval|exec|let)\>"
|
||||
color green "(\{|\}|\(|\)|\;|\]|\[|`|\\|\$|<|>|!|=|&|\|)"
|
||||
color green "-(e|d|f|r|g|u|w|x|L)\>"
|
||||
color green "-[edfgruwxL]\>"
|
||||
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)\>"
|
||||
color red "\<(EAPI|ARCH|HOMEPAGE|DESCRIPTION|IUSE|SRC_URI|LICENSE|SLOT|KEYWORDS|(P|R)?DEPEND|PROVIDE|PROPERTIES|RESTRICT|USERLAND)\>"
|
||||
color red "\<(S|D|T|PV|PF|P|PN|PR|PVR|A|CATEGORY|DISTDIR|FILESDIR|ROOT|WORKDIR)\>" "\<(AS|C(PP|XX)?|LD)FLAGS\>" "\<C(HOST|TARGET|BUILD)\>"
|
||||
color red "\<QA_((TEXTRELS|EXECSTACK|WX_LOAD)(_[a-zA-Z_0-9]+)?|DT_HASH|PRESTRIPPED)\>" "\<WANT_AUTO(CONF|MAKE)\>" "\<AT_M4DIR\>"
|
||||
## 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 "\<e(begin|end|conf|install|make|qmake[34]|ant|(qa)?warn|infon?|error|log|patch|new(group|user))\>"
|
||||
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(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\>"
|
||||
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\>" "\<(cat|cd|chmod|chown|cp|echo|env|export|grep|let|ln|mkdir|mv|rm|sed|set|tar|touch|unset)\>"
|
||||
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)
|
||||
color yellow "#.*$"
|
||||
## Highlight strings (doesnt work that well)
|
||||
@@ -31,17 +35,18 @@ color ,green "[[:space:]]+$"
|
||||
|
||||
## Here is an example for Portage control files
|
||||
##
|
||||
syntax "/etc/portage" "\.(keywords|mask|unmask|use)$"
|
||||
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:
|
||||
## Likely version and slot numbers:
|
||||
color magenta "-[[:digit:]].*([[:space:]]|$)"
|
||||
color magenta ":[^[:space:]]+([[:space:]]|$)"
|
||||
## Accepted arches:
|
||||
color white "[~-]?\<(alpha|amd64|arm|hppa|ia64|mips|ppc|ppc64|s390|sh|sparc|x86|x86-fbsd)\>"
|
||||
color white "[[:space:]][~-]?\*"
|
||||
color white "[~-]?\<(alpha|amd64|arm|hppa|ia64|mips|ppc|ppc64|s390|sh|sparc(-fbsd)?|x86(-fbsd)?)\>"
|
||||
color white "[[:space:]][*~-]?\*"
|
||||
## Categories:
|
||||
color cyan "^[[:space:]]*.*/"
|
||||
## Masking regulators:
|
||||
|
||||
@@ -8,7 +8,7 @@ sub combinations {
|
||||
return @rest, map { [$first, @$_] } @rest;
|
||||
}
|
||||
|
||||
my @allargs=("--enable-debug", "--disable-extra", "--enable-tiny", "--disable-browser --disable-help --disable-mouse --disable-operatingdir --disable-speller", "--disable-multibuffer", "--disable-nanorc", "--with-slang");
|
||||
my @allargs=("--enable-debug", "--disable-justify", "--disable-extra", "--enable-tiny", "--disable-browser --disable-help --disable-mouse --disable-operatingdir --disable-speller", "--disable-multibuffer", "--disable-nanorc", "--with-slang");
|
||||
my @combos = combinations(@allargs);
|
||||
|
||||
my $i = 0;
|
||||
|
||||
664
po/nano.pot
664
po/nano.pot
File diff suppressed because it is too large
Load Diff
664
po/pt_BR.po
664
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
664
po/zh_CN.po
664
po/zh_CN.po
File diff suppressed because it is too large
Load Diff
664
po/zh_TW.po
664
po/zh_TW.po
File diff suppressed because it is too large
Load Diff
@@ -156,7 +156,7 @@ char *do_browser(char *path, DIR *dir)
|
||||
* time, put back the Enter key so that it's
|
||||
* read in. */
|
||||
if (old_selected == selected)
|
||||
unget_kbinput(sc_seq_or(do_enter, 0), FALSE, FALSE);
|
||||
unget_kbinput(sc_seq_or(DO_ENTER, 0), FALSE, FALSE);
|
||||
}
|
||||
}
|
||||
#endif /* !DISABLE_MOUSE */
|
||||
@@ -169,9 +169,9 @@ char *do_browser(char *path, DIR *dir)
|
||||
if (!f)
|
||||
break;
|
||||
|
||||
if (f->scfunc == total_refresh) {
|
||||
if (f->scfunc == TOTAL_REFRESH) {
|
||||
total_redraw();
|
||||
} else if (f->scfunc == do_help_void) {
|
||||
} else if (f->scfunc == DO_HELP_VOID) {
|
||||
#ifndef DISABLE_HELP
|
||||
do_browser_help();
|
||||
curs_set(0);
|
||||
@@ -179,33 +179,33 @@ char *do_browser(char *path, DIR *dir)
|
||||
nano_disabled_msg();
|
||||
#endif
|
||||
/* Search for a filename. */
|
||||
} else if (f->scfunc == do_search) {
|
||||
} else if (f->scfunc == DO_SEARCH) {
|
||||
curs_set(1);
|
||||
do_filesearch();
|
||||
curs_set(0);
|
||||
/* Search for another filename. */
|
||||
} else if (f->scfunc == (void *) whereis_next_msg) {
|
||||
} else if (f->scfunc == WHEREIS_NEXT_MSG) {
|
||||
do_fileresearch();
|
||||
} else if (f->scfunc == do_page_up) {
|
||||
} else if (f->scfunc == DO_PAGE_UP) {
|
||||
if (selected >= (editwinrows + fileline % editwinrows) *
|
||||
width)
|
||||
selected -= (editwinrows + fileline % editwinrows) *
|
||||
width;
|
||||
else
|
||||
selected = 0;
|
||||
} else if (f->scfunc == do_page_down) {
|
||||
} else if (f->scfunc == DO_PAGE_DOWN) {
|
||||
selected += (editwinrows - fileline % editwinrows) *
|
||||
width;
|
||||
if (selected > filelist_len - 1)
|
||||
selected = filelist_len - 1;
|
||||
} else if (f->scfunc == (void *) first_file_msg) {
|
||||
} else if (f->scfunc == FIRST_FILE_MSG) {
|
||||
if (meta_key)
|
||||
selected = 0;
|
||||
} else if (f->scfunc == (void *) last_file_msg) {
|
||||
} else if (f->scfunc == LAST_FILE_MSG) {
|
||||
if (meta_key)
|
||||
selected = filelist_len - 1;
|
||||
/* Go to a specific directory. */
|
||||
} else if (f->scfunc == (void *) goto_dir_msg) {
|
||||
} else if (f->scfunc == GOTO_DIR_MSG) {
|
||||
curs_set(1);
|
||||
|
||||
i = do_prompt(TRUE,
|
||||
@@ -238,7 +238,7 @@ char *do_browser(char *path, DIR *dir)
|
||||
* answer in ans, so that the file list is displayed
|
||||
* again, the prompt is displayed again, and what we
|
||||
* typed before at the prompt is displayed again. */
|
||||
unget_kbinput(sc_seq_or(do_gotolinecolumn_void, 0), FALSE, FALSE);
|
||||
unget_kbinput(sc_seq_or(DO_GOTOLINECOLUMN_VOID, 0), FALSE, FALSE);
|
||||
ans = mallocstrcpy(ans, answer);
|
||||
break;
|
||||
}
|
||||
@@ -285,19 +285,19 @@ char *do_browser(char *path, DIR *dir)
|
||||
free(path);
|
||||
path = new_path;
|
||||
goto change_browser_directory;
|
||||
} else if (f->scfunc == do_up_void) {
|
||||
} else if (f->scfunc == DO_UP_VOID) {
|
||||
if (selected >= width)
|
||||
selected -= width;
|
||||
} else if (f->scfunc == do_left) {
|
||||
} else if (f->scfunc == DO_LEFT) {
|
||||
if (selected > 0)
|
||||
selected--;
|
||||
} else if (f->scfunc == do_down_void) {
|
||||
} else if (f->scfunc == DO_DOWN_VOID) {
|
||||
if (selected + width <= filelist_len - 1)
|
||||
selected += width;
|
||||
} else if (f->scfunc == do_right) {
|
||||
} else if (f->scfunc == DO_RIGHT) {
|
||||
if (selected < filelist_len - 1)
|
||||
selected++;
|
||||
} else if (f->scfunc == do_enter) {
|
||||
} else if (f->scfunc == DO_ENTER) {
|
||||
/* We can't move up from "/". */
|
||||
if (strcmp(filelist[selected], "/..") == 0) {
|
||||
statusbar(_("Can't move up a directory"));
|
||||
@@ -355,7 +355,7 @@ char *do_browser(char *path, DIR *dir)
|
||||
/* Start over again with the new path value. */
|
||||
goto change_browser_directory;
|
||||
/* Abort the file browser. */
|
||||
} else if (f->scfunc == do_exit) {
|
||||
} else if (f->scfunc == DO_EXIT) {
|
||||
abort = TRUE;
|
||||
}
|
||||
}
|
||||
@@ -552,32 +552,32 @@ void parse_browser_input(int *kbinput, bool *meta_key, bool *func_key)
|
||||
if (!*meta_key) {
|
||||
switch (*kbinput) {
|
||||
case ' ':
|
||||
*kbinput = sc_seq_or(do_page_down, 0);
|
||||
*kbinput = sc_seq_or(DO_PAGE_DOWN, 0);
|
||||
break;
|
||||
case '-':
|
||||
*kbinput = sc_seq_or(do_page_up, 0);
|
||||
*kbinput = sc_seq_or(DO_PAGE_UP, 0);
|
||||
break;
|
||||
case '?':
|
||||
#ifndef DISABLE_HELP
|
||||
*kbinput = sc_seq_or(do_help_void, 0);
|
||||
*kbinput = sc_seq_or(DO_HELP_VOID, 0);
|
||||
#endif
|
||||
break;
|
||||
/* Cancel equivalent to Exit here. */
|
||||
case 'E':
|
||||
case 'e':
|
||||
*kbinput = sc_seq_or(do_exit, 0);
|
||||
*kbinput = sc_seq_or(DO_EXIT, 0);
|
||||
break;
|
||||
case 'G':
|
||||
case 'g':
|
||||
*kbinput = sc_seq_or((void *) goto_dir_msg, 0);
|
||||
*kbinput = sc_seq_or(GOTO_DIR_MSG, 0);
|
||||
break;
|
||||
case 'S':
|
||||
case 's':
|
||||
*kbinput = sc_seq_or(do_enter, 0);
|
||||
*kbinput = sc_seq_or(DO_ENTER, 0);
|
||||
break;
|
||||
case 'W':
|
||||
case 'w':
|
||||
*kbinput = sc_seq_or(do_search, 0);
|
||||
*kbinput = sc_seq_or(DO_SEARCH, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -841,18 +841,18 @@ int filesearch_init(void)
|
||||
#endif
|
||||
} else
|
||||
#ifndef NANO_TINY
|
||||
if (s && s->scfunc == (void *) case_sens_msg) {
|
||||
if (s && s->scfunc == CASE_SENS_MSG) {
|
||||
TOGGLE(CASE_SENSITIVE);
|
||||
backupstring = mallocstrcpy(backupstring, answer);
|
||||
return 1;
|
||||
} else if (s && s->scfunc == (void *) backwards_msg) {
|
||||
} else if (s && s->scfunc == BACKWARDS_MSG) {
|
||||
TOGGLE(BACKWARDS_SEARCH);
|
||||
backupstring = mallocstrcpy(backupstring, answer);
|
||||
return 1;
|
||||
} else
|
||||
#endif
|
||||
#ifdef HAVE_REGEX_H
|
||||
if (s && s->scfunc == (void *) regexp_msg) {
|
||||
if (s && s->scfunc == REGEXP_MSG) {
|
||||
TOGGLE(USE_REGEXP);
|
||||
backupstring = mallocstrcpy(backupstring, answer);
|
||||
return 1;
|
||||
|
||||
88
src/color.c
88
src/color.c
@@ -105,11 +105,13 @@ void color_init(void)
|
||||
/* Update the color information based on the current filename. */
|
||||
void color_update(void)
|
||||
{
|
||||
const syntaxtype *tmpsyntax;
|
||||
syntaxtype *tmpsyntax;
|
||||
syntaxtype *defsyntax = NULL;
|
||||
colortype *tmpcolor, *defcolor = NULL;
|
||||
|
||||
assert(openfile != NULL);
|
||||
|
||||
openfile->syntax = NULL;
|
||||
openfile->colorstrings = NULL;
|
||||
|
||||
/* If we specified a syntax override string, use it. */
|
||||
@@ -121,8 +123,10 @@ void color_update(void)
|
||||
|
||||
for (tmpsyntax = syntaxes; tmpsyntax != NULL;
|
||||
tmpsyntax = tmpsyntax->next) {
|
||||
if (strcmp(tmpsyntax->desc, syntaxstr) == 0)
|
||||
if (strcmp(tmpsyntax->desc, syntaxstr) == 0) {
|
||||
openfile->syntax = tmpsyntax;
|
||||
openfile->colorstrings = tmpsyntax->color;
|
||||
}
|
||||
|
||||
if (openfile->colorstrings != NULL)
|
||||
break;
|
||||
@@ -141,6 +145,7 @@ void color_update(void)
|
||||
* extensions, which we've checked for elsewhere. Skip over
|
||||
* it here, but keep track of its color regexes. */
|
||||
if (strcmp(tmpsyntax->desc, "default") == 0) {
|
||||
defsyntax = tmpsyntax;
|
||||
defcolor = tmpsyntax->color;
|
||||
continue;
|
||||
}
|
||||
@@ -159,8 +164,10 @@ void color_update(void)
|
||||
/* Set colorstrings if we matched the extension
|
||||
* regex. */
|
||||
if (regexec(e->ext, openfile->filename, 0, NULL,
|
||||
0) == 0)
|
||||
0) == 0) {
|
||||
openfile->syntax = tmpsyntax;
|
||||
openfile->colorstrings = tmpsyntax->color;
|
||||
}
|
||||
|
||||
if (openfile->colorstrings != NULL)
|
||||
break;
|
||||
@@ -200,8 +207,10 @@ void color_update(void)
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Comparing header regex \"%s\" to fileage \"%s\"...\n", e->ext_regex, openfile->fileage->data);
|
||||
#endif
|
||||
if (regexec(e->ext, openfile->fileage->data, 0, NULL, 0) == 0)
|
||||
if (regexec(e->ext, openfile->fileage->data, 0, NULL, 0) == 0) {
|
||||
openfile->syntax = tmpsyntax;
|
||||
openfile->colorstrings = tmpsyntax->color;
|
||||
}
|
||||
|
||||
if (openfile->colorstrings != NULL)
|
||||
break;
|
||||
@@ -221,8 +230,10 @@ void color_update(void)
|
||||
|
||||
/* If we didn't get a syntax based on the file extension, and we
|
||||
* have a default syntax, use it. */
|
||||
if (openfile->colorstrings == NULL && defcolor != NULL)
|
||||
if (openfile->colorstrings == NULL && defcolor != NULL) {
|
||||
openfile->syntax = defsyntax;
|
||||
openfile->colorstrings = defcolor;
|
||||
}
|
||||
|
||||
for (tmpcolor = openfile->colorstrings; tmpcolor != NULL;
|
||||
tmpcolor = tmpcolor->next) {
|
||||
@@ -243,4 +254,71 @@ void color_update(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset the multicolor info cache for records for any lines which need
|
||||
to be recalculated */
|
||||
void reset_multis_after(filestruct *fileptr, int mindex)
|
||||
{
|
||||
filestruct *oof;
|
||||
for (oof = fileptr->next; 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;
|
||||
}
|
||||
}
|
||||
|
||||
void reset_multis_before(filestruct *fileptr, int mindex)
|
||||
{
|
||||
filestruct *oof;
|
||||
for (oof = fileptr->prev; 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Reset multi line strings around a filestruct ptr, trying to be smart about stopping */
|
||||
void reset_multis(filestruct *fileptr)
|
||||
{
|
||||
int nobegin, noend;
|
||||
regmatch_t startmatch, endmatch;
|
||||
const colortype *tmpcolor = openfile->colorstrings;
|
||||
|
||||
if (!openfile->syntax)
|
||||
return;
|
||||
|
||||
for (; tmpcolor != NULL; tmpcolor = tmpcolor->next) {
|
||||
|
||||
/* If it's not a multi-line regex, amscray */
|
||||
if (tmpcolor->end == NULL)
|
||||
continue;
|
||||
|
||||
alloc_multidata_if_needed(fileptr);
|
||||
/* 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);
|
||||
noend = regexec(tmpcolor->end, fileptr->data, 1, &endmatch, 0);
|
||||
if (fileptr->multidata[tmpcolor->id] == CWHOLELINE) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
#endif /* ENABLE_COLOR */
|
||||
|
||||
39
src/files.c
39
src/files.c
@@ -311,6 +311,10 @@ filestruct *read_line(char *buf, filestruct *prevnode, bool
|
||||
fileptr->data[buf_len - 1] = '\0';
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
fileptr->multidata = NULL;
|
||||
#endif
|
||||
|
||||
if (*first_line_ins) {
|
||||
/* Special case: We're inserting with the cursor on the first
|
||||
* line. */
|
||||
@@ -600,7 +604,7 @@ void read_file(FILE *f, const char *filename, bool undoable)
|
||||
* return value. *f is set to the opened file. */
|
||||
int open_file(const char *filename, bool newfie, FILE **f)
|
||||
{
|
||||
struct stat fileinfo;
|
||||
struct stat fileinfo, fileinfo2;
|
||||
int fd;
|
||||
char *full_filename;
|
||||
|
||||
@@ -609,10 +613,21 @@ int open_file(const char *filename, bool newfie, FILE **f)
|
||||
/* Get the specified file's full path. */
|
||||
full_filename = get_full_path(filename);
|
||||
|
||||
if (full_filename == NULL)
|
||||
/* 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 (stat(full_filename, &fileinfo) == -1) {
|
||||
/* Well, maybe we can open the file even if the OS
|
||||
says its not there */
|
||||
if ((fd = open(filename, O_RDONLY)) != -1) {
|
||||
statusbar(_("Reading File"));
|
||||
free(full_filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (newfie) {
|
||||
statusbar(_("New File"));
|
||||
return -2;
|
||||
@@ -780,14 +795,14 @@ void do_insertfile(
|
||||
#ifndef NANO_TINY
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
|
||||
if (s && s->scfunc == (void *) new_buffer_msg) {
|
||||
if (s && s->scfunc == NEW_BUFFER_MSG) {
|
||||
/* Don't allow toggling if we're in view mode. */
|
||||
if (!ISSET(VIEW_MODE))
|
||||
TOGGLE(MULTIBUFFER);
|
||||
continue;
|
||||
} else
|
||||
#endif
|
||||
if (s && s->scfunc == (void *) ext_cmd_msg) {
|
||||
if (s && s->scfunc == EXT_CMD_MSG) {
|
||||
execute = !execute;
|
||||
continue;
|
||||
}
|
||||
@@ -797,7 +812,7 @@ void do_insertfile(
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
#ifndef DISABLE_BROWSER
|
||||
if (s && s->scfunc == (void *) to_files_msg) {
|
||||
if (s && s->scfunc == TO_FILES_MSG) {
|
||||
char *tmp = do_browse_from(answer);
|
||||
|
||||
if (tmp == NULL)
|
||||
@@ -1917,7 +1932,7 @@ bool do_writeout(bool exiting)
|
||||
s = get_shortcut(currmenu, &i, &meta_key, &func_key);
|
||||
|
||||
#ifndef DISABLE_BROWSER
|
||||
if (s && s->scfunc == (void *) to_files_msg) {
|
||||
if (s && s->scfunc == TO_FILES_MSG) {
|
||||
char *tmp = do_browse_from(answer);
|
||||
|
||||
if (tmp == NULL)
|
||||
@@ -1929,26 +1944,26 @@ bool do_writeout(bool exiting)
|
||||
} else
|
||||
#endif /* !DISABLE_BROWSER */
|
||||
#ifndef NANO_TINY
|
||||
if (s && s->scfunc == (void *) dos_format_msg) {
|
||||
if (s && s->scfunc == DOS_FORMAT_MSG) {
|
||||
openfile->fmt = (openfile->fmt == DOS_FILE) ? NIX_FILE :
|
||||
DOS_FILE;
|
||||
continue;
|
||||
} else if (s && s->scfunc == (void *) mac_format_msg) {
|
||||
} else if (s && s->scfunc == MAC_FORMAT_MSG) {
|
||||
openfile->fmt = (openfile->fmt == MAC_FILE) ? NIX_FILE :
|
||||
MAC_FILE;
|
||||
continue;
|
||||
} else if (s && s->scfunc == (void *) backup_file_msg) {
|
||||
} else if (s && s->scfunc == BACKUP_FILE_MSG) {
|
||||
TOGGLE(BACKUP_FILE);
|
||||
continue;
|
||||
} else
|
||||
#endif /* !NANO_TINY */
|
||||
if (s && s->scfunc == (void *) prepend_msg) {
|
||||
if (s && s->scfunc == PREPEND_MSG) {
|
||||
append = (append == PREPEND) ? OVERWRITE : PREPEND;
|
||||
continue;
|
||||
} else if (s && s->scfunc == (void *) append_msg) {
|
||||
} else if (s && s->scfunc == APPEND_MSG) {
|
||||
append = (append == APPEND) ? OVERWRITE : APPEND;
|
||||
continue;
|
||||
} else if (s && s->scfunc == do_help_void) {
|
||||
} else if (s && s->scfunc == DO_HELP_VOID) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
749
src/global.c
749
src/global.c
File diff suppressed because it is too large
Load Diff
26
src/help.c
26
src/help.c
@@ -145,35 +145,35 @@ void do_help(void (*refresh_func)(void))
|
||||
if (!f)
|
||||
continue;
|
||||
|
||||
if (f->scfunc == total_refresh) {
|
||||
if (f->scfunc == TOTAL_REFRESH) {
|
||||
total_redraw();
|
||||
break;
|
||||
} else if (f->scfunc == do_page_up) {
|
||||
} else if (f->scfunc == DO_PAGE_UP) {
|
||||
if (line > editwinrows - 2)
|
||||
line -= editwinrows - 2;
|
||||
else
|
||||
line = 0;
|
||||
} else if (f->scfunc == do_page_down) {
|
||||
} else if (f->scfunc == DO_PAGE_DOWN) {
|
||||
if (line + (editwinrows - 1) < last_line)
|
||||
line += editwinrows - 2;
|
||||
} else if (f->scfunc == do_up_void) {
|
||||
} else if (f->scfunc == DO_UP_VOID) {
|
||||
if (line > 0)
|
||||
line--;
|
||||
} else if (f->scfunc == do_down_void) {
|
||||
} else if (f->scfunc == DO_DOWN_VOID) {
|
||||
if (line + (editwinrows - 1) < last_line)
|
||||
line++;
|
||||
} else if (f->scfunc == do_first_line) {
|
||||
} else if (f->scfunc == DO_FIRST_LINE) {
|
||||
if (meta_key)
|
||||
line = 0;
|
||||
break;
|
||||
} else if (f->scfunc == do_last_line) {
|
||||
} else if (f->scfunc == DO_LAST_LINE) {
|
||||
if (meta_key) {
|
||||
if (line + (editwinrows - 1) < last_line)
|
||||
line = last_line - (editwinrows - 1);
|
||||
}
|
||||
break;
|
||||
/* Abort the help browser. */
|
||||
} else if (f->scfunc == do_exit) {
|
||||
} else if (f->scfunc == DO_EXIT) {
|
||||
abort = TRUE;
|
||||
break;
|
||||
}
|
||||
@@ -407,7 +407,7 @@ void help_init(void)
|
||||
size_t endis_len = strlen(_("enable/disable"));
|
||||
|
||||
for (s = sclist; s != NULL; s = s->next)
|
||||
if (s->scfunc == (void *) do_toggle)
|
||||
if (s->scfunc == DO_TOGGLE)
|
||||
allocsize += strlen(_(flagtostr(s->toggle))) + endis_len + 9;
|
||||
|
||||
}
|
||||
@@ -478,7 +478,7 @@ void help_init(void)
|
||||
/* And the toggles... */
|
||||
if (currmenu == MMAIN)
|
||||
for (s = sclist; s != NULL; s = s->next)
|
||||
if (s->scfunc == (void *) do_toggle)
|
||||
if (s->scfunc == DO_TOGGLE)
|
||||
ptr += sprintf(ptr, "(%s)\t\t\t%s %s\n",
|
||||
s->keystr, _(flagtostr(s->toggle)), _("enable/disable"));
|
||||
|
||||
@@ -507,15 +507,15 @@ void parse_help_input(int *kbinput, bool *meta_key, bool *func_key)
|
||||
switch (*kbinput) {
|
||||
/* For consistency with the file browser. */
|
||||
case ' ':
|
||||
*kbinput = sc_seq_or(do_page_up, 0);
|
||||
*kbinput = sc_seq_or(DO_PAGE_UP, 0);
|
||||
break;
|
||||
case '-':
|
||||
*kbinput = sc_seq_or(do_page_down, 0);;
|
||||
*kbinput = sc_seq_or(DO_PAGE_DOWN, 0);;
|
||||
break;
|
||||
/* Cancel is equivalent to Exit here. */
|
||||
case 'E':
|
||||
case 'e':
|
||||
*kbinput = sc_seq_or(do_exit, 0);;
|
||||
*kbinput = sc_seq_or(DO_EXIT, 0);;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
12
src/move.c
12
src/move.c
@@ -29,7 +29,7 @@
|
||||
/* Move to the first line of the file. */
|
||||
void do_first_line(void)
|
||||
{
|
||||
const filestruct *current_save = openfile->current;
|
||||
filestruct *current_save = openfile->current;
|
||||
size_t pww_save = openfile->placewewant;
|
||||
|
||||
openfile->current = openfile->fileage;
|
||||
@@ -42,7 +42,7 @@ void do_first_line(void)
|
||||
/* Move to the last line of the file. */
|
||||
void do_last_line(void)
|
||||
{
|
||||
const filestruct *current_save = openfile->current;
|
||||
filestruct *current_save = openfile->current;
|
||||
size_t pww_save = openfile->placewewant;
|
||||
|
||||
openfile->current = openfile->filebot;
|
||||
@@ -130,7 +130,7 @@ void do_page_down(void)
|
||||
* afterwards. */
|
||||
void do_para_begin(bool allow_update)
|
||||
{
|
||||
const filestruct *current_save = openfile->current;
|
||||
filestruct *current_save = openfile->current;
|
||||
const size_t pww_save = openfile->placewewant;
|
||||
|
||||
if (openfile->current != openfile->fileage) {
|
||||
@@ -162,7 +162,7 @@ void do_para_begin_void(void)
|
||||
* paragraph or isn't in a paragraph. */
|
||||
void do_para_end(bool allow_update)
|
||||
{
|
||||
const filestruct *const current_save = openfile->current;
|
||||
filestruct *const current_save = openfile->current;
|
||||
const size_t pww_save = openfile->placewewant;
|
||||
|
||||
while (openfile->current != openfile->filebot &&
|
||||
@@ -206,7 +206,7 @@ void do_para_end_void(void)
|
||||
bool do_next_word(bool allow_punct, bool allow_update)
|
||||
{
|
||||
size_t pww_save = openfile->placewewant;
|
||||
const filestruct *current_save = openfile->current;
|
||||
filestruct *current_save = openfile->current;
|
||||
char *char_mb;
|
||||
int char_mb_len;
|
||||
bool end_line = FALSE, started_on_word = FALSE;
|
||||
@@ -301,7 +301,7 @@ void do_next_word_void(void)
|
||||
bool do_prev_word(bool allow_punct, bool allow_update)
|
||||
{
|
||||
size_t pww_save = openfile->placewewant;
|
||||
const filestruct *current_save = openfile->current;
|
||||
filestruct *current_save = openfile->current;
|
||||
char *char_mb;
|
||||
int char_mb_len;
|
||||
bool begin_line = FALSE, started_on_word = FALSE;
|
||||
|
||||
227
src/nano.c
227
src/nano.c
@@ -32,6 +32,7 @@
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <locale.h>
|
||||
#include <time.h>
|
||||
#ifdef ENABLE_UTF8
|
||||
#include <langinfo.h>
|
||||
#endif
|
||||
@@ -67,6 +68,10 @@ filestruct *make_new_node(filestruct *prevnode)
|
||||
newnode->next = NULL;
|
||||
newnode->lineno = (prevnode != NULL) ? prevnode->lineno + 1 : 1;
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
newnode->multidata = NULL;
|
||||
#endif
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
@@ -83,6 +88,9 @@ filestruct *copy_node(const filestruct *src)
|
||||
dst->next = src->next;
|
||||
dst->prev = src->prev;
|
||||
dst->lineno = src->lineno;
|
||||
#ifdef ENABLE_COLOR
|
||||
dst->multidata = NULL;
|
||||
#endif
|
||||
|
||||
return dst;
|
||||
}
|
||||
@@ -119,6 +127,11 @@ void delete_node(filestruct *fileptr)
|
||||
if (fileptr->data != NULL)
|
||||
free(fileptr->data);
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
if (fileptr->multidata)
|
||||
free(fileptr->multidata);
|
||||
#endif
|
||||
|
||||
free(fileptr);
|
||||
}
|
||||
|
||||
@@ -356,6 +369,10 @@ void move_to_filestruct(filestruct **file_top, filestruct **file_bot,
|
||||
openfile->fileage->data = mallocstrcpy(NULL, "");
|
||||
openfile->filebot = openfile->fileage;
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
openfile->fileage->multidata = NULL;
|
||||
#endif
|
||||
|
||||
/* Restore the current line and cursor position. If the mark begins
|
||||
* inside the partition, set the beginning of the mark to where the
|
||||
* saved text used to start. */
|
||||
@@ -1019,6 +1036,75 @@ void do_exit(void)
|
||||
display_main_list();
|
||||
}
|
||||
|
||||
|
||||
|
||||
static struct sigaction pager_oldaction, pager_newaction; /* Original and temporary handlers for SIGINT. */
|
||||
static bool pager_sig_failed = FALSE; /* Did sigaction() fail without changing the signal handlers? */
|
||||
|
||||
/* Things which need to be run regardless of whether
|
||||
we finished the stdin pipe correctly or not */
|
||||
void finish_stdin_pager(void)
|
||||
{
|
||||
FILE *f;
|
||||
int ttystdin;
|
||||
|
||||
/* Read whatever we did get from stdin */
|
||||
f = fopen("/dev/stdin", "rb");
|
||||
if (f == NULL)
|
||||
nperror("fopen");
|
||||
|
||||
read_file(f, "stdin", TRUE);
|
||||
ttystdin = open("/dev/tty", O_RDONLY);
|
||||
if (!ttystdin)
|
||||
die(_("Couldn't reopen stdin from keyboard, sorry\n"));
|
||||
|
||||
dup2(ttystdin,0);
|
||||
close(ttystdin);
|
||||
tcgetattr(0, &oldterm);
|
||||
if (!pager_sig_failed && sigaction(SIGINT, &pager_oldaction, NULL) == -1)
|
||||
nperror("sigaction");
|
||||
terminal_init();
|
||||
doupdate();
|
||||
}
|
||||
|
||||
|
||||
/* Cancel reading from stdin like a pager */
|
||||
RETSIGTYPE cancel_stdin_pager(int signal)
|
||||
{
|
||||
/* Currently do nothing, just handle the intr silently */
|
||||
}
|
||||
|
||||
/* Let nano read stdin for the first file at least */
|
||||
void stdin_pager(void)
|
||||
{
|
||||
endwin();
|
||||
tcsetattr(0, TCSANOW, &oldterm);
|
||||
fprintf(stderr, _("Reading from stdin, ^C to abort\n"));
|
||||
|
||||
/* Set things up so that Ctrl-C will cancel the new process. */
|
||||
/* Enable interpretation of the special control keys so that we get
|
||||
* SIGINT when Ctrl-C is pressed. */
|
||||
#ifndef NANO_TINY
|
||||
enable_signals();
|
||||
#endif
|
||||
|
||||
if (sigaction(SIGINT, NULL, &pager_newaction) == -1) {
|
||||
pager_sig_failed = TRUE;
|
||||
nperror("sigaction");
|
||||
} else {
|
||||
pager_newaction.sa_handler = cancel_stdin_pager;
|
||||
if (sigaction(SIGINT, &pager_newaction, &pager_oldaction) == -1) {
|
||||
pager_sig_failed = TRUE;
|
||||
nperror("sigaction");
|
||||
}
|
||||
}
|
||||
|
||||
open_buffer("", FALSE);
|
||||
finish_stdin_pager();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Initialize the signal handlers. */
|
||||
void signal_init(void)
|
||||
{
|
||||
@@ -1439,6 +1525,7 @@ int do_input(bool *meta_key, bool *func_key, bool *s_or_t, bool
|
||||
kbinput = (int *)nrealloc(kbinput, kbinput_len *
|
||||
sizeof(int));
|
||||
kbinput[kbinput_len - 1] = input;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1453,7 +1540,7 @@ int do_input(bool *meta_key, bool *func_key, bool *s_or_t, bool
|
||||
* for verbatim input, turn off prepending of wrapped
|
||||
* text. */
|
||||
if (have_shortcut && (!have_shortcut || s == NULL || s->scfunc !=
|
||||
do_verbatim_input))
|
||||
DO_VERBATIM_INPUT))
|
||||
wrap_reset();
|
||||
#endif
|
||||
|
||||
@@ -1488,27 +1575,40 @@ int do_input(bool *meta_key, bool *func_key, bool *s_or_t, bool
|
||||
default:
|
||||
/* If the function associated with this shortcut is
|
||||
* cutting or copying text, indicate this. */
|
||||
if (s->scfunc == do_cut_text_void
|
||||
if (s->scfunc == DO_CUT_TEXT_VOID
|
||||
#ifndef NANO_TINY
|
||||
|| s->scfunc == do_copy_text || s->scfunc ==
|
||||
do_cut_till_end
|
||||
|| s->scfunc == DO_COPY_TEXT || s->scfunc ==
|
||||
DO_CUT_TILL_END
|
||||
#endif
|
||||
)
|
||||
cut_copy = TRUE;
|
||||
|
||||
if (s->scfunc != NULL) {
|
||||
if (s->scfunc != 0) {
|
||||
const subnfunc *f = sctofunc((sc *) s);
|
||||
*ran_func = TRUE;
|
||||
if (ISSET(VIEW_MODE) && f && !f->viewok)
|
||||
print_view_warning();
|
||||
else
|
||||
#ifndef NANO_TINY
|
||||
if (s->scfunc == (void *) do_toggle)
|
||||
if (s->scfunc == DO_TOGGLE)
|
||||
do_toggle(s->toggle);
|
||||
else
|
||||
else {
|
||||
#endif
|
||||
s->scfunc();
|
||||
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 (edit_refresh_needed) {
|
||||
edit_refresh();
|
||||
edit_refresh_needed = FALSE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#ifndef NANO_TINY
|
||||
}
|
||||
#endif
|
||||
*finished = TRUE;
|
||||
break;
|
||||
}
|
||||
@@ -1546,7 +1646,7 @@ int do_mouse(void)
|
||||
bool sameline;
|
||||
/* Did they click on the line with the cursor? If they
|
||||
* clicked on the cursor, we set the mark. */
|
||||
const filestruct *current_save = openfile->current;
|
||||
filestruct *current_save = openfile->current;
|
||||
size_t current_x_save = openfile->current_x;
|
||||
size_t pww_save = openfile->placewewant;
|
||||
|
||||
@@ -1579,6 +1679,94 @@ int do_mouse(void)
|
||||
}
|
||||
#endif /* !DISABLE_MOUSE */
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
void alloc_multidata_if_needed(filestruct *fileptr)
|
||||
{
|
||||
if (!fileptr->multidata)
|
||||
fileptr->multidata = nmalloc(openfile->syntax->nmultis * sizeof(short));
|
||||
}
|
||||
|
||||
/* Precalculate the multi-line start and end regex info so we can speed up
|
||||
rendering (with any hope at all...) */
|
||||
void precalc_multicolorinfo(void)
|
||||
{
|
||||
if (openfile->colorstrings != NULL && !ISSET(NO_COLOR_SYNTAX)) {
|
||||
const colortype *tmpcolor = openfile->colorstrings;
|
||||
regmatch_t startmatch, endmatch;
|
||||
filestruct *fileptr, *endptr;
|
||||
time_t last_check = time(NULL), cur_check = 0;
|
||||
|
||||
/* Let us get keypresses to see if the user is trying to
|
||||
start editing. We may want to throw up a statusbar
|
||||
message before starting this later if it takes
|
||||
too long to do this routine. For now silently
|
||||
abort if they hit a key */
|
||||
nodelay(edit, FALSE);
|
||||
|
||||
for (; tmpcolor != NULL; tmpcolor = tmpcolor->next) {
|
||||
|
||||
/* If it's not a multi-line regex, amscray */
|
||||
if (tmpcolor->end == NULL)
|
||||
continue;
|
||||
|
||||
for (fileptr = openfile->fileage; fileptr != NULL; fileptr = fileptr->next) {
|
||||
int startx = 0;
|
||||
|
||||
alloc_multidata_if_needed(fileptr);
|
||||
|
||||
if ((cur_check = time(NULL)) - last_check > 1) {
|
||||
last_check = cur_check;
|
||||
if (wgetch(edit) != ERR)
|
||||
goto precalc_cleanup;
|
||||
}
|
||||
|
||||
fileptr->multidata[tmpcolor->id] = CNONE;
|
||||
while (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;
|
||||
|
||||
/* 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;
|
||||
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) {
|
||||
|
||||
/* 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)
|
||||
break;
|
||||
}
|
||||
|
||||
if (endptr == NULL)
|
||||
break;
|
||||
|
||||
/* 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;
|
||||
for (fileptr = fileptr->next; fileptr != endptr; fileptr = fileptr->next) {
|
||||
alloc_multidata_if_needed(fileptr);
|
||||
fileptr->multidata[tmpcolor->id] = CWHOLELINE;
|
||||
}
|
||||
alloc_multidata_if_needed(endptr);
|
||||
endptr->multidata[tmpcolor->id] |= CBEGINBEFORE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
precalc_cleanup:
|
||||
nodelay(edit, FALSE);
|
||||
}
|
||||
#endif /* ENABLE_COLOR */
|
||||
|
||||
/* The user typed output_len multibyte characters. Add them to the edit
|
||||
* buffer, filtering out all ASCII control characters if allow_cntrls is
|
||||
* TRUE. */
|
||||
@@ -1683,9 +1871,14 @@ void do_output(char *output, size_t output_len, bool allow_cntrls)
|
||||
|
||||
openfile->placewewant = xplustabs();
|
||||
|
||||
if (do_refresh)
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
reset_multis(openfile->current);
|
||||
#endif
|
||||
if (do_refresh) {
|
||||
edit_refresh();
|
||||
else
|
||||
edit_refresh_needed = FALSE;
|
||||
} else
|
||||
update_line(openfile->current, openfile->current_x);
|
||||
}
|
||||
|
||||
@@ -2212,6 +2405,12 @@ int main(int argc, char **argv)
|
||||
optind++;
|
||||
}
|
||||
|
||||
if (optind < argc && !strcmp(argv[optind], "-")) {
|
||||
stdin_pager();
|
||||
set_modified();
|
||||
optind++;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
old_multibuffer = ISSET(MULTIBUFFER);
|
||||
SET(MULTIBUFFER);
|
||||
@@ -2267,6 +2466,11 @@ int main(int argc, char **argv)
|
||||
fprintf(stderr, "Main: top and bottom win\n");
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
if (openfile->syntax && openfile->syntax->nmultis > 0)
|
||||
precalc_multicolorinfo();
|
||||
#endif
|
||||
|
||||
if (startline > 1 || startcol > 1)
|
||||
do_gotolinecolumn(startline, startcol, FALSE, FALSE, FALSE,
|
||||
FALSE);
|
||||
@@ -2313,3 +2517,4 @@ int main(int argc, char **argv)
|
||||
/* We should never get here. */
|
||||
assert(FALSE);
|
||||
}
|
||||
|
||||
|
||||
247
src/nano.h
247
src/nano.h
@@ -173,36 +173,6 @@ typedef enum {
|
||||
ADD, DEL, REPLACE, SPLIT, UNSPLIT, CUT, UNCUT, INSERT, OTHER
|
||||
} undo_type;
|
||||
|
||||
/* Structure types. */
|
||||
typedef struct filestruct {
|
||||
char *data;
|
||||
/* The text of this line. */
|
||||
ssize_t lineno;
|
||||
/* The number of this line. */
|
||||
struct filestruct *next;
|
||||
/* Next node. */
|
||||
struct filestruct *prev;
|
||||
/* Previous node. */
|
||||
} filestruct;
|
||||
|
||||
typedef struct partition {
|
||||
filestruct *fileage;
|
||||
/* The top line of this portion of the file. */
|
||||
filestruct *top_prev;
|
||||
/* The line before the top line of this portion of the file. */
|
||||
char *top_data;
|
||||
/* The text before the beginning of the top line of this portion
|
||||
* of the file. */
|
||||
filestruct *filebot;
|
||||
/* The bottom line of this portion of the file. */
|
||||
filestruct *bot_next;
|
||||
/* The line after the bottom line of this portion of the
|
||||
* file. */
|
||||
char *bot_data;
|
||||
/* The text after the end of the bottom line of this portion of
|
||||
* the file. */
|
||||
} partition;
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
typedef struct colortype {
|
||||
short fg;
|
||||
@@ -226,6 +196,8 @@ typedef struct colortype {
|
||||
/* The compiled end (if any) of the regex string. */
|
||||
struct colortype *next;
|
||||
/* Next set of colors. */
|
||||
int id;
|
||||
/* basic id for assigning to lines later */
|
||||
} colortype;
|
||||
|
||||
typedef struct exttype {
|
||||
@@ -246,11 +218,61 @@ typedef struct syntaxtype {
|
||||
/* Regexes to match on the 'header' (1st line) of the file */
|
||||
colortype *color;
|
||||
/* The colors used in this syntax. */
|
||||
int nmultis;
|
||||
/* How many multi line strings this syntax has */
|
||||
struct syntaxtype *next;
|
||||
/* Next syntax. */
|
||||
} syntaxtype;
|
||||
|
||||
#define CNONE (1<<1)
|
||||
/* Yay, regex doesn't apply to this line at all! */
|
||||
#define CBEGINBEFORE (1<<2)
|
||||
/* regex starts on an earlier line, ends on this one */
|
||||
#define CENDAFTER (1<<3)
|
||||
/* regex sraers on this line and ends on a later one */
|
||||
#define CWHOLELINE (1<<4)
|
||||
/* whole line engulfed by the regex start < me, end > me */
|
||||
#define CSTARTENDHERE (1<<5)
|
||||
/* regex starts and ends within this line */
|
||||
#define CWTF (1<<6)
|
||||
/* Something else */
|
||||
|
||||
#endif /* ENABLE_COLOR */
|
||||
|
||||
|
||||
/* Structure types. */
|
||||
typedef struct filestruct {
|
||||
char *data;
|
||||
/* The text of this line. */
|
||||
ssize_t lineno;
|
||||
/* The number of this line. */
|
||||
struct filestruct *next;
|
||||
/* Next node. */
|
||||
struct filestruct *prev;
|
||||
/* Previous node. */
|
||||
#ifdef ENABLE_COLOR
|
||||
short *multidata; /* Array of which multi-line regexes apply to this line */
|
||||
#endif
|
||||
} filestruct;
|
||||
|
||||
typedef struct partition {
|
||||
filestruct *fileage;
|
||||
/* The top line of this portion of the file. */
|
||||
filestruct *top_prev;
|
||||
/* The line before the top line of this portion of the file. */
|
||||
char *top_data;
|
||||
/* The text before the beginning of the top line of this portion
|
||||
* of the file. */
|
||||
filestruct *filebot;
|
||||
/* The bottom line of this portion of the file. */
|
||||
filestruct *bot_next;
|
||||
/* The line after the bottom line of this portion of the
|
||||
* file. */
|
||||
char *bot_data;
|
||||
/* The text after the end of the bottom line of this portion of
|
||||
* the file. */
|
||||
} partition;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
typedef struct undo {
|
||||
ssize_t lineno;
|
||||
@@ -323,6 +345,8 @@ typedef struct openfilestruct {
|
||||
undo_type last_action;
|
||||
#endif
|
||||
#ifdef ENABLE_COLOR
|
||||
syntaxtype *syntax;
|
||||
/* The syntax struct for this file, if any */
|
||||
colortype *colorstrings;
|
||||
/* The current file's associated colors. */
|
||||
#endif
|
||||
@@ -380,7 +404,7 @@ typedef struct sc {
|
||||
/* The actual sequence to check on the the type is determined */
|
||||
int menu;
|
||||
/* What list does this apply to */
|
||||
void (*scfunc)(void);
|
||||
short scfunc;
|
||||
/* The function we're going to run */
|
||||
int toggle;
|
||||
/* If a toggle, what we're toggling */
|
||||
@@ -392,7 +416,7 @@ typedef struct sc {
|
||||
} sc;
|
||||
|
||||
typedef struct subnfunc {
|
||||
void (*scfunc)(void);
|
||||
short scfunc;
|
||||
/* What function is this */
|
||||
int menus;
|
||||
/* In what menus does this function applu */
|
||||
@@ -696,8 +720,167 @@ typedef struct subnfunc {
|
||||
#define UNDO_DEL_DEL (1<<0)
|
||||
#define UNDO_DEL_BACKSPACE (1<<1)
|
||||
|
||||
/* Since in ISO C you can't pass around function pointers anymore,
|
||||
let's make some integer macros for function names, and then I
|
||||
can go cut my wrists after writing the big switch statement
|
||||
that will necessitate. */
|
||||
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
#define CASE_SENS_MSG 1
|
||||
#define BACKWARDS_MSG 2
|
||||
#define REGEXP_MSG 3
|
||||
#define WHEREIS_NEXT_MSG 4
|
||||
#define FIRST_FILE_MSG 5
|
||||
#define LAST_FILE_MSG 6
|
||||
#define GOTO_DIR_MSG 7
|
||||
#define TOTAL_REFRESH 8
|
||||
#define DO_HELP_VOID 9
|
||||
#define DO_SEARCH 10
|
||||
#define DO_PAGE_UP 11
|
||||
#define DO_PAGE_DOWN 12
|
||||
#define DO_UP_VOID 13
|
||||
#define DO_LEFT 14
|
||||
#define DO_DOWN_VOID 15
|
||||
#define DO_RIGHT 16
|
||||
#define DO_ENTER 17
|
||||
#define DO_EXIT 18
|
||||
#define NEW_BUFFER_MSG 19
|
||||
#define EXT_CMD_MSG 20
|
||||
#define TO_FILES_MSG 21
|
||||
#define DOS_FORMAT_MSG 23
|
||||
#define MAC_FORMAT_MSG 24
|
||||
#define BACKUP_FILE_MSG 25
|
||||
#define PREPEND_MSG 26
|
||||
#define APPEND_MSG 27
|
||||
#define DO_FIRST_LINE 28
|
||||
#define DO_LAST_LINE 29
|
||||
#define DO_TOGGLE 30
|
||||
#define GOTOTEXT_MSG 31
|
||||
#define NO_REPLACE_MSG 32
|
||||
#define DO_BACKSPACE 33
|
||||
#define DO_DELETE 34
|
||||
#define DO_TAB 35
|
||||
#define DO_VERBATIM_INPUT 36
|
||||
#define SWITCH_TO_NEXT_BUFFER_VOID 37
|
||||
#define SWITCH_TO_PREV_BUFFER_VOID 38
|
||||
#define DO_END 39
|
||||
#define DO_HOME 40
|
||||
#define NEXT_HISTORY_MSG 41
|
||||
#define PREV_HISTORY_MSG 42
|
||||
#define DO_REDO 43
|
||||
#define DO_UNDO 44
|
||||
#define DO_WORDLINECHAR_COUNT 45
|
||||
#define DO_FIND_BRACKET 46
|
||||
#define DO_PREV_WORD_VOID 47
|
||||
#define DO_SUSPEND_VOID 48
|
||||
#define CANCEL_MSG 49
|
||||
#define DO_WRITEOUT_VOID 50
|
||||
#define DO_INSERTFILE_VOID 51
|
||||
#define DO_CUT_TEXT_VOID 52
|
||||
#define DO_UNCUT_TEXT 53
|
||||
#define DO_CURSORPOS_VOID 54
|
||||
#define DO_GOTOLINECOLUMN_VOID 55
|
||||
#define DO_REPLACE 56
|
||||
#define DO_JUSTIFY_VOID 57
|
||||
#define DO_PARA_BEGIN_VOID 58
|
||||
#define DO_PARA_END_VOID 59
|
||||
#define DO_FULL_JUSTIFY 60
|
||||
#define DO_MARK 61
|
||||
#define DO_RESEARCH 62
|
||||
#define DO_COPY_TEXT 63
|
||||
#define DO_INDENT_VOID 64
|
||||
#define DO_UNINDENT 65
|
||||
#define DO_SCROLL_UP 66
|
||||
#define DO_SCROLL_DOWN 67
|
||||
#define DO_NEXT_WORD_VOID 68
|
||||
#define DO_CUT_TILL_END 69
|
||||
#define NANO_GOTODIR_MSG 70
|
||||
#define NANO_LASTFILE_MSG 71
|
||||
#define NANO_FIRSTFILE_MSG 72
|
||||
#define INSERT_FILE_MSG 73
|
||||
#define NANO_MULTIBUFFER_MSG 74
|
||||
#define NANO_EXECUTE_MSG 75
|
||||
#define NANO_BACKUP_MSG 76
|
||||
#define NANO_PREPEND_MSG 77
|
||||
#define NANO_APPEND_MSG 78
|
||||
#define NANO_MAC_MSG 79
|
||||
#define NANO_DOS_MSG 80
|
||||
#define NANO_TOFILES_MSG 81
|
||||
#define NANO_NEXT_HISTORY_MSG 82
|
||||
#define NANO_PREV_HISTORY_MSG 83
|
||||
#define NANO_REGEXP_MSG 84
|
||||
#define NANO_REVERSE_MSG 85
|
||||
#define NANO_CASE_MSG 86
|
||||
#define NANO_SUSPEND_MSG 87
|
||||
#define SUSPEND_MSG 88
|
||||
#define NANO_REFRESH_MSG 89
|
||||
#define REFRESH_MSG 90
|
||||
#define NANO_WORDCOUNT_MSG 91
|
||||
#define NANO_FULLJUSTIFY_MSG 92
|
||||
#define FULLJSTIFY_MSG 93
|
||||
#define XOFF_COMPLAINT 94
|
||||
#define XON_COMPLAINT 95
|
||||
#define NANO_CUT_TILL_END_MSG 96
|
||||
#define NANO_BACKSPACE_MSG 97
|
||||
#define NANO_DELETE_MSG 98
|
||||
#define NANO_ENTER_MSG 99
|
||||
#define NANO_TAB_MSG 100
|
||||
#define NANO_VERBATIM_MSG 101
|
||||
#define NANO_NEXTFILE_MSG 102
|
||||
#define NANO_PREVFILE_MSG 103
|
||||
#define NANO_SCROLLDOWN_MSG 104
|
||||
#define NANO_SCROLLUP_MSG 105
|
||||
#define NANO_BRACKET_MSG 106
|
||||
#define NANO_PARAEND_MSG 107
|
||||
#define END_OF_PAR_MSG 108
|
||||
#define NANO_PARABEGIN_MSG 109
|
||||
#define BEG_OF_PAR_MSG 110
|
||||
#define NANO_END_MSG 111
|
||||
#define NANO_HOME_MSG 112
|
||||
#define NANO_NEXTLINE_MSG 113
|
||||
#define NANO_PREVLINE_MSG 114
|
||||
#define NANO_PREVWORD_MSG 115
|
||||
#define NANO_NEXTWORD_MSG 116
|
||||
#define NANO_BACK_MSG 117
|
||||
#define NANO_FORWARD_MSG 118
|
||||
#define NANO_REDO_MSG 119
|
||||
#define NANO_UNDO_MSG 120
|
||||
#define NANO_UNINDENT_MSG 121
|
||||
#define NANO_INDENT_MSG 122
|
||||
#define NANO_COPY_MSG 123
|
||||
#define NANO_WHEREIS_NEXT_MSG 124
|
||||
#define NANO_MARK_MSG 125
|
||||
#define NANO_REPLACE_MSG 126
|
||||
#define REPLACE_MSG 127
|
||||
#define NANO_GOTOLINE_MSG 128
|
||||
#define NANO_LASTLINE_MSG 129
|
||||
#define NANO_FIRSTLINE_MSG 130
|
||||
#define NANO_SPELL_MSG 131
|
||||
#define DO_SPELL 132
|
||||
#define NANO_CURSORPOS_MSG 133
|
||||
#define NANO_UNCUT_MSG 134
|
||||
#define GET_HELP_MSG 135
|
||||
#define NANO_HELP_MSG 136
|
||||
#define NANO_CANCEL_MSG 137
|
||||
#define NANO_EXIT_MSG 138
|
||||
#define EXIT_MSG 139
|
||||
#define NANO_EXITBROWSER_MSG 140
|
||||
#define NANO_WRITEOUT_MSG 141
|
||||
#define NANO_DISABLED_MSG 142
|
||||
#define NANO_INSERT_MSG 143
|
||||
#define WHEREIS_MSG 144
|
||||
#define NANO_WHEREIS_MSG 145
|
||||
#define NANO_PREVPAGE_MSG 146
|
||||
#define NANO_NEXTPAGE_MSG 147
|
||||
#define NANO_CUT_MSG 148
|
||||
#define DO_CUT_TEXT 149
|
||||
#define DO_NEXT_WORD 150
|
||||
#define DO_PREV_WORD 151
|
||||
|
||||
|
||||
|
||||
|
||||
#define VIEW TRUE
|
||||
#define NOVIEW FALSE
|
||||
|
||||
|
||||
56
src/prompt.c
56
src/prompt.c
@@ -152,38 +152,38 @@ int do_statusbar_input(bool *meta_key, bool *func_key, bool *have_shortcut,
|
||||
}
|
||||
|
||||
if (*have_shortcut) {
|
||||
if (s->scfunc == do_tab || s->scfunc == do_enter)
|
||||
if (s->scfunc == DO_TAB || s->scfunc == DO_ENTER)
|
||||
;
|
||||
else if (s->scfunc == total_refresh)
|
||||
else if (s->scfunc == TOTAL_REFRESH)
|
||||
total_statusbar_refresh(refresh_func);
|
||||
else if (s->scfunc == (void *) do_cut_text) {
|
||||
else if (s->scfunc == DO_CUT_TEXT) {
|
||||
/* If we're using restricted mode, the filename
|
||||
* isn't blank, and we're at the "Write File"
|
||||
* prompt, disable Cut. */
|
||||
if (!ISSET(RESTRICTED) || openfile->filename[0] ==
|
||||
'\0' || currmenu != MWRITEFILE)
|
||||
do_statusbar_cut_text();
|
||||
} else if (s->scfunc == do_right)
|
||||
} else if (s->scfunc == DO_RIGHT)
|
||||
do_statusbar_right();
|
||||
else if (s->scfunc == do_left)
|
||||
else if (s->scfunc == DO_LEFT)
|
||||
do_statusbar_left();
|
||||
|
||||
#ifndef NANO_TINY
|
||||
else if (s->scfunc == (void *) do_next_word)
|
||||
else if (s->scfunc == DO_NEXT_WORD)
|
||||
do_statusbar_next_word(FALSE);
|
||||
else if (s->scfunc == (void *) do_prev_word)
|
||||
else if (s->scfunc == DO_PREV_WORD)
|
||||
do_statusbar_prev_word(FALSE);
|
||||
#endif
|
||||
else if (s->scfunc == do_home)
|
||||
else if (s->scfunc == DO_HOME)
|
||||
do_statusbar_home();
|
||||
else if (s->scfunc == do_end)
|
||||
else if (s->scfunc == DO_END)
|
||||
do_statusbar_end();
|
||||
|
||||
#ifndef NANO_TINY
|
||||
else if (s->scfunc == do_find_bracket)
|
||||
else if (s->scfunc == DO_FIND_BRACKET)
|
||||
do_statusbar_find_bracket();
|
||||
#endif
|
||||
else if (s->scfunc == do_verbatim_input) {
|
||||
else if (s->scfunc == DO_VERBATIM_INPUT) {
|
||||
/* If we're using restricted mode, the filename
|
||||
* isn't blank, and we're at the "Write File"
|
||||
* prompt, disable verbatim input. */
|
||||
@@ -201,18 +201,18 @@ int do_statusbar_input(bool *meta_key, bool *func_key, bool *have_shortcut,
|
||||
* to indicate that we're done. */
|
||||
if (got_enter) {
|
||||
get_input(NULL, 1);
|
||||
input = sc_seq_or(do_enter, 0);
|
||||
input = sc_seq_or(DO_ENTER, 0);
|
||||
*finished = TRUE;
|
||||
}
|
||||
}
|
||||
} else if (s->scfunc == do_delete) {
|
||||
} else if (s->scfunc == DO_DELETE) {
|
||||
/* If we're using restricted mode, the filename
|
||||
* isn't blank, and we're at the "Write File"
|
||||
* prompt, disable Delete. */
|
||||
if (!ISSET(RESTRICTED) || openfile->filename[0] ==
|
||||
'\0' || currmenu != MWRITEFILE)
|
||||
do_statusbar_delete();
|
||||
} else if (s->scfunc == do_backspace) {
|
||||
} else if (s->scfunc == DO_BACKSPACE) {
|
||||
/* If we're using restricted mode, the filename
|
||||
* isn't blank, and we're at the "Write File"
|
||||
* prompt, disable Backspace. */
|
||||
@@ -227,10 +227,10 @@ int do_statusbar_input(bool *meta_key, bool *func_key, bool *have_shortcut,
|
||||
* associated functions. */
|
||||
|
||||
f = sctofunc((sc *) s);
|
||||
if (s->scfunc != NULL && s->execute == TRUE) {
|
||||
if (s->scfunc != 0 && s->execute == TRUE) {
|
||||
*ran_func = TRUE;
|
||||
if (!ISSET(VIEW_MODE) || f->viewok)
|
||||
f->scfunc();
|
||||
iso_me_harder_funcmap(f->scfunc);
|
||||
}
|
||||
*finished = TRUE;
|
||||
}
|
||||
@@ -979,19 +979,19 @@ fprintf(stderr, "get_prompt_string: answer = \"%s\", statusbar_x = %d\n", answer
|
||||
s = get_shortcut(currmenu, &kbinput, meta_key, func_key);
|
||||
|
||||
if (s)
|
||||
if (s->scfunc == (void *) cancel_msg || s->scfunc == do_enter)
|
||||
if (s->scfunc == CANCEL_MSG || s->scfunc == DO_ENTER)
|
||||
break;
|
||||
|
||||
#ifndef DISABLE_TABCOMP
|
||||
if (s && s->scfunc != do_tab)
|
||||
if (s && s->scfunc != DO_TAB)
|
||||
tabbed = FALSE;
|
||||
#endif
|
||||
|
||||
#ifndef DISABLE_TABCOMP
|
||||
#ifndef NANO_TINY
|
||||
if (s && s->scfunc == do_tab) {
|
||||
if (s && s->scfunc == DO_TAB) {
|
||||
if (history_list != NULL) {
|
||||
if (last_kbinput != sc_seq_or(do_tab, NANO_CONTROL_I))
|
||||
if (last_kbinput != sc_seq_or(DO_TAB, NANO_CONTROL_I))
|
||||
complete_len = strlen(answer);
|
||||
|
||||
if (complete_len > 0) {
|
||||
@@ -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 == (void *) prev_history_msg) {
|
||||
if (s && s->scfunc == 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 == (void *) next_history_msg) {
|
||||
} else if (s && s->scfunc == 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,
|
||||
@@ -1071,7 +1071,7 @@ fprintf(stderr, "get_prompt_string: answer = \"%s\", statusbar_x = %d\n", answer
|
||||
} else
|
||||
#endif /* !NANO_TINY */
|
||||
#ifndef DISABLE_HELP
|
||||
if (s && s->scfunc == do_help_void) {
|
||||
if (s && s->scfunc == DO_HELP_VOID) {
|
||||
update_statusbar_line(answer, statusbar_x);
|
||||
|
||||
/* This key has a shortcut list entry when it's used to
|
||||
@@ -1116,7 +1116,7 @@ fprintf(stderr, "get_prompt_string: answer = \"%s\", statusbar_x = %d\n", answer
|
||||
* we've finished putting in an answer, reset the statusbar cursor
|
||||
* position too. */
|
||||
if (s) {
|
||||
if (s->scfunc == (void *) cancel_msg || s->scfunc == do_enter ||
|
||||
if (s->scfunc == CANCEL_MSG || s->scfunc == DO_ENTER ||
|
||||
ran_func) {
|
||||
statusbar_x = old_statusbar_x;
|
||||
statusbar_pww = old_pww;
|
||||
@@ -1203,9 +1203,9 @@ int do_prompt(bool allow_tabs,
|
||||
|
||||
/* If we left the prompt via Cancel or Enter, set the return value
|
||||
* properly. */
|
||||
if (s && s->scfunc == (void *) cancel_msg)
|
||||
if (s && s->scfunc == CANCEL_MSG)
|
||||
retval = -1;
|
||||
else if (s && s->scfunc == do_enter)
|
||||
else if (s && s->scfunc == DO_ENTER)
|
||||
retval = (*answer == '\0') ? -2 : 0;
|
||||
|
||||
blank_statusbar();
|
||||
@@ -1313,7 +1313,7 @@ int do_yesno_prompt(bool all, const char *msg)
|
||||
kbinput = get_kbinput(bottomwin, &meta_key, &func_key);
|
||||
s = get_shortcut(currmenu, &kbinput, &meta_key, &func_key);
|
||||
|
||||
if (s && s->scfunc == (void *) cancel_msg)
|
||||
if (s && s->scfunc == CANCEL_MSG)
|
||||
ok = -1;
|
||||
#ifndef DISABLE_MOUSE
|
||||
else if (kbinput == KEY_MOUSE) {
|
||||
@@ -1345,7 +1345,7 @@ int do_yesno_prompt(bool all, const char *msg)
|
||||
}
|
||||
}
|
||||
#endif /* !DISABLE_MOUSE */
|
||||
else if (s && s->scfunc == total_refresh) {
|
||||
else if (s && s->scfunc == TOTAL_REFRESH) {
|
||||
total_redraw();
|
||||
continue;
|
||||
} else {
|
||||
|
||||
19
src/proto.h
19
src/proto.h
@@ -76,7 +76,7 @@ extern char *quoteerr;
|
||||
extern size_t quotelen;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
bool nodelay_mode;
|
||||
extern char *answer;
|
||||
|
||||
extern ssize_t tabsize;
|
||||
@@ -100,6 +100,7 @@ extern syntaxtype *syntaxes;
|
||||
extern char *syntaxstr;
|
||||
#endif
|
||||
|
||||
extern bool edit_refresh_needed;
|
||||
extern const shortcut *currshortcut;
|
||||
extern int currmenu;
|
||||
|
||||
@@ -542,6 +543,8 @@ 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 alloc_multidata_if_needed(filestruct *fileptr);
|
||||
#endif
|
||||
void parse_rcfile(FILE *rcstream
|
||||
#ifdef ENABLE_COLOR
|
||||
@@ -743,7 +746,7 @@ int get_mouseinput(int *mouse_x, int *mouse_y, bool allow_shortcuts);
|
||||
#endif
|
||||
const sc *get_shortcut(int menu, int *kbinput, bool
|
||||
*meta_key, bool *func_key);
|
||||
const sc *first_sc_for(int menu, void *func);
|
||||
const sc *first_sc_for(int menu, short func);
|
||||
void blank_line(WINDOW *win, int y, int x, int n);
|
||||
void blank_titlebar(void);
|
||||
void blank_topbar(void);
|
||||
@@ -759,13 +762,13 @@ void statusbar(const char *msg, ...);
|
||||
void bottombars(int menu);
|
||||
void onekey(const char *keystroke, const char *desc, size_t len);
|
||||
void reset_cursor(void);
|
||||
void edit_draw(const filestruct *fileptr, const char *converted, int
|
||||
void edit_draw(filestruct *fileptr, const char *converted, int
|
||||
line, size_t start);
|
||||
void update_line(const filestruct *fileptr, size_t index);
|
||||
void 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);
|
||||
void edit_redraw(const filestruct *old_current, size_t pww_save);
|
||||
void edit_redraw(filestruct *old_current, size_t pww_save);
|
||||
void edit_refresh(void);
|
||||
void edit_update(update_type location);
|
||||
void total_redraw(void);
|
||||
@@ -776,6 +779,7 @@ void do_cursorpos_void(void);
|
||||
void do_replace_highlight(bool highlight, const char *word);
|
||||
char *flagtostr(int flag);
|
||||
const subnfunc *sctofunc(sc *s);
|
||||
const subnfunc *getfuncfromkey(WINDOW *win);
|
||||
void print_sclist(void);
|
||||
sc *strtosc(int menu, char *input);
|
||||
function_type strtokeytype(char *str);
|
||||
@@ -783,7 +787,7 @@ int strtomenu(char *input);
|
||||
void assign_keyinfo(sc *s);
|
||||
void xon_complaint(void);
|
||||
void xoff_complaint(void);
|
||||
int sc_seq_or (void *func, int defaultval);
|
||||
int sc_seq_or (short func, int defaultval);
|
||||
void do_suspend_void(void);
|
||||
|
||||
const char *cancel_msg;
|
||||
@@ -814,6 +818,9 @@ 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);
|
||||
void enable_nodelay(void);
|
||||
void disable_nodelay(void);
|
||||
|
||||
#ifdef HAVE_REGEX_H
|
||||
const char *regexp_msg;
|
||||
|
||||
32
src/rcfile.c
32
src/rcfile.c
@@ -107,6 +107,7 @@ static exttype *endheader = NULL;
|
||||
/* End of header list */
|
||||
static colortype *endcolor = NULL;
|
||||
/* The end of the color list for the current syntax. */
|
||||
|
||||
#endif
|
||||
|
||||
/* We have an error in some part of the rcfile. Print the error message
|
||||
@@ -296,6 +297,7 @@ void parse_syntax(char *ptr)
|
||||
endsyntax->extensions = NULL;
|
||||
endsyntax->headers = NULL;
|
||||
endsyntax->next = NULL;
|
||||
endsyntax->nmultis = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Starting a new syntax type: \"%s\"\n", nameptr);
|
||||
@@ -427,7 +429,7 @@ void parse_keybinding(char *ptr)
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "newsc now address %d, menu func assigned = %d, menu = %d\n",
|
||||
&newsc, &newsc->scfunc, menu);
|
||||
&newsc, newsc->scfunc, menu);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -468,7 +470,7 @@ void parse_include(char *ptr)
|
||||
{
|
||||
struct stat rcinfo;
|
||||
FILE *rcstream;
|
||||
char *option, *full_option, *nanorc_save = nanorc;
|
||||
char *option, *nanorc_save = nanorc;
|
||||
size_t lineno_save = lineno;
|
||||
|
||||
option = ptr;
|
||||
@@ -476,37 +478,33 @@ void parse_include(char *ptr)
|
||||
option++;
|
||||
ptr = parse_argument(ptr);
|
||||
|
||||
/* Get the specified file's full path. */
|
||||
full_option = get_full_path(option);
|
||||
|
||||
if (full_option == NULL)
|
||||
full_option = mallocstrcpy(NULL, option);
|
||||
/* Can't get the specified file's full path cause it may screw up
|
||||
our cwd depending on the parent dirs' permissions, (see Savannah bug 25297) */
|
||||
|
||||
/* Don't open directories, character files, or block files. */
|
||||
if (stat(full_option, &rcinfo) != -1) {
|
||||
if (stat(option, &rcinfo) != -1) {
|
||||
if (S_ISDIR(rcinfo.st_mode) || S_ISCHR(rcinfo.st_mode) ||
|
||||
S_ISBLK(rcinfo.st_mode)) {
|
||||
rcfile_error(S_ISDIR(rcinfo.st_mode) ?
|
||||
_("\"%s\" is a directory") :
|
||||
_("\"%s\" is a device file"), option);
|
||||
goto cleanup_include;
|
||||
}
|
||||
}
|
||||
|
||||
/* Open the new syntax file. */
|
||||
if ((rcstream = fopen(full_option, "rb")) == NULL) {
|
||||
if ((rcstream = fopen(option, "rb")) == NULL) {
|
||||
rcfile_error(_("Error reading %s: %s"), option,
|
||||
strerror(errno));
|
||||
goto cleanup_include;
|
||||
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 = full_option;
|
||||
nanorc = option;
|
||||
lineno = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Parsing file \"%s\"\n", full_option);
|
||||
fprintf(stderr, "Parsing file \"%s\"\n", option);
|
||||
#endif
|
||||
|
||||
parse_rcfile(rcstream
|
||||
@@ -520,8 +518,6 @@ void parse_include(char *ptr)
|
||||
nanorc = nanorc_save;
|
||||
lineno = lineno_save;
|
||||
|
||||
cleanup_include:
|
||||
free(full_option);
|
||||
}
|
||||
|
||||
/* Return the short value corresponding to the color named in colorname,
|
||||
@@ -716,6 +712,10 @@ void parse_colors(char *ptr, bool icase)
|
||||
/* Save the ending regex string if it's valid. */
|
||||
newcolor->end_regex = (nregcomp(fgstr, icase ? REG_ICASE :
|
||||
0)) ? mallocstrcpy(NULL, fgstr) : NULL;
|
||||
|
||||
/* Lame way to skip another static counter */
|
||||
newcolor->id = endsyntax->nmultis;
|
||||
endsyntax->nmultis++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -791,7 +791,7 @@ 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 };
|
||||
short vitals[VITALS] = { DO_EXIT, DO_EXIT, CANCEL_MSG, CANCEL_MSG, CANCEL_MSG };
|
||||
int inmenus[VITALS] = { MMAIN, MHELP, MWHEREIS, MREPLACE, MGOTOLINE };
|
||||
|
||||
for (v = 0; v < VITALS; v++) {
|
||||
|
||||
32
src/search.c
32
src/search.c
@@ -28,6 +28,7 @@
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
|
||||
static bool search_last_line = FALSE;
|
||||
/* Have we gone past the last line while searching? */
|
||||
@@ -137,7 +138,7 @@ int search_init(bool replacing, bool use_answer)
|
||||
int i = 0;
|
||||
char *buf;
|
||||
sc *s;
|
||||
void *func = NULL;
|
||||
char func = 0;
|
||||
bool meta_key = FALSE, func_key = FALSE;
|
||||
static char *backupstring = NULL;
|
||||
/* The search string we'll be using. */
|
||||
@@ -235,26 +236,26 @@ int search_init(bool replacing, bool use_answer)
|
||||
#endif
|
||||
;
|
||||
#ifndef NANO_TINY
|
||||
} else if (func == (void *) case_sens_msg) {
|
||||
} else if (func == CASE_SENS_MSG) {
|
||||
TOGGLE(CASE_SENSITIVE);
|
||||
backupstring = mallocstrcpy(backupstring, answer);
|
||||
return 1;
|
||||
} else if (func == (void *) backwards_msg) {
|
||||
} else if (func == BACKWARDS_MSG) {
|
||||
TOGGLE(BACKWARDS_SEARCH);
|
||||
backupstring = mallocstrcpy(backupstring, answer);
|
||||
return 1;
|
||||
#endif
|
||||
#ifdef HAVE_REGEX_H
|
||||
} else if (func == (void *) regexp_msg) {
|
||||
} else if (func == REGEXP_MSG) {
|
||||
TOGGLE(USE_REGEXP);
|
||||
backupstring = mallocstrcpy(backupstring, answer);
|
||||
return 1;
|
||||
#endif
|
||||
} else if (func == (void *) do_replace ||
|
||||
func == (void *) no_replace_msg) {
|
||||
} else if (func == DO_REPLACE ||
|
||||
func == NO_REPLACE_MSG) {
|
||||
backupstring = mallocstrcpy(backupstring, answer);
|
||||
return -2; /* Call the opposite search function. */
|
||||
} else if (func == do_gotolinecolumn_void) {
|
||||
} else if (func == DO_GOTOLINECOLUMN_VOID) {
|
||||
do_gotolinecolumn(openfile->current->lineno,
|
||||
openfile->placewewant + 1, TRUE, TRUE, FALSE,
|
||||
TRUE);
|
||||
@@ -288,6 +289,8 @@ bool findnextstr(
|
||||
ssize_t current_y_find = openfile->current_y;
|
||||
filestruct *fileptr = openfile->current;
|
||||
const char *rev_start = fileptr->data, *found = NULL;
|
||||
const subnfunc *f;
|
||||
time_t lastkbcheck = time(NULL);
|
||||
|
||||
/* rev_start might end up 1 character before the start or after the
|
||||
* end of the line. This won't be a problem because strstrwrapper()
|
||||
@@ -302,7 +305,17 @@ bool findnextstr(
|
||||
openfile->current_x + 1;
|
||||
|
||||
/* Look for needle in the current line we're searching. */
|
||||
enable_nodelay();
|
||||
while (TRUE) {
|
||||
if (time(NULL) - lastkbcheck > 1) {
|
||||
lastkbcheck = time(NULL);
|
||||
f = getfuncfromkey(edit);
|
||||
if (f && f->scfunc == CANCEL_MSG) {
|
||||
statusbar(_("Cancelled"));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
found = strstrwrapper(fileptr->data, needle, rev_start);
|
||||
|
||||
/* We've found a potential match. */
|
||||
@@ -348,6 +361,7 @@ bool findnextstr(
|
||||
/* We've finished processing the file, so get out. */
|
||||
if (search_last_line) {
|
||||
not_found_msg(needle);
|
||||
disable_nodelay();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -405,9 +419,11 @@ bool findnextstr(
|
||||
#endif
|
||||
) {
|
||||
not_found_msg(needle);
|
||||
disable_nodelay();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
disable_nodelay();
|
||||
/* We've definitely found something. */
|
||||
openfile->current = fileptr;
|
||||
openfile->current_x = current_x_find;
|
||||
@@ -1021,7 +1037,7 @@ void do_gotolinecolumn(ssize_t line, ssize_t column, bool use_answer,
|
||||
|
||||
|
||||
s = get_shortcut(currmenu, &i, &meta_key, &func_key);
|
||||
if (s && s->scfunc == (void *) gototext_msg) {
|
||||
if (s && s->scfunc == GOTOTEXT_MSG) {
|
||||
/* Keep answer up on the statusbar. */
|
||||
search_init(TRUE, TRUE);
|
||||
|
||||
|
||||
16
src/text.c
16
src/text.c
@@ -148,7 +148,7 @@ void do_delete(void)
|
||||
#endif
|
||||
|
||||
if (do_refresh)
|
||||
edit_refresh();
|
||||
edit_refresh_needed = TRUE;
|
||||
else
|
||||
update_line(openfile->current, openfile->current_x);
|
||||
}
|
||||
@@ -346,7 +346,7 @@ void do_indent(ssize_t cols)
|
||||
set_modified();
|
||||
|
||||
/* Update the screen. */
|
||||
edit_refresh();
|
||||
edit_refresh_needed = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -423,7 +423,7 @@ void redo_cut(undo *u) {
|
||||
openfile->mark_set = FALSE;
|
||||
openfile->mark_begin = NULL;
|
||||
openfile->mark_begin_x = 0;
|
||||
edit_refresh();
|
||||
edit_refresh_needed = TRUE;
|
||||
}
|
||||
|
||||
/* Undo the last thing(s) we did */
|
||||
@@ -714,7 +714,7 @@ void do_enter(void)
|
||||
|
||||
openfile->placewewant = xplustabs();
|
||||
|
||||
edit_refresh();
|
||||
edit_refresh_needed = TRUE;
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
@@ -1956,7 +1956,7 @@ void do_justify(bool full_justify)
|
||||
last_par_line = openfile->filebot;
|
||||
break;
|
||||
} else {
|
||||
edit_refresh();
|
||||
edit_refresh_needed = TRUE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -2220,7 +2220,7 @@ void do_justify(bool full_justify)
|
||||
&finished, FALSE);
|
||||
s = get_shortcut(currmenu, &kbinput, &meta_key, &func_key);
|
||||
|
||||
if (s && s->scfunc == do_uncut_text) {
|
||||
if (s && s->scfunc == DO_UNCUT_TEXT) {
|
||||
/* Splice the justify buffer back into the file, but only if we
|
||||
* actually justified something. */
|
||||
if (first_par_line != NULL) {
|
||||
@@ -2268,7 +2268,7 @@ void do_justify(bool full_justify)
|
||||
|
||||
if (!openfile->modified)
|
||||
titlebar(NULL);
|
||||
edit_refresh();
|
||||
edit_refresh_needed = TRUE;
|
||||
}
|
||||
} else {
|
||||
unget_kbinput(kbinput, meta_key, func_key);
|
||||
@@ -2621,7 +2621,7 @@ const char *do_int_speller(const char *tempfile_name)
|
||||
|
||||
free(read_buff);
|
||||
search_replace_abort();
|
||||
edit_refresh();
|
||||
edit_refresh_needed = TRUE;
|
||||
|
||||
/* Process the end of the spell process. */
|
||||
waitpid(pid_spell, &spell_status, 0);
|
||||
|
||||
19
src/utils.c
19
src/utils.c
@@ -183,14 +183,7 @@ void sunder(char *str)
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA. */
|
||||
|
||||
#if !defined(NANO_TINY) && defined(ENABLE_NANORC)
|
||||
#ifndef HAVE_GETLINE
|
||||
/* This function is equivalent to getline(). */
|
||||
ssize_t ngetline(char **lineptr, size_t *n, FILE *stream)
|
||||
{
|
||||
return getdelim(lineptr, n, '\n', stream);
|
||||
}
|
||||
#endif
|
||||
#ifdef ENABLE_NANORC
|
||||
|
||||
#ifndef HAVE_GETDELIM
|
||||
/* This function is equivalent to getdelim(). */
|
||||
@@ -242,7 +235,15 @@ ssize_t ngetdelim(char **lineptr, size_t *n, int delim, FILE *stream)
|
||||
return (c == EOF && (indx - 1) == 0) ? -1 : indx - 1;
|
||||
}
|
||||
#endif
|
||||
#endif /* !NANO_TINY && ENABLE_NANORC */
|
||||
|
||||
#ifndef HAVE_GETLINE
|
||||
/* This function is equivalent to getline(). */
|
||||
ssize_t ngetline(char **lineptr, size_t *n, FILE *stream)
|
||||
{
|
||||
return getdelim(lineptr, n, '\n', stream);
|
||||
}
|
||||
#endif
|
||||
#endif /* ENABLE_NANORC */
|
||||
|
||||
#ifdef HAVE_REGEX_H
|
||||
/* Do the compiled regex in preg and the regex in string match the
|
||||
|
||||
232
src/winio.c
232
src/winio.c
@@ -1,4 +1,3 @@
|
||||
|
||||
/* $Id$ */
|
||||
/**************************************************************************
|
||||
* winio.c *
|
||||
@@ -123,17 +122,21 @@ void get_key_buffer(WINDOW *win)
|
||||
doupdate();
|
||||
|
||||
errcount = 0;
|
||||
while ((input = wgetch(win)) == ERR) {
|
||||
errcount++;
|
||||
if (nodelay_mode) {
|
||||
if ((input = wgetch(win)) == ERR)
|
||||
return;
|
||||
} else
|
||||
while ((input = wgetch(win)) == ERR) {
|
||||
errcount++;
|
||||
|
||||
/* If we've failed to get a character MAX_BUF_SIZE times in a
|
||||
* row, assume that the input source we were using is gone and
|
||||
* die gracefully. We could check if errno is set to EIO
|
||||
* ("Input/output error") and die gracefully in that case, but
|
||||
* it's not always set properly. Argh. */
|
||||
if (errcount == MAX_BUF_SIZE)
|
||||
handle_hupterm(0);
|
||||
}
|
||||
/* If we've failed to get a character MAX_BUF_SIZE times in a
|
||||
* row, assume that the input source we were using is gone and
|
||||
* die gracefully. We could check if errno is set to EIO
|
||||
* ("Input/output error") and die gracefully in that case, but
|
||||
* it's not always set properly. Argh. */
|
||||
if (errcount == MAX_BUF_SIZE)
|
||||
handle_hupterm(0);
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
allow_pending_sigwinch(FALSE);
|
||||
@@ -331,7 +334,12 @@ int parse_kbinput(WINDOW *win, bool *meta_key, bool *func_key)
|
||||
*func_key = FALSE;
|
||||
|
||||
/* Read in a character. */
|
||||
while ((kbinput = get_input(win, 1)) == NULL);
|
||||
if (nodelay_mode) {
|
||||
kbinput = get_input(win, 1);
|
||||
if (kbinput == 0)
|
||||
return 0;
|
||||
} else
|
||||
while ((kbinput = get_input(win, 1)) == NULL);
|
||||
|
||||
switch (*kbinput) {
|
||||
case ERR:
|
||||
@@ -489,36 +497,36 @@ int parse_kbinput(WINDOW *win, bool *meta_key, bool *func_key)
|
||||
if (retval != ERR) {
|
||||
switch (retval) {
|
||||
case NANO_CONTROL_8:
|
||||
retval = ISSET(REBIND_DELETE) ? sc_seq_or(do_delete, 0) :
|
||||
sc_seq_or(do_backspace, 0);
|
||||
retval = ISSET(REBIND_DELETE) ? sc_seq_or(DO_DELETE, 0) :
|
||||
sc_seq_or(DO_BACKSPACE, 0);
|
||||
break;
|
||||
case KEY_DOWN:
|
||||
#ifdef KEY_SDOWN
|
||||
/* ncurses and Slang don't support KEY_SDOWN. */
|
||||
case KEY_SDOWN:
|
||||
#endif
|
||||
retval = sc_seq_or((void *) do_down_void, *kbinput);
|
||||
retval = sc_seq_or(DO_DOWN_VOID, *kbinput);
|
||||
break;
|
||||
case KEY_UP:
|
||||
#ifdef KEY_SUP
|
||||
/* ncurses and Slang don't support KEY_SUP. */
|
||||
case KEY_SUP:
|
||||
#endif
|
||||
retval = sc_seq_or((void *) do_up_void, *kbinput);
|
||||
retval = sc_seq_or(DO_UP_VOID, *kbinput);
|
||||
break;
|
||||
case KEY_LEFT:
|
||||
#ifdef KEY_SLEFT
|
||||
/* Slang doesn't support KEY_SLEFT. */
|
||||
case KEY_SLEFT:
|
||||
#endif
|
||||
retval = sc_seq_or((void *) do_left, *kbinput);
|
||||
retval = sc_seq_or(DO_LEFT, *kbinput);
|
||||
break;
|
||||
case KEY_RIGHT:
|
||||
#ifdef KEY_SRIGHT
|
||||
/* Slang doesn't support KEY_SRIGHT. */
|
||||
case KEY_SRIGHT:
|
||||
#endif
|
||||
retval = sc_seq_or((void *) do_right, *kbinput);
|
||||
retval = sc_seq_or(DO_RIGHT, *kbinput);
|
||||
break;
|
||||
#ifdef KEY_SHOME
|
||||
/* HP-UX 10-11 and Slang don't support KEY_SHOME. */
|
||||
@@ -526,36 +534,36 @@ int parse_kbinput(WINDOW *win, bool *meta_key, bool *func_key)
|
||||
#endif
|
||||
case KEY_A1: /* Home (7) on numeric keypad with
|
||||
* NumLock off. */
|
||||
retval = sc_seq_or((void *) do_home, *kbinput);
|
||||
retval = sc_seq_or(DO_HOME, *kbinput);
|
||||
break;
|
||||
case KEY_BACKSPACE:
|
||||
retval = sc_seq_or((void *) do_backspace, *kbinput);
|
||||
retval = sc_seq_or(DO_BACKSPACE, *kbinput);
|
||||
break;
|
||||
#ifdef KEY_SDC
|
||||
/* Slang doesn't support KEY_SDC. */
|
||||
case KEY_SDC:
|
||||
if (ISSET(REBIND_DELETE))
|
||||
retval = sc_seq_or((void *) do_delete, *kbinput);
|
||||
retval = sc_seq_or(DO_DELETE, *kbinput);
|
||||
else
|
||||
retval = sc_seq_or((void *) do_backspace, *kbinput);
|
||||
retval = sc_seq_or(DO_BACKSPACE, *kbinput);
|
||||
break;
|
||||
#endif
|
||||
#ifdef KEY_SIC
|
||||
/* Slang doesn't support KEY_SIC. */
|
||||
case KEY_SIC:
|
||||
retval = sc_seq_or((void *) do_insertfile_void, *kbinput);
|
||||
retval = sc_seq_or(DO_INSERTFILE_VOID, *kbinput);
|
||||
break;
|
||||
#endif
|
||||
case KEY_C3: /* PageDown (4) on numeric keypad with
|
||||
* NumLock off. */
|
||||
retval = sc_seq_or((void *) do_page_down, *kbinput);
|
||||
retval = sc_seq_or(DO_PAGE_DOWN, *kbinput);
|
||||
break;
|
||||
case KEY_A3: /* PageUp (9) on numeric keypad with
|
||||
* NumLock off. */
|
||||
retval = sc_seq_or((void *) do_page_up, *kbinput);
|
||||
retval = sc_seq_or(DO_PAGE_UP, *kbinput);
|
||||
break;
|
||||
case KEY_ENTER:
|
||||
retval = sc_seq_or((void *) do_enter, *kbinput);
|
||||
retval = sc_seq_or(DO_ENTER, *kbinput);
|
||||
break;
|
||||
case KEY_B2: /* Center (5) on numeric keypad with
|
||||
* NumLock off. */
|
||||
@@ -567,7 +575,7 @@ int parse_kbinput(WINDOW *win, bool *meta_key, bool *func_key)
|
||||
/* HP-UX 10-11 and Slang don't support KEY_SEND. */
|
||||
case KEY_SEND:
|
||||
#endif
|
||||
retval = sc_seq_or((void *) do_end, *kbinput);
|
||||
retval = sc_seq_or(DO_END, *kbinput);
|
||||
break;
|
||||
#ifdef KEY_BEG
|
||||
/* Slang doesn't support KEY_BEG. */
|
||||
@@ -583,7 +591,7 @@ int parse_kbinput(WINDOW *win, bool *meta_key, bool *func_key)
|
||||
/* Slang doesn't support KEY_SCANCEL. */
|
||||
case KEY_SCANCEL:
|
||||
#endif
|
||||
retval = first_sc_for(currmenu, (void *) cancel_msg)->seq;
|
||||
retval = first_sc_for(currmenu, CANCEL_MSG)->seq;
|
||||
break;
|
||||
#endif
|
||||
#ifdef KEY_SBEG
|
||||
@@ -596,13 +604,13 @@ int parse_kbinput(WINDOW *win, bool *meta_key, bool *func_key)
|
||||
#ifdef KEY_SSUSPEND
|
||||
/* Slang doesn't support KEY_SSUSPEND. */
|
||||
case KEY_SSUSPEND:
|
||||
retval = sc_seq_or(do_suspend_void, 0);
|
||||
retval = sc_seq_or(DO_SUSPEND_VOID, 0);
|
||||
break;
|
||||
#endif
|
||||
#ifdef KEY_SUSPEND
|
||||
/* Slang doesn't support KEY_SUSPEND. */
|
||||
case KEY_SUSPEND:
|
||||
retval = sc_seq_or(do_suspend_void, 0);
|
||||
retval = sc_seq_or(DO_SUSPEND_VOID, 0);
|
||||
break;
|
||||
#endif
|
||||
#ifdef PDCURSES
|
||||
@@ -750,15 +758,15 @@ int get_escape_seq_kbinput(const int *seq, size_t seq_len)
|
||||
retval = KEY_B2;
|
||||
break;
|
||||
case 'F': /* Esc O F == End on xterm/Terminal. */
|
||||
retval = sc_seq_or(do_end, 0);
|
||||
retval = sc_seq_or(DO_END, 0);
|
||||
break;
|
||||
case 'H': /* Esc O H == Home on xterm/Terminal. */
|
||||
retval = sc_seq_or(do_home, 0);;
|
||||
retval = sc_seq_or(DO_HOME, 0);;
|
||||
break;
|
||||
case 'M': /* Esc O M == Enter on numeric keypad with
|
||||
* NumLock off on VT100/VT220/VT320/xterm/
|
||||
* rxvt/Eterm. */
|
||||
retval = sc_seq_or(do_home, 0);;
|
||||
retval = sc_seq_or(DO_HOME, 0);;
|
||||
break;
|
||||
case 'P': /* Esc O P == F1 on VT100/VT220/VT320/Mach
|
||||
* console. */
|
||||
@@ -823,7 +831,7 @@ int get_escape_seq_kbinput(const int *seq, size_t seq_len)
|
||||
case 'n': /* Esc O n == Delete (.) on numeric keypad
|
||||
* with NumLock off on VT100/VT220/VT320/
|
||||
* xterm/rxvt/Eterm/Terminal. */
|
||||
retval = sc_seq_or(do_delete, 0);;
|
||||
retval = sc_seq_or(DO_DELETE, 0);;
|
||||
break;
|
||||
case 'o': /* Esc O o == '/' on numeric keypad with
|
||||
* NumLock off on VT100/VT220/VT320/xterm/
|
||||
@@ -833,27 +841,27 @@ int get_escape_seq_kbinput(const int *seq, size_t seq_len)
|
||||
case 'p': /* Esc O p == Insert (0) on numeric keypad
|
||||
* with NumLock off on VT100/VT220/VT320/
|
||||
* rxvt/Eterm/Terminal. */
|
||||
retval = sc_seq_or(do_insertfile_void, 0);;
|
||||
retval = sc_seq_or(DO_INSERTFILE_VOID, 0);;
|
||||
break;
|
||||
case 'q': /* Esc O q == End (1) on numeric keypad
|
||||
* with NumLock off on VT100/VT220/VT320/
|
||||
* rxvt/Eterm/Terminal. */
|
||||
retval = sc_seq_or(do_end, 0);;
|
||||
retval = sc_seq_or(DO_END, 0);;
|
||||
break;
|
||||
case 'r': /* Esc O r == Down (2) on numeric keypad
|
||||
* with NumLock off on VT100/VT220/VT320/
|
||||
* rxvt/Eterm/Terminal. */
|
||||
retval = sc_seq_or(do_down_void, 0);;
|
||||
retval = sc_seq_or(DO_DOWN_VOID, 0);;
|
||||
break;
|
||||
case 's': /* Esc O s == PageDown (3) on numeric
|
||||
* keypad with NumLock off on VT100/VT220/
|
||||
* VT320/rxvt/Eterm/Terminal. */
|
||||
retval = sc_seq_or(do_page_down, 0);;
|
||||
retval = sc_seq_or(DO_PAGE_DOWN, 0);;
|
||||
break;
|
||||
case 't': /* Esc O t == Left (4) on numeric keypad
|
||||
* with NumLock off on VT100/VT220/VT320/
|
||||
* rxvt/Eterm/Terminal. */
|
||||
retval = sc_seq_or(do_left, 0);;
|
||||
retval = sc_seq_or(DO_LEFT, 0);;
|
||||
break;
|
||||
case 'u': /* Esc O u == Center (5) on numeric keypad
|
||||
* with NumLock off on VT100/VT220/VT320/
|
||||
@@ -863,22 +871,22 @@ int get_escape_seq_kbinput(const int *seq, size_t seq_len)
|
||||
case 'v': /* Esc O v == Right (6) on numeric keypad
|
||||
* with NumLock off on VT100/VT220/VT320/
|
||||
* rxvt/Eterm/Terminal. */
|
||||
retval = sc_seq_or(do_right, 0);
|
||||
retval = sc_seq_or(DO_RIGHT, 0);
|
||||
break;
|
||||
case 'w': /* Esc O w == Home (7) on numeric keypad
|
||||
* with NumLock off on VT100/VT220/VT320/
|
||||
* rxvt/Eterm/Terminal. */
|
||||
retval = sc_seq_or(do_home, 0);;
|
||||
retval = sc_seq_or(DO_HOME, 0);
|
||||
break;
|
||||
case 'x': /* Esc O x == Up (8) on numeric keypad
|
||||
* with NumLock off on VT100/VT220/VT320/
|
||||
* rxvt/Eterm/Terminal. */
|
||||
retval = sc_seq_or(do_up_void, 0);;
|
||||
retval = sc_seq_or(DO_UP_VOID, 0);
|
||||
break;
|
||||
case 'y': /* Esc O y == PageUp (9) on numeric keypad
|
||||
* with NumLock off on VT100/VT220/VT320/
|
||||
* rxvt/Eterm/Terminal. */
|
||||
retval = sc_seq_or(do_up, 0);;
|
||||
retval = sc_seq_or(DO_PAGE_UP, 0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -972,7 +980,7 @@ int get_escape_seq_kbinput(const int *seq, size_t seq_len)
|
||||
break;
|
||||
default: /* Esc [ 1 ~ == Home on
|
||||
* VT320/Linux console. */
|
||||
retval = sc_seq_or(do_home, 0);;
|
||||
retval = sc_seq_or(DO_HOME, 0);;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1023,40 +1031,40 @@ int get_escape_seq_kbinput(const int *seq, size_t seq_len)
|
||||
default: /* Esc [ 2 ~ == Insert on
|
||||
* VT220/VT320/Linux console/
|
||||
* xterm/Terminal. */
|
||||
retval = sc_seq_or(do_insertfile_void, 0);;
|
||||
retval = sc_seq_or(DO_INSERTFILE_VOID, 0);;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '3': /* Esc [ 3 ~ == Delete on VT220/VT320/
|
||||
* Linux console/xterm/Terminal. */
|
||||
retval = sc_seq_or(do_delete, 0);;
|
||||
retval = sc_seq_or(DO_DELETE, 0);;
|
||||
break;
|
||||
case '4': /* Esc [ 4 ~ == End on VT220/VT320/Linux
|
||||
* console/xterm. */
|
||||
retval = sc_seq_or(do_end, 0);;
|
||||
retval = sc_seq_or(DO_END, 0);;
|
||||
break;
|
||||
case '5': /* Esc [ 5 ~ == PageUp on VT220/VT320/
|
||||
* Linux console/xterm/Terminal;
|
||||
* Esc [ 5 ^ == PageUp on Eterm. */
|
||||
retval = sc_seq_or(do_page_up, 0);;
|
||||
retval = sc_seq_or(DO_PAGE_UP, 0);;
|
||||
break;
|
||||
case '6': /* Esc [ 6 ~ == PageDown on VT220/VT320/
|
||||
* Linux console/xterm/Terminal;
|
||||
* Esc [ 6 ^ == PageDown on Eterm. */
|
||||
retval = sc_seq_or(do_page_down, 0);;
|
||||
retval = sc_seq_or(DO_PAGE_DOWN, 0);;
|
||||
break;
|
||||
case '7': /* Esc [ 7 ~ == Home on rxvt. */
|
||||
retval = sc_seq_or(do_home, 0);
|
||||
retval = sc_seq_or(DO_HOME, 0);
|
||||
break;
|
||||
case '8': /* Esc [ 8 ~ == End on rxvt. */
|
||||
retval = sc_seq_or(do_end, 0);
|
||||
retval = sc_seq_or(DO_END, 0);
|
||||
break;
|
||||
case '9': /* Esc [ 9 == Delete on Mach console. */
|
||||
retval = sc_seq_or(do_delete, 0);;
|
||||
retval = sc_seq_or(DO_DELETE, 0);;
|
||||
break;
|
||||
case '@': /* Esc [ @ == Insert on Mach console. */
|
||||
retval = sc_seq_or(do_insertfile_void, 0);;
|
||||
retval = sc_seq_or(DO_INSERTFILE_VOID, 0);;
|
||||
break;
|
||||
case 'A': /* Esc [ A == Up on ANSI/VT220/Linux
|
||||
* console/FreeBSD console/Mach console/
|
||||
@@ -1079,23 +1087,23 @@ int get_escape_seq_kbinput(const int *seq, size_t seq_len)
|
||||
break;
|
||||
case 'F': /* Esc [ F == End on FreeBSD
|
||||
* console/Eterm. */
|
||||
retval = sc_seq_or(do_end, 0);
|
||||
retval = sc_seq_or(DO_END, 0);
|
||||
break;
|
||||
case 'G': /* Esc [ G == PageDown on FreeBSD
|
||||
* console. */
|
||||
retval = sc_seq_or(do_page_down, 0);
|
||||
retval = sc_seq_or(DO_PAGE_DOWN, 0);
|
||||
break;
|
||||
case 'H': /* Esc [ H == Home on ANSI/VT220/FreeBSD
|
||||
* console/Mach console/Eterm. */
|
||||
retval = sc_seq_or(do_home, 0);
|
||||
retval = sc_seq_or(DO_HOME, 0);
|
||||
break;
|
||||
case 'I': /* Esc [ I == PageUp on FreeBSD
|
||||
* console. */
|
||||
retval = sc_seq_or(do_page_up, 0);
|
||||
retval = sc_seq_or(DO_PAGE_UP, 0);
|
||||
break;
|
||||
case 'L': /* Esc [ L == Insert on ANSI/FreeBSD
|
||||
* console. */
|
||||
retval = sc_seq_or(do_insertfile_void, 0);
|
||||
retval = sc_seq_or(DO_INSERTFILE_VOID, 0);
|
||||
break;
|
||||
case 'M': /* Esc [ M == F1 on FreeBSD console. */
|
||||
retval = KEY_F(1);
|
||||
@@ -1143,10 +1151,10 @@ int get_escape_seq_kbinput(const int *seq, size_t seq_len)
|
||||
retval = KEY_F(8);
|
||||
break;
|
||||
case 'U': /* Esc [ U == PageDown on Mach console. */
|
||||
retval = sc_seq_or(do_page_down, 0);
|
||||
retval = sc_seq_or(DO_PAGE_DOWN, 0);
|
||||
break;
|
||||
case 'V': /* Esc [ V == PageUp on Mach console. */
|
||||
retval = sc_seq_or(do_page_up, 0);
|
||||
retval = sc_seq_or(DO_PAGE_UP, 0);
|
||||
break;
|
||||
case 'W': /* Esc [ W == F11 on FreeBSD console. */
|
||||
retval = KEY_F(11);
|
||||
@@ -1155,7 +1163,7 @@ int get_escape_seq_kbinput(const int *seq, size_t seq_len)
|
||||
retval = KEY_F(12);
|
||||
break;
|
||||
case 'Y': /* Esc [ Y == End on Mach console. */
|
||||
retval = sc_seq_or(do_end, 0);
|
||||
retval = sc_seq_or(DO_END, 0);
|
||||
break;
|
||||
case 'Z': /* Esc [ Z == F14 on FreeBSD console. */
|
||||
retval = KEY_F(14);
|
||||
@@ -1212,13 +1220,13 @@ int get_escape_seq_abcd(int kbinput)
|
||||
{
|
||||
switch (tolower(kbinput)) {
|
||||
case 'a':
|
||||
return sc_seq_or(do_up_void, 0);;
|
||||
return sc_seq_or(DO_UP_VOID, 0);;
|
||||
case 'b':
|
||||
return sc_seq_or(do_down_void, 0);;
|
||||
return sc_seq_or(DO_DOWN_VOID, 0);;
|
||||
case 'c':
|
||||
return sc_seq_or(do_right, 0);;
|
||||
return sc_seq_or(DO_RIGHT, 0);;
|
||||
case 'd':
|
||||
return sc_seq_or(do_left, 0);;
|
||||
return sc_seq_or(DO_LEFT, 0);;
|
||||
default:
|
||||
return ERR;
|
||||
}
|
||||
@@ -1709,7 +1717,7 @@ int get_mouseinput(int *mouse_x, int *mouse_y, bool allow_shortcuts)
|
||||
|
||||
/* And put back the equivalent key. */
|
||||
if (f != NULL) {
|
||||
const sc *s = first_sc_for(currmenu, (void *) f->scfunc);
|
||||
const sc *s = first_sc_for(currmenu, f->scfunc);
|
||||
if (s != NULL)
|
||||
unget_kbinput(s->seq, s->type == META, FALSE);
|
||||
}
|
||||
@@ -1738,7 +1746,7 @@ int get_mouseinput(int *mouse_x, int *mouse_y, bool allow_shortcuts)
|
||||
* wheel is equivalent to moving down three lines. */
|
||||
for (i = 0; i < 3; i++)
|
||||
unget_kbinput((mevent.bstate & BUTTON4_PRESSED) ?
|
||||
sc_seq_or(do_up_void, 0) : sc_seq_or(do_down_void, 0);, FALSE,
|
||||
sc_seq_or(do_up_void, 0) : sc_seq_or(DO_DOWN_VOID, 0);, FALSE,
|
||||
FALSE);
|
||||
|
||||
return 1;
|
||||
@@ -1790,6 +1798,32 @@ const sc *get_shortcut(int menu, int *kbinput, bool
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Try to get a function back from a window. Just a wrapper so
|
||||
functions to need to create function_key meta_key blah blah
|
||||
mmenu - what menu name to look through for valid funcs */
|
||||
const subnfunc *getfuncfromkey(WINDOW *win)
|
||||
{
|
||||
int kbinput;
|
||||
bool func_key = FALSE, meta_key = FALSE;
|
||||
const sc *s;
|
||||
const subnfunc *f;
|
||||
|
||||
kbinput = parse_kbinput(win, &meta_key, &func_key);
|
||||
if (kbinput == 0)
|
||||
return NULL;
|
||||
|
||||
s = get_shortcut(currmenu, &kbinput, &meta_key, &func_key);
|
||||
if (!s)
|
||||
return NULL;
|
||||
|
||||
f = sctofunc((sc *) s);
|
||||
return f;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Move to (x, y) in win, and display a line of n spaces with the
|
||||
* current attributes. */
|
||||
void blank_line(WINDOW *win, int y, int x, int n)
|
||||
@@ -2416,7 +2450,7 @@ void reset_cursor(void)
|
||||
* character of this page. That is, the first character of converted
|
||||
* corresponds to character number actual_x(fileptr->data, start) of the
|
||||
* line. */
|
||||
void edit_draw(const filestruct *fileptr, const char *converted, int
|
||||
void edit_draw(filestruct *fileptr, const char *converted, int
|
||||
line, size_t start)
|
||||
{
|
||||
#if !defined(NANO_TINY) || defined(ENABLE_COLOR)
|
||||
@@ -2444,6 +2478,14 @@ void edit_draw(const filestruct *fileptr, const char *converted, int
|
||||
if (openfile->colorstrings != NULL && !ISSET(NO_COLOR_SYNTAX)) {
|
||||
const colortype *tmpcolor = openfile->colorstrings;
|
||||
|
||||
/* Set up multi-line color data for this line if it's not yet calculated */
|
||||
if (fileptr->multidata == NULL && openfile->syntax
|
||||
&& openfile->syntax->nmultis > 0) {
|
||||
int i;
|
||||
fileptr->multidata = nmalloc(openfile->syntax->nmultis * sizeof(short));
|
||||
for (i = 0; i < openfile->syntax->nmultis; i++)
|
||||
fileptr->multidata[i] = -1; /* Assue this applies until we know otherwise */
|
||||
}
|
||||
for (; tmpcolor != NULL; tmpcolor = tmpcolor->next) {
|
||||
int x_start;
|
||||
/* Starting column for mvwaddnstr. Zero-based. */
|
||||
@@ -2509,7 +2551,7 @@ void edit_draw(const filestruct *fileptr, const char *converted, int
|
||||
}
|
||||
k = startmatch.rm_eo;
|
||||
}
|
||||
} else {
|
||||
} else if (fileptr->multidata != NULL && fileptr->multidata[tmpcolor->id] != CNONE) {
|
||||
/* This is a multi-line regex. There are two steps.
|
||||
* First, we have to see if the beginning of the line is
|
||||
* colored by a start on an earlier line, and an end on
|
||||
@@ -2526,6 +2568,22 @@ void edit_draw(const filestruct *fileptr, const char *converted, int
|
||||
regoff_t start_col;
|
||||
/* Where it starts in that line. */
|
||||
const filestruct *end_line;
|
||||
short md = fileptr->multidata[tmpcolor->id];
|
||||
|
||||
if (md == -1)
|
||||
fileptr->multidata[tmpcolor->id] = CNONE; /* until we find out otherwise */
|
||||
else if (md == CNONE)
|
||||
continue;
|
||||
else if (md == CWHOLELINE) {
|
||||
mvwaddnstr(edit, line, 0, converted, -1);
|
||||
continue;
|
||||
} else if (md == CBEGINBEFORE) {
|
||||
regexec(tmpcolor->end, fileptr->data, 1, &endmatch, 0);
|
||||
paintlen = actual_x(converted, strnlenpt(fileptr->data,
|
||||
endmatch.rm_eo) - start);
|
||||
mvwaddnstr(edit, line, 0, converted, paintlen);
|
||||
continue;
|
||||
}
|
||||
|
||||
while (start_line != NULL && regexec(tmpcolor->start,
|
||||
start_line->data, 1, &startmatch, 0) ==
|
||||
@@ -2589,15 +2647,16 @@ void edit_draw(const filestruct *fileptr, const char *converted, int
|
||||
* expanded location of the end of the match minus
|
||||
* the expanded location of the beginning of the
|
||||
* page. */
|
||||
if (end_line != fileptr)
|
||||
if (end_line != fileptr) {
|
||||
paintlen = -1;
|
||||
else
|
||||
fileptr->multidata[tmpcolor->id] = CWHOLELINE;
|
||||
} else {
|
||||
paintlen = actual_x(converted,
|
||||
strnlenpt(fileptr->data,
|
||||
endmatch.rm_eo) - start);
|
||||
|
||||
fileptr->multidata[tmpcolor->id] = CBEGINBEFORE;
|
||||
}
|
||||
mvwaddnstr(edit, line, 0, converted, paintlen);
|
||||
|
||||
step_two:
|
||||
/* Second step, we look for starts on this line. */
|
||||
start_col = 0;
|
||||
@@ -2642,6 +2701,9 @@ void edit_draw(const filestruct *fileptr, const char *converted, int
|
||||
|
||||
mvwaddnstr(edit, line, x_start,
|
||||
converted + index, paintlen);
|
||||
if (paintlen > 0)
|
||||
fileptr->multidata[tmpcolor->id] = CSTARTENDHERE;
|
||||
|
||||
}
|
||||
} else {
|
||||
/* There is no end on this line. But we
|
||||
@@ -2662,6 +2724,7 @@ void edit_draw(const filestruct *fileptr, const char *converted, int
|
||||
/* We painted to the end of the line, so
|
||||
* don't bother checking any more
|
||||
* starts. */
|
||||
fileptr->multidata[tmpcolor->id] = CENDAFTER;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -2751,7 +2814,7 @@ void edit_draw(const 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(const filestruct *fileptr, size_t index)
|
||||
void update_line(filestruct *fileptr, size_t index)
|
||||
{
|
||||
int line;
|
||||
/* The line in the edit window that we want to update. */
|
||||
@@ -2824,7 +2887,7 @@ bool need_vertical_update(size_t pww_save)
|
||||
void edit_scroll(scroll_dir direction, ssize_t nlines)
|
||||
{
|
||||
bool do_redraw = need_vertical_update(0);
|
||||
const filestruct *foo;
|
||||
filestruct *foo;
|
||||
ssize_t i;
|
||||
|
||||
/* Don't bother scrolling less than one line. */
|
||||
@@ -2919,11 +2982,11 @@ void edit_scroll(scroll_dir direction, ssize_t nlines)
|
||||
|
||||
/* Update any lines between old_current and current that need to be
|
||||
* updated. Use this if we've moved without changing any text. */
|
||||
void edit_redraw(const filestruct *old_current, size_t pww_save)
|
||||
void edit_redraw(filestruct *old_current, size_t pww_save)
|
||||
{
|
||||
bool do_redraw = need_vertical_update(0) ||
|
||||
need_vertical_update(pww_save);
|
||||
const filestruct *foo = NULL;
|
||||
filestruct *foo = NULL;
|
||||
|
||||
/* If either old_current or current is offscreen, scroll the edit
|
||||
* window until it's onscreen and get out. */
|
||||
@@ -3031,7 +3094,7 @@ void edit_redraw(const filestruct *old_current, size_t pww_save)
|
||||
* if we've moved and changed text. */
|
||||
void edit_refresh(void)
|
||||
{
|
||||
const filestruct *foo;
|
||||
filestruct *foo;
|
||||
int nlines;
|
||||
|
||||
if (openfile->current->lineno < openfile->edittop->lineno ||
|
||||
@@ -3183,6 +3246,19 @@ void do_cursorpos_void(void)
|
||||
do_cursorpos(FALSE);
|
||||
}
|
||||
|
||||
void enable_nodelay(void)
|
||||
{
|
||||
nodelay_mode = TRUE;
|
||||
nodelay(edit, TRUE);
|
||||
}
|
||||
|
||||
void disable_nodelay(void)
|
||||
{
|
||||
nodelay_mode = FALSE;
|
||||
nodelay(edit, FALSE);
|
||||
}
|
||||
|
||||
|
||||
/* Highlight the current word being replaced or spell checked. We
|
||||
* expect word to have tabs and control characters expanded. */
|
||||
void do_replace_highlight(bool highlight, const char *word)
|
||||
|
||||
Reference in New Issue
Block a user