Hi all
    a long time ago (2013, gulp), I asked a question here about supporting 
a key-binding feature of my favourite editor, CRiSP/Brief. This is the use 
of multiple 'Home' or 'End' keypresses to move the cursor in different ways:
    
    Home key pressed once, Cursor moves to beginning of line
    Home key pressed twice, Cursor moves to beginning of 'screen' (ie. 
first visible character in pane)
    Home key pressed three times, Cursor moves to beginning of buffer
and
    End key pressed once, Cursor moves to end of line
    End key pressed twice, Cursor moves to end of 'screen' (ie. first 
visible character in pane)
    End key pressed three times, Cursor moves to end of buffer
    
Edward gave me some pointers including the 'lossage' feature - 
g.app.lossage(). I have finally got around to getting something like this 
to work - see below.

There are basically two new cursor motion functions, which move the cursor 
within the Body pane. I have called them cursorToTopOfPane() and 
cursorToEndOfPane().

There is then the function which uses lossage() to see whether the 
combination of up to three last keys pressed should be used for 'special' 
behaviour. Below I actually use Ctrl-Home and Ctrl-End keys to try things 
out, rather than the actual Home and End keys that I intend to use normally.

Edward, I am thinking that it might be worth having the functionality of 
cursorToTopOfPane() and cursorToEndOfPane() in Leo's (Qt) core?

I don't think the 'use lossage()' key functions should be in the core, 
unless you know better...

A few things:

    - depending on the actual size of the Body pane, there can be a small 
amount of 'micro-scrolling' as you move the cursor to the top/bottom of the 
pane. I think my other editor resizes the pane so as not to have partial 
text lines. The current behaviour seems liveable with, although I might be 
interested in learning how to 'fix' this.
    - I don't currently deal with any existing selected region. If this 
were to go into the core this would probably all be refactored, maybe using 
some of the existing helper functions 
    - the doKey() function has to know about the key(s) that are calling 
it, "Home" or "End" in the lossage() list. How might I improve this?
    - I had some trouble calling the pre-existing editor commands, like 
c.editCommand.beginningOfBuffer() etc. Not 100% sure I am doing this 
correctly.
    - as per the comments I am currently assuming that lossage() has at 
least three entries. I'll fix this shortly.
    
Anyway, here's what I have. I am currently using two @command nodes
    @command myCtrlHome @key=Ctrl+Home
    @command myCtrlEnd @key=Ctrl+End
with content like below (merged a bit from two nodes for 'clarity')


from leo.core.leoQt import QtCore

def cursorToEndOfPane():
    """ move the text cursor to the last character visible in the body pane
    """
    w = c.frame.body.widget
    # get viewport of the body widget
    vp = w.viewport()
    
    # get the coordinates of the bottom of the visible area
    vWidth = vp.width() -1
    vHeight = vp.height() -1
    # g.es("width", vWidth, "height", vHeight)
    
    # create a QPoint from this
    bottom_right = QtCore.QPoint(vWidth, vHeight)
    
    # get the (text)'position' within the widget of the bottom right QPoint
    end_pos = w.cursorForPosition(bottom_right).position()
    
    # create a cursor and set it to this position
    cursor = w.textCursor()
    cursor.setPosition(end_pos)
    # set the Leo cursor from this
    w.setTextCursor(cursor)
    
    c.bodyWantsFocusNow()
    
def cursorToTopOfPane():
    """ move the text cursor to the first character visible in the body pane
    """
    w = c.frame.body.widget

    # create a QPoint of the top of the widget (client area)
    top_left = QtCore.QPoint(0, 0)
    
    # get the (text)'position' within the widget of the top left QPoint
    start_pos = w.cursorForPosition(top_left).position()
    
    # create a cursor and set it to this position
    cursor = w.textCursor()
    cursor.setPosition(start_pos)
    # set the Leo cursor from this
    w.setTextCursor(cursor)
    
    c.bodyWantsFocusNow()

# arrive here with 'Ctrl-Home' the first entry in lossage
# XXX for now, assume we have pressed more than three keys...
def doMyCtrlHomeKey():
    if g.app.lossage[1][1] == "Ctrl+Home":
        if g.app.lossage[2][1] == "Ctrl+Home":
            g.es("would move to top of buffer")
            c.editCommands.beginningOfBuffer(None)
        else:
            g.es("would move to top of body")
            cursorToTopOfPane()
    else:
        g.es("would move to beginning of line")
        c.editCommands.beginningOfLine(None)

doMyCtrlHomeKey()

# arrive here with 'Ctrl-End' the first entry in lossage
# XXX for now, assume we have pressed more than three keys...
def doCtrlEndKey():
    showLossage()
    if g.app.lossage[1][1] == "Ctrl+End":
        if g.app.lossage[2][1] == "Ctrl+End":
            g.es("would move to end of buffer")
            c.editCommands.endOfBuffer(None)
        else:
            g.es("would move to end of body pane")
            cursorToEndOfPane()
    else:
        g.es("would move to end of line")
        c.editCommands.endOfLine(None)


doCtrlEndKey()

Comments welcome

    Thanks & Regards
    Jon N
    
    



-- 
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 [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/leo-editor.
For more options, visit https://groups.google.com/d/optout.

Reply via email to