Sublime Text: Pressing Esc from multiple selections -- put cursor at last selection? - sublimetext2

With Sublime Text, after a multi selection is with from CMD+D, I usually alter the text, then want to escape the selections and have the cursor at where the last selection was.
Some feature that are close:
CMD+U will reselect selections
CMD+G will skip to the next occurence
CMD+Shift+G will skip backwards to the previous occurence
Are there any keyboard shortcuts that will do what I want, similar to Esc but forward, rather than backward?

You can create a very simple plugin to do this, and then bind a key to it:
From the Tools menu, select Developer -> New Plugin...
Paste in the following:
import sublime, sublime_plugin
class SingleSelectionLastCommand(sublime_plugin.TextCommand):
def run(self, edit):
last = self.view.sel()[-1]
self.view.sel().clear()
self.view.sel().add(last)
self.view.show(last)
Save it in the folder it recommends, name the file something like single_selection_keep_last_cursor.py
Open Preferences -> Key Bindings - User
Type/Paste in something similar to the following:
{ "keys": ["escape"], "command": "single_selection_last", "context":
[
{ "key": "num_selections", "operator": "not_equal", "operand": 1 }
]
}
Save it
This example creates a new plugin with a command called single_selection_last, and then binds the Esc key to it when there is more than one selection. This therefore overrides the default Esc behavior of keeping the first selection.
The keybindings file needs to be a valid JSON array, so if it is empty you will need to wrap the example above in square brackets [...] for it to work.
If you wish to use a different key, you just need to replace escape with the key combination you want. See Preferences -> Key Bindings - Default for examples.

Related

ROT47 of the current selection in SublimeText

When doing CTRL+SHIFT+P, there is command named Rot13 selection which allows to encrpyt the selected text.
I'd like to add a command named Rot47 selection that does:
selection = 'Test'
print ''.join(chr(33 + ((ord(ch) + 14) % 94)) for ch in selection)
#Output: %6DE
Where to write this Python code in SublimeText to have this new command present in CTRL+SHIFT+P?
You can write a plugin.
Some beginner (and not 100% correct) code is available here.
A complete plugin for Rot47 would have the following code:
import sublime, sublime_plugin
class Rot47Command(sublime_plugin.TextCommand):
def run(self, edit):
for region in self.view.sel():
if not region.empty():
s = self.view.substr(region)
s = ''.join(chr(33 + ((ord(ch) + 14) % 94)) for ch in s)
self.view.replace(edit, region, s)
Where to write this code?
Tools > New Plugin... will open a new buffer with some boilerplate code. Replace the boilerplate with the above code and save the file as rot47.py in /<sublime-text-dir>/Packages/User/.
You can test the above plugin by opening the console using Ctrl+`, and typing view.run_command('rot47') and hitting Enter. Make sure that you've selected some text before running your new Rot47 command.
Furthermore, if you want to create a keyboard shortcut for your new rot47 command: go to Preferences > Key Bindings -- User and add the following entry:
{ "keys": ["ctrl+shift+4"], "command": "rot47" }
(you can of course choose a more meaningful key combination.)
What did the above plugin code do?
self.view.sel() gives an iterable on the selected text regions (there can be multiple selections in the same buffer, go Sublime!). A region is basically a (start_index, end_index) pair that denotes a selected substring. self.view.substr(region) gives you the required substring.
We then modify the selection text (variable s) as desired and replace the selection with the new text (the call to self.view.replace()).
For a more extensive API reference, see this.

Can I create my own command in sublime and how to associate python implementation to that command?

One more depth into my former question Why doesn’t this hotkey configuration for Sublime Text work?. Now I come to the implementation of sublime command, it is really a confusing way to hack what commands sublime has, as the exploration in former thread in order to find the command which is used to open a browser, finally I found it with help of #MattDMo.
Then I find there is one file named open_in_browser.py in the Packages/Default folder, I guess the commands is just the file name of .py files, but in fact I cannot find the corresponding file which could be named find_pre.py to command find_prev, then I copy open_in_browser.py as open_browsers.py, and add { "keys": ["ctrl+b"], "command": "open_browsers"} to sublime keymap, but it doesn't work. Then I realized that there should be some place which registers sublime commands to their implementation, so if there is such a mechanism, what is it? Where can I find it?
TL;DR
Create a file with any name in the Packages/User directory. Create a class in the file like MyTestCommand with a run method. Create a keymap using the class name in snake case and without Command suffix. Use named arguments to pass anything to the command.
Full answer
There is no need to register anything to create custom commands. Filename doesn't matter as Sublime Text simply scans it's directories for .py scripts and automatically executes them (registers them).
Here is the example script I use:
import sublime
import sublime_plugin
class ChangeViewCommand(sublime_plugin.WindowCommand):
def run(self, reverse=False):
window = self.window
group, view_index = window.get_view_index(window.active_view())
if view_index >= 0:
views = window.views_in_group(group)
if reverse:
if view_index == 0:
view_index = len(views)
if reverse:
new_index = view_index - 1
else:
new_index = (view_index + 1) % len(views)
window.focus_view(views[new_index])
So what it does - switches to the next/previous tab in the current group (the default behavior circles around all tab groups).
So we simply save it as any name in Packages/User directory.
Then we must create the key bindings in our user keymap file:
{ "keys": ["ctrl+tab"], "command": "change_view" },
{ "keys": ["ctrl+shift+tab"], "command": "change_view", "args": {"reverse": true} },
As you may see, the command is snake_case of the class name without the Command suffix. This will run the class's run method with named arguments.
Does this answer your question? For debugging in case of any errors - open the ST console (default shortcut is ctrl + `)

