Applescript(osascript):在iTerm 2中打开拆分窗格并执行命令

13
以下工作可在iTerm 2中打开两个标签页。

我似乎无法弄清如何改用分割窗格

我尝试了在几个论坛上看到的方法,但它从未起作用。 有人能指点我吗?

osascript <<-eof
        tell application "iterm"
                set myterm to (make new terminal)
                tell myterm
                        launch session "Default session"
                        tell the last session
                                set name to "Server"
                                write text "cd $projectsFolder"
                        end tell
                        launch session "Default session"
                        tell the last session
                                set name to "Console"
                                write text "cd $projectsFolder"
                        end tell
                end tell
        end tell
eof
6个回答

34

使用新的每夜构建版本非常不错。虽然它大约一年前就已经实现了,但在公开版本中似乎缺失了:

源码 - AppleScriptTest.m
tell application "iTerm"
    activate
    select first window
    
    # Create new tab
    tell current window
        create tab with default profile
    end tell
    
    # Split pane
    tell current session of current window
        split vertically with default profile
        split vertically with default profile
    end tell
    
    # Exec commands
    tell first session of current tab of current window
        write text "cd ~/Developer/master-node"
        write text "coffee"
    end tell
    tell second session of current tab of current window
        write text "gulp w"
    end tell
    tell third session of current tab of current window
    end tell
end tell

我不得不花费太长时间来搜索这个,所以也许我可以帮助某人解决这个问题(可能是几周后的我自己),因为这是我找到的第一件事。这个解决方案甚至可以与激活的焦点跟随鼠标一起使用,这在其他答案中是缺失的。


4
这对我有帮助。我确实需要将“选择第一个终端窗口”更改为“选择第一个窗口”。 - Dennis Best
1
将粘贴的代码粘贴到Apple Script编辑器中,它会给我返回一个错误:"error "iTerm got an error: Can’t get current window of window id 35415." number -1728 from current window of window id 35415"。 - Duncan Krebs
1
确认此方法在 macOS 12.6 上仍然有效,并编辑示例以应用 @DennisBest 建议的修复。 - Dan Tanner

11

正如Dom所指出的,在新的2.9 beta构建版本中,其他答案将不再起作用。我曾因无法自动化而感到沮丧,因此编写了一个teamocil兼容的命令行工具来完成这项工作:

https://github.com/TomAnthony/itermocil

它允许你编写YAML文件,为预配置的窗口和窗格,运行给定项目的预定义命令集合。


告知应用“iTerm” 使用默认配置创建窗口 告知当前窗口的当前会话 写入文本“bash itermocil log” 结束告知 - 120DEV

5
更新: iTerm2 v3具有大幅改进但不兼容的AppleScript支持 - 请参见https://www.iterm2.com/documentation-scripting.html 为了提供一些背景知识,以下是@ Joel自己回答的内容:
iTerm 2的AppleScript支持(截至iTerm 2 v1.0.0.201306220):
  • 不完整的:没有支持脚本分割窗格 - 因此 OP 正在采用发送按键的次优技术。

  • 表现出一些奇怪的行为:当在一个tell application "iTerm"块内编译(在AppleScript编辑器中)一个tell "System Events" ...语句时,前缀i term application被不可理解地插入到"System Events"之前 - 由于下面的代码没有预编译,因此这个前缀不会被包含,以避免未来出现问题。

  • 缺陷/与其字典不一致:字典描述的exec命令 - 实际上并不起作用 - 实际上由write text命令实现:它执行传递的参数或 - 如果参数有尾随空格 - 只是“输入”参数而不提交。

以下是基于解决方法(发送按键)的分割窗格解决方案 - 一个bash脚本通过osascript调用AppleScript代码:

由于窗格不是字典的一部分,因此存在以下限制:

  • 无法为打开的其他窗格命名
  • 无法向其他窗格发送命令
#!/usr/bin/env bash

projectFolder="$HOME/Desktop" # example
osascript <<-EOF
  tell application "iTerm"
    tell (make new terminal) # Create a new pseudo terminal...
      tell (launch session "Default session") # ... and open a session (window)
        # Name the new window (its original pane).
        set name to "Server"
        # Execute the 'cd' command in the original pane.
        write text "cd '$projectFolder'"
        # Create a new split pane, horizontally, by sending ⌘⇧-D 
        tell application "System Events" to keystroke "d" using {shift down, command down}
          # !! Note: We canNOT:
          #  - name this pane separately
          #  - execute a command in it.
        # Return to the original pane, by sending ⌘-[ 
        tell application "System Events" to keystroke "[" using {command down}
      end tell
    end tell
  end tell
