Skip to content

Instantly share code, notes, and snippets.

@lionicsheriff
Last active December 15, 2015 10:08
Show Gist options
  • Save lionicsheriff/5243104 to your computer and use it in GitHub Desktop.
Save lionicsheriff/5243104 to your computer and use it in GitHub Desktop.
(define-minor-mode infer-indentation-mode
"infer-indentation"
""
:keymap nil
;; store the original settings so we can switch back
(when (not (boundp 'infer-indentation-original-style))
(set (make-local-variable 'infer-indentation-original-style) indent-tabs-mode))
(when (not (boundp 'infer-indentation-original-width))
(set (make-local-variable 'infer-indentation-original-width) tab-width))
(defun detect-line-indentation-style (line)
"Detect if a line is indented with tabs or spaces"
(message (concat "testing:'" line "'"))
(when (> (length line) 0)
(let ((first-char (substring line 0 1)))
(cond
((string-equal first-char " ") (cons :spaces (get-indentation-width line)))
((string-equal first-char "\t") (cons :tabs 1))))))
(defun get-indentation-width (line &optional count)
"Detect how many spaces are used for indenting"
(let ((count (if count count 0)))
(cond
((= (length line) 0) count)
((string-equal (substring line 0 1) " ")
(get-indentation-width (substring line 1) (+ 1 count)))
(t count))))
(defun detect-current-line-indentation-style ()
"Detect if the current line is indented with tabs or spaces"
(detect-line-indentation-style
(buffer-substring-no-properties (point-at-bol) (point-at-eol))))
(defun detect-current-buffer-indentation-style ()
"Detect it the current buffer is indenting with tabs or spaces"
(let ((indentation-style (detect-current-line-indentation-style)))
(if indentation-style
indentation-style
;; couldn't use current line for indentation, try the next line
(progn
(forward-line 1)
(detect-current-buffer-indentation-style)))))
(defun infer-indentation-style ()
""
(save-excursion
(progn
(goto-char (point-min))
(detect-current-buffer-indentation-style))))
(defun infer-indentation ()
"Calculate how the current buffer is being indented and set the indentations settings to that"
(let ((style (infer-indentation-style)))
(cond
((equal (car style) :spaces)
(progn
(message (concat "Indenting with " (number-to-string (cdr style)) " spaces"))
(setq indent-tabs-mode nil)
(setq tab-width (cdr style))))
((equal (car style) :tabs)
(progn
(message "Indenting with tabs")
(setq indent-tabs-mode t))))))
(defun use-original-indentation ()
(message "Using original indentation style")
(setq indent-tabs-mode infer-indentation-original-style)
(setq tab-width infer-indentation-original-width)
)
;; toggle infer-indentation
(if infer-indentation-mode
(use-original-indentation)
(infer-indentation))
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment