Hi,
Is there a way to move cursor to previous/next line when word-wrap is on. The file has long lines & span across multiple lines when the word-wrap is on. In this case up & down arrow keys only move across same line.
Hi,
Is there a way to move cursor to previous/next line when word-wrap is on. The file has long lines & span across multiple lines when the word-wrap is on. In this case up & down arrow keys only move across same line.
Been casually wondering the same. I know vim has a solution of sorts for this (if you’re willing to map some keybindings). The move
command may hold the answer … don’t know any details though.
At a basic level, this could be done using a 2-step .sublime-macro
, e.g. for moving to the next line:
[
{"command": "move_to", "args": {"to": "hardeol"}},
{"command": "move", "args": {"by": "characters", "forward": true}},
]
But to also preserve the column that the caret was on (what the API calls xpos
) then Python plugin code probably needs to be involved.
EDIT: Actually you can get the column preservation by taking advantage of the fact that word_wrap
can be “atomically/invisibly” toggled off and then back on during the macro:
[
{"command": "toggle_setting", "args": {"setting": "word_wrap"}},
{"command": "move", "args": {"by": "lines", "forward": true}},
{"command": "toggle_setting", "args": {"setting": "word_wrap"}},
]
Thanks @frou. Based on your suggestion I ended up creating following command which works using row-col navigation. Playing with word-wrap was a little tricky (had to bring current cursor line in focus which didn’t work all the time) so didn’t go that route.
class MoveLineCursorCommand(sublime_plugin.TextCommand):
def run(self, edit, forward):
view = self.view
(row, col) = view.rowcol(view.sel()[0].begin())
if forward:
if row == view.rowcol(view.size())[0]: return
row = int(row) + 1
else:
if row == 0: return
row = int(row) - 1
view.run_command('move_to', {'to': 'hardbol', 'extend': False}),
view.run_command('move', {'by': 'lines', 'forward': forward}),
curr_row_len = len(self.view.substr(self.view.full_line(self.view.text_point(row,0)))) - 1
col = min(col, curr_row_len)
self.view.sel().clear()
self.view.sel().add(sublime.Region(self.view.text_point(row, col)))
self.view.show(self.view.text_point(row, col), animate=False)
And defined key-bindings as follows:
{ "keys": ["ctrl+up"], "command": "move_line_cursor", "args": {"forward": false} },
{ "keys": ["ctrl+down"], "command": "move_line_cursor", "args": {"forward": true} },
Cool - I don’t know if it actually makes sense to do the following, but it’s possible to make a key binding conditional based on a view setting, and reuse already bound keys:
{
"keys": ["down"],
"context": [{"key": "setting.word_wrap", "operator": "equal", "operand": true}],
"command": "...",
"args": { ... }
},