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.