Đã xem nhanh khóa phím xem nhanh để xem trước tập tin


19

Tôi muốn tạo một chức năng "xem nhanh" một tập tin đang được chỉ định trong thư mục.

Cách mà tôi muốn làm việc này là tôi giữ một phím chức năng, sau đó làm cho tệp hiển thị trong bộ đệm, nhưng khi tôi tắt phím, bộ đệm sẽ đóng lại và bộ đệm được chuyển hướng trở lại. Tôi không muốn phải đóng bộ đệm tạm thời với C-x k .

Có cách nào để thực hiện chức năng này trong Emacs không? Có vẻ như tôi có thể liên kết các chức năng với phím nhấn / phím tắt.


1
Bạn không thể liên kết với các sự kiện nhấn, nhưng chức năng này chắc chắn có thể bị tấn công khi sử dụng bản đồ tùy chỉnh và bộ hẹn giờ.
Jordon Biondo

Bạn đang nói về một cửa sổ mới bật lên với một bản xem trước? Hoặc nội dung của bộ đệm sẽ được hiển thị trong cửa sổ được chuyển hướng trong khi phím bị ấn xuống?
nispio

1
Có những nỗ lực để cho phép chúng ta liên kết với các sự kiện? Tôi muốn tính năng này.
wdkrnls

Câu trả lời:


9

Dưới đây là cách siêu hacky của tôi để mô phỏng ràng buộc sự kiện xuống / lên bằng cách tận dụng bộ tính giờ.

Nhìn chung, tôi khuyên bạn nên đi theo câu trả lời của Sigma, nhưng bạn đã hỏi cách đóng bản xem trước bằng cách cho đi nên tôi bắt buộc phải thử.

Về cơ bản những gì bạn có thể làm là liên kết một số chức năng sẽ là chức năng "keydown" của bạn với một keybinding và bên trong hành động đó, hãy bắt đầu một bộ đếm thời gian nhàn rỗi thực thi một chức năng là chức năng "keyup" của bạn, miễn là bạn đang giữ phím các phím đã cho, chức năng "keydown" sẽ kích hoạt liên tục và điều này sẽ ngăn cản các bộ định thời gian không hoạt động. Tất nhiên, bạn cần phải bù cho thực tế là lệnh sẽ lặp đi lặp lại, có khả năng bằng cách đảo ngược phím thành một loại chức năng noop nào đó trong chức năng "keydown" của bạn, sau đó đảo ngược chức năng "keydown" trong chức năng "keyup".

Vì vậy, trong trường hợp sử dụng của bạn, chức năng "keydown" của bạn sẽ mở ra một bộ đệm xem trước với nội dung của tệp tại điểm và trong bộ đệm xem trước đó liên kết cùng một tổ hợp phím với một số lệnh noop. Chức năng "keydown" của bạn cũng sẽ bắt đầu một bộ đếm thời gian nhàn rỗi sẽ xóa bộ đệm xem trước của bạn và khôi phục bạn trở lại vị trí của bạn.

Câu chuyện dài ở đây là đoạn mã:

Liên kết chức năng này với tổ hợp phím (tôi đã sử dụng C-M-v), khi bạn nhấn nó xuống phía trên tên tệp, nó sẽ mở một bộ đệm mới hiển thị nội dung của tệp tại điểm, khi bạn buông tay, bạn sẽ được chuyển về ban đầu đệm.

(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!"))))

Ngoài ra đây là một gif của nó trong hành động, tất cả những gì tôi làm là:

  • đặt con trỏ lên tập tin
  • nhấn và giữ phím bấm của tôi
  • bản xem trước được hiển thị
  • Khi tôi buông tay, bản xem trước bị giết và bạn trở lại vị trí của mình.

nhập mô tả hình ảnh ở đây

Một điều quan trọng cần lưu ý là số giây của máy đếm giờ nhàn rỗi, trong mã của tôi tôi đã sử dụng .7nhưng đó là một số ma thuật, bạn muốn giữ nó thật nhỏ, nhưng nếu bạn thấy bản xem trước nhấp nháy hai lần, hãy thử tăng 1/10 mỗi giây cho đến khi bạn tìm đúng vị trí cho máy của bạn

* Cũng lưu ý rằng trong chức năng tôi cố gắng thực hiện một số phông chữ của bộ đệm xem trước nhưng tôi không thể làm cho nó hoạt động, đó sẽ là bước tiếp theo để làm cho nó hữu ích hơn. **


Tốt đẹp! Đây là loại điều chúng ta cần thấy ở đây.
Malabarba

Tôi nhận được một Error running timer: (void-variable buffer)với điều này, có vẻ như buffervar không có sẵn bên trong run-with-idle-timer?
Lee H

Đảm bảo ràng buộc từ vựng là t
Jordon Biondo

Bạn có thể muốn lặp lại câu trả lời này ở đó .
Malabarba

8

Như được chỉ ra trong các bình luận, các chức năng được liên kết với các khóa, không phải các sự kiện. Nhưng để lùi lại một bước, tôi không chắc tôi hiểu tại sao điều quan trọng đối với bạn là giữ phím trong khi bạn (có lẽ) đang đọc nội dung của tệp. Nó cũng sẽ không tương thích với các hành động cơ bản (và hợp lý) như cuộn để có được nhiều hơn. Chưa kể đến việc nếu phải mất một thời gian, nó có thể trở nên khó chịu :)

