Установите сочетание клавиш «Службы» через скрипт OSX

Мне нужен способ установить следующее программно:

Сочетание клавиш

В частности, для ярлыков в разделе «Службы», если это имеет значение. Мне интересно, возможно ли это через оболочку или AppleScript?

РЕДАКТИРОВАТЬ:

Я видел https://stackoverflow.com/questions/7219134/programmatically-add-keyboard-shortcut-to-mac-system-preferences , но мне до сих пор не ясно, как установить ярлык для существующей службы.

Для Mavericks может быть другая история, но см . stackoverflow.com/questions/7219134/…
... но имейте в виду, что то, как Mavericks обрабатывает разрешение сценариев графического интерфейса пользователя с использованием системных событий, отличается от того, что было раньше, поскольку вы должны разрешить то, что запускает сценарий (приложение сценария, редактор сценария).
Извините, не заметил, что вы уже видели этот пост ... так что вы уже пробовали?
@CRGreen Я возился с несколькими списками, пытаясь найти способ установить этот конкретный ярлык. Последняя ссылка, которую вы предоставили, определенно приближает меня. Я вижу это конкретное свойство там.

Ответы (5)

@chrisKnadler правильно использовал Applescript для этого.

Я использовал это раньше в прошлом, но отказался от него из-за новой проблемы в Mavericks, связанной с кэшированием предпочтений в масштабах всей системы.

Это означает, что вы можете использовать только команду unix

по умолчанию пишут...

чтобы результаты действительно менялись, а не изменялись вручную или с помощью команд элемента plist Applescript .

Но только сейчас, осмотревшись, нашел предложение, что вы можете просто очистить кеш и инициировать систему, чтобы снова прочитать предпочтение, просто вызвав

значения по умолчанию читаются...

в файле plist у вас есть изменения. Кажется, это действительно работает.

  set theServiceName to "(null) - Print to PDF - runWorkflowAsService"
set libPrefPath to POSIX path of (path to preferences folder from user domain as text)
set PlistFile to "pbs.plist"
set PlistPath to libPrefPath & PlistFile as text
set mainPropertyItem to "NSServicesStatus"
set theKey to "key_equivalent"

tell application "System Events"

    set gp to (get property list item theServiceName of property list item mainPropertyItem of property list file PlistPath)

    tell gp
        --set value of property list item "enabled_services_menu" to true
        --set value of property list item "enabled_context_menu" to true
        set value of property list item theKey to "@^h"

    end tell

end tell

do shell script " defaults read " & quoted form of PlistPath & > /dev/null

Вам все равно могут понадобиться отдельные приложения, чтобы они отображали изменения (как обычно)


ОБНОВЛЕНИЕ: Небольшое изменение.

Добавлено > /dev/nullв конец команды по умолчанию, поэтому возвращаются только ошибки.

Вы также можете использовать PlistBuddyи defaults:

/usr/libexec/PlistBuddy -c 'Delete NSServicesStatus:"(null) - test2 - runWorkflowAsService"' ~/Library/Preferences/pbs.plist 2>/dev/null;defaults write pbs NSServicesStatus -dict-add '"(null) - test2 - runWorkflowAsService"' '{key_equivalent = "^~@2";}'

Команда PlistBuddyне нужна, если для службы нет существующей записи. Замените test2на название службы. Закройте и снова откройте приложения, чтобы применить изменения.

^~@2это опция управления-команда-2. См . http://osxnotes.net/keybindings.html .

Я заметил, что некоторые словари NSServiceStatus содержат более одного элемента. Т.е. включить сервисное меню и контекстные меню. Команда plistBuddy удалит их все. Но по умолчанию это не учитывается. Насколько важны эти настройки, я не уверен на 100%. Они есть не у всех диктовок, но все же могут быть включены. Я думаю, это зависит от того, как создается служба. Т.е. автоматом или приложением.

Как и большинство настроек, сочетания клавиш можно установить с помощью команд «записи по умолчанию» в Терминале. Полезно, если у вас есть много ярлыков, которые вы хотите определить, или если вам нужно настроить более одного Mac. Однако синтаксис отличается от обычных команд для установки ключа в значение.

Для команд, специфичных для приложения, используйте следующее:

defaults write com.developer.app NSUserKeyEquivalents -dict-add "Menu Item" -string "@$~^k"

Мета-клавиши устанавливаются как @ для Command, $ для Shift, ~ для Alt и ^ для Ctrl. k в этом примере — это немета-ключ, который вы хотите использовать.

Для общесистемных ярлыков вы можете использовать -g вместо идентификатора приложения, например

defaults write -g NSUserKeyEquivalents -dict-add "Menu Item" -string "@$~^k" 

Обратите внимание, что вам нужно будет перезапустить приложение, прежде чем они вступят в силу. Также вы можете увидеть, были ли они успешными в Системных настройках, которые также потребуется перезапустить, чтобы показать изменения.

