diredでポイントされているファイルの「クイックビュー」を実行する関数を作成したいと思います。
これを機能させる方法は、ファンクションキーを押したままにすることです。これにより、ファイルがバッファ内で表示されるようになりますが、キーを放すとバッファが閉じて、バッファが戻ります。 で一時バッファを閉じる必要はありません C-x k
。
Emacsでこの機能を作成する方法はありますか?キー押下/押下に関数をバインドできれば可能だと思われます。
diredでポイントされているファイルの「クイックビュー」を実行する関数を作成したいと思います。
これを機能させる方法は、ファンクションキーを押したままにすることです。これにより、ファイルがバッファ内で表示されるようになりますが、キーを放すとバッファが閉じて、バッファが戻ります。 で一時バッファを閉じる必要はありません C-x k
。
Emacsでこの機能を作成する方法はありますか?キー押下/押下に関数をバインドできれば可能だと思われます。
回答:
タイマーを利用してキーダウン/アップイベントバインディングをシミュレートする私の非常にハックな方法を次に示します。
全体的には、シグマの回答をお勧めしますが、手放すことでプレビューを閉じる方法を求められたので、試してみる必要があります。
基本的にできることは、「キーダウン」機能となるいくつかの機能をキーバインディングにバインドし、そのアクション内で、「キーアップ」機能である機能を実行するアイドルタイマーを開始することです。キーを指定すると、「キーダウン」機能が何度も起動され、これによりアイドルタイマーの実行が禁止されます。もちろん、おそらく「キーダウン」関数でキーをある種のnoop関数に再バインドし、「キーアップ」関数で「キーダウン」関数を再バインドすることにより、コマンドが何度も起動するという事実を補正する必要があります。
そのため、ユースケースでは、「キーダウン」機能がポイントのファイルの内容でプレビューバッファーを開き、そのプレビューバッファーで同じキーコンボをコマンドのようなnoopにバインドします。また、「キーダウン」機能は、プレビューバッファを削除し、元の場所に戻すアイドルタイマーを開始します。
ここでの短い話はコードです:
この関数をキーコンボ(私は使用しましたC-M-v)にバインドします。ファイル名の上で押すと、新しいバッファが開き、ファイルの内容がポイントで表示されます。放すと元に戻ります。バッファ。
(setq lexical-binding t)
(defun quick-view-file-at-point ()
"Preview the file at point then jump back after some idle time.
In order for this to work you need to bind this function to a key combo,
you cannot call it from the minibuffer and let it work.
The reason it works is that by holding the key combo down, you inhibit
idle timers from running so as long as you hold the key combo, the
buffer preview will still display."
(interactive)
(let* ((buffer (current-buffer))
(file (thing-at-point 'filename t))
(file-buffer-name (format "*preview of %s*" file)))
(if (and file (file-exists-p file))
(let ((contents))
(if (get-buffer file)
(setq contents (save-excursion
(with-current-buffer (get-buffer file)
(font-lock-fontify-buffer)
(buffer-substring (point-min) (point-max)))))
(let ((new-buffer (find-file-noselect file)))
(with-current-buffer new-buffer
(font-lock-mode t)
(font-lock-fontify-buffer)
(setq contents (buffer-substring (point-min) (point-max))))
(kill-buffer new-buffer)))
(switch-to-buffer (get-buffer-create file-buffer-name))
(setq-local header-line-format "%60b")
(delete-region (point-min) (point-max))
(save-excursion (insert contents))
(local-set-key (kbd "C-M-v") (lambda () (interactive) (sit-for .2)))
(run-with-idle-timer
.7
nil
(lambda ()
(switch-to-buffer buffer)
(kill-buffer file-buffer-name))))
(message "no file to preview at point!"))))
また、動作中のgifもここにあります。
私が使用し.7
たコードでは、アイドルタイマーの秒数に注意する必要がありますが、これは魔法の数字のようなものです。本当に小さくしたいのですが、プレビューが2回点滅する場合は、毎秒1/10マシンに最適な場所が見つかるまで。
*また、この関数ではプレビューバッファーのフォント化を試みますが、プレビューバッファーを機能させることができなかったことに注意してください。
Error running timer: (void-variable buffer)
はこれで取得します、buffer
varはrun-with-idle-timer
?の内部では利用できないようです
コメントで指摘されているように、関数はイベントではなくキーにバインドされています。しかし、一歩後退するために、ファイルの内容を(おそらく)読んでいる間にキーを押したままにすることが重要である理由がわかりません。また、スクロールなどの基本的な(および合理的な)アクションと互換性がなく、より多くの情報を取得できます。時間がかかると不快になるかもしれないという事実は言うまでもありません:)
代わりにキーを繰り返すのはどうですか?次のようなものは、機能的に同等の基本的なスケルトンになります。
(defun my-dired-view-file ()
(interactive)
(dired-view-file)
(local-set-key (kbd "<f5>") 'View-quit))
(define-key dired-mode-map (kbd "<f5>") 'my-dired-view-file)
とにかく、この時点であなたの質問に答えるよりもあなたのユースケースに挑戦しています、これはキー押下/押下バインドとは何の関係もないからです:)
dired-view-file
!コードを編集して活用しました。はい、この種のシナリオでは、別のキーに移動する必要がないことが重要です。
キーを押しながらファイルを表示するのではなく、実装が非常に難しいため、次のキーが押されるまでファイルを表示することをお勧めします。
(defun dired-find-file-until-key ()
(interactive)
(let ((filename (dired-file-name-at-point))
(buffer-count (length (buffer-list))))
(dired-find-file)
(message "Showing %s temporarily..." filename)
(isearch-unread-key-sequence (list (read-event)))
(if (= (length (buffer-list)) buffer-count)
(bury-buffer)
(kill-buffer))))
別のウィンドウにファイルを表示するバリアントを次に示します。これは、より便利なユーザーインターフェイスだと思います。
(defun dired-find-file-other-window-until-key ()
(interactive)
(let ((buffer-count (length (buffer-list))))
(dired-find-file-other-window)
(isearch-unread-key-sequence (list (read-event)))
(if (= (length (buffer-list)) buffer-count)
(delete-window)
(kill-buffer-and-window))))
バッファ内をスクロールするほどのことはできません。スクロールコマンドが受け入れられる「クイックビュー」モードを実装する方が理にかなっている場合がありますが、他の入力イベントによりクイックビューモードが終了し、Isearchなどの以前のモードに従って解釈されます。
v
(dired-view-file
)、あなたは中間の何かを得る:バッファがで編集された表示モード、あなたが検索し、周りにスクロールすることができ、などが、バッファを閉じることは簡単なキー操作ですq
。
マウスを使用する場合のもう1つの可能性は、必要なプレビューをツールチップに配置することです。次に、ファイル名(プロパティhelp-echo
)の上にマウスを移動すると、プレビューがポップアップ表示されます。
Dired +でこの手法を使用して、たとえば、ファイル名にマウスオーバーしたときに、(オプションで)画像ファイルに関連付けられた画像のプレビューを表示します。
ロード後にこれを行うと、この効果を確認できますdired+.el
。
tooltip-mode
オンになっていることを確認します(tooltip-mode 1)
。
オプションに値diredp-image-preview-in-tooltip
がないことを確認してくださいnil
(サムネイルサイズまたはfull
フルサイズの画像のいずれか)。
Diredの画像ファイル名の上にマウスポインターを置きます。
関数のコードを使用diredp-mouseover-help
して、必要なことを行うためのインスピレーションとして使用できます(マウスオーバーで「クイックビュー」を表示します)。使用方法については、その関数の呼び出しを参照してください。そのような呼び出しの1つを次に示します。
(add-text-properties (line-beginning-position) (line-end-position)
'(mouse-face highlight help-echo diredp-mouseover-help))
image-dired
作品の罰金が、私のマウスが終わったとき、私が見るすべてmouse-1: visit this file/dir in another window
dired+.el
、私が与えた他の指示に従わない場合、あなたは私が言ったことを見ることができません。これはバニラEmacsの機能ではありません。私は、あなたが望むことをするためにあなた自身のコードを転がすことができる方法を説明しようとしていました。dired+.el
コードは非常に近く、私が思うに、あなたが欲しい言うことにあります。ただし、マウスオーバーツールチップを使用するには、マウスを使用する必要があります。そうしないと、ツールチップを使用するという提案はあまり役に立ちません。;-)
diredバッファーから、v表示専用モードでファイルにアクセスし、q表示モードを終了してdiredバッファーに戻ります。これはファイルをプレビューする簡単な方法であり、スクロールしたり、バッファを検索したりすることもできます。
emacsには、オペレーティングシステムから受信する低レベルのキープレスメッセージを渡す機能がないと思います。これは、部分的には歴史的な理由による可能性があります。1970年代から1980年代にemacsが開発された当時、ハッカーが利用できる端末(「プログラマー」)は、リアルタイムのキーアップ/ダウンイベントではなく、文字とエスケープシーケンスの単純な入力では機能しませんでした。今日まで、emacsは、単純なASCII文字とエスケープシーケンスのみを使用して、単純な端末またはSSHセッションの範囲内で非常に良好に動作します。
それは、メニュー、マルチフレーム管理、マウス操作などの機能を含む機能が長年にわたって大幅に成長していないということではありません。低レベルのキーメッセージを拡張機能で利用できるようにするためにemacsを(コアで)変更できなかった理由はありません(私は承知しています)が、息を止めません。
(免責事項:この投稿は、確固たる事実ではなく、意見と推測と見なすべきです。)
私はこのSOの質問/programming/26409768/how-to-show-buffer-content-in-real-time-in-other-window-when-focus-is-in-でソリューションを与えましたバッファ
そして私の答えは、ナビゲーションキーの動作を変更することであるn
とp
、別のウィンドウ内の点でファイルを表示します。フォーカスはdiredバッファーにとどまり、ブラウジングを続行するときに訪問済みバッファーを削除します。
この機能を簡単に有効/無効にするために、マイナーモードを作成しました。«通常»ナビゲーション用の矢印キーがまだあることに注意してください。呼び出しますM-x dired-show-mode
(またはranger-mode
、これはレンジャーファイルマネージャーで発見した機能です)。
コード:(レビューやバグレポートを歓迎します!) https://gitlab.com/emacs-stuff/my-elisp/blob/master/dired-show.el
(defgroup dired-show nil
"See the file at point when browsing in a Dired buffer."
:group 'dired
)
(setq show-next-current-buffer nil)
(defun show-next ()
(interactive)
(next-line 1)
(dired-find-file-other-window)
(if show-next-current-buffer (kill-buffer show-next-current-buffer))
(setq show-next-current-buffer (current-buffer))
(other-window 1)
)
(defun show-previous ()
(interactive)
(previous-line 1)
(dired-find-file-other-window)
(if show-next-current-buffer (kill-buffer show-next-current-buffer))
(setq show-next-current-buffer (current-buffer))
(other-window 1)
)
(define-minor-mode dired-show-mode
"Toggle preview of files when browsing in a Dired buffer."
:global t
:group 'dired-show
(if dired-show-mode
(progn
(define-key dired-mode-map "n" 'show-next)
(define-key dired-mode-map "p" 'show-previous)
)
(define-key dired-mode-map "n" 'diredp-next-line)
(define-key dired-mode-map "p" 'diredp-previous-line)
))
(defalias 'ranger-mode 'dired-show-mode)
(provide 'dired-show)
;;; dired-show ends here
別のイベントが読み込まれるまで、または読み込まれないまで、イベントキューをポーリングする必要があります。CPU負荷はかなり低いですが、かなり顕著です。
(defun dired-preview-command ()
(interactive)
(let* ((file (or (dired-get-filename nil t)
(error "No file here")))
(visited-p (get-file-buffer file))
(buffer (or visited-p (find-file-noselect file)))
(window
(display-buffer buffer '(nil . ((inhibit-same-window . t)))))
(event (read-event)))
(while (and event (eq last-command-event event))
(setq event (read-event nil nil 0.1)))
(when event
(setq unread-command-events
(list event)))
(quit-window (not visited-p) window)))