在Mac OSX上创建mailto处理程序应用程序

leh*_*off 2 mailto macos emacs

我在Emacs中使用mu4e作为我的邮件客户端,但我无法弄清楚如何创建一个可以将mailto url传递给以下shell脚本的脚本:

#!/bin/sh
# emacs-mailto-handler

mailto=$1
mailto="mailto:${mailto#mailto:}"
mailto=$(printf '%s\n' "$mailto" | sed -e 's/[\"]/\\&/g')
elisp_expr="(mu4e~compose-browse-url-mail \"$mailto\")"

emacsclient -a \"\" --create-frame -n --eval "$elisp_expr" \
        '(set-window-dedicated-p (selected-window) t)'
Run Code Online (Sandbox Code Playgroud)

当我在命令行上调用此脚本时,它会在Emacs中打开一个具有正确地址和主题的新框架:

$ emacs-mailto-handler "mailto:webmonkey@wired.com?subject=I-love-cats-too%21"
Run Code Online (Sandbox Code Playgroud)

问题是我需要创建一个可以配置为Mac OSX中默认邮件客户端的应用程序.我曾尝试使用Automator和Platypus来调用我的shell脚本,但我无法让他们将他们收到的参数传递给shell脚本.(我已经看到了这个问题:OS X:如何使命令行脚本显示为帮助应用程序来处理mailto ? ,但这对我来说不起作用.)

在一天结束时,我必须能够让应用程序执行此脚本调用:emacs-mailto-handler"mailto:webmonkey@wired.com?subject = I-love-cats-too%21"其中mailto链接来自浏览器.

任何线索都是最受欢迎的!

在此先感谢Torben

Ken*_*ses 5

这将需要某种捆绑的应用程序.

当应用程序处理URL时,它不会在其命令行参数(argv参数数组main())中接收它们.实际上,应用程序可以在运行期间随时接收打开URL的请求,而不仅仅是在启动时.因此,它肯定需要一个除命令行参数之外的机制来接收它们.这使得脚本无法在其参数中接收URL.

相反,它接收打开或获取URL作为类kInternetEventClass和ID 的Apple事件的请求kAEGetURL.该应用程序为该Apple事件设置处理程序,并由框架调用该处理程序.为了使框架能够接收和发送Apple事件,应用程序必须a)使用这些框架,以及b)为框架提供机会,以监视它们在内部使用的进程间通信机制来传递事件.同样,这不是shell脚本可以做的事情.

在Cocoa应用程序中,这需要在应用程序的早期启动代码中添加如下代码,例如-applicationWillFinishLaunching:app delegate 的方法:

    NSAppleEventManager* appleEventManager = [NSAppleEventManager sharedAppleEventManager];
    [appleEventManager setEventHandler:self andSelector:@selector(handleGetURLEvent:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL];
Run Code Online (Sandbox Code Playgroud)

然后可以添加一个名称与上面传递的选择器匹配的方法; 在这种情况下-handleGetURLEvent:withReplyEvent::

- (BOOL)handleGetURLEvent:(NSAppleEventDescriptor*)event withReplyEvent:(NSAppleEventDescriptor*)replyEvent
{
    NSAppleEventDescriptor* directObjectDescriptor = [event paramDescriptorForKeyword:keyDirectObject];
    NSString* urlString = [directObjectDescriptor stringValue];
    NSURL* url = [NSURL URLWithString:urlString];
    // ... do something with url ...
}
Run Code Online (Sandbox Code Playgroud)

除了该代码之外,应用程序还必须声明其能够在CFBundleURLTypes密钥下的Info.plist文件中处理特定方案的URL .如下所示的条目将声明处理mailto:URL 的能力:

    <key>CFBundleURLTypes</key>
    <array>
        <dict>
            <key>CFBundleURLName</key>
            <string>Email Address URL</string>
            <key>CFBundleURLSchemes</key>
            <array>
                <string>mailto</string>
            </array>
        </dict>
    </array>
Run Code Online (Sandbox Code Playgroud)

可以想象,由Platypus或Automator生成的应用程序可以在其中包含上述URL支持代码.这很多是通用的.声明支持特定的URL方案是他们必须让您配置的东西.通常无法宣布对任何/所有方案的支持.

我攻击了Automator生成的应用程序的Info.plist文件,看看我是否可以让它处理URL.它没用.但是,我正在测试Automator从OS X 10.6生成的应用程序.新版本的Automator可能会增加支持.这可以解释您引用的其他问题中报告的成功.

我没有检查过鸭嘴兽.