2014-03-04 2 views
7

Мне не нравится, как plists с отступом в Elisp.Настроить выемку plisp elisp

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

Пробовал на M-х Emacs-версии 24.3.1, побежал emacs -Q, набрал PLIST и прессуют C-х ч C-M- \.

Это отступ имеет смысл, если это не список:

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

Как изменить форматирование настроек, так что только plists (или, если это невозможно, все приведенные списки) имеют нужный прямоугольные отступ, но отступ всего остального остается неизменным? Мне нужно, чтобы это было сохранено локально в файле .el, так что, когда я редактирую этот файл, он имеет отступы по желанию, но это поведение не заканчивается нигде.

+0

По этой причине и многие другие, я рекомендую использовать alists, а не plists. – Stefan

ответ

6

Нашел:

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

Вот пример файл:

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

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

Я просто сваливать весь мой отступ конфиг здесь:

(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

Зачем вам файл локально? Документ говорит, что это может быть рискованным :) –

+1

Итак, пользователь получает файл от вас и хочет его отредактировать? –

+0

Я до сих пор не понимаю, как пользователь должен редактировать библиотеку. Они отправляют изменения обратно вам? –

1

Вы можете это исправить (в мое мнение) ошибка путем переопределения lisp-indent-function. Исходным источником взлома был this Github Gist, на который ссылалось еще несколько пояснений от this Emacs Stack Exchange answer.

Однако мне было очень неудобно переопределять основную функцию, подобную этой. Во-первых, это очень непрозрачно - как читатель должен сказать, что изменилось? И хуже - что, если официальное определение lisp-indent-function изменилось в будущем? Как я узнаю, что мне нужно обновить свой взлом?

В ответ я создал библиотеку el-patch, которая специально разработана для решения этой проблемы. После установки пакета, вы можете переопределить lisp-indent-function следующим образом:

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

 Смежные вопросы

  • Нет связанных вопросов^_^