@@ -85,12 +85,169 @@ def reformat_and_execute(event):
8585
8686 kb .add ('f2' , filter = has_focus (DEFAULT_BUFFER ))(open_input_in_editor )
8787
88- if shell .display_completions == 'readlinelike' :
89- kb .add ('c-i' , filter = (has_focus (DEFAULT_BUFFER )
90- & ~ has_selection
91- & insert_mode
92- & ~ cursor_in_leading_ws
93- ))(display_completions_like_readline )
88+ @Condition
89+ def auto_match ():
90+ return shell .auto_match
91+
92+ focused_insert = (vi_insert_mode | emacs_insert_mode ) & has_focus (DEFAULT_BUFFER )
93+ _preceding_text_cache = {}
94+ _following_text_cache = {}
95+
96+ def preceding_text (pattern ):
97+ try :
98+ return _preceding_text_cache [pattern ]
99+ except KeyError :
100+ pass
101+ m = re .compile (pattern )
102+
103+ def _preceding_text ():
104+ app = get_app ()
105+ return bool (m .match (app .current_buffer .document .current_line_before_cursor ))
106+
107+ condition = Condition (_preceding_text )
108+ _preceding_text_cache [pattern ] = condition
109+ return condition
110+
111+ def following_text (pattern ):
112+ try :
113+ return _following_text_cache [pattern ]
114+ except KeyError :
115+ pass
116+ m = re .compile (pattern )
117+
118+ def _following_text ():
119+ app = get_app ()
120+ return bool (m .match (app .current_buffer .document .current_line_after_cursor ))
121+
122+ condition = Condition (_following_text )
123+ _following_text_cache [pattern ] = condition
124+ return condition
125+
126+ # auto match
127+ @kb .add ("(" , filter = focused_insert & auto_match & following_text (r"[,)}\]]|$" ))
128+ def _ (event ):
129+ event .current_buffer .insert_text ("()" )
130+ event .current_buffer .cursor_left ()
131+
132+ @kb .add ("[" , filter = focused_insert & auto_match & following_text (r"[,)}\]]|$" ))
133+ def _ (event ):
134+ event .current_buffer .insert_text ("[]" )
135+ event .current_buffer .cursor_left ()
136+
137+ @kb .add ("{" , filter = focused_insert & auto_match & following_text (r"[,)}\]]|$" ))
138+ def _ (event ):
139+ event .current_buffer .insert_text ("{}" )
140+ event .current_buffer .cursor_left ()
141+
142+ @kb .add ('"' , filter = focused_insert & auto_match & following_text (r"[,)}\]]|$" ))
143+ def _ (event ):
144+ event .current_buffer .insert_text ('""' )
145+ event .current_buffer .cursor_left ()
146+
147+ @kb .add ("'" , filter = focused_insert & auto_match & following_text (r"[,)}\]]|$" ))
148+ def _ (event ):
149+ event .current_buffer .insert_text ("''" )
150+ event .current_buffer .cursor_left ()
151+
152+ # raw string
153+ @kb .add ("(" , filter = focused_insert & preceding_text (r".*(r|R)[\"'](-*)$" ))
154+ def _ (event ):
155+ matches = re .match (
156+ r".*(r|R)[\"'](-*)" ,
157+ event .current_buffer .document .current_line_before_cursor ,
158+ )
159+ dashes = matches .group (2 ) or ""
160+ event .current_buffer .insert_text ("()" + dashes )
161+ event .current_buffer .cursor_left (len (dashes ) + 1 )
162+
163+ @kb .add ("[" , filter = focused_insert & preceding_text (r".*(r|R)[\"'](-*)$" ))
164+ def _ (event ):
165+ matches = re .match (
166+ r".*(r|R)[\"'](-*)" ,
167+ event .current_buffer .document .current_line_before_cursor ,
168+ )
169+ dashes = matches .group (2 ) or ""
170+ event .current_buffer .insert_text ("[]" + dashes )
171+ event .current_buffer .cursor_left (len (dashes ) + 1 )
172+
173+ @kb .add ("{" , filter = focused_insert & preceding_text (r".*(r|R)[\"'](-*)$" ))
174+ def _ (event ):
175+ matches = re .match (
176+ r".*(r|R)[\"'](-*)" ,
177+ event .current_buffer .document .current_line_before_cursor ,
178+ )
179+ dashes = matches .group (2 ) or ""
180+ event .current_buffer .insert_text ("{}" + dashes )
181+ event .current_buffer .cursor_left (len (dashes ) + 1 )
182+
183+ @kb .add ('"' , filter = focused_insert & preceding_text (r".*(r|R)$" ))
184+ def _ (event ):
185+ event .current_buffer .insert_text ('""' )
186+ event .current_buffer .cursor_left ()
187+
188+ @kb .add ("'" , filter = focused_insert & preceding_text (r".*(r|R)$" ))
189+ def _ (event ):
190+ event .current_buffer .insert_text ("''" )
191+ event .current_buffer .cursor_left ()
192+
193+ # just move cursor
194+ @kb .add (")" , filter = focused_insert & auto_match & following_text (r"^\)" ))
195+ @kb .add ("]" , filter = focused_insert & auto_match & following_text (r"^\]" ))
196+ @kb .add ("}" , filter = focused_insert & auto_match & following_text (r"^\}" ))
197+ @kb .add ('"' , filter = focused_insert & auto_match & following_text ('^"' ))
198+ @kb .add ("'" , filter = focused_insert & auto_match & following_text ("^'" ))
199+ def _ (event ):
200+ event .current_buffer .cursor_right ()
201+
202+ @kb .add (
203+ "backspace" ,
204+ filter = focused_insert
205+ & preceding_text (r".*\($" )
206+ & auto_match
207+ & following_text (r"^\)" ),
208+ )
209+ @kb .add (
210+ "backspace" ,
211+ filter = focused_insert
212+ & preceding_text (r".*\[$" )
213+ & auto_match
214+ & following_text (r"^\]" ),
215+ )
216+ @kb .add (
217+ "backspace" ,
218+ filter = focused_insert
219+ & preceding_text (r".*\{$" )
220+ & auto_match
221+ & following_text (r"^\}" ),
222+ )
223+ @kb .add (
224+ "backspace" ,
225+ filter = focused_insert
226+ & preceding_text ('.*"$' )
227+ & auto_match
228+ & following_text ('^"' ),
229+ )
230+ @kb .add (
231+ "backspace" ,
232+ filter = focused_insert
233+ & preceding_text (r".*'$" )
234+ & auto_match
235+ & following_text (r"^'" ),
236+ )
237+ def _ (event ):
238+ event .current_buffer .delete ()
239+ event .current_buffer .delete_before_cursor ()
240+
241+ if shell .display_completions == "readlinelike" :
242+ kb .add (
243+ "c-i" ,
244+ filter = (
245+ has_focus (DEFAULT_BUFFER )
246+ & ~ has_selection
247+ & insert_mode
248+ & ~ cursor_in_leading_ws
249+ ),
250+ )(display_completions_like_readline )
94251
95252 if sys .platform == "win32" :
96253 kb .add ("c-v" , filter = (has_focus (DEFAULT_BUFFER ) & ~ vi_mode ))(win_paste )
0 commit comments