背景
我经常在 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