├── .github ├── FUNDING.yml ├── PULL_REQUEST_TEMPLATE.md ├── dependabot.yml └── workflows │ ├── awesomebot.yml │ └── mega-linter.yml ├── .gitignore ├── .pre-commit-config.yaml ├── CodeOfConduct.md ├── Contributing.md ├── LICENSE ├── README.md ├── bin ├── apt-fzf-search ├── asdf-fzf-install ├── asdf-fzf-remove ├── asdf-fzf-uninstall ├── chrome-bookmark-browser ├── chrome-history ├── d-attach ├── d-image-rm ├── d-rm ├── d-stop-container ├── fif ├── fzf-brew-cask-install ├── fzf-brew-cask-uninstall ├── fzf-brew-install ├── fzf-brew-uninstall ├── fzf-brew-update ├── fzf-browse-pods ├── fzf-find-edit ├── fzf-git-branch ├── fzf-git-checkout ├── fzf-grep-edit ├── fzf-kill ├── fzf-vscode ├── lessfilter-fzf ├── pr-list ├── tm ├── tmux-kill ├── tmux-search └── vagrant-box-search ├── completions └── _fzf ├── fzf-settings.zsh └── fzf-zsh-plugin.plugin.zsh /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: unixorn # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: unixorn # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: unixorn 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Description 4 | 5 | 6 | 7 | # Checklist 8 | 9 | 10 | 11 | 12 | - [ ] All new and existing tests pass. 13 | - [ ] Rather than adding functions to `fzf-zsh-plugin.zsh`, I have created standalone scripts in bin so they can be used by non-ZSH users too. 14 | - [ ] Any scripts added use `#!/usr/bin/env interpreter` instead of potentially platform-specific direct paths (`#!/bin/sh` is an ok exception) 15 | - [ ] Scripts are marked executable 16 | - [ ] Scripts _do not_ have a language file extension unless they are meant to be sourced and not run standalone. No one should have to know if a script was written in bash, python, ruby or whatever. Not including file extensions makes it easier to rewrite the script in another language later without having to change every reference to the previous version. 17 | - [ ] I have confirmed that the link(s) in my PR are valid. 18 | - [ ] I have read the **CONTRIBUTING** document. 19 | 20 | # License Acceptance 21 | 22 | - [ ] This repository is Apache version 2.0 licensed (some scripts may have alternate licensing inline in their code) and by making this PR, I am contributing my changes to the repository under the terms of the Apache 2 license. 23 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Use `allow` to specify which dependencies to maintain 3 | 4 | version: 2 5 | updates: 6 | - package-ecosystem: "github-actions" 7 | directory: "/" 8 | schedule: 9 | interval: "weekly" 10 | 11 | - package-ecosystem: "pip" 12 | directory: "/" 13 | schedule: 14 | interval: "weekly" 15 | -------------------------------------------------------------------------------- /.github/workflows/awesomebot.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Check links in README 3 | 4 | on: 5 | push: 6 | branches: [ '*' ] 7 | pull_request: 8 | branches: [ '*' ] 9 | 10 | jobs: 11 | build: 12 | 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v4 17 | - uses: docker://dkhamsing/awesome_bot:latest 18 | with: 19 | args: /github/workspace/README.md --allow-dupe --allow-timeout --allow 202,429,500,501,502,503,504,509,521 --allow-redirect --request-delay 1 --white-list https://github,https://img.shields.io 20 | -------------------------------------------------------------------------------- /.github/workflows/mega-linter.yml: -------------------------------------------------------------------------------- 1 | --- 2 | ########################### 3 | ########################### 4 | ## Linter GitHub Actions ## 5 | ########################### 6 | ########################### 7 | name: Lint Code Base 8 | 9 | # 10 | # Documentation: 11 | # https://help.github.com/en/articles/workflow-syntax-for-github-actions 12 | # 13 | 14 | ############################# 15 | # Start the job on all push # 16 | ############################# 17 | on: 18 | push: 19 | branches-ignore: [main] 20 | # Remove the line above to run when pushing to main 21 | pull_request: 22 | branches: [main] 23 | 24 | ############### 25 | # Set the Job # 26 | ############### 27 | jobs: 28 | build: 29 | # Name the Job 30 | name: Megalint Code Base 31 | # Set the agent to run on 32 | runs-on: ubuntu-latest 33 | 34 | ################## 35 | # Load all steps # 36 | ################## 37 | steps: 38 | ########################## 39 | # Checkout the code base # 40 | ########################## 41 | - name: Checkout Code 42 | uses: actions/checkout@v4 43 | with: 44 | # Full git history is needed to get a proper list of changed files 45 | # within `mega-linter` 46 | fetch-depth: 0 47 | 48 | ################################ 49 | # Run Linter against code base # 50 | ################################ 51 | - name: Lint Code Base 52 | uses: megalinter/megalinter@v8 53 | env: 54 | ACTION_ACTIONLINT_DISABLE_ERRORS: true 55 | DEFAULT_BRANCH: main 56 | DISABLE_LINTERS: SPELL_CSPELL,MARKDOWN_MARKDOWN_LINK_CHECK 57 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 58 | REPOSITORY_CHECKOV_DISABLE_ERRORS: true 59 | REPOSITORY_KICS_DISABLE_ERRORS: true 60 | SPELL_LYCHEE_DISABLE_ERRORS: true 61 | YAML_YAMLLINT_DISABLE_ERRORS: true 62 | TERRAFORM_KICS_DISABLE_ERRORS: true 63 | VALIDATE_ALL_CODEBASE: false 64 | 65 | # Upload Mega-Linter artifacts. 66 | # They will be available on Github action page "Artifacts" section 67 | - name: Archive production artifacts 68 | if: ${{ success() }} || ${{ failure() }} 69 | uses: actions/upload-artifact@v4 70 | with: 71 | name: Mega-Linter reports 72 | path: | 73 | report 74 | mega-linter.log 75 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # VSCode 2 | .vscode/ 3 | # IntelliJ 4 | .idea/ 5 | *.iml 6 | 7 | # Compiled ZSH 8 | *.zwc 9 | # Byte-compiled / optimized / DLL files 10 | __pycache__/ 11 | *.py[cod] 12 | *$py.class 13 | 14 | # C extensions 15 | *.so 16 | 17 | # Distribution / packaging 18 | .Python 19 | build/ 20 | develop-eggs/ 21 | dist/ 22 | downloads/ 23 | eggs/ 24 | .eggs/ 25 | lib/ 26 | lib64/ 27 | parts/ 28 | sdist/ 29 | var/ 30 | wheels/ 31 | pip-wheel-metadata/ 32 | share/python-wheels/ 33 | *.egg-info/ 34 | .installed.cfg 35 | *.egg 36 | MANIFEST 37 | 38 | # PyInstaller 39 | # Usually these files are written by a python script from a template 40 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 41 | *.manifest 42 | *.spec 43 | 44 | # Installer logs 45 | pip-log.txt 46 | pip-delete-this-directory.txt 47 | 48 | # Unit test / coverage reports 49 | htmlcov/ 50 | .tox/ 51 | .nox/ 52 | .coverage 53 | .coverage.* 54 | .cache 55 | nosetests.xml 56 | coverage.xml 57 | *.cover 58 | *.py,cover 59 | .hypothesis/ 60 | .pytest_cache/ 61 | 62 | # Translations 63 | *.mo 64 | *.pot 65 | 66 | # Django stuff: 67 | *.log 68 | local_settings.py 69 | db.sqlite3 70 | db.sqlite3-journal 71 | 72 | # Flask stuff: 73 | instance/ 74 | .webassets-cache 75 | 76 | # Scrapy stuff: 77 | .scrapy 78 | 79 | # Sphinx documentation 80 | docs/_build/ 81 | 82 | # PyBuilder 83 | target/ 84 | 85 | # Jupyter Notebook 86 | .ipynb_checkpoints 87 | 88 | # IPython 89 | profile_default/ 90 | ipython_config.py 91 | 92 | # pyenv 93 | .python-version 94 | 95 | # pipenv 96 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 97 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 98 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 99 | # install all needed dependencies. 100 | #Pipfile.lock 101 | 102 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 103 | __pypackages__/ 104 | 105 | # Celery stuff 106 | celerybeat-schedule 107 | celerybeat.pid 108 | 109 | # SageMath parsed files 110 | *.sage.py 111 | 112 | # Environments 113 | .env 114 | .venv 115 | env/ 116 | venv/ 117 | ENV/ 118 | env.bak/ 119 | venv.bak/ 120 | 121 | # Spyder project settings 122 | .spyderproject 123 | .spyproject 124 | 125 | # Rope project settings 126 | .ropeproject 127 | 128 | # mkdocs documentation 129 | /site 130 | 131 | # mypy 132 | .mypy_cache/ 133 | .dmypy.json 134 | dmypy.json 135 | 136 | # Pyre type checker 137 | .pyre/ 138 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | repos: 3 | - repo: https://github.com/pre-commit/pre-commit-hooks 4 | rev: v5.0.0 5 | hooks: 6 | - id: check-added-large-files 7 | - id: check-executables-have-shebangs 8 | - id: check-merge-conflict 9 | - id: check-shebang-scripts-are-executable 10 | - id: check-symlinks 11 | - id: check-yaml 12 | - id: debug-statements 13 | - id: end-of-file-fixer 14 | - id: forbid-submodules 15 | - id: mixed-line-ending 16 | - id: trailing-whitespace 17 | 18 | - repo: https://github.com/igorshubovych/markdownlint-cli 19 | rev: v0.45.0 20 | hooks: 21 | - id: markdownlint-fix 22 | args: ["--ignore", "LICENSE.md", "--disable", "~MD013"] 23 | 24 | - repo: https://github.com/thlorenz/doctoc 25 | rev: v2.2.0 26 | hooks: 27 | - id: doctoc 28 | args: ["--update-only"] 29 | -------------------------------------------------------------------------------- /CodeOfConduct.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | TL;DR: Don't be a jerk. Just because it's the internet doesn't mean you get a pass for crappy behavior. Don't be a rules lawyer - if you're trying to say shitty behavior isn't against the letter of the Code of Conduct, you're almost certainly violating the spirit. 4 | 5 | I'm fine with not getting contributions from smart assholes. 6 | 7 | ## Our Pledge 8 | 9 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 10 | 11 | ## Our Standards 12 | 13 | Examples of behavior that contributes to creating a positive environment include: 14 | 15 | * Using welcoming and inclusive language 16 | * Being respectful of differing viewpoints and experiences 17 | * Gracefully accepting constructive criticism 18 | * Focusing on what is best for the community 19 | * Showing empathy towards other community members 20 | 21 | Examples of unacceptable behavior by participants include: 22 | 23 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 24 | * Trolling, insulting/derogatory comments, and personal or political attacks 25 | * Public or private harassment 26 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 27 | * Other conduct which could reasonably be considered inappropriate in a professional setting 28 | 29 | ## Our Responsibilities 30 | 31 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 32 | 33 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 34 | 35 | ## Scope 36 | 37 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. 38 | 39 | Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 40 | 41 | ## Enforcement 42 | 43 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the maintainer at jpb@unixorn.net. 44 | 45 | The maintainer will review and investigate all complaints, and will respond in a way that they deem appropriate to the circumstances. The maintainer is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 46 | 47 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 48 | 49 | ## Attribution 50 | 51 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 52 | 53 | [homepage]: http://contributor-covenant.org 54 | [version]: http://contributor-covenant.org/version/1/4/ 55 | -------------------------------------------------------------------------------- /Contributing.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | **fzf-zsh-commands** is a collection of helper scripts for `fzf` and links to fzf-related articles. 4 | 5 | ## Contribution Guidelines 6 | 7 | ### To add a shell function 8 | 9 | Submit a pull request 10 | - Please consider wrapping it in a script in the `bin` directory instead. That makes it easy for users of any shell to use the script, otherwise they'll have to rewrite the function in their own shell, which is unnecessary work. 11 | 12 | ### To add a helper script 13 | 14 | Submit a pull request. 15 | 16 | - Please use `#!/usr/bin/env interpreter` instead of a direct path to the interpreter, this makes it easier for people to use more recent interpreter versions when the ones packaged with their OS (macOS and CentOS, I'm looking at you) are stale. 17 | - Please _do not_ include a language file extension in the script name unless they are meant to be sourced and not run standalone. No one should have to know if a script was written in bash, python, ruby or whatever language to use a script. Not including file extensions makes it easier to rewrite the script in another language later without having to change every reference to the previous version. 18 | 19 | ### To remove a script 20 | 21 | All of the scripts here were either taken from blog posts, public wikis or had an Open Source license. That said, if you wrote something included here and want it removed, either open an issue to request the removal or submit a pull request. 22 | 23 | For each script you add, please: 24 | 25 | - Include an entry in the contents section of `README.md` for any scripts in your PRs so authors get their work credited correctly. Please keep the contents section in alphabetical order by script name. 26 | - Include a link to the original source in the contents section and the comments at the beginning of added scripts so people can find their other work. 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # fzf-zsh-plugin 2 | 3 | [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) 4 | ![Awesomebot](https://github.com/unixorn/fzf-zsh-plugin/actions/workflows/awesomebot.yml/badge.svg) 5 | ![MegaLinter](https://github.com/unixorn/fzf-zsh-plugin/actions/workflows/mega-linter.yml/badge.svg) 6 | [![Code Climate](https://codeclimate.com/github/unixorn/fzf-zsh-plugin/badges/gpa.svg)](https://codeclimate.com/github/unixorn/fzf-zsh-plugin) 7 | 8 | 9 | 10 | ## Table of Contents 11 | 12 | - [Contents](#contents) 13 | - [Installing](#installing) 14 | - [Zgenom](#zgenom) 15 | - [Antigen](#antigen) 16 | - [Oh-My-Zsh](#oh-my-zsh) 17 | - [Without using a framework](#without-using-a-framework) 18 | - [(optional) Install recommended tools](#optional-install-recommended-tools) 19 | - [Customization](#customization) 20 | - [A note on `lessfilter-fzf`](#a-note-on-lessfilter-fzf) 21 | - [Other FZF resources](#other-fzf-resources) 22 | - [Contributors](#contributors) 23 | 24 | 25 | 26 | This ZSH plugin enables using [fzf](https://github.com/junegunn/fzf) to search your command history and do file searches. 27 | 28 | It will automagically install `fzf` into your home directory if it isn't already there, and bind `^R` to an `fzf`-powered search of your command history. 29 | 30 | Created for the [zsh-quickstart-kit](https://github.com/unixorn/zsh-quickstart-kit) to make the default setup have a more 'batteries included' feel. 31 | 32 | Yes, there is a plugin baked into [oh-my-zsh](https://github.com/ohmyzsh/ohmyzsh), this allows easy `fzf` integration for other frameworks and shells, and adds some helper scripts. 33 | 34 | Note - while these scripts could all be ZSH functions instead of scripts in the `bin` directory, it uses standalone scripts so that non-ZSH users can also use the repository by adding its `bin` directory to their `$PATH`. 35 | 36 | ## Contents 37 | 38 | | Name | Description | Author | 39 | | ---- | ----------- | ------ | 40 | | `asdf-install` | Install one or more versions of the specified language with `fzf` and installs your selection with `asdf` | [fzf wiki](https://github.com/junegunn/fzf/wiki/examples) | 41 | | `asdf-uninstall` | Select one or more versions of the specified language with `fzf` and uninstalls your selection with `asdf` | [fzf wiki](https://github.com/junegunn/fzf/wiki/examples) | 42 | | `chrome-bookmark-browser` | Rummages through your Chrome bookmarks with `fzf` and opens the selected bookmark(s) in your default browser | [fzf wiki](https://github.com/junegunn/fzf/wiki/examples) | 43 | | `d-attach` | Uses `fzf` to select `docker` containers to start and attach to. | From the [fzf wiki](https://github.com/junegunn/fzf/wiki/examples) | 44 | | `d-image-rm` | Uses `fzf` to select `docker` images to remove. | From the [fzf wiki](https://github.com/junegunn/fzf/wiki/examples) | 45 | | `d-rm` | Uses `fzf` to select `docker` containers to remove. | From the [fzf wiki](https://github.com/junegunn/fzf/wiki/examples) | 46 | | `d-stop-container` | Stop a Docker container. | ? | 47 | | `falias` | Searches your ZSH aliases, then puts your selection on the mac clipboard (macOS only) | ? | 48 | | `fif` | Uses `fzf` and `rg` to find a term in files | [Boost Your Command-Line Productivity With Fuzzy Finder](https://betterprogramming.pub/boost-your-command-line-productivity-with-fuzzy-finder-985aa162ba5d) | 49 | | `fzf-brew-cask-install` | Uses `fzf` to select programs to install (or show the home page) based on the output of `brew cask search` | [Boost Your Command-Line Productivity With Fuzzy Finder](https://betterprogramming.pub/boost-your-command-line-productivity-with-fuzzy-finder-985aa162ba5d) | 50 | | `fzf-brew-cask-uninstall` | Uses `fzf` to select `brew`-installed programs to delete (or show the home page) | [Boost Your Command-Line Productivity With Fuzzy Finder](https://betterprogramming.pub/boost-your-command-line-productivity-with-fuzzy-finder-985aa162ba5d) | 51 | | `fzf-brew-install` | Uses `fzf` to select programs to install based on the output of `brew search` | [Boost Your Command-Line Productivity With Fuzzy Finder](https://betterprogramming.pub/boost-your-command-line-productivity-with-fuzzy-finder-985aa162ba5d) | 52 | | `fzf-brew-uninstall` | Uses `fzf` to select `brew`-installed programs to delete | [Boost Your Command-Line Productivity With Fuzzy Finder](https://betterprogramming.pub/boost-your-command-line-productivity-with-fuzzy-finder-985aa162ba5d) | 53 | | `fzf-brew-update` | Uses `fzf` to select `brew`-installed programs to update | [Boost Your Command-Line Productivity With Fuzzy Finder](https://betterprogramming.pub/boost-your-command-line-productivity-with-fuzzy-finder-985aa162ba5d) | 54 | | `fzf-browse-pods` | Use `fzf` to select a k8s pod. Preview shows pod's `log tail` output. | [Using fzf as the secondary filter](https://github.com/junegunn/fzf/blob/master/ADVANCED.md#using-fzf-as-the-secondary-filter) | 55 | | `fzf-find-edit` | Uses `fzf` to select files (displaying previews) to edit with `$EDITOR` | [Boost Your Command-Line Productivity With Fuzzy Finder](https://betterprogramming.pub/boost-your-command-line-productivity-with-fuzzy-finder-985aa162ba5d) | 56 | | `fzf-git-branch` | Uses `fzf` to select a branch name in a `git` repository for use in scripts | From Mark Nielsen's [Fuzzy Git Checkout](https://polothy.github.io/post/2019-08-19-fzf-git-checkout/) article | 57 | | `fzf-git-checkout` | Uses `fzf` to check out a branch in a `git` repository | From Mark Nielsen's [Fuzzy Git Checkout](https://polothy.github.io/post/2019-08-19-fzf-git-checkout/) article | 58 | | `fzf-grep-edit` | Uses `fzf` to select files (displaying previews) that contain a search term to edit with `$EDITOR` | [Boost Your Command-Line Productivity With Fuzzy Finder](https://betterprogramming.pub/boost-your-command-line-productivity-with-fuzzy-finder-985aa162ba5d) | 59 | | `fzf-kill` | Uses `fzf` to select processes to kill | [Boost Your Command-Line Productivity With Fuzzy Finder](https://betterprogramming.pub/boost-your-command-line-productivity-with-fuzzy-finder-985aa162ba5d) | 60 | | `fzf-vscode` | Uses `fzf` and `rg` to search for text and then open the file in vscode | Hangops post by Mark Carey | 61 | | `lessfilter-fzf` | A less pre-processor to nicely display a wide range of file formats, including images and directories that can be used to show fzf previews (see [Customization](#customization) section). | [Aloxaf/fzf-tab - Wiki/Preview](https://github.com/Aloxaf/fzf-tab/wiki/Preview) | 62 | | `pr-list` | Use `fzf` to select a PR using `gh` | ? | 63 | | `tm` | Uses `fzf` to search for a `tmux` session or create one if there are no matches. | From the [fzf wiki](https://github.com/junegunn/fzf/wiki/examples) | 64 | | `tmux-kill` | Uses `fzf` to select a `tmux` session and kill it. | From the [fzf wiki](https://github.com/junegunn/fzf/wiki/examples) | 65 | | `tmux-search` | Uses `fzf` to select a `tmux` session. Skips `fzf` if there's only one match, exits if no match. | From the [fzf wiki](https://github.com/junegunn/fzf/wiki/examples) | 66 | | `vagrant-box-search` | Uses `fzf` to select a `vagrant` box and connect to it with `ssh`. | From the [fzf wiki](https://github.com/junegunn/fzf/wiki/examples) | 67 | 68 | ## Installing 69 | 70 | You should set this plugin to be last, or near to last in your framework's list of plugins to load. It dynamically generates `$FZF_DEFAULT_OPT` and `$FZF_DEFAULT_COMMAND` based on whether it sees things like `rg` and `bat` in your `$PATH`, so it should come after other plugins have had a chance to extend your `$PATH`. 71 | 72 | ### [Zgenom](https://github.com/jandamm/zgenom) 73 | 74 | Add `zgenom load unixorn/fzf-zsh-plugin` to your `.zshrc` with your other load commands. 75 | 76 | ### [Antigen](https://github.com/zsh-users/antigen) 77 | 78 | Add `antigen bundle unixorn/fzf-zsh-plugin@main` to your `.zshrc` 79 | 80 | ☝ **Note** that until gets fixed in Antigen, it only recognizes plugins in `master` branch. So you need to explicitly specify `@main` here. 81 | 82 | ### [Oh-My-Zsh](http://ohmyz.sh/) 83 | 84 | 1. `git clone --depth 1 https://github.com/unixorn/fzf-zsh-plugin.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/fzf-zsh-plugin` 85 | 2. Add **fzf-zsh-plugin** to your plugin list - edit `~.zshrc` and change `plugins=(...)` to `plugins=(... fzf-zsh-plugin)` 86 | 87 | ### Without using a framework 88 | 89 | 1. `git clone --depth 1 git@github.com:unixorn/fzf-zsh-plugin.git`, then add its `bin` directory to your `$PATH`. 90 | 2. Add `source /path/to/repository/checkout/fzf-zsh-plugin.plugin.zsh` to your `.zshrc` file. 91 | 92 | The scripts in this collection don't actually require you to be using ZSH as your login shell, they're being distributed as an [oh-my-zsh](https://github.com/ohmyzsh/ohmyzsh)-compatible plugin because it's convenient for me. 93 | 94 | ### (optional) Install recommended tools 95 | 96 | Optionally, to make the most out of `fzf` preview (`?` toggle), install the following tools and enable the advanced preview (see [Customization](#customization) section): 97 | - `eza` - improved file/directory listing, 98 | - `bat` - a `cat` clone with syntax highlighting and Git integration, 99 | - `chafa` - show images (the image quality depends on the terminal emulator you use), 100 | - `exiftool` - also show image metadata, 101 | - `lesspipe.sh`, e.g. `brew install lesspipe` - and other optional tools `lesspipe.sh` relies on. See 102 | ☝ **Note**: This is not the `lesspipe` already bundled in Ubuntu/Debian but an improved one (while package is called `lesspipe`, the binary is `lesspipe.sh`). 103 | 104 | ## Customization 105 | 106 | You can customize a few features by exporting the following environment variables in your init script (`.zshrc`/`.bashrc` or similar): 107 | 108 | | Export variable | Description | 109 | | ---------------------------------- |----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 110 | | `FZF_PREVIEW_ADVANCED` | Use `less` viewer with a pre-processor to display improved previews for a wide range of files (requires you to install at least `eza`, `bat`, `chafa`, `exiftool`; and very recommended `lesspipe.sh` and the tools it uses underneath: `mdcat`, `in2csv`,...). _This is an opt-in feature._ | 111 | | `FZF_PREVIEW_WINDOW` | Set any value supported by `fzf --preview-window` option, e.g. `right:65%:nohidden` will show the preview by default. | 112 | | `FZF_PATH` | Path to install fzf binary and script, e.g. `${HOME}/.config/fzf`. | 113 | | `FZF_COLOR_SCHEME` | Color scheme for fzf, e.g. `--color='hl:148,hl+:154,pointer:032,marker:010,bg+:237,gutter:008'` | 114 | 115 | ### A note on `lessfilter-fzf` 116 | 117 | You can also use it as a general `less` preprocessor to extend the `less` capabilities. To do that, place the following in your shell init scripts (`.zshrc`/`.bashrc` or equivalent): 118 | 119 | ```shell 120 | export LESSOPEN='| lessfilter-fzf %s' 121 | ``` 122 | 123 | Ultimately, `lesspipe.sh` (if present) will still honor your own `lessfilter` if found in your `PATH`, leading to the following execution: `lessfilter-fzf > lesspipe.sh > lessfilter`. 124 | 125 | ## Other FZF resources 126 | 127 | - [A Practical Guide to fzf: Building a File Explorer](https://thevaluable.dev/practical-guide-fzf-example/) - Part one in a series of articles about `fzf`. 128 | - [Fuzzy Git Checkout](https://polothy.github.io/post/2019-08-19-fzf-git-checkout/) - Mark Nielsen wrote a good blog post showing how to use [fzf](https://github.com/junegunn/fzf) for `git` checkouts. 129 | - [So you've installed `fzf`. Now what?](https://andrew-quinn.me/fzf/) - Good blog post by Andrew Quinn with more tricks you can do with `fzf`. 130 | - [fzf-pass](https://github.com/smeagol74/zsh-fzf-pass) - ZSH plugin that uses [fzf](https://github.com/junegunn/fzf) and [pass](https://www.passwordstore.org/) for better password handling. 131 | - [fzf-tab](https://github.com/Aloxaf/fzf-tab) - Replace ZSH's default completion with [fzf](https://github.com/junegunn/fzf). 132 | 133 | ## Contributors 134 | 135 | 136 | 137 | 138 | 139 | Made with [contributors-img](https://contributors-img.web.app). 140 | -------------------------------------------------------------------------------- /bin/apt-fzf-search: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Use fzf to filter apt-cache search results 4 | # 5 | # From https://www.linuxuprising.com/2021/03/a-quick-introduction-to-fzf-interactive.html 6 | 7 | set -o pipefail 8 | if [[ -n "$DEBUG" ]]; then 9 | set -x 10 | fi 11 | 12 | function debug() { 13 | if [[ -n "$DEBUG" ]]; then 14 | echo "$@" 15 | fi 16 | } 17 | 18 | function fail() { 19 | printf '%s\n' "$1" >&2 ## Send message to stderr. Exclude >&2 if you don't want it that way. 20 | exit "${2-1}" ## Return a code specified by $2 or 1 by default. 21 | } 22 | 23 | function has() { 24 | # Check if a command is in $PATH 25 | which "$@" > /dev/null 2>&1 26 | } 27 | 28 | if has apt-cache; then 29 | apt-cache search "$@" | \ 30 | sort | \ 31 | cut --delimiter ' ' --fields 1 | \ 32 | fzf --multi --cycle --reverse --preview 'apt-cache show {1}' | \ 33 | xargs -r sudo apt install -y 34 | else 35 | fail "Cannot find apt in $PATH. 36 | 37 | Are you sure you're on a Debian or Ubuntu system?" 38 | fi 39 | -------------------------------------------------------------------------------- /bin/asdf-fzf-install: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Install one or more versions of specified language 4 | # e.g. `asdf-install rust` # => fzf multimode, tab to mark, enter to install 5 | # if no plugin is supplied (e.g. `asdf-install`), fzf will list them for you 6 | # Mnemonic [V]ersion [M]anager [I]nstall 7 | # 8 | # Source: https://github.com/junegunn/fzf/wiki/examples 9 | 10 | set -o pipefail 11 | if [[ -n "$DEBUG" ]]; then 12 | set -x 13 | fi 14 | 15 | function fail() { 16 | printf '%s\n' "$1" >&2 ## Send message to stderr. Exclude >&2 if you don't want it that way. 17 | exit "${2-1}" ## Return a code specified by $2 or 1 by default. 18 | } 19 | 20 | function has() { 21 | # Check if a command is in $PATH 22 | which "$@" > /dev/null 2>&1 23 | } 24 | 25 | # Install one or more versions of specified language 26 | # e.g. `vmi rust` # => fzf multimode, tab to mark, enter to install 27 | # if no plugin is supplied (e.g. `vmi`), fzf will list them for you 28 | # Mnemonic [V]ersion [M]anager [I]nstall 29 | asdf-install() { 30 | local lang=${1} 31 | 32 | if [[ ! $lang ]]; then 33 | lang=$(asdf plugin-list | fzf) 34 | fi 35 | 36 | if [[ $lang ]]; then 37 | local versions 38 | versions=$(asdf list-all "$lang" | fzf --tac --no-sort --multi) 39 | if [[ $versions ]]; then 40 | for version in $versions 41 | do 42 | asdf install "$lang" "$version" 43 | done 44 | fi 45 | fi 46 | } 47 | 48 | if has asdf; then 49 | asdf-install "$@" 50 | else 51 | fail "Can't find asdf in $PATH" 52 | fi 53 | -------------------------------------------------------------------------------- /bin/asdf-fzf-remove: -------------------------------------------------------------------------------- 1 | asdf-fzf-uninstall -------------------------------------------------------------------------------- /bin/asdf-fzf-uninstall: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Remove one or more versions of specified language 4 | # e.g. `asdf-remove rust` # => fzf multimode, tab to mark, enter to remove 5 | # if no plugin is supplied (e.g. `asdf-remove`), fzf will list them for you 6 | # 7 | # Source: https://github.com/junegunn/fzf/wiki/examples 8 | 9 | set -o pipefail 10 | if [[ -n "$DEBUG" ]]; then 11 | set -x 12 | fi 13 | 14 | function fail() { 15 | printf '%s\n' "$1" >&2 ## Send message to stderr. Exclude >&2 if you don't want it that way. 16 | exit "${2-1}" ## Return a code specified by $2 or 1 by default. 17 | } 18 | 19 | function has() { 20 | # Check if a command is in $PATH 21 | which "$@" > /dev/null 2>&1 22 | } 23 | 24 | # Remove one or more versions of specified language 25 | # e.g. `vmi rust` # => fzf multimode, tab to mark, enter to remove 26 | # if no plugin is supplied (e.g. `vmi`), fzf will list them for you 27 | asdf-remove() { 28 | local lang=${1} 29 | 30 | if [[ ! $lang ]]; then 31 | lang=$(asdf plugin-list | fzf) 32 | fi 33 | 34 | if [[ $lang ]]; then 35 | local versions 36 | versions=$(asdf list "$lang" | fzf -m) 37 | if [[ $versions ]]; then 38 | for version in $versions 39 | do 40 | asdf uninstall "$lang" "$version" 41 | done 42 | fi 43 | fi 44 | } 45 | 46 | if has asdf; then 47 | asdf-remove "$@" 48 | else 49 | fail "Can't find asdf in $PATH" 50 | fi 51 | -------------------------------------------------------------------------------- /bin/chrome-bookmark-browser: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Chrome Bookmarks browser with jq for OS X 4 | 5 | set -o pipefail 6 | if [[ -n "$DEBUG" ]]; then 7 | set -x 8 | fi 9 | 10 | function debug() { 11 | if [[ -n "$DEBUG" ]]; then 12 | echo "$@" 13 | fi 14 | } 15 | 16 | function fail() { 17 | printf '%s\n' "$1" >&2 ## Send message to stderr. Exclude >&2 if you don't want it that way. 18 | exit "${2-1}" ## Return a code specified by $2 or 1 by default. 19 | } 20 | 21 | function has() { 22 | # Check if a command is in $PATH 23 | which "$@" > /dev/null 2>&1 24 | } 25 | 26 | # b - browse chrome bookmarks 27 | b() { 28 | 29 | # shellcheck disable=SC2016 30 | jq_script=' 31 | def ancestors: while(. | length >= 2; del(.[-1,-2])); 32 | . as $in | paths(.url?) as $key | $in | getpath($key) | {name,url, path: [$key[0:-2] | ancestors as $a | $in | getpath($a) | .name?] | reverse | join("/") } | .path + "/" + .name + "\t" + .url' 33 | 34 | jq -r "$jq_script" < "$bookmarks_path" \ 35 | | sed -E $'s/(.*)\t(.*)/\\1\t\x1b[36m\\2\x1b[m/g' \ 36 | | fzf --ansi \ 37 | | cut -d$'\t' -f2 \ 38 | | xargs open 39 | } 40 | 41 | bookmarks_path=~/Library/Application\ Support/Google/Chrome/Default/Bookmarks 42 | if [[ ! -r "$bookmarks_path" ]]; then 43 | fail "Can't read $bookmarks_path" 44 | fi 45 | 46 | myname=$(basename "$0") 47 | if ! has fzf; then 48 | fail "$myname requires fzf and can't find it in $PATH" 49 | fi 50 | if ! has jq; then 51 | fail "$myname requires jq and can't find it in $PATH" 52 | fi 53 | 54 | b "$@" 55 | -------------------------------------------------------------------------------- /bin/chrome-history: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # browse Chrome history, then open 4 | 5 | set -o pipefail 6 | if [[ -n "$DEBUG" ]]; then 7 | set -x 8 | fi 9 | 10 | function debug() { 11 | if [[ -n "$DEBUG" ]]; then 12 | echo "$@" 13 | fi 14 | } 15 | 16 | function fail() { 17 | printf '%s\n' "$1" >&2 ## Send message to stderr. Exclude >&2 if you don't want it that way. 18 | exit "${2-1}" ## Return a code specified by $2 or 1 by default. 19 | } 20 | 21 | function has() { 22 | # Check if a command is in $PATH 23 | which "$@" > /dev/null 2>&1 24 | } 25 | 26 | function cleanup() { 27 | if [[ -d "$SCRATCH_D" ]]; then 28 | rm -fr "$SCRATCH_D" 29 | fi 30 | } 31 | 32 | # Set up a working scratch directory 33 | SCRATCH_D=$(mktemp -d) 34 | 35 | if [[ ! "$SCRATCH_D" || ! -d "$SCRATCH_D" ]]; then 36 | echo "Could not create temp dir" 37 | exit 1 38 | fi 39 | 40 | trap cleanup EXIT 41 | 42 | # browse Chrome history 43 | chrome-history() { 44 | local cols sep chrome_history open 45 | cols=$(( COLUMNS / 3 )) 46 | sep='{::}' 47 | 48 | cp -f "$chrome_history" "${SCRATCH_D}/chrome-history.sqlite" 49 | sqlite3 -separator $sep "${SCRATCH_D}/chrome-history.sqlite" \ 50 | "select substr(title, 1, $cols), url 51 | from urls order by last_visit_time desc" | 52 | awk -F $sep '{printf "%-'$cols's \x1b[36m%s\x1b[m\n", $1, $2}' | 53 | fzf --ansi --multi | sed 's#.*\(https*://\)#\1#' | xargs "$open" > /dev/null 2> /dev/null 54 | } 55 | 56 | if [ "$(uname)" = "Darwin" ]; then 57 | chrome_history="$HOME/Library/Application Support/Google/Chrome/Default/History" 58 | open=open 59 | else 60 | chrome_history="$HOME/.config/google-chrome/Default/History" 61 | open=xdg-open 62 | fi 63 | 64 | if [[ -r "$chrome_history" ]]; then 65 | chrome-history "$@" 66 | else 67 | fail "Can't read $chrome_history" 68 | fi 69 | -------------------------------------------------------------------------------- /bin/d-attach: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Select a docker container to start and attach to 4 | # 5 | # From fzf wiki: https://github.com/junegunn/fzf/wiki/examples 6 | 7 | set -o pipefail 8 | if [[ -n "$DEBUG" ]]; then 9 | set -x 10 | fi 11 | 12 | function debug() { 13 | if [[ -n "$DEBUG" ]]; then 14 | echo "$@" 15 | fi 16 | } 17 | 18 | function fail() { 19 | printf '%s\n' "$1" >&2 ## Send message to stderr. Exclude >&2 if you don't want it that way. 20 | exit "${2-1}" ## Return a code specified by $2 or 1 by default. 21 | } 22 | 23 | function has() { 24 | # Check if a command is in $PATH 25 | which "$@" > /dev/null 2>&1 26 | } 27 | 28 | function da() { 29 | local cid 30 | cid=$(docker ps -a | sed 1d | fzf -1 -q "$1" | awk '{print $1}') 31 | 32 | [ -n "$cid" ] && docker start "$cid" && docker attach "$cid" 33 | } 34 | 35 | if has docker; then 36 | da "$@" 37 | else 38 | "Cannot find docker in $PATH" 39 | fi 40 | -------------------------------------------------------------------------------- /bin/d-image-rm: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Select a docker image or images to remove 4 | # 5 | # From fzf wiki: https://github.com/junegunn/fzf/wiki/examples 6 | 7 | set -o pipefail 8 | if [[ -n "$DEBUG" ]]; then 9 | set -x 10 | fi 11 | 12 | function debug() { 13 | if [[ -n "$DEBUG" ]]; then 14 | echo "$@" 15 | fi 16 | } 17 | 18 | function fail() { 19 | printf '%s\n' "$1" >&2 ## Send message to stderr. Exclude >&2 if you don't want it that way. 20 | exit "${2-1}" ## Return a code specified by $2 or 1 by default. 21 | } 22 | 23 | function has() { 24 | # Check if a command is in $PATH 25 | which "$@" > /dev/null 2>&1 26 | } 27 | 28 | # Select a docker image or images to remove 29 | function drmi() { 30 | # if the image has no tag, use the image id, otherwise use the image name and 31 | # tag; allows removing a tag from an image with multiple tags 32 | docker images | sed 1d | fzf -q "$1" --no-sort -m --tac | 33 | awk '{ print ($2=="")?$3:$1 ":" $2 }' | 34 | xargs -r docker rmi 35 | } 36 | 37 | if has docker; then 38 | drmi "$@" 39 | else 40 | "Cannot find docker in $PATH" 41 | fi 42 | -------------------------------------------------------------------------------- /bin/d-rm: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Select a docker container to remove 4 | # 5 | # From fzf wiki: https://github.com/junegunn/fzf/wiki/examples 6 | 7 | set -o pipefail 8 | if [[ -n "$DEBUG" ]]; then 9 | set -x 10 | fi 11 | 12 | function debug() { 13 | if [[ -n "$DEBUG" ]]; then 14 | echo "$@" 15 | fi 16 | } 17 | 18 | function fail() { 19 | printf '%s\n' "$1" >&2 ## Send message to stderr. Exclude >&2 if you don't want it that way. 20 | exit "${2-1}" ## Return a code specified by $2 or 1 by default. 21 | } 22 | 23 | function has() { 24 | # Check if a command is in $PATH 25 | which "$@" > /dev/null 2>&1 26 | } 27 | 28 | function drm() { 29 | docker ps -a | sed 1d | fzf -q "$1" --no-sort -m --tac | awk '{ print $1 }' | xargs -r docker rm 30 | } 31 | 32 | if has docker; then 33 | drm "$@" 34 | else 35 | "Cannot find docker in $PATH" 36 | fi 37 | -------------------------------------------------------------------------------- /bin/d-stop-container: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Stop a docker container 4 | # 5 | # From fzf wiki 6 | 7 | set -o pipefail 8 | if [[ -n "$DEBUG" ]]; then 9 | set -x 10 | fi 11 | 12 | function debug() { 13 | if [[ -n "$DEBUG" ]]; then 14 | echo "$@" 15 | fi 16 | } 17 | 18 | function fail() { 19 | printf '%s\n' "$1" >&2 ## Send message to stderr. Exclude >&2 if you don't want it that way. 20 | exit "${2-1}" ## Return a code specified by $2 or 1 by default. 21 | } 22 | 23 | function has() { 24 | # Check if a command is in $PATH 25 | which "$@" > /dev/null 2>&1 26 | } 27 | 28 | # Select a running docker container to stop 29 | function d-stop-container() { 30 | local cid 31 | cid=$(docker ps | sed 1d | fzf -q "$1" | awk '{print $1}') 32 | 33 | [ -n "$cid" ] && docker stop "$cid" 34 | } 35 | 36 | if has docker; then 37 | d-stop-container "$@" 38 | else 39 | "Cannot find docker in $PATH" 40 | fi 41 | -------------------------------------------------------------------------------- /bin/fif: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # fif 4 | # 5 | # Source - https://betterprogramming.pub/boost-your-command-line-productivity-with-fuzzy-finder-985aa162ba5d 6 | 7 | set -o pipefail 8 | if [[ -n "$DEBUG" ]]; then 9 | set -x 10 | fi 11 | 12 | fif() { 13 | if [ ! "$#" -gt 0 ]; then 14 | echo "Need a string to search for!"; 15 | return 1; 16 | fi 17 | # if FZF_PREVIEW_WINDOW is undefined, quoting it breaks the script 18 | # shellcheck disable=SC2086 19 | rg --files-with-matches --no-messages "$1" | fzf --preview-window "$FZF_PREVIEW_WINDOW" --preview "rg --ignore-case --pretty --context 10 '$1' {}" 20 | } 21 | 22 | [[ -z "$FZF_PREVIEW_WINDOW" ]] && export FZF_PREVIEW_WINDOW=':hidden' 23 | 24 | command -v rg >/dev/null 25 | # shellcheck disable=SC2181 26 | if [[ $? -eq 0 ]]; then 27 | # shellcheck disable=SC2068 28 | fif $@ 29 | else 30 | echo "Can't find ripgrep (rg). Please install it" 31 | exit 1 32 | fi 33 | -------------------------------------------------------------------------------- /bin/fzf-brew-cask-install: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Original source: https://bluz71.github.io/2018/11/26/fuzzy-finding-in-bash-with-fzf.html 4 | 5 | set -o pipefail 6 | if [[ -n "$DEBUG" ]]; then 7 | set -x 8 | fi 9 | 10 | fail() { 11 | printf '%s\n' "$1" >&2 ## Send message to stderr. Exclude >&2 if you don't want it that way. 12 | exit "${2-1}" ## Return a code specified by $2 or 1 by default. 13 | } 14 | 15 | has() { 16 | which "$@" > /dev/null 2>&1 17 | } 18 | 19 | if ! has brew; then 20 | fail "Can't find brew in your PATH" 21 | fi 22 | 23 | # Install or open the webpage for the selected application 24 | # using brew cask search as input source 25 | # and display a info quickview window for the currently marked application 26 | fzf-brew-cask-install() { 27 | token=$(brew search --casks | fzf-tmux --query="$1" +m --preview 'brew cask info {}') 28 | 29 | if [ "x$token" != "x" ] 30 | then 31 | echo "(I)nstall or open the (h)omepage of $token" 32 | read -r input 33 | if [ "$input" = "i" ] || [ "$input" = "I" ]; then 34 | brew cask install "$token" 35 | fi 36 | if [ "$input" = "h" ] || [ "$input" = "H" ]; then 37 | brew cask home "$token" 38 | fi 39 | fi 40 | } 41 | # shellcheck disable=SC2068 42 | fzf-brew-install $@ 43 | -------------------------------------------------------------------------------- /bin/fzf-brew-cask-uninstall: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Original source: https://bluz71.github.io/2018/11/26/fuzzy-finding-in-bash-with-fzf.html 4 | 5 | set -o pipefail 6 | if [[ -n "$DEBUG" ]]; then 7 | set -x 8 | fi 9 | 10 | fail() { 11 | printf '%s\n' "$1" >&2 ## Send message to stderr. Exclude >&2 if you don't want it that way. 12 | exit "${2-1}" ## Return a code specified by $2 or 1 by default. 13 | } 14 | 15 | has() { 16 | which "$@" > /dev/null 2>&1 17 | } 18 | 19 | if ! has brew; then 20 | fail "Can't find brew in your PATH" 21 | fi 22 | 23 | # Uninstall or open the webpage for the selected application 24 | # using brew list as input source (all brew cask installed applications) 25 | # and display a info quickview window for the currently marked application 26 | fzf-brew-cask-uninstall() { 27 | local token 28 | token=$(brew cask list | fzf-tmux --query="$1" +m --preview 'brew cask info {}') 29 | 30 | if [ "x$token" != "x" ] 31 | then 32 | echo "(U)ninstall or open the (h)omepage of $token" 33 | read -r input 34 | if [ "$input" = "u" ] || [ "$input" = "U" ]; then 35 | brew cask uninstall "$token" 36 | fi 37 | if [ "$input" = "h" ] || [ "$token" = "h" ]; then 38 | brew cask home "$token" 39 | fi 40 | fi 41 | } 42 | 43 | # shellcheck disable=SC2068 44 | fzf-brew-cask-uninstall $@ 45 | -------------------------------------------------------------------------------- /bin/fzf-brew-install: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Original source: https://bluz71.github.io/2018/11/26/fuzzy-finding-in-bash-with-fzf.html 4 | 5 | set -o pipefail 6 | if [[ -n "$DEBUG" ]]; then 7 | set -x 8 | fi 9 | 10 | fail() { 11 | printf '%s\n' "$1" >&2 ## Send message to stderr. Exclude >&2 if you don't want it that way. 12 | exit "${2-1}" ## Return a code specified by $2 or 1 by default. 13 | } 14 | 15 | has() { 16 | which "$@" > /dev/null 2>&1 17 | } 18 | 19 | if ! has brew; then 20 | fail "Can't find brew in your PATH" 21 | fi 22 | 23 | # Install (one or multiple) selected application(s) 24 | # using "brew search" as source input 25 | function fzf-brew-install(){ 26 | # shellcheck disable=SC2068 27 | inst=$(brew search $@ | fzf -m --preview 'brew info {}') 28 | 29 | if [[ $inst ]]; then 30 | for prog in $inst 31 | do 32 | brew install "$prog" 33 | done 34 | fi 35 | } 36 | 37 | # shellcheck disable=SC2068 38 | fzf-brew-install $@ 39 | -------------------------------------------------------------------------------- /bin/fzf-brew-uninstall: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Original source: https://bluz71.github.io/2018/11/26/fuzzy-finding-in-bash-with-fzf.html 4 | 5 | set -o pipefail 6 | if [[ -n "$DEBUG" ]]; then 7 | set -x 8 | fi 9 | 10 | fail() { 11 | printf '%s\n' "$1" >&2 ## Send message to stderr. Exclude >&2 if you don't want it that way. 12 | exit "${2-1}" ## Return a code specified by $2 or 1 by default. 13 | } 14 | 15 | has() { 16 | which "$@" > /dev/null 2>&1 17 | } 18 | 19 | if ! has brew; then 20 | fail "Can't find brew in your PATH" 21 | fi 22 | 23 | # Delete (one or multiple) selected application(s) 24 | fzf-brew-uninstall() { 25 | uninst=$(brew leaves | fzf -m --preview 'brew info {}') 26 | 27 | if [[ $uninst ]]; then 28 | for prog in $uninst 29 | do 30 | brew uninstall "$prog" 31 | done 32 | fi 33 | } 34 | 35 | # shellcheck disable=SC2068 36 | fzf-brew-uninstall $@ 37 | -------------------------------------------------------------------------------- /bin/fzf-brew-update: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Original source: https://bluz71.github.io/2018/11/26/fuzzy-finding-in-bash-with-fzf.html 4 | 5 | set -o pipefail 6 | if [[ -n "$DEBUG" ]]; then 7 | set -x 8 | fi 9 | 10 | fail() { 11 | printf '%s\n' "$1" >&2 ## Send message to stderr. Exclude >&2 if you don't want it that way. 12 | exit "${2-1}" ## Return a code specified by $2 or 1 by default. 13 | } 14 | 15 | has() { 16 | which "$@" > /dev/null 2>&1 17 | } 18 | 19 | if ! has brew; then 20 | fail "Can't find brew in your PATH" 21 | fi 22 | 23 | # Update (one or multiple) selected application(s) 24 | brew-update-plugin() { 25 | upd=$(brew leaves | fzf -m --preview 'brew info {}') 26 | 27 | if [[ $upd ]]; then 28 | # shellcheck disable=SC2086 29 | for prog in $upd 30 | do 31 | brew upgrade $prog 32 | done 33 | fi 34 | } 35 | 36 | # shellcheck disable=SC2068 37 | brew-update-plugin $@ 38 | -------------------------------------------------------------------------------- /bin/fzf-browse-pods: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Based on https://github.com/junegunn/fzf/blob/master/ADVANCED.md#using-fzf-as-the-secondary-filter 4 | 5 | set -o pipefail 6 | if [[ -n "$DEBUG" ]]; then 7 | # shellcheck disable=SC2086 8 | if [[ "$(echo $DEBUG | tr '[:upper:]' '[:lower:]')" == "verbose" ]]; then 9 | set -x 10 | fi 11 | fi 12 | 13 | function debug() { 14 | if [[ -n "$DEBUG" ]]; then 15 | echo "$@" 16 | fi 17 | } 18 | 19 | function echo-stderr() { 20 | echo "$@" 1>&2 ## Send message to stderr. 21 | } 22 | 23 | function fail() { 24 | printf '%s\n' "$1" >&2 ## Send message to stderr. Exclude >&2 if you don't want it that way. 25 | exit "${2-1}" ## Return a code specified by $2 or 1 by default. 26 | } 27 | 28 | function has() { 29 | # Check if a command is in $PATH 30 | which "$@" > /dev/null 2>&1 31 | } 32 | 33 | function get-settings() { 34 | SETTING_ENV_NAME=${SETTING_ENV_NAME:-'default-value'} 35 | } 36 | 37 | function check-dependencies() { 38 | debug "Checking dependencies..." 39 | # shellcheck disable=SC2041 40 | # Placeholders for whatever programs you really need 41 | for p in 'fzf' 'kubectl' 'sed' 42 | do 43 | if ! has $p; then 44 | fail "Can't find $p in your $PATH" 45 | else 46 | debug "- Found $p" 47 | fi 48 | done 49 | } 50 | 51 | function my-name() { 52 | basename "$0" 53 | } 54 | 55 | function usage() { 56 | echo "Usage: $(my-name)" 57 | echo 58 | echo "Use fzf to browse running k8s pods" 59 | } 60 | 61 | # shellcheck disable=SC2120,SC2016 62 | pods() { 63 | : | command='kubectl get pods --all-namespaces' fzf \ 64 | --info=inline --layout=reverse --header-lines=1 \ 65 | --prompt "$(kubectl config current-context | sed 's/-context$//')> " \ 66 | --header $'╱ Enter (kubectl exec) ╱ CTRL-O (open log in editor) ╱ CTRL-R (reload) ╱\n\n' \ 67 | --bind 'start:reload:$command' \ 68 | --bind 'ctrl-r:reload:$command' \ 69 | --bind 'ctrl-/:change-preview-window(80%,border-bottom|hidden|)' \ 70 | --bind 'enter:execute:kubectl exec -it --namespace {1} {2} -- bash > /dev/tty' \ 71 | --bind 'ctrl-o:execute:${EDITOR:-vim} <(kubectl logs --all-containers --namespace {1} {2}) > /dev/tty' \ 72 | --preview-window up:follow \ 73 | --preview 'kubectl logs --follow --all-containers --tail=10000 --namespace {1} {2}' "$@" 74 | } 75 | 76 | check-dependencies 77 | # shellcheck disable=SC2119 78 | pods 79 | -------------------------------------------------------------------------------- /bin/fzf-find-edit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Original source: https://bluz71.github.io/2018/11/26/fuzzy-finding-in-bash-with-fzf.html 4 | 5 | set -o pipefail 6 | if [[ -n "$DEBUG" ]]; then 7 | set -x 8 | fi 9 | 10 | fail() { 11 | printf '%s\n' "$1" >&2 ## Send message to stderr. Exclude >&2 if you don't want it that way. 12 | exit "${2-1}" ## Return a code specified by $2 or 1 by default. 13 | } 14 | 15 | has() { 16 | which "$@" > /dev/null 2>&1 17 | } 18 | 19 | # Functions from https://bluz71.github.io/2018/11/26/fuzzy-finding-in-bash-with-fzf.html 20 | if has bat; then 21 | fzf-find-edit() { 22 | file=$( 23 | fzf --query="$1" --no-multi --select-1 --exit-0 \ 24 | --preview 'bat --color=always --line-range :500 {}' 25 | ) 26 | if [[ -n "$file" ]]; then 27 | $EDITOR "$file" 28 | fi 29 | } 30 | else 31 | # No bat installed, so use head 32 | fzf-find-edit() { 33 | file=$( 34 | fzf --query="$1" --no-multi --select-1 --exit-0 \ 35 | --preview 'head -100 {}' 36 | ) 37 | if [[ -n "$file" ]]; then 38 | $EDITOR "$file" 39 | fi 40 | } 41 | fi 42 | 43 | # shellcheck disable=SC2068 44 | fzf-find-edit $@ 45 | -------------------------------------------------------------------------------- /bin/fzf-git-branch: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | # 3 | # Original Author: Mark Nielsen 4 | # Original source: https://polothy.github.io/post/2019-08-19-fzf-git-checkout/ 5 | 6 | set -o pipefail 7 | if [[ -n "$DEBUG" ]]; then 8 | set -x 9 | fi 10 | 11 | fail() { 12 | printf '%s\n' "$1" >&2 ## Send message to stderr. Exclude >&2 if you don't want it that way. 13 | exit "${2-1}" ## Return a code specified by $2 or 1 by default. 14 | } 15 | 16 | has() { 17 | which "$@" > /dev/null 2>&1 18 | } 19 | 20 | in_git_repo() { 21 | git rev-parse HEAD > /dev/null 2>&1 22 | } 23 | 24 | if ! in_git_repo; then 25 | fail "Not in a git repository" 26 | fi 27 | 28 | if ! has fzf; then 29 | fail "Can't find fzf in your PATH" 30 | fi 31 | 32 | if ! has git; then 33 | fail "Can't find git in your PATH" 34 | fi 35 | 36 | function fzf-git-branch(){ 37 | git rev-parse HEAD > /dev/null 2>&1 || return 38 | 39 | # shellcheck disable=SC2016 40 | git branch --color=always --all --sort=-committerdate | 41 | grep -v HEAD | 42 | fzf --height 50% --ansi --no-multi --preview-window right:65% \ 43 | --preview 'git log -n 50 --color=always --date=short --pretty="format:%C(auto)%cd %h%d %s" $(sed "s/.* //" <<< {})' | 44 | sed "s/.* //" 45 | } 46 | 47 | # shellcheck disable=SC2068 48 | fzf-git-branch $@ 49 | -------------------------------------------------------------------------------- /bin/fzf-git-checkout: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | # 3 | # Original Author: Mark Nielsen 4 | # Original source: https://polothy.github.io/post/2019-08-19-fzf-git-checkout/ 5 | 6 | set -o pipefail 7 | if [[ -n "$DEBUG" ]]; then 8 | set -x 9 | fi 10 | 11 | fail() { 12 | printf '%s\n' "$1" >&2 ## Send message to stderr. Exclude >&2 if you don't want it that way. 13 | exit "${2-1}" ## Return a code specified by $2 or 1 by default. 14 | } 15 | 16 | has() { 17 | which "$@" > /dev/null 2>&1 18 | } 19 | 20 | in_git_repo() { 21 | git rev-parse HEAD > /dev/null 2>&1 22 | } 23 | 24 | if ! in_git_repo; then 25 | fail "Not in a git repository" 26 | fi 27 | 28 | if ! has fzf; then 29 | fail "Can't find fzf in your PATH" 30 | fi 31 | 32 | if ! has git; then 33 | fail "Can't find git in your PATH" 34 | fi 35 | 36 | fzf-git-checkout() { 37 | in_git_repo || return 38 | 39 | local branch 40 | 41 | branch=$(fzf-git-branch) 42 | if [[ "$branch" = "" ]]; then 43 | echo "No branch selected." 44 | return 45 | fi 46 | 47 | # If branch name starts with 'remotes/' then it is a remote branch. By 48 | # using --track and a remote branch name, it is the same as: 49 | # git checkout -b branchName --track origin/branchName 50 | if [[ "$branch" = 'remotes/'* ]]; then 51 | git checkout --track $branch 52 | else 53 | git checkout $branch; 54 | fi 55 | } 56 | 57 | # shellcheck disable=SC2068 58 | fzf-git-checkout $@ 59 | -------------------------------------------------------------------------------- /bin/fzf-grep-edit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Original source: https://bluz71.github.io/2018/11/26/fuzzy-finding-in-bash-with-fzf.html 4 | 5 | set -o pipefail 6 | if [[ -n "$DEBUG" ]]; then 7 | set -x 8 | fi 9 | 10 | fail() { 11 | printf '%s\n' "$1" >&2 ## Send message to stderr. Exclude >&2 if you don't want it that way. 12 | exit "${2-1}" ## Return a code specified by $2 or 1 by default. 13 | } 14 | 15 | has() { 16 | which "$@" > /dev/null 2>&1 17 | } 18 | 19 | if ! has rg; then 20 | fail "Can't find rg - install ripgrep and try again." 21 | fi 22 | 23 | if has bat; then 24 | fzf-grep-edit(){ 25 | if [[ $# == 0 ]]; then 26 | echo 'Error: search term was not provided.' 27 | return 28 | fi 29 | match=$( 30 | rg --color=never --line-number "$1" | 31 | fzf --no-multi --delimiter : \ 32 | --preview "bat --color=always --line-range {2}: {1}" 33 | ) 34 | file=$(echo "$match" | cut -d':' -f1) 35 | if [[ -n $file ]]; then 36 | # shellcheck disable=SC2046 37 | $EDITOR "$file" +$(echo "$match" | cut -d':' -f2) 38 | fi 39 | } 40 | else 41 | fzf-grep-edit(){ 42 | if [[ $# == 0 ]]; then 43 | echo 'Error: search term was not provided.' 44 | return 45 | fi 46 | match=$( 47 | rg --color=never --line-number "$1" | 48 | fzf --no-multi --delimiter : \ 49 | --preview "head -100 {2}: {1}" 50 | ) 51 | file=$(echo "$match" | cut -d':' -f1) 52 | if [[ -n $file ]]; then 53 | # shellcheck disable=SC2046 54 | $EDITOR "$file" +$(echo "$match" | cut -d':' -f2) 55 | fi 56 | } 57 | fi 58 | # shellcheck disable=SC2068 59 | fzf-grep-edit $@ 60 | -------------------------------------------------------------------------------- /bin/fzf-kill: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Original source: https://bluz71.github.io/2018/11/26/fuzzy-finding-in-bash-with-fzf.html 4 | 5 | set -o pipefail 6 | if [[ -n "$DEBUG" ]]; then 7 | set -x 8 | fi 9 | 10 | fzf-kill() { 11 | local pid_col 12 | local pids 13 | 14 | if [[ $(uname) = Linux ]]; then 15 | pid_col=2 16 | pids=$( 17 | ps -f -u "$USER" | sed 1d | fzf --multi | tr -s "[:blank:]" | cut -d' ' -f"$pid_col" 18 | ) 19 | elif [[ $(uname) = Darwin ]]; then 20 | pid_col=3; 21 | pids=$( 22 | ps -f -u "$USER" | sed 1d | fzf --multi | tr -s "[:blank:]" | cut -d' ' -f"$pid_col" 23 | ) 24 | elif [[ $(uname) = FreeBSD ]]; then 25 | pid_col=2 26 | pids=$( 27 | ps -axu -U "$USER" | sed 1d | fzf --multi | tr -s "[:blank:]" | cut -d' ' -f"$pid_col" 28 | ) 29 | else 30 | echo 'Error: unknown platform' 31 | return 32 | fi 33 | 34 | if [[ -n "$pids" ]]; then 35 | echo "$pids" | xargs kill -9 "$@" 36 | fi 37 | } 38 | 39 | # shellcheck disable=SC2068 40 | fzf-kill $@ 41 | -------------------------------------------------------------------------------- /bin/fzf-vscode: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Based on Mark's script posted to hangops, which in turn was based on 4 | # the example at https://github.com/junegunn/fzf/blob/master/ADVANCED.md#ripgrep-integration 5 | # 6 | # Copyright 2023, Mark Carey 7 | # 8 | # shellcheck disable=SC2086 9 | # 10 | # 1. Search for text in files using Ripgrep 11 | # 2. Interactively narrow down the list using fzf 12 | # 3. Open the file in vscode 13 | 14 | set -euo pipefail 15 | if [[ -n "$DEBUG" ]]; then 16 | set -x 17 | fi 18 | 19 | function debug() { 20 | if [[ -n "$DEBUG" ]]; then 21 | echo "$@" 22 | fi 23 | } 24 | 25 | function echo-stderr() { 26 | echo "$@" 1>&2 ## Send message to stderr. 27 | } 28 | 29 | function fail() { 30 | printf '%s\n' "$1" >&2 ## Send message to stderr. Exclude >&2 if you don't want it that way. 31 | exit "${2-1}" ## Return a code specified by $2 or 1 by default. 32 | } 33 | 34 | function has() { 35 | # Check if a command is in $PATH 36 | which "$@" > /dev/null 2>&1 37 | } 38 | 39 | # shellcheck disable=SC2016 40 | function check-dependencies() { 41 | if ! has code; then 42 | fail 'Could not find code in your $PATH.' 43 | fi 44 | if ! has fzf; then 45 | fail 'Could not find fzf in your $PATH. Installation instructions are at https://github.com/junegunn/fzf' 46 | fi 47 | if ! has rg; then 48 | fail 'Could not find rg in your $PATH. Installation instructions are at https://github.com/BurntSushi/ripgrep' 49 | fi 50 | } 51 | 52 | check-dependencies 53 | 54 | while getopts n OPTION 55 | do 56 | case "${OPTION}" in 57 | n) NEW_WINDOW="--new-window";; 58 | *) echo "ERROR: we only support -n" && exit 1;; 59 | esac 60 | done 61 | shift $((OPTIND-1)) 62 | 63 | : "${NEW_WINDOW:=""}" 64 | 65 | ARGLIST="" 66 | while IFS=: read -ra SELECTED; do 67 | if [ "${#SELECTED[@]}" -gt 0 ]; then 68 | ARGLIST+="--goto ${SELECTED[0]}:${SELECTED[1]} " 69 | fi 70 | done < <( 71 | rg --color=always --line-number --no-heading --smart-case "${*:-}" | 72 | fzf --ansi \ 73 | --color "hl:-1:underline,hl+:-1:underline:reverse" \ 74 | --delimiter : \ 75 | --multi \ 76 | --preview 'bat --color=always {1} --highlight-line {2}' \ 77 | --preview-window 'up,60%,border-bottom,+{2}+3/3,~3' 78 | ) 79 | if [ -n "${ARGLIST}" ]; then 80 | code ${NEW_WINDOW} ${ARGLIST} 81 | fi 82 | -------------------------------------------------------------------------------- /bin/lessfilter-fzf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | # 3 | # lessfilter-fzf is a `less` pre-processor intended (but not strictly required) to work together with `lesspipe.sh`. 4 | # 5 | # Make the most of it by installing lesspipe.sh, e.g. `brew install lesspipe`, see https://github.com/wofr06/lesspipe 6 | # When `lesspipe.sh` is available, it will be used to view a wide range of file formats (directories, images, PDFs, 7 | # CSVs, source code,...). 8 | # 9 | # In case that you are not using your own custom `less` pre-processor, it can also be quite handy to use this one. You 10 | # can export LESSOPEN in your init scripts (.bashrc/.zshrc or similar): 11 | # 12 | # export LESSOPEN='| lessfilter-fzf %s' 13 | # 14 | # Ultimately, lesspipe.sh will honor your own `lessfilter` if found in your PATH, leading to the following execution: 15 | # lessfilter-fzf > lesspipe.sh > lessfilter 16 | # 17 | # Required tools: 18 | # - eza 19 | # - bat 20 | # - chafa, exiftool 21 | # - lesspipe.sh (recommended) 22 | # 23 | # Credits: This script (beyond any modification) was taken from https://github.com/Aloxaf/fzf-tab/wiki/Preview 24 | # 25 | 26 | EXIT_UNHANDLED=10 27 | 28 | has_cmd() { 29 | command -v "$1" >/dev/null 2>&1 30 | } 31 | 32 | mime=$(file -bL --mime-type "$1") # e.g. 'application/pdf' 33 | category=${mime%%/*} 34 | # shellcheck disable=SC2034 # left for completion 35 | kind=${mime##*/} 36 | 37 | if [ -d "$1" ] && has_cmd eza; then 38 | eza --git --header --long --color=always --icons "$1" 39 | elif [ "$category" = image ] && has_cmd chafa && has_cmd exiftool; then 40 | chafa "$1" 41 | exiftool "$1" 42 | elif has_cmd lesspipe.sh; then 43 | # At the time of writing, `lesspipe.sh` does not use `eza` and `chafa`, it just uses `ls` and `exiftool`. It 44 | # will ultimately rely on `less` as a sane fallback. 45 | lesspipe.sh "$1" 2>/dev/null 46 | elif [ "$category" = text ] && has_cmd bat; then # <-- give priority to lesspipe.sh if available 47 | bat "$1" 48 | else 49 | exit $EXIT_UNHANDLED 50 | fi 51 | -------------------------------------------------------------------------------- /bin/pr-list: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Select a PR with fzf 4 | # 5 | # Copyright 2021, Joe Block 6 | 7 | set -o pipefail 8 | if [[ -n "$DEBUG" ]]; then 9 | set -x 10 | fi 11 | 12 | function debug() { 13 | if [[ -n "$DEBUG" ]]; then 14 | echo "$@" 15 | fi 16 | } 17 | 18 | function fail() { 19 | printf '%s\n' "$1" >&2 ## Send message to stderr. Exclude >&2 if you don't want it that way. 20 | exit "${2-1}" ## Return a code specified by $2 or 1 by default. 21 | } 22 | 23 | function has() { 24 | # Check if a command is in $PATH 25 | which "$@" > /dev/null 2>&1 26 | } 27 | 28 | if ! has gh; then 29 | fail "Cannot find 'gh' in your PATH" 30 | fi 31 | 32 | if ! has jq; then 33 | fail "Cannot find 'jq' in your PATH" 34 | fi 35 | 36 | if ! has fzf; then 37 | fail "Cannot find 'fzf' in your PATH" 38 | fi 39 | 40 | gh api --paginate 'repos/:owner/:repo/pulls?state=open' | jq -r '.[] | [.number, .user.login, .title] | @tsv' | fzf 41 | -------------------------------------------------------------------------------- /bin/tm: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # tm - create new tmux session, or switch to existing one. Works from within tmux too. (@bag-man) 4 | # `tm` will allow you to select your tmux session via fzf. 5 | # `tm irc` will attach to the irc session (if it exists), else it will create it. 6 | # 7 | # Source: https://github.com/junegunn/fzf/wiki/examples 8 | 9 | set -o pipefail 10 | if [[ -n "$DEBUG" ]]; then 11 | set -x 12 | fi 13 | 14 | function fail() { 15 | printf '%s\n' "$1" >&2 ## Send message to stderr. Exclude >&2 if you don't want it that way. 16 | exit "${2-1}" ## Return a code specified by $2 or 1 by default. 17 | } 18 | 19 | function has() { 20 | # Check if a command is in $PATH 21 | which "$@" > /dev/null 2>&1 22 | } 23 | 24 | tm() { 25 | [[ -n "$TMUX" ]] && change="switch-client" || change="attach-session" 26 | if [ "$1" ]; then 27 | tmux "$change" -t "$1" 2>/dev/null || (tmux new-session -d -s "$1" && tmux "$change" -t "$1"); return 28 | fi 29 | session=$(tmux list-sessions -F "#{session_name}" 2>/dev/null | fzf --exit-0) && tmux "$change" -t "$session" || echo "No sessions found." 30 | } 31 | 32 | if has tmux; then 33 | tm "$@" 34 | else 35 | fail "Can't find tmux in $PATH" 36 | fi 37 | -------------------------------------------------------------------------------- /bin/tmux-kill: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | # 3 | # tmux-kill-session - kills a tmux session that you select via fzf. 4 | # 5 | # Source: https://github.com/junegunn/fzf/wiki/examples 6 | setopt re_match_pcre 7 | 8 | set -o pipefail 9 | if [[ -n "$DEBUG" ]]; then 10 | set -x 11 | fi 12 | 13 | function fail() { 14 | printf '%s\n' "$1" >&2 ## Send message to stderr. Exclude >&2 if you don't want it that way. 15 | exit "${2-1}" ## Return a code specified by $2 or 1 by default. 16 | } 17 | 18 | function has() { 19 | # Check if a command is in $PATH 20 | which "$@" > /dev/null 2>&1 21 | } 22 | 23 | tmuxkillf () { 24 | local sessions 25 | sessions="$(tmux ls|fzf --exit-0 --multi)" || return $? 26 | local i 27 | for i in "${(f@)sessions}" 28 | do 29 | [[ $i =~ '([^:]*):.*' ]] && { 30 | echo "Killing $match[1]" 31 | tmux kill-session -t "$match[1]" 32 | } 33 | done 34 | } 35 | if has tmux; then 36 | tmuxkillf "$@" 37 | else 38 | fail "Can't find tmux in $PATH" 39 | fi 40 | -------------------------------------------------------------------------------- /bin/tmux-search: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # tm-search [FUZZY PATTERN] - Select selected tmux session 4 | # - Bypass fuzzy finder if there's only one match (--select-1) 5 | # - Exit if there's no match (--exit-0) 6 | # 7 | # From https://github.com/junegunn/fzf/wiki/examples 8 | 9 | set -o pipefail 10 | if [[ -n "$DEBUG" ]]; then 11 | set -x 12 | fi 13 | 14 | function debug() { 15 | if [[ -n "$DEBUG" ]]; then 16 | echo "$@" 17 | fi 18 | } 19 | 20 | function fail() { 21 | printf '%s\n' "$1" >&2 ## Send message to stderr. Exclude >&2 if you don't want it that way. 22 | exit "${2-1}" ## Return a code specified by $2 or 1 by default. 23 | } 24 | 25 | function has() { 26 | # Check if a command is in $PATH 27 | which "$@" > /dev/null 2>&1 28 | } 29 | 30 | tm-search() { 31 | local session 32 | session=$(tmux list-sessions -F "#{session_name}" | \ 33 | fzf --query="$1" --select-1 --exit-0) && 34 | tmux switch-client -t "$session" 35 | } 36 | 37 | if has tmux; then 38 | tm-search "$@" 39 | else 40 | fail "Can't find tmux in $PATH" 41 | fi 42 | -------------------------------------------------------------------------------- /bin/vagrant-box-search: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # List all vagrant boxes available in the system including its status, and try to access the selected one via ssh 4 | # 5 | # From the fzf wiki - https://github.com/junegunn/fzf/wiki/examples 6 | 7 | 8 | set -o pipefail 9 | if [[ -n "$DEBUG" ]]; then 10 | set -x 11 | fi 12 | 13 | function debug() { 14 | if [[ -n "$DEBUG" ]]; then 15 | echo "$@" 16 | fi 17 | } 18 | 19 | function fail() { 20 | printf '%s\n' "$1" >&2 ## Send message to stderr. Exclude >&2 if you don't want it that way. 21 | exit "${2-1}" ## Return a code specified by $2 or 1 by default. 22 | } 23 | 24 | function has() { 25 | # Check if a command is in $PATH 26 | which "$@" > /dev/null 2>&1 27 | } 28 | 29 | vagrant-search(){ 30 | #List all vagrant boxes available in the system including its status, and try to access the selected one via ssh 31 | # shellcheck disable=SC2164,SC2046,SC2002 32 | cd $(cat "$machine_index" | jq '.machines[] | {name, vagrantfile_path, state}' | jq '.name + "," + .state + "," + .vagrantfile_path'| sed 's/^"\(.*\)"$/\1/'| column -s, -t | sort -rk 2 | fzf | awk '{print $3}'); exec vagrant ssh 33 | } 34 | 35 | machine_index=~/.vagrant.d/data/machine-index/index 36 | 37 | if ! has jq; then 38 | fail "Can't find jq in $PATH" 39 | fi 40 | if ! has vagrant; then 41 | fail "Can't find vagrant in $PATH" 42 | fi 43 | if [[ ! -r "$machine_index" ]]; then 44 | fail "Can't read $machine_index" 45 | fi 46 | 47 | vagrant-search "$@" 48 | -------------------------------------------------------------------------------- /completions/_fzf: -------------------------------------------------------------------------------- 1 | #compdef fzf 2 | 3 | _arguments \ 4 | '*:file:_files' \ 5 | {-x,--extended}'[Extended-search mode. Since 0. 10. 9, this is enabled by default.]' \ 6 | {-e,--exact}'[Enable exact-match.]' \ 7 | '-i[Case-insensitive match (default: smart-case match).]' \ 8 | '--literal[Do not normalize latin script letters for matching.]' \ 9 | '--algo[Fuzzy matching algorithm (default: v2) .]' \ 10 | {-n,--nth}'[Comma-separated list of field index expressions for limiting search scope.]' \ 11 | '--with-nth[Transform the presentation of each line using field index expressions.]' \ 12 | {-d,--delimiter}'[Field delimiter regex for --nth and --with-nth (default: AWK-style).]' \ 13 | '--phony[Do not perform search.]' \ 14 | '--no-sort[Do not sort the result.]' \ 15 | '--tac[Reverse the order of the input . RS e. g.]' \ 16 | '--tiebreak[Comma-separated list of sort criteria to apply when the scores are tied. br .]' \ 17 | {-m,--multi}'[Enable multi-select with tab/shift-tab.]' \ 18 | '--no-multi[Disable multi-select.]' \ 19 | '--no-mouse[Disable mouse.]' \ 20 | '--bind[Comma-separated list of custom key bindings.]' \ 21 | '--cycle[Enable cyclic scroll.]' \ 22 | '--keep-right[Keep the right end of the line visible when it'"'"'s too long.]' \ 23 | '--no-hscroll[Disable horizontal scroll.]' \ 24 | '--hscroll-off[Number of screen columns to keep to the right of the highlighted substring (d…]' \ 25 | '--filepath-word[Make word-wise movements and actions respect path separators.]' \ 26 | '--jump-labels[Label characters for jump and jump-accept . SS Layout.]' \ 27 | '--height[Display fzf window below the cursor with the given height instead of using th…]' \ 28 | '--min-height[Minimum height when --height is given in percent (default: 10).]' \ 29 | '--layout[Choose the layout (default: default) .]' \ 30 | '--reverse[A synonym for --layout=reverse.]' \ 31 | '--border[Draw border around the finder .]' \ 32 | '--no-unicode[Use ASCII characters instead of Unicode box drawing characters to draw border.]' \ 33 | '--margin[Comma-separated expression for margins around the finder. br . br .]' \ 34 | '--info[Determines the display style of finder info.]' \ 35 | '--no-info[A synonym for --info=hidden.]' \ 36 | '--prompt[Input prompt (default: '"'"'> '"'"').]' \ 37 | '--pointer[Pointer to the current line (default: '"'"'>'"'"').]' \ 38 | '--marker[Multi-select marker (default: '"'"'>'"'"').]' \ 39 | '--header[The given string will be printed as the sticky header.]' \ 40 | '--header-lines[The first N lines of the input are treated as the sticky header.]' \ 41 | '--ansi[Enable processing of ANSI color codes.]' \ 42 | '--tabstop[Number of spaces for a tab character (default: 8).]' \ 43 | '--color[Color configuration.]' \ 44 | '--no-bold[Do not use bold text.]' \ 45 | '--black[Use black background . SS History.]' \ 46 | '--history[Load search history from the specified file and update the file on completion.]' \ 47 | '--history-size[Maximum number of entries in the history file (default: 1000).]' \ 48 | '--preview[Execute the given command for the current line and display the result on the …]' \ 49 | '--preview-window[Determines the layout of the preview window.]' \ 50 | {-q,--query}'[Start the finder with the given query.]' \ 51 | {-1,--select-1}'[Automatically select the only match.]' \ 52 | {-0,--exit-0}'[Exit immediately when there'"'"'s no match.]' \ 53 | {-f,--filter}'[Filter mode. Do not start interactive finder.]' \ 54 | '--print-query[Print query as the first line.]' \ 55 | '--expect[Comma-separated list of keys that can be used to complete fzf in addition to …]' \ 56 | '--read0[Read input delimited by ASCII NUL characters instead of newline characters.]' \ 57 | '--print0[Print output delimited by ASCII NUL characters instead of newline characters.]' \ 58 | '--no-clear[Do not clear finder interface on exit.]' \ 59 | '--sync[Synchronous search for multi-staged filtering.]' \ 60 | '--version[Display version information and exit.]' \ 61 | '-2[.]' 62 | -------------------------------------------------------------------------------- /fzf-settings.zsh: -------------------------------------------------------------------------------- 1 | # Setup fzf 2 | # --------- 3 | if [[ ! "$PATH" == *${FZF_PATH}/bin* ]]; then 4 | export PATH="$PATH:${FZF_PATH}/bin" 5 | fi 6 | 7 | # Auto-completion 8 | # --------------- 9 | [[ $- == *i* ]] && source "${FZF_PATH}/shell/completion.zsh" 2> /dev/null 10 | 11 | # Key bindings 12 | # ------------ 13 | source "${FZF_PATH}/shell/key-bindings.zsh" 14 | -------------------------------------------------------------------------------- /fzf-zsh-plugin.plugin.zsh: -------------------------------------------------------------------------------- 1 | # Copyright 2020-2024 Joseph Block 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Add our plugin's bin directory to the user's path 16 | local FZF_PLUGIN_BIN="${0:h}/bin" 17 | if [[ ! "$path" == *${FZF_PLUGIN_BIN}* ]]; then 18 | path+=(${FZF_PLUGIN_BIN}) 19 | fi 20 | unset FZF_PLUGIN_BIN 21 | 22 | local FZF_COMPLETIONS_D="$(dirname $0)/completions" 23 | if [[ -d "$FZF_COMPLETIONS_D" ]]; then 24 | export fpath=($FZF_COMPLETIONS_D "${fpath[@]}" ) 25 | fi 26 | unset FZF_COMPLETIONS_D 27 | 28 | function _fzf_has() { 29 | which "$@" > /dev/null 2>&1 30 | } 31 | 32 | function _fzf_debugOut() { 33 | if [[ -n "$DEBUG" ]]; then 34 | echo "$@" 35 | fi 36 | } 37 | 38 | # Install fzf, and enable it for command line history searching and 39 | # file searching. 40 | 41 | # Determine where fzf is installed 42 | local fzf_conf 43 | if [[ -z "$FZF_PATH" ]]; then 44 | FZF_PATH=~/.fzf 45 | fzf_conf=~/.fzf.zsh 46 | else 47 | fzf_conf="$FZF_PATH/fzf.zsh" 48 | fi 49 | unset xdg_path 50 | 51 | # Install fzf into ~ if it hasn't already been installed. 52 | if ! _fzf_has fzf; then 53 | if [[ ! -d $FZF_PATH ]]; then 54 | git clone --depth 1 https://github.com/junegunn/fzf.git $FZF_PATH 55 | $FZF_PATH/install --bin 56 | fi 57 | fi 58 | 59 | # Install some default settings if user doesn't already have fzf 60 | # settings configured. 61 | _fzf_debugOut "fzf_conf: $fzf_conf" 62 | if [[ ! -f $fzf_conf ]]; then 63 | echo "Can't find a fzf configuration file at $fzf_conf, creating a default one" 64 | cp "$(dirname $0)/fzf-settings.zsh" $fzf_conf 65 | fi 66 | 67 | # Source this before we start examining things so we can override the 68 | # defaults cleanly. 69 | [[ -f $fzf_conf ]] && source $fzf_conf 70 | unset fzf_conf 71 | 72 | # Reasonable defaults. Exclude .git directory and the node_modules cesspit. 73 | # Don't step on user's FZF_DEFAULT_COMMAND 74 | if [[ -z "$FZF_DEFAULT_COMMAND" ]]; then 75 | export FZF_DEFAULT_COMMAND='find . -type f -not \( -path "*/.git/*" -o -path "./node_modules/*" \)' 76 | export FZF_ALT_C_COMMAND='find . -type d ( -path .git -o -path node_modules ) -prune' 77 | 78 | if _fzf_has rg; then 79 | # rg is faster than find, so use it instead. 80 | export FZF_DEFAULT_COMMAND='rg --files --hidden --follow --glob "!{.git,node_modules}/**"' 81 | fi 82 | 83 | # If fd command is installed, use it instead of find 84 | _fzf_has 'fd' && _fd_cmd="fd" 85 | _fzf_has 'fdfind' && _fd_cmd="fdfind" 86 | if [[ -n "$_fd_cmd" ]]; then 87 | # Show hidden, and exclude .git and the pigsty node_modules files 88 | export FZF_DEFAULT_COMMAND="$_fd_cmd --hidden --follow --exclude '.git' --exclude 'node_modules'" 89 | export FZF_ALT_C_COMMAND="$FZF_DEFAULT_COMMAND --type d" 90 | 91 | _fzf_compgen_dir() { 92 | eval "$FZF_ALT_C_COMMAND . \"$1\"" 93 | } 94 | 95 | _fzf_compgen_path() { 96 | eval "$FZF_DEFAULT_COMMAND . \"$1\"" 97 | } 98 | fi 99 | unset _fd_cmd 100 | fi 101 | 102 | # Return one of the following preview commands: 103 | # - A basic foolproof preview that will rely on available tools or use fallbacks like `cat`. 104 | # - An advanced preview using a `less` preprocessor, capable of showing a wide range of formats, incl. images, dirs, 105 | # CSVs, and other binary files (depending on available tooling). 106 | _fzf_preview() { 107 | _fzf_preview_pager='cat' 108 | foolproofPreview='cat {}' 109 | if _fzf_has bat; then 110 | _fzf_preview_pager='bat' 111 | foolproofPreview='([[ -f {} ]] && (bat --style=numbers --color=always {} || cat {})) || ([[ -d {} ]] && (tree -C {} | less)) || echo {} 2>/dev/null | head -n 200' 112 | fi 113 | if _fzf_has batcat; then 114 | _fzf_preview_pager='batcat' 115 | foolproofPreview='([[ -f {} ]] && (batcat --style=numbers --color=always {} || cat {})) || ([[ -d {} ]] && (tree -C {} | less)) || echo {} 2>/dev/null | head -n 200' 116 | fi 117 | local preview 118 | [[ "$FZF_PREVIEW_ADVANCED" == true ]] \ 119 | && preview="lessfilter-fzf {}" \ 120 | || preview="$foolproofPreview" 121 | echo "$preview" 122 | } 123 | 124 | # Don't step on user's defined variables. Export to potentially leverage them by other scripts. 125 | [[ -z "$FZF_COLOR_SCHEME" ]] && export FZF_COLOR_SCHEME="--color='hl:148,hl+:154,pointer:032,marker:010,bg+:237,gutter:008'" 126 | [[ -z "$FZF_PREVIEW" ]] && export FZF_PREVIEW="$(_fzf_preview)" 127 | [[ -z "$FZF_PREVIEW_WINDOW" ]] && export FZF_PREVIEW_WINDOW=':hidden' 128 | if [[ -z "$FZF_DEFAULT_OPTS" ]]; then 129 | fzf_default_opts+=( 130 | "--layout=reverse" 131 | "--info=inline" 132 | "--height=80%" 133 | "--multi" 134 | "--preview='${FZF_PREVIEW}'" 135 | "--preview-window='${FZF_PREVIEW_WINDOW}'" 136 | "$FZF_COLOR_SCHEME" 137 | "--prompt='∼ '" 138 | "--pointer='▶'" 139 | "--marker='✓'" 140 | "--bind '?:toggle-preview'" 141 | "--bind 'ctrl-a:select-all'" 142 | "--bind 'ctrl-e:execute(vim {+} >/dev/tty)'" 143 | "--bind 'ctrl-v:execute(code {+})'" 144 | ) 145 | if _fzf_has pbcopy; then 146 | # On macOS, make ^Y yank the selection to the system clipboard. On Linux you can alias pbcopy to `xclip -selection clipboard` or corresponding tool. 147 | fzf_default_opts+=("--bind 'ctrl-y:execute-silent(echo {+} | pbcopy)'") 148 | fi 149 | export FZF_DEFAULT_OPTS=$(printf '%s\n' "${fzf_default_opts[@]}") 150 | fi 151 | 152 | if _fzf_has tree; then 153 | function fzf-change-directory() { 154 | local directory=$( 155 | fd --type d | \ 156 | fzf --query="$1" --no-multi --select-1 --exit-0 \ 157 | --preview 'tree -C {} | head -100' 158 | ) 159 | if [[ -n "$directory" ]]; then 160 | cd "$directory" 161 | fi 162 | } 163 | alias fcd=fzf-change-directory 164 | fi 165 | 166 | alias fkill='fzf-kill' 167 | 168 | if [[ -d $FZF_PATH/man ]]; then 169 | manpath+=(":$FZF_PATH/man") 170 | fi 171 | 172 | if _fzf_has z && ! _fzf_has zoxide; then 173 | unalias z 2> /dev/null 174 | _fzf_z="_z" 175 | (( ${+functions[zshz]} )) && { _fzf_z="zshz"; compdef _zshz z; } 176 | # like normal z when used with arguments but displays an fzf prompt when used without. 177 | function z() { 178 | [ $# -gt 0 ] && $_fzf_z "$*" && return 179 | cd "$($_fzf_z -l 2>&1 | fzf --height 40% --nth 2.. --reverse --inline-info +s --tac --query "${*##-* }" | sed 's/^[0-9,.]* *//')" 180 | } 181 | fi 182 | 183 | export FZF_CTRL_T_COMMAND="${FZF_DEFAULT_COMMAND}" 184 | 185 | # From fzf wiki 186 | # cdf - cd into the directory of the selected file 187 | function cdf() { 188 | local file 189 | local dir 190 | file=$(fzf +m -q "$1") && dir=$(dirname "$file") && cd "$dir" 191 | } 192 | 193 | if _fzf_has pbcopy; then 194 | if _fzf_has ghead; then 195 | function falias { 196 | # Search alias by key or values 197 | local out 198 | out=$(alias | fzf) 199 | echo -n "$(echo -n "${out}" | cut -d= -f2 | ghead -c -1 | pbcopy)" 200 | } 201 | fi 202 | fi 203 | 204 | # Cleanup internal functions 205 | unset -f _fzf_debugOut 206 | unset -f _fzf_has 207 | unset -f _fzf_preview 208 | --------------------------------------------------------------------------------