In an earlier post I said: QQQ Strictly speaking, tab cycling doesn't have to be disabled for all colon commands. One could imaging a list of commands that use tab to complete file names. Otoh, maintaining that list would be clumsy, and it would add still more special cases to ga.do_tab. QQQ
This post describes a much better way, done at rev 3994eca...Leo build: 20140820060754. The new code is gorgeous, if I do say so myself. Even better, the solution is a design pattern with many applications. The trick is to replace functions implementing commands by classes having __call__ methods. See the P.P.S for details. Yes, this has all been done before. Several of Leo's commands are implemented this way. But read on... What's new is that classes can "advertise" their ability to do various things. Here, the classes implementing vim commands advertise, by having a tab_callback method, that they want to handle a tab that follows their name. ga.do_tab then defers to the vim command. There are several really cool things about this code. 1. ga.do_tab, and its helper, ga.do_tab_callback, no longer know *anything* about colon commands, or what any command intends to do with the tab(!!). If the command handler has a tab_callback attribute, ga.do_tab_callback just does:: ga.reset_tab_cycling() k.functionTail = tail # For k.getFileName. handler.tab_callback() Nothing could be simpler, or more general. 2. The code in the command classes is simplified as well. No need for a kludgy test event.get_arg_value. See the P.S. for the full implementation of the :tabnew command. The overall result is a spectacular collapse in complexity, which the attendant increase in power and generality. Edward P.S. Here is the flattened form of the class that handles the :tabnew command (does not require vim-mode). In particular, note that the __call__ and tab_callback methods are trivial. This is the way it is written in The Book. class LoadFileAtCursor: ''' A class to handle Vim's :tabnew command. This class supports the do_tab callback. ''' def __init__(self,vc): '''Ctor for VimCommands.LoadFileAtCursor class.''' self.vc = vc __name__ = ':r' # Required. def __call__(self,event=None): '''Prompt for a file name, the open a new Leo tab.''' self.vc.c.k.getFileName(event,callback=self.open_file_by_name) def tab_callback(self): '''Called when the user types :tabnew<tab>''' self.vc.c.k.getFileName(event=None,callback=self.open_file_by_name) def open_file_by_name(self,fn): c = self.vc.c if fn and not g.os_path_isdir(fn): c2 = g.openWithFileName(fn,old_c=c) try: g.app.gui.runAtIdle(c2.treeWantsFocusNow) except Exception: pass else: c.new() P.P.S. This pattern is particularly well suited to Leo, because the various getPublicCommands methods reference those functions when create command dictionaries. Here, we replace just two entries in the dict:: ':r': vc.LoadFileAtCursor(vc), ':tabnew': vc.Tabnew(vc), This creates instances of the LoadFileAtCursor and Tabnew classes. In other words, we replace a function by an instance of a class. All such classes must have __call__ methods, so that Leo can "call" the instance as if it were a function. EKR -- You received this message because you are subscribed to the Google Groups "leo-editor" group. To unsubscribe from this group and stop receiving emails from it, send an email to leo-editor+unsubscr...@googlegroups.com. To post to this group, send email to leo-editor@googlegroups.com. Visit this group at http://groups.google.com/group/leo-editor. For more options, visit https://groups.google.com/d/optout.