Just to clear up any possible confusion, the technique mentioned in the linked post only works when you are manually invoking the insert_snippet
command yourself to insert a snippet into the buffer. That is to say, you can't use it to add your own variables to snippets that are invoked automatically by Sublime via tab triggers because in that case it's Sublime that's invoking the insert_snippet
command on your behalf.
The insert_snippet
command accepts the following arguments (see here):
-
name
lets you specify the name of the snippet file to get the contents from
-
contents
lets you specify the contents of the snippet on the fly instead of using a snippet file
If you pass it any other arguments, the name of those arguments become the name of extra variables that can be expanded in the snippet, and the values of the arguments become the value of the variables. This is why you can't use this for "standard" snippet expansions; Sublime can't know what arguments to pass or what their values should be unless you tell it explicitly.
The command insert_date_one
executes the insert_snippet
command to insert the snippet you provided in your post above. It passes the extra argument DATE
with a value that is the current date and time, so when the snippet expands ${DATE}
gets expanded.
import sublime, sublime_plugin, time
class InsertDateOne(sublime_plugin.TextCommand):
def run(self, edit):
date = time.strftime("<%d-%m-%Y %H:%M>")
self.view.run_command("insert_snippet", {
"name": "Packages/User/testdatumu.sublime-snippet",
"DATE": date
})
The command insert_date_two
is functionally identical, only here instead of specifying the name of a snippet that exists on disk it specifies the content of the snippet inline instead, so no snippet file needs to exist for this one to work. It still works the same way, by providing an extra DATE
argument that becomes a DATE
variable.
import sublime, sublime_plugin, time
class InsertDateTwo(sublime_plugin.TextCommand):
def run(self, edit):
date = time.strftime("<%d-%m-%Y %H:%M>")
self.view.run_command("insert_snippet", {
"contents": "Date - {$DATE}",
"DATE": date
})
For the sake of completeness, insert_date_three
does the same thing except it uses insert
instead of insert_snippet
. The main reason for using a snippet is that you can specify fields (providing optional default values) for the user to tab through. Your example doesn't do that and just wants to insert text, so insert_snippet
isn't technically needed.
import sublime, sublime_plugin, time
class InsertDateThree(sublime_plugin.TextCommand):
def run(self, edit):
date = time.strftime("<%d-%m-%Y %H:%M>")
self.view.run_command("insert", {
"characters": "Date - %s" % date
})
In all three cases, the plugin creates a command that inserts the date, but you still need to be able to run the command to make the insertion happen. There are a variety of ways that you can go, depending on what you're trying to do and/or how often you need to do this. Some examples are:
Create a key binding to invoke the command:
{ "keys": ["ctrl+alt+d"], "command": "insert_date_one" },
Add it to the command palette by creating a Default.sublime-commands
file in your User
package:
[
{ "caption": "Insert Current Date", "command": "insert_date_one"},
]
Add it to the main menu (here in the Edit
menu) by creating a Main.sublime-menu
file in your User
package:
[
{
"id": "edit",
"children":
[
{ "caption": "-" },
{ "caption": "Insert Current Date", "command": "insert_date_one"},
]
},
]
Add it to the context menu of all edit windows by creating a Context.sublime-menu
file in your User
package:
[
{ "caption": "-", "id": "end" },
{ "caption": "Insert Current Date", "command": "insert_date_one"},
]
As a final note, the original plugin code iterates over all of the selections replacing them (or inserting if there is no selection) inserting the date and time. The insert_snippet
and insert
commands do that internally as well, so all of the sample commands here will work the same way as your example code does.