Skip to content

Commit

Permalink
support modifying default keybindings prototype (#356)
Browse files Browse the repository at this point in the history
* support modifying default keybindings prototype

* Further work on custom keybindings

* Remove keys and just use key
* Handle issue and pr keys
* Handle all keys in universal

* Add comment about key check

handle the pr and issue keys in different cases

* remove universal switch view for per view binds

v4

* fix merge conflicts + format

* readme

* readme

---------

Co-authored-by: Dolev Hadar <[email protected]>
  • Loading branch information
miniscruff and dlvhdr committed Jun 20, 2024
1 parent 0c0c2f6 commit da1221b
Show file tree
Hide file tree
Showing 7 changed files with 384 additions and 120 deletions.
64 changes: 46 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,16 @@
<img src="https://user-images.githubusercontent.com/6196971/198704107-6775a0ba-669d-418b-9ae9-59228aaa84d1.gif" />

## ✨ Features
* 🌅 fully configurable - define sections using github filters
* 🔍 search for both prs and issues
* 📝 customize columns with `hidden`, `width` and `grow` props
* ⚡️ act on prs and issues with checkout, comment, open, merge, diff, etc...
* ⌨️ set custom actions with new keybindings
* 💅 use custom themes
* 🔭 view details about a pr/issue with a detailed sidebar
* 🪟 write multiple configuration files to easily switch between completely different dashboards
* ♻️ set an interval for auto refreshing the dashboard

- 🌅 fully configurable - define sections using github filters
- 🔍 search for both prs and issues
- 📝 customize columns with `hidden`, `width` and `grow` props
- ⚡️ act on prs and issues with checkout, comment, open, merge, diff, etc...
- ⌨️ set custom actions with new keybindings
- 💅 use custom themes
- 🔭 view details about a pr/issue with a detailed sidebar
- 🪟 write multiple configuration files to easily switch between completely different dashboards
- ♻️ set an interval for auto refreshing the dashboard

## 📦 Installation

Expand Down Expand Up @@ -70,19 +71,23 @@
<details>
<summary>How do I get these exact colors and font?</summary>

> I'm using [Alacritty](https://github.com/alacritty/alacritty) with the [tokyonight theme](https://github.com/folke/tokyonight.nvim) and the [Fira Code](https://github.com/ryanoasis/nerd-fonts/tree/master/patched-fonts/FiraCode) Nerd Font.
> For my full setup check out [my dotfiles](https://github.com/dlvhdr/dotfiles/blob/main/.config/alacritty/alacritty.yml).
> I'm using [Alacritty](https://github.com/alacritty/alacritty) with the [tokyonight theme](https://github.com/folke/tokyonight.nvim) and the [Fira Code](https://github.com/ryanoasis/nerd-fonts/tree/master/patched-fonts/FiraCode) Nerd Font.
> For my full setup check out [my dotfiles](https://github.com/dlvhdr/dotfiles/blob/main/.config/alacritty/alacritty.yml).
</details>
## ⚡️ Usage
Run
```sh
gh dash
```
Then press <kbd>?</kbd> for help.
Run `gh dash --help` for more info:
```
Usage:
gh dash [flags]
Expand All @@ -96,6 +101,7 @@ Flags:
## ⚙️ Configuring
A section is defined by a:
- title - shown in the TUI
- filters - how the repo's PRs should be filtered - these are plain [github filters](https://docs.github.com/en/search-github/searching-on-github/searching-issues-and-pull-requests)

Expand Down Expand Up @@ -158,9 +164,31 @@ It can be useful if you want to have a 🧳 work and 👩‍💻 personal dashbo
### ⌨️ Keybindings
Define your own custom keybindings to run bash commands using [Go Templates](https://pkg.go.dev/text/template).
This is available for both PRs and Issues.
You can:
1. Override the builtin commands keybindings
2. Define your own custom keybindings to run bash commands using [Go Templates](https://pkg.go.dev/text/template).
#### Overriding builtin commands keybindings
To override the "checkout" keybinding you can include this in your `config.yml` file:
```yaml
keybindings:
prs:
- key: O
builtin: checkout
```
The list of available builtin commands are:
1. `universal`: up, down, firstLine, lastLine, togglePreview, openGithub, refresh, refreshAll, pageDown, pageUp, nextSection, prevSection, search, copyurl, copyNumber, help, quit
2. `prs`: assign, unassign, comment, diff, checkout, close, ready, reopen, merge, watchChecks, viewIssues
3. `Issues`: assign, unassign, comment, close, reopen, viewPrs
#### Defining custom keybindings
This is available for both PRs and Issues.
For PRs, the available arguments are:
| Argument | Description |
Expand All @@ -179,9 +207,9 @@ For Issues, the available arguments are:
| `RepoPath` | The path to the Repo, using the `config.yml` `repoPaths` key to get the mapping |
| `IssueNumber` | The Issue number |
#### Examples
**Examples**
To review a PR with either Neovim or VSCode include the following in your `config.yml` file:
1. To review a PR with either Neovim or VSCode include the following in your `config.yml` file:
```yaml
repoPaths:
Expand All @@ -202,7 +230,7 @@ keybindings:
gh pr checkout {{.PrNumber}}
```
To pin an issue include the following in your `config.yml` file:
2. To pin an issue include the following in your `config.yml` file:
```yaml
keybindings:
Expand All @@ -222,7 +250,7 @@ An `:owner/:repo` template can be specified as a generic fallback.
```yaml
repoPaths:
:owner/:repo: ~/src/github.com/:owner/:repo # template if you always clone github repos in a consistent location
dlvhdr/*: ~/code/repos/dlvhdr/* # will match dlvhdr/repo-name to ~/code/repos/dlvhdr/repo-name
dlvhdr/*: ~/code/repos/dlvhdr/* # will match dlvhdr/repo-name to ~/code/repos/dlvhdr/repo-name
dlvhdr/gh-dash: ~/code/gh-dash # will not match wildcard and map to specified path
```
Expand Down Expand Up @@ -259,6 +287,7 @@ theme:
You can customize each section's layout as well as the global layout.

For example, to hide the `author` column for **all** PR sections, include the following in your `config.yml`.

```
defaults:
layout:
Expand All @@ -271,7 +300,6 @@ defaults:
- For `issues` the column names are: `updatedAt, state, repo, title, creator, assignees, comments, reactions`.
- The available properties to control are: `grow` (false, true), `width` (number of cells), and `hidden` (false, true).


## Author

Dolev Hadar [email protected]
24 changes: 20 additions & 4 deletions config/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"reflect"
"strings"

"github.com/charmbracelet/bubbles/key"
"github.com/charmbracelet/lipgloss"
"github.com/go-playground/validator/v10"
"gopkg.in/yaml.v2"
Expand Down Expand Up @@ -104,11 +105,25 @@ type Defaults struct {
type Keybinding struct {
Key string `yaml:"key"`
Command string `yaml:"command"`
Builtin string `yaml:"builtin"`
}

func (kb Keybinding) NewBinding(previous *key.Binding) key.Binding {
helpDesc := ""
if previous != nil {
helpDesc = previous.Help().Desc
}

return key.NewBinding(
key.WithKeys(kb.Key),
key.WithHelp(kb.Key, helpDesc),
)
}

type Keybindings struct {
Issues []Keybinding `yaml:"issues"`
Prs []Keybinding `yaml:"prs"`
Universal []Keybinding `yaml:"universal"`
Issues []Keybinding `yaml:"issues"`
Prs []Keybinding `yaml:"prs"`
}

type Pager struct {
Expand Down Expand Up @@ -258,8 +273,9 @@ func (parser ConfigParser) getDefaultConfig() Config {
},
},
Keybindings: Keybindings{
Issues: []Keybinding{},
Prs: []Keybinding{},
Universal: []Keybinding{},
Issues: []Keybinding{},
Prs: []Keybinding{},
},
RepoPaths: map[string]string{},
Theme: &ThemeConfig{
Expand Down
43 changes: 42 additions & 1 deletion ui/keys/issueKeys.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
package keys

import "github.com/charmbracelet/bubbles/key"
import (
"fmt"

"github.com/charmbracelet/bubbles/key"
log "github.com/charmbracelet/log"

"github.com/dlvhdr/gh-dash/v4/config"
)

type IssueKeyMap struct {
Assign key.Binding
Expand Down Expand Up @@ -48,3 +55,37 @@ func IssueFullHelp() []key.Binding {
IssueKeys.ViewPRs,
}
}

func rebindIssueKeys(keys []config.Keybinding) error {
for _, issueKey := range keys {
if issueKey.Builtin == "" {
continue
}

log.Debug("Rebinding issue key", "builtin", issueKey.Builtin, "key", issueKey.Key)

var key *key.Binding

switch issueKey.Builtin {
case "assign":
key = &IssueKeys.Assign
case "unassign":
key = &IssueKeys.Unassign
case "comment":
key = &IssueKeys.Comment
case "close":
key = &IssueKeys.Close
case "reopen":
key = &IssueKeys.Reopen
case "viewPrs":
key = &IssueKeys.ViewPRs
default:
return fmt.Errorf("unknown built-in issue key: '%s'", issueKey.Builtin)
}

key.SetKeys(issueKey.Key)
key.SetHelp(issueKey.Key, key.Help().Desc)
}

return nil
}
77 changes: 76 additions & 1 deletion ui/keys/keys.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package keys

import (
"fmt"

"github.com/charmbracelet/bubbles/help"
"github.com/charmbracelet/bubbles/key"
log "github.com/charmbracelet/log"

"github.com/dlvhdr/gh-dash/v4/config"
)
Expand Down Expand Up @@ -82,7 +85,7 @@ func (k KeyMap) QuitAndHelpKeys() []key.Binding {
return []key.Binding{k.Help, k.Quit}
}

var Keys = KeyMap{
var Keys = &KeyMap{
Up: key.NewBinding(
key.WithKeys("up", "k"),
key.WithHelp("↑/k", "move up"),
Expand Down Expand Up @@ -152,3 +155,75 @@ var Keys = KeyMap{
key.WithHelp("q", "quit"),
),
}

// Rebind will update our saved keybindings from configuration values.
func Rebind(universal, issueKeys, prKeys []config.Keybinding) error {
err := rebindUniversal(universal)
if err != nil {
return err
}

err = rebindPRKeys(prKeys)
if err != nil {
return err
}

return rebindIssueKeys(issueKeys)
}

func rebindUniversal(universal []config.Keybinding) error {
log.Debug("Rebinding universal keys", "keys", universal)
for _, kb := range universal {
if kb.Builtin == "" {
continue
}

log.Debug("Rebinding universal key", "builtin", kb.Builtin, "key", kb.Key)

var key *key.Binding

switch kb.Builtin {
case "up":
key = &Keys.Up
case "down":
key = &Keys.Down
case "firstLine":
key = &Keys.FirstLine
case "lastLine":
key = &Keys.LastLine
case "togglePreview":
key = &Keys.TogglePreview
case "openGithub":
key = &Keys.OpenGithub
case "refresh":
key = &Keys.Refresh
case "refreshAll":
key = &Keys.RefreshAll
case "pageDown":
key = &Keys.PageDown
case "pageUp":
key = &Keys.PageUp
case "nextSection":
key = &Keys.NextSection
case "prevSection":
key = &Keys.PrevSection
case "search":
key = &Keys.Search
case "copyurl":
key = &Keys.CopyUrl
case "copyNumber":
key = &Keys.CopyNumber
case "help":
key = &Keys.Help
case "quit":
key = &Keys.Quit
default:
return fmt.Errorf("unknown built-in universal key: '%s'", kb.Builtin)
}

key.SetKeys(kb.Key)
key.SetHelp(kb.Key, key.Help().Desc)
}

return nil
}
49 changes: 49 additions & 0 deletions ui/keys/prKeys.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package keys

import (
"fmt"

"github.com/charmbracelet/bubbles/key"
log "github.com/charmbracelet/log"

"github.com/dlvhdr/gh-dash/v4/config"
)

type PRKeyMap struct {
Expand Down Expand Up @@ -80,3 +85,47 @@ func PRFullHelp() []key.Binding {
PRKeys.ViewIssues,
}
}

func rebindPRKeys(keys []config.Keybinding) error {
for _, prKey := range keys {
if prKey.Builtin == "" {
continue
}

log.Debug("Rebinding PR key", "builtin", prKey.Builtin, "key", prKey.Key)

var key *key.Binding

switch prKey.Builtin {
case "assign":
key = &PRKeys.Assign
case "unassign":
key = &PRKeys.Unassign
case "comment":
key = &PRKeys.Comment
case "diff":
key = &PRKeys.Diff
case "checkout":
key = &PRKeys.Checkout
case "close":
key = &PRKeys.Close
case "ready":
key = &PRKeys.Ready
case "reopen":
key = &PRKeys.Reopen
case "merge":
key = &PRKeys.Merge
case "watchChecks":
key = &PRKeys.WatchChecks
case "viewIssues":
key = &PRKeys.ViewIssues
default:
return fmt.Errorf("unknown built-in pr key: '%s'", prKey.Builtin)
}

key.SetKeys(prKey.Key)
key.SetHelp(prKey.Key, key.Help().Desc)
}

return nil
}
Loading

0 comments on commit da1221b

Please sign in to comment.