2010-09-02 14 views
2

Im faire un DSL en Lisp (essentiellement ce que je pense est une syntaxe plus belle), c'est la même chose que Lisp sauf avec différents « primitifs », pas au lieu de ne pas, 'as' au lieu de let.Ainsi je dois changer l'indentation et la couleur seulement dans les fichiers qui se terminent par .goby (cela ne devrait pas affecter ceux qui se terminent par .lisp) Donc je voudrais créer des fichiers avec l'extension .goby, et avoir mon nouveau mode mineur/majeur activé (mais avec tout le reste hormis la syntaxe héritée de lisp).Comment étendre emacs mode Lisp avec des changements d'indentation et change de couleur

Cependant, tout ce que je fais aussi les fichiers d'effets! N'importe qui? Par exemple, j'ai essayé de faire une variable locale pour une indentation Lisp unique qui indenterait 'hi' de 10 espaces. mais il effectue tous les fichiers .lisp également

;;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)))) 

Répondre

2

Il y a probablement un moyen plus propre, mais d'une manière qui fonctionne est de réécrire 'lisp-indent-function être 'goby-indent-function et utiliser votre propre table des compensations comme ceci:

(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

parfait ! Je suppose que je fais quelque chose de similaire pour la coloration? – josh

+0

Pour une raison quelconque, cela ne fonctionne pas si je le fais dans emacs (require 'boue) (boue-setup' (-rempl slime-boue fantaisie)) - si la boue doit modifier certaines fonctions du mode Lisp? – josh

+0

@josh Oui, la coloration serait similaire. Vérifiez http://www.emacswiki.org/emacs/FontLockKeywords et http://stackoverflow.com/questions/1063115/a-hello-world-example-for-a-major-mode-in-emacs –