2010-09-02 86 views
2

在lisp中製作DSL(基本上我認爲是一種更好的語法),它與lisp相同,除了使用不同的「基元」,不是不是, 'as'而不是let。因此,我只需要在以.goby結尾的文件中更改縮進和顏色(它不應該影響以.lisp結尾的文件)因此,我想創建擴展名爲.goby的文件,並且啓用了我的新的,次要/主要模式(但除了從lisp繼承的語法之外,還有其他所有內容)。如何擴展縮進更改和顏色變化的emacs lisp模式

但是,無論我做什麼,它也影響.LISP文件!任何人?

例如,我試圖爲獨特的lisp縮進製作局部變量,該縮進會將 'hi'縮進10個空格。但它發生的所有.lisp文件也

;;in goby.el 
(define-derived-mode 
    goby-mode lisp-mode "Goby" 
    "Major mode" 
    (let ((funC#'lisp-indent-function)) 
    (set (make-local-variable 'lisp-indent-function) func) 
    (put 'hi 'lisp-indent-function 10))) 


(provide 'goby) 

;;in .emacs 
(setq auto-mode-alist 
     (append auto-mode-alist 
      '(("\\.gy\\'" . goby-mode)))) 

回答

2

有可能是一個更清潔的方式,但一個可行的辦法是重寫'lisp-indent-function'goby-indent-function和使用自己的偏移表所示:

(define-derived-mode 
    goby-mode lisp-mode "Goby" 
    "Major mode" 
    (set (make-local-variable 'lisp-indent-function) 'goby-indent-function)) 

;; goby specific offsets here 
(put 'hi 'goby-indent-function 10) 
(put 'if 'goby-indent-function 4) 

(defun goby-indent-function (indent-point state) 
    "Same as 'lisp-indent-function but uses 'goby-indent-function symbol 

This function is the normal value of the variable `goby-indent-function'. 
It is used when indenting a line within a function call, to see if the 
called function says anything special about how to indent the line. 

INDENT-POINT is the position where the user typed TAB, or equivalent. 
Point is located at the point to indent under (for default indentation); 
STATE is the `parse-partial-sexp' state for that position. 

If the current line is in a call to a Lisp function 
which has a non-nil property `goby-indent-function', 
that specifies how to do the indentation. The property value can be 
* `defun', meaning indent `defun'-style; 
* an integer N, meaning indent the first N arguments specially 
    like ordinary function arguments and then indent any further 
    arguments like a body; 
* a function to call just as this function was called. 
    If that function returns nil, that means it doesn't specify 
    the indentation. 

This function also returns nil meaning don't specify the indentation." 
    (let ((normal-indent (current-column))) 
    (goto-char (1+ (elt state 1))) 
    (parse-partial-sexp (point) calculate-lisp-indent-last-sexp 0 t) 
    (if (and (elt state 2) 
      (not (looking-at "\\sw\\|\\s_"))) 
     ;; car of form doesn't seem to be a symbol 
     (progn 
      (if (not (> (save-excursion (forward-line 1) (point)) 
         calculate-lisp-indent-last-sexp)) 
       (progn (goto-char calculate-lisp-indent-last-sexp) 
        (beginning-of-line) 
        (parse-partial-sexp (point) 
             calculate-lisp-indent-last-sexp 0 t))) 
      ;; Indent under the list or under the first sexp on the same 
      ;; line as calculate-lisp-indent-last-sexp. Note that first 
      ;; thing on that line has to be complete sexp since we are 
      ;; inside the innermost containing sexp. 
      (backward-prefix-chars) 
      (current-column)) 
     (let ((function (buffer-substring (point) 
             (progn (forward-sexp 1) (point)))) 
      method) 
     (setq method (or (get (intern-soft function) 'goby-indent-function) 
         (get (intern-soft function) 'lisp-indent-hook))) 
     (cond ((or (eq method 'defun) 
        (and (null method) 
         (> (length function) 3) 
         (string-match "\\`def" function))) 
       (lisp-indent-defform state indent-point)) 
       ((integerp method) 
       (lisp-indent-specform method state 
            indent-point normal-indent)) 
       (method 
       (funcall method indent-point state))))))) 
+0

完美!我假設我做了類似的着色? – josh 2010-09-03 01:51:56

+0

由於某種原因,如果我在.emacs (需要'slime) (slime-setup'(slime-repl slime-fancy))中這樣做,這是行不通的 - 所以粘液必須改變一些lisp模式的功能? – josh 2010-09-03 16:12:01

+0

@josh是的,着色將以相似的方式完成。檢查http://www.emacswiki.org/emacs/FontLockKeywords和http://stackoverflow.com/questions/1063115/a-hello-world-example-for-a-major-mode-in-emacs – 2010-09-03 17:10:08