ポイントでファイルをプレビューするための「クイックビュー」キーを押した


19

diredでポイントされているファイルの「クイックビュー」を実行する関数を作成したいと思います。

これを機能させる方法は、ファンクションキーを押したままにすることです。これにより、ファイルがバッファ内で表示されるようになりますが、キーを放すとバッファが閉じて、バッファが戻ります。 で一時バッファを閉じる必要はありません C-x k

Emacsでこの機能を作成する方法はありますか?キー押下/押下に関数をバインドできれば可能だと思われます。


1
押し下げイベントにバインドすることはできませんが、この機能はカスタムマップとタイマーを使用して確実にハッキングできます。
ジョーダンビオンド14

プレビューでポップアップする新しいウィンドウについて話していますか?または、キーが押されている間、バッファの内容がdiredウィンドウに表示されますか?
nispio 14

1
イベントにバインドできるようにする努力はありますか?この機能が欲しい。
wdkrnls 14年

回答:


9

タイマーを利用してキーダウン/アップイベントバインディングをシミュレートする私の非常にハックな方法を次に示します。

全体的には、シグマの回答をお勧めしますが、手放すことでプレビューを閉じる方法を求められたので、試してみる必要があります。

基本的にできることは、「キーダウン」機能となるいくつかの機能をキーバインディングにバインドし、そのアクション内で、「キーアップ」機能である機能を実行するアイドルタイマーを開始することです。キーを指定すると、「キーダウン」機能が何度も起動され、これによりアイドルタイマーの実行が禁止されます。もちろん、おそらく「キーダウン」関数でキーをある種の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マシンに最適な場所が見つかるまで。

*また、この関数ではプレビューバッファーのフォント化を試みますが、プレビューバッファーを機能させることができなかったことに注意してください。


いいね!これは、ここで見る必要のあるものです。
マラバルバ14

Error running timer: (void-variable buffer)はこれで取得します、buffervarはrun-with-idle-timer?の内部では利用できないようです
リーH 14年

字句バインディングがtであることを確認してください
Jordon Biondo 14年

あそこでこの答えを繰り返したくなるかもしれません。
マラバルバ14年

8

コメントで指摘されているように、関数はイベントではなくキーにバインドされています。しかし、一歩後退するために、ファイルの内容を(おそらく)読んでいる間にキーを押したままにすることが重要である理由がわかりません。また、スクロールなどの基本的な(および合理的な)アクションと互換性がなく、より多くの情報を取得できます。時間がかかると不快になるかもしれないという事実は言うまでもありません:)

代わりにキーを繰り返すのはどうですか?次のようなものは、機能的に同等の基本的なスケルトンになります。

(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のファイルの長いリストを想像しています。各ファイルの内容が不明です。F5で表示できる場合は、F5をオフにして表示を停止し、次の候補に進みます。次の候補に進みます。 F5をもう一度押すと、表示が停止します。
エリックブラウン14

何を示唆して真夜中の司令官(F3)での機能と同等である
エリック・ブラウン

1
@Sigmaが提出した回答は興味深いものです。ただし、diredを使用してディレクトリを参照するときは、vキーを押してファイルを表示できます。そのファイルを表示するときは、qキーを押して終了し、ディレクトリに戻ります。表示と終了に同じキーを押す方が簡単だと思います。
Nsukami _ 14

@LeMeteoreを思い出させてくれてありがとうdired-view-file!コードを編集して活用しました。はい、この種のシナリオでは、別のキーに移動する必要がないことが重要です。
シグマ14

4

キーを押しながらファイルを表示するのではなく、実装が非常に難しいため、次のキーが押されるまでファイルを表示することをお勧めします。

(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などの以前のモードに従って解釈されます。

vdired-view-file)、あなたは中間の何かを得る:バッファがで編集された表示モード、あなたが検索し、周りにスクロールすることができ、などが、バッファを閉じることは簡単なキー操作ですq


2

マウスを使用する場合のもう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
nispio

あなたがロードしdired+.el、私が与えた他の指示に従わない場合、あなたは私が言ったことを見ることができません。これはバニラEmacsの機能ではありません。私は、あなたが望むことをするためにあなた自身のコードを転がすことができる方法を説明しようとしていました。dired+.elコードは非常に近く、私が思うに、あなたが欲しい言うことにあります。ただし、マウスオーバーツールチップを使用するには、マウスを使用する必要があります。そうしないと、ツールチップを使用するという提案はあまり役に立ちません。;-)
ドリュー

パッケージをロードして指示に従う方法を理解していますが、うまくいきません。チャットでこの会話を再開する方法はわかりませんが、おそらくそれを行う必要があります。
nispio 14


1

diredバッファーから、v表示専用モードでファイルにアクセスし、q表示モードを終了してdiredバッファーに戻ります。これはファイルをプレビューする簡単な方法であり、スクロールしたり、バッファを検索したりすることもできます。

emacsには、オペレーティングシステムから受信する低レベルのキープレスメッセージを渡す機能がないと思います。これは、部分的には歴史的な理由による可能性があります。1970年代から1980年代にemacsが開発された当時、ハッカーが利用できる端末(「プログラマー」)は、リアルタイムのキーアップ/ダウンイベントではなく、文字とエスケープシーケンスの単純な入力では機能しませんでした。今日まで、emacsは、単純なASCII文字とエスケープシーケンスのみを使用して、単純な端末またはSSHセッションの範囲内で非常に良好に動作します。

それは、メニュー、マルチフレーム管理、マウス操作などの機能を含む機能が長年にわたって大幅に成長していないということではありません。低レベルのキーメッセージを拡張機能で利用できるようにするためにemacsを(コアで)変更できなかった理由はありません(私は承知しています)が、息を止めません。

免責事項:この投稿は、確固たる事実ではなく、意見と推測と見なすべきです。)


1

私はこのSOの質問/programming/26409768/how-to-show-buffer-content-in-real-time-in-other-window-when-focus-is-in-でソリューションを与えましたバッファ

そして私の答えは、ナビゲーションキーの動作を変更することであるnp、別のウィンドウ内の点でファイルを表示します。フォーカスは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

0

別のイベントが読み込まれるまで、または読み込まれないまで、イベントキューをポーリングする必要があります。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)))
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.