Как я могу заставить emacs автоматически вставлять закрывающие фигурные скобки

Я только начал использовать emacs, и есть одна функция, которую я бы очень хотел, и поиск вокруг немного был бесплодным. Я надеюсь, что кто-то еще сделал это, потому что я пока не хочу изучать elisp.

void foo()<cursor>

Я хотел бы ввести " { " , чтобы это произошло

void foo(){
    <cursor>
}

Я хотел бы, чтобы это происходило только в cc-режиме и только в конце строки, когда не в строке / комментарии / etc

первое, что пришло на ум, это перемотка " { " , чтобы сделать это всегда (я мог понять, как это сделать сам), но было бы трудно сделать это только в нужное время.

любые советы будут оценены.

7 ответов


это сделает это:

(defun my-c-mode-insert-lcurly ()
  (interactive)
  (insert "{")
  (let ((pps (syntax-ppss)))
    (when (and (eolp) (not (or (nth 3 pps) (nth 4 pps)))) ;; EOL and not in string or comment
      (c-indent-line)
      (insert "\n\n}")
      (c-indent-line)
      (forward-line -1)
      (c-indent-line))))

(define-key c-mode-base-map "{" 'my-c-mode-insert-lcurly)

на последних emacs вы можете использовать:

electric-pair-mode is an interactive compiled Lisp function.

(electric-pair-mode &optional ARG)

Automatically pair-up parens when inserting an open paren.

это интегрировано в Emacs 24.1 (фактически CVS)


Я сердечно рекомендую вам попробовать отличные autopair minor mode-это намного больше, чем просто вставка фигурных скобок и делает Emacs намного более IDE, как в этой области. Я думаю, что сочетание его с настройкой электрических скобок в cc-режиме даст вам более или менее поведение, которое вы ищете.


попробовать yasnippet (или на странице Emacs Wiki yasnippet). Есть много пакетов для Emacs, которые поддерживают выполнение такого рода вещей, но yasnippet, похоже, имеет импульс в настоящее время и очень расширяема. Посмотри видео.


включите режим электрической пары в emacs 24 или более новой версии.

(electric-pair-mode 1)

вам нужно будет углубиться в emacs-lisp, чтобы сделать это именно так, как вы хотите, так как YASnippet сделает что-то хорошее для вас, но не совсем то, что вы просите.

Я думаю, что самый простой способ сделать это, чтобы привязать функцию к RET ключ, в CC-mode key-map.

функция должна проверить, что предыдущий символ { и если да, выполните требуемое RET, RET, TAB, }, до, TAB чтобы получить курсор, где вы хотите и закрывающим тегом } вставить.

вы можете сделать функцию более надежной, проверив ее на сбалансированное закрытие } но это было бы сложнее, и я бы рекомендовал посмотреть, как он чувствует себя без этой дополнительной функции полировки.

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

альтернативно, я нахожу, что autopair.el делает это достаточно хорошо для меня, и я сам делаю новые строки;)


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

  1. полагайтесь на пакеты, упомянутые в предыдущих ответах, чтобы автоматически добавить закрывающую скобку.
  2. когда вы хотите добавить операторы в теле функции, вы нажимаете Return ключ (пока автоматически добавленная заключительная расчалка все еще под указатель.) Ключ "Return" связан следующим образом:

    ;; automatic first line in function                                             
    (defun my-c-mode-insert-funline ()
      (interactive)
      (newline-and-indent)
      (when (looking-at "}")
        (newline-and-indent)
        (forward-line -1)
        (c-indent-line)))
    (global-set-key (kbd "RET") 'my-c-mode-insert-funline)