Thế còn lặp đi lặp lại một chìa khóa để thay thế? Một cái gì đó như sau có thể là bộ xương cơ bản của một chức năng tương đương:

(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)

Dù sao, tôi đang thách thức trường hợp sử dụng của bạn hơn là trả lời câu hỏi của bạn tại thời điểm này, vì điều này không liên quan gì đến các ràng buộc phím / nhấn phím :)


Tôi đang tưởng tượng một danh sách dài các tập tin trong dired. Tôi không chắc nội dung của mỗi tệp là gì. Nếu tôi có thể F5 để xem, hãy tắt F5 để dừng xem và quay lại trong thư mục, sau đó tiếp tục cho ứng cử viên tiếp theo, v.v. Tôi không nghĩ bạn đã từ chối trường hợp sử dụng của tôi, nhưng bạn có thể đã đề xuất một phương án thay thế tốt nhấn F5 lần nữa để dừng xem.
Eric Brown

những gì bạn đề xuất có thể so sánh với chức năng trong Midnight Commander (F3)
Eric Brown

1
Câu trả lời được gửi bởi @Sigma rất thú vị. Nhưng khi duyệt thư mục bằng thư mục, bạn đã có thể nhấn v để xem tệp và khi xem tệp đó, nhấn q để thoát và quay lại thư mục. Tôi đoán, nhấn cùng một phím để xem và thoát là dễ dàng hơn.
Nsukami _

@LeMeteore cảm ơn đã nhắc nhở tôi dired-view-file! Tôi đã chỉnh sửa mã của mình để tận dụng nó. Vâng, tôi đoán trong loại kịch bản này, không phải chuyển sang một khóa khác là quan trọng.
Sigma

4

Thay vì hiển thị tệp trong khi nhấn phím, điều này sẽ rất khó thực hiện, tôi khuyên bạn nên hiển thị tệp cho đến khi nhấn phím tiếp theo.

(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))))

Đây là một biến thể hiển thị tệp trong một cửa sổ khác, mà tôi nghĩ là giao diện người dùng thuận tiện hơn.

(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))))

Bạn sẽ không thể làm nhiều như cuộn trong bộ đệm. Có thể có ý nghĩa hơn khi triển khai chế độ xem nhanh của Chế độ xem trong đó các lệnh cuộn được chấp nhận, nhưng các sự kiện đầu vào khác khiến chế độ xem nhanh thoát ra và được diễn giải theo chế độ trước đó, như Isearch.

Với v( dired-view-file), bạn nhận được một cái gì đó trung gian: bộ đệm được chỉnh sửa trong chế độ Xem , nơi bạn có thể cuộn xung quanh, tìm kiếm, v.v. nhưng đóng bộ đệm là tổ hợp phím đơn giản q.


2

Một khả năng khác, nếu bạn sử dụng chuột, là đặt phần xem trước bạn muốn vào một chú giải công cụ . Sau đó, khi bạn di chuyển chuột qua tên tệp (có thuộc tính help-echo), phần xem trước sẽ bật lên.

Tôi sử dụng kỹ thuật này trong Dired + , ví dụ, để (tùy chọn) hiển thị chế độ xem trước của hình ảnh được liên kết với tệp hình ảnh, khi bạn di chuột qua tên tệp.

Bạn có thể thấy tác dụng của việc này bằng cách thực hiện việc này sau khi tải dired+.el:

  • Đảm bảo rằng đã tooltip-modeđược bật : (tooltip-mode 1).

  • Đảm bảo rằng tùy chọn diredp-image-preview-in-tooltipnilgiá trị không (kích thước hình thu nhỏ hoặc fullcho hình ảnh kích thước đầy đủ).

  • Đặt con trỏ chuột lên một tên tệp hình ảnh trong Dired.

