pmy is a highly customizable context-aware shell(zsh)-completion scheme utilizing fuzzy finder such as fzf. I'm fully in love with fzf, and I think zsh's completion system is so complicated (I admit it is very powerful), so I developed this system.
First, please get pmy by go get (because the backend system is written in Go)
go get -u github.com/relastle/pmy
Or you can download single binary releases from here
Then, only you have to do is executing folloing zsh command.
eval "$(pmy init)"
You can also add the line into your ~/.zshrc if you want.
Try downloading very simple pmy rule files into $HOME/.pmy
(where pmy searches for rules by default).
git clone https://github.com/relastle/pmy-config $HOME/.pmy
Then, you are already able to enjoy path completion using fuzzy finder (completion is invoked by Ctrl + Space).
This path-completion befavior is realized by simple yml configurations below
- regexp-left: ^(?P<body>.*?)(?P<path>~{0,1}([0-9A-Za-z_\-.]*/)+)(?P<query>[0-9A-Za-z_\-.]*)$
cmd-groups:
- stmt: \ls -AlFG --color=always <path> | tail -n +2 | grep --color=always "<query>"
after: awk '{print $8}'
fuzzy-finder-cmd: fzf -0 -1 --ansi -n8
buffer-left: <body><path>
buffer-right: '[]'
- regexp-left: ^(?P<body>.*?) (?P<query>[0-9A-Za-z_\-.]*)$
cmd-groups:
- stmt: \ls -AlFG --color=always | tail -n +2 | grep --color=always "<query>"
after: awk '{print $8}'
fuzzy-finder-cmd: fzf -0 -1 --ansi -n8
buffer-left: '<body> '
buffer-right: '[]'
Customization is very easy.
- Wrtie your own rule in JSON/YML format.
- Save it in the name of
pmy_rules.[json|yml]
- Locate the file under one of
$PMY_RULE_PATH
.
If you want to investigate into further examples, see Gallery.
Pmy can be invoked by Ctrl + Space. If the current left buffer (the part of the buffer that lies to the left of the cursor position) and the right buffer (the right part) match pre-defined rule (described below), fuzzy-finder launches against outputs of the corresponding command.
Basically, pmy's compleion behavior is solely based on rule
.
A single rule is described as follows
{
"regexpLeft": "git (cp|cherry-pick) *$",
"regexpRight": "",
"cmdGroups": [
{
"tag": "🍒:commit",
"stmt": "git log --oneline --branches --tags",
"after": "awk '{print $1}'"
}
],
"fuzzyFinderCmd": "fzf -0 -1",
"bufferLeft": "[]",
"bufferLeft": "[]",
"bufferRight": "[]"
}
property name (JSON / YML) | description |
---|---|
regexpLeft / regexp-left | If this regexp matches the current left buffer, this rule will be activated. |
regexpRight / regexp-right | Same as left one, but in many cases you don't have to set it becasue you usually work in line left to right. |
cmdGroups.tag / cmd-groups.tag | tag string which will be inserted ahead of each line of outputs of the corresponding command. |
cmdGroups.stmt / cmd-groups.stmt | command that will be executed to make sources for fuzzy-finder. |
cmdGroups.after / cmd-groups.after | command that will be executed against line after fuzzy-finder selection (using pipe). |
fuzzyFinderCmd / fuzzy-finder-cmd | Fuzzy finder command that will be executed (piped) against obtained command |
bufferLeft / buffer-left | Buffer left values after completion. [] denotes the original left buffer. |
bufferRight / buffer-right | Buffer right values after completion. [] denotes the original right buffer. |
pmy searchs for its rule setting in ${HOME}/pmy/rules
by default.
So you can use common settings by executing
git clone https://github.com/relastle/pmy-config ~/.pmy
If you want to customize pmy's rule.
You can define environment variable PMY_RULE_PATH
.
if you want to add /path/to/1
and /path/to/2
into pmy's rules paths,
execute
export PMY_RULE_PATH="/path/to/1:/path/to/2"
This setting is similar that of that of $PATH
variable (, which controlls paths where executable binaries and scripts are located).
In this situation, priorities as follows:
-
/path/to/1/hoge_pmy_rules.json
-
/path/to/2/hoge_pmy_rules.json
-
${HOME}/.pmy/rules/hoge_pmy_rules.json
In many cases, your own rule would be command specific ones (i.g. git-specific rule and cd-spefici-rule),
which means that setting such rules into a single one file will increase searching time and slow pmy unreasonably.
Therefore, you can define command specific rule by putting command-specific rules in the same directory as
${PMY_RULE_PATH}
with an appropriate file name as follows.
├── pmy_rules.json
├── git_pmy_rules.json
├── cd_pmy_rules.json
└── tmux_pmy_rules.json
In this case, if your current left buffer starts with git command and pmy is invoked,
it searched for matched rule first in git_pmy_rules.json
(git-specific rules), and then pmy_rules.json
(globally active rules).
variable name | description | default values |
---|---|---|
PMY_FUZZY_FINDER_DEFAULT_CMD | Default fuzzy finder command used when "fuzzyFinderCmd" is not set in a rule | "fzf -0 -1" |
PMY_TRIGGER_KEY | Trigger key that invokes pmy completion | '^ ' |
If you want to change these values, you should export them in .zshrc before you execute
eval "$(pmy init)"
If you set PMY_TRIGGER_KEY
to ^I
(tab key),
zsh's default completion action will be invoked when no rule was found.
This behavior is similar to kill
command completion of
fzf.
- JSON/YML rule-configurations.
- Customize fuzzy finder command used.
- Combining multiple command into one source.
- Caching compiled regular expression.
- Customizing priority of rules.
The MIT License (MIT)