Sublime Text: set language for each file - sublimetext3

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.

Related

Sublime keeps using 4-space tab for some files instead of 2-space tab even if I've done all the settings, why and how do I fix?

I'm editing files using Sublime 3.2.2 on my iMac.
I have already set tab-size to 2:
It works for some files but doesn't for some files - remaining 4-sized tabs. I can't even find a clue about which is right and which is not.
Are there any other places I need to check except the settings?
There are two things to consider here. First, this setting (shown here with the default value):
// Set to false to disable detection of tabs vs. spaces on load
"detect_indentation": true,
When this setting is turned on, when a file opens it's examined to try and detect how it;s indented. This will override the tab_size in that particular file with whatever the detected tab size is, and can also override translate_taba_to_spaces as well if the file appears to be indented a particular way.
The setting defaults this way so that you can use your settings to determine how you want to create new files while still allowing you to work with existing files in a sane way; setting it to false turns off this detection.
The second thing to note is that preferences can be set on a per-file-type manner, which also overrides the settings in your user preferences for files of that type.
As an example, YAML files have these settings applied (this is from YAML/YAML.sublime-settings):
{
// YAML mandates that tabs aren't used for indentation
"translate_tabs_to_spaces": true,
// In practice, editing YAML files with anything other than two space
// indentation is tedious, due to the "- " list prefix
"tab_size": 2,
}
So, in a YAML file, regardless of your settings, the tab size defaults to 2 and using spaces over tabs is enforced.
As such, the takeaway here is that if changing the detection setting above doesn't work, check to see if the setting only seems to be "not working" in a particular type of file, and if so you can use Preferences > Settings - Syntax Specific while you have a file of that type open to enforce your settings there.

Writing an autocomplete plugin in Sublime Text

Within my company we have an XML-based notation. Among other features, it is possible to define references from one XML document into another. I would like to enable autocompletion in Sublime so that whenever I am adding a reference, the possible files (i.e. XML files within the same project) and link points (i.e. symbols within that file) get offered as recommendations.
So far, I have found a lot of plugins that enable autocomplete for, say, HTML, PHP or LaTeX. However, I have the feeling the code base is too complex for a somewhat simple task. Is there, for instance, some vanilla function that generates completions based on an arbitrary array received as parameter? I would create the logic to determine what is a symbol and derive said array, but the whole process seems somewhat cumbersome to me.
(As a note: I can program in Python and have fiddled with other Sublime features, such as snippets, but these packages seem to be much more complex than it feels necessary.)
The base to create the completions entry is not to complicated. You now need to fill the array with the correct values (this could be done via a project setting or parsing other files).
import sublime
import sublime_plugin
# Your array, which contains the completions
arr = ["foo", "bar", "baz"]
class MyCompletionsListener(sublime_plugin.EventListener):
def on_query_completions(self, view, prefix, locations):
loc = locations[0]
# limit you completions scope
if not view.score_selector(loc, "text"):
return
completions = [(v + "\tYour Description", v) for v in arr]
return completions
OP's note: The answer works as advertised. However, the integration is so seamless that I thought for a while that something was missing. If the Python script above is on the right folder, all of the completions returned by the completions array will be suggested (depending on Sublime settings, it might be necessary to trigger the completions menu with Ctrl+Space). Also worth noting:
The completions may be None, in which case they just don't add any completion option, or an array of 2-tuples, where the first element is the description (which will be shown in the drop-down menu and trigger the completion) and the second is the value (i.e. the text that will be input if the completion is selected).
The score_selector method can be used to determine if the cursor position is within a given scope.

Sublime Text 3 specific file type settings only has JSON file settings. How to create new?

I'm trying to create a syntax specific settings for file types in ST3. As per the documentation I am supposed to find what I need in
Sublime Text>Preferences>Settings - More>Syntax Specific - User
However, when I click that I only get JSON.sublime-settings file. What if I want some other settings file?
The settings file that opens when you select Prefereces > Settings - Syntax Specific is sensitive to the type of file that you're currently editing. So, if you happen to be in a JSON file when you invoke the menu command, you get the file for settings specific to JSON.
In order to get at the setting specific to a different syntax, open a file of that type first, or create an empty buffer and set the syntax to the desired language via View > Syntax from the menu, the command palette, or the menu that pops up when you click the file type in the right side of the status bar (where it will say Plain Text).
The file that you actually want to save is SyntaxName.sublime-settings in your User package, e.g. Python.sublime-settings for Python, etc. However to forestall any problems with the filename (like incorrect case or spelling) it's generally better to do it as above instead, particularly since the name of the syntax can sometimes be non-obvious.

Sublime Text Keybinds Context Within Unsaved Changes

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')

In vim, do fuzzy search of definitions in virtualenv and create import statement

So I'm looking for a vim plugin that will do the following:
On execution open a list of all names defined in all modules in the currently used virtualenv, probably from a tags file already created with ctags.
Let the user limit the list by FuzzyFinder-style controls, with the addition that it should match the file path as well as the definition.
So if the search string User gave back a set of results
User django/contrib/auth/models.py
UserAdmin django/contrib/auth/admin.py
the search string User;models would limit that down to just the first line
When a desired definition is found that name is inserted into the current buffer and a corresponding import statement is added to the top of the file.
With the built-in taglist() function, you can access the tags database (so you don't need to parse the file yourself), and FuzzyFinder allows re-use of its nice drill-down logic via fuf#callbackitem#launch(); I use this myself for custom searches. You can probably combine the two parts with a bit of map(). Inserting the selected item and its import is also just a couple of :normal or append() calls. VoilĂ !

Resources