Mercurial > emacs
comparison lisp/emacs-lisp/smie.el @ 110429:06323f4d421b
* lisp/emacs-lisp/smie.el (smie-bnf-precedence-table): Improve error message.
(smie-debug--prec2-cycle, smie-debug--describe-cycle): New functions.
(smie-prec2-levels): Use them to better diagnose precedence cycles.
(smie-blink-matching-check): Don't signal a mismatch if car is t.
(smie-blink-matching-open): Rewrite to remove assumptions, so that
something like "." can also be a closer.
(smie--associative-p, smie-indent--hanging-p, smie-indent--bolp)
(smie-indent--offset, smie-indent--offset-rule, smie-indent--column):
Rename internal functions to use "--". Update callers.
author | Stefan Monnier <monnier@iro.umontreal.ca> |
---|---|
date | Sun, 19 Sep 2010 16:52:37 +0200 |
parents | eb977e012180 |
children | 6b2714f6bd1f |
comparison
equal
deleted
inserted
replaced
110428:6060b86fc551 | 110429:06323f4d421b |
---|---|
157 (last-ops ()) | 157 (last-ops ()) |
158 (first-ops ()) | 158 (first-ops ()) |
159 (last-nts ()) | 159 (last-nts ()) |
160 (first-nts ())) | 160 (first-nts ())) |
161 (dolist (rhs (cdr rules)) | 161 (dolist (rhs (cdr rules)) |
162 (assert (consp rhs)) | 162 (unless (consp rhs) |
163 (signal 'wrong-type-argument `(consp ,rhs))) | |
163 (if (not (member (car rhs) nts)) | 164 (if (not (member (car rhs) nts)) |
164 (pushnew (car rhs) first-ops) | 165 (pushnew (car rhs) first-ops) |
165 (pushnew (car rhs) first-nts) | 166 (pushnew (car rhs) first-nts) |
166 (when (consp (cdr rhs)) | 167 (when (consp (cdr rhs)) |
167 ;; If the first is not an OP we add the second (which | 168 ;; If the first is not an OP we add the second (which |
304 (dolist (term (reverse (cdr rhs))) | 305 (dolist (term (reverse (cdr rhs))) |
305 (unless (member term nts) | 306 (unless (member term nts) |
306 (pushnew (cons (car rhs) term) alist :test #'equal))))))) | 307 (pushnew (cons (car rhs) term) alist :test #'equal))))))) |
307 (nreverse alist))) | 308 (nreverse alist))) |
308 | 309 |
310 | |
311 (defun smie-debug--prec2-cycle (csts) | |
312 "Return a cycle in CSTS, assuming there's one. | |
313 CSTS is a list of pairs representing arcs in a graph." | |
314 ;; A PATH is of the form (START . REST) where REST is a reverse | |
315 ;; list of nodes through which the path goes. | |
316 (let ((paths (mapcar (lambda (pair) (list (car pair) (cdr pair))) csts)) | |
317 (cycle nil)) | |
318 (while (null cycle) | |
319 (dolist (path (prog1 paths (setq paths nil))) | |
320 (dolist (cst csts) | |
321 (when (eq (car cst) (nth 1 path)) | |
322 (if (eq (cdr cst) (car path)) | |
323 (setq cycle path) | |
324 (push (cons (car path) (cons (cdr cst) (cdr path))) | |
325 paths)))))) | |
326 (cons (car cycle) (nreverse (cdr cycle))))) | |
327 | |
328 (defun smie-debug--describe-cycle (table cycle) | |
329 (let ((names | |
330 (mapcar (lambda (val) | |
331 (let ((res nil)) | |
332 (dolist (elem table) | |
333 (if (eq (cdr elem) val) | |
334 (push (concat "." (car elem)) res)) | |
335 (if (eq (cddr elem) val) | |
336 (push (concat (car elem) ".") res))) | |
337 (assert res) | |
338 res)) | |
339 cycle))) | |
340 (mapconcat | |
341 (lambda (elems) (mapconcat 'indentity elems "=")) | |
342 (append names (list (car names))) | |
343 " < "))) | |
309 | 344 |
310 (defun smie-prec2-levels (prec2) | 345 (defun smie-prec2-levels (prec2) |
311 ;; FIXME: Rather than only return an alist of precedence levels, we should | 346 ;; FIXME: Rather than only return an alist of precedence levels, we should |
312 ;; also extract other useful data from it: | 347 ;; also extract other useful data from it: |
313 ;; - matching sets of block openers&closers (which can otherwise become | 348 ;; - matching sets of block openers&closers (which can otherwise become |
385 (unless (caar cst) | 420 (unless (caar cst) |
386 (setcar (car cst) i) | 421 (setcar (car cst) i) |
387 (incf i)) | 422 (incf i)) |
388 (setq csts (delq cst csts)))) | 423 (setq csts (delq cst csts)))) |
389 (unless progress | 424 (unless progress |
390 (error "Can't resolve the precedence table to precedence levels"))) | 425 (error "Can't resolve the precedence cycle: %s" |
426 (smie-debug--describe-cycle | |
427 table (smie-debug--prec2-cycle csts))))) | |
391 (incf i 10)) | 428 (incf i 10)) |
392 ;; Propagate equalities back to their source. | 429 ;; Propagate equalities back to their source. |
393 (dolist (eq (nreverse eqs)) | 430 (dolist (eq (nreverse eqs)) |
394 (assert (or (null (caar eq)) (eq (car eq) (cdr eq)))) | 431 (assert (or (null (caar eq)) (eq (car eq) (cdr eq)))) |
395 (setcar (car eq) (cadr eq))) | 432 (setcar (car eq) (cadr eq))) |
448 (point) | 485 (point) |
449 (progn (if (zerop (skip-syntax-forward ".")) | 486 (progn (if (zerop (skip-syntax-forward ".")) |
450 (skip-syntax-forward "w_'")) | 487 (skip-syntax-forward "w_'")) |
451 (point)))) | 488 (point)))) |
452 | 489 |
453 (defun smie-associative-p (toklevels) | 490 (defun smie--associative-p (toklevels) |
454 ;; in "a + b + c" we want to stop at each +, but in | 491 ;; in "a + b + c" we want to stop at each +, but in |
455 ;; "if a then b elsif c then d else c" we don't want to stop at each keyword. | 492 ;; "if a then b elsif c then d else c" we don't want to stop at each keyword. |
456 ;; To distinguish the two cases, we made smie-prec2-levels choose | 493 ;; To distinguish the two cases, we made smie-prec2-levels choose |
457 ;; different levels for each part of "if a then b else c", so that | 494 ;; different levels for each part of "if a then b else c", so that |
458 ;; by checking if the left-level is equal to the right level, we can | 495 ;; by checking if the left-level is equal to the right level, we can |
533 ;; It is the last element, let's stop here. | 570 ;; It is the last element, let's stop here. |
534 (throw 'return (list nil (point) token))) | 571 (throw 'return (list nil (point) token))) |
535 ;; If the new operator is not the last in the BNF rule, | 572 ;; If the new operator is not the last in the BNF rule, |
536 ;; ans is not associative, it's one of the inner operators | 573 ;; ans is not associative, it's one of the inner operators |
537 ;; (like the "in" in "let .. in .. end"), so keep looking. | 574 ;; (like the "in" in "let .. in .. end"), so keep looking. |
538 ((not (smie-associative-p toklevels)) | 575 ((not (smie--associative-p toklevels)) |
539 (push toklevels levels)) | 576 (push toklevels levels)) |
540 ;; The new operator is associative. Two cases: | 577 ;; The new operator is associative. Two cases: |
541 ;; - it's really just an associative operator (like + or ;) | 578 ;; - it's really just an associative operator (like + or ;) |
542 ;; in which case we should have stopped right before. | 579 ;; in which case we should have stopped right before. |
543 ((and lastlevels | 580 ((and lastlevels |
544 (smie-associative-p (car lastlevels))) | 581 (smie--associative-p (car lastlevels))) |
545 (throw 'return | 582 (throw 'return |
546 (prog1 (list (or (car toklevels) t) (point) token) | 583 (prog1 (list (or (car toklevels) t) (point) token) |
547 (goto-char pos)))) | 584 (goto-char pos)))) |
548 ;; - it's an associative operator within a larger construct | 585 ;; - it's an associative operator within a larger construct |
549 ;; (e.g. an "elsif"), so we should just ignore it and keep | 586 ;; (e.g. an "elsif"), so we should just ignore it and keep |
718 (cond | 755 (cond |
719 ((not (and ender (rassoc ender smie-closer-alist))) | 756 ((not (and ender (rassoc ender smie-closer-alist))) |
720 ;; This not is one of the begin..end we know how to check. | 757 ;; This not is one of the begin..end we know how to check. |
721 (blink-matching-check-mismatch start end)) | 758 (blink-matching-check-mismatch start end)) |
722 ((not start) t) | 759 ((not start) t) |
760 ((eq t (car (rassoc ender smie-closer-alist))) nil) | |
723 (t | 761 (t |
724 (goto-char start) | 762 (goto-char start) |
725 (let ((starter (funcall smie-forward-token-function))) | 763 (let ((starter (funcall smie-forward-token-function))) |
726 (not (member (cons starter ender) smie-closer-alist)))))))) | 764 (not (member (cons starter ender) smie-closer-alist)))))))) |
727 | 765 |
730 This uses SMIE's tables and is expected to be placed on `post-self-insert-hook'." | 768 This uses SMIE's tables and is expected to be placed on `post-self-insert-hook'." |
731 (when (and blink-matching-paren | 769 (when (and blink-matching-paren |
732 smie-closer-alist ; Optimization. | 770 smie-closer-alist ; Optimization. |
733 (eq (char-before) last-command-event) ; Sanity check. | 771 (eq (char-before) last-command-event) ; Sanity check. |
734 (memq last-command-event smie-blink-matching-triggers) | 772 (memq last-command-event smie-blink-matching-triggers) |
735 (save-excursion | 773 (not (nth 8 (syntax-ppss)))) |
736 ;; FIXME: Here we assume that closers all end | |
737 ;; with a word-syntax char. | |
738 (unless (eq ?\w (char-syntax last-command-event)) | |
739 (forward-char -1)) | |
740 (and (looking-at "\\>") | |
741 (not (nth 8 (syntax-ppss)))))) | |
742 (save-excursion | 774 (save-excursion |
743 (let ((pos (point)) | 775 (let ((pos (point)) |
744 (token (funcall smie-backward-token-function))) | 776 (token (funcall smie-backward-token-function))) |
745 (if (= 1 (length token)) | 777 (when (and (eq (point) (1- pos)) |
746 ;; The trigger char is itself a token but is not | 778 (= 1 (length token)) |
747 ;; one of the closers (e.g. ?\; in Octave mode), | 779 (not (rassoc token smie-closer-alist))) |
748 ;; so go back to the previous token | 780 ;; The trigger char is itself a token but is not one of the |
749 (setq token (save-excursion | 781 ;; closers (e.g. ?\; in Octave mode), so go back to the |
750 (funcall smie-backward-token-function))) | 782 ;; previous token. |
751 (goto-char pos)) | 783 (setq pos (point)) |
752 ;; Here we assume that smie-backward-token-function | 784 (setq token (save-excursion |
753 ;; returns a token that is a string and whose content | 785 (funcall smie-backward-token-function)))) |
754 ;; match the buffer's representation of this token. | 786 (when (rassoc token smie-closer-alist) |
755 (when (and (> (length token) 1) (stringp token) | 787 ;; We're after a close token. Let's still make sure we |
756 (memq (aref token (1- (length token))) | 788 ;; didn't skip a comment to find that token. |
757 smie-blink-matching-triggers) | 789 (funcall smie-forward-token-function) |
758 (not (eq (aref token (1- (length token))) | 790 (when (and (save-excursion |
759 last-command-event))) | 791 ;; Trigger can be SPC, or reindent. |
760 ;; Token ends with a trigger char, so don't blink for | 792 (skip-chars-forward " \n\t") |
761 ;; anything else than this trigger char, lest we'd blink | 793 (>= (point) pos)) |
762 ;; both when inserting the trigger char and when inserting a | 794 ;; If token ends with a trigger char, so don't blink for |
763 ;; subsequent SPC. | 795 ;; anything else than this trigger char, lest we'd blink |
764 (setq token nil)) | 796 ;; both when inserting the trigger char and when |
765 (when (and (rassoc token smie-closer-alist) | 797 ;; inserting a subsequent trigger char like SPC. |
766 (or smie-blink-matching-inners | 798 (or (eq (point) pos) |
767 (null (nth 2 (assoc token smie-op-levels))))) | 799 (not (memq (char-before) |
768 ;; The major mode might set blink-matching-check-function | 800 smie-blink-matching-triggers))) |
769 ;; buffer-locally so that interactive calls to | 801 (or smie-blink-matching-inners |
770 ;; blink-matching-open work right, but let's not presume | 802 (null (nth 2 (assoc token smie-op-levels))))) |
771 ;; that's the case. | 803 ;; The major mode might set blink-matching-check-function |
772 (let ((blink-matching-check-function #'smie-blink-matching-check)) | 804 ;; buffer-locally so that interactive calls to |
773 (blink-matching-open))))))) | 805 ;; blink-matching-open work right, but let's not presume |
806 ;; that's the case. | |
807 (let ((blink-matching-check-function #'smie-blink-matching-check)) | |
808 (blink-matching-open)))))))) | |
774 | 809 |
775 ;;; The indentation engine. | 810 ;;; The indentation engine. |
776 | 811 |
777 (defcustom smie-indent-basic 4 | 812 (defcustom smie-indent-basic 4 |
778 "Basic amount of indentation." | 813 "Basic amount of indentation." |
819 position of its parent, or the position right after its parent. | 854 position of its parent, or the position right after its parent. |
820 | 855 |
821 A nil offset for indentation after an opening token defaults | 856 A nil offset for indentation after an opening token defaults |
822 to `smie-indent-basic'.") | 857 to `smie-indent-basic'.") |
823 | 858 |
824 (defun smie-indent-hanging-p () | 859 (defun smie-indent--hanging-p () |
825 ;; A hanging keyword is one that's at the end of a line except it's not at | 860 ;; A hanging keyword is one that's at the end of a line except it's not at |
826 ;; the beginning of a line. | 861 ;; the beginning of a line. |
827 (and (save-excursion | 862 (and (save-excursion |
828 (when (zerop (length (funcall smie-forward-token-function))) | 863 (when (zerop (length (funcall smie-forward-token-function))) |
829 ;; Could be an open-paren. | 864 ;; Could be an open-paren. |
830 (forward-char 1)) | 865 (forward-char 1)) |
831 (skip-chars-forward " \t") | 866 (skip-chars-forward " \t") |
832 (eolp)) | 867 (eolp)) |
833 (not (smie-bolp)))) | 868 (not (smie-bolp)))) |
834 | 869 |
835 (defun smie-bolp () | 870 (defun smie-indent--bolp () |
836 (save-excursion (skip-chars-backward " \t") (bolp))) | 871 (save-excursion (skip-chars-backward " \t") (bolp))) |
837 | 872 |
838 (defun smie-indent-offset (elem) | 873 (defun smie-indent--offset (elem) |
839 (or (cdr (assq elem smie-indent-rules)) | 874 (or (cdr (assq elem smie-indent-rules)) |
840 (cdr (assq t smie-indent-rules)) | 875 (cdr (assq t smie-indent-rules)) |
841 smie-indent-basic)) | 876 smie-indent-basic)) |
842 | 877 |
843 (defvar smie-indent-debug-log) | 878 (defvar smie-indent-debug-log) |
844 | 879 |
845 (defun smie-indent-offset-rule (tokinfo &optional after parent) | 880 (defun smie-indent--offset-rule (tokinfo &optional after parent) |
846 "Apply the OFFSET-RULES in TOKINFO. | 881 "Apply the OFFSET-RULES in TOKINFO. |
847 Point is expected to be right in front of the token corresponding to TOKINFO. | 882 Point is expected to be right in front of the token corresponding to TOKINFO. |
848 If computing the indentation after the token, then AFTER is the position | 883 If computing the indentation after the token, then AFTER is the position |
849 after the token, otherwise it should be nil. | 884 after the token, otherwise it should be nil. |
850 PARENT if non-nil should be the parent info returned by `smie-backward-sexp'." | 885 PARENT if non-nil should be the parent info returned by `smie-backward-sexp'." |
855 (let ((rule (pop rules))) | 890 (let ((rule (pop rules))) |
856 (cond | 891 (cond |
857 ((not (consp rule)) (setq offset rule)) | 892 ((not (consp rule)) (setq offset rule)) |
858 ((eq (car rule) '+) (setq offset rule)) | 893 ((eq (car rule) '+) (setq offset rule)) |
859 ((eq (car rule) :hanging) | 894 ((eq (car rule) :hanging) |
860 (when (smie-indent-hanging-p) | 895 (when (smie-indent--hanging-p) |
861 (setq rules (cdr rule)))) | 896 (setq rules (cdr rule)))) |
862 ((eq (car rule) :bolp) | 897 ((eq (car rule) :bolp) |
863 (when (smie-bolp) | 898 (when (smie-indent--bolp) |
864 (setq rules (cdr rule)))) | 899 (setq rules (cdr rule)))) |
865 ((eq (car rule) :eolp) | 900 ((eq (car rule) :eolp) |
866 (unless after | 901 (unless after |
867 (error "Can't use :eolp in :before indentation rules")) | 902 (error "Can't use :eolp in :before indentation rules")) |
868 (when (> after (line-end-position)) | 903 (when (> after (line-end-position)) |
898 (unless offset (setq offset rules)) | 933 (unless offset (setq offset rules)) |
899 (when (boundp 'smie-indent-debug-log) | 934 (when (boundp 'smie-indent-debug-log) |
900 (push (list (point) offset tokinfo) smie-indent-debug-log)) | 935 (push (list (point) offset tokinfo) smie-indent-debug-log)) |
901 offset)) | 936 offset)) |
902 | 937 |
903 (defun smie-indent-column (offset &optional base parent virtual-point) | 938 (defun smie-indent--column (offset &optional base parent virtual-point) |
904 "Compute the actual column to use for a given OFFSET. | 939 "Compute the actual column to use for a given OFFSET. |
905 BASE is the base position to use, and PARENT is the parent info, if any. | 940 BASE is the base position to use, and PARENT is the parent info, if any. |
906 If VIRTUAL-POINT is non-nil, then `point' is virtual." | 941 If VIRTUAL-POINT is non-nil, then `point' is virtual." |
907 (cond | 942 (cond |
908 ((eq (car-safe offset) '+) | 943 ((eq (car-safe offset) '+) |
909 (apply '+ (mapcar (lambda (offset) (smie-indent-column offset nil parent)) | 944 (apply '+ (mapcar (lambda (offset) (smie-indent--column offset nil parent)) |
910 (cdr offset)))) | 945 (cdr offset)))) |
911 ((integerp offset) | 946 ((integerp offset) |
912 (+ offset | 947 (+ offset |
913 (case base | 948 (case base |
914 ((nil) 0) | 949 ((nil) 0) |
939 (setq parent (or (smie-backward-sexp 'halfsexp) :notfound))) | 974 (setq parent (or (smie-backward-sexp 'halfsexp) :notfound))) |
940 (if (consp parent) (goto-char (cadr parent))) | 975 (if (consp parent) (goto-char (cadr parent))) |
941 (smie-indent-virtual)) | 976 (smie-indent-virtual)) |
942 ((eq offset nil) nil) | 977 ((eq offset nil) nil) |
943 ((and (symbolp offset) (boundp 'offset)) | 978 ((and (symbolp offset) (boundp 'offset)) |
944 (smie-indent-column (symbol-value offset) base parent virtual-point)) | 979 (smie-indent--column (symbol-value offset) base parent virtual-point)) |
945 (t (error "Unknown indentation offset %s" offset)))) | 980 (t (error "Unknown indentation offset %s" offset)))) |
946 | 981 |
947 (defun smie-indent-forward-token () | 982 (defun smie-indent-forward-token () |
948 "Skip token forward and return it, along with its levels." | 983 "Skip token forward and return it, along with its levels." |
949 (let ((tok (funcall smie-forward-token-function))) | 984 (let ((tok (funcall smie-forward-token-function))) |
972 "Compute the virtual indentation to use for point. | 1007 "Compute the virtual indentation to use for point. |
973 This is used when we're not trying to indent point but just | 1008 This is used when we're not trying to indent point but just |
974 need to compute the column at which point should be indented | 1009 need to compute the column at which point should be indented |
975 in order to figure out the indentation of some other (further down) point." | 1010 in order to figure out the indentation of some other (further down) point." |
976 ;; Trust pre-existing indentation on other lines. | 1011 ;; Trust pre-existing indentation on other lines. |
977 (if (smie-bolp) (current-column) (smie-indent-calculate))) | 1012 (if (smie-indent--bolp) (current-column) (smie-indent-calculate))) |
978 | 1013 |
979 (defun smie-indent-fixindent () | 1014 (defun smie-indent-fixindent () |
980 ;; Obey the `fixindent' special comment. | 1015 ;; Obey the `fixindent' special comment. |
981 (and (smie-bolp) | 1016 (and (smie-indent--bolp) |
982 (save-excursion | 1017 (save-excursion |
983 (comment-normalize-vars) | 1018 (comment-normalize-vars) |
984 (re-search-forward (concat comment-start-skip | 1019 (re-search-forward (concat comment-start-skip |
985 "fixindent" | 1020 "fixindent" |
986 comment-end-skip) | 1021 comment-end-skip) |
1016 (token (pop toklevels))) | 1051 (token (pop toklevels))) |
1017 (if (null (car toklevels)) | 1052 (if (null (car toklevels)) |
1018 (save-excursion | 1053 (save-excursion |
1019 (goto-char pos) | 1054 (goto-char pos) |
1020 ;; Different cases: | 1055 ;; Different cases: |
1021 ;; - smie-bolp: "indent according to others". | 1056 ;; - smie-indent--bolp: "indent according to others". |
1022 ;; - common hanging: "indent according to others". | 1057 ;; - common hanging: "indent according to others". |
1023 ;; - SML-let hanging: "indent like parent". | 1058 ;; - SML-let hanging: "indent like parent". |
1024 ;; - if-after-else: "indent-like parent". | 1059 ;; - if-after-else: "indent-like parent". |
1025 ;; - middle-of-line: "trust current position". | 1060 ;; - middle-of-line: "trust current position". |
1026 (cond | 1061 (cond |
1027 ((null (cdr toklevels)) nil) ;Not a keyword. | 1062 ((null (cdr toklevels)) nil) ;Not a keyword. |
1028 ((smie-bolp) | 1063 ((smie-indent--bolp) |
1029 ;; For an open-paren-like thingy at BOL, always indent only | 1064 ;; For an open-paren-like thingy at BOL, always indent only |
1030 ;; based on other rules (typically smie-indent-after-keyword). | 1065 ;; based on other rules (typically smie-indent-after-keyword). |
1031 nil) | 1066 nil) |
1032 (t | 1067 (t |
1033 ;; We're only ever here for virtual-indent, which is why | 1068 ;; We're only ever here for virtual-indent, which is why |
1035 (let* ((tokinfo (or (assoc (cons :before token) | 1070 (let* ((tokinfo (or (assoc (cons :before token) |
1036 smie-indent-rules) | 1071 smie-indent-rules) |
1037 ;; By default use point unless we're hanging. | 1072 ;; By default use point unless we're hanging. |
1038 `((:before . ,token) (:hanging nil) point))) | 1073 `((:before . ,token) (:hanging nil) point))) |
1039 ;; (after (prog1 (point) (goto-char pos))) | 1074 ;; (after (prog1 (point) (goto-char pos))) |
1040 (offset (smie-indent-offset-rule tokinfo))) | 1075 (offset (smie-indent--offset-rule tokinfo))) |
1041 (smie-indent-column offset))))) | 1076 (smie-indent--column offset))))) |
1042 | 1077 |
1043 ;; FIXME: This still looks too much like black magic!! | 1078 ;; FIXME: This still looks too much like black magic!! |
1044 ;; FIXME: Rather than a bunch of rules like (PARENT . TOKEN), we | 1079 ;; FIXME: Rather than a bunch of rules like (PARENT . TOKEN), we |
1045 ;; want a single rule for TOKEN with different cases for each PARENT. | 1080 ;; want a single rule for TOKEN with different cases for each PARENT. |
1046 (let* ((parent (smie-backward-sexp 'halfsexp)) | 1081 (let* ((parent (smie-backward-sexp 'halfsexp)) |
1052 `((:before . ,token) | 1087 `((:before . ,token) |
1053 ;; (:parent open 0) | 1088 ;; (:parent open 0) |
1054 point))) | 1089 point))) |
1055 (offset (save-excursion | 1090 (offset (save-excursion |
1056 (goto-char pos) | 1091 (goto-char pos) |
1057 (smie-indent-offset-rule tokinfo nil parent)))) | 1092 (smie-indent--offset-rule tokinfo nil parent)))) |
1058 ;; Different behaviors: | 1093 ;; Different behaviors: |
1059 ;; - align with parent. | 1094 ;; - align with parent. |
1060 ;; - parent + offset. | 1095 ;; - parent + offset. |
1061 ;; - after parent's column + offset (actually, after or before | 1096 ;; - after parent's column + offset (actually, after or before |
1062 ;; depending on where backward-sexp stopped). | 1097 ;; depending on where backward-sexp stopped). |
1077 ;; maybe when an infix or close-paren is at the beginning | 1112 ;; maybe when an infix or close-paren is at the beginning |
1078 ;; of a buffer. | 1113 ;; of a buffer. |
1079 nil) | 1114 nil) |
1080 ((eq (car parent) (car toklevels)) | 1115 ((eq (car parent) (car toklevels)) |
1081 ;; We bumped into a same-level operator. align with it. | 1116 ;; We bumped into a same-level operator. align with it. |
1082 (if (and (smie-bolp) (/= (point) pos) | 1117 (if (and (smie-indent--bolp) (/= (point) pos) |
1083 (save-excursion | 1118 (save-excursion |
1084 (goto-char (goto-char (cadr parent))) | 1119 (goto-char (goto-char (cadr parent))) |
1085 (not (smie-bolp))) | 1120 (not (smie-indent--bolp))) |
1086 ;; Check the offset of `token' rather then its parent | 1121 ;; Check the offset of `token' rather then its parent |
1087 ;; because its parent may have used a special rule. E.g. | 1122 ;; because its parent may have used a special rule. E.g. |
1088 ;; function foo; | 1123 ;; function foo; |
1089 ;; line2; | 1124 ;; line2; |
1090 ;; line3; | 1125 ;; line3; |
1117 ;; a -> b -> c | 1152 ;; a -> b -> c |
1118 ;; -> d | 1153 ;; -> d |
1119 ;; So as to align with the earliest appropriate place. | 1154 ;; So as to align with the earliest appropriate place. |
1120 (smie-indent-virtual))) | 1155 (smie-indent-virtual))) |
1121 (tokinfo | 1156 (tokinfo |
1122 (if (and (= (point) pos) (smie-bolp) | 1157 (if (and (= (point) pos) (smie-indent--bolp) |
1123 (or (eq offset 'point) | 1158 (or (eq offset 'point) |
1124 (and (consp offset) (memq 'point offset)))) | 1159 (and (consp offset) (memq 'point offset)))) |
1125 ;; Since we started at BOL, we're not computing a virtual | 1160 ;; Since we started at BOL, we're not computing a virtual |
1126 ;; indentation, and we're still at the starting point, so | 1161 ;; indentation, and we're still at the starting point, so |
1127 ;; we can't use `current-column' which would cause | 1162 ;; we can't use `current-column' which would cause |
1128 ;; indentation to depend on itself. | 1163 ;; indentation to depend on itself. |
1129 nil | 1164 nil |
1130 (smie-indent-column offset 'parent parent | 1165 (smie-indent--column offset 'parent parent |
1131 ;; If we're still at pos, indent-virtual | 1166 ;; If we're still at pos, indent-virtual |
1132 ;; will inf-loop. | 1167 ;; will inf-loop. |
1133 (unless (= (point) pos) 'virtual)))))))))) | 1168 (unless (= (point) pos) 'virtual)))))))))) |
1134 | 1169 |
1135 (defun smie-indent-comment () | 1170 (defun smie-indent-comment () |
1136 "Compute indentation of a comment." | 1171 "Compute indentation of a comment." |
1137 ;; Don't do it for virtual indentations. We should normally never be "in | 1172 ;; Don't do it for virtual indentations. We should normally never be "in |
1138 ;; front of a comment" when doing virtual-indentation anyway. And if we are | 1173 ;; front of a comment" when doing virtual-indentation anyway. And if we are |
1139 ;; (as can happen in octave-mode), moving forward can lead to inf-loops. | 1174 ;; (as can happen in octave-mode), moving forward can lead to inf-loops. |
1140 (and (smie-bolp) | 1175 (and (smie-indent--bolp) |
1141 (looking-at comment-start-skip) | 1176 (looking-at comment-start-skip) |
1142 (save-excursion | 1177 (save-excursion |
1143 (forward-comment (point-max)) | 1178 (forward-comment (point-max)) |
1144 (skip-chars-forward " \t\r\n") | 1179 (skip-chars-forward " \t\r\n") |
1145 (smie-indent-calculate)))) | 1180 (smie-indent-calculate)))) |
1176 ;; The default indentation after a keyword/operator is 0 for | 1211 ;; The default indentation after a keyword/operator is 0 for |
1177 ;; infix and t for prefix. | 1212 ;; infix and t for prefix. |
1178 ;; Using the BNF syntax, we could come up with better | 1213 ;; Using the BNF syntax, we could come up with better |
1179 ;; defaults, but we only have the precedence levels here. | 1214 ;; defaults, but we only have the precedence levels here. |
1180 (setq tokinfo (list tok 'default-rule | 1215 (setq tokinfo (list tok 'default-rule |
1181 (if (cadr toklevel) 0 (smie-indent-offset t))))) | 1216 (if (cadr toklevel) 0 (smie-indent--offset t))))) |
1182 (let ((offset | 1217 (let ((offset |
1183 (or (smie-indent-offset-rule tokinfo pos) | 1218 (or (smie-indent--offset-rule tokinfo pos) |
1184 (smie-indent-offset t)))) | 1219 (smie-indent--offset t)))) |
1185 (let ((before (point))) | 1220 (let ((before (point))) |
1186 (goto-char pos) | 1221 (goto-char pos) |
1187 (smie-indent-column offset before))))))) | 1222 (smie-indent--column offset before))))))) |
1188 | 1223 |
1189 (defun smie-indent-exps () | 1224 (defun smie-indent-exps () |
1190 ;; Indentation of sequences of simple expressions without | 1225 ;; Indentation of sequences of simple expressions without |
1191 ;; intervening keywords or operators. E.g. "a b c" or "g (balbla) f". | 1226 ;; intervening keywords or operators. E.g. "a b c" or "g (balbla) f". |
1192 ;; Can be a list of expressions or a function call. | 1227 ;; Can be a list of expressions or a function call. |
1205 (save-excursion | 1240 (save-excursion |
1206 (let ((positions nil) | 1241 (let ((positions nil) |
1207 arg) | 1242 arg) |
1208 (while (and (null (car (smie-backward-sexp))) | 1243 (while (and (null (car (smie-backward-sexp))) |
1209 (push (point) positions) | 1244 (push (point) positions) |
1210 (not (smie-bolp)))) | 1245 (not (smie-indent--bolp)))) |
1211 (save-excursion | 1246 (save-excursion |
1212 ;; Figure out if the atom we just skipped is an argument rather | 1247 ;; Figure out if the atom we just skipped is an argument rather |
1213 ;; than a function. | 1248 ;; than a function. |
1214 (setq arg (or (null (car (smie-backward-sexp))) | 1249 (setq arg (or (null (car (smie-backward-sexp))) |
1215 (member (funcall smie-backward-token-function) | 1250 (member (funcall smie-backward-token-function) |
1230 (goto-char (cadr positions)) | 1265 (goto-char (cadr positions)) |
1231 (current-column)) | 1266 (current-column)) |
1232 (positions | 1267 (positions |
1233 ;; We're the first arg. | 1268 ;; We're the first arg. |
1234 (goto-char (car positions)) | 1269 (goto-char (car positions)) |
1235 ;; FIXME: Use smie-indent-column. | 1270 ;; FIXME: Use smie-indent--column. |
1236 (+ (smie-indent-offset 'args) | 1271 (+ (smie-indent--offset 'args) |
1237 ;; We used to use (smie-indent-virtual), but that | 1272 ;; We used to use (smie-indent-virtual), but that |
1238 ;; doesn't seem right since it might then indent args less than | 1273 ;; doesn't seem right since it might then indent args less than |
1239 ;; the function itself. | 1274 ;; the function itself. |
1240 (current-column))))))) | 1275 (current-column))))))) |
1241 | 1276 |