Dosyayı noktada önizlemek için ayrıntılı “hızlı görüntüleme” tuşu


19

Ben dired nokta altında olan bir dosyanın "hızlı görünümü" yapan bir işlev oluşturmak istiyorum.

Bunun çalışması için istediğim yol, daha sonra dosyayı bir arabellekte görünür kılan bir işlev tuşunu basılı tutmam, ancak anahtarı bıraktığımda arabellek kapanır ve yönlendirilen arabellek geri döner. Geçici arabelleği kapatmak zorunda kalmak istemiyorum C-x k .

Emacs'ta bu işlevselliği yapmanın bir yolu var mı? Tuşlara basma / basma işlevlerini bağlayabilirsem mümkün görünüyor.


1
Depresyon olaylarına basmak için bağlanamazsınız, ancak bu işlev özel bir harita ve bir zamanlayıcı kullanarak kesinlikle saldırıya uğrayabilir.
Jordon Biondo

Önizlemeyle açılan yeni bir pencereden mi bahsediyorsunuz? Yoksa tuşa basıldığında arabellek içeriği yönetilen pencerede mi görüntülenecek?
nispio

1
Olaylara bağlanmamızı sağlayacak çabalar var mı? Bu özelliği istiyorum.
wdkrnls

Yanıtlar:


9

İşte zamanlayıcılardan yararlanarak tuş aşağı / yukarı olay bağlamasını simüle etmenin süper hacky yolu.

Genel olarak Sigma'nın cevabına girmeyi öneririm, ama denemek zorunda olduğum için önizlemeyi kapatmanın bir yolunu istediniz.

Temelde yapabileceğiniz şey, "tuşlama" işleviniz olacak bazı işlevleri bir tuşa bağlamak ve bu eylemin içinde, tuşunu basılı tuttuğunuz sürece "keyup" işleviniz olan bir işlevi yürüten bir boşta kalma zamanlayıcısı başlatın. tuşlar verildiğinde, "keydown" fonksiyonu tekrar tekrar tetiklenir ve bu da rölanti zamanlayıcılarının çalışmasını engeller. Tabii ki, komutun muhtemelen "keydown" fonksiyonunuzda bir çeşit noop fonksiyonunun anahtarını yeniden bağlayıp "keyup" fonksiyonundaki "keydown" fonksiyonunu yeniden takarak tekrar tekrar tetikleneceği gerçeğini telafi etmeniz gerekir.

Bu nedenle, kullanım durumunuz için "keydown" işleviniz, dosyanın içeriği ile birlikte bir önizleme arabelleği açar ve bu önizleme arabelleğinde, aynı tuş kombinasyonunu noop benzeri komutlara bağlar. "Keydown" işlevi, önizleme arabelleğinizi silecek ve bulunduğunuz yere geri dönmenizi sağlayacak boşta bir zamanlayıcı da başlatacaktır.

Uzun hikaye kısa burada kod:

Bu işlevi bir tuş kombinasyonuna bağlayın (kullandım C-M-v), bir dosya adının üstüne bastırdığınızda, dosyanın içeriğini görüntüleyen yeni bir tampon açacak, bıraktığınızda orijinaline geri döneceksiniz tampon.

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

Ayrıca burada eylem bir gif, tek yaptığım:

  • imlecimi dosyanın üzerine getir
  • tuş takımımı basılı tut
  • önizleme görüntülenir
  • bıraktığımda, önizleme öldürüldü ve bulunduğun yere geri döndün.

resim açıklamasını buraya girin

Unutulmaması gereken önemli bir şey, kullandığım kodda boşta kalma zamanlayıcısının saniyeleridir, .7ancak bu biraz sihirli bir sayıdır, gerçekten küçük tutmak istersiniz, ancak önizlemenin iki kez yanıp söndüğünü görürseniz, her seferinde 1/10. makineniz için doğru yeri bulana kadar.

* Ayrıca fonksiyonda önizleme arabelleğinin bazı yazı tiplerini yapmaya çalıştığımı ancak işe yarayamayacağımı, daha kullanışlı hale getirmenin bir sonraki adımı olacağını unutmayın. **


Güzel! Burada görmemiz gereken bir şey.
Malabarba

