gtoolkit icon indicating copy to clipboard operation
gtoolkit copied to clipboard

editor Home key shortcut behavior (first press, second press)

Open cminter opened this issue 8 months ago • 0 comments

Proposing a change to the Home key shortcut behavior in the editor. IMHO, this behavior (as seen in some popular IDEs) feels more useful:

  1. first Home key press - moves the cursor before the first non-whitespace character
  2. second Home key press - moves to the start of the line (current behavior)
  3. ideally additional pressing of Home key again should move between the two positions. In other words, whenever the cursor is:
    • in the leading whitespace the cursor is moved to the start of the line
    • at the start of the line the cursor is moved to the first non-whitespace character

Below is code that implements the behavior described in 1 and 2 above in BrTextEditorOperator>>#findTextIndexAtLineStart:. There is a hack at the end to deal with an off by 2 problem because I couldn't figure out how to manipulate the text iterator properly to avoid it. Also, I'm a Smalltalk newbie trying to learn the idioms.

findTextIndexAtLineStart: aCursor
	"Find a text index at the start of the line where the cursor is located"

	<return: #Number>
	| aText aTextIterator foundLineBreak foundNonWhiteSpace nHack |
	aText := self text.
	aTextIterator := aText iterator: 1 to: aCursor position.
	aTextIterator skip: aCursor position.	"if we have a line break before cursor - do nothing"
	(aTextIterator hasPrevious
		and: [ (aTextIterator
				previous;
				hasPrevious) and: [ aTextIterator peek isLineBreak ] ])
		ifTrue: [ ^ aCursor position ].

	foundLineBreak := false.
	foundNonWhiteSpace := false.
	[ aTextIterator hasPrevious
		and: [ foundLineBreak := aTextIterator previous isLineBreak.
			foundNonWhiteSpace := foundNonWhiteSpace | aTextIterator peek isSeparator not.
			foundLineBreak not ] ] whileTrue.
	foundNonWhiteSpace
		ifTrue: [ foundNonWhiteSpace := false.	"Now find first non whitespace to the right"
			[ aTextIterator hasNext
				and: [ foundNonWhiteSpace := aTextIterator next isSeparator ] ] whileTrue.
			nHack := 2.
			[ nHack > 0 and: aTextIterator hasPrevious ]
				whileTrue: [ aTextIterator previous.
					nHack := nHack - 1 ] ].	"these previous operations are because am off by 2 and do not know why"

	^ aTextIterator position + foundLineBreak asBit

cminter avatar May 31 '25 08:05 cminter