macOS 上使用 Chrome 在后台打开网页

2023/07/30
Tags:  #Swift #Vim #实践

背景

我经常在 nvim 上写 markdown 文档,并配合 markdown-preview.nvim 插件来实时预览。这个插件做得很好,当我切换不同的 markdown 文件时,插件会自动调用浏览器打开一个实时预览网页,当我的光标在 nvim 中移动,预览网页也会跟着同步滚动。但美中不足的是,每次切换 markdown 文件打开预览网页时,浏览器都会切换到前台,获得键盘的焦点,但我想让键盘焦点继续留在 nvim 里。

使用 AppleScript 调用 Chrome 在后台打开网页

通过多次 Google 搜索,找到了一个能在 macOS 上后台打开网页的方法,就是通过 AppleScript 调用 Chrome 的方式。

AppleScript 的内容如下:

set myURL to "https://www.example.com"

if running of application "Google Chrome" then
    tell application "Google Chrome"
        if window 1 exists then
            tell window 1
                make new tab
                repeat while (loading of active tab)
                    delay 0.1
                end repeat
                execute active tab javascript "document.location.href = '" & myURL & "';"
            end tell
        end if
    end tell
end if

将这段代码粘贴到“脚本编辑器”中运行,如果发现 Chrome 创建了新标签页,但是没有跳转到指定链接,则要在 Chrome 的状态栏中勾选 “视图——开发者——允许 Apple 事件中的 JavaScript”

包装成一个控制台程序

因为 nvim 不能直接执行 AppleScript,因此可以把这段 AppleScript 代码包装成控制台程序。我选择使用 Swift,因为 Swift 能调用 AppleScript,Swift 也能编译成控制台程序,具体代码如下:

import Foundation

func open(url: String) {
  let applesript = """
    set myURL to "\(url)"

    if running of application "Google Chrome" then
        tell application "Google Chrome"
            if window 1 exists then
                tell window 1
                    make new tab
                    repeat while (loading of active tab)
                        delay 0.1
                    end repeat
                    execute active tab javascript "document.location.href = '" & myURL & "';"
                end tell
            end if
        end tell
    end if
    """

  if let script = NSAppleScript(source: applesript) {
    var error: NSDictionary?

    script.executeAndReturnError(&error)

    if let err = error {
      print("[Applescript] NSAppleScript.executeAndReturnError(): \(err)")
    }
  }
}

let arguments = CommandLine.arguments
let argCount = arguments.count

if argCount > 1 {
  // 第一个参数是可执行文件的路径,所以实际的参数从第二个开始
  let url = arguments[1]
  open(url: url)
}

编译成控制台程序的方法:

swiftc silent-chrome-launcher.swift -o silent-chrome-launcher

编译完成后就能使用以下方法调用了

silent-chrome-launcher https://www.google.com