Sublime Forum

Customizing ctrl+click

#1

Iā€™ve found how to bind my own command to ctrl+click, but now Iā€™m struggling with obtaining current position of the cursor. Doing view.sel()[0] is obviously unreliable, so Iā€™m looking for a better way.

A great solution would be to get mouse coordinates of the click, convert them to text coordinates via view.layout_to_text and do my stuff. After enabling sublime.log_commands Iā€™ve noticed that Sublime passes mouse coordinates to drag_select handlers (e.g. ā€œcommand: drag_select {ā€œeventā€: {ā€œbuttonā€: 1, ā€œxā€: 582.5, ā€œyā€: 274.5}}ā€). However, Iā€™ve been unable to get hold of them - neither bound by press_command, nor by command in sublime-mousemap entry, my command doesnā€™t receive the ā€œeventā€ argument.

Any ideas?

0 Likes

How does drag_select work?
#2

Let me know if you figure out how to do thisā€”I tried briefly a while ago but I donā€™t think I found anything.

0 Likes

#3

Normally itā€™s simply part of the args variable:

[code]import sublime, sublime_plugin

class TestPluginCommand(sublime_plugin.TextCommand):
def run_(self, args):
print argsā€™eventā€™]
[/code]

I tried to play with this but i had issues converting reliably (x,y) to test position (it was some times ago but maybe things are better now ā€¦). So in the end what i did was pass the arg to the drag_select command, and then use view.sel()[0].
This was for a plugin to emulate a kind of drag&drop (more a sel&click) before it was implemented: you can find the very simple source here: bitbucket.org/Clams/pasteselonclick/src

0 Likes

#4

Didnā€™t work for me. The second argument is just a plain Edit object, which cannot be indexed. Could you, please, post your mousemap?

0 Likes

#5

{ "button": "button2", "modifiers": "alt"], "press_command": "paste_sel_on_click", "press_args" : {"del" : true} }, { "button": "button2", "modifiers": "alt","ctrl"], "press_command": "paste_sel_on_click", "press_args" : {"del" : false} } ]

0 Likes

#6

Ah I see! run_ (with an underscore) strips the event from the arguments list before calling run (no underscore). So you have to override run_ instead of overriding run.
Awesome.

0 Likes

#7

I donā€™t think wbondā€™s package manager does anything with dependencies, but I just wrote a cool mouse-callback thing:
gist.github.com/2979613
It lets you inherit from MouseEventListener and then you get an on_pre_click with the args and an on_post_click with the position in the file where the user clicked.
I think I might upload it to github and make it a real repo, and then Iā€™ll make my ScrollOffset plugin ignore mouse input. Now that would rock!

0 Likes

#8

[quote=ā€œadzenithā€]Ah I see! run_ (with an underscore) strips the event from the arguments list before calling run (no underscore). So you have to override run_ instead of overriding run.
Awesome.[/quote]

Woot! Whatā€™s the difference between run and run_?

0 Likes

#9

/quick thread hijack:

@adzenith I was checking out your ScrollOffset plugin earlier today. I use a similar plugin that always keeps the cursor centered, so I thought your ā€œmouse-callback thingā€ may be solving similar problems as the ones I am encountering. Honestly, I canā€™t figure out what itā€™s supposed to do. What I was looking for is disabling the click+hold for selection so that I could only use mouse button 1 to change the cursorā€™s location. (I would then use shift+click for selection). With the aforementioned plugin, my thumb has a bad habit of tapping the touchpad, selecting chunks of text which I then gleefully proceed to overwrite without noticingā€¦ Hope this makes, sense

0 Likes

#10

The mouse-callback thing is not yet integrated into my ScrollOff plugin, which may have explained what you were seeing.
My plan was to capture on_pre_click, disable ScrollOff for the next on_selection_modified, then capture on_post_click and re-enable. This would make it so that clicking wouldnā€™t scroll the display, allowing normal selections with the mouse. Does that make sense?

0 Likes

#11

[quote=ā€œxeno.byā€]

[quote=ā€œadzenithā€]Ah I see! run_ (with an underscore) strips the event from the arguments list before calling run (no underscore). So you have to override run_ instead of overriding run.
Awesome.[/quote]

Woot! Whatā€™s the difference between run and run_?[/quote]

Thatā€™s the entire difference right there. run doesnā€™t get the event.

0 Likes

#12

I wasnā€™t clear, sorry. I tried the Scroll Off plugin and the mouse stuff separately (one after the other). If the latter only works with the former, then thatā€™s why I didnā€™t see any effect. Or maybe I still donā€™t understand what itā€™s supposed to do.

Sort of. (Iā€™m not a programmer and your explanation is a little technical.) Iā€™ll keep an eye out for what youā€™re building and see if it might work for me also, although probably not out of the box.

In the meantime I would be quite happy with just disabling the mouse (or, at least, button 1) altogether when my plugin is enabled, but ā€œcontextā€ seems to be ignored in mousemaps. Darn.

0 Likes

#13

I just pushed my changes. Try installing both ScrollOffset and MouseEventListener and tell me if you like what you see.

0 Likes

#14

You should put something in the README about the fact that ScrollOffset only works when word wrap is off :confused:

ScrollOffset looks like a plugin I might well use (for coding, which is a different situation than the one Iā€™ve been talking about).

As for using MouseEventListener with my typewriter plugin, I didnā€™t manage to get anything particularly useful done.

Iā€™ve thrown up the plugin below, if you donā€™t mind having a look. (But I donā€™t mean to impose.)

import sublime, sublime_plugin

class AlwaysCenterCommand(sublime_plugin.EventListener):
	def on_selection_modified(self, view):
		if view.settings().get('typewriter_mode') == 1:
			sel = view.sel()
			region = sel[0] if len(sel) == 1 else None
			if region != None:
				view.show_at_center(region)

The plugin keeps the cursor always centered. What Iā€™ve been hoping to do is to prevent is extending the selection with mouse clicking. Is this possible?

Again, feel free to ignore this stuff.

0 Likes

#15

I guess I never use word wrapā€¦ Maybe I should look into why it doesnā€™t work.

Iā€™d install MouseEventListener, then in your AlwaysCenterCommand add this:

ignore_count = 0 def on_pre_mouse_down(self, args): self.ignore_count = 3 def on_post_mouse_down(self, click_point): self.ignore_count = 1

Then inside of on_selection_modified, throw this at the top:

if self.ignore_count: self.ignore_count -= 1 return

Lemme know if that works.

0 Likes

#16

typewriter_mode was added to bufferscroll, did you have some problem with this plugin? I want to fix it, if that is the case.

REgars,

0 Likes

#17

Hi @tito,

I am not using your BufferScroll plugin, so there isnā€™t anything related to that for you to fix. If youā€™re offering your excellent services thoughā€¦ :wink:

I am using the plugin I posted above; itā€™s slightly modified from something @facelessuser has written1. This plugin activates on ā€œon_selection_modifiedā€ rather than ā€œon_modifiedā€ (as is the case with BufferScroll). This means that the screen is scrolled every time the cursor changes position,which works great when you are:

a) writing prose rather than code,
b) using the keyboard rather than the mouse

Unfortunately, the functionality of the mouse is quite broken: itā€™s too easy to select text when trying to position the cursor. I havenā€™t actually used iA Writer2, but it disables the mouse completely, I suspect for this reason.

I actually rather like how it works, if only I could disable extending the selection on mouse click.

0 Likes

#18

I understand, Iā€™ll take a look after lunch, Iā€™m interested into providing better behaviour for these features.

0 Likes