Import readline 7.0 (patch 5)
[deliverable/binutils-gdb.git] / readline / parens.c
CommitLineData
cc88a640 1/* parens.c -- implementation of matching parentheses feature. */
d60d9f65 2
775e241e 3/* Copyright (C) 1987, 1989, 1992-2015 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
67_rl_enable_paren_matching (on_or_off)
68 int on_or_off;
69{
70 if (on_or_off)
775e241e
TT
71 {
72 /* ([{ */
1b17e766
EZ
73 rl_bind_key_in_map (')', rl_insert_close, emacs_standard_keymap);
74 rl_bind_key_in_map (']', rl_insert_close, emacs_standard_keymap);
75 rl_bind_key_in_map ('}', rl_insert_close, emacs_standard_keymap);
775e241e
TT
76
77#if defined (VI_MODE)
78 /* ([{ */
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 rl_bind_key_in_map ('}', rl_insert_close, vi_insertion_keymap);
82#endif
1b17e766
EZ
83 }
84 else
775e241e
TT
85 {
86 /* ([{ */
1b17e766
EZ
87 rl_bind_key_in_map (')', rl_insert, emacs_standard_keymap);
88 rl_bind_key_in_map (']', rl_insert, emacs_standard_keymap);
89 rl_bind_key_in_map ('}', rl_insert, emacs_standard_keymap);
775e241e
TT
90
91#if defined (VI_MODE)
92 /* ([{ */
93 rl_bind_key_in_map (')', rl_insert, vi_insertion_keymap);
94 rl_bind_key_in_map (']', rl_insert, vi_insertion_keymap);
95 rl_bind_key_in_map ('}', rl_insert, vi_insertion_keymap);
96#endif
1b17e766
EZ
97 }
98}
d60d9f65 99
9255ee31
EZ
100int
101rl_set_paren_blink_timeout (u)
102 int u;
103{
104 int o;
105
106 o = _paren_blink_usec;
107 if (u > 0)
108 _paren_blink_usec = u;
109 return (o);
110}
111
d60d9f65
SS
112int
113rl_insert_close (count, invoking_key)
114 int count, invoking_key;
115{
116 if (rl_explicit_arg || !rl_blink_matching_paren)
9255ee31 117 _rl_insert_char (count, invoking_key);
d60d9f65
SS
118 else
119 {
120#if defined (HAVE_SELECT)
121 int orig_point, match_point, ready;
122 struct timeval timer;
123 fd_set readfds;
124
9255ee31 125 _rl_insert_char (1, invoking_key);
d60d9f65
SS
126 (*rl_redisplay_function) ();
127 match_point =
128 find_matching_open (rl_line_buffer, rl_point - 2, invoking_key);
129
130 /* Emacs might message or ring the bell here, but I don't. */
131 if (match_point < 0)
775e241e 132 return 1;
d60d9f65
SS
133
134 FD_ZERO (&readfds);
135 FD_SET (fileno (rl_instream), &readfds);
cc88a640 136 USEC_TO_TIMEVAL (_paren_blink_usec, timer);
d60d9f65
SS
137
138 orig_point = rl_point;
139 rl_point = match_point;
140 (*rl_redisplay_function) ();
141 ready = select (1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &timer);
142 rl_point = orig_point;
143#else /* !HAVE_SELECT */
9255ee31 144 _rl_insert_char (count, invoking_key);
d60d9f65
SS
145#endif /* !HAVE_SELECT */
146 }
147 return 0;
148}
149
150static int
151find_matching_open (string, from, closer)
152 char *string;
153 int from, closer;
154{
155 register int i;
156 int opener, level, delimiter;
157
158 switch (closer)
159 {
160 case ']': opener = '['; break;
161 case '}': opener = '{'; break;
162 case ')': opener = '('; break;
163 default:
164 return (-1);
165 }
166
167 level = 1; /* The closer passed in counts as 1. */
168 delimiter = 0; /* Delimited state unknown. */
169
170 for (i = from; i > -1; i--)
171 {
172 if (delimiter && (string[i] == delimiter))
173 delimiter = 0;
174 else if (rl_basic_quote_characters && strchr (rl_basic_quote_characters, string[i]))
175 delimiter = string[i];
176 else if (!delimiter && (string[i] == closer))
177 level++;
178 else if (!delimiter && (string[i] == opener))
179 level--;
180
181 if (!level)
182 break;
183 }
184 return (i);
185}
This page took 0.85916 seconds and 4 git commands to generate.