EOF

大部分正确@mklement0,但您可以为每个窗格命名并向另一个窗格发送按键。我已经更新了上面的内容。 - Joel
@Joel:嗯...这对我不起作用。看着你更新后的代码逻辑,你在_原始_窗格中执行了所有操作(因为在发送⌘-]之后执行name和其他一组write命令,这会导致你返回到_原始_窗格)。我有什么遗漏吗?你使用的是哪个版本的iTerm - mklement0

2

从@mklement0开始,这是我的脚本,它打开一个新的标签页,分成4个面板并运行命令:

#!/usr/bin/env bash
osascript <<-EOF
    set cmds to {"rabbitmq-server", "mongod", "redis-server", "htop"}

    tell application "iTerm"
        activate
        set myterm to (current terminal)

        tell myterm
            launch session "Default Session"

            # split vertically
            tell application "System Events" to keystroke "d" using command down
            delay 1
            # previus panel
            tell application "System Events" to keystroke "[" using command down
            delay 1
            # split horizontally
            tell application "System Events" to keystroke "d" using {shift down, command down}
            delay 1
            # next panel
            tell application "System Events" to keystroke "]" using command down
            delay 1
            # split horizontally
            tell application "System Events" to keystroke "d" using {shift down, command down}

            set n to count of cmds
            repeat with i from 1 to n
                # next panel
                tell application "System Events" to keystroke "]" using command down
                delay 1
                tell the current session to write text (item i of cmds)
            end repeat
        end tell

    end tell  
EOF

1
如果有帮助的话:我有一个类似的问题,想在iTerm中使用键盘组合键快速拆分窗格,并使新窗格继承原始会话的标题。我想出了以下解决方案,可以解决这个问题,并且不太依赖于发送按键(虽然我很想完全消除它们)。
tell application "iTerm"
    tell the current terminal
        tell the current session
            set the_name to get name
            tell i term application "System Events" to keystroke "d" using {command down, shift down}
        end tell

        tell the current session
            set name to the_name
        end tell
    end tell
end tell

我正在使用BetterTouchTool将键组合(即cmd+')绑定到执行此AppleScript的操作上。(我发现对于某些键组合,它会变得混乱,我天真地猜测是因为你实际上在按住该键组合的同时发送脚本所需的任何按键。我还没有追查如何在iTerm本身的首选项中定义键盘快捷键。我怀疑这可能会缓解问题。)

0

好的,我终于弄清楚了。

通过向应用程序发送按键,您可以打开和导航分割窗格。

tell i term application "System Events" to keystroke "D" using command down

tell i term application "System Events" to keystroke "]" using command down

一个向分割窗格发送命令并为每个窗格命名的示例。我用这个启动我的节点应用程序。
write text "cd $projectsFolder/$2.m"

write text "/usr/local/bin/frontend.sh $1 $2"

tell i term application "System Events" to keystroke "D" using command down

tell i term application "System Events" to keystroke "]" using command down

set name to "$2.api"

write text "cd $projectsFolder/$2.api"

write text "/usr/local/bin/backend.sh $1 $2"

你是不是无意中包含了“i term”这些标记? - mklement0
不,我没有,@mklement0。 - Joel
谢谢,我后来意识到这实际上是在一个“tell application“iTerm””块中才能正常工作的。我被不寻常的语法所困扰 - 似乎当你在“tell application“iTerm””块内编译一个“tell application ...”语句时,“iTerm”本身会将“iterm应用程序”前缀添加到应用程序名称中。一个等效的形式(带有显式的“activate”命令,以确保按键发送到“iTerm”)是:“tell application“iTerm”to activate”,然后是“tell application“System Events”to keystroke“D”using command down”。 - mklement0
啊,好的。我实际上还没有编译任何东西,这只是我正在开发的一个bash脚本中包含的内容。 - Joel
1
明白了。如果意图是返回到先前活动的窗格,则最好发送“[”而不是]`——这样,即使已经有多个窗格,它也可以工作。 - mklement0
我建议您从“tell i term application“ System Events”语句中删除“i term application”:这样,您的代码将在没有它们的情况下运行,并且最重要的是,如果/当底层问题在iTerm中得到解决时,代码仍将继续运行(正如我所说:虽然AppleScript编辑器会在编译时插入“i term 应用程序”,但在您的情况下,由于您直接将源代码传递给“osascript”,因此不适用)。 - mklement0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接