Sublime: Shortcut Key to Confirm Replace All?

After I hit Ctrl-H and enter my search/replace terms, is there another key combination I can hit to actually execute that command, without having to use the mouse to press the Replace All button?
I am not a mouse guy, and would prefer to do it from the keyboard.
Thanks
The shortcut for replace all should be "ctrl+alt+enter"
Here it is in the Keybinding JSON.
{ "keys": ["ctrl+alt+enter"], "command": "replace_all", "args": {"close_panel": true},
"context": [{"key": "panel", "operand": "replace"}, {"key": "panel_has_focus"}]
},
You can see the full list of key bindings / shortcuts by going to the Preferences Menu then Keybindings -> Keybindings - Default . It will show a json file full of all the shortcuts.
To create your own shortcut by going to the Preferences Menu then Keybindings -> Keybindings - User, just add your own entry to the json file, in the same format as the json file openend by doing the above.

Hotkey to end the line with a semicolon and jump to a new line in Sublime Text 2

I'm trying to figure out a hotkey at work. I just got this job and I am using a Mac for more or less the first time in my life.
Back home on my Laptop, when using Eclipse, I seem to remember there being a single hotkey which would both:
Add a ; to the end of my current line (no matter where the caret was within said line)
Place my cursor at the beginning of a new line, with the same indentation level as the line I had just added a semicolon to
Does anybody know if this was an Eclipse-specific hotkey, or know of a way to replicate said hotkey in Sublime Text 2?
Best solution for this is recording a macro on Sublime Text and then assigning it to a keyboard shortcut. Follow these steps:
Create a line such as alert('hello') and leave the cursor right
after letter 'o'.
Then go to Tools > Record a Macro to start recording.
Press Command+→ to go to the end of line.
Press ; and hit Enter
Stop recording the macro by going to Tools > Stop Recording Macro
You can now test your macro by Tools > Playback Macro (optional)
Save your macro by going to Tools > Save Macro (ex: EndOfLine.sublime-macro)
Create a shortcut by adding this between the square brackets in your
in your Preferences > Key Bindings - User file:
{
"keys": ["super+;"], "command": "run_macro_file", "args": {"file": "Packages/User/EndOfLine.sublime-macro"}
}
Now, every time you hit Command+;, it will
magically place the semicolon at the end of current line and move the cursor to the next line.
Happy coding!
After reading your question about three times, I finally realized that you were looking for one hotkey to perform both operations. Whoops.
Your request sounds like the Ctrl+Shift+; hotkey of the Smart Semicolon Eclipse plugin. While adding semicolons of a genius-level IQ would probably require an entirely new Sublime Text 2 plugin, you can easily create a smart semicolon–esque key binding with Sublime Text's Macros. I actually didn't know about them until now!
In this case, recording the macro yourself is actually the fastest way to create it, rather than copying and pasting a new file (and now you'll have the experience for making more). First, open a new file and type in your favorite garbage line:
Lord Vetinari's cat|
Then move the caret to anywhere within the line:
Lord Veti|nari's cat
Now, press Ctrl+Q, the hotkey for Tools -> Record Macro. If the status bar is enabled, it will notify you that it is "Starting to record [a] macro". Press End (if you don't have an End key, skip to below), then ;, then Enter. Finally, press Ctrl+Q again to stop recording. When you do, the status bar will display "Stopped recording macro". Check that your macro is working by hitting Ctrl+Shift+Q on a code segment of your choosing.
Just pressing Enter will adjust indentation on the next line accordingly as long as the "auto_indent" setting is set to true. See Preferences -> Settings – Default, line 59.
When you're satisfied, save your new macro with Tools -> Save Macro.... I saved mine as Packages/User/smart-semicolon.sublime-macro. My file looked something like this; feel free to copy it if you can't or won't make the macro manually:
[
{
"args":
{
"extend": false,
"to": "eol"
},
"command": "move_to"
},
{
"args":
{
"characters": ";"
},
"command": "insert"
},
{
"args":
{
"characters": "\n"
},
"command": "insert"
}
]
"extend": false, just means that the macro won't add any text to the working selection. Read more about the options for commands at the Unofficial Docs Commands Page.
Now that you have your macro, we can give it a custom key binding. Add the following lines to your Preferences -> Key Bindings – User file:
{ "keys": ["ctrl+shift+;"], "command": "run_macro_file", "args": {"file": "Packages/User/smart-semicolon.sublime-macro"}, "context":
[
{ "key": "selector", "operator": "equal", "operand": "source.java" }
]
},
Replace Ctrl+Shift+; with whatever key binding you prefer, save your file, and give it a shot. The "context" array restricts the key binding to Java files (see the Unofficial Docs Key Bindings page for more information on contexts); if you want the key binding to be active everywhere, use this line instead:
{ "keys": ["ctrl+shift+;"], "command": "run_macro_file", "args": {"file": "Packages/User/smart-semicolon.sublime-macro"} },
This NetTuts+ article has much more information on macros and binding them to keys; I referenced it often. This UserEcho post looks like it has more information on making the insertion more extensible.
You can also use a ready-made sublime package built for this purpose: AppendSemiColon
You can use package control to install it, just search for "AppendSemiColon".
Place a semicolon at the end of the cursor's current line(s) by pressing:
Command+; on OS X
Ctrl+; on Windows and Linux
and
You can also automatically go to the next line at the same time like this:
Command+Shift+; on OS X
Ctrl+Shift+; on Windows and Linux
I've been using this package for a while now, and it works great.
UPDATE:
As the author mentioned in a comment, you can now also change the default hotkeys if you like (personally, I love the defaults). As an example, just change:
[
{ "keys": ["ctrl+;"], "command": "append_semi_colon" },
{ "keys": ["ctrl+shift+;"], "command": "append_semi_colon", "args": {"enter_new_line": "true"} }
]
in your sublime-keymap to use whatever keys you want.
I tested the latest version, and this feature too works fine. There was a bug where extra semicolons were being appended incorrectly upon extra hotkey presses - this minor annoyance has been fixed too. Thanks, MauriceZ/mzee99!
Ctrl+Enter will create a new line with the same level of indentation.
I could not find anything like the Ctrl+A you mentioned
I'm on Sublime Text 3 ... inspired by your post, I've added the following to my .sublime-keymap:
{ "keys": ["ctrl+enter"], "command": "run_macro_file", "args": {"file": "Packages/User/endOfLine.sublime-macro"} },
I'm amazed at how much time this saves.
#Felipe covered the second point. You can mimic the behavior of the first with a simple macro or plugin. I say or because you didn't describe the cursor position after you hit the key combination. Does it move the cursor to the next line? Does it insert a new line? I think you get the idea.
I'm pretty sure eclipse works on OS X as well as windows, so if you are more comfortable with that, why not use it (unless your job requires ST of course)? Most of the key bindings are probably the same/similar (well it's probably command rather than control for shortcuts).
http://www.eclipse.org/downloads/?osType=macosx
If you continue using ST, it's probably worthwhile to learn the basics of plugins. A lot can be built so you have the same behavior as other editors, it just takes some extra effort (through creating the plugin or finding a plugin that does it) up front.

Sublime Text 2 : Rectangular or column select by keyboard only on Mac 10.8.3?

I cannot figure out how to do rectangular selection in Sublime Text 2 using only keyboard. What I seem to always come across is to do ctrl-shift-up or -down (which I assume mean arrow keys), as laid out here: https://stackoverflow.com/a/13796939/1022967
But when I try to use that, I must send an OS-level command, because what happens is that my window slowly recedes and shows me all of the open apps/windows I have going on my Mac (I forget what that's called -- like a dashboard of what I have running). This happens when I use this key chord in apps outside of Sublime Text 2 as well.
Do I have something misconfigured? Could I have alternate key chords to do this?
You do not need to change the Sublime Text key bindings.
Simply go to System Preferences -> Keyboard -> Keyboard Shortcuts, click on Mission Control, and uncheck the boxes next to Mission Control and Application windows, then you will be able to use the default keys for column selection. This is a quick and easy fix, especially if you are not using Mission Control.
Go to the menu:
Sublime Text -> Preferences -> Key Bindings - Default
What are you looking for is:
{ "keys": ["ctrl+shift+up"], "command": "select_lines", "args": {"forward": false} },
{ "keys": ["ctrl+shift+down"], "command": "select_lines", "args": {"forward": true} },
The actual keys might be different, you need to find "select_lines" commands with these arguments.
If you want to change the keys, you need to open Key Bindings - User in the menu, then copy-paste and edit these lines according to your needs.
You will notice the change immediately after saving the file, if it has proper format (JSON), otherwise you'll get an error message.
FWIW, on my MacBook Pro running OS X 10.8.5, I set the keyboard bindings for column selection mode in my "Key Bindings - User" file in Sublime. Setting the key binding at the Mac System level in System Preferences > Keyboard > Keyboard Shortcuts > Application Shortcuts doesn't work.
After looking through the Sublime "Key Bindings - Default" preferences file and my Mac system preferences to make sure I wouldn't break an existing key binding, I went with Ctrl+Alt+Shift+Up and Ctrl+Alt+Shift+Down for column selection.
Here's what I have in my Sublime "Key Bindings - User" file:
{ "keys": ["ctrl+alt+shift+up"], "command": "select_lines", "args": {"forward": false} },
{ "keys": ["ctrl+alt+shift+down"], "command": "select_lines", "args": {"forward": true} }
Hope this helps.
For Mac, you need to use the command key, not control. So vertical select would be Command-Shift-Up/Down, horizontal is Command-Shift-Right/left
Both of the selection types go from where your cursor is currently so make sure your cursor is in the correct place you want it.
Simplest solution, don't need to touch the bindings file.
Hold down ALT key and make a selection using touchpad in 'clicked' state. It only selects the column.