summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--linenoise/linenoise.c62
-rw-r--r--txr.112
2 files changed, 74 insertions, 0 deletions
diff --git a/linenoise/linenoise.c b/linenoise/linenoise.c
index fedb7805..782fdfde 100644
--- a/linenoise/linenoise.c
+++ b/linenoise/linenoise.c
@@ -1046,6 +1046,51 @@ static size_t scan_rev(const char *s, size_t i)
}
}
+static size_t scan_match_fwd(const char *s, size_t i, int mch)
+{
+ while (s[++i]) {
+ int ch = s[i];
+
+ if (ch == mch)
+ return i;
+
+ switch (ch) {
+ case '(':
+ if ((i = scan_match_fwd(s, i, ')')) == -1)
+ return -1;
+ break;
+ case '[':
+ if ((i = scan_match_fwd(s, i, ']')) == -1)
+ return -1;
+ break;
+ case '{':
+ if ((i = scan_match_fwd(s, i, '}')) == -1)
+ return -1;
+ break;
+ case ')': case ']': case '}':
+ return -1;
+ default:
+ break;
+ }
+ }
+
+ return -1;
+}
+
+static size_t scan_fwd(const char *s, size_t i)
+{
+ switch (s[i]) {
+ case '(':
+ return scan_match_fwd(s, i, ')');
+ case '[':
+ return scan_match_fwd(s, i, ']');
+ case '{':
+ return scan_match_fwd(s, i, '}');
+ default:
+ return -1;
+ }
+}
+
static void usec_delay(lino_t *l, long usec)
{
#if HAVE_POLL
@@ -1220,6 +1265,20 @@ static void edit_move_end(lino_t *l) {
}
}
+static void edit_move_matching_paren(lino_t *l)
+{
+ size_t fw = scan_fwd(l->data, l->dpos);
+ size_t re = scan_rev(l->data, l->dpos);
+
+ if (fw != -1) {
+ l->dpos = fw;
+ l->need_refresh = 1;
+ } else if (re != -1) {
+ l->dpos = re;
+ l->need_refresh = 1;
+ }
+}
+
/* Substitute the currently edited line with the next or previous history
* entry as specified by 'dir'. */
#define LINENOISE_HISTORY_NEXT 0
@@ -1828,6 +1887,9 @@ static int edit(lino_t *l, const char *prompt)
case CTL('E'):
edit_move_end(l);
break;
+ case CTL(']'):
+ edit_move_matching_paren(l);
+ break;
case CTL('L'):
lino_clear_screen(l);
l->need_refresh = 1;
diff --git a/txr.1 b/txr.1
index 53d7e32a..76fda8f6 100644
--- a/txr.1
+++ b/txr.1
@@ -33588,6 +33588,18 @@ such that the last character of the line is to the left of the cursor
position. On terminals which have the Home and End keys, these may also
be used instead of Ctrl-A and Ctrl-E.
+.NP* Jump to Matching Parenthesis
+
+If the cursor is on an opening or closing parenthesis, brace or bracket,
+the Ctrl-] command will jump to the matching character. The logic for
+finding the matching character is identical to that of the Parenthesis Matching
+feature.
+
+Note: the Ctrl-] character can be produced on some terminals using Ctrl-5
+(using the keyboard home row 5, not the numeric keypad 5). This the same
+key which produces the % character when Shift is used. The % character is
+used in the Vi editor for parenthesis matching.
+
.NP* Character Swap
The Ctrl-T (twiddle) command exchanges the character under the cursor with the