як отримати буфери (не лише файли) для вшанування автоматичного режиму?


13

Питання: як я можу отримати нові буфери для вшанування відображення auto-mode-alist?

При пошуку файлу Emacs порівнює розширення файлу з тим, auto-mode-alistщоб визначити, який основний режим використовувати для буфера файлу. Чи є спосіб використовувати інформацію auto-mode-alistдля визначення режиму для буфера, який ще не має (пов'язаний) з ним файл?

Тобто: якщо я відкрию новий буфер , ім'я якого має щось схоже на розширення файлу, чи можу я змусити його автоматично відкриватися в очікуваному режимі? Наприклад, якщо я мав би відкрити новий буфер, a-new-buffer.elякий ще не пов'язаний з файлом, я хочу, щоб він відкривався, emacs-lisp-modeа не в режимі за замовчуванням.


2
Просто цікаво: у чому справа використання? IOW, чому / коли / в якому контексті ти хочеш це робити? Як правило, якщо ви хочете, щоб буфер був пов’язаний з файлом і таким чином вибирали його режим auto-mode-alist, ви робите буфер " відвідувати " файл (і це бере на себе все).
Дрю

5
Прикладами типових для мене випадків використання є: а) тимчасовий orgбуфер для перевірки нових функцій, в яких я пишу для використання org-mode; б) тимчасовий Rбуфер для здійснення деяких швидких статистичних маніпуляцій; в) тимчасовий текстовий буфер для створення електронної пошти. У кожному випадку я не хочу створювати файл для відвідування, я просто хочу викинути буфер, який, тим не менш, відкриється у відповідному режимі.
Дан

2
Файлові відвідування команди , такі як C-x C-fби НЕ « створити файл для відвідування ». Це принципове непорозуміння. Вони просто роблять саме те, що ви шукаєте. Це тільки якщо і коли ви намагаєтеся зберегти буфер , що файл буде створений. Якщо ви не намагаєтеся зберегти буфер, файл не створюється. Те, що ви хочете, з того, що я розумію до цього часу, - це "відвідати файл" (що насправді означає відкрити буфер у належному режимі).
Дрю

8
Як і Ден, я створюю тимчасові буфери весь час, які я не хочу асоціювати з фактичним шляхом до файлу. Відвідування помилкового файлового шляху буде спрацьовувати, але при виборі каталогу (або прийнятті поточного) існує хоча б невелика кількість тертя. Можуть бути й інші побічні ефекти, залежно від решти вашої конфігурації: Автоматичне збереження поведінки? Групи Ibuffer або снаряди, визначені шляхом? Підказки підтвердження Ido? Оскільки в буферах все одно має бути ім'я, для мене має сенс використовувати ім'я для автоматичного встановлення режиму тимчасового буфера.
глюкас

@Drew, так, це має сенс, і це було б найпростішою відповіддю на це питання - чи можете ви опублікувати це як відповідь, будь ласка? Він заслуговує на оновлення.
Дан

Відповіді:


8

Файли команд відвідування, таких як C-x C-f не створювати файл для відвідування. Вони роблять те, що ви шукаєте.

Файл створюється лише тоді, коли ви намагаєтесь зберегти буфер .

Якщо ви не намагаєтеся зберегти буфер, файл не створюється. Те, що ви хочете, з того, що я розумію до цього часу, - це " відвідати файл " (що насправді означає відкрити буфер у належному режимі).


4
Що робити, якщо у вас гіперактивний палець, який постійно зберігає поточний файл кожні 3 секунди незалежно від того, що ви хочете?
Малабарба

1
@Malabarba: Насправді я маю цей палець! ;-) Можливо, більшість із нас, старі пукає, це роблять - звичка відбиралася назад, коли речі весь час руйнувалися. Але все одно, я роблю саме те, що я запропонував: редагувати в буфері відвіданого файлу, який викинув. Якщо моя гіперактивна м’язова пам’ять заважає і намагається зберегти, так і бути: будь я натискаю, nщоб не зберегти, або (часто) я просто зберігаю буфер. А пізніше я підкидаю створений файл ... чи ні.)
Дрю

