Acme Plumbing
Make your text clickable (Sublime Text 3)
Details
Installs
- Total 5K
- Win 3K
- Mac 821
- Linux 577
Nov 21 | Nov 20 | Nov 19 | Nov 18 | Nov 17 | Nov 16 | Nov 15 | Nov 14 | Nov 13 | Nov 12 | Nov 11 | Nov 10 | Nov 9 | Nov 8 | Nov 7 | Nov 6 | Nov 5 | Nov 4 | Nov 3 | Nov 2 | Nov 1 | Oct 31 | Oct 30 | Oct 29 | Oct 28 | Oct 27 | Oct 26 | Oct 25 | Oct 24 | Oct 23 | Oct 22 | Oct 21 | Oct 20 | Oct 19 | Oct 18 | Oct 17 | Oct 16 | Oct 15 | Oct 14 | Oct 13 | Oct 12 | Oct 11 | Oct 10 | Oct 9 | Oct 8 | Oct 7 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Windows | 1 | 0 | 0 | 0 | 0 | 2 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 |
Mac | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Linux | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 3 |
Readme
- Source
- raw.githubusercontent.com
AcmePlumbing
Make your text clickable
What
- Right click on https://www.google.com/search?q=Acme+Editor and a google search is opened in your browser.
- Right click on Commands.py@prepare_command and Commands.py is opened at the definition for prepare_command.
- Right click on pydoc(re) to see help on python regular expressions.
- Right click on shutdown and your computer turns off (causing you to wonder why you set up that last one).
Why
I played with Acme Editor and found the way it considered text to be part of the UI fun. However I wanted to play with it in an environment that I was more comfortable in (and runs nicely on Windows). Besides, I really wanted to be able to link files together as an adhoc wiki.
How
Select text with the right mouse button. The selected text is placed into a message as the data and is then passed to a set of commands (a rule). The commands are evaluated from the first to the last, and if one fails the rule stops processing and the next rule is tried.
If you only want to select a word, you can save effort by just right clicking in the middle of the word. This will cause AcmePlumbing to expand the selection along the word boundaries.
Configuration
see AcmePlumbing (Linux).sublime-settings
Each rule is a list of commands to run. You can pass extra arguments to a command by wrapping it in a list.
[
"is_file",
[ "pattern", "\.txt$"],
"open_in_tab"
]
When a message is passed to this rule, the first commands checks that the message data refers to a file. If it is a file the next command is run, otherwise the rule exits. The second command then checks the message data against a regular expression. This command takes the regular expression as an argument. In this case it tests if the file is a .txt file. If that passes, the message is handed to the open_in_tab command, which opens the file referred to in the message data into a new tab.
NOTE: commands in the pipeline are free to modify the message (if the rule fails, the message is set back to the original for the next rule)
Commands
pattern
see Commands.py@pattern
Runs the data against a regular expression specified in the second argument. The results are stored in the match_data allowing the action pipeline to use segments of the data.
is_file
see Commands.py@is_file
is_file tests if the message data references a file. If it fails, it tries again as a relative path using the current working directory set in the message. If a file is found, the message data is set to the full path.
is_dir
see Commands.py@is_dir
is_dir tests if the message data references a directory. Like is_file, if it fails it tries again as a relative path using the current working directory set in the message. If a directory is found, the message data is set to the full path.
list_dir
see Commands.py@list_dir
list_dir assumes the message data is the path to a directory and lists it. Each item in the directory is expanded to its full path, and are separated by new lines. The message data is replaced with the list of items.
extract_jump
see Commands.py@extract_jump
This test is different as it will always pass. It's purpose is to remove jump locations form the data and store them somewhere separate (match_data) so they don't interfere with subsequent tests. This is important as keeps stops is_file from having to be aware of how to jump to a location in a file, and it can focus on just testing if a file exists
see Commands.py@jump for the syntax used to jump
prepare_command
see Commands.py@prepare_command
preparecommand replaces text in the data based off the results of the match pipeline. At its most basic $\ is replaced with the contents of the message data (the text that you clicked on).
pattern
Results from the pattern test can be replaced by either referencing them by their group position (e.g. $1) or by the group name (e.g. $section)
open_in_tab
see Commands.py@open_in_tab
open_in_tab opens whatever is in message['data'] in a new tab. If a file exists with that path it will open that file. Otherwise it will assume that the data is a shell command. It will run the command and if there is output it will be placed in a new tab. An example of this is the rule to open man pages.
display_data_in_new_tab
see Commands.py@display_data_in_new_tab
display_data_in_new_tab creates a new tab and outputs the contents of the message data into it.
jump
see Commands.py@jump
jump uses the results from extract_jump and moves the cursor to a new location. It uses syntax similar to Go To Anything:
- @ jump to symbol
- # jump to text
- : jump to line
open_in_external_process
see Commands.py@open_in_external_process
open_in_external_process assumes that the message data is a command and runs it. No new tabs are opened. This is primarily used for rules like URLs where you want them to open in your browser, not your text editor.
extern
see Commands.py@extern
extern runs a command defined in an external module. The first argument is the module name, the second in the function, and the remainder are the arguments.
["extern", "ExternalPlugin.Module", "custom_command", "arg1", "arg2", "arg3"]
print_pipeline
see Commands.py@print_pipeline
print_pipeline outputs the message and pipeline data at that point in the pipeline into the console. It is useful when debugging a pipeline.
Extending
Message
The structure of the message looks like
{
"data": "the selected text",
"cwd": "the parent directory of the current file",
"src": "the view id",
"edit_token": "the edit token used for editing views"
}
Creating new commands
You can add custom commands by creating them in AcmePlumbingCommands.py in your user directory. Each action is a function with the signature:
def custom_command(message, arguments, pipeline_data):
return True
The command must return a true value if it succeeds. Otherwise the rule will be considered failed and the next rule will be run.
You can then reference them by the function name in your rule set:
[ "custom_command" ]
The return value is placed into pipeline_data, a dictionary that contains the results of all the previous commands in the rule.
Calling from another plugin
You can use SublimeAcmePlumbing.AcmePlumbing.add_rule (AcmePlumbing.py@add_rule) to inject a rule into the plumbing. This can be combined with the “extern” command to call a command defined in another module (e.g. another plugin). The rule is saved in the user settings to allow the user to tweak it and control its position in the plumbing. Additional rules have a key to allow the rule to be updated if it already exists, as such they should be unique.
see AcmePlumbing.py@add_rule
def add_rule(key, comment, rule)
The rule is saved in this format:
// key
// comment
[
"rule"
],
Example
OtherPlugin.Plumbing.py
import sublime
from AcmePlumbing import AcmePlumbing
def greet(message, args, match_data):
window = sublime.active_window()
tab = window.new_file()
tab.set_scratch(True)
edit_token = message['edit_token']
tab.insert(edit_token, 0, "Hello. How's the weather?")
return tab
def plugin_loaded():
AcmePlumbing.add_rule("OtherPlugin.greet",
"Ask about the weather",
["extern", "OtherPlugin.Plumbing", "greet"])
This plugin sets up the plumbing so that anything you right click on will open a new tab asking you about the weather
FAQ
Where is my context menu?
Since Acme Plumbing binds itself to the right mouse button, you can't access the right click menu normally. Don't panic: it is just a shift + right click away.
However, if you don't want Acme Plumbing on your right mouse button, you can move it to the middle mouse button by putting this into Default.sublime-mousemap in the Users package directory.
[
{
"button": "button2", "count": 1, "modifiers": [],
"press_command": "context_menu"
},
{
"button": "button3", "count": 1, "modifiers": [],
"command": "acme_plumbing_send",
"press_command": "drag_select"
},
]
License
MIT