allow specifying matching bracket characters other than the default via

the "matchbrackets" rcfile option


git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@3259 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
master
David Lawrence Ramsey 2006-01-06 21:51:10 +00:00
parent a248863b43
commit d89617fb17
9 changed files with 82 additions and 56 deletions

View File

@ -8,10 +8,12 @@ CVS code -
ASCII. Changes to main(), nano.1, nanorc.5, and ASCII. Changes to main(), nano.1, nanorc.5, and
nanorc.sample. (DLR) nanorc.sample. (DLR)
- Rework the bracket searching code to handle multibyte bracket - Rework the bracket searching code to handle multibyte bracket
characters. New functions mbstrpbrk() and mbrevstrpbrk(); characters, and allow specifying matching bracket characters
changes to find_statusbar_bracket_match(), other than the default via the "matchbrackets" rcfile option.
do_statusbar_find_bracket(), find_bracket_match(), and New functions mbstrpbrk() and mbrevstrpbrk(); changes to
do_find_bracket(). (DLR) find_statusbar_bracket_match(), do_statusbar_find_bracket(),
find_bracket_match(), do_find_bracket(), main(),
nanorc.5, and nanorc.sample. (DLR)
- chars.c: - chars.c:
mbstrchr() mbstrchr()
- Make parameter c const. (DLR) - Make parameter c const. (DLR)

View File

@ -6,7 +6,7 @@
.\" Public License for copying conditions. There is NO warranty. .\" Public License for copying conditions. There is NO warranty.
.\" .\"
.\" $Id$ .\" $Id$
.TH NANORC 5 "version 1.3.10" "January 02, 2006" .TH NANORC 5 "version 1.3.10" "January 06, 2006"
.\" Please adjust this date whenever revising the manpage. .\" Please adjust this date whenever revising the manpage.
.\" .\"
.SH NAME .SH NAME
@ -77,6 +77,11 @@ default value is -8.
Enable \fI~/.nano_history\fP for saving and reading search/replace Enable \fI~/.nano_history\fP for saving and reading search/replace
strings. strings.
.TP .TP
.B set matchbrackets "\fIstring\fP"
Set the opening and closing brackets that can be found by bracket
searches. The former set must come before the latter set, and both must
be in the same order. The default value is "\fI(<[{)>]}\fP".
.TP
.B set/unset morespace .B set/unset morespace
Allow use of the blank line below the titlebar as extra editing space. Allow use of the blank line below the titlebar as extra editing space.
.TP .TP

View File

@ -45,6 +45,12 @@
## Enable ~/.nano_history for saving and reading search/replace strings. ## Enable ~/.nano_history for saving and reading search/replace strings.
# set historylog # set historylog
## The opening and closing brackets that can be found by bracket
## searches. The former set must come before the latter set, and both
## must be in the same order.
##
# set matchbrackets "(<[{)>]}"
## Use the blank line below the titlebar as extra editing space. ## Use the blank line below the titlebar as extra editing space.
# set morespace # set morespace
@ -331,7 +337,7 @@
## highlight possible errors and parameters ## highlight possible errors and parameters
# icolor brightwhite "^[[:space:]]*(set|unset|syntax|i?color).*$" # icolor brightwhite "^[[:space:]]*(set|unset|syntax|i?color).*$"
## set, unset and syntax ## set, unset and syntax
# icolor cyan "^[[:space:]]*(set|unset)[[:space:]]+(autoindent|backup|backupdir|backwards|brackets|casesensitive|const|cut|fill|historylog|morespace|mouse|multibuffer|noconvert|nofollow|nohelp|nonewlines|nowrap|operatingdir|preserve|punct|quickblank)\>" "^[[:space:]]*(set|unset)[[:space:]]+(quotestr|rebinddelete|rebindkeypad|regexp|smarthome|smooth|speller|suspend|tabsize|tabstospaces|tempfile|view|whitespace|wordbounds)\>" # icolor cyan "^[[:space:]]*(set|unset)[[:space:]]+(autoindent|backup|backupdir|backwards|brackets|casesensitive|const|cut|fill|historylog|matchbrackets|morespace|mouse|multibuffer|noconvert|nofollow|nohelp|nonewlines|nowrap|operatingdir|preserve|punct|quickblank)\>" "^[[:space:]]*(set|unset)[[:space:]]+(quotestr|rebinddelete|rebindkeypad|regexp|smarthome|smooth|speller|suspend|tabsize|tabstospaces|tempfile|view|whitespace|wordbounds)\>"
# icolor green "^[[:space:]]*(set|unset|syntax)\>" # icolor green "^[[:space:]]*(set|unset|syntax)\>"
## colors ## colors
# icolor yellow "^[[:space:]]*i?color[[:space:]]*(bright)?(white|black|red|blue|green|yellow|magenta|cyan)?(,(white|black|red|blue|green|yellow|magenta|cyan))?\>" # icolor yellow "^[[:space:]]*i?color[[:space:]]*(bright)?(white|black|red|blue|green|yellow|magenta|cyan)?(,(white|black|red|blue|green|yellow|magenta|cyan))?\>"

