Sublime Forum

How can I expand_selection to a sentence?

#1

I’d like to be able to select the sentence under my cursor. In essence I’d like something like vim’s vis or vas commands: Select all the text between two fullstops, including the ending fullstop.

I’ve looked in various .sublime-commands but I can’t find the right argument to pass to the expand_selection command. All I see is for brackets, tags, paragraphs etc.

Unless I’m mistaken, Vintage mode does not support selecting sentences either.

0 Likes

#2

Still no update on this one, eh?

I guess it could be implemented on top of a plugin like Bracket Highlighter, but instead of matching against brackets, it would match against fullstops.

0 Likes

#3

It might be more fruitful to investigate the **move **command with the argument “extend”:True:

self.view.run_command("move", {"by": "stops", "extend":False, "forward":False, "word_begin":True, "punct_begin":True, "separators": ""})

There may be a clue in this key-binding:

[code] { “keys”: “]”], “command”: “move”, “args”: {“by”: “characters”, “forward”: true}, “context”:

		{ "key": "setting.auto_match_enabled", "operator": "equal", "operand": true },
		{ "key": "selection_empty", "operator": "equal", "operand": true, "match_all": true },
		{ "key": "following_text", "operator": "regex_contains", "operand": "^\\]", "match_all": true }
	]
},[/code]

If you decide to create or extend a .py plug-in then you might side-step ‘run_command’ and manipulate sel() directly using the ST-API.

0 Likes

#4

Any progress on this front? I’m pretty surprised to come from Vim and find that I can’t do v i s or v i p, for example. There is no sentence selection or paragraph selection from command mode. ???

0 Likes

#5

You would have to write a small plugin to select a sentence (probably using view.find() to get the end point and using the cursor as a start point). There is a built in command for paragraph selection. You can create a keybinding with the following command “expand_selection_to_paragraph”

0 Likes

#6

Easily done via Python API, add a keybinding for “expand_selection_to_sentence” and add a .py file to your User folder with following contents:

[code]import sublime, sublime_plugin, string

class ExpandSelectionToSentenceCommand(sublime_plugin.TextCommand):
def run(self, edit):
view = self.view
oldSelRegions = list(view.sel())
view.sel().clear()
for thisregion in oldSelRegions:
thisRegionBegin = thisregion.begin() - 1
while ((view.substr(thisRegionBegin) not in “.”) and (thisRegionBegin >= 0)):
thisRegionBegin -= 1

		thisRegionBegin += 1
		while((view.substr(thisRegionBegin) in string.whitespace) and (thisRegionBegin < view.size())):
			thisRegionBegin += 1

		thisRegionEnd = thisregion.end()
		while((view.substr(thisRegionEnd) not in ".") and (thisRegionEnd < view.size())):
			thisRegionEnd += 1

		if(thisRegionBegin != thisRegionEnd):
			view.sel().add(sublime.Region(thisRegionBegin, thisRegionEnd+1))
		else:
			view.sel().add(sublime.Region(thisRegionBegin, thisRegionBegin))

[/code]

3 Likes

#7

[quote=“robertcollier4”]Easily done via Python API, add a keybinding for “expand_selection_to_sentence” and add a .py file to your User folder with following contents:

... [/quote]

That worked flawlessly. Thank you very much.

0 Likes

#8

This is exactly what I want to do too. I use a macbook and have places this inside ~/Library/Application Support/Sublime Text 3/Packages/User/

Is this the right folder or where do I place the above code and how do I verify it is being read into sublime text. I have placed a keybinding already in the user keybinding preferences.

0 Likes

#9

Yes, that is the correct folder. Here’s the exact steps to make this work:

  1. Create the plugin file: In the User folder, create a file called expandSelectionToSentenceCommand.py
  2. Add the plugin code: Copy the code from above and paste it in the file you just created.
  3. Add key binding to call the code: In the User folder, locate the file called Default (OSX).sublime-keymap and add the following text in it:
    { "keys": ["ctrl+alt+space"], "command": "expand_selection_to_sentence" }
    Make sure you add the appropriate commas before/after this line to properly separate it from the key bindings after/before it.

You’re set! When you press Ctrl + Alt + Space, your selection will be expanded to the current sentence.

Optionally, you might want to also create a Command so you can expand selections through the Command Palette (accessed via Ctrl+Shift+P or via the menu Tools → Command Palette… ):

  1. Locate your custom Commands file: In the same folder as before, locate the file User.sublime-commands. If it doesn’t exist, create a new file with that name.
  2. Add Command to call the plugin: In that file, add the following text:
    { "caption": "Selection: Expand to Sentence", "command": "expand_selection_to_sentence" }
    Again, pay attention to any commas needed.

Once again you’re set. Once you restart Sublime Text, you’ll find a new command in your Command Palette called “Selection: Expand to Sentence”

1 Like

How can I keybind repl_python_run?
#10

I saved it as “select-sentence.py” in ~/Library/Application Support/Sublime Text 3/Packages/User

I added 1 line to my User Keybindings:

{ "keys": ["ctrl+shift+."], "command": "expand_selection_to_sentence" },

It’s not perfect but ok.

cheers!

0 Likes

#13

I realized the problem was with copying and having tabs and spaces mixed if anyone is having issues. Actually added an additional command to move to the end of the sentence or beginning of the sentence for navigating as well. Basically moving by . with an option to move before or after the . if anyone wants the aditional function let me know. Cheers

0 Likes

#14

Thanks for this. I was having trouble getting this to run on ST3, but found this slightly modified version here which worked for me:

import sublime, sublime_plugin, string
class ExpandSelectionToSentenceCommand(sublime_plugin.TextCommand):
	# TODO: Add foward command to go forward and backward selction of sentences
	def run(self, edit, forward = False):
		view = self.view
		# whitespace = '\t\n\x0b\x0c\r ' # Equivalent to string.whitespace
		oldSelRegions = list(view.sel())
		view.sel().clear()
		for thisregion in oldSelRegions:
			thisRegionBegin = thisregion.begin() - 1
			while ((view.substr(thisRegionBegin) not in ".") and (thisRegionBegin >= 0)):
				thisRegionBegin -= 1
			thisRegionBegin += 1
		while((view.substr(thisRegionBegin) in string.whitespace) and (thisRegionBegin < view.size())):
			thisRegionBegin += 1

		thisRegionEnd = thisregion.end()
		while((view.substr(thisRegionEnd) not in ".") and (thisRegionEnd < view.size())):
			thisRegionEnd += 1

		if(thisRegionBegin != thisRegionEnd):
			view.sel().add(sublime.Region(thisRegionBegin, thisRegionEnd+1))
		else:
			view.sel().add(sublime.Region(thisRegionBegin, thisRegionBegin))
0 Likes