Sublime Text Keybinds Context Within Unsaved Changes - sublimetext3

I am trying to create a keybind within sublime text 3 that changes its behavior depending if a file has unsaved changes or not.
Sublime already supports a context option within the creation of keybinds such as this:
{"keys":[":","e"],"command":"revert","context":[{"key": "setting.command_mode", "operand": true}]},
However I can't find if there is a way to detect if the file is saved or dirty.
Anyone have some insights on this?

Looking at the unofficial documentation (the official documentation is out-of-date), there seems to be no context that can be used in keybindings to determine if a file is saved or dirty.
I think it would therefore be necessary to create a plugin in Python, with a command which would perform the actions you require based on whether the file has unsaved changes or not. You could then set the keybinding to execute this command regardless of context, as the plugin will contain the necessary logic.
The official documentation mentions that a plugin can determine whether a file is saved or not using the is_dirty() method on the view.
I see from your question that you want to execute the revert command, so I have drawn up a quick and simple Sublime Text plugin / python script that will achieve this:
import sublime, sublime_plugin
class RevertIfUnsavedCommand(sublime_plugin.TextCommand):
def run(self, edit):
if self.view.is_dirty():
self.view.run_command('revert')
else:
print('TODO: do something else here')

Related

control+/ does not work to comment multi line in sublime 3

I can't comment out multi line in sublime 3. Looked at this Keyboard shortcut to comment lines in Sublime Text 3 already but it is not fixing it
Sublime version is 3.2.1 build 3207 . on windows 10.
Please help me out if have any tips.
The keyboard binding for commenting is indeed Ctrl+/ (Cmd+/ on MacOS) so in the general case what you're trying should work just fine.
That said, the keys in question are bound to the toggle_comment command and that command requires language specific metadata to know what comments are supposed to look like. For example comments look and work differently in HTML than they do in C or JavaScript. Some file types (such as plain text files) aren't code and thus don't have a concept of comments at all.
If the metadata file for a file type is missing, then the toggle_comment command won't do anything because comments are assumed to not be valid, which seems to be what's happening to here.
The first thing to check would be to examine the bottom right of the window to see if Sublime agrees with you about what the file type is supposed to be. For example, newly created tabs are Plain Text files until you save the file for the first time, and comments are not allowed in Plain Text files.
If the file type doesn't say what you think it should, you can click it to open a menu and select the appropriate type for that file.
If the type of the file looks to be correct and the command still doesn't work, then the metadata file needed is not being provided in the package that is adding support for that language. In that case you should raise an issue with whoever is responsible for the package in question and get them to add the appropriate file.
Based on the comments on your question, you think you're editing JavaScript files but Sublime thinks you're editing an ActionScript file instead. The JavaScript package includes the appropriate file, but the ActionScript package does not.
So in your particular case, your best bet is to switch the file type to JavaScript and your problem should go away. If you actually want to be editing ActionScript instead, then you need to create an issue on the Default package tracker and ask for this to be added.

UltiSnips doesn't automatically reload changes to snippets file

