Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/konodyuk/obsidian-text-expander

Text Expander plugin for Obsidian
https://github.com/konodyuk/obsidian-text-expander

Last synced: 8 days ago
JSON representation

Text Expander plugin for Obsidian

Awesome Lists containing this project

README

        

> ⚠️ UPDATE (NOV 2023): This plugin is not maintained. Do not install it, use supported alternatives.

> ⚠️ CM6-based editor (default option in Obsidian >= v13.0.0) is not supported. Consider using Legacy editor.

![demo](https://raw.githubusercontent.com/konodyuk/obsidian-text-expander/master/images/obsidian-text-expander-demo.gif)

# Text Expander Plugin
The plugin replaces shortcuts of format `{{}}` on Tab press. The replacement can be either static text or the result of execution of arbitrary commands.

> ⚠️ Currently, the plugin supports Windows only partially. See the Known Issues section.

## Use Cases
- Shortcuts for static text templates: `{{trigger}}` -> `Some template text`
- For dynamic values: `{{now}}` -> `14:23`, `{{date}}` -> `2021-01-15`
- For python expressions: `{{eval:2**10}}` -> `1024`, `{{eval:len(open("").readlines())}}`, `{{py:from numpy import*;print(linalg.inv(triu([1,2,3,4])))}}`, ...
- For shell commands: `{{shell:ls /attachments}}`
- For custom tools: `{{mytool:extract_all_lines_starting_with_(#tag)}}` -> `#tag Text\n#tag ...`

## Installation
Open `Settings > Third-party plugins > Community Plugins > Browse`, then search for `Text Expander` and click `Install`.

## Settings
The shortcuts are defined as a JSON-list of entries, each containing three fields: `regex` (required), `replacement` (optional) and `command` (optional).
- `regex` field defines the trigger pattern. The entries are tried sequentially, until `regex` matches the input.
- `replacement` simply replaces the shortcut, if provided.
- `command` contains the command which is run in shell. The shortcut is replaced with its output.

### Default Shortcuts
Below is the default configuration that can be changed in `Settings > Plugin Options > Text Expander > Shortcuts`:
```json
[
{
"regex": "^trigger$",
"replacement": "## Example replacement\n- [ ] ",
},
{
"regex": "^now$",
"command": "printf `date +%H:%M`",
},
{
"regex": "^py:",
"command": "echo | cut -c 4- | python3"
},
{
"regex": "^eval:",
"command": "echo | cut -c 6- | python3 -c 'print(eval(input()), end=\"\")'"
},
{
"regex": "^shell:",
"command": "echo | cut -c 7- | sh"
},
{
"regex": "^tool:",
"command": "echo | cut -c 6- | python3 /tool.py"
},
{
"regex": "^sympy:",
"command": "echo | cut -c 7- | python3 /sympy_tool.py"
}
]
```

### Variables
With `` you can insert the value of a variable into the `command` field before it is executed. The following variables can be used:
- `` The contents of brackets, with escaped single-quotes. Recommended in most cases.
- `` Same as ``, but nothing is escaped.
- `` The absolute path of current vault.
- `` The directory of the current note in obsidian file explorer. E.g. inside `/folder/folder2/note.md` its value will be `folder/folder2`.
- `` The filename of the current note, i.e. `note.md` in the example above.
- `` The shortcut for `/`.
- `` The shortcut for `/.obsidian/scripts`.

### Example flows
#### Example #1
- `{{trigger}}`Tab is entered
- `^trigger$` matches `trigger` -> the first shortcut is used
- `replacement` field of the first shortcut replaces `{{trigger}}`

#### Example #2
- `{{now}}`Tab
- `^trigger$` doesn't match `now` -> proceeding to the second shortcut
- `^now$` matches `now` -> the second shortcut is used
- `command` field is executed in the specified shell, then the output is used to replace `{{now}}`

#### Example #3
- `{{sympy:latex(integrate(x, x))}}`Tab
- Only the last shortcut's `regex` matches the input
- Variables are processed: `echo | cut -c 7- | python3 /sympy_tool.py` -> `echo 'sympy:latex(integrate(x, x))' | cut -c 7- | python3 /path/to/vault/.obsidian/scripts/sympy_tool.py`
- The command is executed: `cut` cuts the `sympy:` prefix and `latex(integrate(x, x))` is passed as input to `sympy_tool.py`
- `sympy_tool.py` outputs `\frac{x^{2}}{2}`, which replaces the `{{sympy:latex(integrate(x, x))}}`

### Custom Scripts
You can place any scripts to `/.obsidian/scripts` to use them in commands. The [examples](https://github.com/konodyuk/obsidian-text-expander/tree/master/examples/scripts) folder contains two sample scripts, enabling `{{tool:` and `{{sympy:` shortcuts.

## Security
As the plugin is shell-powered, one can easily run destructive commands just by typing `{{shell:rm -rf ...}}`Tab. Think twice before pressing Tab when your cursor is on something like `{{shell:...}}`. I also strongly discourage using the `{{shell:...}}` pattern, which was added mostly for demonstration purposes, and recommend writing python scripts instead.

## Future Work
- `` placeholder, defining the cursor position after replacement. Example usage: `{{texenv:cases}}` -> `\begin{cases}\n\t\n\end{cases}`. In case if multiple `` placeholders are used in single shortcut, then Tab will switch the cursor position between them until all are visited.
- Special syntax (something like `{*{}}`) for preview-time rendering instead of instant replacement.
- Static-only support for Windows.

## Known Issues
- Long-running commands can cause issues. E.g. if you type `{{shell:sleep 10 && echo 1}}`Tab and before it finishes type `{{now}}`Tab, then `{{now}}` will be replaced with `1`.
- Windows support is currently limited:
- Shortcuts with `replacement` field are processed correctly
- To use `command` field on Windows you need to have a [WSL Subsystem](https://docs.microsoft.com/en-us/windows/wsl/install-win10) installed and set `Settings > Plugin Options > Text Expander > Shell executable` to `.exe`(`ubuntu.exe` for Ubuntu), also make sure any python packages you use are installed
- or set `Settings > Plugin Options > Text Expander > Shell executable` to `powershell` and use Powershell syntax in your commands.

## Credits
The project was inspired by the [PoC text expander implementation](https://github.com/akaalias/text-expander-plugin). I also used certain ideas from the [Run Snippets plugin](https://github.com/cristianvasquez/obsidian-snippets-plugin).

## Release Notes
### 1.1.0
- Added support for `:now` syntax. Use `{{py: long command}}` syntax for triggers containing whitespace characters and `:trigger` for short triggers without whitespace
- Shell executable is now automatically respawned on "Shell executable" value change

### 1.0.1
- Fixed errors caused by incorrect "Shell executable" value