wez / wezterm

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

Wezterm regression on wezterm.on("gui-startup", function() - split{} no longer works as before #3985

Closed dmilith closed 1 year ago

dmilith commented 1 year ago

What Operating System(s) are you seeing this problem on?

macOS

Which Wayland compositor or X11 Window manager(s) are you using?

No response

WezTerm version

20230713-081419-f73f7180

Did you try the latest nightly build to see if the issue is better (or worse!) than your current version?

Yes, and I updated the version box above to show the version of the nightly that I tried

Describe the bug

I have this in my configuration:

 -- define first tab to be a special tab
  wezterm.on("gui-startup", function()
    local projects_dir = "/Volumes/Projects"

    -- the first tab
    local tab, first_pane, window = mux.spawn_window{
      workspace="sccache",
      cwd=projects_dir,
    }
    first_pane:send_text("clear; while true; do clear; sccache --show-stats; sleep 5; done\n")

    local second_pane = first_pane:split{
      direction="Right",
      size=0.8,
      cwd=projects_dir,
    }
    second_pane:send_text("clear; while true; do date; brew upgrade; brew cleanup; echo; echo; echo; sleep 7200; done\n")

    local third_pane = second_pane:split{
      direction="Bottom",
      size=0.4,
      cwd=projects_dir,
    }
    third_pane:send_text("rlwrap bc\n")

But after the update, only the first pane is created (that one with sccache).

To Reproduce

Just use my configuration

Configuration

local wezterm = require 'wezterm';
local mux = wezterm.mux
local act = wezterm.action

local MY_EDITOR = "/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl"

return {
  front_end = "WebGpu",
  webgpu_power_preference = "HighPerformance",
  default_cwd = "/Volumes/Projects",
  set_environment_variables={
    TERMINFO_DIRS='~/.terminfo/',
    TERM='xterm-256color',
  },
  ulimit_nproc = 2048,
  ulimit_nofile = 4096,
  term = "xterm-256color",
  skip_close_confirmation_for_processes_named = {
    "bash", "sh", "zsh", "fish", "tmux"
  },
  pane_focus_follows_mouse = false,
  native_macos_fullscreen_mode = false,
  enable_scroll_bar = true,
  send_composed_key_when_left_alt_is_pressed=true,
  send_composed_key_when_right_alt_is_pressed=true,
  switch_to_last_active_tab_when_closing_tab = true,

  -- unicoden = 14,
  animation_fps = 60,
  font_size = 30,
  command_palette_font_size = 28,
  line_height = 1.05,
  initial_cols = 300,
  initial_rows = 49,
  window_background_opacity = 0.89,
  macos_window_background_blur = 4,

  scrollback_lines = 1000000,

  audible_bell = "SystemBeep",
  --custom_block_glyphs = true,
  default_cursor_style = "BlinkingBlock",
  cursor_blink_rate = 900,
  cursor_blink_ease_in = 'Linear',
  cursor_blink_ease_out = 'Linear',
  bold_brightens_ansi_colors = true,
  use_resize_increments = false,

  tab_bar_at_bottom = false,
  hide_tab_bar_if_only_one_tab = true,
  use_fancy_tab_bar = false,
  show_tab_index_in_tab_bar = true,

  font = wezterm.font({
    family="Iosevka",
    harfbuzz_features={"calt=1", "clig=1", "liga=1"},
  }),

  color_scheme = "Abernathy",
  color_schemes = {
   ["Abernathy"] = {
     cursor_border = "#52ad70",
     cursor_bg = "#00f200",
     cursor_fg = "#0c0c0c",
     selection_fg = "white",
     selection_bg = "#1972a1",
     ansi = {"#2c2c2c", "#c91b00", "#00c200", "#ffaa00", "#4069e9", "#c930c7", "#00c5c7", "#c7c7c7"},
     brights = {"#676767", "#ff6d67", "#5ff967", "#fefb67", "#6871ff", "#ff76ff", "#5ffdff", "#fffefe"},
   }
  },
  window_decorations = "RESIZE",

  key_tables = {
    copy_mode = {
      {key="c", mods="CTRL", action=act.CopyMode("Close")},
      {key="g", mods="CTRL", action=act.CopyMode("Close")},
      {key="q", mods="NONE", action=act.CopyMode("Close")},
      {key="Escape", mods="NONE", action=act.CopyMode("Close")},

      {key="h", mods="NONE", action=act.CopyMode("MoveLeft")},
      {key="j", mods="NONE", action=act.CopyMode("MoveDown")},
      {key="k", mods="NONE", action=act.CopyMode("MoveUp")},
      {key="l", mods="NONE", action=act.CopyMode("MoveRight")},

      {key="LeftArrow",  mods="NONE", action=act.CopyMode("MoveLeft")},
      {key="DownArrow",  mods="NONE", action=act.CopyMode("MoveDown")},
      {key="UpArrow",    mods="NONE", action=act.CopyMode("MoveUp")},
      {key="RightArrow", mods="NONE", action=act.CopyMode("MoveRight")},

      {key="RightArrow", mods="ALT",  action=act.CopyMode("MoveForwardWord")},
      {key="f",          mods="ALT",  action=act.CopyMode("MoveForwardWord")},
      {key="Tab",        mods="NONE", action=act.CopyMode("MoveForwardWord")},
      {key="w",          mods="NONE", action=act.CopyMode("MoveForwardWord")},

      {key="LeftArrow", mods="ALT",   action=act.CopyMode("MoveBackwardWord")},
      {key="b",         mods="ALT",   action=act.CopyMode("MoveBackwardWord")},
      {key="Tab",       mods="SHIFT", action=act.CopyMode("MoveBackwardWord")},
      {key="b",         mods="NONE",  action=act.CopyMode("MoveBackwardWord")},

      {key="0",     mods="NONE",  action=act.CopyMode("MoveToStartOfLine")},
      {key="Enter", mods="NONE",  action=act.CopyMode("MoveToStartOfNextLine")},

      {key="$",     mods="NONE",  action=act.CopyMode("MoveToEndOfLineContent")},
      {key="$",     mods="SHIFT", action=act.CopyMode("MoveToEndOfLineContent")},
      {key="^",     mods="NONE",  action=act.CopyMode("MoveToStartOfLineContent")},
      {key="^",     mods="SHIFT", action=act.CopyMode("MoveToStartOfLineContent")},
      {key="m",     mods="ALT",   action=act.CopyMode("MoveToStartOfLineContent")},

      {key=" ", mods="NONE",  action=act.CopyMode{SetSelectionMode="Cell"}},
      {key="v", mods="NONE",  action=act.CopyMode{SetSelectionMode="Cell"}},
      {key="V", mods="NONE",  action=act.CopyMode{SetSelectionMode="Line"}},
      {key="V", mods="SHIFT", action=act.CopyMode{SetSelectionMode="Line"}},
      {key="v", mods="CTRL",  action=act.CopyMode{SetSelectionMode="Block"}},

      {key="G", mods="NONE",  action=act.CopyMode("MoveToScrollbackBottom")},
      {key="G", mods="SHIFT", action=act.CopyMode("MoveToScrollbackBottom")},
      {key="g", mods="NONE",  action=act.CopyMode("MoveToScrollbackTop")},

      {key="H", mods="NONE",  action=act.CopyMode("MoveToViewportTop")},
      {key="H", mods="SHIFT", action=act.CopyMode("MoveToViewportTop")},
      {key="M", mods="NONE",  action=act.CopyMode("MoveToViewportMiddle")},
      {key="M", mods="SHIFT", action=act.CopyMode("MoveToViewportMiddle")},
      {key="L", mods="NONE",  action=act.CopyMode("MoveToViewportBottom")},
      {key="L", mods="SHIFT", action=act.CopyMode("MoveToViewportBottom")},

      {key="o", mods="NONE",  action=act.CopyMode("MoveToSelectionOtherEnd")},
      {key="O", mods="NONE",  action=act.CopyMode("MoveToSelectionOtherEndHoriz")},
      {key="O", mods="SHIFT", action=act.CopyMode("MoveToSelectionOtherEndHoriz")},

      {key="PageUp",   mods="NONE", action=act.CopyMode("PageUp")},
      {key="PageDown", mods="NONE", action=act.CopyMode("PageDown")},

      {key="b", mods="CTRL", action=act.CopyMode("PageUp")},
      {key="f", mods="CTRL", action=act.CopyMode("PageDown")},

      {key="y", mods="NONE", action=act.Multiple{
        -- act.Copy,
        act.CompleteSelection("Clipboard"),
        act.ClearSelection,
        act.CopyMode("Close"),
      }},
    },
  },

  keys = {
    {key="Enter", mods="SUPER", action="ToggleFullScreen"},
    {key="l", mods="SUPER", action="ShowDebugOverlay"},
    {key="k", mods="SUPER", action=act.ClearScrollback("ScrollbackAndViewport")},
    {key="x", mods="SUPER", action="ActivateCopyMode"},
    {key="s", mods="SUPER", action=act.QuickSelect},

    {key="d", mods="SUPER", action=act.SplitPane{
      direction="Right", -- command={args={"top"}},
      size={Percent=50},
    }},

    {key="d", mods="SUPER|SHIFT", action=act.SplitPane{
      direction="Down",
      size={Percent=50},
    }},

    {key="UpArrow", mods="SUPER", action=act.ScrollByLine(-1)},
    {key="DownArrow", mods="SUPER", action=act.ScrollByLine(1)},
  },

  window_padding = {
    left = "0.3cell",
    right = "0.3cell",
    top = "0.3cell",
    bottom = "0.3cell",
  },

  -- format tab naming
  wezterm.on("format-tab-title", function(tab, tabs, panes, config, hover, max_width)
   if tab.is_active then
     return {
       {Background={Color="#002010"}},
       {Text= "   " .. tab.tab_index + 1 .. "   "},
     }
   else
     return {
       {Background={Color="black"}},
       {Text= "   " .. tab.tab_index + 1 .. "   "},
     }
   end
   return tab.active_pane.title
  end),

  -- position window to the top
  wezterm.on("window-config-reloaded", function(window, pane)
    window:set_position(0, 0)
  end),

  -- handle battery info
  wezterm.on("update-right-status", function(window, pane)
    -- The powerline < symbol
    local LEFT_ARROW = utf8.char(0xe0b3);
    -- The filled in variant of the < symbol
    local SOLID_LEFT_ARROW = utf8.char(0xe0b2)
    -- local SOLID_RIGHT_ARROW = utf8.char(0xe0b0)

    -- Each element holds the text for a cell in a "powerline" style << fade
    local cells = {};

    -- Figure out the cwd and host of the current pane.
    -- This will pick up the hostname for the remote host if your
    -- shell is using OSC 7 on the remote host.
    -- local cwd_uri = pane:get_current_working_dir()
    -- if cwd_uri then
    --   cwd_uri = cwd_uri:sub(8);
    --   local slash = cwd_uri:find("/")
    --   local cwd = ""
    --   local hostname = ""
    --   if slash then
    --     hostname = cwd_uri:sub(1, slash-1)
    --     -- Remove the domain name portion of the hostname
    --     local dot = hostname:find("[.]")
    --     if dot then
    --       hostname = hostname:sub(1, dot-1)
    --     end
    --     -- and extract the cwd from the uri
    --     cwd = cwd_uri:sub(slash)

    --     table.insert(cells, cwd);
    --     table.insert(cells, hostname);
    --   end
    -- end
    -- Color palette for the backgrounds of each cell
    local colors = {
      "#002010",
      "#02300a",
      "#0c5295",
      "#063a82",
    };
    -- local colors = {
    --   "#52307c",
    --   "#3c1361",
    --   "#7c5295",
    --   "#663a82",
    -- };

    -- I like my date/time in this style: "Wed Mar 3 08:14"
    local date = wezterm.strftime("%a, %-d %b %Y");
    table.insert(cells, date);
    -- table.insert(cells, {Text=SOLID_LEFT_ARROW})

    -- An entry for each battery (typically 0 or 1 battery)
    for _, b in ipairs(wezterm.battery_info()) do
      table.insert(cells, string.format("%.0f%%", b.state_of_charge * 100))
    end

    -- Foreground color for the text across the fade
    local text_fg = "#c0c0c0";

    -- The elements to be formatted
    local elements = {};
    -- How many cells have been formatted
    local num_cells = 0;

    -- table.insert(cells, {Background={Color=colors[2]}})
    -- table.insert(cells, {Text=SOLID_LEFT_ARROW})

    -- Translate a cell into elements
    function push(text, is_last)
      local cell_no = num_cells + 1
      table.insert(elements, {Foreground={Color=text_fg}})

      table.insert(elements, {Background={Color=colors[cell_no]}})
      table.insert(elements, {Text=" "..text.." "})
      if not is_last then
        table.insert(elements, {Foreground={Color=colors[cell_no+1]}})
        table.insert(elements, {Text=SOLID_LEFT_ARROW})
      else
        table.insert(elements, {Text="🔋"})
      end
      num_cells = num_cells + 1
    end

    while #cells > 0 do
      local cell = table.remove(cells, 1)
      push(cell, #cells == 0)
    end

    window:set_right_status(wezterm.format(elements));
  end);

  -- define first tab to be a special tab
  wezterm.on("gui-startup", function()
    local projects_dir = "/Volumes/Projects"

    -- the first tab
    local tab, first_pane, window = mux.spawn_window{
      workspace="sccache",
      cwd=projects_dir,
    }
    first_pane:send_text("clear; while true; do clear; sccache --show-stats; sleep 5; done\n")

    local second_pane = first_pane:split{
      direction="Right",
      size=0.8,
      cwd=projects_dir,
    }
    second_pane:send_text("clear; while true; do date; brew upgrade; brew cleanup; echo; echo; echo; sleep 7200; done\n")

    local third_pane = second_pane:split{
      direction="Bottom",
      size=0.4,
      cwd=projects_dir,
    }
    third_pane:send_text("rlwrap bc\n")

    -- -- the second tab
    -- local fbsd_arm64_13_1 = "/Volumes/Projects/VMs/FreeBSD-13.1"

    -- local tab, first_pane, window = mux.spawn_window{
    --   workspace="qemu131",
    --   cwd=fbsd_arm64_13_1,
    -- }
    -- first_pane:send_text("./ssh.sh \"ccache -s\"\n")

    -- local second_pane = first_pane:split{
    --   direction="Right",
    --   size=0.8,
    --   cwd=fbsd_arm64_13_1,
    -- }
    -- second_pane:send_text("./ssh.sh \"gstat\"\n")

    -- local third_pane = second_pane:split{
    --   direction="Bottom",
    --   size=0.4,
    --   cwd=fbsd_arm64_13_1,
    -- }
    -- third_pane:send_text("./start.sh")

    -- local fbsd_arm64_13_2 = "/Volumes/Projects/VMs/FreeBSD-13.2"

  end),

  wezterm.on("open-uri", function(window, pane, uri)
    local prefix = "src"
    local start, match_end = uri:find(prefix)
    if start == 1 then
      wezterm.log_info("opening editor for: " .. uri)
      local file_at_some_position = prefix .. uri:sub(match_end+1)
      window:perform_action(wezterm.action.SpawnCommandInNewWindow{args = {MY_EDITOR, file_at_some_position}}, pane)

      -- prevent the default action from opening in a browser
      return false
    end

    local prefix = "http"
    local start, match_end = uri:find(prefix)
    if start == 1 then
      local an_url = prefix .. uri:sub(match_end+1)
      wezterm.log_info("opening: " .. an_url)
      window:perform_action(wezterm.action.SpawnCommandInNewWindow{args = {"open", an_url}}, pane) -- , "-g"
      return false
    end

    -- otherwise, by not specifying a return value, we allow later
    -- handlers and ultimately the default action to caused the
    -- URI to be opened in the browser
  end),

  -- handle src/path.rs:123:45 with MY_EDITOR
  hyperlink_rules = {
    {
      regex = [[\b(src.*rs):(\d+):(\d+)\b]],
      format = "$0",
    },
    {
      regex = [[\bhttps?://\S*\b]],
      format = "$0",
    },

    -- Matches: a URL in parens: (URL)
    {
      regex = '\\((\\w+://\\S+)\\)',
      format = '$1',
      highlight = 1,
    },
    -- Matches: a URL in brackets: [URL]
    {
      regex = '\\[(\\w+://\\S+)\\]',
      format = '$1',
      highlight = 1,
    },
    -- Matches: a URL in curly braces: {URL}
    {
      regex = '\\{(\\w+://\\S+)\\}',
      format = '$1',
      highlight = 1,
    },
    -- Matches: a URL in angle brackets: <URL>
    {
      regex = '<(\\w+://\\S+)>',
      format = '$1',
      highlight = 1,
    },
    -- Then handle URLs not wrapped in brackets
    {
      regex = '\\b\\w+://\\S+[)/a-zA-Z0-9-]+',
      format = '$0',
    },
    -- implicit mailto link
    {
      regex = '\\b\\w+@[\\w-]+(\\.[\\w-]+)+\\b',
      format = 'mailto:$0',
    },
  },

  quick_select_patterns = {
    -- match all kinds of paths
    '/[0-9A-Za-z.+_/-]+',

    -- match versions
    ' ([0-9]{1,}.[0-9]{1,}.[0-9]{1,})',

    -- match branch names in ()
    '\\(([0-9A-Za-z_+-]+)\\)'
  },

}

Expected Behavior

No response

Logs

No response

Anything else?

No response

dmilith commented 1 year ago

split:pane() stopped working?

dmilith commented 1 year ago

Also

wezterm.on('mux-startup', function()
    local tab, pane, window = mux.spawn_window {}
    pane:split { direction = 'Top' }

  end),

doesn't seem to be triggered at all

dmilith commented 1 year ago

Debug overlay says:

00:02:12.004 ERROR wezterm_gui > while processing gui-startup event: bad argument #2 to `MuxPane.split`: error converting Lua table to userdata (expected userdata of type mux_lua::pane::SplitPane)
stack traceback:
        [C]: in local 'poll'
        [string "?"]:5: in method 'split'
        [string "/Users/dmilith/.config/wezterm/wezterm.lua"]:304: in function <[string "/Users/dmilith/.config/wezterm/wezterm.lua"]:293>

when I try the more elaborate example from https://wezfurlong.org/wezterm/config/lua/gui-events/gui-startup.html

dmilith commented 1 year ago

For now, the workaround I've found is to just use first_pane:split() (no curly braces). Then it works (well, kinda - since no options can be specified).

wez commented 1 year ago

This should be resolved now in main.

It typically takes about an hour before commits are available as nightly builds for all platforms. Linux builds are the fastest to build and are often available within about 20 minutes. Windows and macOS builds take a bit longer.

Please take a few moments to try out the fix and let me know how that works out. You can find the nightly downloads for your system in the wezterm installation docs.

If you prefer to use packages provided by your distribution or package manager of choice and don't want to replace that with a nightly download, keep in mind that you can download portable packages (eg: a .dmg file on macOS, a .zip file on Windows and an .AppImage file on Linux) that can be run without permanently installing or replacing an existing package, and can then simply be deleted once you no longer need them.

If you are eager and can build from source then you may be able to try this out more quickly.

dmilith commented 1 year ago

Works like a charm in the new build! thanks! <3

github-actions[bot] commented 1 year ago

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.