Sublime Forum

Get point under mouse?

#1

Is it possible in a plugin to get the point currently under the cursor?

I want to build a plugin that does fuzzy cursor insertion so that if I hold down a meta key while mousing around the cursor is moved to be at the word boundary nearest to the current mouse location instead of being in the middle of a word.

To start, I want to have a text command that moves the cursor to the matching point under the cursor but I can’t seem to sort out how to get where the cursor by asking for it. I don’t want to be relegated to on_hover actions.

Thanks!

0 Likes

#2

on_hover is the only way to get notified about cursor positions.

3 Likes

#3

By including a mousemap, I can get mouse point information on click and release, is it possible to get updates for drags as well?

0 Likes

#4

One method of getting that information is to create an EventListener and listen for the drag_select command being executed, but there may be another way.

2 Likes

#5

Using on_selection_changed() in a ViewEventListener definitely works better than the text command. But I don’t want to have this behavior be enabled all the time, and I don’t want it to be modal. Is there any way to get the currently pressed keys, or ways to finagle a mousemap to both call drag_select and also set a global variable?

I’ve tried making a text command triggered by a mousemap with ctrl + option + button1, having that command set a global variable and then call sublime.run_command(‘drag_select’), but that doesn’t seem to work. No selection ends up happening. Invoking drag_select from the mousemap directly does work, but I don’t know how to get at the args being passed into it from my EventListener.

Thanks! This is getting closer.

0 Likes

#6

That seems like it should work (having said that I haven’t had a chance to poke at it).

Things to check would be:

  • Is your command returning True for want_event? The default is to return False. If you’re just acting as a proxy and passing all of your arguments to the core command, it may be doing nothing because without an event argument it doesn’t know what to do.
  • You may want to try self.view.run_command() (or self.view.window().run_command()) instead of sublime.run_command() and see if that triggers it like you expect. There is some subtle interplay between what type of commands each of the versions of run_command can run sometimes.
  • When in doubt, sublime.log_commands(True) from the sublime console and make sure that your mapping is actually triggering the way you expect it to.
2 Likes

#7

I’m surprised to find that when I call run_command() from inside a command, nothing is logged by sublime.log_commands(True). So far, no combination of self.view[.window()].run_command(“drag_select”,[event]) has made text selection occur.

Is there a way to get text events triggered by both key down and key up? It’s possible for mousemap commands but I don’t seen any examples for keymap commands. Then I could fake this by setting a global during key down and looking for it in on_selection_chaged()

0 Likes

#8

Indeed, the command log only displays commands executed at the top level. Possibly this is because so many commands build their functionality by executing other commands and it would be hard to track what exactly is happening, but that’s just a guess on my part.

I don’t think there’s any way to detect a key up event, no.

Simplistically, this plugin creates a drop in replacement for drag_select that lets you know that a drag selection is happening and then invokes the underlying drag_select command to perform the selection:

import sublime
import sublime_plugin


class MyDragSelectCommand(sublime_plugin.TextCommand):
    def run(self, edit, **kwargs):
        print("my drag select", kwargs)
        self.view.run_command("drag_select", kwargs)

    def want_event(self):
        return True

Replacing the drag_select command in the standard mouse map with my_drag_select works as I would expect it to; it outputs its arguments to the console and then the appropriate selection changes.

Note however that it’s the drag_select command that performs the drag select, so you don’t get notifications of the selection as it changes (except through a selection changed event). As such I don’t know that this helps you much unless you can figure a way to detect when the drag_select command has finished executing so you know to stop paying attention to selection changes.

2 Likes

#9

Fabulous! the kwargs do the trick, maybe the event just needed to be wrapped in an array.

This has got it working great. To determine if the drag_select command has finished, I just check instead to see if a new one has started by checking to see if both the left and right anchors for the selection have changed. If one of them is the same then it’s probably the same drag event.

Hacks on hacks on hacks but it seems to work well. Thank you for all your help!

0 Likes

#10

If the API allowed it, I would make holding down crtl-option cause a shadow cursor to appear where it would be inserted on click, so that’s my feature request, but otherwise this lets me do everything I want.

0 Likes

#11

There is a similar feature request on the core:

  1. Core$1371 Underline all clickable text elements when pressed ctrl

You open up vote it or open a new feature request for a API to correctly handle this.

0 Likes