**** Stephan による問題 1 の解決策 - 以下の回答を参照してください****
構文テーブルでエスケープ文字としてマーク\
しますが、 のような Mathematica 構文要素の指定をオーバーライドします\[Infinity]
。これが私のものsyntax-propertize-function
です:
(defconst math-syntax-propertize-function
(syntax-propertize-rules
("\\\\\\[\\([A-Z][A-Za-z]*\\)]" (0 "_"))))
(defun math-node()
次のように関数から参照しました。
(set (make-local-variable 'syntax-propertize-function)
math-syntax-propertize-function)
最初の試みでは、関数を使用しなかったためmake-local-variable
、elisp バッファーの強調表示がうまくいかなかったので驚きました。
****問題 1 の解決策を終了****
Mathematica ファイルを編集するために、cc-mode から派生した Emacs にメジャーモードを実装しています。目標は、構文の強調表示とインデントです。Mathematica カーネルとのインターフェースは後回しにします。
基本的な機能は動作していますが、問題を引き起こしている問題がいくつかあります。
****問題 1** -\
文字はエスケープ文字として使用され、複数文字の括弧で囲まれたキーワードの前に付けられます。**
多くの言語と同様に、 Mathematica は\
文字をエスケープ"
に使用し、他の\
文字は文字列です。
Mathematic では、Mathematica で呼び出されているものに、Mathematica の演算子や定数を表す 、 、 など\[Times]
の\[Element]
構文文字を話します。\[Infinity]
また、Mathematica は、関数の定義や呼び出しなどに[
andの]
代わりに(
andを多用します。)
そのため、構文テーブルでエスケープ文字としてマーク\
すると、構文文字を使用する場所で括弧が不一致になります。例えば、
If[x < \[Pi], True, False]
もちろん、cc-mode は . の[
直後を無視するつもり\
です。Mathematica の機能的性質を考えると、モードがブラケットに一致しない場合、モードはほとんど役に立ちません。括弧のマッチングなしでLispを考えてください。
構文テーブルにエスケープ文字を入れない場合\
、コメントや文字列でエスケープ シーケンスを処理するにはどうすればよいですか?
Times、Element、Infinity などをキーワード リストに入れ、すべてが正しく動作するようにできれば素晴らしいと思います。
****問題 2** - Mathematica の構文は、C、C++、Java、ObjC などとは十分に異なっているため、cc-mode の組み込みの構文解析が常に望ましい結果を生成するとは限りません。**
次のコード ブロックを検討してください。
FooBar[expression1,
expression2,
expression3];
式が引数リストとして認識されるため、これは美しくフォーマットされます。
ただし、リストが引数として渡される場合、
FooBar[{expression1,
expression2,
expression3}];
{
式はand内の単一ステートメントの継続と見なされるため、結果はきれいではありません}
。残念ながら、次のような実際の継続c-continuation-offset
を中断するように設定するという単純なハックは、0
addMe[x_Real, y_Real] :=
Plus[x, y];
インデントしたいもの。
問題は、Mathematica{
と}
delineate リストであり、コード ブロックではありません。
私が使用している現在のelispファイルは次のとおりです。
(require 'cc-mode)
;; There are required at compile time to get the sources for the
;; language constants.
(eval-when-compile
(require 'cc-langs)
(require 'cc-fonts))
;; Add math mode the the language constant system. This needs to be
;; done at compile time because that is when the language constants
;; are evaluated.
(eval-and-compile
(c-add-language 'math-mode 'c-mode))
;; Function names
(c-lang-defconst c-cpp-matchers
math (append
(c-lang-const c-cpp-matchers c)
;; Abc[
'(("\\<\\([A-Z][A-Za-z0-9]*\\)\\>\\[" 1 font-lock-type-face))
;; abc[
'(("\\<\\([A-Za-z][A-Za-z0-9]*\\)\\>\\[" 1 font-lock-function-name-face))
;; Abc
'(("\\<\\([A-Z][A-Za-z0-9]*\\)\\>" 1 font-lock-keyword-face))
;; abc_
'(("\\<\\([a-z][A-Za-z0-9]*[_]\\)\\>" 1 font-lock-variable-name-face))
))
;; font-lock-comment-face
;; font-lock-doc-face
;; font-lock-string-face
;; font-lock-keyword-fact
;; font-lock-function-name-face
;; font-lock-constant-face
;; font-lock-type-face
;; font-lock-builtin-face
;; font-lock-reference-face
;; font-lock-warning-face
;; There is no line comment character.
(c-lang-defconst c-line-comment-starter
math nil)
;; The block comment starter is (*.
(c-lang-defconst c-block-comment-starter
math "(*")
;; The block comment ender is *).
(c-lang-defconst c-block-comment-ender
math "*)")
;; The assignment operators.
(c-lang-defconst c-assignment-operators
math '("=" ":=" "+=" "-=" "*=" "/=" "->" ":>"))
;; The operators.
(c-lang-defconst c-operators
math `(
;; Unary.
(prefix "+" "-" "!")
;; Multiplicative.
(left-assoc "*" "/")
;; Additive.
(left-assoc "+" "-")
;; Relational.
(left-assoc "<" ">" "<=" ">=")
;; Equality.
(left-assoc "==" "=!=")
;; Assignment.
(right-assoc ,@(c-lang-const c-assignment-operators))
;; Sequence.
(left-assoc ",")))
;; Syntax modifications necessary to recognize keywords with
;; punctuation characters.
;; (c-lang-defconst c-identifier-syntax-modifications
;; math (append '((?\\ . "w"))
;; (c-lang-const c-identifier-syntax-modifications)))
;; Constants.
(c-lang-defconst c-constant-kwds
math '( "False" "True" )) ;; "\\[Infinity]" "\\[Times]" "\\[Divide]" "\\[Sqrt]" "\\[Element]"\
))
(defcustom math-font-lock-extra-types nil
"Extra types to recognize in math mode.")
(defconst math-font-lock-keywords-1 (c-lang-const c-matchers-1 math)
"Minimal highlighting for math mode.")
(defconst math-font-lock-keywords-2 (c-lang-const c-matchers-2 math)
"Fast normal highlighting for math mode.")
(defconst math-font-lock-keywords-3 (c-lang-const c-matchers-3 math)
"Accurate normal highlighting for math mode.")
(defvar math-font-lock-keywords math-font-lock-keywords-3
"Default expressions to highlight in math mode.")
(defvar math-mode-syntax-table nil
"Syntax table used in math mode.")
(message "Setting math-mode-syntax-table to nil to force re-initialization")
(setq math-mode-syntax-table nil)
;; If a syntax table has not yet been set, allocate a new syntax table
;; and setup the entries.
(unless math-mode-syntax-table
(setq math-mode-syntax-table
(funcall (c-lang-const c-make-mode-syntax-table math)))
(message "Modifying the math-mode-syntax-table")
;; character (
;; ( - open paren class
;; ) - matching paren character
;; 1 - 1st character of comment delimitter (**)
;; n - nested comments allowed
(modify-syntax-entry ?\( "()1n" math-mode-syntax-table)
;; character )
;; ) - close parent class
;; ( - matching paren character
;; 4 - 4th character of comment delimitter (**)
;; n - nested comments allowed
(modify-syntax-entry ?\) ")(4n" math-mode-syntax-table)
;; character *
;; . - punctuation class
;; 2 - 2nd character of comment delimitter (**)
;; 3 - 3rd character of comment delimitter (**)
(modify-syntax-entry ?\* ". 23n" math-mode-syntax-table)
;; character [
;; ( - open paren class
;; ] - matching paren character
(modify-syntax-entry ?\[ "(]" math-mode-syntax-table)
;; character ]
;; ) - close paren class
;; [ - mathcing paren character
(modify-syntax-entry ?\] ")[" math-mode-syntax-table)
;; character {
;; ( - open paren class
;; } - matching paren character
(modify-syntax-entry ?\{ "(}" math-mode-syntax-table)
;; character }
;; ) - close paren class
;; { - matching paren character
(modify-syntax-entry ?\} "){" math-mode-syntax-table)
;; The following characters are punctuation (i.e. they cannot appear
;; in identifiers).
;;
;; / ' % & + - ^ < > = |
(modify-syntax-entry ?\/ "." math-mode-syntax-table)
(modify-syntax-entry ?\' "." math-mode-syntax-table)
(modify-syntax-entry ?% "." math-mode-syntax-table)
(modify-syntax-entry ?& "." math-mode-syntax-table)
(modify-syntax-entry ?+ "." math-mode-syntax-table)
(modify-syntax-entry ?- "." math-mode-syntax-table)
(modify-syntax-entry ?^ "." math-mode-syntax-table)
(modify-syntax-entry ?< "." math-mode-syntax-table)
(modify-syntax-entry ?= "." math-mode-syntax-table)
(modify-syntax-entry ?> "." math-mode-syntax-table)
(modify-syntax-entry ?| "." math-mode-syntax-table)
;; character $
;; _ - word class (since $ is allowed in identifier names)
(modify-syntax-entry ?\$ "_" math-mode-syntax-table)
;; character \
;; . - punctuation class (for now treat \ as punctuation
;; until we can fix the \[word] issue).
(modify-syntax-entry ?\\ "." math-mode-syntax-table)
) ;; end of math-mode-syntax-table adjustments
;;
;;
(defvar math-mode-abbrev-table nil
"Abbrevation table used in math mode buffers.")
(defvar math-mode-map (let ((map (c-make-inherited-keymap)))
map)
"Keymap used in math mode buffers.")
;; math-mode
;;
(defun math-mode ()
"Major mode for editing Mathematica code."
(interactive)
(kill-all-local-variables)
(c-initialize-cc-mode t)
(set-syntax-table math-mode-syntax-table)
(setq major-mode 'math-mode
mode-name "Math"
local-abbrev-table math-mode-abbrev-table
abbrev-mode t)
(use-local-map math-mode-map)
(c-init-language-vars math-mode)
(c-common-init 'math-mode)
(run-hooks 'c-mode-common-hook)
(run-hooks 'math-mode-hook)
(c-update-modeline))
(provide 'math-mode)
そしていくつかのスクリーンショット。