Import readline 8.0
[deliverable/binutils-gdb.git] / readline / parens.c
CommitLineData
cc88a640 1/* parens.c -- implementation of matching parentheses feature. */
d60d9f65 2
cb41b9e7 3/* Copyright (C) 1987, 1989, 1992-2015, 2017 Free Software Foundation, Inc.
d60d9f65 4
cc88a640
JK
5 This file is part of the GNU Readline Library (Readline), a library
6 for reading lines of text with interactive input and history editing.
d60d9f65 7
cc88a640
JK
8 Readline is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
d60d9f65
SS
11 (at your option) any later version.
12
cc88a640
JK
13 Readline is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
d60d9f65
SS
16 GNU General Public License for more details.
17
cc88a640
JK
18 You should have received a copy of the GNU General Public License
19 along with Readline. If not, see <http://www.gnu.org/licenses/>.
20*/
21
d60d9f65
SS
22#define READLINE_LIBRARY
23
5bdf8622
DJ
24#if defined (__TANDEM)
25# include <floss.h>
26#endif
27
d60d9f65
SS
28#include "rlconf.h"
29
d60d9f65
SS
30#if defined (HAVE_CONFIG_H)
31# include <config.h>
32#endif
33
34#include <stdio.h>
35#include <sys/types.h>
36
9255ee31
EZ
37#if defined (HAVE_UNISTD_H)
38# include <unistd.h>
39#endif
40
cc88a640 41#include "posixselect.h"
d60d9f65
SS
42
43#if defined (HAVE_STRING_H)
44# include <string.h>
45#else /* !HAVE_STRING_H */
46# include <strings.h>
47#endif /* !HAVE_STRING_H */
48
49#if !defined (strchr) && !defined (__STDC__)
50extern char *strchr (), *strrchr ();
51#endif /* !strchr && !__STDC__ */
52
53#include "readline.h"
1b17e766 54#include "rlprivate.h"
d60d9f65 55
9255ee31 56static int find_matching_open PARAMS((char *, int, int));
d60d9f65
SS
57
58/* Non-zero means try to blink the matching open parenthesis when the
59 close parenthesis is inserted. */
d60d9f65 60int rl_blink_matching_paren = 0;
d60d9f65 61
9255ee31
EZ
62static int _paren_blink_usec = 500000;
63
1b17e766
EZ
64/* Change emacs_standard_keymap to have bindings for paren matching when
65 ON_OR_OFF is 1, change them back to self_insert when ON_OR_OFF == 0. */
66void
cb41b9e7 67_rl_enable_paren_matching (int on_or_off)
1b17e766
EZ
68{
69 if (on_or_off)
775e241e
TT
70 {
71 /* ([{ */
1b17e766
EZ
72 rl_bind_key_in_map (')', rl_insert_close, emacs_standard_keymap);
73 rl_bind_key_in_map (']', rl_insert_close, emacs_standard_keymap);
74 rl_bind_key_in_map ('}', rl_insert_close, emacs_standard_keymap);
775e241e
TT
75
76#if defined (VI_MODE)
77 /* ([{ */
78 rl_bind_key_in_map (')', rl_insert_close, vi_insertion_keymap);
79 rl_bind_key_in_map (']', rl_insert_close, vi_insertion_keymap);
80 rl_bind_key_in_map ('}', rl_insert_close, vi_insertion_keymap);
81#endif
1b17e766
EZ
82 }
83 else
775e241e
TT
84 {
85 /* ([{ */
1b17e766
EZ
86 rl_bind_key_in_map (')', rl_insert, emacs_standard_keymap);
87 rl_bind_key_in_map (']', rl_insert, emacs_standard_keymap);
88 rl_bind_key_in_map ('}', rl_insert, emacs_standard_keymap);
775e241e
TT
89
90#if defined (VI_MODE)
91 /* ([{ */
92 rl_bind_key_in_map (')', rl_insert, vi_insertion_keymap);
93 rl_bind_key_in_map (']', rl_insert, vi_insertion_keymap);
94 rl_bind_key_in_map ('}', rl_insert, vi_insertion_keymap);
95#endif
1b17e766
EZ
96 }
97}
d60d9f65 98
9255ee31 99int
cb41b9e7 100rl_set_paren_blink_timeout (int u)
9255ee31
EZ
101{
102 int o;
103
104 o = _paren_blink_usec;
105 if (u > 0)
106 _paren_blink_usec = u;
107 return (o);
108}
109
d60d9f65 110int
cb41b9e7 111rl_insert_close (int count, int invoking_key)
d60d9f65
SS
112{
113 if (rl_explicit_arg || !rl_blink_matching_paren)
9255ee31 114 _rl_insert_char (count, invoking_key);
d60d9f65
SS
115 else
116 {
117#if defined (HAVE_SELECT)
118 int orig_point, match_point, ready;
119 struct timeval timer;
120 fd_set readfds;
121
9255ee31 122 _rl_insert_char (1, invoking_key);
d60d9f65
SS
123 (*rl_redisplay_function) ();
124 match_point =
125 find_matching_open (rl_line_buffer, rl_point - 2, invoking_key);
126
127 /* Emacs might message or ring the bell here, but I don't. */
128 if (match_point < 0)
775e241e 129 return 1;
d60d9f65
SS
130
131 FD_ZERO (&readfds);
132 FD_SET (fileno (rl_instream), &readfds);
cc88a640 133 USEC_TO_TIMEVAL (_paren_blink_usec, timer);
d60d9f65
SS
134
135 orig_point = rl_point;
136 rl_point = match_point;
137 (*rl_redisplay_function) ();
138 ready = select (1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &timer);
139 rl_point = orig_point;
140#else /* !HAVE_SELECT */
9255ee31 141 _rl_insert_char (count, invoking_key);
d60d9f65
SS
142#endif /* !HAVE_SELECT */
143 }
144 return 0;
145}
146
147static int
cb41b9e7 148find_matching_open (char *string, int from, int closer)
d60d9f65
SS
149{
150 register int i;
151 int opener, level, delimiter;
152
153 switch (closer)
154 {
155 case ']': opener = '['; break;
156 case '}': opener = '{'; break;
157 case ')': opener = '('; break;
158 default:
159 return (-1);
160 }
161
162 level = 1; /* The closer passed in counts as 1. */
163 delimiter = 0; /* Delimited state unknown. */
164
165 for (i = from; i > -1; i--)
166 {
167 if (delimiter && (string[i] == delimiter))
168 delimiter = 0;
169 else if (rl_basic_quote_characters && strchr (rl_basic_quote_characters, string[i]))
170 delimiter = string[i];
171 else if (!delimiter && (string[i] == closer))
172 level++;
173 else if (!delimiter && (string[i] == opener))
174 level--;
175
176 if (!level)
177 break;
178 }
179 return (i);
180}
This page took 0.987469 seconds and 4 git commands to generate.