字典外观来自BBEdit,Mailsmith和TextWrangler

The new Dictionary app is one of my favorite new features in Mac OS X 10.4Dictionary’s primary advantage over online dictionaries — including Sherlock’s — is that its database is stored on your computer, and thus is always available; online dictionaries are useless to an offline laptopPlus, I like the presentation, and I like the definitionsAs a writer, Dictionary is pretty much exactly what I want.

But, since I do the vast majority of my writing in BBEdit and Mailsmith, I was faced with a problemTo be truly useful as a writing aid, you need to be able to invoke your dictionary easily from the app in which you’re writingWhat I want to do is select a word in BBEdit (or Mailsmith or TextWrangler) and tell Dictionary to look up that word in one quick action但:

  • Dictionary’s “Look Up in Dictionary” contextual menu item currently only appears in Cocoa NSTextView and WebView control fieldsThus it doesn’t appear in BBEdit, TextWrangler, or Mailsmith.

  • Dictionary’s system-wide keyboard shortcut — Command-Control-D by default, but configurable in the Keyboard & Mouse panel in System Preferences — also only works in Cocoa NSTextView and WebView fields.

    更新,2005年5月12日: BBEdit 8.2.1 now supports the Command-Control-D shortcut and inline Dictionary panelVery, very coolI’m fairly certain Bare Bones is now the first third-party developer to add support for these hooks.

  • 字典没有AppleScript字典(Technically, ithave a scripting dictionary, but it’s just a default Cocoa dictionary, and offers no scripting features for performing definition look-ups, which means it’s effectively useless.)

  • 表面上,字典允许您通过。执行查找字典://URL方案,但是,就像我一样documented on my Tiger Details report, this feature is half-baked at best, and for some users doesn’t seem to work at all.

这留下了两个选项,我发现这两个选项都能很好地工作。

“在字典中查找”服务

Dictionary’s menu command in the Services menu works just fine from BBEdit/TextWrangler/MailsmithThe only downside is that it doesn’t have a keyboard shortcut, and mousing into the Services sub-menu is too inconvenient.

However, you can easily add a custom shortcut to the “Look Up in Dictionary” Services menu item:

  1. Open the Keyboard & Mouse panel in System Preferences, then click on the Keyboard Shortcuts tab.

  2. 单击“+”按钮添加新快捷方式。

  3. In the configuration sheet, you can either choose “All Applications” or just pick a single applicationEven though it seems as though there’s just one system-wide Services menu, the truth is that each app creates its own instance of the Services menuSo if you want, you can customize a Service menu item shortcut for just one particular appFor consistency, though, I think it’s better to choose “All Applications” and use the same shortcut everywhere.

  4. 在“菜单标题”字段中键入“在字典中查找”This must match exactly.

  5. 在“键盘快捷键”字段中键入新快捷方式You can pretty much type whatever shortcut you want here, and it’s important to note that the system does not perform any conflict checking, so you can use a shortcut that’s already used by other menu items (including another command in the Services menu itself).

  6. You’ll need to quit and relaunch any apps that are currently running to use this new shortcut.

通过GUI脚本编写字典应用程序脚本

I’m so lazy that I don’t even want to have to select a word before doing a look-up on itIf I don’t have a selection, I’d like my look-up command to use whatever word the insertion point is touching. This means the Services menu command is out, because it’s only enabled when there’s a range of selected text.

We can use AppleScript to get the “current word” adjacent to the insertion point (cf“为BBEdit选择“Word”脚本”, published here back in 2003), but what can we do with it if Dictionary isn’t scriptable and its support for字典://URLs is broken? We resort toGUI脚本

这是脚本(To use it with Mailsmith or TextWrangler, all you need to do is change the告诉应用程序“BBEdit”线。)

-- This script uses the selected text in the frontmost window
-- as a query string for the Dictionary appIf there is no selection,
-- it uses whatever word the insertion point is touching.

tell application "BBEdit"
   tell window 1
      set dict_query to selection
      if (dict_query = "") or (class of dict_query is not character) then
         set sel_offset to characterOffset of selection
         set cur_line to startDisplayLine of selection
         try
            select (last word of display_line cur_line ¬
               whose characterOffset ≤ sel_offset)
            set dict_query to selection as text
         on error
            set dict_query to text returned of ¬
               (display dialog "Look Up in Dictionary:" default answer ¬
                  "" buttons {"Cancel", "Look Up"} default button 2)
         end try
      end if
   end tell
   set dict_query to dict_query as text
end tell

if dict_query is not "" then
   tell application "Dictionary" to activate
   tell application "System Events"
      tell process "Dictionary"
         set tf to text field 1 of group 1 of tool bar 1 ¬
            of window "Dictionary and Thesaurus"
         set value of tf to ""
         tell tf
            -- set value to dict_query
            keystroke dict_query
            keystroke return
         end tell
      end tell
   end tell
end if

脚本的第一部分设置dict_queryto the text of the current selectionIf there is no text selection, then it tries to get the “current word” adjacent to the insertion pointIf that fails (e.gif the insertion point is currently on a blank line), it uses a dialog box to prompt for a word to look up.

GUI脚本编写部分有两个关键步骤(确定后)dict_query变量不为空并激活Dictionary应用程序):

  1. Set the tell target to the search field in Dictionary’s main window’s toolbar.

  2. 模拟按键进入dict_query字段中的字符串。

  3. 模拟“返回”击键。

该脚本使用GUI脚本按键command instead of setting the value of the search field and then simulating a click on the magnifying glass search button; in my experience this works betterAlso, the script first sets the value of the search text field to the empty string; without this step, the new query is sometimes appended to the existing query instead of replacing it.

Save the script in your BBEdit (or Mailsmith or TextWrangler) scripts folder, then use the Scripts palette to assign a keyboard shortcut, and you’re set(I’ve got mine bound to Control-D, which is super-easy to type.)

Remember that to use GUI Scripting, you need to turn it on; it’s off by defaultOn Mac OS X 10.4, the easiest way to turn it on is to use the new AppleScript Utility app (in the “AppleScript” folder inside the top-level “Applications” folder)If you try running this script with GUI Scripting turned off, you’ll get strange “NSReceiverEvaluationScriptError” error messages.

PreFab UI浏览器的简短插件

The GUI scripting part of the script looks fairly simple, but how did I know that the name of the magnifying-glass icon button was “search”? You need to know this, because simply setting the value of the text field doesn’t initiate a look-upFor that matter, how did I know how to string together the chain of objects to address the search text field in the first place — the “text field 1 of group 1 of tool bar 1“有点?

Apple的解决方案非常痛苦UI元素检查器应用程序。

But the only good way to determine the syntax for addressing interface elements via GUI scripting is to usePreFab UI浏览器, an excellent utility that puts Apple’s UI Element Inspector羞愧It costs $55, but has a lenient and generous demo period during which you can try it for free.

Trying to accomplish something with GUI scripting without using UI Browser is like trying to walk around blindfoldedIf not for UI Browser, I seriously doubt I would have even attempted this script.

It’s a completely valid gripe that Dictionary ought to provide a proper AppleScript command for performing look-ups, and I hope this gets addressed in a future updateBut in the meantime, GUI scripting gets the job done today.