- (save-excursion
- (goto-char (point-min))
- (let ((learned-var-list nil)
- (out-buffer "*indent*")
- (num-diffs 0)
- previous-set-info
- (max 17)
- vec
- msg
- (comment-col nil) ;; number if all same, t if seen diff values
- (comments-always-default t) ;; nil if we see one not default
- initial-msg
- (specified-basic-offset (and arg (numberp arg)
- (> arg 0)))
- (linenum 0)
- suggested)
- (setq vec (make-vector max 0))
- (sh-mark-init out-buffer)
-
- (if specified-basic-offset
- (progn
- (setq sh-basic-offset arg)
- (setq initial-msg
- (format "Using specified sh-basic-offset of %d"
- sh-basic-offset)))
- (setq initial-msg
- (format "Initial value of sh-basic-offset: %s"
- sh-basic-offset)))
-
- (while (< (point) (point-max))
- (setq linenum (1+ linenum))
- ;; (if (zerop (% linenum 10))
- (message "line %d" linenum)
- ;; )
- (unless (looking-at "\\s-*$") ;; ignore empty lines!
- (let* ((sh-indent-comment t) ;; info must return default indent
- (info (sh-get-indent-info))
- (var (sh-get-indent-var-for-line info))
- sval ival diff new-val
- (curr-indent (current-indentation)))
- (cond
- ((null var)
- nil)
- ((stringp var)
- nil)
- ((numberp (setq sval (sh-var-value var 'no-error)))
- ;; the numberp excludes comments since sval will be t.
- (setq ival (sh-calculate-indent))
- (setq diff (- curr-indent ival))
- (setq new-val (+ sval diff))
- (sh-set-var-value var new-val 'no-symbol)
- (unless (looking-at "\\s-*#") ;; don't learn from comments
- (if (setq previous-set-info (assoc var learned-var-list))
- (progn
- ;; it was already there, is it same value ?
- (unless (eq (symbol-value var)
- (nth 1 previous-set-info))
- (sh-mark-line
- (format "Variable %s was set to %s"
- var (symbol-value var))
- (point) out-buffer t t)
- (sh-mark-line
- (format " but was previously set to %s"
- (nth 1 previous-set-info))
- (nth 2 previous-set-info) out-buffer t)
- (setq num-diffs (1+ num-diffs))
- ;; (delete previous-set-info learned-var-list)
- (setcdr previous-set-info
- (list (symbol-value var) (point)))
- )
- )
- (setq learned-var-list
- (append (list (list var (symbol-value var)
- (point)))
- learned-var-list)))
- (if (numberp new-val)
- (progn
- (sh-debug
- "This line's indent value: %d" new-val)
- (if (< new-val 0)
- (setq new-val (- new-val)))
- (if (< new-val max)
- (aset vec new-val (1+ (aref vec new-val))))))
- ))
- ((eq var 'sh-indent-comment)
- (unless (= curr-indent (sh-calculate-indent info))
- ;; this is not the default indentation
- (setq comments-always-default nil)
- (if comment-col ;; then we have see one before
- (or (eq comment-col curr-indent)
- (setq comment-col t)) ;; seen a different one
- (setq comment-col curr-indent))
- ))
- (t
- (sh-debug "Cannot learn this line!!!")
- ))
- (sh-debug
- "at %s learned-var-list is %s" (point) learned-var-list)
- ))
- (forward-line 1)
- ) ;; while
- (if sh-debug
- (progn
- (setq msg (format
- "comment-col = %s comments-always-default = %s"
- comment-col comments-always-default))
- ;; (message msg)
- (sh-mark-line msg nil out-buffer)))
- (cond
- ((eq comment-col 0)
- (setq msg "\nComments are all in 1st column.\n"))
- (comments-always-default
- (setq msg "\nComments follow default indentation.\n")
- (setq comment-col t))
- ((numberp comment-col)
- (setq msg (format "\nComments are in col %d." comment-col)))
- (t
- (setq msg "\nComments seem to be mixed, leaving them as is.\n")
- (setq comment-col nil)
- ))
- (sh-debug msg)
- (sh-mark-line msg nil out-buffer)
-
- (sh-mark-line initial-msg nil out-buffer t t)
-
- (setq suggested (sh-guess-basic-offset vec))
-
- (if (and suggested (not specified-basic-offset))
- (let ((new-value
- (cond
- ;; t => set it if we have a single value as a number
- ((and (eq sh-learn-basic-offset t) (numberp suggested))
- suggested)
- ;; other non-nil => set it if only one value was found
- (sh-learn-basic-offset
- (if (numberp suggested)
- suggested
- (if (= (length suggested) 1)
- (car suggested))))
- (t
- nil))))
- (if new-value
- (progn
- (setq learned-var-list
- (append (list (list 'sh-basic-offset
- (setq sh-basic-offset new-value)
- (point-max)))
- learned-var-list))
- ;; Not sure if we need to put this line in, since
- ;; it will appear in the "Learned variable settings".
- (sh-mark-line
- (format "Changed sh-basic-offset to: %d" sh-basic-offset)
- nil out-buffer))
- (sh-mark-line
- (if (listp suggested)
- (format "Possible value(s) for sh-basic-offset: %s"
- (mapconcat 'int-to-string suggested " "))
- (format "Suggested sh-basic-offset: %d" suggested))
- nil out-buffer))))
-
-
- (setq learned-var-list
- (append (list (list 'sh-indent-comment comment-col (point-max)))
- learned-var-list))
- (setq sh-indent-comment comment-col)
- (let ((name (buffer-name)))
- (sh-mark-line "\nLearned variable settings:" nil out-buffer)
- (if arg
- ;; Set learned variables to symbolic rather than numeric
- ;; values where possible.
- (dolist (learned-var (reverse learned-var-list))
- (let ((var (car learned-var))
- (val (nth 1 learned-var)))
- (when (and (not (eq var 'sh-basic-offset))
- (numberp val))
- (sh-set-var-value var val)))))
- (dolist (learned-var (reverse learned-var-list))
- (let ((var (car learned-var)))
- (sh-mark-line (format " %s %s" var (symbol-value var))
- (nth 2 learned-var) out-buffer)))
- (with-current-buffer out-buffer
- (goto-char (point-min))
- (insert
- (format "Indentation values for buffer %s.\n" name)
- (format "%d indentation variable%s different values%s\n\n"
- num-diffs
- (if (= num-diffs 1)
- " has" "s have")
- (if (zerop num-diffs)
- "." ":"))
- )))
- ;; Are abnormal hooks considered bad form?
- (run-hook-with-args 'sh-learned-buffer-hook learned-var-list)
- (and (called-interactively-p 'any)
- (or sh-popup-occur-buffer (> num-diffs 0))
- (pop-to-buffer out-buffer)))))
+ (if sh-use-smie
+ (smie-config-guess)
+ (save-excursion
+ (goto-char (point-min))
+ (let ((learned-var-list nil)
+ (out-buffer "*indent*")
+ (num-diffs 0)
+ previous-set-info
+ (max 17)
+ vec
+ msg
+ (comment-col nil) ;; number if all same, t if seen diff values
+ (comments-always-default t) ;; nil if we see one not default
+ initial-msg
+ (specified-basic-offset (and arg (numberp arg)
+ (> arg 0)))
+ (linenum 0)
+ suggested)
+ (setq vec (make-vector max 0))
+ (sh-mark-init out-buffer)
+
+ (if specified-basic-offset
+ (progn
+ (setq sh-basic-offset arg)
+ (setq initial-msg
+ (format "Using specified sh-basic-offset of %d"
+ sh-basic-offset)))
+ (setq initial-msg
+ (format "Initial value of sh-basic-offset: %s"
+ sh-basic-offset)))
+
+ (while (< (point) (point-max))
+ (setq linenum (1+ linenum))
+ ;; (if (zerop (% linenum 10))
+ (message "line %d" linenum)
+ ;; )
+ (unless (looking-at "\\s-*$") ;; ignore empty lines!
+ (let* ((sh-indent-comment t) ;; info must return default indent
+ (info (sh-get-indent-info))
+ (var (sh-get-indent-var-for-line info))
+ sval ival diff new-val
+ (curr-indent (current-indentation)))
+ (cond
+ ((null var)
+ nil)
+ ((stringp var)
+ nil)
+ ((numberp (setq sval (sh-var-value var 'no-error)))
+ ;; the numberp excludes comments since sval will be t.
+ (setq ival (sh-calculate-indent))
+ (setq diff (- curr-indent ival))
+ (setq new-val (+ sval diff))
+ (sh-set-var-value var new-val 'no-symbol)
+ (unless (looking-at "\\s-*#") ;; don't learn from comments
+ (if (setq previous-set-info (assoc var learned-var-list))
+ (progn
+ ;; it was already there, is it same value ?
+ (unless (eq (symbol-value var)
+ (nth 1 previous-set-info))
+ (sh-mark-line
+ (format "Variable %s was set to %s"
+ var (symbol-value var))
+ (point) out-buffer t t)
+ (sh-mark-line
+ (format " but was previously set to %s"
+ (nth 1 previous-set-info))
+ (nth 2 previous-set-info) out-buffer t)
+ (setq num-diffs (1+ num-diffs))
+ ;; (delete previous-set-info learned-var-list)
+ (setcdr previous-set-info
+ (list (symbol-value var) (point)))
+ )
+ )
+ (setq learned-var-list
+ (append (list (list var (symbol-value var)
+ (point)))
+ learned-var-list)))
+ (if (numberp new-val)
+ (progn
+ (sh-debug
+ "This line's indent value: %d" new-val)
+ (if (< new-val 0)
+ (setq new-val (- new-val)))
+ (if (< new-val max)
+ (aset vec new-val (1+ (aref vec new-val))))))
+ ))
+ ((eq var 'sh-indent-comment)
+ (unless (= curr-indent (sh-calculate-indent info))
+ ;; this is not the default indentation
+ (setq comments-always-default nil)
+ (if comment-col ;; then we have see one before
+ (or (eq comment-col curr-indent)
+ (setq comment-col t)) ;; seen a different one
+ (setq comment-col curr-indent))
+ ))
+ (t
+ (sh-debug "Cannot learn this line!!!")
+ ))
+ (sh-debug
+ "at %s learned-var-list is %s" (point) learned-var-list)
+ ))
+ (forward-line 1)
+ ) ;; while
+ (if sh-debug
+ (progn
+ (setq msg (format
+ "comment-col = %s comments-always-default = %s"
+ comment-col comments-always-default))
+ ;; (message msg)
+ (sh-mark-line msg nil out-buffer)))
+ (cond
+ ((eq comment-col 0)
+ (setq msg "\nComments are all in 1st column.\n"))
+ (comments-always-default
+ (setq msg "\nComments follow default indentation.\n")
+ (setq comment-col t))
+ ((numberp comment-col)
+ (setq msg (format "\nComments are in col %d." comment-col)))
+ (t
+ (setq msg "\nComments seem to be mixed, leaving them as is.\n")
+ (setq comment-col nil)
+ ))
+ (sh-debug msg)
+ (sh-mark-line msg nil out-buffer)
+
+ (sh-mark-line initial-msg nil out-buffer t t)
+
+ (setq suggested (sh-guess-basic-offset vec))
+
+ (if (and suggested (not specified-basic-offset))
+ (let ((new-value
+ (cond
+ ;; t => set it if we have a single value as a number
+ ((and (eq sh-learn-basic-offset t) (numberp suggested))
+ suggested)
+ ;; other non-nil => set it if only one value was found
+ (sh-learn-basic-offset
+ (if (numberp suggested)
+ suggested
+ (if (= (length suggested) 1)
+ (car suggested))))
+ (t
+ nil))))
+ (if new-value
+ (progn
+ (setq learned-var-list
+ (append (list (list 'sh-basic-offset
+ (setq sh-basic-offset new-value)
+ (point-max)))
+ learned-var-list))
+ ;; Not sure if we need to put this line in, since
+ ;; it will appear in the "Learned variable settings".
+ (sh-mark-line
+ (format "Changed sh-basic-offset to: %d" sh-basic-offset)
+ nil out-buffer))
+ (sh-mark-line
+ (if (listp suggested)
+ (format "Possible value(s) for sh-basic-offset: %s"
+ (mapconcat 'int-to-string suggested " "))
+ (format "Suggested sh-basic-offset: %d" suggested))
+ nil out-buffer))))
+
+
+ (setq learned-var-list
+ (append (list (list 'sh-indent-comment comment-col (point-max)))
+ learned-var-list))
+ (setq sh-indent-comment comment-col)
+ (let ((name (buffer-name)))
+ (sh-mark-line "\nLearned variable settings:" nil out-buffer)
+ (if arg
+ ;; Set learned variables to symbolic rather than numeric
+ ;; values where possible.
+ (dolist (learned-var (reverse learned-var-list))
+ (let ((var (car learned-var))
+ (val (nth 1 learned-var)))
+ (when (and (not (eq var 'sh-basic-offset))
+ (numberp val))
+ (sh-set-var-value var val)))))
+ (dolist (learned-var (reverse learned-var-list))
+ (let ((var (car learned-var)))
+ (sh-mark-line (format " %s %s" var (symbol-value var))
+ (nth 2 learned-var) out-buffer)))
+ (with-current-buffer out-buffer
+ (goto-char (point-min))
+ (let ((inhibit-read-only t))
+ (insert
+ (format "Indentation values for buffer %s.\n" name)
+ (format "%d indentation variable%s different values%s\n\n"
+ num-diffs
+ (if (= num-diffs 1)
+ " has" "s have")
+ (if (zerop num-diffs)
+ "." ":"))))))
+ ;; Are abnormal hooks considered bad form?
+ (run-hook-with-args 'sh-learned-buffer-hook learned-var-list)
+ (and (called-interactively-p 'any)
+ (or sh-popup-occur-buffer (> num-diffs 0))
+ (pop-to-buffer out-buffer))))))