{"id":13475314,"url":"https://github.com/knqyf263/pet","last_synced_at":"2025-05-13T18:09:31.085Z","repository":{"id":37484311,"uuid":"84618431","full_name":"knqyf263/pet","owner":"knqyf263","description":"Simple command-line snippet manager","archived":false,"fork":false,"pushed_at":"2025-05-07T11:12:10.000Z","size":4177,"stargazers_count":4808,"open_issues_count":21,"forks_count":239,"subscribers_count":46,"default_branch":"main","last_synced_at":"2025-05-09T22:34:53.888Z","etag":null,"topics":["command-line","go","golang","linux","snippets","standalone"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/knqyf263.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2017-03-11T02:42:24.000Z","updated_at":"2025-05-08T21:29:35.000Z","dependencies_parsed_at":"2023-09-26T00:46:21.952Z","dependency_job_id":"2ef67e9d-7c30-480b-97b4-e3eeedacaade","html_url":"https://github.com/knqyf263/pet","commit_stats":{"total_commits":195,"total_committers":64,"mean_commits":3.046875,"dds":0.7846153846153846,"last_synced_commit":"9bcebb77964e2f7a298d05daeac1552f20510d59"},"previous_names":[],"tags_count":32,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/knqyf263%2Fpet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/knqyf263%2Fpet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/knqyf263%2Fpet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/knqyf263%2Fpet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/knqyf263","download_url":"https://codeload.github.com/knqyf263/pet/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254000851,"owners_count":21997441,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["command-line","go","golang","linux","snippets","standalone"],"created_at":"2024-07-31T16:01:19.323Z","updated_at":"2025-05-13T18:09:31.071Z","avatar_url":"https://github.com/knqyf263.png","language":"Go","funding_links":[],"categories":["Go","Development","工具和库","Productivity","Weapons","linux","Tools","\u003ca name=\"cheatsheet\"\u003e\u003c/a\u003eCommands cheatsheet and snippets","tools","Command Line and Tooling"],"sub_categories":["Snippets Manager","Kubernetes","Tools","Command line","Observability"],"readme":"# Pet - CLI Snippet Manager\n\n[![GitHub release](https://img.shields.io/github/release/knqyf263/pet.svg)](https://github.com/knqyf263/pet/releases/latest)\n[![MIT License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](https://github.com/knqyf263/pet/blob/master/LICENSE)\n\n\u003cdiv align=\"center\"\u003e\n\u003cimg src=\"doc/logo.png\" width=\"350\"\u003e\n\u003c/div\u003e\n\n\n# Motivation\n\n`pet` is a simple command-line snippet manager (inspired by [memo](https://github.com/mattn/memo)).\n\nI have a hard time remembering complex command or ones that I rarely use. Moreover, it is difficult to find them in shell history.\n\nIt's time to let go of the expectation of remembering every command, and focus on productivity and finding the right commands as fast as possible. It's fun when you're 2 years in and work with 2 tools, but less so when you're a decade in and work across backend/frontend/infrastructure with tons of tools. You most probably relate to this if you're a developer.\n\n`pet` is a simple tool that allows you to save, tag, search, and execute command-line snippets easily! It's now nearly 8 years old and is used by many developers around the world.\n\n`pet` is written in Go, and therefore you can just grab the binary releases and drop it in your $PATH.\n\n\u003cimg src=\"doc/pet01.gif\" width=\"700\"\u003e\n\nYou can use variables (`\u003cparam\u003e` or `\u003cparam=default_value\u003e` ) in snippets.\n\n\u003cimg src=\"doc/pet08.gif\" width=\"700\"\u003e\n\n# TOC\n\n- [Main features](#main-features)\n- [Parameters](#parameters)\n- [Examples](#examples)\n  - [Register the previous command easily](#register-the-previous-command-easily)\n    - [bash](#bash-prev-function)\n    - [zsh](#zsh-prev-function)\n    - [fish](#fish)\n  - [Select snippets at the current line (like C-r) (RECOMMENDED)](#select-snippets-at-the-current-line-like-c-r-recommended)\n    - [bash](#bash)\n    - [zsh](#zsh)\n    - [fish](#fish-1)\n  - [Copy snippets to clipboard](#copy-snippets-to-clipboard)\n- [Features](#features)\n  - [Edit snippets](#edit-snippets)\n  - [Sync snippets](#sync-snippets)\n- [Hands-on Tutorial](#hands-on-tutorial)\n- [Usage](#usage)\n- [Snippet](#snippet)\n- [Configuration](#configuration)\n  - [Selector option](#selector-option)\n  - [Tag](#tag)\n  - [Sync](#sync)\n  - [Auto Sync](#auto-sync)\n- [Installation](#installation)\n  - [Binary](#binary)\n  - [macOS / Homebrew](#macos--homebrew)\n  - [RedHat, CentOS](#redhat-centos)\n  - [Debian, Ubuntu](#debian-ubuntu)\n  - [Archlinux](#archlinux)\n  - [Build](#build)\n- [Migration](#migration)\n- [Contribute](#contribute)\n\n# Main features\n`pet` has the following features.\n\n- Register your command snippets easily.\n- Use variables (with one or several default values) in snippets.\n- Search snippets interactively\n- Run snippets directly.\n- Edit snippets easily (config is just a TOML file).\n- Sync snippets via Gist or GitLab Snippets automatically.\n\n# Creating a snippet\n\nYou can create a snippet by running `pet new`.\n\n```\n$ pet new\nCommand\u003e echo Hello world!\nDescription\u003e print Hello world\n```\n\nTo see all available arguments, run `pet new --help`.\n\nMultiline commands can be entered by using the multiline argument `pet new --multiline`\n\nYou can use also use variables in snippets, these are called parameters. More information on that in the next section.\n\nYou can also *tag* snippets to search for them faster. More information on that in the tag section.\n\n\n# Parameters\nThere are `\u003cn_ways\u003e` ways of entering parameters.\n\nThey can contain default values: Hello `\u003csubject=world\u003e`\ndefined by the equal sign. \n\nThey can even contain `\u003ccontent=spaces \u0026 = signs\u003e` where the default value would be \\\u003ccontent=\u003cmark\u003espaces \u0026 = signs\u003c/mark\u003e\\\u003e.\n\nDefault values just can't \\\u003cend with spaces \\\u003e.\n\nThey can also contain multiple default values:\nHello `\u003csubject=|_John_||_Sam_||_Jane Doe = special #chars_|\u003e`\n\nThe values in this case would be :Hello \\\u003csubject=\\|\\_\u003cmark\u003eJohn\u003c/mark\u003e\\_\\|\\|\\_\u003cmark\u003eSam\u003c/mark\u003e\\_\\|\\|\\_\u003cmark\u003eJane Doe = special #chars\u003c/mark\u003e\\_\\|\\\u003e\n\n# Examples\nSome examples are shown below.\n\n## Register the previous command easily\nBy adding the following config to `.bashrc` or `.zshrc`, you can easily register the previous command.\n\n### bash prev function\n\n```\nfunction prev() {\n  PREV=$(echo `history | tail -n2 | head -n1` | sed 's/[0-9]* //')\n  sh -c \"pet new `printf %q \"$PREV\"`\"\n}\n```\n\n### zsh prev function\n\n```\ncat .zshrc\nfunction prev() {\n  PREV=$(fc -lrn | head -n 1)\n  sh -c \"pet new `printf %q \"$PREV\"`\"\n}\n```\n\n### fish\nSee below for details.  \nhttps://github.com/otms61/fish-pet\n\n\u003cimg src=\"doc/pet02.gif\" width=\"700\"\u003e\n\n## Select snippets at the current line (like C-r) (RECOMMENDED)\n\n### bash\nBy adding the following config to `.bashrc`, you can search snippets and output on the shell.\nThis will also allow you to execute the commands yourself, which will add them to your shell history! This is basically the only way we can manipulate shell history.\nThis also allows you to *chain* commands! [Example here](https://github.com/knqyf263/pet/discussions/266)\n\nYou can also customize the search and list commands with options, example `-t` or `--tags`, for example to only search the subset of snippets tagged with myjob `pet search -t myjob`.\n\n```\ncat .bashrc\nfunction pet-select() {\n  BUFFER=$(pet search --query \"$READLINE_LINE\")\n  READLINE_LINE=$BUFFER\n  READLINE_POINT=${#BUFFER}\n}\nbind -x '\"\\C-x\\C-r\": pet-select'\n```\n\n### zsh\n\n```\ncat .zshrc\nfunction pet-select() {\n  BUFFER=$(pet search --query \"$LBUFFER\")\n  CURSOR=$#BUFFER\n  zle redisplay\n}\nzle -N pet-select\nstty -ixon\nbindkey '^s' pet-select\n```\n\n### fish\nSee below for details.  \nhttps://github.com/otms61/fish-pet\n\n\u003cimg src=\"doc/pet03.gif\" width=\"700\"\u003e\n\n\n## Copy snippets to clipboard\nBy using `pbcopy` on macOS, you can copy snippets to clipboard.\n\n\u003cimg src=\"doc/pet06.gif\" width=\"700\"\u003e\n\n## Allow to register from history when using fzf\n\nJust export this to your `.bashrc` or `.zshrc` file. This will show your history\nas default (when using fzf) and it also binds the `alt+s` key combination\nto allow you to search and save some previous used command command.\n\n```\nexport FZF_CTRL_R_OPTS=\"\n  --reverse\n  --cycle\n  --info=right\n  --color header:italic\n  --header 'alt+s (pet new)'\n  --preview 'echo {}' --preview-window down:3:hidden:wrap \n  --bind '?:toggle-preview'\n  --bind 'alt-s:execute(pet new --tag {2..})+abort'\"\n```\n\n# Features\n\n## Edit snippets\nThe snippets are managed in the TOML file, so it's easy to edit.\n\n\u003cimg src=\"doc/pet04.gif\" width=\"700\"\u003e\n\n\n## Sync snippets\nYou can share snippets via Gist.\n\n\u003cimg src=\"doc/pet05.gif\" width=\"700\"\u003e\n\n# Usage\n\n```\nUsage:\n  pet [command]\n\nAvailable Commands:\n  clip        Copy the selected commands\n  configure   Edit config file\n  edit        Edit snippet file\n  exec        Run the selected commands\n  help        Help about any command\n  list        Show all snippets\n  new         Create a new snippet\n  search      Search snippets\n  sync        Sync snippets\n  version     Print the version number\n\nFlags:\n      --config string   config file (default is $HOME/.config/pet/config.toml)\n      --debug           debug mode\n  -h, --help            help for pet\n\nUse \"pet [command] --help\" for more information about a command.\n```\n\n# Snippet\nRun `pet edit`  \nYou can also register the output of command (but cannot search).\n\n```\n[[snippets]]\n  command = \"echo | openssl s_client -connect example.com:443 2\u003e/dev/null |openssl x509 -dates -noout\"\n  description = \"Show expiration date of SSL certificate\"\n  output = \"\"\"\nnotBefore=Nov  3 00:00:00 2015 GMT\nnotAfter=Nov 28 12:00:00 2018 GMT\"\"\"\n```\n\nRun `pet list`\n\n```\n    Command: echo | openssl s_client -connect example.com:443 2\u003e/dev/null |openssl x509 -dates -noout\nDescription: Show expiration date of SSL certificate\n     Output: notBefore=Nov  3 00:00:00 2015 GMT\n             notAfter=Nov 28 12:00:00 2018 GMT\n------------------------------\n```\n\n\n# Configuration\n\nRun `pet configure`\n\n```\n[General]\n  snippetfile = \"path/to/snippet\" # specify snippet directory\n  editor = \"vim\"                  # your favorite text editor\n  column = 40                     # column size for list command\n  selectcmd = \"fzf\"               # selector command for edit command (fzf or peco)\n  backend = \"gist\"                # specify backend service to sync snippets (gist, ghe or gitlab, default: gist)\n  sortby  = \"description\"         # specify how snippets get sorted (recency (default), -recency, description, -description, command, -command, output, -output)\n  cmd = [\"sh\", \"-c\"]              # specify the command to execute the snippet with\n  color = false                   # enables output coloring with fzf, same as '--color' flag\n  format = \"[$description]: $command $tags\" controls the format of the output when searching\n\n[Gist]\n  file_name = \"pet-snippet.toml\"  # specify gist file name\n  access_token = \"\"               # your access token\n  gist_id = \"\"                    # Gist ID\n  public = false                  # public or priate\n  auto_sync = false               # sync automatically when editing snippets\n\n[GitLab]\n  file_name = \"pet-snippet.toml\"  # specify GitLab Snippets file name\n  access_token = \"XXXXXXXXXXXXX\"  # your access token\n  id = \"\"                         # GitLab Snippets ID\n  visibility = \"private\"          # public or internal or private\n  auto_sync = false               # sync automatically when editing snippets\n```\n\n## Multi directory and multi file setup\n\nDirectories must be specified as an array.\nAll `toml` files will be scraped and found snippets will be added.\n\nExample1: single directory\n\n```toml\n[GHEGist]\n  base_url = \"\"                   # GHE base URL\n  upload_url = \"\"                 # GHE upload URL (often the same as the base URL)\n  file_name = \"pet-snippet.toml\"  # specify gist file name\n  access_token = \"\"               # your access token\n  gist_id = \"\"                    # Gist ID\n  public = false                  # public or priate\n  auto_sync = false               # sync automatically when editing snippets\n```\n\n```\n$ pet configure\n[General]\n...\n  snippetdirs = [\"/path/to/some/snippets/\"]\n...\n```\n\nExample2: multiple directories\n\n```\n$ pet configure\n[General]\n...\n  snippetdirs = [\"/path/to/some/snippets/\", \"/more/snippets/\"]\n...\n```\n If `snippetfile` setting is omitted, new snippets will be added in a separate file to the first directory. The generated filename is time based.\n\nSnippet files in `snippetdirs` will not be added to Gist or GitLab. You've to do version control manually.\n\n\n## Selector option\nExample1: Change layout (bottom up)\n\n```\npet configure\n[General]\n...\n  selectcmd = \"fzf\"\n...\n```\n\nExample2: Enable colorized output\n```\npet configure\n[General]\n...\n  selectcmd = \"fzf --ansi\"\n...\npet search --color\n```\n\n## Tag\nYou can use tags (delimiter: space).\n```\npet new -t\nCommand\u003e ping 8.8.8.8\nDescription\u003e ping\nTag\u003e network google\n```\n\nOr edit manually.\n```\npet edit\n[[snippets]]\n  description = \"ping\"\n  command = \"ping 8.8.8.8\"\n  tag = [\"network\", \"google\"]\n  output = \"\"\n```\n\nThey are displayed with snippets.\n```\npet search\n[ping]: ping 8.8.8.8 #network #google\n```\n\nYou can exec snippet with filtering the tag\n\n```\npet exec -t google\n\n[ping]: ping 8.8.8.8 #network #google\n```\n\n## Sync\n### Gist\nYou must obtain access token.\nGo https://github.com/settings/tokens/new and create access token (only need \"gist\" scope).\nSet that to `access_token` in `[Gist]` or use an environment variable with the name `$PET_GITHUB_ACCESS_TOKEN`.\n\nAfter setting, you can upload snippets to Gist.  \nIf `gist_id` is not set, new gist will be created.\n```\npet sync\nGist ID: 1cedddf4e06d1170bf0c5612fb31a758\nUpload success\n```\n\nSet `Gist ID` to `gist_id` in `[Gist]`.\n`pet sync` compares the local file and gist with the update date and automatically download or upload.\n\nIf the local file is older than gist, `pet sync` download snippets.\n```\npet sync\nDownload success\n```\n\nIf gist is older than the local file, `pet sync` upload snippets.\n```\npet sync\nUpload success\n```\n\n*Note: `-u` option is deprecated*\n\n### GHE Gist\n\nTo use Gist with GitHub Enterprise, you need to follow these steps:\n\n1. Obtain an Access Token: Visit your GitHub Enterprise settings page to create a new access token with just the \"gist\" scope. This is necessary to authenticate and interact with the Gist API on GitHub Enterprise.\n2. Set the Access Token: Assign the newly created access token to `access_token` in the `[GHEGist]` section of your configuration. Alternatively, you can use an environment variable named `$PET_GITHUB_ENTERPRISE_ACCESS_TOKEN` to manage your token securely.\n3. Configure API Endpoints: Unlike the regular Gist config, you need to set `base_url` and `upload_url` to point to your GitHub Enterprise API endpoints. For example:\n\n```toml\n\n[GHEGist]\nbase_url = \"https://github-enterprise.example.com/api/v3/gists\"\nupload_url = \"https://github-enterprise.example.com/api/v3/gists\"  # Often the same as the base URL\n```\n\nBy setting these parameters, your tool will be configured to interact with GitHub Enterprise Gist, enabling you to sync and manage your snippets just as you would with the standard GitHub Gist service.\n\nRemember to replace `https://github-enterprise.example.com` with the actual URL of your GitHub Enterprise instance. This customization allows your tool to correctly connect to and use the Gist service in a GitHub Enterprise environment.\n\n### GitLab Snippets\nYou must obtain access token.\nGo https://gitlab.com/-/profile/personal_access_tokens and create access token.\nSet that to `access_token` in `[GitLab]` or use an environment variable with the name `$PET_GITLAB_ACCESS_TOKEN`.\n\nYou also have to configure the `url` under `[GitLab]`, so pet knows which endpoint to access. You would use `url = \"https://gitlab.com\"`unless you have another instance of Gitlab.\n\nAt last, switch the `backend` under `[General]` to `backend = \"gitlab\"`.\n\nAfter setting, you can upload snippets to GitLab Snippets.\nIf `id` is not set, new snippet will be created.\n```\npet sync\nGitLab Snippet ID: 12345678\nUpload success\n```\n\nSet `GitLab Snippet ID` to `id` in `[GitLab]`.\n`pet sync` compares the local file and gitlab with the update date and automatically download or upload.\n\nIf the local file is older than gitlab, `pet sync` download snippets.\n```\npet sync\nDownload success\n```\n\nIf gitlab is older than the local file, `pet sync` upload snippets.\n```\npet sync\nUpload success\n```\n\n## Auto Sync\nYou can sync snippets automatically.\nSet `true` to `auto_sync` in `[Gist]`, `[GHEGist]` or `[GitLab]`.\nThen, your snippets sync automatically when `pet new` or `pet edit`.\n\n```\npet edit\nGetting Gist...\nUpdating Gist...\nUpload success\n```\n\n# Installation\nYou need to install selector command ([fzf](https://github.com/junegunn/fzf) or [peco](https://github.com/peco/peco)).  \n`homebrew` install `fzf` automatically.\n\nAfter you install Pet, it's HIGHLY recommended to install the shortcuts mentioned in the section on [ZSH Prev](#zsh-prev-function)\n\n\n## Binary\nGo 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. \n\n## macOS / Homebrew\n\nInstall [selector command](#Installation) first.\nYou can use homebrew on macOS.\n```\nbrew install knqyf263/pet/pet\n```\n\nIf you receive an error (`Error: knqyf263/pet/pet 64 already installed`) during `brew upgrade`, try the following command\n\n```\nbrew unlink pet \u0026\u0026 brew uninstall pet\n(rm -rf /usr/local/Cellar/pet/64)\nbrew install knqyf263/pet/pet\n```\n\n## Fedora, RedHat, CentOS\nInstall [selector command](#Installation) first.\nDownload rpm package from [the releases page](https://github.com/knqyf263/pet/releases)\n```\nsudo rpm -ivh https://github.com/knqyf263/pet/releases/download/vx.x.x/pet_x.x.x_linux_amd64.rpm\n```\nAlso available on the [Terra repository](https://terra.fyralabs.com/) (3rd party) for Fedora/Fedora-based distros\n```\nsudo dnf install pet\n```\n\n## Debian, Ubuntu\nInstall [selector command](#Installation) first.\nDownload deb package from [the releases page](https://github.com/knqyf263/pet/releases)\n```\nwget https://github.com/knqyf263/pet/releases/download/vx.x.x/pet_x.x.x_linux_amd64.deb\ndpkg -i pet_x.x.x_linux_amd64.deb\n```\n\n## Archlinux\nInstall [selector command](#Installation) first.\nTwo packages are available in [AUR](https://wiki.archlinux.org/index.php/Arch_User_Repository).\nYou can install the package [from source](https://aur.archlinux.org/packages/pet-git):\n```\nyay -S pet-git\n```\nOr [from the binary](https://aur.archlinux.org/packages/pet-bin):\n```\nyay -S pet-bin\n```\n\n## Build\nInstall [selector command](#Installation) first.\n\n```\nmkdir -p $GOPATH/src/github.com/knqyf263\ncd $GOPATH/src/github.com/knqyf263\ngit clone https://github.com/knqyf263/pet.git\ncd pet\nmake install\n```\n\n# Migration\n## From Keep\nhttps://blog.saltedbrain.org/2018/12/converting-keep-to-pet-snippets.html\n\n# Contribute\n\n1. fork a repository: github.com/knqyf263/pet to github.com/you/repo\n2. get original code: `go get github.com/knqyf263/pet`\n3. work on original code\n4. add remote to your repo: git remote add myfork https://github.com/you/repo.git\n5. push your changes: git push myfork\n6. create a new Pull Request\n\n- see [GitHub and Go: forking, pull requests, and go-getting](http://blog.campoy.cat/2014/03/github-and-go-forking-pull-requests-and.html)\n\n----\n\n# License\nMIT\n\n# Author\nTeppei Fukuda\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fknqyf263%2Fpet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fknqyf263%2Fpet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fknqyf263%2Fpet/lists"}