From e39465caf3293f56d0a9bccee599ea3f902fc2b2 Mon Sep 17 00:00:00 2001 From: Mx Kookie Date: Wed, 23 Dec 2020 02:08:14 +0100 Subject: [PATCH] libkookie: emacs: add package to overlay with installed configs --- infra/libkookie/overlays/default.nix | 3 +- .../overlays/kookie/emacs/default.nix | 43 +++ infra/libkookie/overlays/kookie/emacs/init.el | 290 ++++++++++++++++++ 3 files changed, 335 insertions(+), 1 deletion(-) create mode 100644 infra/libkookie/overlays/kookie/emacs/default.nix create mode 100644 infra/libkookie/overlays/kookie/emacs/init.el diff --git a/infra/libkookie/overlays/default.nix b/infra/libkookie/overlays/default.nix index f503537d4f5..cf40e3e59ce 100644 --- a/infra/libkookie/overlays/default.nix +++ b/infra/libkookie/overlays/default.nix @@ -10,7 +10,8 @@ self: super: { barrel-blog = self.callPackage ./kookie/barrel-blog { inherit (super); }; invoice = self.callPackage ./kookie/invoice { inherit (super); }; spacekookie-de = self.callPackage ./kookie/spacekookie-de { inherit (super); }; - + libkookie-emacs = self.callPackage ./kookie/emacs { inherit (super); }; + nodemcu-uploader = self.callPackage ./staging/nodemcu-uploader { }; pleroma = self.callPackage ./staging/pleroma { }; foo2zjs = self.callPackage ./staging/foo2zjs { }; diff --git a/infra/libkookie/overlays/kookie/emacs/default.nix b/infra/libkookie/overlays/kookie/emacs/default.nix new file mode 100644 index 00000000000..e6f1e511525 --- /dev/null +++ b/infra/libkookie/overlays/kookie/emacs/default.nix @@ -0,0 +1,43 @@ +{ stdenv, pkgs, ... }: + +with pkgs; emacsWithPackages (epkgs: + (with epkgs; [ + (runCommand "init.el" {} '' + mkdir -p $out/share/emacs/site-lisp + cp ${./init.el} $out/share/emacs/site-lisp/default.el + '') + + # Language support + fish-mode + lsp-mode + # markdown-mode + nim-mode + nix-mode + protobuf-mode + python-mode + rust-mode + + color-identifiers-mode + color-theme-sanityinc-tomorrow + company + company-lsp + # direnv + fzf + ido-vertical-mode + ledger-mode + lsp-ui + magit + monokai-theme + multiple-cursors + notmuch + org + protobuf-mode + scad-mode + smex + sublimity + treemacs + undo-tree + visual-fill-column + which-key + yasnippet + ])) diff --git a/infra/libkookie/overlays/kookie/emacs/init.el b/infra/libkookie/overlays/kookie/emacs/init.el new file mode 100644 index 00000000000..61b23dcea7d --- /dev/null +++ b/infra/libkookie/overlays/kookie/emacs/init.el @@ -0,0 +1,290 @@ +;; 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))) + +;; More sane line-number behaviour +(setq display-line-numbers-grow-only 1) +(setq display-line-numbers-width-start 1) +(global-display-line-numbers-mode 1) + +;; I just need my personal space +(setq tab-width 2) +(setq-default indent-tabs-mode nil) +(defvaralias 'c-basic-offset 'tab-width) +(defvaralias 'cperl-indent-level 'tab-width) + +;; disable splash screen and startup message +(setq inhibit-startup-message 1) +(setq initial-scratch-message nil) + +(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)) + +;; Some editing niceties +(delete-selection-mode 1) +(show-paren-mode 1) +(setq-default truncate-lines t) + +;; Explicitly enable lsp-mode for certain languages +(add-hook 'rust-mode-hook #'lsp) +(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)) + +(menu-bar-mode -1) +(tool-bar-mode -1) +(scroll-bar-mode -1) + +(column-number-mode 1) +(setq ido-enable-flex-matching t) +(setq ido-everywhere t) +(ido-mode 1) + +(add-hook 'find-file-hook (lambda () (ruler-mode 1))) + +(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)) + +;;; Some stolen bindings from ergo-emacs +(global-set-key (kbd "C-x C-k") 'kill-current-buffer) +(global-set-key (kbd "C-x n") 'new-empty-buffer) +(global-set-key (kbd "C-") 'next-user-buffer) +(global-set-key (kbd "C-") 'previous-user-buffer) +(global-set-key (kbd "M-s M-s") 'save-buffer) +(global-set-key (kbd "C-t") 'smex) +(global-set-key (kbd "C-M-") 'move-section-up) +(global-set-key (kbd "C-M-") '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-" nil) +(define-key org-mode-map "\C-S-" nil)