SciTE Snippets
Contents
Templating utility for SciTE
(like Textmate's snippets).
- Introduction
- Quick Installation
- Full Installation
- Creating Snippets (Syntax)
- Scopes
- Generate Snippets (Ruby Script)
- Limitations
- Bugs, suggestions, etc.
Screencasts:
- Snippet examples (~1.6MB)
- Snippets with scopes (~2.8MB)
- Snippet examples (old) (~500KB)
Important
Please see snippets_doc.txt
for complete, up-to-date documentation.
Introduction
Basically, snippets are pieces of text inserted into a document, but can
execute shell code at run-time, contain placeholders for additional
information to be added, and make simple transforms on that information.
This is much more powerful than SciTE's abbreviation expansion system.
There is no other editor that comes close to matching Textmate (sadly, MacOSX
only) but SciTE. Of course, SciTE in its default state doesn't, but with Lua,
it can. This snippet system is designed to come close to mimicking Textmate,
although it will never be a perfect clone.
Quick Installation
- Make sure you are using the newest SciTE. Older versions use Lua 5.0, but 5.1 is required.
- Download snippets.lua
-
Be sure to set the
PLATFORM,RUBY_CMD,FILE_IN, andFILE_OUTvariables as appropriate. Regexps use Ruby, so Ruby must be installed. That, or you can modify the code to use another language's regexps. (Get Ruby at http://ruby-lang.org)
-
If you have a Lua startup script defined, add
require 'path/to/snippets.lua'to it. - Otherwise, add
ext.lua.startup.script=path/to/snippets.luato your SciTE global/user properties file.
-
If you have a Lua startup script defined, add
-
Add the following to your SciTE user/global properties file:
# Snippets... command.name.10.*=Insert command.10.*=dostring modules.scite.snippets.insert() command.mode.10.*=subsystem:lua,savebefore:no command.shortcut.10.*=Ctrl+I command.name.11.*=Cancel command.11.*=dostring modules.scite.snippets.cancel_current() command.mode.11.*=subsystem:lua,savebefore:no command.shortcut.11.*=Ctrl+Shift+I command.name.12.*=List command.12.*=dostring modules.scite.snippets.list() command.mode.12.*=subsystem:lua,savebefore:no command.shortcut.12.*=Ctrl+Alt+I
(Note you can change the shortcut keys, but do NOT change them to Tab, Shift+Tab, etc. because that will mess up how tab keys are normally handled by SciTE.) - Restart SciTE
-
Snippets are loaded, try one out by typing
pathand executing the key shortcut for modules.scite.snippets.insert (Ctrl+I by default). It should insert the current working directory.
Full Installation
TODO. (Basically download the SVN repository with custom SciTE
binary which uses my Lua key commands module instead of
SciTE's properties file implementation. And don't forget change the variables mentioned
above in the Quick Installation.)
Creating Snippets
Snippets are defined in a user-defined table
snippets. Scopes (discussed
below) are numeric indices of the snippets table and are tables themselves.
Each string index in each scope table is the snippet trigger text. The
expanded text is equated to this trigger.
For example:
snippets = {
file = "$(FileNameExt)",
[SCLEX_RUBY] = {
['def'] = "def ${1:initialize}(${2:})\n ${0}\nend"
[SCE_RB_STRING] = {
['c'] = "#{${0}}"
}
}
}
The top-level snippets are global, the SCLEX_RUBY snippets are global to a
buffer with Ruby syntax highlighting enabled, and the SCLEX_RUBY
SCE_RB_STRING snippet is expanded in that buffer only when currently in
Ruby's string scope.
Syntax:
-
Placeholders/tab stops:
${num:text}(e.g.${1:text})
These are visited in numeric order with${0}being the final cursor position. If the final cursor position is not specified, the cursor is placed at the end of the snippet. -
Mirrors:
${num}(e.g.${1})
${1}would be mirrored by whatever value${1:text}is in the above example. Note that mirrors are not updated as text is typed, only after the next item is moved to. -
Transformations:
${num/pattern/replacement/options}
(e.g.${1/text/other $0/}) Transformations are like mirrors, only they transform the text to mirror. In this case,textwould be replaced withother textif the value of${1:text}in the example above matched the pattern. The regular expressions are Ruby's regexps. Captures groups are referenced with the prefix$and$0is the entire match. Ruby code can be executed inside the replacement text using#{}. (e.g.${1/text/#{$0.capitalize}/}) -
SciTE variables:
$(variable)(e.g.$(FileNameExt))
SelectedText is a special variable having the value of the currently selected text. - Interpolated shell code:
`shell_code`(e.g.`date`) -
The
$,/,}, and`characters can be escaped with the\character. Keep in mind that this follows Lua syntax, so in literal strings (" "or' '),\\is equivalent to one\character, but in strings like[[ ]], a single\is used.
Scopes
In the previous example,
SCLEX_RUBY is a constant defining the Ruby lexer
and has the value in Scintilla.iface (22). SCE_RB_STRING is the string
scope in SCLEX_RUBY whose definition is also in Scintilla.iface (6).
Scope-insensitive snippets should be placed in the lexer table, and
lexer-insensitive key commands should be placed in the keys table.
By default scopes are enabled. To disable them, set the
SCOPES_ENABLED
variable to false.
Order of expansion precidence: Scope, Lexer, Global.
Snippets in the current scope have the first priority, snippets in the
current lexer have the second, and global snippets have the last
priority.
Generate Snippets
This Ruby script is a
utility generates snippets for snippets.lua. It currently supports the Ruby, Python, C/C++,
Java, HTML, XML, PHP, Properties, Lua, CSS, YAML, Bash, and Perl lexers, because they happen
to be the only ones I use, but more can be added quite easily.
Limitations
- Shell code inside regexps is executed the moment a snippet is inserted, not as placeholders are filled
- Calling undo or performing other text operations outside the snippet WILL probably cause unexpected behavior.
- I don't recommend using the TAB key as the trigger word expander. I've tried with mixed success to keep the key's original functionality along with snippet expansion. I happen to use Ctrl+I instead.
-
Apparently you cannot call Snippets.* from a command
defined in a SciTE properties file without prepending
dostringfirst. So something likecommand.0.*=dostring modules.scite.snippets.insert()will function as expected.
Additionals
-
Reporting bugs
If you come across a bug, please turn the DEBUG variable on and send me both the snippet text and output text. -
Questions? Comments? Suggestions? Additions?
Contact me: mitchell {att} caladbolg {dott} net