ブラケットを自動的にフォーマットする


9

(Cでコーディングするための)Allmanスタイルのフォーマットに従って中かっこを配置/配置/インデントする関数を作成しようとしています。

一般的に言えば、私はユーザーが機能をカスタマイズするために使用できるSmartparensのインターフェースのファンです。私はSmartparensインターフェースを使用して他の関数をたくさん書いたので、この時点でパッケージを切り替えないようにしてください。そうは言っても、私はパッケージにとらわれない実装を受け入れています(たとえば、defadviceここで関連性があるかもしれませんか?)。

目の前の問題に移ります。最終目標は何ですか?コーディングしていて、以下に示す状態になったとしましょう。パイプ記号はカーソルを表します。関数ヘッダーと開き括弧を入力しました{。Smartparensが自動的に閉じ括弧を追加しました }。この時点で、それを押してくださいRET...

int main {|}

...次のようになります:

int main
{
    |
}

この動作を引き起こす関数を書くことができましたが、それは最初のレベルのインデント(たとえば、上の例のメイン関数)でのみ機能します。それ以降のレベルのインデントでは機能しません(gifを参照)。

ここに画像の説明を入力してください

関連するコードは次のとおりです。関数はきれいではありませんが、うまくいくと思います...最後の行はSmartparensへのインターフェースです。

助言がありますか?


(defun my-create-newline-and-enter-sexp (&rest _ignored)
  "Open a new brace or bracket expression, with relevant newlines and indent. "
  (interactive)
  (progn
    (backward-char 2) (newline) (forward-char) (newline)     
    (indent-according-to-mode)                               
    (previous-line 2) (indent-according-to-mode)         
    (next-line) (next-line) (indent-according-to-mode)))      

(sp-local-pair 'c-mode "{" nil :post-handlers '((my-create-newline-and-enter-sexp "RET")))

回答:


11

Emacs-24.4 electric-pair-modeは、あなたが既に望んでいることの一部を実行します(このモードはautopair.elと非常に似ていますが、smartparensとの比較がわかりません)。そしてc-toggle-auto-newline、他の部分を行います。

しかし残念なことに、それらは一緒に正しく機能しません。M-x report-emacs-bugそれを修正できるようにしてください。

の代わりにc-toggle-auto-newlineelectric-layout-modeなどの設定で使用することもできます(setq electric-layout-rules '((?\{ . around) (?\} . around)))


1
報告!二人が一緒に働くことができれば、それは確かに素晴らしいでしょう。
アイスマン2014年

7

解決しました。最初のバージョン(元の投稿)からのカーソル移動のシーケンスはファンキーでした。

将来の読者のための参照として、次のコードが機能するはずです。これには、Smartparensパッケージ(git-hubから入手できます)が必要です。Emacs 24.4を実行しています。電気インデントモードを有効または無効にして動作します。

(defun my-create-newline-and-allman-format (&rest _ignored)
"Allman-style formatting for C."
  (interactive)
  (progn
    (newline-and-indent)
    (previous-line) (previous-line) (search-forward "{") (backward-char) (newline-and-indent)
    (next-line) (indent-according-to-mode)))

また、Smartparensパッケージをロードした後のどこかで、initファイルに以下を含める必要があります。

(sp-local-pair '(c-mode) "{" nil :post-handlers '((my-create-newline-and-allman-format "RET")))

2
previous-linewithのようなものを使用しsearch-forwardて、どこにいたかを再発見するのではなく、変数内での位置を覚えてからを使用する方がはるかに優れていますgoto-char
Stefan

それはおそらくより堅牢なルートです。このコンテキストで役立つと思われる関数/変数/その他はありますか?私は思いつくことができますがsave-excursion、知らない他の人がいると確信しています。
アイスマン2014年


0

私が使用するコードは次のとおりです。コードを修正するためのアイデアを提供するためです。

(defun ins-c++-curly ()
  "Insert {}.
Threat is as function body when from endline before )"
  (interactive)
  (cond ((eq major-mode 'term-mode)
         (term-send-raw-string "{}")
         (term-send-raw-string "^B"))
        ((looking-back "\\()\\|try\\|else\\|const\\|:\\)$")
         (insert " {\n\n}")
         (indent-according-to-mode)
         (forward-line -1)
         (indent-according-to-mode))
        ((region-active-p)
         (let ((beg (region-beginning))
               (end (region-end)))
           (deactivate-mark)
           (goto-char beg)
           (insert "{")
           (goto-char (1+ end))
           (insert "}")))
        (t
         (insert "{}")
         (indent-according-to-mode)
         (backward-char))))

スペースを節約できるので、私はぶら下げブレーススタイルを好みます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.