Sublime Forum

Pressing Up or Down after End has been pressed: auto-scroll to line end (EOL)

#1

When I press an End key, the caret jumps to the end of the current line (EOL). This is expected.
When I press either Down Arrow or Up Arrow right after that (to move the caret to the next or previous line), the caret automatically jumps to EOL of each line. This is not expected! (At least, this should be configurable!)
Is there an option to disable such jumping to EOL when Down Arrow or Up Arrow is pressed?
Or maybe I could specify some additional args for the “Down” and “Up” key bindings to disable that?

0 Likes

#2

ST tries to keep caret in same column when navigating up/down. The stored column is updated when navigating horizontally via left-/right arrow keys. If a line is not long enough, caret can only be moved to EOL. As soon as a line of sufficient length is hit again, caret is moved to original column again.

This behavior is not configurable.

You could however update the column by presing left/right after a page change or use “chain” command to do that automatically.

0 Likes

#3

Probably my explanations were not clear enough.

The behavior that you described is the default one: when an End key has not been pressed in advance, then the caret’s vertical position is preserved among all the lines whenever Arrow Down or Arrow Up is pressed. This behavior is the same among all the text editors, as far as I know.

I was trying to describe another behavior which seems to be unique to Sublime Text.
First, I press End key to jump to the end of a short line. The caret jumps to the end of this short line.
Now, whenever I press Arrow Down or Arrow Up, the caret jumps to the very end of any line, even if these lines are much longer than the initial one. So, my problem is that the caret’s vertical position is not preserved.

I believe it is rather a feature than a bug because there may be a wish to always jump to the very end of any line when End key has been pressed in advance.
However, it is not the default behavior that I would expect.
That’s why I’m asking whether there is an ability to configure this behavior.

0 Likes

#4

I see. Yes, that’s probably unique feature which makes ST superior over other editors :wink:

I am not aware of that behavior being configurable.

Still the same trick would work: Press End, Left Arrow, Right Arrow in sequence or use a key binding to do it for you.

	{
		"keys": ["end"],
		"command": "chain",
		"args": {
			"commands": [
				[ "move_to", {"to": "eol", "extend": false}],
				[ "move", {"by": "characters", "forward": false}],
				[ "move", {"by": "characters", "forward": true}]
			]
		}
	},
1 Like

#5

Thank you!

And I think, to make this solution perfect, we may add one more key binding that preserves the behavior I described above:

{
	"keys": ["end", "end"],
	"command": "move_to", "args": {"to": "eol", "extend": false}
},

Thus, the End key pressed twice will enable the “auto-jump to EOL” behavior.

Though it looks like these two key-bindings conflict with each other…
Do I need to specify some selector/context?

0 Likes

#6

Maybe a context to check, whether caret is already at eol. I am however not aware of any one suitable.

Otherwise overlapping bindings of sequences and single keys are tricky, yes.

0 Likes

#7

Looks like I was able to sort it out, basing on this old topic:

So, the final solution seems to be the following:

{
	"keys": ["end"],
	"command": "move_to", 
	"args": {"to": "eol", "extend": false},
	"context": [
		{
			"key": "following_text",
			"operator": "regex_match",
			"operand": "$",
			"match_all": true
		}
	]
},
{
	"keys": ["end"],
	"command": "chain",
	"args": {
		"commands": [
			[ "move_to", {"to": "eol", "extend": false}],
			[ "move", {"by": "characters", "forward": false}],
			[ "move", {"by": "characters", "forward": true}]
		]
	},
	"context": [
		{
			"key": "following_text",
			"operator": "not_regex_match",
			"operand": "$",
			"match_all": true
		}
	]
},
{
	"keys": ["end"],
	"command": "move_to", 
	"args": {"to": "eol", "extend": false},
	"context": [
		{
			"key": "overlay_visible"
		}
	]
},
0 Likes

#8

Looks good. Maybe you can even reduce it to a single key binding by adjusting context a little bit.

	{
		"keys": ["end"],
		"command": "chain",
		"args": {
			"commands": [
				[ "move_to", {"to": "eol", "extend": false}],
				[ "move", {"by": "characters", "forward": false}],
				[ "move", {"by": "characters", "forward": true}]
			]
		},
		"context": [
			{ "key": "following_text", "operator": "not_regex_match", "operand": "$", "match_all": true },
			{ "key": "overlay_visible", "operand": false },
			{ "key": "auto_complete_visible", "operand": false }
		]
	},
1 Like