doomemacs/core/defuns/defuns-whitespace.el

199 lines
7.1 KiB
EmacsLisp
Raw Normal View History

2015-06-15 09:05:52 +02:00
;;; defuns-whitespace.el
;;;###autoload
2016-05-20 22:37:30 -04:00
(defun doom--point-at-bol-non-blank()
2015-06-15 09:05:52 +02:00
(save-excursion (evil-first-non-blank) (point)))
;;;###autoload
2016-05-20 22:37:30 -04:00
(defun doom/surrounded-p ()
2015-06-15 09:05:52 +02:00
(and (looking-back "[[{(]\\(\s+\\|\n\\)?\\(\s\\|\t\\)*")
(let* ((whitespace (match-string 1))
(match-str (concat whitespace (match-string 2) "[])}]")))
(looking-at-p match-str))))
;;;###autoload
2016-05-20 22:37:30 -04:00
(defun doom/backward-kill-to-bol-and-indent ()
2015-06-15 09:05:52 +02:00
"Kill line to the first non-blank character. If invoked again
afterwards, kill line to column 1."
(interactive)
(let ((empty-line (sp-point-in-blank-line)))
(evil-delete (point-at-bol) (point))
(if (not empty-line)
(indent-according-to-mode))))
;;;###autoload
2016-05-20 22:37:30 -04:00
(defun doom/move-to-bol ()
2015-06-15 09:05:52 +02:00
"Moves cursor to the first non-blank character on the line. If
already there, move it to the true bol."
(interactive)
(evil-save-goal-column
2016-05-20 22:37:30 -04:00
(let ((point-at-bol (doom--point-at-bol-non-blank))
2015-06-15 09:05:52 +02:00
(point (point)))
(if (= point-at-bol point)
(evil-move-beginning-of-line)
(unless (= (point-at-bol) point)
(evil-first-non-blank))))))
;;;###autoload
2016-05-20 22:37:30 -04:00
(defun doom/move-to-eol ()
2015-06-15 09:05:52 +02:00
(interactive)
(evil-save-goal-column
(let ((old-point (point)))
(when (comment-search-forward (point-at-eol) t)
(goto-char (match-beginning 0))
2016-05-20 22:37:30 -04:00
(skip-syntax-backward " ^<*" (doom--point-at-bol-non-blank))
2015-06-15 09:05:52 +02:00
(if (eq old-point (point)) ;
(evil-move-end-of-line))))))
;; Mimic expandtab in vim
;;;###autoload
;;;###autoload
2016-05-20 22:37:30 -04:00
(defun doom/backward-delete-whitespace-to-column ()
"Delete back to the previous column of whitespace, or as much whitespace as
possible, or just one char if that's not possible."
2015-06-15 09:05:52 +02:00
(interactive)
(let* ((context (sp--get-pair-list-context 'navigate))
(open-pair-re (sp--get-opening-regexp context))
(close-pair-re (sp--get-closing-regexp context))
open-len close-len)
(cond ;; When in strings (sp acts weird with quotes; this is the fix)
;; Also, skip closing delimiters
((and (and (sp--looking-back open-pair-re)
(setq open-len (- (match-beginning 0) (match-end 0))))
(and (looking-at close-pair-re)
(setq close-len (- (match-beginning 0) (match-end 0))))
(string= (plist-get (sp-get-thing t) :op)
(plist-get (sp-get-thing) :cl)))
(delete-backward-char open-len)
(delete-char close-len))
;; Delete up to the nearest tab column IF only whitespace between
;; point and bol.
((save-match-data (looking-back "^[\\t ]*" (line-beginning-position)))
(let ((movement (% (current-column) tab-width))
(p (point)))
(when (= movement 0)
(setq movement tab-width))
(save-match-data
(if (string-match "\\w*\\(\\s-+\\)$"
(buffer-substring-no-properties (- p movement) p))
(delete-backward-char (- (match-end 1) (match-beginning 1)))
(call-interactively 'delete-backward-char)))))
;; Otherwise do a regular delete
(t (call-interactively 'delete-backward-char)))))
2015-06-15 09:05:52 +02:00
;;;###autoload
2016-05-20 22:37:30 -04:00
(defun doom/dumb-indent (&optional smart)
2015-06-15 09:05:52 +02:00
"Inserts a tab character (or spaces x tab-width). Checks if the
auto-complete window is open."
(interactive)
(if indent-tabs-mode
(insert "\t")
(let* ((movement (% (current-column) tab-width))
2015-06-15 09:05:52 +02:00
(spaces (if (zerop movement) tab-width (- tab-width movement))))
(insert (s-repeat spaces " ")))))
;;;###autoload
2016-05-20 22:37:30 -04:00
(defun doom/smart-indent ()
(interactive)
(save-excursion
(back-to-indentation)
2016-05-20 22:37:30 -04:00
(doom/dumb-indent)))
;;;###autoload
2016-05-20 22:37:30 -04:00
(defun doom/dumb-dedent ()
(interactive)
(if indent-tabs-mode
(call-interactively 'backward-delete-char)
(save-excursion
(unless (looking-back "^[\s\t]*")
(evil-first-non-blank))
(let* ((movement (% (current-column) tab-width))
(spaces (if (zerop movement) tab-width (- tab-width movement))))
(delete-char (- spaces))))))
2015-06-15 09:05:52 +02:00
;;;###autoload
2016-05-20 22:37:30 -04:00
(defun doom/inflate-space-maybe ()
2015-06-15 09:05:52 +02:00
"Checks if point is surrounded by {} [] () delimiters and adds a
space on either side of the point if so."
(interactive)
2016-05-20 22:37:30 -04:00
(if (doom/surrounded-p)
2015-06-15 09:05:52 +02:00
(progn (call-interactively 'self-insert-command)
(save-excursion (call-interactively 'self-insert-command)))
(call-interactively 'self-insert-command)))
;;;###autoload
2016-05-20 22:37:30 -04:00
(defun doom/deflate-space-maybe ()
2015-06-15 09:05:52 +02:00
"Checks if point is surrounded by {} [] () delimiters, and deletes
spaces on either side of the point if so. Resorts to
2016-05-20 22:37:30 -04:00
`doom/backward-delete-whitespace-to-column' otherwise."
2015-06-15 09:05:52 +02:00
(interactive)
(save-match-data
2016-05-20 22:37:30 -04:00
(if (doom/surrounded-p)
2015-06-15 09:05:52 +02:00
(let ((whitespace-match (match-string 1)))
(cond ((not whitespace-match)
(call-interactively 'delete-backward-char))
2015-06-15 09:05:52 +02:00
((string-match "\n" whitespace-match)
(evil-delete (point-at-bol) (point))
(call-interactively 'delete-backward-char)
(save-excursion (call-interactively 'delete-char)))
(t (just-one-space 0))))
2016-05-20 22:37:30 -04:00
(doom/backward-delete-whitespace-to-column))))
2015-06-15 09:05:52 +02:00
;;;###autoload
2016-05-20 22:37:30 -04:00
(defun doom/newline-and-indent ()
2015-06-15 09:05:52 +02:00
(interactive)
(cond ((sp-point-in-string)
(newline))
((sp-point-in-comment)
(cond ((eq major-mode 'js2-mode)
(js2-line-break))
((-contains? '(java-mode php-mode) major-mode)
(c-indent-new-comment-line))
((-contains? '(c-mode c++-mode objc-mode css-mode scss-mode js2-mode) major-mode)
2015-06-15 09:05:52 +02:00
(newline-and-indent)
(insert "* ")
(indent-according-to-mode))
(t
;; Fix an off-by-one cursor-positioning issue
;; with `indent-new-comment-line'
(let ((col (save-excursion (comment-beginning) (current-column))))
(indent-new-comment-line)
(unless (= col (current-column))
(insert " "))))))
2015-07-31 00:01:55 +02:00
(t
(newline nil t)
(indent-according-to-mode))))
2015-06-15 09:05:52 +02:00
2016-05-20 22:37:30 -04:00
;;;###autoload (autoload 'doom:whitespace-retab "defuns-whitespace" nil t)
(evil-define-operator doom:whitespace-retab (beg end)
2015-06-15 09:05:52 +02:00
"Akin to vim's retab, this changes all tabs-to-spaces or spaces-to-tabs,
depending on `indent-tab-mode'. Untested."
:motion nil
:move-point nil
:type line
(interactive "<r>")
(unless (and beg end)
(setq beg (point-min))
(setq end (point-max)))
(if indent-tabs-mode
(tabify beg end)
(untabify beg end)))
2016-05-20 22:37:30 -04:00
;;;###autoload (autoload 'doom:whitespace-align "defuns-whitespace" nil t)
(evil-define-command doom:whitespace-align (beg end &optional regexp bang)
2015-06-15 09:05:52 +02:00
:repeat nil
(interactive "<r><a><!>")
(when regexp
(align-regexp beg end
(concat "\\(\\s-*\\)" (rxt-pcre-to-elisp regexp)) 1 1)))
2016-05-24 22:15:44 -04:00
;;;###autoload
(defun doom/static-reindent ()
"Reindent without moving cursor."
(interactive)
(save-excursion (call-interactively 'evil-indent)))
2015-06-15 09:05:52 +02:00
(provide 'defuns-whitespace)
;;; defuns-whitespace.el ends here