0

内部スクリプト言語 ( と呼びましょうpkc) を使用して、C++ コードを埋め込むことができます。{{{C++ コード セグメントは、および}}}マーカーで区切られます。

Generic Modemmm-modeを使用して、この言語の emacs モードを作成します。

これが私が得たものです(ここに投稿するために重要ではない部分を取り除いています):

(require 'generic-x)

(setq pkc-imenu-generic-expression
      '(("macros" "^[ \t]*macro[ \n\t]+\\([a-zA-Z0-9_]+\\)" 1)
        ("functions" "function[ \n\t]+\\([a-zA-Z0-9_]+\\)" 1)
        ))

(require 'cc-mode)      ;; for c++-mode
(require 'mmm-auto)
(setq mmm-global-mode 'maybe)

(define-generic-mode
  'pkc-mode                                  ;; name of the mode to create
  '("//" ("/*" . "*/"))                      ;; comments are same C++ comments
  '( ... )                                   ;; some keywords
  '("\\.pkc$")                               ;; files for which to activate this mode

  ;; other functions to call
  '((lambda ()
      (mmm-mode 1)
      (setq mmm-submode-decoration-level 2)
      (setq imenu-generic-expression pkc-imenu-generic-expression)
      (which-function-mode 1)

      (c-initialize-cc-mode t)
      (c-init-language-vars-for 'c++-mode)
      (c-common-init 'c++-mode)
      (c-update-modeline)

      (message "pkc-mode[mmm] is on")))

  "A mode for pkc source files"                  ;; doc string for this mode
  )

(mmm-add-classes
 '((embedded-c++
    :submode c++-mode
    :face mmm-default-submode-face
    :front "{{{"
    :front-offset -1
    :back "}}}"
    :back-offset 1)))

(mmm-add-mode-ext-class 'pkc-mode nil 'embedded-c++)

C++ コード セグメントが埋め込まれたソース ファイルをロードすると、C++ モードがメジャー モードの場合よりも強調表示がやや少なくなります (ただし、これは私の問題ではありません)。C++ コードでカーソルを移動すると、モードラインがpkc/l[C++/l](予想どおり) に変わります。

TAB問題は、行をインデントするために押すたびにエラーが発生することWrong type argument: stringp, nilです。デバッガーをオンにしたときのスタック トレースは次のとおりです。

Debugger entered--Lisp error: (wrong-type-argument stringp nil)
  c-syntactic-skip-backward(nil nil t)
  c-looking-at-decl-block(nil t)
  c-guess-basic-syntax()
  c-indent-line()
  #[nil \302>\203)\212\303 \210\304\305x\210\303 \210\306 )i\306 X\203\"\307    !\202'\212\307  !))\20 \207" [indent-line-function column (indent-relative indent-relative-maybe) beginning-of-line "\n     " nil current-indentation indent-line-to] 2 1908700 nil]()
  c-indent-command(nil)
  c-indent-line-or-region(nil nil)
  call-interactively(c-indent-line-or-region nil nil)

の定義c-looking-at-decl-block、特に `c-syntactic-skip-backward の呼び出しを見ると、次のことがわかります。

    (c-syntactic-skip-backward c-block-prefix-charset limit t)

最初の引数を調べるc-block-prefix-charsetと、その値が であることがわかりますnil。プレーンな C++ バッファから同じことを行うと、非nil値が表示されます。したがって、C++ モードでは、適切に行われていない初期化が必要であると思われます。

だから、私の質問は次のとおりです。

  1. 実装の C++ モード初期化セクションで何が欠けていますか?
  2. 正しいアプローチを使用していますか ( と を組み合わせgeneric-xていmmm-modeますか?) より良いアプローチはありますか?

ファイルをロードすると別のエラー ( File mode specification error) も表示されますが、問題は同じか、似ていると思われます。

御時間ありがとうございます。

4

1 に答える 1

1

(コメントでの議論の後に、後の訪問者のために書き直されました)。

問題の設定は基本的には問題ありませんが、現在の設定c++-modeを使用するには、の更新バージョンを使用する必要がありますmmm-modeGitHubプロジェクトページMelpaで入手できます。

関連するパッチ(1、2、3 は、値に新しいエントリを追加しましたmmm-save-local-variablesこれmmm-modeは、サブモード領域を出たり入ったりするときに保存または復元するローカル変数を決定するために使用されます。

私が理解していることから、将来の更新cc-modeでそのような変数をさらに追加できるため、リストを時々更新する必要があるかもしれません。

追加のヒント:サブリージョンのインデントを改善するには、サブモードindent-line-functionを呼び出す前にバッファーを絞り込むコードでサブモードをラップすることをお勧めします(ここの例)。インデント関数(およびそれが呼び出すかどうかwiden)に応じて、役立つ場合と役に立たない場合があります。

于 2013-01-08T21:58:30.860 に答える