Skip to content

Commit

Permalink
feat: support killing panes and groups
Browse files Browse the repository at this point in the history
  • Loading branch information
cfoust committed Sep 20, 2023
1 parent e0590ae commit 29b4f92
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 0 deletions.
4 changes: 4 additions & 0 deletions pkg/cy/api/tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,10 @@ func (t *TreeModule) Parent(id tree.NodeID) *tree.NodeID {
return &parentId
}

func (t *TreeModule) Kill(id tree.NodeID) error {
return t.Tree.RemoveNode(id)
}

func (t *TreeModule) Root() tree.NodeID {
return t.Tree.Root().Id()
}
30 changes: 30 additions & 0 deletions pkg/cy/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ type Client struct {
outerLayers *screen.Layers
renderer *stream.Renderer

// history is an array of all of the panes this client has attached to
history []tree.NodeID

raw emu.Terminal
info screen.RenderContext
}
Expand Down Expand Up @@ -300,8 +303,35 @@ func (c *Client) Attach(node tree.Node) error {

c.muxClient.Attach(c.Ctx(), pane.Screen())

go func() {
select {
case <-c.Ctx().Done():
return
case <-c.muxClient.Attachment().Ctx().Done():
return
case <-pane.Ctx().Done():
// if the pane dies, just re-attach to the last node the user visited
c.RLock()
history := c.history
c.RUnlock()

if len(history) < 2 {
// TODO(cfoust): 09/20/23
return
}

node, ok := c.cy.tree.NodeById(history[len(history)-2])
if !ok {
return
}
c.Attach(node)
return
}
}()

c.Lock()
c.node = node
c.history = append(c.history, node.Id())
c.Unlock()

// Update bindings
Expand Down
6 changes: 6 additions & 0 deletions pkg/cy/cy-boot.janet
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@
(0) # Gets the first index, the editor
(pane/attach))))

(key/bind
[prefix "x"]
"kill the current pane"
(fn [&]
(tree/kill (pane/current))))

(key/bind
[prefix "l"]
"jump to a shell"
Expand Down
18 changes: 18 additions & 0 deletions pkg/cy/cy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,3 +186,21 @@ func TestScopes(t *testing.T) {
require.NoError(t, err)
require.Equal(t, 3, len(client.binds.Scopes()))
}

func TestPaneKill(t *testing.T) {
server := setupServer(t)
defer server.Release()

_, client, err := server.Standard()
require.NoError(t, err)

require.NoError(t, client.execute(`
(def shell (cmd/new (tree/root) "/tmp"))
(pp shell)
(pane/attach shell)
(tree/kill shell)
`))
time.Sleep(100 * time.Millisecond) // lol
leaves := server.cy.tree.Leaves()
require.Equal(t, leaves[0].Id(), client.Node().Id())
}
8 changes: 8 additions & 0 deletions pkg/cy/janet.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ type CmdParams struct {
Args []string
}

// execute runs some Janet code on behalf of the Client. This is only used in testing.
func (c *Client) execute(code string) error {
return c.cy.janet.ExecuteCall(c.Ctx(), c, janet.Call{
Code: []byte(code),
Options: janet.DEFAULT_CALL_OPTIONS,
})
}

func (c *Cy) initJanet(ctx context.Context) (*janet.VM, error) {
vm, err := janet.New(ctx)
if err != nil {
Expand Down
4 changes: 4 additions & 0 deletions pkg/mux/screen/server/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ func (c *Client) State() *tty.State {
return screen.State()
}

func (c *Client) Attachment() *util.Lifetime {
return c.attachment
}

func (c *Client) Updates() *mux.Updater {
return c.publisher.Subscribe()
}
Expand Down

0 comments on commit 29b4f92

Please sign in to comment.