ambevar-dotfiles/.emacs.d/functions.el

207 lines
7.2 KiB
EmacsLisp

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; FUNCTIONS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun unfill-paragraph ()
(interactive)
(let ((fill-column (point-max)))
(fill-paragraph nil)))
(defun unfill-region ()
(interactive)
(let ((fill-column (point-max)))
(fill-region (region-beginning) (region-end) nil)))
(defun sort-lines-unique ()
"Remove duplicate lines using shell command `sort -u'"
(interactive)
(shell-command-on-region (point) (mark) "sort -u" (buffer-name) t))
(defun dtwi () "Delete trailing whitespaces interactively."
(interactive)
(query-replace-regexp " +
" "
"))
(defun toggle-window-split ()
"Vertical split shows more of each line, horizontal split shows
more lines. This code toggles between them. It only works for
frames with exactly two windows."
(interactive)
(if (= (count-windows) 2)
(let* ((this-win-buffer (window-buffer))
(next-win-buffer (window-buffer (next-window)))
(this-win-edges (window-edges (selected-window)))
(next-win-edges (window-edges (next-window)))
(this-win-2nd (not (and (<= (car this-win-edges)
(car next-win-edges))
(<= (cadr this-win-edges)
(cadr next-win-edges)))))
(splitter
(if (= (car this-win-edges)
(car (window-edges (next-window))))
'split-window-horizontally
'split-window-vertically)))
(delete-other-windows)
(let ((first-win (selected-window)))
(funcall splitter)
(if this-win-2nd (other-window 1))
(set-window-buffer (selected-window) this-win-buffer)
(set-window-buffer (next-window) next-win-buffer)
(select-window first-win)
(if this-win-2nd (other-window 1))))))
(define-key my-keys-minor-mode-map [(control c) (|)] 'toggle-window-split)
(defun duplicate (arg)
"Duplicates the current line or region ARG times.
If there's no region, the current line will be duplicated. However, if
there's a region, all lines that region covers will be duplicated."
(interactive "p")
(let (beg
end
(origin (point))
(auto-fill-p (symbol-value 'auto-fill-function)))
(if (and mark-active (> (point) (mark)))
(exchange-point-and-mark))
(setq beg (line-beginning-position))
(if mark-active
(exchange-point-and-mark))
(setq end (line-end-position))
(let ((region (buffer-substring-no-properties beg end)))
(auto-fill-mode -1)
(dotimes (i arg)
(goto-char end)
(newline)
(insert region)
(setq end (point)))
(if auto-fill-p (auto-fill-mode))
(goto-char (+ origin (* (length region) arg) arg)))))
(define-key my-keys-minor-mode-map (kbd "C-c C-d") 'duplicate)
(defun comment-or-uncomment-current-line-or-region ()
"Comments or uncomments current current line or whole lines in region."
(interactive)
(save-excursion
(let (min max)
(if (region-active-p)
(setq min (region-beginning) max (region-end))
(setq min (point) max (point)))
(comment-or-uncomment-region
(progn (goto-char min) (line-beginning-position))
(progn (goto-char max) (line-end-position))))))
(define-key my-keys-minor-mode-map "\M-;" 'comment-or-uncomment-current-line-or-region)
(defun xor (b1 b2)
"Exclusive or of its two arguments."
(or (and b1 b2)
(and (not b1) (not b2))))
(defun move-border-left-or-right (arg dir)
"General function covering move-border-left and
move-border-right. If DIR is t, then move left, otherwise move
right."
(interactive)
(if (null arg) (setq arg 5))
(let ((left-edge (nth 0 (window-edges))))
(if (xor (= left-edge 0) dir)
(shrink-window arg t)
(enlarge-window arg t))))
(defun move-border-left (arg)
"If this is a window with its right edge being the edge of the
screen, enlarge the window horizontally. If this is a window with
its left edge being the edge of the screen, shrink the window
horizontally. Otherwise, default to enlarging horizontally.
Enlarge/Shrink by ARG columns, or 5 if arg is nil."
(interactive "P")
(if (= (count-windows) 2)
(move-border-left-or-right arg t)))
(defun move-border-right (arg)
"If this is a window with its right edge being the edge of the
screen, shrink the window horizontally. If this is a window with
its left edge being the edge of the screen, enlarge the window
horizontally. Otherwise, default to shrinking horizontally.
Enlarge/Shrink by ARG columns, or 5 if arg is nil."
(interactive "P")
(if (= (count-windows) 2)
(move-border-left-or-right arg nil)))
(define-key my-keys-minor-mode-map (kbd "M-(") 'move-border-left)
(define-key my-keys-minor-mode-map (kbd "M-)") 'move-border-right)
(defun eval-and-replace ()
"Replace the last sexp with its value."
(interactive)
(backward-kill-sexp)
(condition-case nil
(prin1 (eval (read (current-kill 0)))
(current-buffer))
(error (message "Invalid expression")
(insert (current-kill 0)))))
(defun swap-windows ()
"If you have 2 windows, it swaps them."
(interactive)
(cond ((/= (count-windows) 2)
(message "You need exactly 2 windows to do this."))
(t
(let* ((w1 (first (window-list)))
(w2 (second (window-list)))
(b1 (window-buffer w1))
(b2 (window-buffer w2))
(s1 (window-start w1))
(s2 (window-start w2)))
(set-window-buffer w1 b2)
(set-window-buffer w2 b1)
(set-window-start w1 s2)
(set-window-start w2 s1))))
(other-window 1))
(define-key my-keys-minor-mode-map (kbd "C-c s") 'swap-windows)
(defun rename-buffer-and-file ()
"Renames current buffer and file it is visiting."
(interactive)
(let ((name (buffer-name))
(filename (buffer-file-name)))
(if (not (and filename (file-exists-p filename)))
(error "Buffer '%s' is not visiting a file!" name)
(let ((new-name (read-file-name "New name: " filename)))
(cond ((get-buffer new-name)
(error "A buffer named '%s' already exists!" new-name))
(t
(rename-file filename new-name 1)
(rename-buffer new-name)
(set-visited-file-name new-name)
(set-buffer-modified-p nil)
(message "File '%s' successfully renamed to '%s'" name (file-name-nondirectory new-name))))))))
(define-key my-keys-minor-mode-map (kbd "C-x C-w") 'rename-buffer-and-file)
(defun kill-all-buffers ()
"Kill all buffers, leaving *scratch* only."
(interactive)
(mapc
(lambda (x)
(kill-buffer x))
(buffer-list))
(delete-other-windows))
(defun sanitize ()
"Untabifies, indents and deletes trailing whitespace from buffer or region."
(interactive)
(save-excursion
(unless (region-active-p)
(mark-whole-buffer))
(untabify (region-beginning) (region-end))
(indent-region (region-beginning) (region-end))
(save-restriction
(narrow-to-region (region-beginning) (region-end))
(delete-trailing-whitespace))))