1
@Malabarba Саме для того, щоб запобігти захаращенню тимчасових файлів, я почав використовувати спеціальні буфери подряпин для основного режиму. Якщо нуля заслуговує на файл, ви завжди можете зберегти його як пізніше.
Каушал Моді

1
@kaushalmodi: Нічого проти буферів, що стосуються вашого режиму, але " загроза тимчасових файлів " так само легко очищається, як і буфер буферів . ;-) І гіперактивний палець у специфічному для режиму буфера подряпин представляє ту саму проблему, імовірно - таку ж, як і в *scratch*: вам буде запропоновано зберегти, коли цей палець автоматично потрапить C-x C-s.
Дрю

9

Якщо рішенням Юрі Лінков користувалися роками.

Я створюю тимчасові буфери з чимось подібним C-x b test.org C-j. major-modeВизначається розширенням файлу через auto-mode-alist.

;; http://thread.gmane.org/gmane.emacs.devel/115520/focus=115794
(setq-default major-mode
              (lambda () (if buffer-file-name
                          (fundamental-mode)
                            (let ((buffer-file-name (buffer-name)))
                          (set-auto-mode)))))

Щоб перевірити ефект, можна спробувати (prog1 (and (switch-to-buffer "my-new.org") major-mode) (kill-buffer "my-new.org")) => org-mode. У чистоті emacs -qтест повернувся б fundamental-mode.


1
Це дуже розумно! Це також охайніше, ніж adviceваріант, який я використовував. Не впевнений, що я слідкую за тим, для чого потрібна (prog1...)частина, але (setq-default major-mode ...)частина є досить приємною.
Дан

1
Ви можете перевірити сайт Emacs Juri . У prog1-TEST просто показує , що ви отримаєте очікуваний major-modeпри перемиканні в буфер. Оцініть setq-defaultдеталь і проведіть тест. Він повернеться org-mode Без того, setq-defaultщо повернеться fundamental-mode.
rasmus

Це спосіб більш елегантний, ніж мій буфер-список-оновлення-гачок. Спасибі!
глюкас

це має бути прийнятою відповіддю, оскільки він насправді відповідає на питання, а не повідомляє нам, чому ми помиляємось, коли його задаємо :)
Shlomi

6

Вигадав поради на основі порад, використовуючи ідеї, що випливали з коментарів @ Drew та відповіді @ glucas, які я запишу тут, якщо вони корисні для когось.

Коротка версія: скористайтеся afterпорадами, щоб запитати, чи має буфер пов’язане ім'я файлу, встановіть його тимчасово, якщо це не так, а потім дозвольте решті set-auto-modeмеханізмів подбати про деталі. Після трохи тестування (не обширного), здається, це працює просто чудово.

Для ido-switch-bufferванілі switch-to-bufferдва поради:

(defadvice ido-switch-buffer (after set-mode activate)
  (unless buffer-file-name
    (let ((buffer-file-name (buffer-name)))
      (set-auto-mode t))))

(defadvice switch-to-buffer (after set-mode activate)
  (unless buffer-file-name
    (let ((buffer-file-name (buffer-name)))
      (set-auto-mode t))))

Я вважаю цей варіант корисним find-fileнапроти того, що @Drew підняв, тому що мої пальці можуть випереджати мій мозок: м'язова пам’ять часто переводить мене на територію перемикання на буфер, перш ніж мені це станеться повністю, що find-fileзробить те, що мені потрібно. Тепер доступні обидва варіанти.

ОНОВЛЕННЯ: невелика, але потенційно дратує помилку у наведеному вище коді: вона буде повторно запускати гачок режиму на буфері щоразу, коли ви переходите на нього. Нижче наведено фактичне ім'я файлу з /tmpкаталогу та уникає цієї проблеми:

