;;; shoshimacs.el --- Beginner's Mind Config -*- lexical-binding:t -*- (let ((my-custom-file (expand-file-name "shoshimacs-custom.el" user-emacs-directory))) (unless (file-exists-p my-custom-file) (make-empty-file my-custom-file)) (setq custom-file my-custom-file) (load custom-file)) (defvar *my-config* "~/projects/shoshimacs/shoshimacs.org" "Path to my main configuration file.") (defun my-configuration () "Opens my configuration file in buffer." (interactive) (find-file *my-config*)) (defun my-reload-config () "Tangles and reloads a literate config with `org-babel-load-file'" (interactive) (org-babel-load-file *my-config*)) (defun my-hostname () "Helper function to determine on which host Emacs is starting." (string-trim (with-temp-buffer (shell-command "hostname" t) (buffer-string)))) (defvar my-themes-to-install '(cyberpunk-theme dracula-theme nano-theme ef-themes) "List of themes to install when loading shoshimacs config.") (defvar my-chosen-themes '(cyberpunk dichromacy dracula leuven modus-operandi modus-vivendi nano-dark nano-light tango tango-dark ef-day ef-dark ef-light ef-night ef-autumn ef-spring ef-summer ef-winter ef-deuteranopia-dark ef-deuteranopia-light) "List of themes I prefer for narrowing and random selection.") ;;; Package Management (when (< emacs-major-version 28) (add-to-list 'package-archives '("nongnu" . "https://elpa.nongnu.org/nongnu/"))) (package-initialize) (package-refresh-contents) ;; this will make internet requests on start up (when (and (functionp #'native-comp-available-p) (native-comp-available-p)) (setq native-comp-always-compile t package-native-compile t)) ;;; Major Keybinding ;; these need to be set before requiring the package (setq xah-fly-use-control-key nil xah-fly-use-meta-key nil) (package-install 'xah-fly-keys) (require 'xah-fly-keys) (xah-fly-keys-set-layout "qwerty") (xah-fly-keys t) (define-key 'xah-fly-leader-key-map (kbd "1") #'delete-other-windows) (defmacro with-map-defkey (keymap leader &rest pairs) "Define a new KEYMAP with prefix key LEADER, and list of bindings in it." (declare (indent 2)) `(progn (defvar ,keymap (make-sparse-keymap)) (define-prefix-command (quote ,keymap)) (global-set-key (kbd ,leader) ,keymap) (mapc (lambda (pair) (define-key ,keymap (kbd (if (numberp (car pair)) (number-to-string (car pair)) (symbol-name (car pair)))) (cadr pair))) (quote ,(seq-partition pairs 2))))) (with-map-defkey my-key-map "M-m" 1 delete-other-windows a apropos b consult-buffer c my-configuration d embark-act e eshell f find-file g magit h info i consult-imenu j describe-function k describe-variable n tab-next p project-prefix-map s consult-git-grep t consult-theme w which-key-mode my-reload-config) ;;; Completion (setq completion-styles '(flex basic partial-completion emacs22) completion-cycle-threshold 3 tab-always-indent 'complete) (package-install 'consult) (global-set-key (kbd "C-x b") #'consult-buffer) (define-key xah-fly-leader-key-map (kbd "f") #'consult-buffer) (define-key xah-fly-command-map (kbd "n") #'consult-line) (with-eval-after-load 'consult (consult-customize consult-theme :preview-key '(:debounce 0.5 any)) (setq consult-themes my-chosen-themes)) (defun my-show-all-themes () (interactive) (setq consult-themes nil)) (package-install 'embark) (package-install 'embark-consult) (global-set-key (kbd "C-;") #'embark-act) (setq prefix-help-command #'embark-prefix-help-command) (package-install 'marginalia) (marginalia-mode) (package-install 'vertico) (setq minibuffer-prompt-properties '(read-only t cursor-intangible t face minibuffer-prompt)) (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode) (setq read-extended-command-predicate #'command-completion-default-include-p) (setq enable-recursive-minibuffers t) (vertico-mode) (require 'vertico-directory) (define-key vertico-map (kbd "RET") #'vertico-directory-enter) (define-key vertico-map (kbd "DEL") #'vertico-directory-delete-char) (define-key vertico-map (kbd "M-DEL") #'vertico-directory-delete-word) (define-key vertico-map (kbd "M-j") #'vertico-quick-insert) (package-install 'company) (setq company-minimum-prefix-length 2 company-idle-delay 0.3) ;; default is 0.2 (add-hook 'after-init-hook 'global-company-mode) (package-install 'which-key) (which-key-mode) ;;; Editing (package-install 'smartparens) (require 'smartparens-config) (smartparens-global-mode 1) ;(sp-local-pair 'sly-mrepl-mode "'" nil :actions nil) (sp-local-pair 'slime-repl-mode "'" nil :actions nil) (package-install 'markdown-mode) (setq org-directory (expand-file-name "~/Nextcloud/org")) (setq org-default-notes-file (concat org-directory "/notes.org")) (setq org-capture-templates `(("p" "Protocol" entry (file+headline ,org-default-notes-file "Inbox") "* %^{Title}\nSource: %u, %c\n #+BEGIN_QUOTE\n%i\n#+END_QUOTE\n\n\n%?") ("L" "Protocol Link" entry (file+headline ,org-default-notes-file "Inbox") "* %? [[%:link][%:description]] \nCaptured On: %U"))) (setq org-refile-use-outline-path t org-refile-allow-creating-parent-nodes t org-refile-targets '((nil . (:maxlevel . 2)))) (defun my-org-top-level-heading () (interactive) (let ((moo 1)) (while moo (setq moo (org-up-heading-safe))))) (package-install 'htmlize) (org-babel-do-load-languages 'org-babel-load-languages '((emacs-lisp . t) (lisp . t) (org . t) (plantuml . t) (ruby . t) (shell . t))) (package-install 'org-tree-slide) (add-to-list 'org-structure-template-alist '("se" . "src emacs-lisp")) (add-to-list 'org-structure-template-alist '("sr" . "src ruby")) (add-to-list 'org-structure-template-alist '("ss" . "src shell")) (recentf-mode) (setq indent-tabs-mode nil show-trailing-whitespace t) (package-install 'crdt) ;;; Programming (setq inferior-lisp-program "sbcl") (defvar slime-repo "https://github.com/slime/slime") (defvar slime-src-dir (expand-file-name "~/src/slime/")) (unless (file-directory-p slime-src-dir) (shell-command (format "git clone %s %s" slime-repo slime-src-dir))) (add-to-list 'load-path slime-src-dir) (require 'slime-autoloads) (let ((default-directory (concat slime-src-dir "doc/")) (buf (get-buffer-create "*slime-make-info*"))) (unless (file-exists-p "slime.info") (shell-command "make clean" "*slime-make-info*") (shell-command "make slime.info" "*slime-make-info*"))) (defvar slime-company-repo "https://github.com/anwyn/slime-company") (defvar slime-company-src-dir (expand-file-name "~/src/slime-company/")) (unless (file-directory-p slime-company-src-dir) (shell-command (format "git clone %s %s" slime-company-repo slime-company-src-dir))) (add-to-list 'load-path slime-company-src-dir) (setq slime-company-completion 'fuzzy slime-company-display-arglist 1) (setq slime-contribs '( slime-fancy ;; default value, includes many fundamental contribs slime-company slime-mrepl inferior-slime slime-fuzzy slime-asdf slime-banner slime-presentations slime-xref-browser slime-highlight-edits slime-quicklisp )) (slime-setup) (defun my-slime-return (_) "Function to advise `slime-repl-return' to make inspect the presentation at point." (when (slime-presentation-around-or-before-point-p) (slime-inspect-presentation-at-point (point)))) (advice-add 'slime-repl-return :before #'my-slime-return) (package-install 'json-mode) (add-hook 'ruby-mode-hook #'flymake-mode) (package-install 'inf-ruby) (when (executable-find "pry") (setq inf-ruby-default-implementation "pry")) (defvar minitest-emacs-repo "https://github.com/arthurnn/minitest-emacs.git") (defvar minitest-emacs-src-dir "~/src/minitest-emacs") (unless (file-directory-p minitest-emacs-src-dir) (shell-command (format "git clone %s %s" minitest-emacs-repo minitest-emacs-src-dir))) (add-to-list 'load-path minitest-emacs-src-dir) (require 'minitest) (package-install 'haml-mode) (package-install 'devdocs) (with-eval-after-load 'flymake (define-key flymake-mode-map (kbd "M-n") 'flymake-goto-next-error) (define-key flymake-mode-map (kbd "M-p") 'flymake-goto-prev-error)) (defvar plantuml-mode-repo "https://github.com/skuro/plantuml-mode") (defvar plantuml-mode-src-dir "~/src/plantuml-mode") (unless (file-directory-p plantuml-mode-src-dir) (shell-command (format "git clone %s %s" plantuml-mode-repo plantuml-mode-src-dir))) (add-to-list 'load-path plantuml-mode-src-dir) (require 'plantuml-mode) (customize-set-value 'plantuml-default-exec-mode 'executable) ;;; Projects (fset 'project-prefix-map project-prefix-map) (package-install 'magit) ;; Applications (require 'emms-setup) (emms-all) (setq emms-player-list '(emms-player-mpv)) (setq emms-source-file-default-directory "~/Music/") (add-to-list 'emms-tag-editor-tagfile-functions '("wav" . emms-tag-tracktag-file)) (setq erc-server "irc.libera.chat" erc-nick "shoshin" erc-autojoin-channels-alist '(("libera.chat" "#emacs" "#emacsconf" "#lispgames")) erc-interpret-mirc-color t erc-hide-list '("JOIN" "PART" "QUIT")) ;;; External Services (package-install 'plz) (package-install 'srht) (setq srht-username "shoshin") (defun read-file-into-string (f) (with-temp-buffer (insert-file-contents f) (buffer-string))) (setq cicadas-paste-pw (read-file-into-string "~/.bepasty-key")) (defun cicadas-paste-current-buffer () (interactive) (let ((tmpfile (concat "/tmp/" (buffer-name)))) (write-region nil nil tmpfile) (let ((url (cl-first (last (butlast (split-string (shell-command-to-string (format "pastebinit -i '%s' -p %s -t '%s' -f text/plain" tmpfile cicadas-paste-pw (buffer-name))) "\n")))))) (delete-file tmpfile) (kill-new url) (message "Pasted to %s (on kill ring)" url)))) (defvar restclient-repo "https://github.com/pashky/restclient.el.git") (defvar restclient-dir "~/src/restclient.el") (unless (file-directory-p restclient-dir) (shell-command (format "git clone %s %s" restclient-repo restclient-dir))) (add-to-list 'load-path restclient-dir) (require 'restclient) ;;; User Interface (when (display-graphic-p) (scroll-bar-mode -1) (fringe-mode '(8 . 0)) (menu-bar-mode -1) (tool-bar-mode -1)) (package-install 'darkroom) (let* ((size (if (or (equal (system-name) "zebes") (equal (system-name) "ridley")) 16 12)) (font (format "Victor Mono-%s" size))) (add-to-list 'default-frame-alist `(font . ,font))) (global-hl-line-mode t) (mapc #'package-install my-themes-to-install) (defvar emacs-kaolin-repo "https://github.com/ogdenwebb/emacs-kaolin-themes") (defvar emacs-kaolin-src-dir (expand-file-name "~/src/emacs-kaolin/")) (unless (file-directory-p emacs-kaolin-src-dir) (shell-command (format "git clone %s %s" emacs-kaolin-repo emacs-kaolin-src-dir))) (add-to-list 'load-path emacs-kaolin-src-dir) (require 'kaolin-themes) (package-install 'autothemer) (setq telephone-line-lhs '((evil . (telephone-line-evil-tag-segment)) (accent . (telephone-line-vc-segment telephone-line-erc-modified-channels-segment telephone-line-process-segment)) (nil . ( ;; telephone-line-minor-mode-segment telephone-line-buffer-segment)))) (setq telephone-line-rhs '((nil . (telephone-line-misc-info-segment telephone-line-flymake-segment)) (accent . (telephone-line-major-mode-segment)) (evil . (telephone-line-airline-position-segment)))) (telephone-line-mode t) (set-face-background 'telephone-line-evil-normal "deep pink") (set-face-background 'telephone-line-evil-insert "Dark Turquoise") (defun screenshot-svg () "Save a screenshot of the current frame as an SVG image. Saves to a temp file and puts the filename in the kill ring." (interactive) (let* ((filename (make-temp-file "Emacs" nil ".svg")) (data (x-export-frames nil 'svg))) (with-temp-file filename (insert data)) (kill-new filename) (message filename))) (package-install 'windresize)