Ben Error running timer: (void-variable buffer)bununla bir buffervar, var içinde mevcut değil gibi görünüyor run-with-idle-timer?
Lee H

Sözcük bağlamanın t olmasını sağlayın
Jordon Biondo

Bu cevabı tekrarlamak isteyebilirsiniz oraya .
Malabarba

8

Yorumlarda belirtildiği gibi, işlevler olaylara değil tuşlara bağlıdır. Ancak geri adım atmak için, (muhtemelen) dosyanın içeriğini okurken anahtarı basılı tutmanızın neden önemli olduğunu anladığımdan emin değilim. Daha fazlasını elde etmek için kaydırma gibi temel (ve makul) eylemlerle de uyumsuz olur. Bir süre alırsa, rahatsız edici olabileceği gerçeğinden bahsetmiyorum bile :)

Bunun yerine bir anahtarı tekrarlamaya ne dersiniz ? Aşağıdakine benzer bir şey, işlevsel bir eşdeğerin temel iskeleti olabilir:

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

Her neyse, kullanım noktanızı bu noktada sorunuzu cevaplamaktan daha zorluyorum, çünkü bu tuşa basma / basma bağlamaları ile ilgisi yok :)


Ben dired dosyaları uzun bir liste hayal ediyorum. Dosyaların her birinin içeriğinin ne olduğundan emin değilim. Eğer F5'i görüntüleyebilseydim, F5'i görüntülemeyi bırakıp direk olarak geri dönün, sonra bir sonraki adaya devam edin, vb. Kullanım durumumu çürüttüğünüzü sanmıyorum, ancak görüntülemeyi durdurmak için F5 tuşuna tekrar basın.
Eric Brown

önerdiğiniz Midnight Commander (F3) 'deki işlevsellik ile karşılaştırılabilir
Eric Brown

1
@Sigma tarafından verilen cevap ilginç. Ancak dired kullanarak bir dizine göz atarken, dosyayı görüntülemek için v tuşuna zaten basabilir ve bu dosyayı görüntülerken çıkmak ve dizine geri dönmek için q tuşuna basabilirsiniz. Sanırım, görüntülemek ve çıkmak için aynı tuşa basmak daha kolay.
Nsukami _

@LeMeteore bana hatırlattığın için teşekkürler dired-view-file! Kodumu kaldırabilmek için düzenledim. Evet, sanırım bu tür senaryoda, farklı bir anahtara geçmek zorunda kalmamak önemlidir.
Sigma

4

Bir tuşa basıldığında dosyayı göstermek yerine, uygulanması çok zor olacaktır, bir sonraki tuşa basılana kadar dosyayı göstermenizi öneririm.

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

İşte dosyayı daha uygun bir kullanıcı arayüzü olduğunu düşündüğüm başka bir pencerede gösteren bir varyant.

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

Arabellekte kaydırma kadar çok şey yapamazsınız. Kaydırma komutlarının kabul edildiği bir “hızlı görüntüleme” modunun uygulanması daha mantıklı olabilir, ancak diğer giriş olayları hızlı görüntüleme modunun çıkmasına neden olur ve Isearch gibi önceki moda göre yorumlanır.

v( dired-view-file) İle ara bir şey elde edersiniz: arabellek Görünüm modunda düzenlenir , burada kaydırma yapabilir, arama yapabilir vb. Ancak arabelleği kapatmak basit tuş vuruşudur q.


2

Başka bir olasılık, fare kullanıyorsanız, istediğiniz önizlemeyi araç ipucuna koymaktır . Ardından, fareyi bir dosya adının (özellikli help-echo) üzerine getirdiğinizde önizleme açılır.

Bu tekniği Dired + uygulamasında , örneğin, dosya adlarını fareyle üzerine getirdiğinizde (isteğe bağlı olarak) görüntü dosyalarıyla ilişkili görüntülerin önizlemelerini göstermek için kullanıyorum.

Yükledikten sonra bunu yaparak bunun etkisini görebilirsiniz dired+.el:

  • Emin olun tooltip-modeaçıldıktan: (tooltip-mode 1).

  • Bu seçeneği sağlayın diredp-image-preview-in-tooltipolmayan bir sahiptir nil(ya küçük resim boyutu veya değeri fulltam boyutlu görüntü için).

  • Fare işaretçisini Dired'de bir görüntü dosyası adının üzerine getirin.

