Adding dired to Leo

12 views
Skip to first unread message

Edward K. Ream

unread,
Aug 13, 2014, 7:20:28 AM8/13/14
to leo-e...@googlegroups.com
In the thread, "vim mode is a great success, even when not enabled", I said,

    "
The code for every kind of completion tab is hairy,  but a filename
    completion/browsing tab would be useful not just for vim commands.
    Imo, Leo must have this."

Well, it turns out that Leo already has such code: k.getFileName.  It is used by the open-outline-by-name command. Alas, k.getFileName is pretty much broken.  Apparently, nobody uses open-outline-by-name, or they have used it once and given up on Leo :-(

Last night I found a way to remove *all* the behind-the-scenes complexity with tab completion in k.getFileName. This Aha should apply to Leo's workhorse k.getArg method as well. I'll discuss the (interesting!) coding details in the P.S.

Some real work remains: the code that actually computes the completion list needs a lot of work.  I expect to finish it today, if birthday revels do not interfere ;-)

Edward

P.S. Engineering Note Book: feel free to ignore.

I began the task of fixing k.getFileName by creating a FileNameChooser class.  Not pushed yet.

The original intention of the FileNameChooser class was to hide the details of the code.  Like this::

    def getFileName():
        '''Create a FileNameChooser and use it to get a file name.'''
        fnc = FileNameChooser(c,handler,filterExt='.py')
            # handler=None,prefix='Enter File Name:',tabName='Dired')
        fnc.get_file_name()

I have often found that creating a helper class like this clarifies the code in unexpected ways. Rather than dealing with a set of a set of helper methods of k (class KeyHandlerClass), grouping the methods into a new class simplifies everything.

The old code in both k.getFileName and k.getArg keeps track of several truly ugly and hard-to-understand ivars, whose only real purpose is to keep track of the "protected" label in the minibuffer, so as either ignore it or prevent the label from being deleted by a backspace character. In the new class it was much easier to see that none of this complexity is needed!  The trick is to define the following methods::

    def extend_label(fnc,s):
        '''Extend the label by s.'''
        fnc.c.k.extendLabel(s,select=False,protect=False)
   
    def get_label(fnc):
        '''Return the label, not including the prompt.'''
        return fnc.c.k.getLabel(ignorePrompt=True)
   
    def set_label(fnc,s):
        '''Set the label after the prompt to s. The prompt never changes.'''
        fnc.c.k.setLabel(fnc.prompt,protect=True)
        fnc.c.k.extendLabel(s or '',select=False,protect=False

As you can see, these are simply thin wrappers on the corresponding k methods, but they deal only with what follows the prompt.  All the apparent complexity of tab completion simply disappears!  We use fnc.get_label to get the text to be completed, and use fnc.set_label/extend_label to update the label.

All this is obvious in retrospect, but I would never have seen it without creating the new class.  Pretty amazing.

P.P.S.   This collapse in complexity might apply to k.getArg as well, but there are complications.   k.getArg has accreted over the years, and it contains several hacks (keyword arguments) not related to tab completion. It might not be possible for k.getArg to create a new instance of, say, a GetArg class without having unpleasant ripple effects throughout Leo.

If k.getArg *can* create one-off instances of the GetArg class, then both the GetArg and FileNameChooser classes would likely become a subclass of a BaseGetArg class.

EKR

Edward K. Ream

unread,
Aug 13, 2014, 10:02:16 AM8/13/14
to leo-editor
On Wed, Aug 13, 2014 at 6:20 AM, Edward K. Ream

> Some real work remains [in k.getFileName & helpers]

Done. For the first time ever, file-open-by-name has good filename
completion. The command itself has a few rough edges that I'll fix
soon.

k.getFileName will be the foundation of the :r and :tabnew commands.

Edward
Reply all
Reply to author
Forward
0 new messages