# FilterPipes
FilterPipes is a SublimeText (v2 and v3) plugin for filtering selected text
through pipes or filters, either written as Python functions or as external
processes.
This project lives at [github.com/tylerl/FilterPipes](https://github.com/tylerl/FilterPipes).
### Filter Through Process
This plugin provides a prompt for you to supply the shell command to execute.
![Shell execute animation](https://raw.githubusercontent.com/tylerl/FilterPipes/media/fp_sort.gif)
### Filter Through Python
Python code can also be used as the filter function. Several useful examples
are provided as listed below, but the real power comes in when you create your
own functions.
### Creating Custom Filters
FilterPipes makes it crazy-simple for you to create your own custom filter
plugins. There are some pre-defined classes for simple text replacement,
regular expressions, character-for-character translations, and external
processes. Creating your own custom filter is as simple as creating a
Python class with a single method called `filter` as demonstrated below:
![Plugin creation animation](https://raw.githubusercontent.com/tylerl/FilterPipes/media/fp_reverse.gif)
# Provided Commands
The following commands are included. All commands are accessible from
the command palette. No shortcut keys are assigned by default,
though you are free to add your own if you like.
* **My Custom Filters Plugin**: Create and access your own FilterPipes-derived
custom plugin. The first time you run this command it will create the plugin
for you and add some sample content. Every subsequent run will simply open
your existing plugin directory.
* **Send Text to Command**: Prompts you for a shell command to run, and
then executes that command using your selection(s) as `stdin`, and replacing
them with `stdout` if the program ends successfully.
* **Base64 Encode** and **Base64 Decode**: Encodes and decodes text using
[Base64](Base64 Decode) encoding rules.
* **URL Encode** and **URL Decode**: Similarly, encodes and decodes text
using [URL ("percent") encoding](http://en.wikipedia.org/wiki/Percent-encoding).
* **String Escape** and **String Unescape**: Encodes and decodes strings using
simple string-escaping rules (e.g. TAB character becomes `\t`, newline becomes
`\n`, and so forth.
* **Strip Trailing Space**: Does what it says on the tin: it strips any spaces
at the end of lines. While mildly useful, this is here primarily because I
wanted to include an example of a Regex-based filter.
### Example Filters
These filters are included in the "My Custom Filters Plugin" example. Run the
"My Custom Filters Plugin" command to install them.
Most of these filters don't use any custom Python class, but instead use the
customization options of the provided generic filters to do something more
interesting. The only code will be the entry in `Default.sublime-commands` file
for your created plugin.
#### Translation Commands
These provide simple character-for-character translations to apply. Think of
them like the unix `tr` command, if you're nerdy enough to ever have used it.
* **Swap Quotes**: Swaps single quotes for double quotes (and vice-versa).
(surprisingly useful, but not context-aware).
* **Convert to Straight Quotes**: Turns all the varieties of "smart quotes" into
normal "straight" quotes, like any good programmer would prefer.
#### Regex Filter
Your regex filter configuration provides a simple search regex and replacement
string. It's not unlike regex-based search-and-replace, except your setup gets
baked into a single simple command.
* **Collapse Spaces**: Turns runs of any sort of whitespace into a single
space character.
* **Hex to Decimal, Decimal to Hex, Octal to Decimal, Decimal to Octal**:
Convert integers between popular numeric bases. This is provided as an
example of a regex filter that uses a callback function for replacements
instead of a simple string constant. It's also an example of the use of
using the `post_init` callback to rewrite the runtime configuration
(in this case the search regex) programatically.
#### Process Filters
Entire plugins have been written for performing this one simple action. Actually,
this plugin started out as one of them. It's gotten much more useful since then,
though. This filter type lets you specify a command to run. Kind of like the
"Send Text to Command" filter, but without the input prompt, and (by default)
without the shell interpretation (you can optionally turn that on, though).
Note that the included examples require you to install the associated program.
You may have to fiddle with the path (and perhaps command-line options) as well,
depending on your local installation.
* **Beautify JS (js-beautify)**: Many javascript developers use a command called
"js-beautify" to clean up their code. This filter calls that command... assuming
it's installed in the PATH. Otherwise, it does nothing but serve as an example
of how to write this kind of filter.
* **Minify JS (uglifyjs)**: Just like the above, but exactly the opposite. This
command makes your javascript compact and illegible... assuming you have it
installed -- the same caveat applies as above.
#### Python Filters
These are the *really* cool ones. You write your own python code to transform
the selected text. Note that the naming of the command follows the same pattern
as per normal for SublimeText. You convert the Python class name from CamelCase
to underscore_case and remove `_command` from the end to ge the name that goes into
your `.sublime-commands` file. This is done internally by SublimeText, so don't get
mad at me about it.
* **Reverse Words**: This is the example coded in the animation above. It reverses
the order of words delimited by spaces. I have no idea why anyone would ever
want to do that, but the code is tiny and the effect is obvious, so it makes a
pretty compelling piece of example code.
* **to CamelCase**: Converts words from `underscore_case` to `CamelCase`.
* **to mixedCase**: Converts words from `underscore_case` to `mixedCase`, which is
exactly the same as CamelCase, but without the first letter capitalized. In fact,
both these filters use the same Python class. This filter demonstrates how to add
your own custom command options.
* **to underscore_case**: Converts from `CamelCase` back to `underscore_case`, included
mostly out of an obsessive-compulsive need for parity.
# Creating Your Own
To write your own plugin, start out by bringing up the command pallete (typically
ctrl+shift+P or
cmd+shift+P) and running "My Custom Filters Plugin".
Even if you don't end up using the plugin it creates, this will at least give
you a working scaffold with all the right configuration and examples such to get started.
All commands take the optional parameter `use_selections`, which when set to false, tells
the system to ignore your text selections and pass the whole file in. Typically this is
useful for tools that use the entire file for context, such as source code formatters.
## Using the built-in filter classes
Generic filter classes are provided that allow you to do a lot of cool things without
writing any Python code. For these, you don't need a custom plugin, you can just
put the appropriate command invocation in your own `.sublime-settings` or `.sublime-keymap`
file.
#### Using `filter_pipes_process`
This sends text to an external process. The general configuration looks like
this. Note that unless you've specified `shell` as `true`, you'll want your
command to be a list of parameters rather than a single string.
```json
{
"caption": "YOLO Text",
"command": "filter_pipes_process",
"args": {
"command": ["banner", "-w", "80"],
"shell": false
}
}
```
#### Using `filter_pipes_translate`
Does character-for-character translations using Python's `string.translate`
function. That remark earlier about the `tr` command? Yeah, time to get your *Nerd* on.
```json
{
"caption": "H4X0R",
"command": "filter_pipes_translate",
"args": {
"before": "AaEeiIoOlsSTt",
"after": "4433110015577"
}
}
```
#### Using `filter_pipes_regex`
Supply a regex and replacement. Pretty straightforward, but don't forget that
backslashes have to be escaped for JSON encoding.
```json
{
"caption": "Format Phone Numbers",
"command": "filter_pipes_regex",
"args": {
"regex": "(\\d{3})(\\d{3})(\\d{4})",
"replacement": "(\\1) \\2-\\3"
}
}
```
#### Writing your own custom Python Filters
Here's where the real magic happens. You can very easily write
custom code to transform your text in any way imaginable, and
it only takes a minute or two to get going.
Once you've got your custom filter plugin created, open
up the `myfilters.py` file and at the bottom of the file
create a class like this:
```python
class SuperAwesomeFilterCommand(filterpipes.FilterPipesCommandBase):
"""Does approximately nothing, but does it with style."""
def filter(self, data):
return data
```
The class name determines the command name using the SublimeText rules
metioned earlier. So `SuperAwesomeFilterCommand` becomes `super_awesome_filter`.
Whatever your `filter()` function returns is what your text will
be replaced with. So go get creative.
Note that if you want your plugin to take some configurable parameter
from the `.sublime-commands` file, it's pretty easy. First you create
a class variable and assign it your desired default value:
```python
class SurroundSelectionCommand(filterpipes.FilterPipesCommandBase):
"""Prepends and appends some string to the selected text."""
prepend = '{'
append = '}'
def filter(self, data):
return self.prepend + data + self.append
```
Then in your `.sublime-keymap` or `.sublime-commands` file, specify
some alternate value for those variables in the "args" section like so:
```json
{
"caption": "Double Power Bracket",
"command": "surround_selection",
"args": {
"prepend": ".:[[",
"append": "]]:."
}
}
```
# Copyright and License
***This is not an official Google product.***
Copyright 2015 Google Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.