İşlev kodunu diredp-mouseover-helpistediğiniz şeyi yapmak için ilham kaynağı olarak kullanabilirsiniz (fareyle "hızlı görünümünüzü görüntüleyin"). Nasıl kullanılacağı hakkında bu işlevin çağrılarına bakın. İşte böyle bir çağrı:

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

Beni "fare kullanırsan" kaybettin. ;-) Bu benim için çalışmıyor. image-dirediyi çalışıyor, ama fareyle üzerine geldiğimde gördüğüm tek şeymouse-1: visit this file/dir in another window
nispio

Yüklediğim dired+.elve verdiğim diğer talimatları takip etmediysen ne dediğimi görmeyeceksin . Vanilya Emacs özelliği değildir. Nasıl istediğinizi yapmak için kendi kodunuzu haddeleme hakkında gidebilirsiniz anlatmaya çalışıyordu. dired+.elKod çok yakın, bence, istediğiniz söylediklerine etmektir. Ancak evet, fareyle üzerine gelme araç ipuçları fare kullanmanızı gerektirir. Bunu yapmazsanız, araç ipucu kullanma önerisi pek yardımcı olmaz. ;-)
Drew

Paketlerin nasıl yükleneceğini ve talimatların nasıl izleneceğini anlıyorum, ancak benim için çalışmıyor. Bu sohbeti sohbette nasıl sürdüreceğimi bilmiyorum, ama belki de bunu yapmalıyız.
nispio


1

Yönlendirilmiş bir arabellekten, vsalt görüntüleme modunda bir dosyayı ziyaret eder ve qgörüntüleme modundan çıkar ve sizi yöneltilen arabelleğe geri götürür. Bu, bir dosyayı önizlemenin hızlı bir yoludur ve arabelleği kaydırma ve hatta arama olanağı sağlar.

Emacs'ın işletim sisteminden aldığı düşük seviyeli tuş basımı mesajlarını iletme yeteneğine sahip olduğunu düşünmüyorum. Bu kısmen tarihsel nedenlerden dolayı olabilir. 1970'lerde-1980'lerde emacs geliştirilirken bilgisayar korsanları için kullanılabilir terminaller ("programcılar" oku) gerçek zamanlı tuş yukarı / aşağı olayları ile değil, basit bir karakter girişi ve kaçış dizisi ile çalıştı. Emacs, basit bir terminalin veya SSH oturumunun sınırları içinde sadece basit ASCII karakterlerini ve kaçış dizilerini kullanarak hala etkileyici bir şekilde çalışabilir.

Bu, işlevselliklerin menüler, çoklu çerçeve yönetimi ve fare etkileşimi gibi özellikleri içerecek şekilde yıllar içinde önemli ölçüde artmadığı anlamına gelmez. Emacs'ın düşük seviyeli anahtar mesajlarını uzantılara sunmak için değiştirilememesinin (özünde) hiçbir nedeni yoktur, ancak nefesinizi tutamazdım.

( Feragatname: Bu yazı, zor gerçeklerden ziyade fikir ve spekülasyon olarak alınmalıdır.)


1

Bu SO sorusunda çözümümü verdim /programming/26409768/how-to-show-buffer-content-in-real-time-in-other-window-when-focus-is-in- tampon

ve cevabım navigasyon tuşlarının davranışını değiştirmektir nve pbaşka bir pencerede noktada dosyayı göstermek için. Odak, yönlendirilmiş arabellekte kalır ve gezinmeye devam ettiğimizde ziyaret edilen arabelleği öldürürüz.

Bu özelliği kolayca etkinleştirmek / devre dışı bırakmak için küçük bir mod oluşturdum. «Normal» navigasyon için hala ok tuşlarımız olduğunu unutmayın. Ara M-x dired-show-mode(veya ranger-modebu ranger dosya yöneticisinde keşfettiğim bir özellik olduğundan ).

Kod: (herhangi bir inceleme ve hata raporu takdir edildi!) 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

Farklı bir olay okunana veya hiçbiri okunana kadar olay sırasını yoklamanız gerekir. CPU yükü oldukça düşük olmasına rağmen fark edilir.

(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)))
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.