(defadvice ido-switch-buffer (after set-mode activate)
  (unless buffer-file-name
    (setq buffer-file-name (concat "/tmp/" (buffer-name)))
    (set-auto-mode t)))

Виглядає добре, і очищає суть, моя відповідь накопичилася за пару ітерацій. :-) Я просто повторю тут, що якщо ви з якоїсь причини не хочете встановлювати фактичний шлях до файлу, ви можете використовувати локальну змінну буфера, щоб уникнути встановлення режиму кілька разів.
глюкас

5

set-auto-modeФункція встановлює режим , заснований на файл , пов'язаний з буфером. Ось функція, яка тимчасово встановлюється buffer-file-nameз імені буфера, щоб встановити режим:

(defun my/set-buffer-mode (buffer &optional again)
  "Set the mode for BUFFER from the name.  
When called repeatedly for the same buffer only set the mode the first
time, unless the optional argument AGAIN is specified.
Does nothing if the buffer is associated with a file."

  (with-current-buffer buffer
    (when again (kill-local-variable 'my/buffer-mode-set))
    (unless (or buffer-file-name 
            (local-variable-p 'my/buffer-mode-set))
      (let ((buffer-file-name (buffer-name)))
        (set-auto-mode t)
        (setq-local my/buffer-mode-set t)))))

Ви можете запустити це, коли буфер перейменований за допомогою порад:

(defadvice rename-buffer (after my/rename-update-mode activate)
  (my/set-buffer-mode (current-buffer) 'again))

Я не впевнений, що найкраще підключити це, щоб вплинути на нові буфери. Тут я використовую buffer-list-update-hook, але це називається в більшій кількості випадків, ніж нам потрібно.

(add-hook 'buffer-list-update-hook
      '(lambda ()
         (my/set-buffer-mode (car (buffer-list)))))

Вищезгадана відповідь була переглянута для вирішення деяких питань. Зокрема, я повернувся до використання, buffer-list-update-hookоскільки change-major-mode-hookне викликався очікуваним буфером поточного струму. Для запису, мабуть, має сенс порадити свою функцію буфера комутації, як це робить @Dan у своїй відповіді.
глюкас

3

Ви можете використовувати * scratch * буфери для створення тимчасових буферів, які мають той самий основний режим, що і файл, над яким ви могли працювати.

Ось відповідь emacs SE, яка може вирішити вашу проблему:

Як я можу швидко перемикатися між файлом і буфером * scratch *, що має той самий основний режим?

Посилане питання та відповідь були опубліковані мною. Відповідь у функції виконує наступне:

  • Якщо у файлі ви працюєте в основному режимі X, виклик цієї функції створює новий буфер нуля, який називається, *scratch-X-mode*якщо такого ще не існує, і перемикається на цей новостворений буфер.
  • Якщо вона *scratch-X-mode*вже існує, вона просто переходить на цей буфер.
  • Викликаючи цю функцію ще раз, коли знаходиться у цьому буфері подряпин, ви повернетесь до буфера файлів, над яким ви спочатку працювали.

0

Тут є кілька хороших відповідей, але я хотів додати ще одну річ. У Emacs є багато можливостей, і часто існує кілька способів зробити щось. Ви можете додати теги у верхній частині будь-якого файлу, який повідомляє emacs, який тип його, незалежно від розширення. Наприклад, додавши це:

# -*-Python-*-

У верхній частині файлу повідомлятиме Emacs, що це файл Python навіть із .pyрозширенням. Зауважте, що #на початку рядка є коментар у стилі Python. Для різних типів файлів ви можете використовувати різні коментарі. Наприклад, щоб вказати файл Lisp, який ви використовуєте ;для запуску рядка коментарів та встановлення режиму в emacs, як це:

; -*- mode: Lisp;-*-

Див. Розділ Вказівки змінних файлів та вибір режимів файлів .


Так, але питання тут полягає саме у створенні нового тимчасового буфера (наприклад, з switch-buffer) та встановлення режиму автоматично встановленого на щось інше, ніж fundamental-mode.
глюкас
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.