次: , 前: Lazy Properties, 上: Text Properties


31.19.9 クリック可能なテキストを定義する

バッファ内にクリック可能なテキスト(clickable text)を設定するには 2つの方法があります。 これは典型的には2つの部分から成ります。 つまり、マウスが重なるとテキストを強調表示し、 テキストのその部分をクリックすると マウスボタンがなんらかの処理を行うようにします。

強調表示はテキスト属性mouse-faceで行います。 diredでの方法を例として示します。

     (condition-case nil
         (if (dired-move-to-filename)
             (put-text-property (point)
                                (save-excursion
                                  (dired-move-to-end-of-filename)
                                  (point))
                                'mouse-face 'highlight))
       (error nil))

put-text-propertyの最初の2つの引数は、 テキストの先頭と末尾を指定します。

このテキストをクリックしたときにマウスになにかをさせるようにする 普通の方法は、メジャーモードのキーマップでmouse-2を定義することです。 クリック可能なテキストをクリックしたかどうかの検査は、 コマンド定義で行われます。 diredではつぎのようにしています。

     (defun dired-mouse-find-file-other-window (event)
       "In dired, visit the file or directory name you click on."
       (interactive "e")
       (let (file)
         (save-excursion
           (set-buffer (window-buffer (posn-window (event-end event))))
           (save-excursion
             (goto-char (posn-point (event-end event)))
             (setq file (dired-get-filename))))
         (select-window (posn-window (event-end event)))
         (find-file-other-window (file-name-sans-versions file t))))

外側のsave-excursionは、カレントバッファが変わることを防ぎます。 内側のは、クリックしたバッファのポイントを恒久的に変更することを防ぎます。 この例では、diredは関数dired-get-filenameを用いて、 イベントの位置に基づいて訪問すべきファイルを決定します。

メジャーモードのマウスコマンドを定義するかわりに、 テキスト属性local-mapを使って、 クリック可能なテキストそのものにキーバインディングを定義することもできます。

     (let ((map (make-sparse-keymap)))
       (define-key-binding map [mouse-2] 'operate-this-button)
       (put-text-property (point)
                          (save-excursion
                            (dired-move-to-end-of-filename)
                            (point))
                          'local-map map))

この方法では、テキストのさまざまなクリック可能な部分に 異なるコマンドを定義できます。 さらに、バッファの残りの部分に対しては、 メジャーモードの定義(やグローバルな定義)がそのまま有効です。