Skip to content

Commit

Permalink
feat: add root command (#191)
Browse files Browse the repository at this point in the history
* feat: add root command
* chore: update mockery
* docs: add filter by root gum example
  • Loading branch information
joshmedeski authored Oct 18, 2024
1 parent 39e5fab commit 2f1dfc1
Show file tree
Hide file tree
Showing 29 changed files with 253 additions and 34 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,18 @@ I recommend adding this to your `tmux.conf`:
bind -N "switch to root session (via sesh) " 9 run-shell "sesh connect --root \'$(pwd)\'"
```

### Filter by root

If you want to filter your search by the root of the active project, you can modify your piker by using the `sesh root` command:

```sh
bind-key "R" display-popup -E -w 40% "sesh connect \"$(
sesh list -i -H | gum filter --value \"$(sesh root)\" --limit 1 --fuzzy --no-sort --placeholder 'Pick a sesh' --prompt=''
)\""
```

I have this bound to `<prefix>+R` so I can use an alternative binding.

**Note:** This will only work if you are in a git worktree or git repository. For now, git worktrees expect a `.bare` folder.

## Configuration
Expand Down
2 changes: 1 addition & 1 deletion cloner/mock_Cloner.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion configurator/mock_Configurator.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion connector/mock_Connector.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dir/mock_Dir.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion execwrap/mock_Exec.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion execwrap/mock_ExecCmd.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion git/mock_Git.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion home/mock_Home.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion icon/mock_Icon.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion json/mock_Json.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions lister/lister.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
type Lister interface {
List(opts ListOptions) (model.SeshSessions, error)
FindTmuxSession(name string) (model.SeshSession, bool)
GetAttachedTmuxSession() (model.SeshSession, bool)
GetLastTmuxSession() (model.SeshSession, bool)
FindConfigSession(name string) (model.SeshSession, bool)
FindZoxideSession(name string) (model.SeshSession, bool)
Expand Down
57 changes: 56 additions & 1 deletion lister/mock_Lister.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lister/mock_srcStrategy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions lister/tmux.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ func (l *RealLister) GetLastTmuxSession() (model.SeshSession, bool) {
return sessions.Directory[secondSessionIndex], true
}

func (l *RealLister) GetAttachedTmuxSession() (model.SeshSession, bool) {
return GetAttachedTmuxSession(l)
}

func GetAttachedTmuxSession(l *RealLister) (model.SeshSession, bool) {
tmuxSessions, err := l.tmux.ListSessions()
if err != nil {
Expand Down
32 changes: 31 additions & 1 deletion namer/git.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,23 @@
package namer

import "strings"
import (
"fmt"
"strings"
)

func gitBareRootName(n *RealNamer, path string) (string, error) {
isGit, commonDir, _ := n.git.GitCommonDir(path)
if isGit && strings.HasSuffix(commonDir, "/.bare") {
topLevelDir := strings.TrimSuffix(commonDir, "/.bare")
name, err := n.home.ShortenHome(topLevelDir)
if err != nil {
return "", fmt.Errorf("couldn't shorten path: %q", err)
}
return name, nil
} else {
return "", nil
}
}

// Gets the name from a git bare repository
func gitBareName(n *RealNamer, path string) (string, error) {
Expand All @@ -17,6 +34,19 @@ func gitBareName(n *RealNamer, path string) (string, error) {
}
}

func gitRootName(n *RealNamer, path string) (string, error) {
isGit, topLevelDir, _ := n.git.ShowTopLevel(path)
if isGit && topLevelDir != "" {
name, err := n.home.ShortenHome(topLevelDir)
if err != nil {
return "", fmt.Errorf("couldn't shorten path: %q", err)
}
return name, nil
} else {
return "", nil
}
}

// Gets the name from a git repository
func gitName(n *RealNamer, path string) (string, error) {
isGit, topLevelDir, _ := n.git.ShowTopLevel(path)
Expand Down
58 changes: 57 additions & 1 deletion namer/mock_Namer.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 27 additions & 1 deletion namer/namer.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,27 @@ import (
"fmt"

"github.com/joshmedeski/sesh/git"
"github.com/joshmedeski/sesh/home"
"github.com/joshmedeski/sesh/pathwrap"
)

type Namer interface {
// Names a sesh session from a given path
Name(path string) (string, error)
RootName(path string) (string, error)
}

type RealNamer struct {
pathwrap pathwrap.Path
git git.Git
home home.Home
}

func NewNamer(pathwrap pathwrap.Path, git git.Git) Namer {
func NewNamer(pathwrap pathwrap.Path, git git.Git, home home.Home) Namer {
return &RealNamer{
pathwrap: pathwrap,
git: git,
home: home,
}
}

Expand All @@ -46,3 +50,25 @@ func (n *RealNamer) Name(path string) (string, error) {
}
return "", fmt.Errorf("could not determine name from path: %s", path)
}

func (n *RealNamer) RootName(path string) (string, error) {
path, err := n.pathwrap.EvalSymlinks(path)
if err != nil {
return "", err
}

strategies := []func(*RealNamer, string) (string, error){
gitRootName,
dirName,
}
for _, strategy := range strategies {
name, err := strategy(n, path)
if err != nil {
return "", err
}
if name != "" {
return convertToValidName(name), nil
}
}
return "", fmt.Errorf("could not determine root name from path: %s", path)
}
7 changes: 5 additions & 2 deletions namer/namer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"testing"

"github.com/joshmedeski/sesh/git"
"github.com/joshmedeski/sesh/home"
"github.com/joshmedeski/sesh/pathwrap"
"github.com/stretchr/testify/assert"
)
Expand All @@ -13,7 +14,8 @@ func TestFromPath(t *testing.T) {
t.Run("when path does not contain a symlink", func(t *testing.T) {
mockPathwrap := new(pathwrap.MockPath)
mockGit := new(git.MockGit)
n := NewNamer(mockPathwrap, mockGit)
mockHome := new(home.MockHome)
n := NewNamer(mockPathwrap, mockGit, mockHome)

t.Run("name for git repo", func(t *testing.T) {
mockPathwrap.On("EvalSymlinks", "/Users/josh/config/dotfiles/.config/neovim").Return("/Users/josh/config/dotfiles/.config/neovim", nil)
Expand Down Expand Up @@ -46,7 +48,8 @@ func TestFromPath(t *testing.T) {
t.Run("when path contains a symlink", func(t *testing.T) {
mockPathwrap := new(pathwrap.MockPath)
mockGit := new(git.MockGit)
n := NewNamer(mockPathwrap, mockGit)
mockHome := new(home.MockHome)
n := NewNamer(mockPathwrap, mockGit, mockHome)

t.Run("name for symlinked file in symlinked git repo", func(t *testing.T) {
mockPathwrap.On("EvalSymlinks", "/Users/josh/d/.c/neovim").Return("/Users/josh/dotfiles/.config/neovim", nil)
Expand Down
Loading

0 comments on commit 2f1dfc1

Please sign in to comment.