This extension is a command-line tool that uses the GitHub REST API and fzf
to
interactively search and preview code.
gh find-code [Flags] [Search query]
- Use valid qualifiers to refine the results of your search.
Qualifier | Search query example | Description |
---|---|---|
in |
'in:path zsh' |
matches code where zsh appears in the file path |
user |
'user:ashtom Development' |
files with the word Development only from @ashtom |
org |
'org:cli searcher' |
searches all code in the cli org for searcher |
repo |
'repo:junegunn/fzf FZF_PORT' |
searches only in the junegunn/fzf repo for FZF_PORT |
path |
'path:.github shfmt' |
files with the word shfmt in the .github path |
language |
'language:js "new Proxy"' |
search for the string new Proxy in JavaScript files |
size (>, >=, <, and <=) |
'size:<100 _gnu_generic' |
files smaller than 100 bytes with _gnu_generic |
filename |
'filename:.zshrc GOCACHE' |
search in all filenames .zshrc for GOCACHE |
extension |
'extension:rs "Hello, world!"' |
find .rs files with the string Hello, world! |
Important
The search syntax differs between the WebUI and the REST API, with the latter not supporting regex.
Flags | Description |
---|---|
-l |
limit the number of listed results (default 30, max 100) |
-h |
help |
Key Bindings fzf | Purpose | Keybind Environment Variable |
---|---|---|
? |
toggle help | |
ctrl-b |
open the file in the browser | GHFC_OPEN_BROWSER_KEY |
ctrl-o |
open the file content in the editor | GHFC_OPEN_EDITOR_KEY |
ctrl-p |
prepend "repo:{owner/name}" to the query | GHFC_FILTER_BY_REPO_KEY |
ctrl-r |
reload with up to 100 results | GHFC_RELOAD_KEY |
ctrl-space |
toggle command history | GHFC_TOGGLE_HISTORY_KEY |
ctrl-t |
toggle between Code and Fuzzy search | GHFC_TOGGLE_FUZZY_SEARCH_KEY |
ctrl-x |
open the search query in the browser | GHFC_OPEN_BROWSER_QUERY_KEY |
enter |
open the file in the pager | GHFC_VIEW_CONTENTS_KEY |
tab |
toggle the file preview | GHFC_TOGGLE_PREVIEW_KEY |
esc |
quit |
To avoid interfering with a user's typical keybinds, key bindings can be customized by setting the
corresponding environment variables. For example, to change the key binding for opening a file in
the browser from ctrl-b
to ctrl-k
:
GHFC_OPEN_BROWSER_KEY="ctrl-k" gh find-code
Note
The assigned key must be a valid key listed under AVAILABLE KEYS
in the fzf
man page.
man fzf | less --pattern "AVAILABLE KEYS"
- bat - preview looks better
- curl - sending updates to
fzf
- Fuzzy Finder (fzf) - allow for interaction with listed data
- GitHub command line tool (gh) - get the data from Github
- Python - used to parse and open custom URLs on different operating systems
# install this extension
gh ext install LangLangBart/gh-find-code
# upgrade
gh ext upgrade LangLangBart/gh-find-code
# uninstall
gh ext remove LangLangBart/gh-find-code
Table 1: Environment Variables Utilized
Variable | Purpose | Default |
---|---|---|
BAT_THEME |
Preview theme for syntax highlighting. | Monokai Extended |
EDITOR |
Editor to open selected files. | vim |
PAGER |
Pager for file viewing. | less |
Table 2: Environment Variables Defined and Utilized
Variable | Purpose | Default |
---|---|---|
GHFC_DEBUG_MODE |
Enable debug mode | 0 (Disabled) |
GHFC_HISTORY_FILE |
Custom location | ${XDG_STATE_HOME:-$HOME/.local/state}/gh-find-code/history.txt |
GHFC_HISTORY_LIMIT |
Max number of stored commands | 500 |
- The name
gh find-code
was chosen for its descriptive nature. For frequent use, consider setting up an alias.
# ~/.bashrc or ~/.zshrc
alias ghfc='gh find-code'
# or add a custom 'BAT_THEME'/ 'EDITOR'
alias ghfc='BAT_THEME="Dracula" EDITOR="vim" gh find-code'
- Set
BAT_THEME
to change the preview color scheme:
# To view all default themes
bat --list-themes --color=never
# Recommended themes: 1337, Dracula, gruvbox-dark, Monokai Extended
# To launch this extension with the 'Dracula' theme
BAT_THEME="Dracula" gh find-code
- The extension uses the
EDITOR
environment variable to determine in which editor the selected file will be opened, works withnano
,nvim/vi/vim
, andVSCode
and some of its derivatives (e.g.VSCodium
). - The code from opened files is stored temporarily and is removed when the program ends.
# Set the editor to Visual Studio Code
EDITOR="code" gh find-code
- Scroll the preview in larger steps by adding this snippet to your shell setup.
# ~/.bashrc or ~/.zshrc
# scroll the preview in larger steps with ctrl+w/s
export FZF_DEFAULT_OPTS="
--bind 'ctrl-w:preview-half-page-up,ctrl-s:preview-half-page-down'"
- See
man fzf
forAVAILABLE KEYS
or junegunn/fzf for more details. - NOTE: How to use ALT commands in a terminal on macOS?
- The history file stores successfully completed unique commands.
- Customize history file location and limit:
# Specify a custom location for the history file
GHFC_HISTORY_FILE="/custom/location/history.txt" gh find-code
# Set the maximum number of stored commands to 1000
GHFC_HISTORY_LIMIT="1000" gh find-code
- In rare cases, when the API returns patterns with newline characters,
pcre2grep
,pcregrep
, orrg
will be used to find line numbers if any of them is installed. Otherwise,grep
will be used by default, which will not match patterns containing newlines.
The API may return irrelevant text
matches, which can lead to incorrect line numbers in the entire
document.
I occasionally encounter this issue in readme.md
files when the fragment contains Asian characters
prior to the desired search keyword. For example, when searching for commander.js
in the
nieweidong/fetool
repository, the API may return text matches that are all 12 characters long, but
there seems to be a bug in the GitHub code as it does not correctly count when the search keyword
appears in the fragment. Instead of matching commander.js
, it returns er](https://
.
command gh api search/code --method GET --cache 1h --field per_page=1 \
--header 'Accept: application/vnd.github.text-match+json' \
--raw-field 'q=repo:nieweidong/fetool commander.js' \
--jq '.items[].text_matches[].matches | first | {text}'
{
"text": "er](https://"
}
Here is an example of a proper text
response from the search API:
command gh api search/code --method GET --cache 1h --field per_page=1 \
--header 'Accept: application/vnd.github.text-match+json' \
--raw-field 'q=repo:calvinmetcalf/ltcdr commander.js' \
--jq '.items[].text_matches[].matches | first | {text}'
{
"text": "commander.js"
}
Note
Pre-commit is a multi-language package manager for pre-commit hooks. You specify a list of hooks you want and pre-commit manages the installation and execution of any hook written in any language before every commit.
Source: pre-commit introduction
# install the git hook scripts
pre-commit install --hook-type commit-msg --hook-type pre-commit
# pre-commit installed at .git/hooks/commit-msg
# pre-commit installed at .git/hooks/pre-commit