Skip to content

Instantly share code, notes, and snippets.

@umireon
Last active July 30, 2022 22:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save umireon/9d7a0d48bbd2574407008ab6c121b7ad to your computer and use it in GitHub Desktop.
Save umireon/9d7a0d48bbd2574407008ab6c121b7ad to your computer and use it in GitHub Desktop.
CotEditor: Help for Scripting hook

Adding scripting hooks for CotEditor scripts

Scripting hooks allows CotEditor scripts to be executed on certain events. The following events are available with CotEditor:

  • document opened: after you opened the file and then the contents was loaded
  • document saved: after you saved the file and then the contents was stored

See CotEditor Event Handler suite section on AppleScript Dictionary for further information.

The rest of this page describes how to include the script hooking to your CotEditor script.

Synopsis

Scripts with scripting hook must conforms to the following protocols:

  • written in AppleScript or JavaScript for Automation (JXA)
  • stored in the form of script bundle (.scptd) In addition, events to subscribe and handlers for them must be declared, as described below.

Structure of Script Bundle

A script bundle is the directory structure as follows:

HookingScript.scptd
└── Contents
    ├── Info.plist
    └── Resources
        ├── Script Libraries
        │   └── my-fancy-library.scpt
        ├── Scripts
        │   └── main.scpt
        └── description.rtfd
            └── TXT.rtf

Any scripts can be exported in this form with Script Editor.app, which is one of standard applications distributed with macOS.

To support scripting hooks, the list of events to subscribe must be written in Contents/Info.plist. Info.plist is a property list containing the metadata of the bundle and formatted in XML as the following example:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CFBundleIdentifier</key>
	<string>com.coteditor.hooking-script</string>
	<key>CFBundleName</key>
	<string>Hooking Script</string>
	<key>CFBundleShortVersionString</key>
	<string>1.0</string>
</dict>
</plist>

The events to subscribe must be stored at the key CotEditorHandlers and in the form of array of string.

<key>CotEditorHandlers</key>
<array>
	<string>document opened</string>
	<string>document saved</string>
</array>

Event Handlers

A event handler is the block to receive certain events which the application caused and do something with the received event. In this section, the manners to write an event handler are described with the simple example, which shows the dialog on opening and saving a file.

AppleScript

In AppleScript, handlers are written with a using terms from block and on blocks.

using terms from application "CotEditor"
	on document opened theDocument
		set thePath to file of theDocument
		display alert "Opened " & thePath
	end document opened
	
	on document saved theDocument
		set thePath to file of theDocument
		display alert "Saved " & thePath
	end document saved
end using terms from

JavaScript for Automation (JXA)

In JXA, function statements on the global object will create handlers.

CotEditor = Application.currentApplication()
CotEditor.includeStandardAdditions = true

function documentOpened(document) {
	CotEditor.displayAlert("Opened " + document.file().toString())
}

function documentSaved(document) {
	CotEditor.displayAlert("Saved " + document.file().toString())
}

スクリプトフックの追加

スクリプトフックは、特定のイベント発生時にスクリプトを起動する機能です。 CotEditor は、次に挙げるイベントでのフックをサポートしています。

  • document opened: ファイルを開く操作を行い、テキストが読み込まれた直後
  • document saved: ファイルを保存する操作を行い、テキストが書き込まれた直後

イベントの詳細な仕様については、AppleScript 辞書の CotEditor Event Handler suite 項を参照してください。

このページでは CotEditor スクリプトをスクリプトフックへ対応させる方法について説明します。

概要

フックに対応したスクリプトを作成する場合、以下の制約を満足する必要があります。

  • AppleScript または JavaScript for Automation (JXA) による記述
  • スクリプト バンドル 形式 (.scptd) で格納 以上に加えて、フックしたいイベントをメタデータファイルにて明示し、イベントハンドラを記述する必要があります。

スクリプトバンドルの構造

スクリプト バンドルは、以下に示す構造を持つディレクトリ構造です。

HookingScript.scptd
└── Contents
    ├── Info.plist
    └── Resources
        ├── Script Libraries
        │   └── my-fancy-library.scpt
        ├── Scripts
        │   └── main.scpt
        └── description.rtfd
            └── TXT.rtf

この形式には、macOSに標準で添付されているスクリプト エディタを用いることにより、簡単に書き出すことができます。

CotEditorのスクリプトフックに対応させるためには、まず、Info.plistにフックしたいイベントの一覧を記載する必要があります。 plistファイルはプロパティリストと呼ばれ、その内容は以下に示すようなXML形式で記述されたバンドルのメタデータです。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CFBundleIdentifier</key>
	<string>com.coteditor.hooking-script</string>
	<key>CFBundleName</key>
	<string>Hooking Script</string>
	<key>CFBundleShortVersionString</key>
	<string>1.0</string>
</dict>
</plist>

フックしたいイベントの一覧は、キーCotEditorHandlersに文字列の配列として記載します。以下にその一例を示します。

<key>CotEditorHandlers</key>
<array>
  <string>document opened</string>
  <string>document saved</string>
</array>

イベントハンドラ

イベントハンドラは、アプリケーションが発生させたイベントを受信し、処理を行うスクリプトを指します。 ここでは、ファイルを読み込んだ後と書き込んだ後にダイアログを表示するスクリプトを例に採り上げ、イベントハンドラの記述方法について説明します。

AppleScript

AppleScriptでスクリプトを記述する場合、using terms fromブロックとonブロックを組み合わせることで、ハンドラを作成します。

using terms from application "CotEditor"
	on document opened theDocument
		set thePath to file of theDocument
		display alert "Opened " & thePath
	end document opened
	
	on document saved theDocument
		set thePath to file of theDocument
		display alert "Saved " & thePath
	end document saved
end using terms from

JavaScript for Automation (JXA)

JXAでスクリプトを記述する場合、function文を用いてハンドラを作成します。関数はグローバルオブジェクト上で定義する必要があります。

CotEditor = Application.currentApplication()
CotEditor.includeStandardAdditions = true

function documentOpened(document) {
	CotEditor.displayAlert("Opened " + document.file().toString())
}

function documentSaved(document) {
	CotEditor.displayAlert("Saved " + document.file().toString())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment