2014-04-10 36 views
1

我正在爲類似Lisp的語言編寫簡單模式,並且在設置縮進時遇到了麻煩。我一直在關注emacswiki mode tutorial創建emacs模式:定義縮進

但是,我不知道如何調整他們的示例縮進符合我的需求,因爲他們沒有做任何形式的計數。

基本上,我只需要2個空格添加到我的壓痕計數每次見到{(時間,即使有多個在同一行,並減去2位,當我看到上面的封鎖。我是新來的elisp;我怎樣才能調整他們的例子來計算大括號和括號?

爲了方便起見,這裏是他們使用的代碼(非支架語言):

(defun wpdl-indent-line() 
    "Indent current line as WPDL code" 
    (interactive) 
    (beginning-of-line) 
    (if (bobp) ; Check for rule 1 
     (indent-line-to 0) 
    (let ((not-indented t) cur-indent) 
     (if (looking-at "^[ \t]*END_") ; Check for rule 2 
     (progn 
     (save-excursion 
      (forward-line -1) 
      (setq cur-indent (- (current-indentation) default-tab-width))) 
     (if (< cur-indent 0) 
     (setq cur-indent 0))) 
     (save-excursion 
      (while not-indented 
      (forward-line -1) 
      (if (looking-at "^[ \t]*END_") ; Check for rule 3 
       (progn 
        (setq cur-indent (current-indentation)) 
        (setq not-indented nil)) 
        ; Check for rule 4 
       (if (looking-at "^[ \t]*\\(PARTICIPANT\\|MODEL\\|APPLICATION\\|WORKFLOW\\|ACTIVITY\\|DATA\\|TOOL_LIST\\|TRANSITION\\)") 
        (progn 
        (setq cur-indent (+ (current-indentation) default-tab-width)) 
        (setq not-indented nil)) 
       (if (bobp) ; Check for rule 5 
        (setq not-indented nil))))))) 
     (if cur-indent 
      (indent-line-to cur-indent) 
     (indent-line-to 0))))) ; If we didn't see an indentation hint, then allow no indentation 

我怎麼能只實現Lisp的縮進(而且與大括號)?

+2

爲什麼不看「lisp-indent-function」的來源? –

+0

abo-abo,我無法找到該函數的未編譯定義。 – WorldsEndless

+0

從源代碼安裝emacs,然後您可以通過'describe-function'輕鬆找到定義。 –

回答

1

如果你想要一個簡單的Lisp風格的語言,我建議你從(syntax-ppss)開始,它返回點「解析狀態」。該狀態的第一個元素是當前的嵌套深度。雖然我使用了「paren」這個詞,但這並不真正計算parens,而是計算那些語法表定義爲paren-like的那些字符,所以如果設置語法表使得{和}被聲明爲paren-like那麼這些也將被計算在內。

所以,你可以使用的東西開始喜歡

(defun foo-indent-function() 
    (save-excursion 
    (beginning-of-line) 
    (indent-line-to (* 2 (car (syntax-ppss)))))) 

不要將此定義爲互動,因爲這樣在你的主要模式的功能附加

(set (make-local-variable 'indent-line-function) #'foo-indent-function) 

使用它。

但也許是更好的選擇是簡單地做:

(require 'smie) 
... 
(define-derived-mode foo-mode "Foo" 
    ... 
    (smie-setup nil #'ignore) 
    ...) 

這將使用的4(以smie-indent-basic配置)的壓痕一步。

+0

這幾乎完美!我使用前者的功能非常棒。你會添加一個關於如何定義/擴展語法-PPss的鏈接或簡短的解釋嗎?另外,我注意到我的左大括號仍然在這裏縮進,當我想讓它左齊時。任何建議? – WorldsEndless

+0

擴展語法-ppss並不是一個真正的選項。在這個意義上使用SMIE是最好的,因爲它意味着要被擴展。此外,SMIE默認應該爲您處理「左大括號」。 – Stefan