GNU Emacs 32.0.50 (9008bf64c3) のマニュアルを PLaMo 翻訳で機械翻訳したものです。誤訳を含むことがあります。原文: https://www.gnu.org/software/emacs/manual/html_node/elisp/Drag-and-Drop.html ・ emacs-doc.conao3.com

30.25 ドラッグ&ドロップ

ドラッグ&ドロップで転送されるデータは、一般的にプレーンテキストか、ファイルやその他のリソースを指定するURLのリストのいずれかです。テキストをドロップすると、その位置に挿入され、それが不可能な場合はキルリングに保存されます。

ドロップされたURLは、変数dnd-protocol-alistを介して該当するDNDハンドラ関数に、あるいは変数browse-url-handlersおよびbrowse-url-default-handlersで定義される「URLハンドラ」に渡されます。いずれのタイプの対応するハンドラも存在しない場合は、プレーンテキストとして扱われ、バッファに挿入されます。

変数: dnd-protocol-alist

この変数は、URLの照合に用いる正規表現と、一致するURLがドロップされた際に呼び出されるDNDハンドラ関数との対応関係を示すalistです。

ハンドラ関数が、dnd-multiple-handler プロパティ(シンボルプロパティを参照)が設定されたシンボルである場合、ドロップ時にその正規表現に一致するすべてのURLのリストが渡されます。このプロパティが設定されていない場合は、それらのURLごとに1回ずつ呼び出されます。この第1引数に続くのは、実行すべきアクションを識別するシンボル copy、move、link、private、または ask のいずれかです。

action が private である場合、ドロップを開始したプログラムは、受信側に対して特定の動作を要求しません。その場合に取るべき妥当な対応は、URL を開くか、その内容を現在のバッファにコピーすることです。action のその他の値は、dnd-begin-file-drag の action 引数とほぼ同様の意味を持ちます。

処理が完了すると、ハンドラ関数は実行したアクションを示すシンボルを返さなければなりません。それは、指定されたアクションか、あるいは指定されたアクションが実行されなかったことをドロップ元に伝えるシンボル private のいずれかです。

ドロップ内の重複するアイテムのサブセットに対して複数のハンドラがマッチした場合、最も多くのアイテムにマッチしたハンドラが呼び出され、そのサブセットを開きます。当該ハンドラに渡されたアイテムは、その後、たとえ他のハンドラにもマッチする場合であっても、それらのハンドラには渡されません。

Emacsでは、テキストとURL以外のデータを受け付けるための措置を講じていない。これを可能にするウィンドウシステムのインターフェース同士は、互いに乖離しすぎており、一貫した形で抽象化することができないためである。また、特定のドラッグ&ドロッププロトコルが受信側にそのような制御権を認めていないため、DNDハンドラが本来行うべき動作に影響を及ぼすこともできない。X11のドラッグ&ドロップ実装は、選択転送を利用し、多くの共通点を持つ複数の基盤プロトコルに基づいており、それらへの低レベルアクセスは以下の関数および変数を通じて提供されている:

変数: x-dnd-test-function

この関数は、Emacsがドロップを受け付けるべきかどうかを判定するために呼び出されます。3つの引数を取って呼び出されます:

  • ドラッグ対象の下にあるウィンドウ、すなわちドロップ先となるバッファを持つウィンドウ。対象がフレームのウィンドウ以外のコンポーネント(スクロールバーやツールバーなど)に位置している場合は、代わりにフレーム自体が指定されます。
  • ドロップ元が提案するアイテムデータに対して実行する操作を表すシンボル move、copy、link、または ask のいずれか。これらのシンボルは、x-begin-drag と同様の意味を持つ。
  • アイテムが提供する選択データ型のベクトル(X Selectionsを参照)。

この関数は、ドロップを拒否する場合は nil を、実行されるアクション(DNDハンドラ関数への転送など)の cons および要求する選択データ型を返さなければなりません。その cons で返されるアクションにはシンボル private が含まれる場合もあり、これは実行されるアクションが現時点では未確定であることを示します。

変数: x-dnd-known-types