Bạn có thể sử dụng mã trong chức năng diredp-mouseover-helplàm nguồn cảm hứng để thực hiện những gì bạn muốn (hiển thị "chế độ xem nhanh" khi di chuột qua). Xem các cuộc gọi của chức năng đó để biết cách sử dụng nó. Đây là một cuộc gọi như vậy:

 (add-text-properties (line-beginning-position) (line-end-position)
                      '(mouse-face highlight help-echo diredp-mouseover-help))

Bạn đã mất tôi tại "nếu bạn sử dụng chuột." ;-) Điều này không làm việc cho tôi. image-diredhoạt động tốt, nhưng tất cả những gì tôi thấy khi tôi di chuột qua làmouse-1: visit this file/dir in another window
nispio

Bạn sẽ không thấy những gì tôi nói nếu bạn không tải dired+.elvà làm theo các hướng dẫn khác mà tôi đã đưa ra. Nó không phải là một tính năng vanilla Emacs. Tôi đã cố gắng mô tả làm thế nào bạn có thể đi về việc cuộn mã của riêng bạn để làm những gì bạn muốn. Các dired+.elmã là rất gần, tôi nghĩ rằng, những gì bạn nói bạn muốn. Nhưng vâng, chú giải công cụ di chuột yêu cầu bạn sử dụng chuột. Nếu bạn không, thì gợi ý sử dụng một tooltip sẽ không giúp ích nhiều. ;-)
vẽ

Tôi hiểu làm thế nào để tải các gói và làm theo hướng dẫn, nhưng nó không hoạt động đối với tôi. Tôi không chắc làm thế nào để tiếp tục cuộc trò chuyện này trong trò chuyện, nhưng có lẽ chúng ta nên làm điều đó.
nispio


1

Từ bộ đệm được điều hướng, vsẽ truy cập một tệp ở chế độ chỉ xem và qsẽ thoát khỏi chế độ xem và đưa bạn trở lại bộ đệm được chuyển hướng. Đây là một cách nhanh chóng để xem trước một tập tin và nó cho khả năng cuộn và thậm chí tìm kiếm bộ đệm.

Tôi không nghĩ rằng emacs có khả năng chuyển qua bất kỳ tin nhắn nhấn phím cấp thấp nào mà nó nhận được từ hệ điều hành. Điều này có thể là một phần vì lý do lịch sử. Các thiết bị đầu cuối có sẵn cho tin tặc (đọc "lập trình viên") tại thời điểm emacs được phát triển trở lại vào những năm 1970-1980 không hoạt động với các sự kiện lên / xuống khóa thời gian thực, mà là một đầu vào đơn giản của các ký tự và các chuỗi thoát. Cho đến ngày nay, các emacs vẫn có thể hoạt động tốt một cách ấn tượng trong giới hạn của một thiết bị đầu cuối đơn giản hoặc phiên SSH chỉ sử dụng các ký tự ASCII đơn giản và các chuỗi thoát.

Điều đó không có nghĩa là chức năng đã không phát triển đáng kể trong nhiều năm qua để bao gồm các tính năng như menu, quản lý nhiều khung và tương tác chuột. Không có lý do nào (mà tôi biết) rằng emacs không thể bị thay đổi (cốt lõi) để cung cấp các thông điệp chính cấp thấp cho các tiện ích mở rộng, nhưng tôi sẽ không nín thở.

( Tuyên bố miễn trừ trách nhiệm: Bài đăng này nên được coi là ý kiến ​​và suy đoán, thay vì thực tế khó khăn.)


1

Tôi đã đưa ra giải pháp của mình trong câu hỏi SO này /programming/26409768/how-to-show-buffer-content-in-real-time-in-other-window-when-f Focus-is-in- đệm

và câu trả lời của tôi là thay đổi hành vi của các phím điều hướng nphiển thị tệp tại điểm trong một cửa sổ khác. Trọng tâm vẫn nằm trong bộ đệm được chuyển hướng và chúng ta sẽ giết bộ đệm đã truy cập khi chúng ta tiếp tục duyệt.

Tôi đã tạo một chế độ nhỏ để bật / tắt tính năng này một cách dễ dàng. Lưu ý rằng chúng ta vẫn có các phím mũi tên để điều hướng «bình thường». Gọi M-x dired-show-mode(hoặc ranger-modevì đây là một tính năng tôi phát hiện ra trong trình quản lý tệp kiểm lâm ).

Mã: (mọi đánh giá và báo cáo lỗi được đánh giá cao!) Https://gitlab.com/emacs- ware / 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

Bạn cần thăm dò hàng đợi sự kiện cho đến khi một sự kiện khác, hoặc không có gì được đọc. Tải CPU là đáng chú ý, mặc dù hợp lý thấp.

(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)))
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.