Как можно быстро просмотреть множество файлов в Emacs?
Есть ли способ быстро просмотреть множество файлов в Emacs (24.3)? Более конкретно:
Давайте предположим, что фрейм Emacs разделен на два окна. Предположим, фокус находится в левом окне, в котором есть открытый буфер с большим количеством текстовых файлов (или кода). Я хотел бы идти вверх и вниз по списку файлов (например, с помощью клавиш курсора), в то же время текущий файл отображается в правом окне. Более того, файл просматривается и закрывается только после того, как я перейду в буфер с задержкой к следующему файлу. Это было бы очень полезно, особенно в сочетании с некоторым режимом "пропустить".
Можно ли это сделать в "dired"? Я также не могу найти эту функцию в Dired-X или в Sunrise-Commander. Является ли это возможным?
Лучшие кандидаты, которых я пробовал (и почему они не решают проблему):
"V", который показывает текущий файл, но также перемещает внимание
'Co', который показывает текущий файл, но после перемещения вверх или вниз мне нужно снова нажать Co, также он генерирует много буферов
Большое спасибо за вашу помощь!
7 ответов
Большое спасибо за все эти ответы. Подводя итог, я создал следующее решение (расширив ответ "abo-abo"):
;; little modification to dired-mode that let's you browse through lots of files
(add-hook 'dired-mode-hook
(lambda()
(define-key dired-mode-map (kbd "C-o") 'dired-view-current) ; was dired-display-file
(define-key dired-mode-map (kbd "n") 'dired-view-next) ; was dired-next-line
(define-key dired-mode-map (kbd "p") 'dired-view-previous))) ; was dired-previous-line
(defun dired-view-next ()
"Move down one line and view the current file in another window."
(interactive)
(dired-next-line)
(dired-view-current))
(defun dired-view-previous ()
"Move up one line and view the current file in another window."
(interactive)
(dired-previous-line)
(dired-view-current))
(defun dired-view-current ()
"View the current file in another window (possibly newly created)."
(interactive)
(if (not (window-parent))
(split-window)) ; create a new window if necessary
(let ((file (dired-get-file-for-visit))
(dbuffer (current-buffer)))
(other-window 1) ; switch to the other window
(unless (equal dbuffer (current-buffer)) ; don't kill the dired buffer
(if (or view-mode (equal major-mode 'dired-mode)) ; only if in view- or dired-mode
(kill-buffer))) ; ... kill it
(let ((filebuffer (get-file-buffer file)))
(if filebuffer ; does a buffer already look at the file
(switch-to-buffer filebuffer) ; simply switch
(view-file file)) ; ... view it
(other-window -1)))) ; give the attention back to the dired buffer
Три клавиши изменены:
C-o
просмотреть текущий элемент в другом окне (возможно, создать его).n
для просмотра следующего элемента в другом окне.p
просмотреть предыдущий элемент в другом окне.
Это может быть использовано в буфере Dired. Обратите внимание, что только буферы в режиме Dired и буферы в режиме просмотра убиваются при перемещении вверх и вниз. Если файл показывает, что другой буфер уже посещает (не в режиме просмотра), этот буфер также отображается, но не уничтожается при переходе к следующему. Еще одна тонкость - это случай, когда пассивно показанный буфер является буфером с задержкой, используемым для просмотра списка (это может легко случиться, когда вы входите в папку с RET
). Чтобы разобраться с этим случаем, мы сначала проверяем, пытаемся ли мы уничтожить начальный буфер с задержкой.
Вот как я делаю это с view-mode
:
(add-hook 'view-mode-hook
(lambda()
(define-key view-mode-map (kbd "n") 'dired-view-next)
(define-key view-mode-map (kbd "p") 'dired-view-prev)))
(defun dired-view-next ()
"Move to next dired line and view ."
(interactive)
(quit-window)
(dired-next-line 1)
(dired-view-file))
(defun dired-view-prev ()
"Move to next dired line and view ."
(interactive)
(quit-window)
(dired-next-line -1)
(dired-view-file))
UPD:
У этого есть две панели:
(defun dired-view-next-pane ()
(interactive)
(other-window 1)
(if view-mode
(kill-buffer))
(other-window -1)
(dired-next-line 1)
(view-file-other-window
(dired-get-file-for-visit))
(other-window -1))
Простое и общее (хотя и не оптимальное) решение может быть с помощью механизма Cx ().
Сначала откройте две панели в Emacs, и, скажем, верхняя часть будет запущена.
- Нажмите o, чтобы открыть первый файл на 2- й панели.
Затем вы можете запустить механизм повторения:
- сделать Cx ( чтобы начать запись макроса
- сделать Cx k и вернуться, чтобы закрыть буфер
- сделать снова, чтобы вернуться в Dired
- нажмите клавишу вниз, чтобы перейти к следующему файлу
- сделать o, чтобы открыть следующий файл в нижней панели
- сделать Cx), чтобы завершить макрос
С этого момента (находясь в нижней панели, в верхней панели), просто
- Cx e (и только тогда e, если между ними нет других операций)
будет автоматически
- закрыть файл нижней панели, перейти к верхней панели, перейти к следующему файлу, открыть его в нижней панели
Возможно, есть более конкретный способ сделать это, но знание механизма макросов в любом случае очень полезно в Emacs.
Загрузите Сосульки.
Определите эту команду:
(defun my-find-file () Msgstr "Как`icicle-find-file', но alt action временно просматривает файл. Альтернативные ключи действий, такие как `CS-down', посещают файл кандидата в `view-mode 'и уничтожить буфер последнего такого просматриваемого кандидата." (Интерактивный) (пусть ((icicle -андидат-alt-action-fn (лямбда (файл) (когда (и мой последний просмотренный (get-file-buffer my-last-views)) (kill-buffer (get-file-buffer my-last-просмотров))) (setq my-last-views (файл сокращенного имени файла)) (просмотр файла-файла) (Выберите кадр набора входов-фокус (оконная рама (активное-минибуферное окно)))))) (Сосулька-найти-файл-из-контента))) (defvar мой последний просмотренный ноль "Последний файл, просмотренный альтернативным действием` my-find-file '. ")
Тогда ты можешь:
- использование
M-x my-find-file
(или связать его с ключом - например,C-x C-f
). - При желании введите часть имени файла, чтобы ограничить совпадающие имена.
- Опционально использовать
down
или жеup
цикл между именами файлов. - использование
C-S-down
посетить следующий файл по порядку. - Повторите #4, чтобы увидеть другие файлы по порядку.
- Повторите #2 или #3, чтобы увидеть другие наборы файлов.
- Конец с
RET
выбрать файл для посещения илиC-g
отменить.
Каждый файловый буфер, который вы посетили C-S-down
был убит при просмотре следующего. Вы также можете смешать в C-down
или же C-RET
также посещать файлы, чьи буферы вы не хотите уничтожать автоматически. (Изменить view-file
в find-file
если вы не хотите побывать в view-mode
, который только для чтения.)
[По умолчанию альтернативное действие для icicle-find-file
являетсяicicle-alt-act-fn-for-type
, который запрашивает у вас соответствующее файлу действие для конкретного кандидата, выбранного для действия. команда my-find-file
просто заменяет другую альтернативную функцию действия (для всех выбранных вами кандидатов).]
Смотрите также эту ветку по адресу help-gnu-emacs@gnu.org. Думаю, это почти такой же вопрос, как и ваш. Мои ответы были почти такими же, как мой ответ здесь, но есть и ответы других, которые также могут вам помочь.
Другое решение для режима просмотра поверх списков ag-mode. Я не смог найти вопрос для ag-mode, возможно, это поможет кому-то обобщить ffap-preview для любого режима.
(defun directory-ag-results ()
(save-excursion
(goto-char (point-min))
(search-forward "\"")
(setq a (point))
(search-forward "\"")
(setq b (- (point) 1))
(buffer-substring-no-properties a b)))
(defun search-item-path ()
(let ((dir (directory-ag-results))
(file-parts (split-string (substring-no-properties (thing-at-point 'filename)) ":")))
(concat dir (nth 0 file-parts))))
(defun search-item-line ()
(let ((file-parts (split-string (substring-no-properties (thing-at-point 'filename)) ":")))
(- (string-to-number (nth 1 file-parts)) 1)))
(defun view-current ()
"Quickly view the current file in another window."
(if (not (window-parent))
(split-window)) ; create a new window if necessary
(let ((file (search-item-path))
(line (search-item-line))
(dbuffer (current-buffer)))
(other-window 1) ; switch to the other window
(unless (equal dbuffer (current-buffer)) ; don't kill the dired buffer
(if (or view-mode (equal major-mode 'dired-mode)) ; only if in view- or dired-mode
(kill-buffer))) ; ... kill it
(let ((filebuffer (get-file-buffer file)))
(if filebuffer ; does a buffer already look at the file
(switch-to-buffer filebuffer) ; simply switch
(progn
(view-file file) ; ... view it
(goto-char (point-min))
(next-line line)))
(other-window -1))))
(defun next-view-current ()
(interactive)
(next-line)
(view-current))
(defun previous-view-current ()
(interactive)
(previous-line)
(view-current))
(define-key ag-mode-map (kbd "M-p") 'previous-view-current)
(define-key ag-mode-map (kbd "M-n") 'next-view-current)
Это единственное, что, я думаю, Sublime делает лучше, чем Emacs. Богохульство, я знаю! Мне нравится ощущение "q to exit" в режиме просмотра, а не решения на основе таймера, и мне нравится прокручивать предварительно просматриваемый файл. Этот фрагмент перемещается к номеру строки, найденному в результатах поиска, оптимизируя скорость просмотра.
Примечание о коде: я попытался заполнить vc-root-dir из Emacs 25, но это не имеет смысла для ag-режима, так как буфер ag-mode находится вне репо, в котором вы ищете. В итоге я извлек рут dir из верхней части буфера "ag search".
Ранние стадии. Улучшения приветствуются.
Редактировать: он работает в режиме аг, не Dired. Демоверсия
Кредиты: abo-abo, user2979331
В интересах поддержания StackOverflow в актуальном состоянии пакет peep-dired делает все, что опубликовано в других ответах, и я уверен, что есть и другие пакеты. Вам не нужно поддерживать скопированный или доморощенный лисп для этой работы.