danth / pathfinder.vim

Vim plugin to suggest better movements
MIT License
290 stars 4 forks source link

Make PathfinderBegin and PathfinderRun automatic #12

Closed aryabhatta-dey closed 4 years ago

aryabhatta-dey commented 4 years ago

This is a feature request to make the plugin track my position between edits and take those two points as the beginning and ending points for the path to be optimized. The way this can work is PathfinderBegin is auto set to take the point where the last edit was made as the starting pint and the moment I do an edit PathfinderRun auto runs.

danth commented 4 years ago

Possible implementation

This could be done by starting a background thread in Python, and sending it CursorMoved events using an autocmd.

CursorMoved - After the cursor was moved in Normal mode. Also when the text of the cursor line has been changed, e.g., with "x", "rx" or "p". Not triggered when there is typeahead or when an operator is pending. For an example see |match-parens|.

When the thread receives no motions for a while (g:pf_autorun_delay?), it will generate a path between the position the cursor was at before and after. x,rx,p and so on, or leaving normal mode, should finish the movement regardless of the delay.

Running on a thread means Vim is not blocked, so the user can continue working while the path is processed. Once pathfinding completes, the result should be shown only if it is shorter than the recorded input. For example, you don't want gg appearing as a suggestion if you used 2k to get to the same place.

I suggest using a popup window either next to the cursor or in a corner of the screen to show suggestions in a notification style. If the current vim doesn't have +popupwin, then just echo it.

This behaviour should be able to be disabled, e.g. by setting the delay option to a negative value. In that case, the current commands would still be available to use manually.

danth commented 4 years ago

11 would only be useable with manual commands since it'd take up a lot of screen space appearing all the time.

danth commented 4 years ago

The path should finish on:

danth commented 4 years ago

@aryabhatta-dey I have just realised that running the pathfinder in a thread would still cause the cursor to jump around while motions are tested. Don't know why I didn't think of that before.

I've had an idea how to work around this:

  1. When Vim is opened, launch another instance of Vim in a subprocess (subprocess.Popen), with -u set to a custom vimrc included with the plugin.
  2. The custom vimrc loads the pathfinding code, which starts a multiprocessing.connection.Listener or similar to listen for pathfinding requests.
  3. When a path needs to be calculated:
    1. Send the current buffer contents and window size to the subprocess. The window size can be restored using the &lines and &columns options, to avoid needing to copy surrounding windows over. Remember to include space for &cmdheight.
    2. Send the start and target positions.
    3. Pathfinding runs in the background instance of Vim, while the user continues to work.
    4. When complete, send the finished path back to the client (the main Vim instance).
    5. Display the received path.
  4. Ensure that the subprocess Vim closes itself when the client Vim disconnects.

I'm going to try implementing that to see if it works.