Действительно ли это отвечает на вопрос о добавлении ярлыка в существующее сервисное меню?

Сочетания клавиш для служб немного отличаются от сочетаний клавиш для конкретных приложений или общесистемных, хотя ими можно управлять с помощью defaults readи defaults write.

Самый простой способ, который я нашел, чтобы понять такие вещи, это:

defaults read > /tmp/a

Измените сочетание клавиш вручную с помощью Системных настроек.

defaults read > /tmp/b
diff /tmp/[ab]

Для конкретного случая сочетаний клавиш для служб в OS-X 10.8 важными доменами являются «com.apple.ServicesMenu.Services» и «pbs». Вам нужно просмотреть домен com.apple.ServicesMenu.Services, чтобы получить информацию, необходимую для создания записи в домене pbs.

Например:

Ключ CFVendedServicesот com.apple.ServicesMenu.Services«Разархивировать в текущую папку»:

{
    NSBundleIdentifier = "cx.c3.theunarchiver";
    NSBundlePath = "/opt/homebrew-cask/Caskroom/the-unarchiver/3.9.1/The Unarchiver.app";
    NSKeyEquivalent = { };
    NSMenuItem = {
        default = "The Unarchiver/Unarchive To Current Folder";
    };
    NSMessage = unarchiveToCurrentFolderWithPasteboard;
    NSPortName = "The Unarchiver";
    NSSendTypes = (
        NSFilenamesPboardType
    );
    NSUUID = <be1910e8 cb1a3475 90854bc5 09f0c0ab>;
},

Чтобы создать для него сочетание клавиш, ключ pbs NSServices создается из NSBundleIdentifier, NSMenuItem и NSMessage. Пример:

defaults read pbs
{
        "cx.c3.theunarchiver - The Unarchiver/Unarchive To Current Folder - unarchiveToCurrentFolderWithPasteboard" =         {
            "enabled_context_menu" = 1;
            "enabled_services_menu" = 1;
            "key_equivalent" = "@~^u";
        };
        "org.vim.MacVim - MacVim/New MacVim Buffer Here - newFileHere" =         {
            "key_equivalent" = "@~^v";
        };
    };
}

К сожалению, домен pbs построен как вложенные словари, которые не могут быть обработаны defaults writeподобными более простыми случаями для других сочетаний клавиш. Вам нужно будет прочитать весь ключ NSServicesStatus, вставить новую запись, а затем записать ее обратно:

defaults write pbs NSServicesStatus '{
    "com.cocoatech.PathFinder - Path Finder/Show Info - getInfoInPathFinderService" =     {
        "key_equivalent" = "@~^$i";
    };
    "cx.c3.theunarchiver - The Unarchiver/Unarchive To Current Folder - unarchiveToCurrentFolderWithPasteboard" =     {
        "enabled_context_menu" = 1;
        "enabled_services_menu" = 1;
        "key_equivalent" = "@~^u";
    };
    "org.vim.MacVim - MacVim/New MacVim Buffer Here - newFileHere" =     {
        "key_equivalent" = "@~^v";
    };
}'

Также может потребоваться принудительно очистить кеш pbs:

/System/Library/CoreServices/pbs -flush
У меня была игра, делающая это вчера, но я не опубликовал ее. (Я использовал копию plist bps для работы) Я прочитал в NSServicesStatus и использовал sedдля изменения часть, которую я хотел изменить. Но хотя это работает при изменении словаря, когда я записываю его обратно в plist, любое число или логическое значение будет заменено на строку. Вы преодолели это.
Из справочных страниц кажется, что -dataэто сработает. Я попробую и посмотрю, не могу ли я что-то сделать. Это определенно похоже на то, как это сделать! ^_^
Это похоже на другой способ сделать это: обсуждения.apple.com/thread /4709713?tstart=0

Я ленивый — я использую такой инструмент, как FastScripts, для установки глобальных сочетаний клавиш и вызова сценариев.

Это бесплатно, если вам не нужно определить 11 или более ярлыков. Кроме того, автор - прекрасный джентльмен, который делает качественное программное обеспечение и поддерживает пользователей намного больше, чем вы могли бы ожидать от магазина одного человека.

Это потрясающе, но на самом деле я пытаюсь сделать этот ярлык частью установщика. Я хочу попробовать сделать это без использования стороннего программного обеспечения. Тем не менее, это круто, и я обязательно буду использовать его в целом. Спасибо! (проголосовал бы, если бы мог ^_^)
Не беспокойтесь о голосовании. Я ценю хорошие комментарии и сложные вопросы, подобные этому, больше, чем любые 100 голосов, которые приходят, когда внимание Интернета привлекает один вопрос или ответ. Я буду следить за другими вариантами, но похоже, что все простые решения были предложены в других ответах здесь.