You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
253 lines
7.1 KiB
253 lines
7.1 KiB
;; Kookie's emacs config
|
|
|
|
;; Enable automatic shell.nix loading
|
|
;; (require 'direnv)
|
|
;; (direnv-mode)
|
|
|
|
(require 'magit)
|
|
|
|
(require 'multiple-cursors)
|
|
|
|
(require 'org)
|
|
(add-to-list 'auto-mode-alist '("\\.org$" . org-mode))
|
|
|
|
(defun org-open-at-point-in-current-window ()
|
|
(interactive)
|
|
(let ((org-link-frame-setup (quote
|
|
((vm . vm-visit-folder)
|
|
(vm-imap . vm-visit-imap-folder)
|
|
(gnus . gnus)
|
|
(file . find-file)
|
|
(wl . wl)))
|
|
))
|
|
(org-open-at-point)))
|
|
|
|
|
|
(autoload 'notmuch "notmuch" "notmuch mail" t)
|
|
(setq notmuch-search-oldest-first nil)
|
|
(setq mml-secure-openpgp-encrypt-to-self t)
|
|
(setq mml-secure-smime-encrypt-to-self t)
|
|
|
|
(add-hook 'message-setup-hook 'mml-secure-message-sign-pgpmime)
|
|
(add-hook 'notmuch-hello-refresh-hook
|
|
(lambda ()
|
|
(if (and (eq (point) (point-min))
|
|
(search-forward "Saved searches:" nil t))
|
|
(progn
|
|
(forward-line)
|
|
(widget-forward 1))
|
|
(if (eq (widget-type (widget-at)) 'editable-field)
|
|
(beginning-of-line)))))
|
|
|
|
(define-transient-command notmuch-apply-email ()
|
|
"Apply patches received by email."
|
|
["Arguments"
|
|
("-s" "Sign off on patches" ("-s" "--signoff"))
|
|
("-r" "Set this reject thingy" ("-r" "--reject"))
|
|
("-o" "Skip cover letter automatically" ("-o" "--skip-coverletter"))]
|
|
["Method"
|
|
("p" "patchset" notmuch--apply-email)])
|
|
|
|
(defun notmuch--apply-email ()
|
|
"Apply a patch directly from a notmuch frame."
|
|
(interactive)
|
|
(let ((repository (read-directory-name "Select repository")))
|
|
(cd repository)
|
|
(notmuch-show-pipe-message t "git am -3 -")))
|
|
|
|
;; change the swap/autosave directory
|
|
(let ((backup-dir (concat user-emacs-directory "backups")))
|
|
(make-directory backup-dir t)
|
|
(setq backup-directory-alist (list (cons "." backup-dir)))
|
|
(setq message-auto-save-directory backup-dir))
|
|
|
|
;; Explicitly enable lsp-mode for certain languages
|
|
|
|
(add-hook 'c-mode-hook #'lsp)
|
|
(add-hook 'c++-mode-hook #'lsp)
|
|
|
|
;; OpenSCAD mode
|
|
(add-to-list 'auto-mode-alist '("\\.scad$" . scad-mode))
|
|
|
|
;; Capn Proto mode
|
|
(add-to-list 'auto-mode-alist '("\\.capnp$" . protobuf-mode))
|
|
|
|
(require 'color-theme-sanityinc-tomorrow)
|
|
(load-theme 'sanityinc-tomorrow-eighties)
|
|
|
|
;; Distraction free mode and minimap
|
|
(require 'sublimity)
|
|
(require 'sublimity-attractive)
|
|
|
|
;; This is require for lsp-mode
|
|
(require 'yasnippet)
|
|
|
|
(defun lorri (&optional buffer-name)
|
|
(interactive)
|
|
(setq buffer-name (or buffer-name (generate-new-buffer "*lorri*")))
|
|
(start-process "lorri" buffer-name "lorri" "watch")
|
|
(display-buffer buffer-name))
|
|
|
|
;; Better completion handling with lsp-mode
|
|
(require 'company-lsp)
|
|
(push 'company-lsp company-backends)
|
|
(setq lsp-ui-doc-position 'top)
|
|
(setq lsp-ui-doc-max-width 45)
|
|
(setq lsp-ui-doc-max-height 10)
|
|
|
|
(add-hook 'after-init-hook 'global-company-mode)
|
|
|
|
;; Turns out I'm a huge dork
|
|
(setq emacs-anchor default-directory)
|
|
(defun mitosis () (interactive) (make-frame))
|
|
|
|
;; Setup RSS feeds
|
|
(setq elfeed-feeds
|
|
'(("https://alyssa.is/feed.xml" girlfriend blog)
|
|
("https://spacekookie.de/rss.xml" self blog)
|
|
("https://xkcd.com/rss.xml" webcomic)
|
|
("https://deterministic.space/feed.xml" rust blog)
|
|
))
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;;;;;;;;; ;;;;;;;;;;;;
|
|
;;;;;;;;; KOOKIE-MODE DEFINITIONS BELOW ;;;;;;;;;;;;
|
|
;;;;;;;;; ;;;;;;;;;;;;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
(defun new-empty-buffer ()
|
|
"Opens a new empty buffer."
|
|
(interactive)
|
|
(let ((buf (generate-new-buffer "untitled")))
|
|
(switch-to-buffer buf)
|
|
(funcall (and initial-major-mode))
|
|
(setq buffer-offer-save t)))
|
|
|
|
(defun user-buffer-q ()
|
|
"Check if a buffer is a user buffer"
|
|
(interactive)
|
|
(if (string-equal "*" (substring (buffer-name) 0 1))
|
|
nil
|
|
(if (string-equal major-mode "dired-mode")
|
|
nil
|
|
t
|
|
)))
|
|
|
|
(defun next-user-buffer ()
|
|
"Switch to the next user buffer."
|
|
(interactive)
|
|
(next-buffer)
|
|
(let ((i 0))
|
|
(while (< i 20)
|
|
(if (not (user-buffer-q))
|
|
(progn (next-buffer)
|
|
(setq i (1+ i)))
|
|
(progn (setq i 100))))))
|
|
|
|
(defun previous-user-buffer ()
|
|
"Switch to the previous user buffer."
|
|
(interactive)
|
|
(previous-buffer)
|
|
(let ((i 0))
|
|
(while (< i 20)
|
|
(if (not (user-buffer-q))
|
|
(progn (previous-buffer)
|
|
(setq i (1+ i)))
|
|
(progn (setq i 100))))))
|
|
|
|
|
|
(defun move--section (offset)
|
|
"Move a line or reg up or down by on offset."
|
|
|
|
;; We'll have to track 4 text points in this function
|
|
;; Future me: the * is important....
|
|
(let* (txt-start
|
|
txt-end
|
|
(reg-start (point))
|
|
(reg-end reg-start)
|
|
|
|
;; De we delete a trailing \n
|
|
del-nl-trail)
|
|
|
|
;; Find the text borders
|
|
(when (region-active-p)
|
|
(if (> (point) (mark))
|
|
(setq reg-start (mark))
|
|
(exchange-point-and-mark)
|
|
(setq reg-end (point))))
|
|
(end-of-line)
|
|
|
|
;; If point > point-max there is no trailing \n
|
|
(if (< (point) (point-max))
|
|
(forward-char 1)
|
|
(setq del-nl-trail t)
|
|
(insert-char ?\n))
|
|
(setq txt-end (point)
|
|
reg-end (- reg-end txt-end))
|
|
|
|
;; text/region start points
|
|
(goto-char reg-start)
|
|
(beginning-of-line)
|
|
(setq txt-start (point)
|
|
reg-start (- reg-start txt-end))
|
|
|
|
;; I'm tired and numbers are hard
|
|
(message "ts: %d, te: %d, rs: %d, re: %d"
|
|
txt-start
|
|
txt-end
|
|
reg-start
|
|
reg-end)
|
|
|
|
;; Fake the txt move
|
|
(let ((text (delete-and-extract-region txt-start txt-end)))
|
|
(forward-line offset)
|
|
(when (not (= (current-column) 0))
|
|
(insert-char ?\n)
|
|
(setq del-nl-trail t))
|
|
(insert text))
|
|
|
|
;; Restore point position
|
|
(forward-char reg-start)
|
|
|
|
;; Clean that annoying \n at the end
|
|
(when del-nl-trail
|
|
(save-excursion
|
|
(goto-char (point-max))
|
|
(delete-char -1)))
|
|
|
|
;; If we operated on a region we need to fix the selection
|
|
(when (region-active-p)
|
|
(setq deactivate-mark nil)
|
|
(set-mark (+ (point) (- (- reg-start reg-end)))))))
|
|
|
|
(defun move-section-up (offset)
|
|
"Move a line or reg upwards"
|
|
(interactive "p")
|
|
(if (eq offset nil)
|
|
setq offset 1)
|
|
(move--section (- offset)))
|
|
|
|
(defun move-section-down (offset)
|
|
"Move a line or region dawnwards"
|
|
(interactive "p")
|
|
(if (eq offset nil)
|
|
setq offset 1)
|
|
(move--section offset))
|
|
|
|
(global-set-key (kbd "C-M-<up>") 'move-section-up)
|
|
(global-set-key (kbd "C-M-<down>") 'move-section-down)
|
|
|
|
;;; Multiple cursors bindings
|
|
(global-set-key (kbd "C-H-c C-H-c") 'mc/edit-lines)
|
|
(global-set-key (kbd "C->") 'mc/mark-next-like-this)
|
|
(global-set-key (kbd "C-<") 'mc/mark-previous-like-this)
|
|
(global-set-key (kbd "C-c C-<") 'mc/mark-all-like-this)
|
|
|
|
|
|
|
|
;;; Org mode bindings replicated here to make it easier for me
|
|
(define-key org-mode-map "\C-c\C-o" 'org-open-at-point-in-current-window)
|
|
(define-key org-mode-map "\C-S-<up>" nil)
|
|
(define-key org-mode-map "\C-S-<down>" nil)
|
|
|