339 lines
10 KiB
EmacsLisp
339 lines
10 KiB
EmacsLisp
;; -*- lexical-binding: t -*-
|
|
|
|
;;; Compilation
|
|
(setq compile-command "make ")
|
|
;; C-m functions as \r, so pressing C-x C-m C-m will call compile and skip the prompt.
|
|
(global-set-key (kbd "C-x C-m") 'compile)
|
|
|
|
;; Nicer movement in compilation-mode.
|
|
(add-hook 'compilation-mode-hook
|
|
(lambda () (local-set-key (kbd "n") 'compilation-next-error)))
|
|
(add-hook 'compilation-mode-hook
|
|
(lambda () (local-set-key (kbd "p") 'compilation-previous-error)))
|
|
|
|
;; Function for selecting the current line.
|
|
(defun fez/mark-line ()
|
|
"Selects the current line with the mark."
|
|
(interactive)
|
|
(move-beginning-of-line nil)
|
|
(set-mark (point))
|
|
(next-line))
|
|
|
|
(defun fez/toggle-indent ()
|
|
"Toggle between indenting with tabs or spaces."
|
|
(interactive)
|
|
(setq-default indent-tabs-mode (not indent-tabs-mode)))
|
|
|
|
(defun fez/current-line-empty-p ()
|
|
"Checks if the current line is empty or not."
|
|
(save-excursion
|
|
(beginning-of-line)
|
|
(looking-at-p "[[:space:]]*$")))
|
|
|
|
(defun fez/current-line-comment-p ()
|
|
"Checks if the current line is a commented out one or not."
|
|
(save-excursion
|
|
(beginning-of-line)
|
|
(let ((a (point)))
|
|
(end-of-line)
|
|
(let ((b (point)))
|
|
(comment-only-p a b)))))
|
|
|
|
(defun fez/flash-region (&optional timeout)
|
|
"Temporarily highlight region from START to END. Taken from SLIME source code and modified."
|
|
(interactive)
|
|
(transient-mark-mode)
|
|
(save-excursion
|
|
(mark-defun)
|
|
;; Don't mark the line or the comments above the s-expression.
|
|
(while (or (fez/current-line-empty-p)
|
|
(fez/current-line-comment-p))
|
|
;; Can probably be optimized...
|
|
(forward-char))
|
|
(let* ((start (region-beginning))
|
|
(end (region-end))
|
|
(overlay (make-overlay start end)))
|
|
(deactivate-mark)
|
|
(overlay-put overlay 'face 'secondary-selection)
|
|
(run-with-timer (or timeout 0.2) nil 'delete-overlay overlay)))
|
|
(transient-mark-mode))
|
|
|
|
(defun fez/insert-keybind ()
|
|
"Prompts the user for a key combination like C-h k does, then inserts that key combination."
|
|
(interactive)
|
|
(insert (concat "(kbd \""
|
|
(key-description (read-key-sequence-vector "Key sequence: "))
|
|
"\")")))
|
|
|
|
(defun fez/time-stamp ()
|
|
"Insert the current date."
|
|
(interactive)
|
|
(shell-command "LANG=nb_NO.UTF-8 date +%Y-%m-%d" t))
|
|
|
|
(defun fez/kill-all-buffers ()
|
|
"Kill all buffers other than the currently active one."
|
|
(interactive)
|
|
(mapc #'kill-buffer (delete (current-buffer) (buffer-list))))
|
|
|
|
(defun fez/view-kill-ring ()
|
|
"Display the kill ring in a buffer."
|
|
(interactive)
|
|
(get-buffer-create "*kill-buffer*")
|
|
(switch-to-buffer-other-window "*kill-buffer*")
|
|
(erase-buffer)
|
|
(dolist (l (reverse kill-ring))
|
|
(insert l)))
|
|
|
|
(defun fez/lookup-key ()
|
|
"Search for KEY in all known keymaps (outputs to *Messages*)"
|
|
(interactive)
|
|
(let ((key (read-key-sequence-vector "Key sequence: ")))
|
|
(mapatoms (lambda (ob) (when (and (boundp ob) (keymapp (symbol-value ob)))
|
|
(when (functionp (lookup-key (symbol-value ob) key))
|
|
(message (symbol-name ob)))))
|
|
obarray)))
|
|
|
|
(defun fez/ttm-upload ()
|
|
"Upload file in selected buffer to ttm.sh and output the link in the echo area (and in *Messages*)"
|
|
(interactive)
|
|
(let ((link (shell-command-to-string (concat "curl -Ffile=@"
|
|
(buffer-file-name)
|
|
" https://ttm.sh -s"))))
|
|
(message "%s" link)
|
|
(kill-new link)))
|
|
|
|
(defun fez/last-occurrence-of-char (c)
|
|
"Go to the previous occurrence of C in the current buffer."
|
|
(interactive)
|
|
(when (equal (following-char) c)
|
|
(backward-char))
|
|
(while (not (equal (following-char)
|
|
c))
|
|
(backward-char)))
|
|
|
|
(defun fez/last-open-paren ()
|
|
(interactive)
|
|
(fez/last-occurrence-of-char ?\())
|
|
|
|
(defun fez/send-vterm-command (cmd)
|
|
"Executes CMD in a vterm buffer."
|
|
(kill-new cmd)
|
|
(vterm-yank)
|
|
(vterm-send-return))
|
|
|
|
(defun fez/cl ()
|
|
"Prepares the environment for Common Lisp development."
|
|
(interactive)
|
|
(let ((original-buffer (current-buffer)))
|
|
(vterm)
|
|
(let ((vterm-buffer (current-buffer)))
|
|
(fez/send-vterm-command "slystart")
|
|
(switch-to-buffer original-buffer)
|
|
;; This is probably useless for anyone that doesn't use frames-only-mode
|
|
(make-frame-command)
|
|
(switch-to-buffer vterm-buffer)))
|
|
(sleep-for 1)
|
|
(sly-connect "localhost" 4005))
|
|
|
|
(defmacro fez/save-buffer-excursion (&rest body)
|
|
(declare (indent defun))
|
|
(let ((original-buffer (gensym)))
|
|
`(let ((,original-buffer (current-buffer)))
|
|
,@body
|
|
(switch-to-buffer ,original-buffer))))
|
|
|
|
(defun fez/goto-first-occurrence (str)
|
|
(goto-char (point-min))
|
|
(search-forward-regexp str)
|
|
(beginning-of-thing 'symbol))
|
|
|
|
;; https://emacs.stackexchange.com/a/33709
|
|
(defmacro with-keybinding (map key command &rest body)
|
|
`(let* ((map ,map)
|
|
(key ,key)
|
|
(newcommand ,command)
|
|
(prevbinding (lookup-key map key)))
|
|
(unwind-protect
|
|
(progn
|
|
(define-key map key newcommand)
|
|
,@body)
|
|
(define-key map key prevbinding))))
|
|
|
|
(defun fez/org-roam-new-note ()
|
|
"Creates a new org-roam note, and adds an entry to that note in my index.org file."
|
|
(interactive)
|
|
(let ((category (read-string "Category: ")))
|
|
(find-file (concat org-roam-directory "/index.org"))
|
|
(fez/goto-first-occurrence (concat "^\* " category))
|
|
(end-of-line)
|
|
(newline)
|
|
(org-cycle)
|
|
(with-keybinding selectrum-minibuffer-map (kbd "SPC") (lambda () (interactive (insert-char ?-)))
|
|
(org-roam-insert))))
|
|
|
|
(setq x-mouse-on t)
|
|
(setq x-mouse-value "13")
|
|
(defun fez/toggle-x-mouse ()
|
|
"Toggle the X mouse."
|
|
(interactive)
|
|
(setq x-mouse-on (not x-mouse-on))
|
|
(shell-command (concat "xinput "
|
|
(if x-mouse-on "--enable " "--disable ")
|
|
x-mouse-value))
|
|
(message (concat "Mouse "
|
|
(if x-mouse-on "enabled." "disabled."))))
|
|
|
|
(defun fez/screenshot ()
|
|
"Prompts the user for a filename and saves a screenshot at that path."
|
|
(interactive)
|
|
(let ((path (read-string "Filename: ")))
|
|
(shell-command (concat "import -window root "
|
|
path))))
|
|
|
|
(setq current-layout "nous")
|
|
(defun fez/swap-keyboard ()
|
|
"Swap between my selected keyboard layouts."
|
|
(interactive)
|
|
(cond ((string= current-layout "nous") (setq current-layout "ru"))
|
|
(t (setq current-layout "nous")))
|
|
(shell-command (concat "setxkbmap " current-layout)))
|
|
|
|
(defun fez/change-volume (delta)
|
|
"Change volume. Delta must be a valid amixer string, like '5%+' or '5%-'"
|
|
(interactive)
|
|
(shell-command
|
|
(concat
|
|
"amixer sset Master " delta
|
|
" | grep \"Front Left:\" | head -n 1 | sed 's/\\].*//g' | sed 's/.*\\[//g'")))
|
|
|
|
(defun fez/man-at-point ()
|
|
(interactive)
|
|
(let ((word (current-word)))
|
|
(if word
|
|
(man word)
|
|
"Not a word.")))
|
|
|
|
(defun fez/insert-line ()
|
|
(interactive)
|
|
(move-beginning-of-line nil)
|
|
(open-line 1))
|
|
|
|
;; TODO: Put this in C-mode or something
|
|
(defun fez/include-guard ()
|
|
(interactive)
|
|
(let ((guard (concat (upcase (file-name-base (buffer-file-name)))
|
|
"_H")))
|
|
(goto-char (point-min))
|
|
(insert (concat "#ifndef "
|
|
guard
|
|
"\n#define "
|
|
guard
|
|
"\n"))
|
|
(goto-char (point-max))
|
|
(insert (concat "\n\n\n#endif /* "
|
|
guard
|
|
" */\n")))
|
|
(forward-line -3))
|
|
|
|
(defun fez/tex-word-count ()
|
|
(interactive)
|
|
(message
|
|
(substring
|
|
(shell-command-to-string
|
|
(concat "texcount " (buffer-file-name) " | grep \"^Words in text:\""))
|
|
0 -1)))
|
|
|
|
(defun fez/log ()
|
|
"Add entry to daily log."
|
|
(interactive)
|
|
(let ((temp-buffer (generate-new-buffer (generate-new-buffer-name "temp-log"))))
|
|
(switch-to-buffer temp-buffer)
|
|
(text-mode)
|
|
(writeroom-mode)
|
|
(local-set-key (kbd "C-c C-c")
|
|
(lambda () (interactive)
|
|
(find-file "~/doc/log.txt")
|
|
(goto-char (point-max))
|
|
(insert "\n")
|
|
(fez/time-stamp)
|
|
(goto-char (point-max))
|
|
(insert-buffer-substring temp-buffer)
|
|
(insert "\nHumør:")
|
|
(save-buffer)
|
|
(bookmark-set "log.txt")
|
|
(insert " ")
|
|
(kill-buffer temp-buffer)))))
|
|
|
|
(defun fez/eshell-new ()
|
|
"Open a new instance of eshell."
|
|
(interactive)
|
|
(eshell 'N))
|
|
|
|
(defun fez/goto-file ()
|
|
"Go to the file associated with the given name in fez/file-keys."
|
|
(interactive)
|
|
(let ((match (assoc (completing-read "Key: " fez/file-keys) fez/file-keys)))
|
|
(when match
|
|
(find-file (cdr match)))))
|
|
|
|
(defun fez/dired-open-file ()
|
|
"In dired, open the file named on this line in the default application for the filetype."
|
|
(interactive)
|
|
(let ((file (dired-get-filename nil t)))
|
|
(message "Opening %s..." file)
|
|
(call-process "xdg-open" nil 0 nil file)
|
|
(message "Opening %s done" file)))
|
|
|
|
;; Eshell convenience commands.
|
|
(defalias 'open 'find-file-other-window)
|
|
(defalias 'clean 'eshell/clear-scrollback)
|
|
|
|
;;; Keybinds
|
|
|
|
;; C-x C-z and C-z are normally mapped to suspend-frame, an absolutely useless function.
|
|
;; Unbind them before making the keybind useful.
|
|
(global-unset-key (kbd "C-x C-z"))
|
|
(global-unset-key (kbd "C-z"))
|
|
(global-set-key (kbd "C-x C-z") 'fez/mark-line)
|
|
|
|
;; Better buffer management (smol).
|
|
(global-set-key (kbd "C-x C-b") 'bs-show)
|
|
|
|
;; Kill the current buffer and close the window it occupied.
|
|
(global-set-key (kbd "C-x C-k")
|
|
(lambda ()
|
|
(interactive)
|
|
(kill-this-buffer)
|
|
(when (> (length (window-list)) 1)
|
|
(delete-window))))
|
|
|
|
(global-set-key (kbd "C-c t") 'fez/time-stamp)
|
|
|
|
(global-set-key (kbd "C-z C-m") 'fez/man-at-point)
|
|
|
|
(global-set-key (kbd "C-S-o") 'open-line)
|
|
(global-set-key (kbd "C-o") 'fez/insert-line)
|
|
|
|
(global-set-key (kbd "C-c C-s") 'fez/eshell-new)
|
|
|
|
;; zap-up-to-char > zap-to-char
|
|
(global-set-key (kbd "M-z") 'zap-up-to-char)
|
|
|
|
;; Binds for switching between light and dark themes.
|
|
(defun fez/switch-theme (new-theme)
|
|
(lambda ()
|
|
(interactive)
|
|
(disable-theme (car custom-enabled-themes))
|
|
(enable-theme new-theme)))
|
|
|
|
(global-set-key [f5] (fez/switch-theme 'magik))
|
|
(global-set-key [f6] (fez/switch-theme 'basic))
|
|
|
|
(add-hook 'emacs-lisp-mode-hook
|
|
(lambda () (local-set-key (kbd "C-c k") #'fez/insert-keybind)))
|
|
|
|
;;; Variables
|
|
|
|
(setq ssh-private-key-location "~/.ssh/id_ed25519")
|
|
(setq ssh-public-key-location (concat ssh-private-key-location ".pub"))
|