@@ -17,7 +17,6 @@ class AbstractEdits(object):
1717 'line' : 'hello world' ,
1818 'cursor_offset' : 5 ,
1919 'cut_buffer' : 'there' ,
20- 'indent' : 4 ,
2120 }
2221
2322 def __contains__ (self , key ):
@@ -28,15 +27,22 @@ def __contains__(self, key):
2827 else :
2928 return True
3029
31- def add (self , key , func ):
30+ def add (self , key , func , overwrite = False ):
3231 if key in self :
33- raise ValueError ('key %r already has a mapping' % (key ,))
32+ if overwrite :
33+ del self [key ]
34+ else :
35+ raise ValueError ('key %r already has a mapping' % (key ,))
3436 params = inspect .getargspec (func )[0 ]
3537 args = dict ((k , v ) for k , v in self .default_kwargs .items () if k in params )
3638 r = func (** args )
3739 if len (r ) == 2 :
40+ if hasattr (func , 'kills' ):
41+ raise ValueError ('function %r returns two values, but has a kills attribute' % (func ,))
3842 self .simple_edits [key ] = func
3943 elif len (r ) == 3 :
44+ if not hasattr (func , 'kills' ):
45+ raise ValueError ('function %r returns three values, but has no kills attribute' % (func ,))
4046 self .cut_buffer_edits [key ] = func
4147 else :
4248 raise ValueError ('return type of function %r not recognized' % (func ,))
@@ -52,11 +58,20 @@ def call(self, key, **kwargs):
5258 args = dict ((k , v ) for k , v in kwargs .items () if k in params )
5359 return func (** args )
5460
61+ def call_without_cut (self , key , ** kwargs ):
62+ """Looks up the function and calls it, returning only line and cursor offset"""
63+ r = self .call_for_two (key , ** kwargs )
64+ return r [:2 ]
65+
5566 def __getitem__ (self , key ):
5667 if key in self .simple_edits : return self .simple_edits [key ]
5768 if key in self .cut_buffer_edits : return self .cut_buffer_edits [key ]
5869 raise KeyError ("key %r not mapped" % (key ,))
5970
71+ def __delitem__ (self , key ):
72+ if key in self .simple_edits : del self .simple_edits [key ]
73+ elif key in self .cut_buffer_edits : del self .cut_buffer_edits [key ]
74+ else : raise KeyError ("key %r not mapped" % (key ,))
6075
6176class UnconfiguredEdits (AbstractEdits ):
6277 """Maps key to edit functions, and bins them by what parameters they take.
@@ -104,7 +119,8 @@ def __init__(self, simple_edits, cut_buffer_edits, awaiting_config, config, key_
104119 self .simple_edits = dict (simple_edits )
105120 self .cut_buffer_edits = dict (cut_buffer_edits )
106121 for attr , func in awaiting_config .items ():
107- super (ConfiguredEdits , self ).add (key_dispatch [getattr (config , attr )], func )
122+ for key in key_dispatch [getattr (config , attr )]:
123+ super (ConfiguredEdits , self ).add (key , func , overwrite = True )
108124
109125 def add_config_attr (self , config_attr , func ):
110126 raise NotImplementedError ("Config already set on this mapping" )
@@ -117,6 +133,14 @@ def add(self, key, func):
117133# Because the edits.on decorator runs the functions, functions which depend
118134# on other functions must be declared after their dependencies
119135
136+ def kills_behind (func ):
137+ func .kills = 'behind'
138+ return func
139+
140+ def kills_ahead (func ):
141+ func .kills = 'ahead'
142+ return func
143+
120144@edit_keys .on ('<Ctrl-b>' )
121145@edit_keys .on ('<LEFT>' )
122146def left_arrow (cursor_offset , line ):
@@ -183,22 +207,29 @@ def delete_from_cursor_back(cursor_offset, line):
183207 return 0 , line [cursor_offset :]
184208
185209@edit_keys .on ('<Esc+d>' ) # option-d
210+ @kills_ahead
186211def delete_rest_of_word (cursor_offset , line ):
187212 m = re .search (r'\w\b' , line [cursor_offset :])
188213 if not m :
189- return cursor_offset , line
190- return cursor_offset , line [:cursor_offset ] + line [m .start ()+ cursor_offset + 1 :]
214+ return cursor_offset , line , ''
215+ return (cursor_offset , line [:cursor_offset ] + line [m .start ()+ cursor_offset + 1 :],
216+ line [cursor_offset :m .start ()+ cursor_offset + 1 ])
191217
192218@edit_keys .on ('<Ctrl-w>' )
193219@edit_keys .on (config = 'clear_word_key' )
220+ @kills_behind
194221def delete_word_to_cursor (cursor_offset , line ):
195222 matches = list (re .finditer (r'\s\S' , line [:cursor_offset ]))
196223 start = matches [- 1 ].start ()+ 1 if matches else 0
197- return start , line [:start ] + line [cursor_offset :]
224+ return start , line [:start ] + line [cursor_offset :], line [ start : cursor_offset ]
198225
199226@edit_keys .on ('<Esc+y>' )
200- def yank_prev_prev_killed_text (cursor_offset , line ):
201- return cursor_offset , line #TODO Not implemented
227+ def yank_prev_prev_killed_text (cursor_offset , line , cut_buffer ): #TODO not implemented - just prev
228+ return cursor_offset + len (cut_buffer ), line [:cursor_offset ] + cut_buffer + line [cursor_offset :]
229+
230+ @edit_keys .on (config = 'yank_from_buffer_key' )
231+ def yank_prev_killed_text (cursor_offset , line , cut_buffer ):
232+ return cursor_offset + len (cut_buffer ), line [:cursor_offset ] + cut_buffer + line [cursor_offset :]
202233
203234@edit_keys .on ('<Ctrl-t>' )
204235def transpose_character_before_cursor (cursor_offset , line ):
@@ -223,21 +254,24 @@ def uppercase_next_word(cursor_offset, line):
223254 return cursor_offset , line #TODO Not implemented
224255
225256@edit_keys .on ('<Ctrl-k>' )
257+ @kills_ahead
226258def delete_from_cursor_forward (cursor_offset , line ):
227- return cursor_offset , line [:cursor_offset ]
259+ return cursor_offset , line [:cursor_offset ], line [ cursor_offset :]
228260
229261@edit_keys .on ('<Esc+c>' )
230262def titlecase_next_word (cursor_offset , line ):
231263 return cursor_offset , line #TODO Not implemented
232264
233265@edit_keys .on ('<Esc+BACKSPACE>' )
234266@edit_keys .on ('<Meta-BACKSPACE>' )
267+ @kills_behind
235268def delete_word_from_cursor_back (cursor_offset , line ):
236269 """Whatever my option-delete does in bash on my mac"""
237270 if not line :
238271 return cursor_offset , line
239272 starts = [m .start () for m in list (re .finditer (r'\b\w' , line )) if m .start () < cursor_offset ]
240273 if starts :
241- return starts [- 1 ], line [:starts [- 1 ]] + line [cursor_offset :]
242- return cursor_offset , line
274+ return starts [- 1 ], line [:starts [- 1 ]] + line [cursor_offset :], line [starts [- 1 ]:cursor_offset ]
275+ return cursor_offset , line , ''
276+
243277
0 commit comments