2016-02-24 47 views
0

我寫了一個很簡單的Emacs模式標準ML:Emacs的增加是一致的縮進規則,通用-X模式

;; sml syntax 
(require 'generic-x) 

(define-generic-mode 
    'sml-mode       ;; name of the mode 
    '(("(*" . "*)"))       ;; comments delimiter 
    '("fun" "fn" "let" "val" "datatype" "type" "case" "of" "end" "structure" "struct" "signature" "sig") 
    '(("=" . 'font-lock-builtin-face) 
    ("|" . 'font-lock-builtin-face) 
    (">" . 'font-lock-builtin-face) 
    ("<" . 'font-lock-builtin-face) 
    ("-" . 'font-lock-builtin-face) 
    ("+" . 'font-lock-builtin-face) 
    (";" . 'font-lock-builtin-face) 
    ("," . 'font-lock-builtin-face) 
    ("{" . 'font-lock-builtin-face) 
    ("}" . 'font-lock-builtin-face) 
    ("(" . 'font-lock-builtin-face) 
    (")" . 'font-lock-builtin-face) 
    (":" . 'font-lock-builtin-face) 
    ("[" . 'font-lock-builtin-face) 
    ("]" . 'font-lock-builtin-face))  ;; a built-in 
    '("\\.sml$")     ;; files that trigger this mode 
    nil        ;; any other functions to call 
    "SML highlighting mode"  ;; doc string 
) 

但是,它不會持續縮進。我無法準確描述它如何縮進,但它在製表符和空格以及空格的長度之間切換不一致。我能想到的最簡單的規則是始終在同一列上開始一個新行,並且標籤總是將您帶到下一個爲4的倍數的列。標籤應該是空格。我如何使用通用模式來做到這一點?

由於在模式定義一個音符,我使用的是內置的臉,因爲不正確的操作面沒有着色。現在看起來很醜陋。

+0

爲了得到您想要的縮進行爲,您嘗試過了些什麼? – Thomas

回答

1

首先第一件事情:我強烈建議你開始define-derived-mode而不是define-generic-mode因爲前者將無縫擴展,以適應一個全功能的主要模式,而define-generic-mode將很快徵收是不方便解決的限制。

E.g.你可以重寫你的代碼爲:

(defvar sml-mode-syntax-table 
    (let ((st (make-syntax-table))) 
    ;; Make (*...*) a comment. 
    (modify-syntax-entry ?\("()1" st) 
    (modify-syntax-entry ?\) ")(4" st) 
    (modify-syntax-entry ?\* ". 23n" st) 
    st)) 

(defvar sml-font-lock-keywords 
    `((,(concat "\\_<" 
       (regexp-opt '("fun" "fn" "let" "val" "datatype" "type" "case" "of" "end" "structure" "struct" "signature" "sig")) 
       "\\_>") 
    (0 font-lock-keyword-face)) 
    ("[][=|><-+;,{}():]" (0 font-lock-builtin-face)))) 

;;;###autoload 
(define-derived-mode sml-mode prog-mode "SML" 
    "SML major mode." 
    (set (make-local-variable 'comment-start) "(* ") 
    (set (make-local-variable 'comment-end) " *)") 
    (set (make-local-variable 'font-lock-defaults) 
     '(sml-font-lock-keywords))) 

;;;###autoload 
(add-to-list 'auto-mode-alist '("\\.sml\\'" . sml-mode)) 

W.r.t製表符和SPC,「它們之間的切換」是默認的Emacs的行爲(態度在於TAB只是當它是適用的,我們使用優化)。如果你不喜歡它,然後把(setq-default indent-tabs-mode nil)~/.emacs,而不是在你的主要模式的定義,因爲這是SML無關個人的選擇(不區分製表符和SPC,相反,比方說,哈斯克爾)。

至於你建議的縮進,你可以從添加(set (make-local-variable 'indent-line-function) #'indent-relative)開始,它應該確保默認縮進與前一行相同;和「TAB應該提前4列」可能類似(set (make-local-variable 'tab-stop-list '(4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64))會做的伎倆(在更近的Emacsen,'(4 8)是足夠的,因爲Emacs終於學會了「自動擴展列表」

但我很好奇:爲什麼不直接使用GNU ELPA中現有的sml-mode

+0

感謝您的詳細回覆!我將再次詳細閱讀它,但我只是想回答你的最後一個問題。這兩個ocaml的模式(圖阿雷格人)和SML-模式有很奇怪的縮進規則,我覺得折騰的夠證明與簡單規則不同的模式。 – eatonphil

+0

我建議你試試並行方法,您可以問如何讓sml-mode按照您喜歡的方式縮進您的代碼。 – Stefan

+0

鑑於您提供的關於縮進的信息似乎與我正在使用的特定模式有所不同,因此採用並行方法可能有意義。也就是說,我也很高興能夠開發一種模式。 – eatonphil