2014-03-04 16 views
7

Ich mag nicht wie in Elisp plists eingerückt sind.Anpassen Elisp Plist Einrückung

;; current desired Python (for comparison) 
;; '(a 1  '(a 1  {'a': 1, 
;;  b 2  b 2  'b': 2, 
;;  c 3) c 3)  'c': 3} 

Versuchte auf M-x Emacs-Version 24.3.1, lief emacs -Q, die plist eingegeben und gedrückt C-x h C-M- \.

Diese Vertiefung macht Sinn, wenn es keine Liste ist:

(mapcar (lambda (x) (x + 1)) 
     '(1 2 3 4)) 

Wie kann ich Formatierungseinstellungen ändern, so dass nur plists (oder, falls dies nicht möglich ist, alle genannten Listen) den gewünschten rechteckigen Einrückung, aber Einrückung von allem anderen bleibt gleich? Ich brauche dies lokal in einer .el-Datei gespeichert, so dass, wenn ich diese Datei bearbeiten, es wie gewünscht eingerückt ist, aber dieses Verhalten nicht irgendwo anders endet.

+0

Aus diesem Grund und viele andere, ich empfehlen die Verwendung von Alists statt plists. – Stefan

Antwort

6

es gefunden:

(setq lisp-indent-function 'common-lisp-indent-function) 

Hier ist eine Beispieldatei:

(setq x '(a 1 
      b 2 
      c 3)) 

;;; Local Variables: 
;;; lisp-indent-function: common-lisp-indent-function 
;;; End: 

Ich werde einfach hier meine ganze Einzug Config-Dump:

(setq lisp-indent-function 'common-lisp-indent-function) 
(put 'cl-flet 'common-lisp-indent-function 
    (get 'flet 'common-lisp-indent-function)) 
(put 'cl-labels 'common-lisp-indent-function 
    (get 'labels 'common-lisp-indent-function)) 
(put 'if 'common-lisp-indent-function 2) 
(put 'dotimes-protect 'common-lisp-indent-function 
    (get 'when 'common-lisp-indent-function)) 
+0

Warum brauchen Sie es lokal? Der Doc sagt, es könnte riskant sein :) –

+1

Also der Benutzer bekommt die Datei von Ihnen und will sie bearbeiten? –

+0

Ich verstehe immer noch nicht, wie ein Benutzer eine Bibliothek bearbeiten soll. Senden sie die Änderungen an Sie zurück? –

1

Sie können dieses Problem beheben (in meine Meinung) Bug durch Überschreiben lisp-indent-function. Die ursprüngliche Quelle des Hacks war this Github Gist, auf die mit weiteren Erläuterungen von this Emacs Stack Exchange answer verwiesen wurde.

Allerdings war ich sehr unangenehm über eine Kernfunktion wie folgt. Zum einen ist es sehr undurchsichtig - wie soll ein Leser sagen, was sich verändert hat? Und noch schlimmer - was, wenn sich die offizielle Definition von lisp-indent-function in Zukunft ändert? Woher sollte ich wissen, dass ich meinen Hack aktualisieren musste?

Als Antwort habe ich die Bibliothek el-patch erstellt, die speziell entwickelt wurde, um dieses Problem zu beheben. Nach der Installation des Pakets können Sie lisp-indent-function außer Kraft setzen, wie folgt:

(el-patch-defun lisp-indent-function (indent-point state) 
    "This function is the normal value of the variable `lisp-indent-function'. 
The function `calculate-lisp-indent' calls this to determine 
if the arguments of a Lisp function call should be indented specially. 

INDENT-POINT is the position at which the line being indented begins. 
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 that has a non-nil 
property `lisp-indent-function' (or the deprecated `lisp-indent-hook'), 
it specifies how to indent. The property value can be: 

* `defun', meaning indent `defun'-style 
    (this is also the case if there is no property and the function 
    has a name that begins with \"def\", and three or more arguments); 

* 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 that returns the indentation (or nil). 
    `lisp-indent-function' calls this function with the same two arguments 
    that it itself received. 

This function returns either the indentation to use, or nil if the 
Lisp function does not specify a special indentation." 
    (el-patch-let (($cond (and (elt state 2) 
          (el-patch-wrap 1 1 
           (or (not (looking-at "\\sw\\|\\s_")) 
            (looking-at ":"))))) 
       ($then (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))) 
       ($else (let ((function (buffer-substring (point) 
                  (progn (forward-sexp 1) (point)))) 
           method) 
          (setq method (or (function-get (intern-soft function) 
                 'lisp-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)))))) 
    (let ((normal-indent (current-column)) 
      (el-patch-add 
      (orig-point (point)))) 
     (goto-char (1+ (elt state 1))) 
     (parse-partial-sexp (point) calculate-lisp-indent-last-sexp 0 t) 
     (el-patch-swap 
     (if $cond 
      ;; car of form doesn't seem to be a symbol 
      $then 
      $else) 
     (cond 
     ;; car of form doesn't seem to be a symbol, or is a keyword 
     ($cond $then) 
     ((and (save-excursion 
       (goto-char indent-point) 
       (skip-syntax-forward " ") 
       (not (looking-at ":"))) 
       (save-excursion 
       (goto-char orig-point) 
       (looking-at ":"))) 
      (save-excursion 
      (goto-char (+ 2 (elt state 1))) 
      (current-column))) 
     (t $else))))))