1# pet : CLI Snippet Manager
2
3[![GitHub release](https://img.shields.io/github/release/knqyf263/pet.svg)](https://github.com/knqyf263/pet/releases/latest)
4[![MIT License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](https://github.com/knqyf263/pet/blob/master/LICENSE)
5
6<img src="doc/logo.png" width="150">
7
8Simple command-line snippet manager, written in Go
9
10<img src="doc/pet01.gif" width="700">
11
12You can use variables (`<param>` or `<param=default_value>` ) in snippets.
13
14<img src="doc/pet08.gif" width="700">
15
16
17# Abstract
18
19`pet` is written in Go, and therefore you can just grab the binary releases and drop it in your $PATH.
20
21`pet` is a simple command-line snippet manager (inspired by [memo](https://github.com/mattn/memo)).
22I always forget commands that I rarely use. Moreover, it is difficult to search them from shell history. There are many similar commands, but they are all different.
23
24e.g.
25- `$ awk -F, 'NR <=2 {print $0}; NR >= 5 && NR <= 10 {print $0}' company.csv` (What I am looking for)
26- `$ awk -F, '$0 !~ "DNS|Protocol" {print $0}' packet.csv`
27- `$ awk -F, '{print $0} {if((NR-1) % 5 == 0) {print "----------"}}' test.csv`
28
29In the above case, I search by `awk` from shell history, but many commands hit.
30
31Even if I register an alias, I forget the name of alias (because I rarely use that command).
32
33So I made it possible to register snippets with description and search them easily.
34
35# TOC
36
37- [Main features](#main-features)
38- [Examples](#examples)
39    - [Register the previous command easily](#register-the-previous-command-easily)
40        - [bash](#bash-prev-function)
41        - [zsh](#zsh-prev-function)
42        - [fish](#fish)
43    - [Select snippets at the current line (like C-r)](#select-snippets-at-the-current-line-like-c-r)
44        - [bash](#bash)
45        - [zsh](#zsh)
46        - [fish](#fish-1)
47    - [Copy snippets to clipboard](#copy-snippets-to-clipboard)
48- [Features](#features)
49    - [Edit snippets](#edit-snippets)
50    - [Sync snippets](#sync-snippets)
51- [Hands-on Tutorial](#hands-on-tutorial)
52- [Usage](#usage)
53- [Snippet](#snippet)
54- [Configuration](#configuration)
55    - [Selector option](#selector-option)
56    - [Tag](#tag)
57    - [Sync](#sync)
58    - [Auto Sync](#auto-sync)
59- [Installation](#installation)
60    - [Binary](#binary)
61    - [Mac OS X / Homebrew](#mac-os-x--homebrew)
62    - [RedHat, CentOS](#redhat-centos)
63    - [Debian, Ubuntu](#debian-ubuntu)
64    - [Archlinux](#archlinux)
65    - [Build](#build)
66- [Migration](#migration)
67- [Contribute](#contribute)
68
69# Main features
70`pet` has the following features.
71
72- Register your command snippets easily.
73- Use variables in snippets.
74- Search snippets interactively.
75- Run snippets directly.
76- Edit snippets easily (config is just a TOML file).
77- Sync snippets via Gist or GitLab Snippets automatically.
78
79# Examples
80Some examples are shown below.
81
82## Register the previous command easily
83By adding the following config to `.bashrc` or `.zshrc`, you can easily register the previous command.
84
85### bash prev function
86
87```
88function prev() {
89  PREV=$(echo `history | tail -n2 | head -n1` | sed 's/[0-9]* //')
90  sh -c "pet new `printf %q "$PREV"`"
91}
92```
93
94### zsh prev function
95
96```
97$ cat .zshrc
98function prev() {
99  PREV=$(fc -lrn | head -n 1)
100  sh -c "pet new `printf %q "$PREV"`"
101}
102```
103
104### fish
105See below for details.
106https://github.com/otms61/fish-pet
107
108<img src="doc/pet02.gif" width="700">
109
110## Select snippets at the current line (like C-r)
111
112### bash
113By adding the following config to `.bashrc`, you can search snippets and output on the shell.
114
115```
116$ cat .bashrc
117function pet-select() {
118  BUFFER=$(pet search --query "$READLINE_LINE")
119  READLINE_LINE=$BUFFER
120  READLINE_POINT=${#BUFFER}
121}
122bind -x '"\C-x\C-r": pet-select'
123```
124
125### zsh
126
127```
128$ cat .zshrc
129function pet-select() {
130  BUFFER=$(pet search --query "$LBUFFER")
131  CURSOR=$#BUFFER
132  zle redisplay
133}
134zle -N pet-select
135stty -ixon
136bindkey '^s' pet-select
137```
138
139### fish
140See below for details.
141https://github.com/otms61/fish-pet
142
143<img src="doc/pet03.gif" width="700">
144
145
146## Copy snippets to clipboard
147By using `pbcopy` on OS X, you can copy snippets to clipboard.
148
149<img src="doc/pet06.gif" width="700">
150
151# Features
152
153## Edit snippets
154The snippets are managed in the TOML file, so it's easy to edit.
155
156<img src="doc/pet04.gif" width="700">
157
158
159## Sync snippets
160You can share snippets via Gist.
161
162<img src="doc/pet05.gif" width="700">
163
164# Hands-on Tutorial
165
166To experience `pet` in action, try it out in this free O'Reilly Katacoda scenario, [Pet, a CLI Snippet Manager](https://katacoda.com/javajon/courses/kubernetes-tools/snippets-pet). As an example, you'll see how `pet` may enhance your productivity with the Kubernetes `kubectl` tool. Explore how you can use `pet` to curated a library of helpful snippets from the 800+ command variations with `kubectl`.
167
168# Usage
169
170```
171pet - Simple command-line snippet manager.
172
173Usage:
174  pet [command]
175
176Available Commands:
177  configure   Edit config file
178  edit        Edit snippet file
179  exec        Run the selected commands
180  help        Help about any command
181  list        Show all snippets
182  new         Create a new snippet
183  search      Search snippets
184  sync        Sync snippets
185  version     Print the version number
186
187Flags:
188      --config string   config file (default is $HOME/.config/pet/config.toml)
189      --debug           debug mode
190
191Use "pet [command] --help" for more information about a command.
192```
193
194# Snippet
195Run `pet edit`
196You can also register the output of command (but cannot search).
197
198```
199[[snippets]]
200  command = "echo | openssl s_client -connect example.com:443 2>/dev/null |openssl x509 -dates -noout"
201  description = "Show expiration date of SSL certificate"
202  output = """
203notBefore=Nov  3 00:00:00 2015 GMT
204notAfter=Nov 28 12:00:00 2018 GMT"""
205```
206
207Run `pet list`
208
209```
210    Command: echo | openssl s_client -connect example.com:443 2>/dev/null |openssl x509 -dates -noout
211Description: Show expiration date of SSL certificate
212     Output: notBefore=Nov  3 00:00:00 2015 GMT
213             notAfter=Nov 28 12:00:00 2018 GMT
214------------------------------
215```
216
217
218# Configuration
219
220Run `pet configure`
221
222```
223[General]
224  snippetfile = "path/to/snippet" # specify snippet directory
225  editor = "vim"                  # your favorite text editor
226  column = 40                     # column size for list command
227  selectcmd = "fzf"               # selector command for edit command (fzf or peco)
228  backend = "gist"                # specify backend service to sync snippets (gist or gitlab, default: gist)
229  sortby  = "description"         # specify how snippets get sorted (recency (default), -recency, description, -description, command, -command, output, -output)
230
231[Gist]
232  file_name = "pet-snippet.toml"  # specify gist file name
233  access_token = ""               # your access token
234  gist_id = ""                    # Gist ID
235  public = false                  # public or priate
236  auto_sync = false               # sync automatically when editing snippets
237
238[GitLab]
239  file_name = "pet-snippet.toml"  # specify GitLab Snippets file name
240  access_token = "XXXXXXXXXXXXX"  # your access token
241  id = ""                         # GitLab Snippets ID
242  visibility = "private"          # public or internal or private
243  auto_sync = false               # sync automatically when editing snippets
244
245```
246
247## Selector option
248Example1: Change layout (bottom up)
249
250```
251$ pet configure
252[General]
253...
254  selectcmd = "fzf"
255...
256```
257
258Example2: Enable colorized output
259```
260$ pet configure
261[General]
262...
263  selectcmd = "fzf --ansi"
264...
265$ pet search --color
266```
267
268## Tag
269You can use tags (delimiter: space).
270```
271$ pet new -t
272Command> ping 8.8.8.8
273Description> ping
274Tag> network google
275```
276
277Or edit manually.
278```
279$ pet edit
280[[snippets]]
281  description = "ping"
282  command = "ping 8.8.8.8"
283  tag = ["network", "google"]
284  output = ""
285```
286
287They are displayed with snippets.
288```
289$ pet search
290[ping]: ping 8.8.8.8 #network #google
291```
292
293You can exec snipet with filtering the tag
294
295```
296$ pet exec -t google
297
298[ping]: ping 8.8.8.8 #network #google
299```
300
301## Sync
302### Gist
303You must obtain access token.
304Go https://github.com/settings/tokens/new and create access token (only need "gist" scope).
305Set that to `access_token` in `[Gist]` or use an environment variable with the name `$PET_GITHUB_ACCESS_TOKEN`.
306
307After setting, you can upload snippets to Gist.
308If `gist_id` is not set, new gist will be created.
309```
310$ pet sync
311Gist ID: 1cedddf4e06d1170bf0c5612fb31a758
312Upload success
313```
314
315Set `Gist ID` to `gist_id` in `[Gist]`.
316`pet sync` compares the local file and gist with the update date and automatically download or upload.
317
318If the local file is older than gist, `pet sync` download snippets.
319```
320$ pet sync
321Download success
322```
323
324If gist is older than the local file, `pet sync` upload snippets.
325```
326$ pet sync
327Upload success
328```
329
330*Note: `-u` option is deprecated*
331
332### GitLab Snippets
333You must obtain access token.
334Go https://gitlab.com/profile/personal_access_tokens and create access token.
335Set that to `access_token` in `[GitLab]` or use an environment variable with the name `$PET_GITLAB_ACCESS_TOKEN`..
336
337After setting, you can upload snippets to GitLab Snippets.
338If `id` is not set, new snippet will be created.
339```
340$ pet sync
341GitLab Snippet ID: 12345678
342Upload success
343```
344
345Set `GitLab Snippet ID` to `id` in `[GitLab]`.
346`pet sync` compares the local file and gitlab with the update date and automatically download or upload.
347
348If the local file is older than gitlab, `pet sync` download snippets.
349```
350$ pet sync
351Download success
352```
353
354If gitlab is older than the local file, `pet sync` upload snippets.
355```
356$ pet sync
357Upload success
358```
359
360## Auto Sync
361You can sync snippets automatically.
362Set `true` to `auto_sync` in `[Gist]` or `[GitLab]`.
363Then, your snippets sync automatically when `pet new` or `pet edit`.
364
365```
366$ pet edit
367Getting Gist...
368Updating Gist...
369Upload success
370```
371
372# Installation
373You need to install selector command ([fzf](https://github.com/junegunn/fzf) or [peco](https://github.com/peco/peco)).
374`homebrew` install `fzf` automatically.
375
376## Binary
377Go to [the releases page](https://github.com/knqyf263/pet/releases), find the version you want, and download the zip file. Unpack the zip file, and put the binary to somewhere you want (on UNIX-y systems, /usr/local/bin or the like). Make sure it has execution bits turned on.
378
379## Mac OS X / Homebrew
380You can use homebrew on OS X.
381```
382$ brew install knqyf263/pet/pet
383```
384
385If you receive an error (`Error: knqyf263/pet/pet 64 already installed`) during `brew upgrade`, try the following command
386
387```
388$ brew unlink pet && brew uninstall pet
389($ rm -rf /usr/local/Cellar/pet/64)
390$ brew install knqyf263/pet/pet
391```
392
393## RedHat, CentOS
394Download rpm package from [the releases page](https://github.com/knqyf263/pet/releases)
395```
396$ sudo rpm -ivh https://github.com/knqyf263/pet/releases/download/v0.3.0/pet_0.3.0_linux_amd64.rpm
397```
398
399## Debian, Ubuntu
400Download deb package from [the releases page](https://github.com/knqyf263/pet/releases)
401```
402$ wget https://github.com/knqyf263/pet/releases/download/v0.3.6/pet_0.3.6_linux_amd64.deb
403dpkg -i pet_0.3.6_linux_amd64.deb
404```
405
406## Archlinux
407Two packages are available in [AUR](https://wiki.archlinux.org/index.php/Arch_User_Repository).
408You can install the package [from source](https://aur.archlinux.org/packages/pet-git):
409```
410$ yaourt -S pet-git
411```
412Or [from the binary](https://aur.archlinux.org/packages/pet-bin):
413```
414$ yaourt -S pet-bin
415```
416
417## Build
418
419```
420$ mkdir -p $GOPATH/src/github.com/knqyf263
421$ cd $GOPATH/src/github.com/knqyf263
422$ git clone https://github.com/knqyf263/pet.git
423$ cd pet
424$ make install
425```
426
427# Migration
428## From Keep
429https://blog.saltedbrain.org/2018/12/converting-keep-to-pet-snippets.html
430
431# Contribute
432
4331. fork a repository: github.com/knqyf263/pet to github.com/you/repo
4342. get original code: `go get github.com/knqyf263/pet`
4353. work on original code
4364. add remote to your repo: git remote add myfork https://github.com/you/repo.git
4375. push your changes: git push myfork
4386. create a new Pull Request
439
440- see [GitHub and Go: forking, pull requests, and go-getting](http://blog.campoy.cat/2014/03/github-and-go-forking-pull-requests-and.html)
441
442----
443
444# License
445MIT
446
447# Author
448Teppei Fukuda
449