wez / wezterm

A GPU-accelerated cross-platform terminal emulator and multiplexer written by @wez and implemented in Rust
https://wezfurlong.org/wezterm/
Other
18.01k stars 807 forks source link

CloseWorkspace api and in cli #3658

Open sudo-tee opened 1 year ago

sudo-tee commented 1 year ago

Is your feature request related to a problem? Please describe. Comming from tmux, I really enjoy wezterm. Hovewer I used to script a lot of things with tmux. A feature I use is a key-bind for for closing a workspace. It removes the clutter and free some system ressources when I don't need the workspace anymore. Having to close all the panes to close a workspace is tedious.

Describe the solution you'd like I would like to have an api to close a workspace like mux.CloseWorkspace(workspace_name, {confirm = false}) Also having a wezterm cli kill-workspace my-workspace

Describe alternatives you've considered Creating a bash script to call wezterm cli kill-pane for all the panes in a workspace since there is no native api to kill a pane by id.

Thanks for your help and your wonderful application

sudo-tee commented 5 months ago

In the meantime I have this function in my config

function kill_wokspace(workspace)
  return function(window, pane, line)
    workspace = workspace or window:get_active_workspace()
    local success, stdout = wezterm.run_child_process({ "wezterm", "cli", "list", "--format=json" })

    if success then
      local json = wezterm.json_parse(stdout)
      if not json then
        return
      end

      local workspace_panes = u.filter(json, function(p)
        return p.workspace == workspace
      end)

      for _, p in ipairs(workspace_panes) do
        wezterm.run_child_process({ "wezterm", "cli", "kill-pane", "--pane-id=" .. p.pane_id })
      end
    end
  end
end
tjex commented 4 months ago

In case it helps others, this is how I built u.filter() to look.

local M = {}
local wezterm = require("wezterm")

M.filter = function(tbl, callback)
    local filt_table = {}

    for i, v in ipairs(tbl) do
        if callback(v, i) then
            table.insert(filt_table, v)
        end
    end
    return filt_table
end

return M

Keybind then looks like:

        {
            key = "k",
            mods = "LEADER",
            action = wezterm.action_callback(function(window)
                local w = window:active_workspace()
                func.kill_workspace(w)
            end),
        },

And the actual function (note some slight tweaks):

local util = require("util")
local wezterm = require("wezterm")
local M = {}

M.kill_workspace = function(workspace)
    local success, stdout =
        wezterm.run_child_process({ "/opt/homebrew/bin/wezterm", "cli", "list", "--format=json" })

    if success then
        local json = wezterm.json_parse(stdout)
        if not json then
            return
        end

        local workspace_panes = util.filter(json, function(p)
            return p.workspace == workspace
        end)

        for _, p in ipairs(workspace_panes) do
            wezterm.run_child_process({
                "/opt/homebrew/bin/wezterm",
                "cli",
                "kill-pane",
                "--pane-id=" .. p.pane_id,
            })
        end
    end
end
return M
piedrahitapablo commented 1 month ago

@sudo-tee @tjex thanks for the code samples, are they still working for you? I'm getting the following error:

01:03:28.901 ERROR wezterm_gui::termwindow > while processing user-defined-2 event: No such file or directory (os error 2)
stack traceback:
        [C]: in local 'poll'
        [string "?"]:4: in function 'wezterm.run_child_process'
        /Users/piedra/.config/wezterm/utils.lua:19: in function 'utils.kill_workspace'
        /Users/piedra/.config/wezterm/behavior/keymaps.lua:27: in function </Users/piedra/.config/wezterm/behavior/keymaps.lua:26>

and line 19 is:

local success, stdout, stderr = wezterm.run_child_process({
    "wezterm",
    "cli",
    "list",
    "--format=json",
})

do you know how can I debug this?

thanks!

loops commented 1 month ago

Hi piedrahitapablo,

It appears that the "wezterm" executable can't be located. Try adding the full path to wherever you have the executable installed, as it was in the original script.

piedrahitapablo commented 1 month ago

Hey @loops, thank you, I tried that yesterday before posting and saw the "same" error. It turns out that the new error was pointing to the other run_child_process call.

Thanks!

sudo-tee commented 1 month ago

What is your setup ?

Are you on windows / WSL / linux ?

what do you get when you run which wezterm ?

If you are in wsl wezterm.exe might be what you need

piedrahitapablo commented 4 days ago

@sudo-tee sorry for not replying earlier, the fix was using "/opt/homebrew/bin/wezterm", for both of the run_child_process calls. At first, I replaced that in only one call and didn't notice that I got a new error, it was very late when I was doing that, but the next day with a clear mind I read the error properly and was able to fix it