View File

@ -3,7 +3,7 @@
* global.c * * global.c *
* * * *
* Copyright (C) 1999-2004 Chris Allegretta * * Copyright (C) 1999-2004 Chris Allegretta *
* Copyright (C) 2005 David Lawrence Ramsey * * Copyright (C) 2005-2006 David Lawrence Ramsey *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2, or (at your option) * * the Free Software Foundation; either version 2, or (at your option) *
@ -65,6 +65,12 @@ partition *filepart = NULL;
openfilestruct *openfile = NULL; openfilestruct *openfile = NULL;
/* The list of all open file buffers. */ /* The list of all open file buffers. */
#ifndef NANO_TINY
char *matchbrackets = NULL;
/* The opening and closing brackets that can be found by bracket
* searches. */
#endif
#if !defined(NANO_TINY) && defined(ENABLE_NANORC) #if !defined(NANO_TINY) && defined(ENABLE_NANORC)
char *whitespace = NULL; char *whitespace = NULL;
/* The characters used when displaying the first characters of /* The characters used when displaying the first characters of

View File

@ -3,7 +3,7 @@
* nano.c * * nano.c *
* * * *
* Copyright (C) 1999-2004 Chris Allegretta * * Copyright (C) 1999-2004 Chris Allegretta *
* Copyright (C) 2005 David Lawrence Ramsey * * Copyright (C) 2005-2006 David Lawrence Ramsey *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2, or (at your option) * * the Free Software Foundation; either version 2, or (at your option) *
@ -1955,12 +1955,15 @@ int main(int argc, char **argv)
#endif #endif
#ifndef DISABLE_JUSTIFY #ifndef DISABLE_JUSTIFY
/* If punct wasn't specified, set its default value. */
if (punct == NULL) if (punct == NULL)
punct = mallocstrcpy(NULL, "!.?"); punct = mallocstrcpy(NULL, "!.?");
/* If brackets wasn't specified, set its default value. */
if (brackets == NULL) if (brackets == NULL)
brackets = mallocstrcpy(NULL, "\"')>]}"); brackets = mallocstrcpy(NULL, "\"')>]}");
/* If quotestr wasn't specified, set its default value. */
if (quotestr == NULL) if (quotestr == NULL)
quotestr = mallocstrcpy(NULL, quotestr = mallocstrcpy(NULL,
#ifdef HAVE_REGEX_H #ifdef HAVE_REGEX_H
@ -2000,6 +2003,12 @@ int main(int argc, char **argv)
} }
#endif #endif
#ifndef NANO_TINY
/* If matchbrackets wasn't specified, set its default value. */
if (matchbrackets == NULL)
matchbrackets = mallocstrcpy(NULL, "(<[{)>]}");
#endif
#if !defined(NANO_TINY) && defined(ENABLE_NANORC) #if !defined(NANO_TINY) && defined(ENABLE_NANORC)
/* If whitespace wasn't specified, set its default value. */ /* If whitespace wasn't specified, set its default value. */
if (whitespace == NULL) { if (whitespace == NULL) {

View File

@ -711,22 +711,20 @@ bool find_statusbar_bracket_match(bool reverse, const char
void do_statusbar_find_bracket(void) void do_statusbar_find_bracket(void)
{ {
size_t statusbar_x_save, pww_save; size_t statusbar_x_save, pww_save;
const char *bracket_list = "(<[{)>]}";
/* The list of brackets we can find matches to. */
const char *ch; const char *ch;
/* The location in bracket_list of the bracket at the current /* The location in matchbrackets of the bracket at the current
* cursor position. */ * cursor position. */
int ch_len; int ch_len;
/* The length of ch in bytes. */ /* The length of ch in bytes. */
const char *wanted_ch; const char *wanted_ch;
/* The location in bracket_list of the bracket complementing the /* The location in matchbrackets of the bracket complementing
* bracket at the current cursor position. */ * the bracket at the current cursor position. */
int wanted_ch_len; int wanted_ch_len;
/* The length of wanted_ch in bytes. */ /* The length of wanted_ch in bytes. */
char *bracket_set; char *bracket_set;
/* The pair of characters in ch and wanted_ch. */ /* The pair of characters in ch and wanted_ch. */
size_t bracket_halflist; size_t matchhalf;
/* The number of characters in one half of bracket_list. */ /* The number of characters in one half of matchbrackets. */
size_t count = 1; size_t count = 1;
/* The initial bracket count. */ /* The initial bracket count. */
bool reverse; bool reverse;
@ -734,11 +732,11 @@ void do_statusbar_find_bracket(void)
char *found_ch; char *found_ch;
/* The character we find. */ /* The character we find. */
assert(mbstrlen(bracket_list) % 2 == 0); assert(mbstrlen(matchbrackets) % 2 == 0);
ch = answer + statusbar_x; ch = answer + statusbar_x;
if (ch == '\0' || (ch = mbstrchr(bracket_list, ch)) == NULL) if (ch == '\0' || (ch = mbstrchr(matchbrackets, ch)) == NULL)
return; return;
/* Save where we are. */ /* Save where we are. */
@ -746,27 +744,27 @@ void do_statusbar_find_bracket(void)
pww_save = statusbar_pww; pww_save = statusbar_pww;
/* If we're on an opening bracket, which must be in the first half /* If we're on an opening bracket, which must be in the first half
* of bracket_list, we want to search forwards for a closing * of matchbrackets, we want to search forwards for a closing
* bracket. If we're on a closing bracket, which must be in the * bracket. If we're on a closing bracket, which must be in the
* second half of bracket_list, we want to search backwards for an * second half of matchbrackets, we want to search backwards for an
* opening bracket. */ * opening bracket. */
bracket_halflist = mbstrlen(bracket_list) / 2; matchhalf = mbstrlen(matchbrackets) / 2;
reverse = ((ch - bracket_list) > bracket_halflist); reverse = ((ch - matchbrackets) > matchhalf);
/* If we're on an opening bracket, set wanted_ch to the character /* If we're on an opening bracket, set wanted_ch to the character
* that's bracket_halflist characters after ch. If we're on a * that's matchhalf characters after ch. If we're on a closing
* closing bracket, set wanted_ch to the character that's * bracket, set wanted_ch to the character that's matchhalf
* bracket_halflist characters before ch. */ * characters before ch. */
wanted_ch = ch; wanted_ch = ch;
while (bracket_halflist > 0) { while (matchhalf > 0) {
if (reverse) if (reverse)
wanted_ch = bracket_list + move_mbleft(bracket_list, wanted_ch = matchbrackets + move_mbleft(matchbrackets,
wanted_ch - bracket_list); wanted_ch - matchbrackets);
else else
wanted_ch += move_mbright(wanted_ch, 0); wanted_ch += move_mbright(wanted_ch, 0);
bracket_halflist--; matchhalf--;
} }
ch_len = parse_mbchar(ch, NULL, NULL); ch_len = parse_mbchar(ch, NULL, NULL);

View File

@ -48,6 +48,10 @@ extern filestruct *jusbuffer;
extern partition *filepart; extern partition *filepart;
extern openfilestruct *openfile; extern openfilestruct *openfile;
#ifndef NANO_TINY
extern char *matchbrackets;
#endif
#if !defined(NANO_TINY) && defined(ENABLE_NANORC) #if !defined(NANO_TINY) && defined(ENABLE_NANORC)
extern char *whitespace; extern char *whitespace;
extern int whitespace_len[2]; extern int whitespace_len[2];

View File

@ -3,7 +3,7 @@
* rcfile.c * * rcfile.c *
* * * *
* Copyright (C) 2001-2004 Chris Allegretta * * Copyright (C) 2001-2004 Chris Allegretta *
* Copyright (C) 2005 David Lawrence Ramsey * * Copyright (C) 2005-2006 David Lawrence Ramsey *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2, or (at your option) * * the Free Software Foundation; either version 2, or (at your option) *
@ -81,6 +81,7 @@ const static rcoption rcopts[] = {
{"casesensitive", CASE_SENSITIVE}, {"casesensitive", CASE_SENSITIVE},
{"cut", CUT_TO_END}, {"cut", CUT_TO_END},
{"historylog", HISTORYLOG}, {"historylog", HISTORYLOG},
{"matchbrackets", 0},
{"noconvert", NO_CONVERT}, {"noconvert", NO_CONVERT},
{"quickblank", QUICK_BLANK}, {"quickblank", QUICK_BLANK},
{"smarthome", SMART_HOME}, {"smarthome", SMART_HOME},
@ -144,13 +145,10 @@ char *parse_next_word(char *ptr)
return ptr; return ptr;
} }
/* The keywords operatingdir, backupdir, fill, tabsize, speller, punct, /* Parse an argument, with optional quotes, after a keyword that takes
* brackets, quotestr, and whitespace take an argument when set. Among * one. If the next word starts with a ", we say that it ends with the
* these, operatingdir, backupdir, speller, punct, brackets, quotestr, * last " of the line. Otherwise, we interpret it as usual, so that the
* and whitespace have to allow tabs and spaces in the argument. Thus, * arguments can contain "'s too. */
* if the next word starts with a ", we say it ends with the last " of
* the line. Otherwise, the word is interpreted as usual. That is so
* the arguments can contain "s too. */
char *parse_argument(char *ptr) char *parse_argument(char *ptr)
{ {
const char *ptr_bak = ptr; const char *ptr_bak = ptr;

View File

@ -1130,22 +1130,20 @@ void do_find_bracket(void)
{ {
filestruct *current_save; filestruct *current_save;
size_t current_x_save, pww_save; size_t current_x_save, pww_save;
const char *bracket_list = "(<[{)>]}";
/* The list of brackets we can find matches to. */
const char *ch; const char *ch;
/* The location in bracket_list of the bracket at the current /* The location in matchbrackets of the bracket at the current
* cursor position. */ * cursor position. */
int ch_len; int ch_len;
/* The length of ch in bytes. */ /* The length of ch in bytes. */
const char *wanted_ch; const char *wanted_ch;
/* The location in bracket_list of the bracket complementing the /* The location in matchbrackets of the bracket complementing
* bracket at the current cursor position. */ * the bracket at the current cursor position. */
int wanted_ch_len; int wanted_ch_len;
/* The length of wanted_ch in bytes. */ /* The length of wanted_ch in bytes. */
char *bracket_set; char *bracket_set;
/* The pair of characters in ch and wanted_ch. */ /* The pair of characters in ch and wanted_ch. */
size_t bracket_halflist; size_t matchhalf;
/* The number of characters in one half of bracket_list. */ /* The number of characters in one half of matchbrackets. */
size_t count = 1; size_t count = 1;
/* The initial bracket count. */ /* The initial bracket count. */
bool reverse; bool reverse;
@ -1153,11 +1151,11 @@ void do_find_bracket(void)
char *found_ch; char *found_ch;
/* The character we find. */ /* The character we find. */
assert(mbstrlen(bracket_list) % 2 == 0); assert(mbstrlen(matchbrackets) % 2 == 0);
ch = openfile->current->data + openfile->current_x; ch = openfile->current->data + openfile->current_x;
if (ch == '\0' || (ch = mbstrchr(bracket_list, ch)) == NULL) { if (ch == '\0' || (ch = mbstrchr(matchbrackets, ch)) == NULL) {
statusbar(_("Not a bracket")); statusbar(_("Not a bracket"));
return; return;
} }
@ -1168,27 +1166,27 @@ void do_find_bracket(void)
pww_save = openfile->placewewant; pww_save = openfile->placewewant;
/* If we're on an opening bracket, which must be in the first half /* If we're on an opening bracket, which must be in the first half
* of bracket_list, we want to search forwards for a closing * of matchbrackets, we want to search forwards for a closing
* bracket. If we're on a closing bracket, which must be in the * bracket. If we're on a closing bracket, which must be in the
* second half of bracket_list, we want to search backwards for an * second half of matchbrackets, we want to search backwards for an
* opening bracket. */ * opening bracket. */
bracket_halflist = mbstrlen(bracket_list) / 2; matchhalf = mbstrlen(matchbrackets) / 2;
reverse = ((ch - bracket_list) > bracket_halflist); reverse = ((ch - matchbrackets) > matchhalf);
/* If we're on an opening bracket, set wanted_ch to the character /* If we're on an opening bracket, set wanted_ch to the character
* that's bracket_halflist characters after ch. If we're on a * that's matchhalf characters after ch. If we're on a closing
* closing bracket, set wanted_ch to the character that's * bracket, set wanted_ch to the character that's matchhalf
* bracket_halflist characters before ch. */ * characters before ch. */
wanted_ch = ch; wanted_ch = ch;
while (bracket_halflist > 0) { while (matchhalf > 0) {
if (reverse) if (reverse)
wanted_ch = bracket_list + move_mbleft(bracket_list, wanted_ch = matchbrackets + move_mbleft(matchbrackets,
wanted_ch - bracket_list); wanted_ch - matchbrackets);
else else
wanted_ch += move_mbright(wanted_ch, 0); wanted_ch += move_mbright(wanted_ch, 0);
bracket_halflist--; matchhalf--;
} }
ch_len = parse_mbchar(ch, NULL, NULL); ch_len = parse_mbchar(ch, NULL, NULL);