Syntax specific settings in sublime-project settings file - sublimetext2

A sublime-settings file enforces settings on a per-project basis:
{
"folders": [ ... ]
"settings":
{
"tab_size": 4
}
}
How is it possible to use syntax specific settings in this file, for example to set a tab_size of 2 only for *.js files?

You could checkout .editorconfig.
Basically an .editorconfig file would look like,
# editorconfig.org
# top-most EditorConfig file
root = true
# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true
# Matches multiple files with brace expansion notation
# Set default charset
[*.{js,py}]
charset = utf-8
# 4 space indentation
[*.py]
indent_style = space
indent_size = 4
# Tab indentation (no size specified)
[Makefile]
indent_style = tab
# Indentation override for all JS under lib directory
[lib/**.js]
indent_style = space
indent_size = 2
# Matches the exact files either package.json or .travis.yml
[{package.json,.travis.yml}]
indent_style = space
indent_size = 2
There's even a nice Sublime Text package that automatically reads and understands them. Just throw your .editorconfig in version control and you're ready to go.

You can't set language-exclusive settings directly in your user Preferences.sublime-settings file. However, when editing a file of a given type, you can create a settings file limited only to that type with the menu item Preferences -> Settings–More -> Syntax Specific – User.
This new file will appear in your Packages/User directory with a name matching its language, e.g. Markdown.sublime-settings would be a Markdown-specific settings file.

Related

Sublime Text open all files containing search term

When I pres ctrl+shift+F to search across all the files in the current scope, I get a new window listing all the files that contain that search term.
How can I quickly open all of these files?
Hold down the F4 key from the Search Results screen, and it will "Navigate to next match" - which causes it to open each file listed in the results.
Just a small note, if you are getting 10+ matches per file this method starts to fail because it gets slow.
Sublime doesn't have the ability to do this out of the box; however the plugin API gives you the power to create a plugin to do something like this fairly simply (depending on how you ultimately want it to work).
I assume there are plugins available for something like this, but for reference purposes here is a simple example:
import sublime
import sublime_plugin
class OpenAllFoundFilesCommand(sublime_plugin.TextCommand):
def run(self, edit, new_window=False):
# Collect all found filenames
positions = self.view.find_by_selector ("entity.name.filename.find-in-files")
if len(positions) > 0:
# Set up the window to open the files in
if new_window:
sublime.run_command ("new_window")
window = sublime.active_window ()
else:
window = self.view.window ()
# Open each file in the new window
for position in positions:
window.run_command ('open_file', {'file': self.view.substr (position)})
else:
self.view.window ().status_message ("No find results")
This provides a command named open_all_found_files which could be bound to a key, added to a menu, added to the command palette, etc.
Using the notion that sublime has a custom syntax for the find results with a scope dedicated to the matching filenames, this collects all such regions and then opens the associated files.
The optional command argument new_window can be passed and set to true to open the files in a new window; leaving it off or setting it to false opens the files in the same window as the find results. You can of course change the default as you see fit.
You can't do that from within Sublime Text.
If you are using Linux/UNIX/OSX you can open all the files that contain a particular string or matching regex by using a combination of grep and xargs on the command line using a command like this:
grep -rlZ "search_str_or_regex" /path/to/search/* | xargs -0 subl
// Command line options (may vary between OSes):
//
// grep -r Recurse directories
// grep -l Output only the filenames of the files which contain the search pattern
// grep -Z Output null terminated filenames
// xargs -0 Input filenames are null terminated
// xargs subl Sublime Text executable
//
// The combination of -Z and -0 allows filenames containing spaces to be handled
The files will be opened in the most recently used Sublime Text window. Add -n or --new-window after subl to have them opened in a new window.
If you are using Windows, consider using GOW or Cygwin.
I had to change the Code of OdatNurd. I had problems with the ":" and the " " at the end of the Filename... Under Mac OS Big Sur...
import sublime
import sublime_plugin
class OpenAllFoundFilesCommand(sublime_plugin.TextCommand):
"""
Collect the names of all files from a Find in Files result and open them
all at once, optionally in a new window.
"""
def run(self, edit, new_window=False):
# Collect all found filenames
positions = self.view.find_by_selector("entity.name.filename.find-in-files")
if len(positions) > 0:
# Set up the window to open the files in
if new_window:
sublime.run_command("new_window")
window = sublime.active_window()
else:
window = self.view.window()
# Open each file in the new window
for position in positions:
file = self.view.substr (position)
#print(file)
file = file.replace(":","")
window.run_command('open_file', {'file': file.strip()})
else:
self.view.window().status_message("No find results")
def is_enabled(self):
return self.view.match_selector(0, "text.find-in-files")

Is it possible to show the size of files next to the file names inside Sublime sidebar?

I run an application that generates and updates a number of files in a specific folder. While the application runs, I observe the content of the folder through the sublime sidebar. Because I am interested to see the current size of each file while the application runs, I have an open terminal (Mac) where I use the following command to get the live state of the folder.
watch -d ls -al -h folderName
I was wondering if I can obtain this information directly from sublime.
So my question is: Is it possible to have the size of each file next to the file-names in the sublime sidebar? And if yes, how?
Since the sidebar is not in the official API, I don't think this is possible or at least it is not easy.
However getting the information into sublime text is easy. You can archive this by using a view. Just execute the ls command and write the result in the view.
I wrote a small (ST3) plugin for this purpose:
import subprocess
import sublime
import sublime_plugin
# change to whatever command you want to execute
commands = ["ls", "-a", "-s", "-1", "-h"]
# the update interval
TIMEOUT = 2000 # ms
def watch_folder(view, watch_command):
"""create a closure to watch a folder and update the view content"""
window = view.window()
def watch():
# stop if the view is not longer open
open_views = [v.id() for v in window.views()]
if view.id() not in open_views:
print("closed")
return
# execute the command and read the output
output = subprocess.check_output(watch_command).decode()
# replace the view content with the output
view.set_read_only(False)
view.run_command("select_all")
view.run_command("insert", {"characters": output})
view.set_read_only(True)
# call this function again after the interval
sublime.set_timeout(watch, TIMEOUT)
return watch
class WatchFolderCommand(sublime_plugin.WindowCommand):
def run(self):
folders = self.window.folders()
if not folders:
sublime.error_message("You don't have opened any folders")
return
folder = folders[0] # get the first folder
watch_command = commands + [folder]
# create a view and set the desired properties
view = self.window.new_file()
view.set_name("Watch files")
view.set_scratch(True)
view.set_read_only(True)
view.settings().set("auto_indent", False)
# create and call the watch closure
watch_folder(view, watch_command)()
Just open the User folder (or any other sub-folder of Packages), create a python file (e.g. watch_folder.py) and paste the source code.
You can bind it to a keybinding by pasting the following to your keymap:
{
"keys": ["ctrl+alt+shift+w"],
"command": "watch_folder",
},

Insert file (foo.txt) into open file (bar.txt) at caret position

What would be the best method, please, to insert file (foo.txt) into open file (bar.txt) at caret position?
It would be nice to have an open-file dialog to choose anything to be inserted.
The word processing equivalent would be "insert file" here.
Here is a substitute for foo.sublime-snippet, which can be linked to form files elsewhere:
import sublime, sublime_plugin
class InsertFileCommand(sublime_plugin.TextCommand):
def run(self, edit):
v = self.view
template = open('foo.txt').read()
print template
v.run_command("insert_snippet", {"contents": template})
From within a text command you can access the current view. You can get the cursor positions using self.view.sel(). I don't know how to do gui stuff in python, but you can do file selection using the quick panel (similar to FuzzyFileNav).
Here is my unofficial modification of https://github.com/mneuhaus/SublimeFileTemplates which permits me to insert-a-file-here using the quick panel. It works on an OSX operating system (running Mountain Lion).
The only disadvantage I see so far is the inability to translate a double-slash \\ in the form file correctly -- it gets inserted instead as just a single-slash \. In my LaTex form files, the double-slash \\ represents a line ending, or a new line if preceded by a ~. The workaround is to insert an extra slash at each occurrence in the actual form file (i.e., put three slashes, with the understanding that only two slashes will be inserted when running the plugin). The form files need to be LF endings and I'm using UTF-8 encoding -- CR endings are not translated properly. With a slight modification, it is also possible to have multiple form file directories and/or file types.
import sublime, sublime_plugin
import os
class InsertFileCommand(sublime_plugin.WindowCommand):
def run(self):
self.find_templates()
self.window.show_quick_panel(self.templates, self.template_selected)
def find_templates(self):
self.templates = []
self.template_paths = []
for root, dirnames, filenames in os.walk('/path_to_forms_directory'):
for filename in filenames:
if filename.endswith(".tex"): # extension of form files
self.template_paths.append(os.path.join(root, filename))
self.templates.append(os.path.basename(root) + ": " + os.path.splitext(filename)[0])
def template_selected(self, selected_index):
if selected_index != -1:
self.template_path = self.template_paths[selected_index]
print "\n" * 25
print "----------------------------------------------------------------------------------------\n"
print ("Inserting File: " + self.template_path + "\n")
print "----------------------------------------------------------------------------------------\n"
template = open(self.template_path).read()
print template
view = self.window.run_command("insert_snippet", {'contents': template})
sublime.status_message("Inserted File: %s" % self.template_path)

Fixing Sublime Text 2 line endings?

Here is my Settings - User config:
{
"auto_indent": true,
"color_scheme": "Packages/Color Scheme - Default/Twilight.tmTheme",
"default_line_ending": "LF",
"detect_indentation": true,
"font_size": 10.0,
"ignored_packages":
[
"Vintage"
],
"indent_to_bracket": false,
"smart_indent": true,
"tab_size": 4,
"translate_tabs_to_spaces": true,
"trim_automatic_white_space": true,
"use_tab_stops": true
}
Comment to default_line_ending option says:
When I create a new file, I check line ending here:
As you can see it's still Windows...
Any ideas?
The comment states
// Determines what character(s) are used to terminate each line in new files.
// Valid values are 'system' (whatever the OS uses), 'windows' (CRLF) and
// 'unix' (LF only).
You are setting
"default_line_ending": "LF",
You should set
"default_line_ending": "unix",
The EditorConfig project (Github link) is another very viable solution. Similar to sftp-config.json and .sublime-project/workspace sort of file, once you set up a .editorconfig file, either in project folder or in a parent folder, every time you save a file within that directory structure the plugin will automatically apply the settings in the dot file and automate a few different things for you. Some of which are saving Unix-style line endings, adding end-of-file newline, removing whitespace, and adjusting your indent tab/space settings.
QUICK EXAMPLE
Install the EditorConfig plugin in Sublime using Package Control; then place a file named .editorconfig in a parent directory (even your home or the root if you like), with the following content:
[*]
end_of_line = lf
That's it. This setting will automatically apply Unix-style line endings whenever you save a file within that directory structure. You can do more cool stuff, ex. trim unwanted trailing white-spaces or add a trailing newline at the end of each file. For more detail, refer to the example file at https://github.com/sindresorhus/editorconfig-sublime, that is:
# editorconfig.org
root = true
[*]
indent_style = tab
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
The root = true line means that EditorConfig won't look for other .editorconfig files in the upper levels of the directory structure.
to chnage line endings from LF to CRLF:
open Sublime and follow the steps:-
1 press Ctrl+shift+p then install package name line unify endings
then again press Ctrl+shift+p
2 in the blank input box type "Line unify ending "
3 Hit enter twice
Sublime may freeze for sometimes and as a result will change the line endings from LF to CRLF
The simplest way to modify all files of a project at once (batch) is through Line Endings Unify package:
Ctrl+Shift+P type inst + choose Install Package.
Type line end + choose Line Endings Unify.
Once installed, Ctrl+Shift+P + type end + choose Line Endings Unify.
OR (instead of 3.) copy:
{
"keys": ["ctrl+alt+l"],
"command": "line_endings_unify"
},
to the User array (right pane, after the opening [) in Preferences -> KeyBindings + press Ctrl+Alt+L.
As mentioned in another answer:
The Carriage Return (CR) character (0x0D, \r) [...] Early Macintosh operating systems (OS-9 and earlier).
The Line Feed (LF) character (0x0A, \n) [...] UNIX based systems (Linux, Mac OSX)
The End of Line (EOL) sequence (0x0D 0x0A, \r\n) [...] (non-Unix: Windows, Symbian OS).
If you have node_modules, build or other auto-generated folders, delete them before running the package.
When you run the package:
you are asked at the bottom to choose which file extensions to search through a comma separated list (type the only ones you need to speed up the replacements, e.g. js,jsx).
then you are asked which Input line ending to use, e.g. if you need LF type \n.
press ENTER and wait until you see an alert window with LineEndingsUnify Complete.

mercurial keywords not expanding in js and css files

I am on Windows 7 using TortoiseHg 2.1.3 and I have configure it to use the keyword extension (please, no "it is bad practice" remarks, I have studied the arguments and I think in my case it is a valid use).
My mercurial.ini file looks like this:
[ui]
username = xxx
merge =beyondcompare3
ignore = ~/.hgignore
[tortoisehg]
vdiff =beyondcompare3
engmsg = True
ui.language = en
[extensions]
mercurial_keyring =
keyword =
convert =
[keyword]
*.css =
*.js =
*.php =
*.html =
*.htaccess =
[keywordmaps]
Id = {file|basename} {rev}.{node|short} {date|utcdate} {author|user}
Revision = {desc}
Now in any php, html and htaccess file my $Id$ gets expanded as expected when I commit the file, but in any js and css file they do not?
I am at a loss as to understand why, in all files, the document header is the same (I use a template for that which has the $Id$ in it).
Side note:
File-mask pattern for keyword section (and for other parts, where they used) must be **. (not Win-pattern with one star, but two). Sometimes for some filenames it can play
For the ID expansion I'll try probably to create clone of this keyword and test inside problem file-types (don't forget kwshrink|kwexpand magic words), catch differences after tests