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