x-dnd-test-function を変更することは一般的に不要です。というのも、ドロップを受理するためのデフォルトの判定基準は、この選択データ型のリストを変更することで調整できるからです。各要素は文字列であり、デフォルトの「テスト関数」によってデータ型リスト内の要素のシンボル名として検出された場合、その関数がドロップを受理するようになります。

このリストに新しいエントリを追加する場合、x-dnd-types-alistに対応するハンドラ関数を追記しない限り意味がありません。

変数: x-dnd-types-alist

この変数は、選択データ型を指定する文字列と、それらの型のオブジェクトがドロップされた際に呼び出される関数との対応関係を示すalistです。

こうした各関数には3つの引数が渡されます。1つ目は、x-dnd-test-functionのようにドロップ位置の下にあるウィンドウまたはフレーム、2つ目は実行されるアクション(テスト関数が返すアクションのいずれか)、そして3つ目は選択データそのものです(選択へのアクセスを参照)。

X11のドラッグ&ドロッププロトコルで提供される選択データ型は、ICCCMや準拠するクリップボードまたはプライマリ選択オーナーが提供するものとは異なる場合があります。多くの場合、"text/plain;charset=utf-8"(“utf-8”の大文字・小文字が異なる)のようなMIMEタイプ名が、UTF8_STRINGのような標準的なX選択名の代わりに用いられます。

X Direct Save (XDS) プロトコルにより、プログラムはドロップされたファイルの命名責任を受信側に委譲できるようになります。このようなドロップが発生すると、DNDハンドラや前述のX固有のインターフェースは概ねバイパスされ、別の機能がドロップへの対応を担うことになります。

変数: x-dnd-direct-save-function

この変数には、XDSプロトコルを用いてドロップされたファイルを2段階の手順で登録し、命名する関数を設定する必要があります。この変数には、need-name と filename の2つの引数が渡されます。

  1. ファイルをドラッグしたアプリケーションは、ファイルを保存する際の完全なファイル名をEmacsに指定するよう求めます。この目的のため、direct-save関数が呼び出されます。その第1引数にはneed-name(non-nil)が、第2引数には保存対象ファイルのベース名であるfilenameが指定されます。この関数は、ファイルを保存する際の完全に展開された絶対ファイル名を返す必要があります。例えば、ファイルをDiredウィンドウにドラッグした場合、そのファイルの自然なディレクトリは、ドロップ位置に表示されているファイルのディレクトリとなります。何らかの理由でファイルの保存が不可能な場合、関数はnilを返す必要があり、これによりドラッグ&ドロップ操作がキャンセルされます。
  2. ファイルをドラッグしたアプリケーションは、direct-save関数の初回呼び出しで返された名前でファイルを保存します。ファイルの保存に成功した場合、direct-save関数が再度呼び出されます。この際、第1引数 need-name には nil が、第2引数 filename には保存されたファイルの完全な絶対名が設定されます。その後、この関数はファイルが保存されたという事実に基づき、必要な処理を行うことになります。例えば、Diredは画面上のディレクトリを更新し、そこに新しいファイルを表示させる必要があります。

デフォルトの x-dnd-direct-save-function は x-dnd-save-direct です。

関数: x-dnd-save-direct need-name filename

need-name 引数に non-nil を指定して呼び出すと、この関数は保存先となる絶対ファイル名をユーザーに入力させます。指定したファイルが既に存在する場合は、さらに上書きするかどうかをユーザーに確認し、ユーザーが上書きを承認した場合にのみ絶対ファイル名を返します。

need-name 引数 nil を指定して呼び出すと、現在のバッファが Dired モードまたはその派生モードにある場合は Dired の一覧表示に戻り、そうでない場合は find-file を呼び出してファイルを訪問します(ファイル訪問用関数 を参照)。

関数: x-dnd-save-direct-immediately need-name filename

この関数は x-dnd-save-direct と同様に動作しますが、引数 need-name に non-nil を指定して呼び出すと、保存するファイル名のフルネームをユーザーに問い合わせることはなく、代わりに現在のバッファのデフォルトディレクトリに基づいて展開された引数 filename を返します(ファイル名を展開する関数 を参照)。(ただし、デフォルトディレクトリにその名前のファイルが既に存在する場合は、引き続き確認を求めます。)

