Получение Emacs для отмены стабилизации при сохранении определенных типов файлов (и только этих типов файлов)

В моем файле .emacs есть следующее:

 (defun c++-mode-untabify ()
   (save-excursion
     (goto-char (point-min))
     (while (re-search-forward "[ \t]+$" nil t)
       (delete-region (match-beginning 0) (match-end 0)))
     (goto-char (point-min))
     (if (search-forward "\t" nil t)
         (untabify (1- (point)) (point-max))))
   nil)

 (add-hook 'c++-mode-hook
           '(lambda ()
              (make-local-hook 'write-contents-hooks)
              (add-hook 'write-contents-hooks 'c++-mode-untabify)))

В основном сдирался с http://www.jwz.org/doc/tabs-vs-spaces.html. Это заставляет emacs запускать untabify в буфере перед сохранением файла C++.

Проблема в том, что после того, как я загрузил файл C++, ловушка untabify применяется к последующей записи файла все, даже для буферов других типов файлов. Это означает, что если я открою файл C++, а затем отредактирую, скажем, текстовый файл с разделителями табуляции, вкладки будут затираться при сохранении файла.

Я не гуру elisp, но я думаю, что линия (make-local-hook 'write-contents-hooks) пытается сделать дополнение к write-contents-hooks применимым только к локальному буферу. Однако это не работает, и c++-mode-untabify находится в write-contents-hooks для всех буферов.

Я использую EmacsW32 22.0 на Windows XP. Кто-нибудь знает, как заставить write-contents-hooks изменяться локально для определенного буфера или как сбросить его на nil при переключении на другие буферы, отличные от C++?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
12
0
5 435
3

Ответы 3

В документации моего Emacs сказано, что make-local-hook теперь устарел с 21.1, поскольку add-hook теперь принимает необязательный аргумент для создания локального буфера ловушки. Итак, вы можете попробовать:

(add-hook 'c++-mode-hook
           '(lambda ()
              (add-hook 'write-contents-hooks 'c++-mode-untabify nil t)))

Другой вариант - использовать функцию C++ - mode-untabify для проверки текущего режима. Я бы, наверное, просто написал это как-то вроде:

(defun c++-mode-untabify ()
  (if (string= (substring mode-name 0 3) "C++")
      (save-excursion
       (delete-trailing-whitespace)
       (untabify (point-min) (point-max)))))

Попробуйте добавить свой крючок следующим образом:

 (add-hook 'c++-mode-hook
           '(lambda ()
              (add-hook 'write-contents-hooks 'c++-mode-untabify nil t)))

Обратите внимание на два дополнительных агумента для добавления крючка. Если я правильно прочитал, согласно документации, завершающий t должен делать то, что делает make-local-hook (или наоборот), но я также видел ссылки на то, что make-local-hook устарел. По крайней мере, на моем ящике (linux, gnu emacs 21.3.1) я вижу желаемый эффект - ловушка прикреплена только к буферам C++, а не ко всем остальным.

В крайнем случае вы всегда можете поставить галочку в своей функции C++ - mode-untabify, чтобы она творила волшебство, только если текущий основной режим - это режим C++.

Однако это любопытное решение. Если вы удалите все вкладки, что вы делаете, чтобы вставить вкладки обратно? Если вы прекратите что бы то ни было, этот хак вам не понадобится.

Спасибо! Я вставил это, чтобы автоматически удалять вкладки из старого кода, который я не писал, но иногда должен поддерживать,

DanielMcP 26.11.2008 00:53

write-contents-hooks также устарело. Это то, что вам нужно:

(add-hook 'c++-mode-hook
      '(lambda ()
         (add-hook 'before-save-hook
                   (lambda ()
                     (untabify (point-min) (point-max))))))

Это заимствовано из того, что я использую, которое выполняет еще несколько вещей и абстрагируется для работы с режимами, специфичными для программирования:

(defun untabify-buffer ()
  "Untabify current buffer"
  (interactive)
  (untabify (point-min) (point-max)))

(defun progmodes-hooks ()
  "Hooks for programming modes"
  (yas/minor-mode-on)
  (add-hook 'before-save-hook 'progmodes-write-hooks))

(defun progmodes-write-hooks ()
  "Hooks which run on file write for programming modes"
  (prog1 nil
    (set-buffer-file-coding-system 'utf-8-unix)
    (untabify-buffer)
    (copyright-update)
    (maybe-delete-trailing-whitespace)))

(defun delete-trailing-whitespacep ()
  "Should we delete trailing whitespace when saving this file?"
  (save-excursion
    (goto-char (point-min))
    (ignore-errors (next-line 25))
    (let ((pos (point)))
      (goto-char (point-min))
      (and (re-search-forward (concat "@author +" user-full-name) pos t) t))))

(defun maybe-delete-trailing-whitespace ()
  "Delete trailing whitespace if I am the author of this file."
  (interactive)
  (and (delete-trailing-whitespacep) (delete-trailing-whitespace)))

(add-hook 'php-mode-hook 'progmodes-hooks)
(add-hook 'python-mode-hook 'progmodes-hooks)
(add-hook 'js2-mode-hook 'progmodes-hooks)

Другие вопросы по теме