(Documenting this here because I couldn't find a good answer online.)
When using UltiSnips, the documentation says (2:12 in this screencast) that writing the .snippets file is enough to cause an automatic reload of the snippet. However, this doesn't work for me. What's happening?
I had this question myself, as frequently updating my own .snippets files and not having them immediately available is unpleasant. After some experiments I discovered the answer:
:call UltiSnips#RefreshSnippets()
In case you are curious, I found it by typing :call <C-d> (a very long list, by the way).
However, this command does not update the autocompletion list of YouCompleteMe (which is mostly irrelevant, but sometimes you might want to browse through your options with description next to it).
Looks like the UltiSnips reload applies within a vim instance. So make sure to open & save the snippets file within the vim instance that you want the changes to take effect in.
To help with this, the command :UltiSnipsEdit will open the .snippets file corresponding to your correct file. You can configure how the snippets file opens using this command:
g:UltiSnipsEditSplit Defines how the edit window is opened. Possible
values:
|normal| Default. Opens in the current window.
|tabdo| Opens the window in a new tab.
|horizontal| Splits the window horizontally.
|vertical| Splits the window vertically.
|context| Splits the window vertically or
horizontally depending on context.
Sample usage in .vimrc: let g:UltiSnipsEditSplit="context"
Note that this doesn't work as well if you'd like to make the changes in a different snippets file (e.g. you're working on a cpp file and you want to add a snippet for all c files (and your cpp.snippets file does extends c). If you're in this situation and you're editing your snippets frequently, consider keeping that snippets file open in a tab/pane.
Other suggestions / input welcome!
(from Documentation)
I haven't been able to find a satisfactory answer to this either. Until somebody can post something better, I recommend just using
:e!
This reloads the current window to the most recently-saved file. I know it's not much, but it's what I'm using until I find a better way to do it.

How to change the Sublime Text 3 StatusBar message in a command or macro (no plugin)?

addressing Sublime Text 3 users here.
I wrote a couple of macros to enable spell-check and load a specific dictionary, as I constantly swap between French and English and I wanted a simple shortcut for this (instead of browsing the menu or two successive commands in the command pallet).
My macros work as expected (french-spellcheck.sublime-macro, english-spellcheck.sublime-macro).
But I would like to display a message in the Status Bar, for instance "Switched to French" or "Switched to English" (for some time, let say 5 sec).
I looked everywhere I know and I tried for some time, but apparently there is no way to do this in a command (that could be added at the end of the macro), as the set_status internal ST3's Python API command (from Window package) is only available for plugins...
Does any one has an idea of how to display a message to the SublimeText3 StatusBar in a command/macro and not with a plugin? Thanks!
There is no built in command that invokes the API methods for doing this (at least not a documented one), so there's no way to go about this without a plugin of some sort.
That said, in order to do what you want, the following is all you would need to save into a file named e.g. set_status.py in your Packages/User folder (alongside your macros). This provides a set_status command that takes a value named value for the text to display, as mentioned in the commented out portion of your macro file.
import sublime, sublime_plugin
class SetStatusCommand(sublime_plugin.TextCommand):
def run(self, edit, value="set_status: use arg 'value' to set text"):
self.view.window ().status_message (value)
This uses a different API than the one you mention in your macro file comments; status_message does the work of displaying a message in the status bar, waiting a few seconds, and then removing it, which makes the command simple to implement.
If you wanted more control (i.e. to change the duration) you would need to modify this to invoke the API commands your macro files already mention: view.set_status() and sublime.set_timeout().

How to run command on save in Sublime Text 3?

Sublime Text offers built-in commands, such as paste, new_window, toggle_comment etc. In addition, some plugins offer their own commands that can be used for key binding.
Can I force any of these commands to be ran on file save? The reason I need is because I'd like to run CSScomb on file save instead of / in addition to having key binding for it. The command name is css_comb.
Sublime-hooks package allows you to run packages based on event (on new, on save, etc.), so you can use it to achieve your goal. Just add this code to CSS syntax settings:
"on_pre_save_language": [
{
"command": "css_comb"
}
]
If you are familiar with plugins maybe you can make a plugin that extends EventListener and override on_post_save or on_pre_save methods.

Sublime Text: set language for each file

In Sublime Text (3), I can select the dictionary to use for spell checking. However, this setting seems to be global rather than on a per-file basis.
This is annoying when I'm working on multiple files that use different languages.
How can I achieve that Sublime Text remembers what dictionary to use for a file?
Usually it is needed to set settings based on the syntax of the file (one dictonary for javascript files, another for css files, etc.). You can achieve this goal easily using syntax specific settings. But there are also times where you need file-specific settings (files with the same syntax with different settings values). I give you example solutions for both cases.
File-specific way
In order to set view-specific settings (similar to file-specific) you can write a plugin. This simple example shows an input panel in which you can set the desired dictionary for the opened file.
import sublime, sublime_plugin
class Example(sublime_plugin.TextCommand):
def run(self, edit):
"""Default dictionary (caption)"""
defaultDict = 'Packages/Language - English/en_US.dic'
if self.view.settings().get('spell_check') == True and self.view.settings().get('dictionary') != None:
defaultDict = self.view.settings().get('dictionary')
"""Show panel to input dictionary name"""
self.view.window().show_input_panel('Dictionary value (cancel to disable spell check)', defaultDict, self.setDictionary, None, self.disableSpellCheck)
def setDictionary(self, dictionary):
"""Enables spell check and sets the dictionary (it is associated with the view)"""
self.view.settings().set('spell_check', True)
self.view.settings().set('dictionary', dictionary)
def disableSpellCheck(self):
self.view.settings().erase('spell_check')
self.view.settings().erase('dictionary')
Save it as example.py inside Packages>User. Then add a key-binding and trigger it when you're focused in the desired view:
{ "keys": ["ctrl+alt+e"], "command": "example" }
Note that this is view-specific, so if you close sublime and then re-open it the setting is restored, but if you close the file tab the setting is lost, so if you open the file in the future you'll have to set the setting again. To add a real file-specific setting you need a more complex plugin that extends EventListener and reads the files names in order to set the syntax.
Syntax-specific way
In addition to default settings and user settings you can use syntax speific settings.
Lets say you want to set the dictonary for javascript files, to add the required syntax specific settings open a javascript source file, then go to menu Preferences>Settings-more>Syntax-specific-user, and in the file opened set the settings:
{
"spell_check": true,
"dictionary": "Packages/Language - English/en_GB.dic"
}
Finally save it and now your javascript files are using the specified dictonary. Repeat the proccess for other file types.
Note that this is not file-specific but syntax-specific, so if you really need different dictionaries for different javascript files (for example) you'll need to use the other way.

Resources