また、現在のウィンドウシステムが対応していれば、Emacsから他のプログラムへコンテンツをドラッグすることも可能です。これを実現する関数は以下の通りです。

関数: dnd-begin-text-drag text &optional frame action allow-same-frame

この関数は、frame から別のプログラム(ドロップ先と呼ばれる)へのドラッグ&ドロップ操作を開始し、text がドロップされるか、あるいは操作がキャンセルされたときに戻ります。

action はシンボル copy または move のいずれかである必要があります。ここで copy はドロップターゲットによって text が挿入されるべきであることを意味し、move は copy と同じ意味ですが、呼び出し側はまた、以下のリストで説明されている通り、ソースから text を削除しなければなりません。

frame は現在マウスボタンが押されているフレーム、nil は選択中のフレームを使用することを意味します。この関数は、マウスボタンが押されていない場合には即座に返り値を返す可能性があるため、down-mouse-1 またはそれに類するイベント(マウスイベント を参照)に応じてのみ呼び出すべきであり、その際 frame にはそのイベントが発生したフレーム(クリックイベント を参照)を設定します。

allow-same-frame が nil の場合、frame の上にドロップしたものは無視されます。

戻り値は、ドロップターゲットが実際に実行した操作を反映しており、したがって、呼び出し側が次にどのような操作を行うべきか(あるいは行う必要がないか)も示します。戻り値は、以下のシンボルのいずれかとなります。

copy

ドロップターゲットにドロップしたテキストが挿入されました。

move

ドロップターゲットがドロップされたテキストを挿入し、必要に応じて、呼び出し元はそれが抽出されたバッファから text を削除する必要があります。

private

ドロップターゲットは、その他の不特定の操作を行った。

nil

ドラッグ&ドロップ操作がキャンセルされました。

関数: dnd-begin-file-drag file &optional frame action allow-same-frame

この関数は、frame から別のプログラム(ドロップ先と呼ばれる)へのドラッグ&ドロップ操作を開始し、file がドロップされるか、あるいは操作がキャンセルされたときに戻ります。

file がリモートファイルの場合、一時的なローカルコピーが作成されます。

action は copy、move、または link のいずれかの記号である必要があります。ここで、copy はドロップ先が file を展開またはコピーすることを、move はドロップ先がファイルを別の場所に移動することを、link はドロップ先が file へのシンボリックリンクを作成することをそれぞれ意味します。file がリモートファイルである場合に、アクションとして link を指定するとエラーとなります。

frame および allow-same-frame は、dnd-begin-text-drag の呼び出し時と同様の意味を持ちます。

戻り値は、ドロップターゲットが実際に実行した操作であり、以下のシンボルのいずれかとなります。

copy

ドロップ先が開いたか、file を別の場所にコピーしました。

move

ドロップターゲットが file だけ別の位置に移動しました。

link

ドロップ先(通常はファイルマネージャー)が file へのシンボリックリンクを作成しました。

private

ドロップターゲットが、その他の不特定の操作を行った。

nil

ドラッグ&ドロップ操作がキャンセルされました。

関数: dnd-begin-drag-files files &optional frame action allow-same-frame

この関数は dnd-begin-file-drag と同様ですが、files がファイルのリストである点が異なります。ドロップ先が複数ファイルのドロップに対応していない場合は、代わりに最初のファイルが使用されます。

関数: dnd-direct-save file name &optional frame allow-same-frame

この関数の動作は、dnd-begin-file-drag(デフォルトの動作であるcopyが使用される場合)と同様ですが、コピーを格納するファイル名を指定できる点が異なります。

上述の高レベルインターフェースは、より低レベルなプリミティブの上に実装されています。また、テキストやファイル以外のコンテンツをドラッグするための低レベルインターフェース x-begin-drag も利用可能です。これには、呼び出し元がサポートしたい各プラットフォーム上のプログラムが認識するデータ型や操作に関する詳細な知識が求められます。

関数: x-begin-drag targets &optional action frame return-frame allow-current-frame follow-tooltip

