Eureka! How to simplify Leo's key handling

68 views
Skip to first unread message

Edward K. Ream

unread,
Apr 12, 2018, 4:47:12 AM4/12/18
to leo-editor
Chance favors the prepared mindLouis Pasteur.

When I awoke just now I saw the answer to a question I didn't know my mind was working on, namely, how to drastically simplify Leo's key handling code, including the key settings.  This is huge.

The work that prepared my mind:

1. The recent ipynb importer code.  It uses nbconvert to translate a string (the file's text) into a python data structure, that contains text, but also contained bools and lists.

2. Recent work on converting Meta to Alt on MacOS.  This reacquainted me with the horrors of the code that converts a Qt key event into Leo's internal representation.  At present, this representation contains an oh-so-fragile string.

3. Yesterday's post on branches.

The Aha:  Don't use a string to do an object's work!

The plan

1. Just like with nbconvert, Leo's code that handles incoming Qt key events will output a python data structure, say LeoKey, not a string.

2. Leo's code that translates user key settings will generate a LeoKey. It's not clear what to do about the pane specifiers. It might well be an auxiliary field of LeoKeys.

That's all!  But the effects are widespread:

- The code that translates Qt keys to LeoKeys instantly collapses in complexity.

- Ditto for the code that translates user settings to "canonical key representation".

- Ditto for code that prints/dumps keys and user key settings.

- There is no longer any need to distinguish between canonical and non-canonical key strings. In particular, the infamous g.KeyStroke class will disappear. It's docstring:

    '''A class that announces that its contents has been canonicalized by k.strokeFromSetting.
    This allows type-checking assertions in the code.'''

Summary

The code that handles Qt key events (the key handler) and the code that handles key-related user settings (the key setting handler) will meet in the middle by producing a common data structure, a LeoKey.  This structure will contain strings, but will not be a string.

For example, the representation of Alt+Ctrl+s will have:

- a mods field: set(['alt', 'ctrl']). This is the big simplification.
- a key field of "s".
- a code field whatever the Qt key code is, for debugging.
- a pane field (set only by the key setting handler) of one of ('all', 'text', 'outline', 'body', etc.)

No more horrendous "canonicalizing" of key representations!  No more confusion!

I expect to be able to do this work in a day or three.

Edward

Edward K. Ream

unread,
Apr 12, 2018, 5:40:56 AM4/12/18
to leo-editor
On Thursday, April 12, 2018 at 3:47:12 AM UTC-5, Edward K. Ream wrote:

2. Leo's code that translates user key settings will generate a LeoKey.

To avoid confusion, the class is g.NewLeoKey.

- The code that translates Qt keys to [New]LeoKeys instantly collapses in complexity.


- Ditto for the code that translates user settings to "canonical key representation".

- Ditto for code that prints/dumps keys and user key settings.

Indeed, here is NewLeoKey.__repr__ and helper (untested):

def __repr__(self):
   
return self.toString()
   
__str__
= repr

def toString(self, show_code=False, show_pane=False):
    mods
= sorted(list(self.mods))
    mods
= ''.join(['%s+' % z.capitalize() for z in mods])
    code
= ' code: %s' % (self.code) if show_code else ''
    pane
= ' pane: %s' % (self.pane) if show_pane else ''
   
return '%s%s%s%s' % (mods, self.key, code, pane)

This will replace several pages of difficult and fragile legacy code.

Edward

Edward K. Ream

unread,
Apr 12, 2018, 12:24:30 PM4/12/18
to leo-editor
On Thursday, April 12, 2018 at 3:47:12 AM UTC-5, Edward K. Ream wrote:

When I awoke just now I saw...how to drastically simplify Leo's key handling code.

Phase 1 of the project is complete, exactly following the process described in Lesson 7 of LeoU: How to make complex changes to a code base.  That is, Leo now opens without crashing.

Phase 2 will handle all incoming keystrokes without crashing. That will take several hours, perhaps later today.

Edward

jkn

unread,
Apr 12, 2018, 1:43:37 PM4/12/18
to leo-editor

Hi Edward
    This all sounds cool stuff!

I have a previous interest in this ... can I remind you of:

    https://github.com/leo-editor/leo-editor/issues/423

and some associated discussions, in particular with me being interested in distinguishing between keys on thr Numeric keypad?

I realise the jusry is still out a bit on Qts support for this but it would be good to bear in mind wrt. modifiers etc.

Thanks, Jon N
 

Edward K. Ream

unread,
Apr 13, 2018, 6:31:53 AM4/13/18
to leo-editor
On Thu, Apr 12, 2018 at 12:43 PM, jkn <jkn...@nicorp.f9.co.uk> wrote:

I have a previous interest in this ... can I remind you of:

    https://github.com/leo-editor/leo-editor/issues/423

and some associated discussions, in particular with me being interested in distinguishing between keys on
​the ​
Numeric keypad?

​Hehe.  It appears that this Eureka has happened before.

I am deep into the actual work now. The settings half of the code appears to work, and parts of the input half.

This truly is sclerotic code. Previously, we have all been reluctant to touch any part of it, for fear of breaking it in obscure ways.  Surely, a longer-than-usual period of testing will be needed.

I am pleased with yesterday's work. It foreshadows all the benefits promised in #423, and perhaps others.  There is massive confusion in the old code, and a lot of truly ugly code, some of which has already disappeared.

I am going to put my head down and work on this project until all unit tests pass regardless of the g.new_keys switch.  At which point I'll depend on you, Jon, to test the code and suggest improvements.

Edward

Edward K. Ream

unread,
Apr 13, 2018, 6:37:25 AM4/13/18
to leo-editor
On Friday, April 13, 2018 at 5:31:53 AM UTC-5, Edward K. Ream wrote:

I am going to put my head down and work on this project until all unit tests pass regardless of the g.new_keys switch. 

Perhaps some other devs can answer newbie questions while I obsess about the code.

I expect to get the new code working today.  I will also take as much time as possible to clean and simplify the code while all complications are fresh in my mind. Also, the new code offers a way to do new unit tests...

Edward

jkn

unread,
Apr 13, 2018, 12:25:38 PM4/13/18
to leo-editor

Hi Edward


> At which point I'll depend on you, Jon, to test the code and suggest improvements.

sounds reasonable ;-)

    Jon N

Edward K. Ream

unread,
Apr 13, 2018, 5:02:04 PM4/13/18
to leo-editor
On Friday, April 13, 2018 at 5:37:25 AM UTC-5, Edward K. Ream wrote:

> I expect to get the new code working today.

That was wildly optimistic.  #423 looks like a better plan  If focuses on improving g.KeyStroke.

I am now backing out of some recent changes in the "keys" branch.  It's no big deal. One "survivor" is a drastic simplification of the main eventFilter.  That will remain whatever else happens.

> I will also take as much time as possible to clean and simplify the code.

Making small, self-contained changes is the surest way forward, especially for code as complex as this.  I'll likely be working on this project for at least a week.

Edward
Reply all
Reply to author
Forward
0 new messages