Как получить автоматический отступ (не умный отступ) в emacs во всех режимах

Я новичок в emacs, и его отступы заставляют меня взбираться по стенам. Это слишком умно для собственного блага; он (ошибочно) думает, что знает, как я хочу отформатировать свой исходный код, но у меня нет времени разбираться с каждой настройкой для каждого режима для каждого языка, для которого я пишу код; и на многих из этих языков вообще не включен какой-либо режим.

Вот поведение, которое я хотел бы:

  • TAB вставляет отступ
  • RET вставляет новую строку, затем копирует пустые символы из начала предыдущей строки в первый непустой символ или конец строки, в зависимости от того, что наступит раньше.
  • DEL (клавиша возврата) в пустом тексте между началом строки и первым непустым символом / концом строки удаляет один отступ, если это возможно, в противном случае - один символ, как обычно
  • Без автоматического отступа на {
  • Без автоудаления на}
  • Фактически, никакого умного отступа нигде в любое время, просто скопируйте отступ предыдущей строки на RET.
  • Две переменные, которые необходимо настроить для каждого формата исходного файла: ширина табуляции и содержимое отступа. Предпочтительно они могут быть настроены для произвольных форматов исходного кода без необходимости писать для них основной режим, если только запись основного режима не является однострочным в .emacs, состоящим из двух setqs.

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

Возможно ли вышеперечисленное? Неужто кто-то еще делал это раньше? Есть ли какой-нибудь второстепенный режим, который делает это так?


person Barry Kelly    schedule 22.09.2013    source источник
comment
Если вам не нравится возиться, то Emacs не для вас :). А если серьезно, сделайте свой вопрос более информативным: добавьте режимы, которые не работают. Я использовал по крайней мере 15 различных режимов программирования для Emacs, и в основном они великолепны. Или, если вы хотите отказаться от всех режимов и придерживаться основного режима, выделите конкретные особенности основного режима, которые вам не подходят.   -  person abo-abo    schedule 22.09.2013
comment
@ abo-abo Я не хочу терять подсветку синтаксиса или возможность добавлять такие вещи, как автозаполнение. Но за последние два уик-энда я потратил более 15 часов, пытаясь придать emacs разумную форму, и он все еще не подходит для переключения между редактированием C и языком с разделителями-скобками в режиме Fundamental.   -  person Barry Kelly    schedule 22.09.2013
comment
Обидно, что подпрограмма завершения также является подпрограммой табуляции. Я повторно привязываю TAB к команде self-insert-command и повторно привязываю C- ‹space› (C- @) к indent-for-tab-command и устанавливаю tab-always-indent для завершения, чтобы я мог получить, например, elisp в .emacs, но это также означает, что C- ‹space› пытается выполнить автоматическое форматирование. Чьей была блестящая идея связать завершение и форматирование кода в одной функции?   -  person Barry Kelly    schedule 22.09.2013
comment
Во-первых, повторная привязка C-<space> - очень плохая идея, так как она играет очень важную роль в маркировке региона. Во-вторых, нет причин тратить 15 часов на приведение Emacs в форму. Текущее состояние является результатом 30-летнего развития и использования тысячами программистов. Проблема в том, что вы пытаетесь заставить Emacs вести себя как то, что вы использовали раньше. Просто делайте это шаг за шагом. Я могу написать ниже некоторый код, который повторно связывает ключи для всех указанных вами режимов. Вы можете изменить настройки позже, если захотите.   -  person abo-abo    schedule 22.09.2013
comment
Я повторно использовал команду set-mark в другом месте, но я не использую этот стиль маркировки очень часто, поскольку использую режим временной маркировки. Что касается 30 лет, тысячи программистов и т. Д .; для меня это не имеет значения, так как я работаю не как 99% программистов; инженер-компилятор, пользователь Dvorak и т. д. Моя основная причина, по которой я взялась за emacs, - это получить программируемый редактор терминала, а не его мешанину из недоделанных режимов пользовательского интерфейса. Он не работает в своем состоянии по умолчанию на Cygwin, и половина привязок клавиш не работает внутри экрана, было много работы только для того, чтобы правильно настроить terminfo, не говоря уже о том, чтобы исправить все остальное.   -  person Barry Kelly    schedule 22.09.2013
comment
В настоящее время я пишу второстепенный режим, чтобы сделать отступы, как описано в моем вопросе. Посмотрим, насколько хорошо это работает на практике; Я добавлю свой код в качестве ответа, когда закончу.   -  person Barry Kelly    schedule 22.09.2013
comment
Что касается поведения автоматического отступа {и}, я бы рассмотрел это как ошибку (это отличная функция, но ее следует активировать только по явному запросу пользователя, например, с использованием electric-indent-mode).   -  person Stefan    schedule 22.09.2013


Ответы (1)


Вот код:

(setq tab-width 4)
(defun plain-tab ()
  (interactive)
  (insert (make-string tab-width ?\ )))
(defun plain-ret ()
  (interactive)
  (looking-back "^\\( +\\).*")
  (newline)
  (insert (match-string 1)))
(defun plain-del ()
  (interactive)
  (backward-delete-char
   (if (looking-back (format " \\{%d\\}" tab-width)) tab-width 1)))
(defvar all-the-mode-maps
  '(c-mode-map c++-mode-map java-mode-map
    js-mode-map emacs-lisp-mode-map
    clojure-mode-map))
(require 'cc-mode)
(require 'js)
(require 'clojure-mode)
(eval `(mapc 
        (lambda(map)
          (define-key map [tab] 'plain-tab)
          (define-key map [return] 'plain-ret)
          (define-key map [backspace] 'plain-del)
          (define-key map "{" (lambda()(interactive)(insert "{")))
          (define-key map "}" (lambda()(interactive)(insert "}"))))
        (list ,@all-the-mode-maps)))
person abo-abo    schedule 22.09.2013
comment
+1 за то, что сообщил мне о множестве полезных форм. Я собираюсь включить большую часть этого в свой второстепенный режим с изменениями; например в некоторых файлах используются табуляции, а не пробелы; Я буду использовать хуки, а не требовать, чтобы влиять на другие режимы, так как emacs запускается не мгновенно; и это должно повлиять на bash, Haskell, OCaml, Ruby, Python, Go, JS, css, html, xml, xsd, scss, coffeescript, elisp, C #, yaml, erb, puppet, yacc, lex, awk, lua и make-файлы, как неполный набор типов файлов, которые я редактировал за последний месяц, не включая форматы файлов с настраиваемыми парсерами. - person Barry Kelly; 22.09.2013
comment
У меня просто нет времени найти основные режимы для всех этих форматов и правильно их настроить. - person Barry Kelly; 22.09.2013
comment
Думаю, вам придется написать второстепенный режим, в котором будут записаны все используемые вами режимы :) - person abo-abo; 22.09.2013
comment
Вы можете определить глобальный второстепенный режим, который повторно связывает tab' to plain-tab 'и т. Д., И тогда вам не нужно беспокоиться о перечислении основных используемых вами режимов. - person Stefan; 22.09.2013
comment
Вы правы, @Stefan, я еще не успел написать второстепенный режим, поскольку большая часть того, что я пишу, относится к одному режиму. - person abo-abo; 22.09.2013