この関数は frame からドラッグを開始し、ドロップが成功したか、あるいはドロップが拒否されたかのいずれかの理由でドラッグ&ドロップ操作が終了した際に復帰します。ドロップは、frame 以外の X ウィンドウ(ドロップターゲット)、または allow-current-frame が nil 以外の場合は任意の X ウィンドウ上で、すべてのマウスボタンが離されたときに発生します。ドラッグ&ドロップ操作の開始時にマウスボタンが一つも押されていない場合、この関数は直ちに nil を返すことがあります。

targets は、gui-get-selection の引数 data-type と同様に、ドロップターゲットが Emacs に要求できる選択対象を表す文字列のリストです(ウィンドウシステムの選択 を参照)。

action は、対象に対して推奨される操作を示す記号です。XdndActionCopy または XdndActionMove のいずれかであり、いずれも選択範囲 XdndSelection の内容をドロップ先にコピーすることを意味しますが、後者はさらにコピー後に選択範囲の内容を削除するという約束を含んでいます。

action は、利用可能なアクションを表すシンボルと、ドロップターゲットがユーザーに提示してそれらのアクションから選択させる文字列とを対応付けるアリストである場合もあります。

return-frame が nil ではなく、まず frame の外に移動した後にマウスが Emacs フレーム上に移動した場合、マウスが移動した先のフレームが直ちに返されます。return-frame がシンボル now である場合、マウスが frame の外に最初に移動するのを待たずに、マウスポインタの下にある任意のフレームが返されます。return-frame は、あるフレームから別のフレームへコンテンツをドラッグする場合を特別に扱いつつ、同時に他のプログラムへもコンテンツをドラッグしたい場合に有用ですが、すべてのシステムやすべてのウィンドウマネージャで動作することが保証されているわけではありません。

follow-tooltip が nil 以外の場合、任意のツールチップ(tooltip-show によって表示されるものなど)の位置は、ドラッグ&ドロップ操作中に移動するマウスポインタの位置に従います。すべてのマウスボタンが離されると、ツールチップは非表示になります。

ドロップが拒否されたか、あるいはドロップ先が見つからなかった場合、この関数は nil を返します。それ以外の場合は、ターゲットが選択しようとしたアクションを表すシンボルを返します。ドロップ先がそのアクションをサポートしていない場合、この値は action とは異なることがあります。XdndActionCopy および XdndActionMove に加えて、XdndActionPrivate も有効な戻り値となります。これは、ドロップ先が未確定のアクションを選択したことを示しており、呼び出し側でさらなるアクションを行う必要はありません。

呼び出し元は、ターゲットが選択したアクションを完了させるために、ターゲットに協力しなければなりません。例えば、この関数が XdndActionMove を返した場合、呼び出し元はドラッグされたバッファテキストを削除すべきであり、同様の基準が適用される他のドラッグデータについても同様とします。

x-begin-drag 関数は、「裏側」で複数のドラッグ&ドロッププロトコルを活用しています。特定のドラッグ&ドロッププロトコルでサポートされていないことが分かっているコンテンツをドラッグする場合、以下の変数の値を変更することで、そのプロトコルを無効化できます。

変数: x-dnd-disable-motif-protocol

これが nil 以外の場合、Motif のドラッグ&ドロッププロトコルは無効となり、それらのみに対応しているプログラム上にドロップしても動作しません。

変数: x-dnd-use-offix-drop

これが nil の場合、OffiX(旧KDE)のドラッグ&ドロッププロトコルは無効になります。これがシンボル files の場合、"FILE_NAME" が x-begin-drag に指定されたターゲットのいずれかである場合にのみ、OffiXプロトコルが使用されます。それ以外の値は、サポートされているすべてのコンテンツをドロップする際にOffiXプロトコルを使用することを意味します。

変数: x-dnd-use-unsupported-drop

x-begin-drag に指定されたリストに "STRING"、"UTF8_STRING"、"COMPOUND_TEXT"、または "TEXT" のいずれかのターゲットが含まれている場合、ドロップターゲットがドラッグ&ドロッププロトコルを一切サポートしていないなら、Emacs は合成マウスイベントとプライマリセレクションを用いてテキストを挿入しようとします。

副作用として、このようなドロップを行うと Emacs がプライマリセレクションの所有者になります。このエミュレーションは、この変数を nil に設定することで無効にできます。