@@ -0,0 +1,580 @@ | |||||
(doom-load-envvars-file (concat doom-private-dir "env.el")) | |||||
(setq doom-theme 'doom-catppuccin) | |||||
(setq doom-font (font-spec :family "monospace" :size 13) | |||||
doom-big-font (font-spec :family "monospace" :size 13) | |||||
doom-variable-pitch-font (font-spec :family "sans-serif" :size 13)) | |||||
(set-frame-parameter (selected-frame) 'alpha-background 85) | |||||
(add-to-list 'default-frame-alist '(alpha-background . 85)) | |||||
(setq evil-want-fine-undo t) | |||||
(defun my/line-numbers-relative () | |||||
(setq display-line-numbers 'relative)) | |||||
(defun my/line-numbers-absolute () | |||||
(setq display-line-numbers 'absolute)) | |||||
(add-hook 'evil-insert-state-entry-hook #'my/line-numbers-absolute) | |||||
(add-hook 'evil-insert-state-exit-hook #'my/line-numbers-relative) | |||||
(use-package copilot | |||||
:commands (copilot-complete)) | |||||
(defun my/copilot-complete () | |||||
(interactive) | |||||
(copilot-complete) | |||||
(my/hydra-copilot/body) | |||||
(copilot-clear-overlay)) | |||||
(defhydra my/hydra-copilot () | |||||
"Copilot" | |||||
("<return>" copilot-accept-completion "Accept" :color blue ) | |||||
("<tab>" copilot-next-completion "Next" ) | |||||
("<backtab>" copilot-previous-completion "Prev") | |||||
("<escape>" copilot-clear-overlay "Cancel" :color blue)) | |||||
(setq doom-scratch-initial-major-mode 'lisp-interaction-mode) | |||||
(map! :leader | |||||
"b" nil | |||||
"f" nil | |||||
"h" nil | |||||
"p" nil | |||||
"t" nil) | |||||
(map! :map evil-org-mode-map | |||||
:n "zc" nil) | |||||
(map! | |||||
:desc "Increase font size" :ni "C-=" #'text-scale-increase | |||||
:desc "Decrease font size" :ni "C--" #'text-scale-decrease) | |||||
(map! | |||||
:desc "Copilot" :i "C-," #'my/copilot-complete) | |||||
(map! :map minibuffer-mode-map | |||||
:desc "Next history" "C-j" #'next-history-element | |||||
:desc "Prev history" "C-k" #'previous-history-element) | |||||
(map! :leader | |||||
:desc "M-x" "x" #'counsel-M-x | |||||
:desc "M-:" ";" #'pp-eval-expression) | |||||
(map! :leader | |||||
:desc "Find file" "." #'counsel-find-file | |||||
:desc "Find dir" ">" #'+default/dired | |||||
:desc "Find in project" "SPC" #'+ivy/projectile-find-file | |||||
:desc "Find in project uncached" "C-SPC" #'my/projectile-find-file-nocache) | |||||
(defun my/projectile-find-file-nocache () | |||||
(interactive) | |||||
(projectile-invalidate-cache nil) | |||||
(+ivy/projectile-find-file)) | |||||
(map! :leader | |||||
:desc "Switch buffer" "," #'+vertico/switch-workspace-buffer | |||||
:desc "Switch all buffers" ">" #'consult-buffer) | |||||
(map! :leader | |||||
:desc "Search online" "/" #'counsel-search) | |||||
(map! :leader | |||||
:prefix ("b" . "buffers") | |||||
:desc "Switch buffer" "b" #'consult-buffer | |||||
:desc "ibuffer" "i" #'ibuffer | |||||
:desc "Kill buffer" "d" #'kill-current-buffer | |||||
:desc "Kill all buffers" "D" #'doom/kill-all-buffers) | |||||
(map! :leader | |||||
:prefix ("f" . "files") | |||||
:desc "Recent files" "r" #'consult-recent-file | |||||
:desc "Find file" "f" #'counsel-find-file | |||||
:desc "Find file as root" "u" #'doom/sudo-find-file | |||||
:desc "Find package" "p" #'counsel-find-library | |||||
:desc "Copy this file" "c" #'doom/copy-this-file | |||||
:desc "Delete this file" "d" #'doom/delete-this-file | |||||
:desc "Move this file" "m" #'doom/move-this-file | |||||
:desc "Revert this file" "l" #'revert-buffer | |||||
:desc "Copy file path" "y" #'+default/yank-buffer-path | |||||
:desc "Copy project file path" "Y" #'+default/yank-buffer-path-relative-to-project | |||||
:desc "Open scratch" "x" #'doom/open-scratch-buffer) | |||||
(map! :leader | |||||
:prefix ("f s" . "snippets") | |||||
:desc "New snippet" "n" #'yas-new-snippet | |||||
:desc "Edit snippet" "e" #'yas-visit-snippet-file | |||||
:desc "Browse docs" "?" #'my/yas-browse-docs) | |||||
(defun my/yas-browse-docs () | |||||
(interactive) | |||||
(browse-url "https://joaotavora.github.io/yasnippet")) | |||||
(map! :leader | |||||
:prefix ("f e" . "emacs") | |||||
:desc "Find in config" "f" #'doom/find-file-in-private-config | |||||
:desc "Reload config" "r" #'doom/reload | |||||
:desc "Edit config" "c" #'my/edit-config | |||||
:desc "Edit packages" "p" #'my/edit-packages | |||||
:desc "Edit env" "e" #'my/edit-env | |||||
:desc "Edit init" "i" #'my/edit-init) | |||||
(defun my/edit-config () | |||||
(interactive) | |||||
(find-file (concat doom-private-dir "config.org"))) | |||||
(defun my/edit-packages () | |||||
(interactive) | |||||
(find-file (concat doom-private-dir "packages.el"))) | |||||
(defun my/edit-init () | |||||
(interactive) | |||||
(find-file (concat doom-private-dir "init.el"))) | |||||
(defun my/edit-env () | |||||
(interactive) | |||||
(find-file (concat doom-private-dir "env.el"))) | |||||
(define-derived-mode org-config-mode org-mode "Org config mode") | |||||
(add-to-list 'auto-mode-alist '("config\\.org" . org-config-mode)) | |||||
(map! :leader | |||||
:prefix ("h" . "help") | |||||
:desc "Apropos" "/" #'consult-apropos | |||||
:desc "Apropos docs" "?" #'apropos-documentation | |||||
:desc "Help at point" "p" #'helpful-at-point | |||||
:desc "Help info" "h" #'info | |||||
:desc "Help for help" "H" #'help-for-help | |||||
:desc "Describe function" "f" #'counsel-describe-function | |||||
:desc "Describe function key" "F" #'where-is | |||||
:desc "Describe variable" "v" #'counsel-describe-variable | |||||
:desc "Describe custom variable" "V" #'doom/help-custom-variable | |||||
:desc "Describe command" "x" #'helpful-command | |||||
:desc "Describe key" "k" #'describe-key-briefly | |||||
:desc "Describe key fully" "K" #'describe-key | |||||
:desc "Describe char" "'" #'describe-char | |||||
:desc "Describe coding system" "\"" #'describe-coding-system | |||||
:desc "Describe input method" "i" #'describe-input-method | |||||
:desc "Emacs manual" "e" #'info-emacs-manual | |||||
:desc "ASCII table" "a" #'my/ascii-table | |||||
:desc "View messages" "e" #'view-echo-area-messages | |||||
:desc "View keystrokes" "l" #'view-lossage) | |||||
(defface my/ascii-table-highlight-face | |||||
'((t (:foreground "pink"))) | |||||
"Face for highlighting ASCII chars.") | |||||
(defun my/ascii-table () | |||||
"Display basic ASCII table (0 thru 128)." | |||||
(interactive) | |||||
(pop-to-buffer "*ASCII*") | |||||
(erase-buffer) | |||||
(setq buffer-read-only nil) | |||||
(my/buffer-local-set-key "q" #'+popup/quit-window) | |||||
(setq lower32 '("nul" "soh" "stx" "etx" "eot" "enq" "ack" "bel" | |||||
"bs" "ht" "nl" "vt" "np" "cr" "so" "si" | |||||
"dle" "dc1" "dc2" "dc3" "dc4" "nak" "syn" "etb" | |||||
"can" "em" "sub" "esc" "fs" "gs" "rs" "us")) | |||||
(save-excursion (let ((i -1)) | |||||
(insert " Hex Dec Char | Hex Dec Char | Hex Dec Char | Hex Dec Char\n") | |||||
(insert " ---------------+-----------------+-----------------+----------------\n") | |||||
(while (< i 31) | |||||
(insert (format "%4x %4d %4s | %4x %4d %4s | %4x %4d %4s | %4x %4d %4s\n" | |||||
(setq i (+ 1 i)) i (elt lower32 i) | |||||
(setq i (+ 32 i)) i (single-key-description i) | |||||
(setq i (+ 32 i)) i (single-key-description i) | |||||
(setq i (+ 32 i)) i (single-key-description i))) | |||||
(overlay-put (make-overlay (- (point) 4) (- (point) 1)) 'face 'my/ascii-table-highlight-face) | |||||
(overlay-put (make-overlay (- (point) 22) (- (point) 19)) 'face 'my/ascii-table-highlight-face) | |||||
(overlay-put (make-overlay (- (point) 40) (- (point) 37)) 'face 'my/ascii-table-highlight-face) | |||||
(overlay-put (make-overlay (- (point) 58) (- (point) 55)) 'face 'my/ascii-table-highlight-face) | |||||
(setq i (- i 96)) | |||||
)))) | |||||
(set-popup-rule! "^\\*ASCII" | |||||
:side 'right | |||||
:select t | |||||
:width 70) | |||||
(map! :leader | |||||
:prefix ("h d" . "doom") | |||||
:desc "Doom manual" "d" #'doom/help | |||||
:desc "Doom FAQ" "f" #'doom/help-faq | |||||
:desc "Doom modules" "m" #'doom/help-modules | |||||
:desc "Doom news" "n" #'doom/help-news | |||||
:desc "Doom help search" "/" #'doom/help-search-headings | |||||
:desc "Doom version" #'doom/version | |||||
:desc "Doom package configuration" "p" #'doom/help-package-config | |||||
:desc "Doom sandbox" "x" #'doom/sandbox) | |||||
(map! :leader | |||||
:prefix ("p" . "projects") | |||||
:desc "Switch project" "p" #'counsel-projectile-switch-project | |||||
:desc "Add new project" "a" #'projectile-add-known-project | |||||
:desc "Remove project" "d" #'projectile-remove-known-project | |||||
:desc "Find in project root" "." #'counsel-projectile-find-file | |||||
:desc "Search in project" "/" #'+default/search-project | |||||
:desc "Invalidate project cache" "i" #'projectile-invalidate-cache | |||||
:desc "Run cmd in project root" "!" #'projectile-run-shell-command-in-root | |||||
:desc "Run async cmd in project root" "&" #'projectile-run-async-shell-command-in-root) | |||||
(defun my/projectile-find-in-root () | |||||
(interactive) | |||||
(counsel-find-file nil projectile-project-root)) | |||||
(map! :leader | |||||
:prefix ("t" . "toggle") | |||||
;; Wrap | |||||
:desc "Auto Wrap" "a" #'auto-fill-mode | |||||
:desc "Wrap Indicator" "c" #'global-display-fill-column-indicator-mode | |||||
:desc "Wrap Column" "C" #'set-fill-column | |||||
:desc "Line Wrap" "w" #'visual-line-mode | |||||
;; Modes | |||||
:desc "Flycheck" "f" #'flycheck-mode | |||||
;; Files | |||||
:desc "Read-only" "r" #'read-only-mode) | |||||
(defun my/auto-fill-mode (cols) | |||||
(interactive)) | |||||
(map! :leader | |||||
:prefix-map ("w" . "window") | |||||
;; Navigation | |||||
:desc "Go..." "w" #'ace-window | |||||
:desc "Go left" "h" #'evil-window-left | |||||
:desc "Go down" "j" #'evil-window-down | |||||
:desc "Go up" "k" #'evil-window-up | |||||
:desc "Go right" "l" #'evil-window-right | |||||
:desc "Go other" "o" #'other-window | |||||
;; Layout | |||||
:desc "Rotate up" "K" #'evil-window-rotate-upwards | |||||
:desc "Rotate down" "J" #'evil-window-rotate-downwards | |||||
;; Splits | |||||
:desc "VSplit" "=" #'+evil/window-vsplit-and-follow | |||||
:desc "HSplit" "-" #'+evil/window-split-and-follow | |||||
:desc "Tear off" "t" #'tear-off-window | |||||
;; History | |||||
:desc "Undo" "u" #'winner-undo | |||||
:desc "Redo" "U" #'winner-redo | |||||
;; Misc | |||||
:desc "Resize" "r" #'my/hydra-window-resize/body | |||||
:desc "Balance" "b" #'balance-windows | |||||
;; Management | |||||
:desc "Kill window" "d" #'+workspace/close-window-or-workspace) | |||||
;; TODO: Maybe check out: | |||||
;; evil-window-mru | |||||
(setq my/window-resize-step 3) | |||||
(defun my/window-increase-height () | |||||
(interactive) | |||||
(evil-window-increase-height my/window-resize-step)) | |||||
(defun my/window-decrease-height () | |||||
(interactive) | |||||
(evil-window-decrease-height my/window-resize-step)) | |||||
(defun my/window-increase-width () | |||||
(interactive) | |||||
(evil-window-increase-width my/window-resize-step)) | |||||
(defun my/window-decrease-width () | |||||
(interactive) | |||||
(evil-window-decrease-width my/window-resize-step)) | |||||
(defhydra my/hydra-window-resize () | |||||
"Resize window" | |||||
("=" my/window-increase-height "++Height") | |||||
("-" my/window-decrease-height "--Height") | |||||
("<" my/window-decrease-width "--Width") | |||||
(">" my/window-increase-width "++Width")) | |||||
(map! :map org-config-mode-map | |||||
:localleader | |||||
:v :desc "Eval Region" "e" #'eval-region | |||||
:n :desc "Eval Source" "e" #'my/org-config-eval-source) | |||||
(defun my/org-config-eval-source () | |||||
(interactive) | |||||
(org-ctrl-c-ctrl-c) | |||||
(org-babel-remove-result)) | |||||
(map! :map rustic-mode-map | |||||
:localleader | |||||
:desc "Debug..." "d" #'my/rust/dap-hydra/body) | |||||
(map! :map rustic-mode-map | |||||
:desc "Pluralize import" "," #'my/rust/import-pluralize | |||||
:desc "Singularize import" "<backspace>" #'my/rust/import-singularize | |||||
:desc "Singularize import" "C-<backspace>" #'my/rust/import-c-singularize) | |||||
(defhydra my/rust/dap-hydra (:color pink :hint nil :foreign-keys run) | |||||
" | |||||
^Stepping^ ^Switch^ ^Breakpoints^ ^Debug^ ^Eval | |||||
^^^^^^^^---------------------------------------------------------------------------------------------------------------- | |||||
_n_: Next _ss_: Session _bb_: Toggle _dd_: Debug binary _ee_: Eval | |||||
_i_: Step in _st_: Thread _bd_: Delete _dr_: Restart debugging _es_: Eval thing at point | |||||
_o_: Step out _sf_: Stack frame _ba_: Add _ea_: Add expression | |||||
_c_: Continue _su_: Up stack frame _bc_: Set condition | |||||
_Q_: Disconnect _sd_: Down stack frame _bh_: Set hit count | |||||
_sl_: List locals _bl_: Set log message | |||||
_sb_: List breakpoints | |||||
_sS_: List sessions | |||||
" | |||||
("n" dap-next) | |||||
("i" dap-step-in) | |||||
("o" dap-step-out) | |||||
("c" dap-continue) | |||||
("r" dap-restart-frame) | |||||
("ss" dap-switch-session) | |||||
("st" dap-switch-thread) | |||||
("sf" dap-switch-stack-frame) | |||||
("su" dap-up-stack-frame) | |||||
("sd" dap-down-stack-frame) | |||||
("sl" dap-ui-locals) | |||||
("sb" dap-ui-breakpoints) | |||||
("sS" dap-ui-sessions) | |||||
("bb" dap-breakpoint-toggle) | |||||
("ba" dap-breakpoint-add) | |||||
("bd" dap-breakpoint-delete) | |||||
("bc" dap-breakpoint-condition) | |||||
("bh" dap-breakpoint-hit-condition) | |||||
("bl" dap-breakpoint-log-message) | |||||
("dd" my/rust/debug-binary) | |||||
("dr" dap-debug-restart) | |||||
("ee" dap-eval) | |||||
("ea" dap-ui-expressions-add) | |||||
("es" dap-eval-thing-at-point) | |||||
("q" nil "quit" :color blue) | |||||
("Q" dap-disconnect :color red)) | |||||
(map! :prefix "z" | |||||
:desc "Kill buffer" :n "x" #'kill-current-buffer | |||||
:desc "Kill window" :n "c" #'+workspace/close-window-or-workspace) | |||||
(map! :prefix "[" | |||||
:desc "Start of fn" :n "f" #'beginning-of-defun) | |||||
(map! :prefix "]" | |||||
:desc "End of fn" :n "f" #'end-of-defun) | |||||
(add-to-list 'projectile-globally-ignored-files "Cargo.lock") | |||||
(defun my/rust/import-pluralize () | |||||
"Convert a singular import into a brace-wrapped plural import." | |||||
(interactive) | |||||
(if (and | |||||
(not (my/kbd!-p)) | |||||
(my/insert-mode-p) | |||||
(my/line-match-p | |||||
;; use foo::bar::baz; | |||||
(rx line-start "use " | |||||
(+ (+ word) "::") | |||||
(+ word) | |||||
(? ";") line-end))) | |||||
(kbd! "ESC vb S} f} i,") | |||||
(insert ","))) | |||||
(defun my/rust/import-singularize () | |||||
"Convert a brace-wrapped plural import into a singular import." | |||||
(interactive) | |||||
(if (and | |||||
(not (my/kbd!-p)) | |||||
(my/insert-mode-p) | |||||
(my/line-match-p | |||||
;; use foo::bar::baz::{qux::quo,}; | |||||
(rx line-start "use " | |||||
(+ (+ word) "::") | |||||
"{" (* (+ word) "::") (+ word) ",}" | |||||
(? ";") line-end))) | |||||
(kbd! "ESC l dF, ds} $i") | |||||
(evil-delete-backward-char-and-join 1))) | |||||
(defun my/rust/import-c-singularize () | |||||
"Convert a brace-wrapped plural import into a singular import." | |||||
(interactive) | |||||
(if (and | |||||
(not (my/kbd!-p)) | |||||
(my/insert-mode-p) | |||||
(my/line-match-p | |||||
;; use foo::bar::baz::{qux::quo, }; | |||||
(rx line-start | |||||
"use " | |||||
(+ (+ word) "::") | |||||
"{" (* (+ word) "::") (+ word) "," (* whitespace) "}" | |||||
(? ";") line-end))) | |||||
(kbd! "ESC l dF, ds} $i") | |||||
(backward-kill-word 1))) | |||||
(defun my/rust/debug-config (args) | |||||
(append | |||||
`(:type "lldb-vscode" | |||||
;; `(:type "lldb" | |||||
:request "launch" | |||||
:dap-server-path ,(list (executable-find "lldb-vscode")) | |||||
;; :dap-server-path ,(list (executable-find "rust-lldb")) | |||||
,@args))) | |||||
;; use a::TestThin | |||||
;; (:MIMode "gdb" | |||||
;; :miDebuggerPath "gdb" | |||||
;; :stopAtEntry t | |||||
;; :externalConsole | |||||
;; :json-false | |||||
;; :type "cppdbg" | |||||
;; :request "launch" | |||||
;; :name "test test2" | |||||
;; :args ["test2" "--exact" "--nocapture"] | |||||
;; :cwd "/home/lain/Code/test/rust/debug" | |||||
;; :sourceLanguages ["rust"] | |||||
;; :program "/home/lain/Code/test/rust/debug/target/debug/deps/...") | |||||
;; (require 'dap-cpptools) | |||||
(defun my/rust/debug-binary (args) | |||||
(interactive "sArgs: ") | |||||
(let* ((root (projectile-project-root)) | |||||
(name (projectile-project-name)) | |||||
(target (concat root "target/debug/" name))) | |||||
;; (rustic-cargo-build) | |||||
(dap-debug | |||||
(my/rust/debug-config | |||||
`(:program ,target | |||||
:cwd ,root | |||||
:args ,(apply #'vector (split-string-and-unquote args))))))) | |||||
(defun my/rust/debug-lsp-runnable (runnable) | |||||
"Select and debug a RUNNABLE action." | |||||
(interactive (list (lsp-rust-analyzer--select-runnable))) | |||||
(-let (((&rust-analyzer:Runnable | |||||
:args (&rust-analyzer:RunnableArgs :cargo-args :workspace-root? :executable-args) | |||||
:label) runnable)) | |||||
(pcase (aref cargo-args 0) | |||||
("run" (aset cargo-args 0 "build")) | |||||
("test" (when (-contains? (append cargo-args ()) "--no-run") | |||||
(cl-callf append cargo-args (list "--no-run"))))) | |||||
(->> (append (list (executable-find "cargo")) | |||||
cargo-args | |||||
(list "--message-format=json")) | |||||
(s-join " ") | |||||
(shell-command-to-string) | |||||
(s-lines) | |||||
(-keep (lambda (s) | |||||
(condition-case nil | |||||
(-let* ((json-object-type 'plist) | |||||
((msg &as &plist :reason :executable) (json-read-from-string s))) | |||||
(when (and executable (string= "compiler-artifact" reason)) | |||||
executable)) | |||||
(error)))) | |||||
(funcall | |||||
(lambda (artifact-spec) | |||||
(pcase artifact-spec | |||||
(`() (user-error "No compilation artifacts or obtaining the runnable artifacts failed")) | |||||
(`(,spec) spec) | |||||
(_ (user-error "Multiple compilation artifacts are not supported"))))) | |||||
(list :name label | |||||
:args executable-args | |||||
:cwd workspace-root? | |||||
;; :sourceLanguages ["rust"] | |||||
:stopAtEntry t | |||||
:stopAtEntry :json-true | |||||
:externalConsole :json-false | |||||
:program) | |||||
(my/rust/debug-config) | |||||
(dap-debug)))) | |||||
(advice-add #'lsp-rust-analyzer-debug :override #'my/rust/debug-lsp-runnable) | |||||
;; (setq projectile-project-search-path | |||||
;; '("~/Code")) | |||||
(let ((found (nth 0 (auth-source-search :host "kagi.com")))) | |||||
(when found | |||||
(let ((token (plist-get found :secret))) | |||||
(when (functionp token) | |||||
(setq token (funcall token))) | |||||
(add-to-list | |||||
'counsel-search-engines-alist | |||||
`(kagi | |||||
"https://duckduckgo.com/ac/" | |||||
,(format "https://kagi.com/search?token=%s&q=" token) | |||||
counsel--search-request-data-ddg)) | |||||
(setq counsel-search-engine 'kagi)))) | |||||
(load! "lisp/emacs-everywhere.el") | |||||
(setq emacs-everywhere-paste-command '("xdotool" "key" "--clearmodifiers" "ctrl+v")) | |||||
(setq emacs-everywhere-frame-parameters | |||||
'((title . "Emacs Everywhere") | |||||
(width . 120) | |||||
(height . 36))) | |||||
(defun my/line () | |||||
(buffer-substring-no-properties | |||||
(line-beginning-position) | |||||
(line-end-position))) | |||||
(defun my/line-match-p (regexp) | |||||
(string-match-p regexp (my/line))) | |||||
(defun my/insert-mode-p () | |||||
(eq evil-state 'insert)) | |||||
(defun my/normal-mode-p () | |||||
(eq evil-state 'normal)) | |||||
(defun my/kbd-replace (str) | |||||
"Convert STR into a keyboard macro string by replacing terminal key sequences with GUI keycodes." | |||||
(let ((kbd-regex '(("ESC" . "<escape>") | |||||
("DEL" . "<delete>" ) | |||||
("BS" . "<backspace>") | |||||
("RET" . "<return>") | |||||
("SPC" . "<SPC>") | |||||
("TAB" . "<tab>")))) | |||||
(my/replace-regexps-in-string str kbd-regex))) | |||||
(setq my//kbd-p nil) | |||||
(defun my/kbd!-p () (eq my//kbd-p t)) | |||||
(defun kbd! (str) | |||||
"Execute the key sequence defined by STR like a VIM macro." | |||||
(let ((minibuffer-message-timeout 0)) | |||||
(setq my//kbd-p t) | |||||
(execute-kbd-macro (read-kbd-macro (my/kbd-replace str))) | |||||
(setq my//kbd-p nil))) | |||||
(defun my/buffer-local-set-key (key fn) | |||||
(let ((mode (intern (format "%s-local-mode" (buffer-name)))) | |||||
(map (intern (format "%s-local-mode-map" (buffer-name))))) | |||||
(unless (boundp map) | |||||
(set map (make-sparse-keymap)) | |||||
(evil-make-overriding-map map 'normal)) | |||||
(eval | |||||
`(define-minor-mode ,mode | |||||
"A minor mode for buffer-local keybinds." | |||||
:keymap ,map)) | |||||
(eval | |||||
`(define-key ,map ,key #',fn)) | |||||
(funcall mode t))) | |||||
(defun my/replace-regexps-in-string (str regexps) | |||||
"Replace all pairs of (regex . replacement) defined by REGEXPS in STR." | |||||
(if (null regexps) | |||||
str | |||||
(my/replace-regexps-in-string | |||||
(replace-regexp-in-string (caar regexps) (cdar regexps) str t) | |||||
(cdr regexps)))) |
@@ -0,0 +1,733 @@ | |||||
#+title: Config | |||||
* Setup | |||||
** Environment Variables | |||||
#+BEGIN_SRC elisp | |||||
(doom-load-envvars-file (concat doom-private-dir "env.el")) | |||||
#+END_SRC | |||||
* Appearance | |||||
Set a nice theme and font. | |||||
#+BEGIN_SRC elisp | |||||
(setq doom-theme 'doom-catppuccin) | |||||
(setq doom-font (font-spec :family "monospace" :size 13) | |||||
doom-big-font (font-spec :family "monospace" :size 13) | |||||
doom-variable-pitch-font (font-spec :family "sans-serif" :size 13)) | |||||
#+END_SRC | |||||
Sprinkle in a little background transparency. Instead of making the entire frame | |||||
transparent (including the text) with =alpha=, we use the =alpha-background= | |||||
frame parameter which just landed in the Emacs 29 development branch. | |||||
#+BEGIN_SRC elisp | |||||
(set-frame-parameter (selected-frame) 'alpha-background 85) | |||||
(add-to-list 'default-frame-alist '(alpha-background . 85)) | |||||
#+END_SRC | |||||
* Editing | |||||
** Evil | |||||
#+BEGIN_SRC elisp | |||||
(setq evil-want-fine-undo t) | |||||
#+END_SRC | |||||
*** Line Numbers | |||||
Use relative line numbers in normal mode, and absolute line numbers in insert | |||||
mode. | |||||
#+BEGIN_SRC emacs-lisp | |||||
(defun my/line-numbers-relative () | |||||
(setq display-line-numbers 'relative)) | |||||
(defun my/line-numbers-absolute () | |||||
(setq display-line-numbers 'absolute)) | |||||
(add-hook 'evil-insert-state-entry-hook #'my/line-numbers-absolute) | |||||
(add-hook 'evil-insert-state-exit-hook #'my/line-numbers-relative) | |||||
#+END_SRC | |||||
** Copilot | |||||
Add support for GitHub Copilot ([[*Copilot][keybinds]]). | |||||
#+BEGIN_SRC elisp | |||||
(use-package copilot | |||||
:commands (copilot-complete)) | |||||
(defun my/copilot-complete () | |||||
(interactive) | |||||
(copilot-complete) | |||||
(my/hydra-copilot/body) | |||||
(copilot-clear-overlay)) | |||||
(defhydra my/hydra-copilot () | |||||
"Copilot" | |||||
("<return>" copilot-accept-completion "Accept" :color blue ) | |||||
("<tab>" copilot-next-completion "Next" ) | |||||
("<backtab>" copilot-previous-completion "Prev") | |||||
("<escape>" copilot-clear-overlay "Cancel" :color blue)) | |||||
#+END_SRC | |||||
** Scratch | |||||
Use =lisp-interaction-mode= by default for the scratch buffer. | |||||
#+BEGIN_SRC elisp | |||||
(setq doom-scratch-initial-major-mode 'lisp-interaction-mode) | |||||
#+END_SRC | |||||
* Keybinds | |||||
** Unmaps | |||||
Unmap a bunch of the default keybindings. | |||||
#+BEGIN_SRC elisp | |||||
(map! :leader | |||||
"b" nil | |||||
"f" nil | |||||
"h" nil | |||||
"p" nil | |||||
"t" nil) | |||||
(map! :map evil-org-mode-map | |||||
:n "zc" nil) | |||||
#+END_SRC | |||||
** Global | |||||
*** Font Size | |||||
#+BEGIN_SRC elisp | |||||
(map! | |||||
:desc "Increase font size" :ni "C-=" #'text-scale-increase | |||||
:desc "Decrease font size" :ni "C--" #'text-scale-decrease) | |||||
#+END_SRC | |||||
*** Copilot | |||||
#+BEGIN_SRC elisp | |||||
(map! | |||||
:desc "Copilot" :i "C-," #'my/copilot-complete) | |||||
#+END_SRC | |||||
*** LSP | |||||
#+BEGIN_SRC elisp | |||||
#+END_SRC | |||||
*** Minibuffer | |||||
#+BEGIN_SRC elisp | |||||
(map! :map minibuffer-mode-map | |||||
:desc "Next history" "C-j" #'next-history-element | |||||
:desc "Prev history" "C-k" #'previous-history-element) | |||||
#+END_SRC | |||||
** Leader | |||||
*** Root | |||||
**** Eval | |||||
#+BEGIN_SRC elisp | |||||
(map! :leader | |||||
:desc "M-x" "x" #'counsel-M-x | |||||
:desc "M-:" ";" #'pp-eval-expression) | |||||
#+END_SRC | |||||
**** Files | |||||
#+BEGIN_SRC elisp | |||||
(map! :leader | |||||
:desc "Find file" "." #'counsel-find-file | |||||
:desc "Find dir" ">" #'+default/dired | |||||
:desc "Find in project" "SPC" #'+ivy/projectile-find-file | |||||
:desc "Find in project uncached" "C-SPC" #'my/projectile-find-file-nocache) | |||||
(defun my/projectile-find-file-nocache () | |||||
(interactive) | |||||
(projectile-invalidate-cache nil) | |||||
(+ivy/projectile-find-file)) | |||||
#+END_SRC | |||||
**** Buffers | |||||
#+BEGIN_SRC elisp | |||||
(map! :leader | |||||
:desc "Switch buffer" "," #'+vertico/switch-workspace-buffer | |||||
:desc "Switch all buffers" ">" #'consult-buffer) | |||||
#+END_SRC | |||||
**** Search | |||||
#+BEGIN_SRC elisp | |||||
(map! :leader | |||||
:desc "Search online" "/" #'counsel-search) | |||||
#+END_SRC | |||||
*** b: Buffers | |||||
#+BEGIN_SRC elisp | |||||
(map! :leader | |||||
:prefix ("b" . "buffers") | |||||
:desc "Switch buffer" "b" #'consult-buffer | |||||
:desc "ibuffer" "i" #'ibuffer | |||||
:desc "Kill buffer" "d" #'kill-current-buffer | |||||
:desc "Kill all buffers" "D" #'doom/kill-all-buffers) | |||||
#+END_SRC | |||||
*** f: Files | |||||
#+BEGIN_SRC elisp | |||||
(map! :leader | |||||
:prefix ("f" . "files") | |||||
:desc "Recent files" "r" #'consult-recent-file | |||||
:desc "Find file" "f" #'counsel-find-file | |||||
:desc "Find file as root" "u" #'doom/sudo-find-file | |||||
:desc "Find package" "p" #'counsel-find-library | |||||
:desc "Copy this file" "c" #'doom/copy-this-file | |||||
:desc "Delete this file" "d" #'doom/delete-this-file | |||||
:desc "Move this file" "m" #'doom/move-this-file | |||||
:desc "Revert this file" "l" #'revert-buffer | |||||
:desc "Copy file path" "y" #'+default/yank-buffer-path | |||||
:desc "Copy project file path" "Y" #'+default/yank-buffer-path-relative-to-project | |||||
:desc "Open scratch" "x" #'doom/open-scratch-buffer) | |||||
#+END_SRC | |||||
**** s: Snippets | |||||
#+BEGIN_SRC emacs-lisp | |||||
(map! :leader | |||||
:prefix ("f s" . "snippets") | |||||
:desc "New snippet" "n" #'yas-new-snippet | |||||
:desc "Edit snippet" "e" #'yas-visit-snippet-file | |||||
:desc "Browse docs" "?" #'my/yas-browse-docs) | |||||
#+END_SRC | |||||
Add a command to open the YASnippet docs. | |||||
#+BEGIN_SRC elisp | |||||
(defun my/yas-browse-docs () | |||||
(interactive) | |||||
(browse-url "https://joaotavora.github.io/yasnippet")) | |||||
#+END_SRC | |||||
**** e: Emacs Files | |||||
#+BEGIN_SRC elisp | |||||
(map! :leader | |||||
:prefix ("f e" . "emacs") | |||||
:desc "Find in config" "f" #'doom/find-file-in-private-config | |||||
:desc "Reload config" "r" #'doom/reload | |||||
:desc "Edit config" "c" #'my/edit-config | |||||
:desc "Edit packages" "p" #'my/edit-packages | |||||
:desc "Edit env" "e" #'my/edit-env | |||||
:desc "Edit init" "i" #'my/edit-init) | |||||
#+END_SRC | |||||
#+BEGIN_SRC elisp | |||||
(defun my/edit-config () | |||||
(interactive) | |||||
(find-file (concat doom-private-dir "config.org"))) | |||||
(defun my/edit-packages () | |||||
(interactive) | |||||
(find-file (concat doom-private-dir "packages.el"))) | |||||
(defun my/edit-init () | |||||
(interactive) | |||||
(find-file (concat doom-private-dir "init.el"))) | |||||
(defun my/edit-env () | |||||
(interactive) | |||||
(find-file (concat doom-private-dir "env.el"))) | |||||
#+END_SRC | |||||
Define a derived mode for editing the literate config so we can specify some | |||||
keybindings specific to =config.org=. | |||||
#+BEGIN_SRC elisp | |||||
(define-derived-mode org-config-mode org-mode "Org config mode") | |||||
(add-to-list 'auto-mode-alist '("config\\.org" . org-config-mode)) | |||||
#+END_SRC | |||||
*** h: Help | |||||
#+BEGIN_SRC elisp | |||||
(map! :leader | |||||
:prefix ("h" . "help") | |||||
:desc "Apropos" "/" #'consult-apropos | |||||
:desc "Apropos docs" "?" #'apropos-documentation | |||||
:desc "Help at point" "p" #'helpful-at-point | |||||
:desc "Help info" "h" #'info | |||||
:desc "Help for help" "H" #'help-for-help | |||||
:desc "Describe function" "f" #'counsel-describe-function | |||||
:desc "Describe function key" "F" #'where-is | |||||
:desc "Describe variable" "v" #'counsel-describe-variable | |||||
:desc "Describe custom variable" "V" #'doom/help-custom-variable | |||||
:desc "Describe command" "x" #'helpful-command | |||||
:desc "Describe key" "k" #'describe-key-briefly | |||||
:desc "Describe key fully" "K" #'describe-key | |||||
:desc "Describe char" "'" #'describe-char | |||||
:desc "Describe coding system" "\"" #'describe-coding-system | |||||
:desc "Describe input method" "i" #'describe-input-method | |||||
:desc "Emacs manual" "e" #'info-emacs-manual | |||||
:desc "ASCII table" "a" #'my/ascii-table | |||||
:desc "View messages" "e" #'view-echo-area-messages | |||||
:desc "View keystrokes" "l" #'view-lossage) | |||||
#+END_SRC | |||||
**** a: Ascii Table | |||||
#+BEGIN_SRC elisp | |||||
(defface my/ascii-table-highlight-face | |||||
'((t (:foreground "pink"))) | |||||
"Face for highlighting ASCII chars.") | |||||
(defun my/ascii-table () | |||||
"Display basic ASCII table (0 thru 128)." | |||||
(interactive) | |||||
(pop-to-buffer "*ASCII*") | |||||
(erase-buffer) | |||||
(setq buffer-read-only nil) | |||||
(my/buffer-local-set-key "q" #'+popup/quit-window) | |||||
(setq lower32 '("nul" "soh" "stx" "etx" "eot" "enq" "ack" "bel" | |||||
"bs" "ht" "nl" "vt" "np" "cr" "so" "si" | |||||
"dle" "dc1" "dc2" "dc3" "dc4" "nak" "syn" "etb" | |||||
"can" "em" "sub" "esc" "fs" "gs" "rs" "us")) | |||||
(save-excursion (let ((i -1)) | |||||
(insert " Hex Dec Char | Hex Dec Char | Hex Dec Char | Hex Dec Char\n") | |||||
(insert " ---------------+-----------------+-----------------+----------------\n") | |||||
(while (< i 31) | |||||
(insert (format "%4x %4d %4s | %4x %4d %4s | %4x %4d %4s | %4x %4d %4s\n" | |||||
(setq i (+ 1 i)) i (elt lower32 i) | |||||
(setq i (+ 32 i)) i (single-key-description i) | |||||
(setq i (+ 32 i)) i (single-key-description i) | |||||
(setq i (+ 32 i)) i (single-key-description i))) | |||||
(overlay-put (make-overlay (- (point) 4) (- (point) 1)) 'face 'my/ascii-table-highlight-face) | |||||
(overlay-put (make-overlay (- (point) 22) (- (point) 19)) 'face 'my/ascii-table-highlight-face) | |||||
(overlay-put (make-overlay (- (point) 40) (- (point) 37)) 'face 'my/ascii-table-highlight-face) | |||||
(overlay-put (make-overlay (- (point) 58) (- (point) 55)) 'face 'my/ascii-table-highlight-face) | |||||
(setq i (- i 96)) | |||||
)))) | |||||
(set-popup-rule! "^\\*ASCII" | |||||
:side 'right | |||||
:select t | |||||
:width 70) | |||||
#+END_SRC | |||||
**** d: Doom | |||||
#+BEGIN_SRC elisp | |||||
(map! :leader | |||||
:prefix ("h d" . "doom") | |||||
:desc "Doom manual" "d" #'doom/help | |||||
:desc "Doom FAQ" "f" #'doom/help-faq | |||||
:desc "Doom modules" "m" #'doom/help-modules | |||||
:desc "Doom news" "n" #'doom/help-news | |||||
:desc "Doom help search" "/" #'doom/help-search-headings | |||||
:desc "Doom version" #'doom/version | |||||
:desc "Doom package configuration" "p" #'doom/help-package-config | |||||
:desc "Doom sandbox" "x" #'doom/sandbox) | |||||
#+END_SRC | |||||
*** p: Projects | |||||
#+BEGIN_SRC elisp | |||||
(map! :leader | |||||
:prefix ("p" . "projects") | |||||
:desc "Switch project" "p" #'counsel-projectile-switch-project | |||||
:desc "Add new project" "a" #'projectile-add-known-project | |||||
:desc "Remove project" "d" #'projectile-remove-known-project | |||||
:desc "Find in project root" "." #'counsel-projectile-find-file | |||||
:desc "Search in project" "/" #'+default/search-project | |||||
:desc "Invalidate project cache" "i" #'projectile-invalidate-cache | |||||
:desc "Run cmd in project root" "!" #'projectile-run-shell-command-in-root | |||||
:desc "Run async cmd in project root" "&" #'projectile-run-async-shell-command-in-root) | |||||
(defun my/projectile-find-in-root () | |||||
(interactive) | |||||
(counsel-find-file nil projectile-project-root)) | |||||
#+END_SRC | |||||
*** t: Toggle | |||||
#+BEGIN_SRC elisp | |||||
(map! :leader | |||||
:prefix ("t" . "toggle") | |||||
;; Wrap | |||||
:desc "Auto Wrap" "a" #'auto-fill-mode | |||||
:desc "Wrap Indicator" "c" #'global-display-fill-column-indicator-mode | |||||
:desc "Wrap Column" "C" #'set-fill-column | |||||
:desc "Line Wrap" "w" #'visual-line-mode | |||||
;; Modes | |||||
:desc "Flycheck" "f" #'flycheck-mode | |||||
;; Files | |||||
:desc "Read-only" "r" #'read-only-mode) | |||||
#+END_SRC | |||||
#+BEGIN_SRC elisp | |||||
(defun my/auto-fill-mode (cols) | |||||
(interactive)) | |||||
#+END_SRC | |||||
*** w: Window | |||||
#+BEGIN_SRC elisp | |||||
(map! :leader | |||||
:prefix-map ("w" . "window") | |||||
;; Navigation | |||||
:desc "Go..." "w" #'ace-window | |||||
:desc "Go left" "h" #'evil-window-left | |||||
:desc "Go down" "j" #'evil-window-down | |||||
:desc "Go up" "k" #'evil-window-up | |||||
:desc "Go right" "l" #'evil-window-right | |||||
:desc "Go other" "o" #'other-window | |||||
;; Layout | |||||
:desc "Rotate up" "K" #'evil-window-rotate-upwards | |||||
:desc "Rotate down" "J" #'evil-window-rotate-downwards | |||||
;; Splits | |||||
:desc "VSplit" "=" #'+evil/window-vsplit-and-follow | |||||
:desc "HSplit" "-" #'+evil/window-split-and-follow | |||||
:desc "Tear off" "t" #'tear-off-window | |||||
;; History | |||||
:desc "Undo" "u" #'winner-undo | |||||
:desc "Redo" "U" #'winner-redo | |||||
;; Misc | |||||
:desc "Resize" "r" #'my/hydra-window-resize/body | |||||
:desc "Balance" "b" #'balance-windows | |||||
;; Management | |||||
:desc "Kill window" "d" #'+workspace/close-window-or-workspace) | |||||
;; TODO: Maybe check out: | |||||
;; evil-window-mru | |||||
#+END_SRC | |||||
#+BEGIN_SRC elisp | |||||
(setq my/window-resize-step 3) | |||||
(defun my/window-increase-height () | |||||
(interactive) | |||||
(evil-window-increase-height my/window-resize-step)) | |||||
(defun my/window-decrease-height () | |||||
(interactive) | |||||
(evil-window-decrease-height my/window-resize-step)) | |||||
(defun my/window-increase-width () | |||||
(interactive) | |||||
(evil-window-increase-width my/window-resize-step)) | |||||
(defun my/window-decrease-width () | |||||
(interactive) | |||||
(evil-window-decrease-width my/window-resize-step)) | |||||
(defhydra my/hydra-window-resize () | |||||
"Resize window" | |||||
("=" my/window-increase-height "++Height") | |||||
("-" my/window-decrease-height "--Height") | |||||
("<" my/window-decrease-width "--Width") | |||||
(">" my/window-increase-width "++Width")) | |||||
#+END_SRC | |||||
** Local Leader | |||||
*** Org Config | |||||
#+BEGIN_SRC elisp | |||||
(map! :map org-config-mode-map | |||||
:localleader | |||||
:v :desc "Eval Region" "e" #'eval-region | |||||
:n :desc "Eval Source" "e" #'my/org-config-eval-source) | |||||
(defun my/org-config-eval-source () | |||||
(interactive) | |||||
(org-ctrl-c-ctrl-c) | |||||
(org-babel-remove-result)) | |||||
#+END_SRC | |||||
*** Rust | |||||
#+BEGIN_SRC elisp | |||||
(map! :map rustic-mode-map | |||||
:localleader | |||||
:desc "Debug..." "d" #'my/rust/dap-hydra/body) | |||||
(map! :map rustic-mode-map | |||||
:desc "Pluralize import" "," #'my/rust/import-pluralize | |||||
:desc "Singularize import" "<backspace>" #'my/rust/import-singularize | |||||
:desc "Singularize import" "C-<backspace>" #'my/rust/import-c-singularize) | |||||
#+END_SRC | |||||
#+BEGIN_SRC elisp | |||||
(defhydra my/rust/dap-hydra (:color pink :hint nil :foreign-keys run) | |||||
" | |||||
^Stepping^ ^Switch^ ^Breakpoints^ ^Debug^ ^Eval | |||||
^^^^^^^^---------------------------------------------------------------------------------------------------------------- | |||||
_n_: Next _ss_: Session _bb_: Toggle _dd_: Debug binary _ee_: Eval | |||||
_i_: Step in _st_: Thread _bd_: Delete _dr_: Restart debugging _es_: Eval thing at point | |||||
_o_: Step out _sf_: Stack frame _ba_: Add _ea_: Add expression | |||||
_c_: Continue _su_: Up stack frame _bc_: Set condition | |||||
_Q_: Disconnect _sd_: Down stack frame _bh_: Set hit count | |||||
_sl_: List locals _bl_: Set log message | |||||
_sb_: List breakpoints | |||||
_sS_: List sessions | |||||
" | |||||
("n" dap-next) | |||||
("i" dap-step-in) | |||||
("o" dap-step-out) | |||||
("c" dap-continue) | |||||
("r" dap-restart-frame) | |||||
("ss" dap-switch-session) | |||||
("st" dap-switch-thread) | |||||
("sf" dap-switch-stack-frame) | |||||
("su" dap-up-stack-frame) | |||||
("sd" dap-down-stack-frame) | |||||
("sl" dap-ui-locals) | |||||
("sb" dap-ui-breakpoints) | |||||
("sS" dap-ui-sessions) | |||||
("bb" dap-breakpoint-toggle) | |||||
("ba" dap-breakpoint-add) | |||||
("bd" dap-breakpoint-delete) | |||||
("bc" dap-breakpoint-condition) | |||||
("bh" dap-breakpoint-hit-condition) | |||||
("bl" dap-breakpoint-log-message) | |||||
("dd" my/rust/debug-binary) | |||||
("dr" dap-debug-restart) | |||||
("ee" dap-eval) | |||||
("ea" dap-ui-expressions-add) | |||||
("es" dap-eval-thing-at-point) | |||||
("q" nil "quit" :color blue) | |||||
("Q" dap-disconnect :color red)) | |||||
#+END_SRC | |||||
** Modes | |||||
*** Evil | |||||
**** z | |||||
#+BEGIN_SRC elisp | |||||
(map! :prefix "z" | |||||
:desc "Kill buffer" :n "x" #'kill-current-buffer | |||||
:desc "Kill window" :n "c" #'+workspace/close-window-or-workspace) | |||||
#+END_SRC | |||||
**** g | |||||
**** [ | |||||
#+BEGIN_SRC elisp | |||||
(map! :prefix "[" | |||||
:desc "Start of fn" :n "f" #'beginning-of-defun) | |||||
(map! :prefix "]" | |||||
:desc "End of fn" :n "f" #'end-of-defun) | |||||
#+END_SRC | |||||
*** Dap | |||||
#+BEGIN_SRC elisp | |||||
#+END_SRC | |||||
* Languages | |||||
** Rust | |||||
*** General | |||||
#+BEGIN_SRC elisp | |||||
(add-to-list 'projectile-globally-ignored-files "Cargo.lock") | |||||
#+END_SRC | |||||
*** Editing | |||||
#+BEGIN_SRC elisp | |||||
(defun my/rust/import-pluralize () | |||||
"Convert a singular import into a brace-wrapped plural import." | |||||
(interactive) | |||||
(if (and | |||||
(not (my/kbd!-p)) | |||||
(my/insert-mode-p) | |||||
(my/line-match-p | |||||
;; use foo::bar::baz; | |||||
(rx line-start "use " | |||||
(+ (+ word) "::") | |||||
(+ word) | |||||
(? ";") line-end))) | |||||
(kbd! "ESC vb S} f} i,") | |||||
(insert ","))) | |||||
(defun my/rust/import-singularize () | |||||
"Convert a brace-wrapped plural import into a singular import." | |||||
(interactive) | |||||
(if (and | |||||
(not (my/kbd!-p)) | |||||
(my/insert-mode-p) | |||||
(my/line-match-p | |||||
;; use foo::bar::baz::{qux::quo,}; | |||||
(rx line-start "use " | |||||
(+ (+ word) "::") | |||||
"{" (* (+ word) "::") (+ word) ",}" | |||||
(? ";") line-end))) | |||||
(kbd! "ESC l dF, ds} $i") | |||||
(evil-delete-backward-char-and-join 1))) | |||||
(defun my/rust/import-c-singularize () | |||||
"Convert a brace-wrapped plural import into a singular import." | |||||
(interactive) | |||||
(if (and | |||||
(not (my/kbd!-p)) | |||||
(my/insert-mode-p) | |||||
(my/line-match-p | |||||
;; use foo::bar::baz::{qux::quo, }; | |||||
(rx line-start | |||||
"use " | |||||
(+ (+ word) "::") | |||||
"{" (* (+ word) "::") (+ word) "," (* whitespace) "}" | |||||
(? ";") line-end))) | |||||
(kbd! "ESC l dF, ds} $i") | |||||
(backward-kill-word 1))) | |||||
#+END_SRC | |||||
*** Debugging | |||||
#+BEGIN_SRC elisp | |||||
(defun my/rust/debug-config (args) | |||||
(append | |||||
`(:type "lldb-vscode" | |||||
;; `(:type "lldb" | |||||
:request "launch" | |||||
:dap-server-path ,(list (executable-find "lldb-vscode")) | |||||
;; :dap-server-path ,(list (executable-find "rust-lldb")) | |||||
,@args))) | |||||
;; use a::TestThin | |||||
;; (:MIMode "gdb" | |||||
;; :miDebuggerPath "gdb" | |||||
;; :stopAtEntry t | |||||
;; :externalConsole | |||||
;; :json-false | |||||
;; :type "cppdbg" | |||||
;; :request "launch" | |||||
;; :name "test test2" | |||||
;; :args ["test2" "--exact" "--nocapture"] | |||||
;; :cwd "/home/lain/Code/test/rust/debug" | |||||
;; :sourceLanguages ["rust"] | |||||
;; :program "/home/lain/Code/test/rust/debug/target/debug/deps/...") | |||||
;; (require 'dap-cpptools) | |||||
(defun my/rust/debug-binary (args) | |||||
(interactive "sArgs: ") | |||||
(let* ((root (projectile-project-root)) | |||||
(name (projectile-project-name)) | |||||
(target (concat root "target/debug/" name))) | |||||
;; (rustic-cargo-build) | |||||
(dap-debug | |||||
(my/rust/debug-config | |||||
`(:program ,target | |||||
:cwd ,root | |||||
:args ,(apply #'vector (split-string-and-unquote args))))))) | |||||
(defun my/rust/debug-lsp-runnable (runnable) | |||||
"Select and debug a RUNNABLE action." | |||||
(interactive (list (lsp-rust-analyzer--select-runnable))) | |||||
(-let (((&rust-analyzer:Runnable | |||||
:args (&rust-analyzer:RunnableArgs :cargo-args :workspace-root? :executable-args) | |||||
:label) runnable)) | |||||
(pcase (aref cargo-args 0) | |||||
("run" (aset cargo-args 0 "build")) | |||||
("test" (when (-contains? (append cargo-args ()) "--no-run") | |||||
(cl-callf append cargo-args (list "--no-run"))))) | |||||
(->> (append (list (executable-find "cargo")) | |||||
cargo-args | |||||
(list "--message-format=json")) | |||||
(s-join " ") | |||||
(shell-command-to-string) | |||||
(s-lines) | |||||
(-keep (lambda (s) | |||||
(condition-case nil | |||||
(-let* ((json-object-type 'plist) | |||||
((msg &as &plist :reason :executable) (json-read-from-string s))) | |||||
(when (and executable (string= "compiler-artifact" reason)) | |||||
executable)) | |||||
(error)))) | |||||
(funcall | |||||
(lambda (artifact-spec) | |||||
(pcase artifact-spec | |||||
(`() (user-error "No compilation artifacts or obtaining the runnable artifacts failed")) | |||||
(`(,spec) spec) | |||||
(_ (user-error "Multiple compilation artifacts are not supported"))))) | |||||
(list :name label | |||||
:args executable-args | |||||
:cwd workspace-root? | |||||
;; :sourceLanguages ["rust"] | |||||
:stopAtEntry t | |||||
:stopAtEntry :json-true | |||||
:externalConsole :json-false | |||||
:program) | |||||
(my/rust/debug-config) | |||||
(dap-debug)))) | |||||
(advice-add #'lsp-rust-analyzer-debug :override #'my/rust/debug-lsp-runnable) | |||||
#+END_SRC | |||||
** Go | |||||
*** Debugging | |||||
Setup: run =M-x dap-go-setup= | |||||
* Tools | |||||
** Projectile | |||||
#+BEGIN_SRC elisp | |||||
;; (setq projectile-project-search-path | |||||
;; '("~/Code")) | |||||
#+END_SRC | |||||
** Counsel Search | |||||
#+BEGIN_SRC elisp | |||||
(let ((found (nth 0 (auth-source-search :host "kagi.com")))) | |||||
(when found | |||||
(let ((token (plist-get found :secret))) | |||||
(when (functionp token) | |||||
(setq token (funcall token))) | |||||
(add-to-list | |||||
'counsel-search-engines-alist | |||||
`(kagi | |||||
"https://duckduckgo.com/ac/" | |||||
,(format "https://kagi.com/search?token=%s&q=" token) | |||||
counsel--search-request-data-ddg)) | |||||
(setq counsel-search-engine 'kagi)))) | |||||
#+END_SRC | |||||
* Apps | |||||
** Emacs Everywhere | |||||
#+BEGIN_SRC elisp | |||||
(load! "lisp/emacs-everywhere.el") | |||||
(setq emacs-everywhere-paste-command '("xdotool" "key" "--clearmodifiers" "ctrl+v")) | |||||
(setq emacs-everywhere-frame-parameters | |||||
'((title . "Emacs Everywhere") | |||||
(width . 120) | |||||
(height . 36))) | |||||
#+END_SRC | |||||
* Lisp | |||||
** Editing | |||||
#+BEGIN_SRC elisp | |||||
(defun my/line () | |||||
(buffer-substring-no-properties | |||||
(line-beginning-position) | |||||
(line-end-position))) | |||||
(defun my/line-match-p (regexp) | |||||
(string-match-p regexp (my/line))) | |||||
#+END_SRC | |||||
#+BEGIN_SRC elisp | |||||
(defun my/insert-mode-p () | |||||
(eq evil-state 'insert)) | |||||
(defun my/normal-mode-p () | |||||
(eq evil-state 'normal)) | |||||
#+END_SRC | |||||
** Keybindings | |||||
#+BEGIN_SRC elisp | |||||
(defun my/kbd-replace (str) | |||||
"Convert STR into a keyboard macro string by replacing terminal key sequences with GUI keycodes." | |||||
(let ((kbd-regex '(("ESC" . "<escape>") | |||||
("DEL" . "<delete>" ) | |||||
("BS" . "<backspace>") | |||||
("RET" . "<return>") | |||||
("SPC" . "<SPC>") | |||||
("TAB" . "<tab>")))) | |||||
(my/replace-regexps-in-string str kbd-regex))) | |||||
(setq my//kbd-p nil) | |||||
(defun my/kbd!-p () (eq my//kbd-p t)) | |||||
(defun kbd! (str) | |||||
"Execute the key sequence defined by STR like a VIM macro." | |||||
(let ((minibuffer-message-timeout 0)) | |||||
(setq my//kbd-p t) | |||||
(execute-kbd-macro (read-kbd-macro (my/kbd-replace str))) | |||||
(setq my//kbd-p nil))) | |||||
#+END_SRC | |||||
#+BEGIN_SRC elisp | |||||
(defun my/buffer-local-set-key (key fn) | |||||
(let ((mode (intern (format "%s-local-mode" (buffer-name)))) | |||||
(map (intern (format "%s-local-mode-map" (buffer-name))))) | |||||
(unless (boundp map) | |||||
(set map (make-sparse-keymap)) | |||||
(evil-make-overriding-map map 'normal)) | |||||
(eval | |||||
`(define-minor-mode ,mode | |||||
"A minor mode for buffer-local keybinds." | |||||
:keymap ,map)) | |||||
(eval | |||||
`(define-key ,map ,key #',fn)) | |||||
(funcall mode t))) | |||||
#+END_SRC | |||||
** Regex | |||||
#+BEGIN_SRC elisp | |||||
(defun my/replace-regexps-in-string (str regexps) | |||||
"Replace all pairs of (regex . replacement) defined by REGEXPS in STR." | |||||
(if (null regexps) | |||||
str | |||||
(my/replace-regexps-in-string | |||||
(replace-regexp-in-string (caar regexps) (cdar regexps) str t) | |||||
(cdr regexps)))) | |||||
#+END_SRC |
@@ -0,0 +1,2 @@ | |||||
("DISPLAY=:0" | |||||
"SSH_AUTH_SOCK=/run/user/1000/gnupg/S.gpg-agent.ssh") |
@@ -0,0 +1,189 @@ | |||||
;;; init.el -*- lexical-binding: t; -*- | |||||
;; This file controls what Doom modules are enabled and what order they load | |||||
;; in. Remember to run 'doom sync' after modifying it! | |||||
;; NOTE Press 'SPC h d h' (or 'C-h d h' for non-vim users) to access Doom's | |||||
;; documentation. There you'll find a "Module Index" link where you'll find | |||||
;; a comprehensive list of Doom's modules and what flags they support. | |||||
;; NOTE Move your cursor over a module's name (or its flags) and press 'K' (or | |||||
;; 'C-c c k' for non-vim users) to view its documentation. This works on | |||||
;; flags as well (those symbols that start with a plus). | |||||
;; | |||||
;; Alternatively, press 'gd' (or 'C-c c d') on a module to browse its | |||||
;; directory (for easy access to its source code). | |||||
(doom! :input | |||||
;;chinese | |||||
;;japanese | |||||
;;layout ; auie,ctsrnm is the superior home row | |||||
:completion | |||||
company ; the ultimate code completion backend | |||||
;;helm ; the *other* search engine for love and life | |||||
;;ido ; the other *other* search engine... | |||||
(ivy +prescient +icons) ; a search engine for love and life | |||||
vertico ; the search engine of the future | |||||
:ui | |||||
;;deft ; notational velocity for Emacs | |||||
doom ; what makes DOOM look the way it does | |||||
doom-dashboard ; a nifty splash screen for Emacs | |||||
doom-quit ; DOOM quit-message prompts when you quit Emacs | |||||
(emoji +unicode) ; 🙂 | |||||
hl-todo ; highlight TODO/FIXME/NOTE/DEPRECATED/HACK/REVIEW | |||||
hydra | |||||
;;indent-guides ; highlighted indent columns | |||||
;;ligatures ; ligatures and symbols to make your code pretty again | |||||
;;minimap ; show a map of the code on the side | |||||
modeline ; snazzy, Atom-inspired modeline, plus API | |||||
;;nav-flash ; blink cursor line after big motions | |||||
;;neotree ; a project drawer, like NERDTree for vim | |||||
ophints ; highlight the region an operation acts on | |||||
(popup +defaults) ; tame sudden yet inevitable temporary windows | |||||
;;tabs ; a tab bar for Emacs | |||||
(treemacs +lsp) ; a project drawer, like neotree but cooler | |||||
;;unicode ; extended unicode support for various languages | |||||
vc-gutter ; vcs diff in the fringe | |||||
vi-tilde-fringe ; fringe tildes to mark beyond EOB | |||||
;;window-select ; visually switch windows | |||||
workspaces ; tab emulation, persistence & separate workspaces | |||||
;;zen ; distraction-free coding or writing | |||||
:editor | |||||
(evil +everywhere); come to the dark side, we have cookies | |||||
;;file-templates ; auto-snippets for empty files | |||||
fold ; (nigh) universal code folding | |||||
format ; (+onsave) automated prettiness | |||||
;;god ; run Emacs commands without modifier keys | |||||
lispy ; vim for lisp, for people who don't like vim | |||||
multiple-cursors ; editing in many places at once | |||||
;;objed ; text object editing for the innocent | |||||
;;parinfer ; turn lisp into python, sort of | |||||
;;rotate-text ; cycle region at point between text candidates | |||||
snippets ; my elves. They type so I don't have to | |||||
;;word-wrap ; soft wrapping with language-aware indent | |||||
:emacs | |||||
dired ; making dired pretty [functional] | |||||
electric ; smarter, keyword-based electric-indent | |||||
;;ibuffer ; interactive buffer management | |||||
undo ; persistent, smarter undo for your inevitable mistakes | |||||
vc ; version-control and Emacs, sitting in a tree | |||||
:term | |||||
eshell ; the elisp shell that works everywhere | |||||
;;shell ; simple shell REPL for Emacs | |||||
;;term ; basic terminal emulator for Emacs | |||||
;;vterm ; the best terminal emulation in Emacs | |||||
:checkers | |||||
syntax ; tasing you for every semicolon you forget | |||||
;;(spell +flyspell) ; tasing you for misspelling mispelling | |||||
;;grammar ; tasing grammar mistake every you make | |||||
:tools | |||||
;;ansible | |||||
(debugger +lsp) ; FIXME stepping through code, to help you add bugs | |||||
;;direnv | |||||
docker | |||||
editorconfig ; let someone else argue about tabs vs spaces | |||||
;;ein ; tame Jupyter notebooks with emacs | |||||
(eval +overlay) ; run code, run (also, repls) | |||||
;;gist ; interacting with github gists | |||||
lookup ; navigate your code and its documentation | |||||
lsp ; M-x vscode | |||||
(magit +forge) ; a git porcelain for Emacs | |||||
make ; run make tasks from Emacs | |||||
;;pass ; password manager for nerds | |||||
pdf ; pdf enhancements | |||||
;;prodigy ; FIXME managing external services & code builders | |||||
;;rgb ; creating color strings | |||||
taskrunner ; taskrunner for all your projects | |||||
terraform ; infrastructure as code | |||||
tmux ; an API for interacting with tmux | |||||
;;upload ; map local to remote projects via ssh/ftp | |||||
:os | |||||
(:if IS-MAC macos) ; improve compatibility with macOS | |||||
;;tty ; improve the terminal Emacs experience | |||||
:lang | |||||
;;agda ; types of types of types of types... | |||||
;;beancount ; mind the GAAP | |||||
(cc +lsp) ; C > C++ == 1 | |||||
;;clojure ; java with a lisp | |||||
;;common-lisp ; if you've seen one lisp, you've seen them all | |||||
;;coq ; proofs-as-programs | |||||
;;crystal ; ruby at the speed of c | |||||
;;csharp ; unity, .NET, and mono shenanigans | |||||
;;data ; config/data formats | |||||
;;(dart +flutter) ; paint ui and not much else | |||||
;;dhall | |||||
elixir ; erlang done right | |||||
;;elm ; care for a cup of TEA? | |||||
emacs-lisp ; drown in parentheses | |||||
;;erlang ; an elegant language for a more civilized age | |||||
;;ess ; emacs speaks statistics | |||||
;;factor | |||||
;;faust ; dsp, but you get to keep your soul | |||||
;;fsharp ; ML stands for Microsoft's Language | |||||
;;fstar ; (dependent) types and (monadic) effects and Z3 | |||||
;;gdscript ; the language you waited for | |||||
(go +lsp) ; the hipster dialect | |||||
(haskell +lsp) ; a language that's lazier than I am | |||||
;;hy ; readability of scheme w/ speed of python | |||||
;;idris ; a language you can depend on | |||||
json ; At least it ain't XML | |||||
(java +meghanada) ; the poster child for carpal tunnel syndrome | |||||
javascript ; all(hope(abandon(ye(who(enter(here)))))) | |||||
julia ; a better, faster MATLAB | |||||
;;kotlin ; a better, slicker Java(Script) | |||||
latex ; writing papers in Emacs has never been so fun | |||||
;;lean ; for folks with too much to prove | |||||
;;ledger ; be audit you can be | |||||
lua ; one-based indices? one-based indices | |||||
markdown ; writing docs for people to ignore | |||||
;;nim ; python + lisp at the speed of c | |||||
;;nix ; I hereby declare "nix geht mehr!" | |||||
;;ocaml ; an objective camel | |||||
org ; organize your plain life in plain text | |||||
php ; perl's insecure younger brother | |||||
;;plantuml ; diagrams for confusing people more | |||||
;;purescript ; javascript, but functional | |||||
(python +lsp +pyright) ; beautiful is better than ugly | |||||
;;qt ; the 'cutest' gui framework ever | |||||
;;racket ; a DSL for DSLs | |||||
;;raku ; the artist formerly known as perl6 | |||||
;;rest ; Emacs as a REST client | |||||
;;rst ; ReST in peace | |||||
;;(ruby +rails) ; 1.step {|i| p "Ruby is #{i.even? ? 'love' : 'life'}"} | |||||
(rust +lsp) ; Fe2O3.unwrap().unwrap().unwrap().unwrap() | |||||
;;scala ; java, but good | |||||
(scheme +guile) ; a fully conniving family of lisps | |||||
(sh +fish) ; she sells {ba,z,fi}sh shells on the C xor | |||||
;;sml | |||||
;;solidity ; do you need a blockchain? No. | |||||
;;swift ; who asked for emoji variables? | |||||
;;terra ; Earth and Moon in alignment for performance. | |||||
web ; the tubes | |||||
yaml ; JSON, but readable | |||||
;;zig ; C, but simpler | |||||
;;(mu4e +org +gmail) | |||||
;;notmuch | |||||
;;(wanderlust +gmail) | |||||
:app | |||||
calendar | |||||
;;emms | |||||
everywhere ; *leave* Emacs!? You must be joking | |||||
irc ; how neckbeards socialize | |||||
;;(rss +org) ; emacs as an RSS reader | |||||
;;twitter ; twitter client https://twitter.com/vnought | |||||
:config | |||||
literate | |||||
(default +bindings +smartparens)) |
@@ -0,0 +1,546 @@ | |||||
;;; emacs-everywhere.el --- System-wide popup windows for quick edits -*- lexical-binding: t; -*- | |||||
;; Copyright (C) 2021 TEC | |||||
;; Author: TEC <https://github.com/tecosaur> | |||||
;; Maintainer: TEC <tec@tecosaur.com> | |||||
;; Created: February 06, 2021 | |||||
;; Modified: February 06, 2021 | |||||
;; Version: 0.1.0 | |||||
;; Keywords: conenience, frames | |||||
;; Homepage: https://github.com/tecosaur/emacs-everywhere | |||||
;; Package-Requires: ((emacs "26.3")) | |||||
;;; License: | |||||
;; This file is part of org-pandoc-import, which is not part of GNU Emacs. | |||||
;; SPDX-License-Identifier: GPL-3.0-or-later | |||||
;;; Commentary: | |||||
;; System-wide popup Emacs windows for quick edits | |||||
;;; Code: | |||||
(require 'cl-lib) | |||||
(require 'server) | |||||
(defgroup emacs-everywhere () | |||||
"Customise group for Emacs-everywhere." | |||||
:group 'convenience) | |||||
(define-obsolete-variable-alias | |||||
'emacs-everywhere-paste-p 'emacs-everywhere-paste-command "0.1.0") | |||||
(defvar emacs-everywhere--display-server | |||||
(cond | |||||
((eq system-type 'darwin) 'quartz) | |||||
((memq system-type '(ms-dos windows-nt cygwin)) 'windows) | |||||
((executable-find "loginctl") | |||||
(pcase (string-trim | |||||
(shell-command-to-string "loginctl show-session $(loginctl | grep $(whoami) | awk '{print $1}') -p Type") | |||||
"Type=" "\n") | |||||
("x11" 'x11) | |||||
("wayland" 'wayland) | |||||
(_ 'unknown))) | |||||
(t 'unknown)) | |||||
"The detected display server.") | |||||
(defcustom emacs-everywhere-paste-command | |||||
(pcase emacs-everywhere--display-server | |||||
('quartz (list "osascript" "-e" "tell application \"System Events\" to keystroke \"v\" using command down")) | |||||
('x11 (list "xdotool" "key" "--clearmodifiers" "Shift+Insert")) | |||||
((or 'wayland 'unknown) | |||||
(list "notify-send" | |||||
"No paste command defined for emacs-everywhere" | |||||
"-a" "Emacs" "-i" "emacs"))) | |||||
"Command to trigger a system paste from the clipboard. | |||||
This is given as a list in the form (CMD ARGS...). | |||||
To not run any command, set to nil." | |||||
:type '(set (repeat string) (const nil)) | |||||
:group 'emacs-everywhere) | |||||
(defcustom emacs-everywhere-copy-command | |||||
(pcase emacs-everywhere--display-server | |||||
('x11 (list "xclip" "-selection" "clipboard" "%f")) | |||||
((and 'wayland (guard (executable-find "wl-copy"))) | |||||
(list "sh" "-c" "wl-copy < %f"))) | |||||
"Command to write to the system clipboard from a file (%f). | |||||
This is given as a list in the form (CMD ARGS...). | |||||
In the arguments, \"%f\" is treated as a placeholder for the path | |||||
to the file. | |||||
When nil, nothing is executed. | |||||
`gui-select-text' is always called on the buffer content, however experience | |||||
suggests that this can be somewhat flakey, and so an extra step to make sure | |||||
it worked can be a good idea." | |||||
:type '(set (repeat string) (const nil)) | |||||
:group 'emacs-everywhere) | |||||
(defcustom emacs-everywhere-window-focus-command | |||||
(pcase emacs-everywhere--display-server | |||||
('quartz (list "osascript" "-e" "tell application \"%w\" to activate")) | |||||
('x11 (list "xdotool" "windowactivate" "--sync" "%w"))) | |||||
"Command to refocus the active window when emacs-everywhere was triggered. | |||||
This is given as a list in the form (CMD ARGS...). | |||||
In the arguments, \"%w\" is treated as a placeholder for the window ID, | |||||
as returned by `emacs-everywhere-app-id'. | |||||
When nil, nothing is executed, and pasting is not attempted." | |||||
:type '(set (repeat string) (const nil)) | |||||
:group 'emacs-everywhere) | |||||
(defcustom emacs-everywhere-markdown-windows | |||||
'("Reddit" "Stack Exchange" "Stack Overflow" ; Sites | |||||
"Discord" "Element" "Slack" "HedgeDoc" "HackMD" "Zulip" ; Web Apps | |||||
"Pull Request" "Issue" "Comparing .*\\.\\.\\.") ; Github | |||||
"For use with `emacs-everywhere-markdown-p'. | |||||
Patterns which are matched against the window title." | |||||
:type '(rep string) | |||||
:group 'emacs-everywhere) | |||||
(defcustom emacs-everywhere-markdown-apps | |||||
'("Discord" "Element" "Fractal" "NeoChat" "Slack") | |||||
"For use with `emacs-everywhere-markdown-p'. | |||||
Patterns which are matched against the app name." | |||||
:type '(rep string) | |||||
:group 'emacs-everywhere) | |||||
(defcustom emacs-everywhere-frame-name-format "Emacs Everywhere :: %s — %s" | |||||
"Format string used to produce the frame name. | |||||
Formatted with the app name, and truncated window name." | |||||
:type 'string | |||||
:group 'emacs-everywhere) | |||||
(defcustom emacs-everywhere-init-hooks | |||||
`(emacs-everywhere-set-frame-name | |||||
emacs-everywhere-set-frame-position | |||||
,(cond | |||||
((executable-find "pandoc") #'org-mode) | |||||
((fboundp 'markdown-mode) #'emacs-everywhere-major-mode-org-or-markdown) | |||||
(t #'text-mode)) | |||||
emacs-everywhere-insert-selection | |||||
emacs-everywhere-remove-trailing-whitespace | |||||
emacs-everywhere-init-spell-check) | |||||
"Hooks to be run before function `emacs-everywhere-mode'." | |||||
:type 'hook | |||||
:group 'emacs-everywhere) | |||||
(defcustom emacs-everywhere-final-hooks | |||||
'(emacs-everywhere-remove-trailing-whitespace | |||||
emacs-everywhere-return-converted-org-to-gfm) | |||||
"Hooks to be run just before content is copied." | |||||
:type 'hook | |||||
:group 'emacs-everywhere) | |||||
(defcustom emacs-everywhere-frame-parameters | |||||
`((name . "emacs-everywhere") | |||||
(width . 80) | |||||
(height . 12)) | |||||
"Parameters `make-frame' recognises to apply to the emacs-everywhere frame." | |||||
:type 'list | |||||
:group 'emacs-everywhere) | |||||
(defcustom emacs-everywhere-file-dir | |||||
temporary-file-directory | |||||
"The default directory for temp files generated by `emacs-everywhere-filename-function'." | |||||
:type 'string | |||||
:group 'emacs-everywhere) | |||||
(defcustom emacs-everywhere-file-patterns | |||||
(let ((default-directory emacs-everywhere-file-dir)) | |||||
(list (concat "^" (regexp-quote (file-truename "emacs-everywhere-"))) | |||||
;; For qutebrowser 'editor.command' support | |||||
(concat "^" (regexp-quote (file-truename "qutebrowser-editor-"))))) | |||||
"A list of file regexps to activate `emacs-everywhere-mode' for." | |||||
:type '(repeat regexp) | |||||
:group 'emacs-everywhere) | |||||
(defun emacs-everywhere-temp-filename (app-info) | |||||
"Generate a temp file." | |||||
(concat "emacs-everywhere-" | |||||
(format-time-string "%Y%m%d-%H%M%S-" (current-time)) | |||||
(emacs-everywhere-app-class app-info))) | |||||
(defcustom emacs-everywhere-filename-function | |||||
#'emacs-everywhere-temp-filename | |||||
"A function which generates a file name for the buffer. | |||||
The function is passed the result of `emacs-everywhere-app-info'. | |||||
Make sure that it will be matched by `emacs-everywhere-file-patterns'." | |||||
:type 'function | |||||
:group 'emacs-everywhere) | |||||
;; Semi-internal variables | |||||
(defconst emacs-everywhere-osascript-accessibility-error-message | |||||
"osascript is not allowed assistive access" | |||||
"String to search for to determine if Emacs does not have accessibility rights.") | |||||
(defvar-local emacs-everywhere-current-app nil | |||||
"The current `emacs-everywhere-app'") | |||||
;; Prevents buffer-local variable from being unset by major mode changes | |||||
(put 'emacs-everywhere-current-app 'permanent-local t) | |||||
(defvar-local emacs-everywhere--contents nil) | |||||
;; Make the byte-compiler happier | |||||
(declare-function org-in-src-block-p "org") | |||||
(declare-function org-ctrl-c-ctrl-c "org") | |||||
(declare-function org-export-to-buffer "ox") | |||||
(declare-function evil-insert-state "evil-states") | |||||
(declare-function spell-fu-buffer "spell-fu") | |||||
(declare-function markdown-mode "markdown-mode") | |||||
;;; Primary functionality | |||||
;;;###autoload | |||||
(defun emacs-everywhere (&optional file line column) | |||||
"Lanuch the emacs-everywhere frame from emacsclient." | |||||
(let ((app-info (emacs-everywhere-app-info))) | |||||
(apply #'call-process "emacsclient" nil 0 nil | |||||
(delq | |||||
nil (list | |||||
(when (server-running-p) | |||||
(if server-use-tcp | |||||
(concat "--server-file=" | |||||
(shell-quote-argument | |||||
(expand-file-name server-name server-auth-dir))) | |||||
(concat "--socket-name=" | |||||
(shell-quote-argument | |||||
(expand-file-name server-name server-socket-dir))))) | |||||
"-c" "-F" | |||||
(prin1-to-string | |||||
(cons (cons 'emacs-everywhere-app app-info) | |||||
emacs-everywhere-frame-parameters)) | |||||
(cond ((and line column) (format "+%d:%d" line column)) | |||||
(line (format "+%d" line))) | |||||
(or file | |||||
(expand-file-name | |||||
(funcall emacs-everywhere-filename-function app-info) | |||||
emacs-everywhere-file-dir))))))) | |||||
(defun emacs-everywhere-file-p (file) | |||||
"Return non-nil if FILE should be handled by emacs-everywhere. | |||||
This matches FILE against `emacs-everywhere-file-patterns'." | |||||
(let ((file (file-truename file))) | |||||
(cl-some (lambda (pattern) (string-match-p pattern file)) | |||||
emacs-everywhere-file-patterns))) | |||||
;;;###autoload | |||||
(defun emacs-everywhere-initialise () | |||||
"Entry point for the executable. | |||||
APP is an `emacs-everywhere-app' struct." | |||||
(let ((file (buffer-file-name (buffer-base-buffer)))) | |||||
(when (and file (emacs-everywhere-file-p file)) | |||||
(let ((app (or (frame-parameter nil 'emacs-everywhere-app) | |||||
(emacs-everywhere-app-info)))) | |||||
(setq-local emacs-everywhere-current-app app) | |||||
(with-demoted-errors "Emacs Everywhere: error running init hooks, %s" | |||||
(run-hooks 'emacs-everywhere-init-hooks)) | |||||
(emacs-everywhere-mode 1) | |||||
(setq emacs-everywhere--contents (buffer-string)))))) | |||||
;;;###autoload | |||||
(add-hook 'server-visit-hook #'emacs-everywhere-initialise) | |||||
(add-hook 'server-done-hook #'emacs-everywhere-finish) | |||||
(defvar emacs-everywhere-mode-initial-map | |||||
(let ((keymap (make-sparse-keymap))) | |||||
(define-key keymap (kbd "DEL") #'emacs-everywhere-erase-buffer) | |||||
(define-key keymap (kbd "C-SPC") #'emacs-everywhere-erase-buffer) | |||||
keymap) | |||||
"Transient keymap invoked when an emacs-everywhere buffer is first created. | |||||
Set to `nil' to prevent this transient map from activating in emacs-everywhere | |||||
buffers.") | |||||
(define-minor-mode emacs-everywhere-mode | |||||
"Tweak the current buffer to add some emacs-everywhere considerations." | |||||
:init-value nil | |||||
:keymap `((,(kbd "C-c C-c") . emacs-everywhere-finish-or-ctrl-c-ctrl-c) | |||||
(,(kbd "C-x 5 0") . emacs-everywhere-finish) | |||||
(,(kbd "C-c C-k") . emacs-everywhere-abort)) | |||||
;; line breaking | |||||
(turn-off-auto-fill) | |||||
(visual-line-mode t) | |||||
;; DEL/C-SPC to clear (first keystroke only) | |||||
(when (keymapp emacs-everywhere-mode-initial-map) | |||||
(set-transient-map emacs-everywhere-mode-initial-map))) | |||||
(defun emacs-everywhere-erase-buffer () | |||||
"Delete the contents of the current buffer." | |||||
(interactive) | |||||
(delete-region (point-min) (point-max))) | |||||
(defun emacs-everywhere-finish-or-ctrl-c-ctrl-c () | |||||
"Finish emacs-everywhere session or invoke `org-ctrl-c-ctrl-c' in org-mode." | |||||
(interactive) | |||||
(if (and (eq major-mode 'org-mode) | |||||
(org-in-src-block-p)) | |||||
(org-ctrl-c-ctrl-c) | |||||
(emacs-everywhere-finish))) | |||||
(defun emacs-everywhere-finish (&optional abort) | |||||
"Copy buffer content, close emacs-everywhere window, and maybe paste. | |||||
Must only be called within a emacs-everywhere buffer. | |||||
Never paste content when ABORT is non-nil." | |||||
(interactive) | |||||
(when emacs-everywhere-mode | |||||
(when (equal emacs-everywhere--contents (buffer-string)) | |||||
(setq abort t)) | |||||
(unless abort | |||||
(run-hooks 'emacs-everywhere-final-hooks) | |||||
(gui-select-text (buffer-string)) | |||||
(when emacs-everywhere-copy-command ; handle clipboard finicklyness | |||||
(let ((inhibit-message t) | |||||
(require-final-newline nil) | |||||
write-file-functions) | |||||
(write-file buffer-file-name) | |||||
(apply #'call-process (car emacs-everywhere-copy-command) | |||||
nil nil nil | |||||
(mapcar (lambda (arg) | |||||
(replace-regexp-in-string "%f" buffer-file-name arg)) | |||||
(cdr emacs-everywhere-copy-command)))))) | |||||
(sleep-for 0.01) ; prevents weird multi-second pause, lets clipboard info propagate | |||||
(when emacs-everywhere-window-focus-command | |||||
(let* ((window-id (emacs-everywhere-app-id emacs-everywhere-current-app)) | |||||
(window-id-str (if (numberp window-id) (number-to-string window-id) window-id))) | |||||
(apply #'call-process (car emacs-everywhere-window-focus-command) | |||||
nil nil nil | |||||
(mapcar (lambda (arg) | |||||
(replace-regexp-in-string "%w" window-id-str arg)) | |||||
(cdr emacs-everywhere-window-focus-command))) | |||||
;; The frame only has this parameter if this package initialized the temp | |||||
;; file its displaying. Otherwise, it was created by another program, likely | |||||
;; a browser with direct EDITOR support, like qutebrowser. | |||||
(when (and (frame-parameter nil 'emacs-everywhere-app) | |||||
emacs-everywhere-paste-command | |||||
(not abort)) | |||||
(apply #'call-process (car emacs-everywhere-paste-command) | |||||
nil nil nil (cdr emacs-everywhere-paste-command))))) | |||||
;; Clean up after ourselves in case the buffer survives `server-buffer-done' | |||||
;; (b/c `server-existing-buffer' is non-nil). | |||||
(emacs-everywhere-mode -1) | |||||
(server-buffer-done (current-buffer)))) | |||||
(defun emacs-everywhere-abort () | |||||
"Abort current emacs-everywhere session." | |||||
(interactive) | |||||
(set-buffer-modified-p nil) | |||||
(emacs-everywhere-finish t)) | |||||
;;; Window info | |||||
(cl-defstruct emacs-everywhere-app | |||||
"Metadata about the last focused window before emacs-everywhere was invoked." | |||||
id class title geometry) | |||||
(defun emacs-everywhere-app-info () | |||||
"Return information on the active window." | |||||
(let ((w (pcase system-type | |||||
(`darwin (emacs-everywhere-app-info-osx)) | |||||
(_ (emacs-everywhere-app-info-linux))))) | |||||
(setf (emacs-everywhere-app-title w) | |||||
(replace-regexp-in-string | |||||
(format " ?-[A-Za-z0-9 ]*%s" | |||||
(regexp-quote (emacs-everywhere-app-class w))) | |||||
"" | |||||
(replace-regexp-in-string | |||||
"[^[:ascii:]]+" "-" (emacs-everywhere-app-title w)))) | |||||
w)) | |||||
(defun emacs-everywhere-call (command &rest args) | |||||
"Execute COMMAND with ARGS synchronously." | |||||
(with-temp-buffer | |||||
(apply #'call-process command nil t nil (remq nil args)) | |||||
(when (and (eq system-type 'darwin) | |||||
(string-match-p emacs-everywhere-osascript-accessibility-error-message (buffer-string))) | |||||
(call-process "osascript" nil nil nil | |||||
"-e" (format "display alert \"emacs-everywhere\" message \"Emacs has not been granted accessibility permissions, cannot run emacs-everywhere! | |||||
Please go to 'System Preferences > Security & Privacy > Privacy > Accessibility' and allow Emacs.\"" )) | |||||
(error "MacOS accessibility error, aborting.")) | |||||
(string-trim (buffer-string)))) | |||||
(defun emacs-everywhere-app-info-linux () | |||||
"Return information on the active window, on linux." | |||||
(let ((window-id (emacs-everywhere-call "xdotool" "getactivewindow"))) | |||||
(let ((app-name | |||||
(car (split-string-and-unquote | |||||
(string-trim-left | |||||
(emacs-everywhere-call "xprop" "-id" window-id "WM_CLASS") | |||||
"[^ ]+ = \"[^\"]+\", ")))) | |||||
(window-title | |||||
(car (split-string-and-unquote | |||||
(string-trim-left | |||||
(emacs-everywhere-call "xprop" "-id" window-id "_NET_WM_NAME") | |||||
"[^ ]+ = ")))) | |||||
(window-geometry | |||||
(let ((info (mapcar (lambda (line) | |||||
(split-string line ":" nil "[ \t]+")) | |||||
(split-string | |||||
(emacs-everywhere-call "xwininfo" "-id" window-id) "\n")))) | |||||
(mapcar #'string-to-number | |||||
(list (cadr (assoc "Absolute upper-left X" info)) | |||||
(cadr (assoc "Absolute upper-left Y" info)) | |||||
(cadr (assoc "Relative upper-left X" info)) | |||||
(cadr (assoc "Relative upper-left Y" info)) | |||||
(cadr (assoc "Width" info)) | |||||
(cadr (assoc "Height" info))))))) | |||||
(make-emacs-everywhere-app | |||||
:id (string-to-number window-id) | |||||
:class app-name | |||||
:title window-title | |||||
:geometry (list | |||||
(if (= (nth 0 window-geometry) (nth 2 window-geometry)) | |||||
(nth 0 window-geometry) | |||||
(- (nth 0 window-geometry) (nth 2 window-geometry))) | |||||
(if (= (nth 1 window-geometry) (nth 3 window-geometry)) | |||||
(nth 1 window-geometry) | |||||
(- (nth 1 window-geometry) (nth 3 window-geometry))) | |||||
(nth 4 window-geometry) | |||||
(nth 5 window-geometry)))))) | |||||
(defvar emacs-everywhere--dir (file-name-directory load-file-name)) | |||||
(defun emacs-everywhere-app-info-osx () | |||||
"Return information on the active window, on osx." | |||||
(emacs-everywhere-ensure-oscascript-compiled) | |||||
(let ((default-directory emacs-everywhere--dir)) | |||||
(let ((app-name (emacs-everywhere-call | |||||
"osascript" "app-name")) | |||||
(window-title (emacs-everywhere-call | |||||
"osascript" "window-title")) | |||||
(window-geometry (mapcar #'string-to-number | |||||
(split-string | |||||
(emacs-everywhere-call | |||||
"osascript" "window-geometry") ", ")))) | |||||
(make-emacs-everywhere-app | |||||
:id app-name | |||||
:class app-name | |||||
:title window-title | |||||
:geometry window-geometry)))) | |||||
(defun emacs-everywhere-ensure-oscascript-compiled (&optional force) | |||||
"Ensure that compiled oscascript files are present. | |||||
Will always compile when FORCE is non-nil." | |||||
(unless (and (file-exists-p "app-name") | |||||
(file-exists-p "window-geometry") | |||||
(file-exists-p "window-title") | |||||
(not force)) | |||||
(let ((default-directory emacs-everywhere--dir) | |||||
(app-name | |||||
"tell application \"System Events\" | |||||
set frontAppName to name of first application process whose frontmost is true | |||||
end tell | |||||
return frontAppName") | |||||
(window-geometry | |||||
"tell application \"System Events\" | |||||
set frontWindow to front window of (first application process whose frontmost is true) | |||||
set windowPosition to (get position of frontWindow) | |||||
set windowSize to (get size of frontWindow) | |||||
end tell | |||||
return windowPosition & windowSize") | |||||
(window-title | |||||
"set windowTitle to \"\" | |||||
tell application \"System Events\" | |||||
set frontAppProcess to first application process whose frontmost is true | |||||
end tell | |||||
tell frontAppProcess | |||||
if count of windows > 0 then | |||||
set windowTitle to name of front window | |||||
end if | |||||
end tell | |||||
return windowTitle")) | |||||
(dolist (script `(("app-name" . ,app-name) | |||||
("window-geometry" . ,window-geometry) | |||||
("window-title" . ,window-title))) | |||||
(write-region (cdr script) nil (concat (car script) ".applescript")) | |||||
(shell-command (format "osacompile -r scpt:128 -t osas -o %s %s" | |||||
(car script) (concat (car script) ".applescript"))))))) | |||||
;;; Secondary functionality | |||||
(defun emacs-everywhere-set-frame-name () | |||||
"Set the frame name based on `emacs-everywhere-frame-name-format'." | |||||
(set-frame-name | |||||
(format emacs-everywhere-frame-name-format | |||||
(emacs-everywhere-app-class emacs-everywhere-current-app) | |||||
(truncate-string-to-width | |||||
(emacs-everywhere-app-title emacs-everywhere-current-app) | |||||
45 nil nil "…")))) | |||||
(defun emacs-everywhere-remove-trailing-whitespace () | |||||
"Move point to the end of the buffer, and remove all trailing whitespace." | |||||
(goto-char (max-char)) | |||||
(delete-trailing-whitespace) | |||||
(delete-char (- (skip-chars-backward "\n")))) | |||||
(defun emacs-everywhere-set-frame-position () | |||||
"Set the size and position of the emacs-everywhere frame." | |||||
(cl-destructuring-bind (x . y) (mouse-absolute-pixel-position) | |||||
(set-frame-position (selected-frame) | |||||
(- x 100) | |||||
(- y 50)))) | |||||
(defun emacs-everywhere-insert-selection () | |||||
"Insert the last text selection into the buffer." | |||||
(if (eq system-type 'darwin) | |||||
(progn | |||||
(call-process "osascript" nil nil nil | |||||
"-e" "tell application \"System Events\" to keystroke \"c\" using command down") | |||||
(sleep-for 0.01) ; lets clipboard info propagate | |||||
(yank)) | |||||
(when-let ((selection (gui-get-selection 'PRIMARY 'UTF8_STRING))) | |||||
(gui-backend-set-selection 'PRIMARY "") | |||||
(insert selection))) | |||||
(when (and (eq major-mode 'org-mode) | |||||
(emacs-everywhere-markdown-p) | |||||
(executable-find "pandoc")) | |||||
(shell-command-on-region (point-min) (point-max) | |||||
"pandoc -f markdown-auto_identifiers -t org" nil t) | |||||
(deactivate-mark) (goto-char (point-max))) | |||||
(cond ((bound-and-true-p evil-local-mode) (evil-insert-state)))) | |||||
(defun emacs-everywhere-init-spell-check () | |||||
"Run a spell check function on the buffer, using a relevant enabled mode." | |||||
(cond ((bound-and-true-p spell-fu-mode) (spell-fu-buffer)) | |||||
((bound-and-true-p flyspell-mode) (flyspell-buffer)))) | |||||
(defun emacs-everywhere-markdown-p () | |||||
"Return t if the original window is recognised as markdown-flavoured." | |||||
(let ((title (emacs-everywhere-app-title emacs-everywhere-current-app)) | |||||
(class (emacs-everywhere-app-class emacs-everywhere-current-app))) | |||||
(or (cl-some (lambda (pattern) | |||||
(string-match-p pattern title)) | |||||
emacs-everywhere-markdown-windows) | |||||
(cl-some (lambda (pattern) | |||||
(string-match-p pattern class)) | |||||
emacs-everywhere-markdown-apps)))) | |||||
(defun emacs-everywhere-major-mode-org-or-markdown () | |||||
"Use markdow-mode, when window is recognised as markdown-flavoured. | |||||
Otherwise use `org-mode'." | |||||
(if (emacs-everywhere-markdown-p) | |||||
(markdown-mode) | |||||
(org-mode))) | |||||
(defcustom emacs-everywhere-org-export-options | |||||
"#+property: header-args :exports both | |||||
#+options: toc:nil\n" | |||||
"A string inserted at the top of the Org buffer prior to export. | |||||
This is with the purpose of setting #+property and #+options parameters. | |||||
Should end in a newline to avoid interfering with the buffer content." | |||||
:type 'string | |||||
:group 'emacs-everywhere) | |||||
(defvar org-export-show-temporary-export-buffer) | |||||
(defun emacs-everywhere-return-converted-org-to-gfm () | |||||
"When appropriate, convert org buffer to markdown." | |||||
(when (and (eq major-mode 'org-mode) | |||||
(emacs-everywhere-markdown-p)) | |||||
(goto-char (point-min)) | |||||
(insert emacs-everywhere-org-export-options) | |||||
(let (org-export-show-temporary-export-buffer) | |||||
(require 'ox-md) | |||||
(org-export-to-buffer (if (featurep 'ox-gfm) 'gfm 'md) (current-buffer))))) | |||||
(provide 'emacs-everywhere) | |||||
;;; emacs-everywhere.el ends here |
@@ -0,0 +1,57 @@ | |||||
;; -*- no-byte-compile: t; -*- | |||||
;;; $DOOMDIR/packages.el | |||||
;; To install a package with Doom you must declare them here and run 'doom sync' | |||||
;; on the command line, then restart Emacs for the changes to take effect -- or | |||||
;; use 'M-x doom/reload'. | |||||
;; To install SOME-PACKAGE from MELPA, ELPA or emacsmirror: | |||||
;(package! some-package) | |||||
;; To install a package directly from a remote git repo, you must specify a | |||||
;; `:recipe'. You'll find documentation on what `:recipe' accepts here: | |||||
;; https://github.com/raxod502/straight.el#the-recipe-format | |||||
;(package! another-package | |||||
; :recipe (:host github :repo "username/repo")) | |||||
;; If the package you are trying to install does not contain a PACKAGENAME.el | |||||
;; file, or is located in a subdirectory of the repo, you'll need to specify | |||||
;; `:files' in the `:recipe': | |||||
;(package! this-package | |||||
; :recipe (:host github :repo "username/repo" | |||||
; :files ("some-file.el" "src/lisp/*.el"))) | |||||
;; If you'd like to disable a package included with Doom, you can do so here | |||||
;; with the `:disable' property: | |||||
;(package! builtin-package :disable t) | |||||
;; You can override the recipe of a built in package without having to specify | |||||
;; all the properties for `:recipe'. These will inherit the rest of its recipe | |||||
;; from Doom or MELPA/ELPA/Emacsmirror: | |||||
;(package! builtin-package :recipe (:nonrecursive t)) | |||||
;(package! builtin-package-2 :recipe (:repo "myfork/package")) | |||||
;; Specify a `:branch' to install a package from a particular branch or tag. | |||||
;; This is required for some packages whose default branch isn't 'master' (which | |||||
;; our package manager can't deal with; see raxod502/straight.el#279) | |||||
;(package! builtin-package :recipe (:branch "develop")) | |||||
;; Use `:pin' to specify a particular commit to install. | |||||
;(package! builtin-package :pin "1a2b3c4d5e") | |||||
;; Doom's packages are pinned to a specific commit and updated from release to | |||||
;; release. The `unpin!' macro allows you to unpin single packages... | |||||
;(unpin! pinned-package) | |||||
;; ...or multiple packages | |||||
;(unpin! pinned-package another-pinned-package) | |||||
;; ...Or *all* packages (NOT RECOMMENDED; will likely break things) | |||||
;(unpin! t) | |||||
(package! emacs-everywhere :ignore t) | |||||
(package! doom-snippets :ignore t) | |||||
(package! copilot | |||||
:recipe (:host github :repo "zerolfx/copilot.el" | |||||
:files ("dist" "copilot.el"))) |
@@ -0,0 +1,8 @@ | |||||
# -*- mode: snippet -*- | |||||
# name: src_elisp | |||||
# key: <el | |||||
# expand-env: ((yas-after-exit-snippet-hook #'org-edit-special)) | |||||
# -- | |||||
#+BEGIN_SRC elisp | |||||
$0 | |||||
#+END_SRC |
@@ -0,0 +1,154 @@ | |||||
;;; doom-catppuccin-theme.el --- inspired by Catppuccin -*- lexical-binding: t; no-byte-compile: t; -*- | |||||
(require 'doom-themes) | |||||
;; | |||||
;;; Variables | |||||
(defgroup doom-catppuccin-theme nil | |||||
"Options for the `doom-catppuccin' theme." | |||||
:group 'doom-themes) | |||||
(defcustom doom-catppuccin-brighter-modeline nil | |||||
"If non-nil, more vivid colors will be used to style the mode-line." | |||||
:group 'doom-catppuccin-theme | |||||
:type 'boolean) | |||||
(defcustom doom-catppuccin-brighter-comments nil | |||||
"If non-nil, comments will be highlighted in more vivid colors." | |||||
:group 'doom-catppuccin-theme | |||||
:type 'boolean) | |||||
(defcustom doom-catppuccin-padded-modeline doom-themes-padded-modeline | |||||
"If non-nil, adds a 4px padding to the mode-line. | |||||
Can be an integer to determine the exact padding." | |||||
:group 'doom-catppuccin-theme | |||||
:type '(choice integer boolean)) | |||||
;; | |||||
;;; Theme definition | |||||
(def-doom-theme doom-catppuccin | |||||
"A dark theme inspired by Catppuccin." | |||||
;; name default 256 16 | |||||
((bg '("#1e1e2e" "black" "black" )) | |||||
(fg '("#d9e0ee" "#bfbfbf" "brightwhite" )) | |||||
;; These are off-color variants of bg/fg, used primarily for `solaire-mode', | |||||
;; but can also be useful as a basis for subtle highlights (e.g. for hl-line | |||||
;; or region), especially when paired with the `doom-darken', `doom-lighten', | |||||
;; and `doom-blend' helper functions. | |||||
(bg-alt '("#1a1826" "black" "black" )) | |||||
(fg-alt '("#d9e0ee" "#2d2d2d" "white" )) | |||||
;; These should represent a spectrum from bg to fg, where base0 is a starker | |||||
;; bg and base8 is a starker fg. For example, if bg is light grey and fg is | |||||
;; dark grey, base0 should be white and base8 should be black. | |||||
(base0 '("#161320" "black" "black" )) | |||||
(base1 '("#1a1826" "#1e1e1e" "brightblack" )) | |||||
(base2 '("#1e1e1e" "#2e2e2e" "brightblack" )) | |||||
(base3 '("#302d41" "#262626" "brightblack" )) | |||||
(base4 '("#575268" "#3f3f3f" "brightblack" )) | |||||
(base5 '("#6e6c7e" "#525252" "brightblack" )) | |||||
(base6 '("#988ba2" "#6b6b6b" "brightblack" )) | |||||
(base7 '("#c3bac6" "#979797" "brightblack" )) | |||||
(base8 '("#d9e0ee" "#dfdfdf" "white" )) | |||||
(grey base4) | |||||
(red '("#f28fad" "#ff6655" "red" )) | |||||
(orange '("#f8bd96" "#dd8844" "brightred" )) | |||||
(green '("#abe9b3" "#99bb66" "green" )) | |||||
(teal '("#b5e8e0" "#44b9b1" "brightgreen" )) | |||||
(yellow '("#fae3b0" "#ECBE7B" "yellow" )) | |||||
(blue '("#96cdfb" "#51afef" "brightblue" )) | |||||
(dark-blue '("#96cdfb" "#2257A0" "blue" )) | |||||
(magenta '("#f5c2e7" "#c678dd" "brightmagenta")) | |||||
(violet '("#ddb6f2" "#a9a1e1" "magenta" )) | |||||
(cyan '("#89dceb" "#46D9FF" "brightcyan" )) | |||||
(dark-cyan '("#89dceb" "#5699AF" "cyan" )) | |||||
;; These are the "universal syntax classes" that doom-themes establishes. | |||||
;; These *must* be included in every doom themes, or your theme will throw an | |||||
;; error, as they are used in the base theme defined in doom-themes-base. | |||||
(highlight magenta) | |||||
(vertical-bar (doom-darken base1 0.1)) | |||||
(selection dark-blue) | |||||
(builtin teal) | |||||
(comments (if doom-catppuccin-brighter-comments green base5)) | |||||
(doc-comments (doom-lighten (if doom-catppuccin-brighter-comments green base5) 0.25)) | |||||
(constants orange) | |||||
(functions blue) | |||||
(keywords magenta) | |||||
(methods blue) | |||||
(operators blue) | |||||
(type yellow) | |||||
(strings green) | |||||
(variables cyan) | |||||
;; (variables (doom-lighten magenta 0.4)) | |||||
(numbers orange) | |||||
(region `(,(doom-lighten (car bg-alt) 0.15) ,@(doom-lighten (cdr base1) 0.35))) | |||||
(error red) | |||||
(warning yellow) | |||||
(success green) | |||||
(vc-modified orange) | |||||
(vc-added green) | |||||
(vc-deleted red) | |||||
;; These are extra color variables used only in this theme; i.e. they aren't | |||||
;; mandatory for derived themes. | |||||
(modeline-fg fg) | |||||
(modeline-fg-alt base5) | |||||
(modeline-bg (if doom-catppuccin-brighter-modeline | |||||
(doom-darken blue 0.45) | |||||
(doom-darken bg-alt 0.1))) | |||||
(modeline-bg-alt (if doom-catppuccin-brighter-modeline | |||||
(doom-darken blue 0.475) | |||||
`(,(doom-darken (car bg-alt) 0.15) ,@(cdr bg)))) | |||||
(modeline-bg-inactive `(,(car bg-alt) ,@(cdr base1))) | |||||
(modeline-bg-inactive-alt `(,(doom-darken (car bg-alt) 0.1) ,@(cdr bg))) | |||||
(-modeline-pad | |||||
(when doom-catppuccin-padded-modeline | |||||
(if (integerp doom-catppuccin-padded-modeline) doom-catppuccin-padded-modeline 4)))) | |||||
;;;; Base theme face overrides | |||||
(((line-number &override) :foreground base4) | |||||
((line-number-current-line &override) :foreground fg) | |||||
((font-lock-comment-face &override) | |||||
:background (if doom-catppuccin-brighter-comments (doom-lighten bg 0.05))) | |||||
(mode-line | |||||
:background modeline-bg :foreground modeline-fg | |||||
:box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg))) | |||||
(mode-line-inactive | |||||
:background modeline-bg-inactive :foreground modeline-fg-alt | |||||
:box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive))) | |||||
(mode-line-emphasis :foreground (if doom-catppuccin-brighter-modeline base8 highlight)) | |||||
;;;; css-mode <built-in> / scss-mode | |||||
(css-proprietary-property :foreground orange) | |||||
(css-property :foreground magenta) | |||||
(css-selector :foreground blue) | |||||
;;;; doom-modeline | |||||
(doom-modeline-bar :background (if doom-catppuccin-brighter-modeline modeline-bg highlight)) | |||||
(doom-modeline-buffer-file :inherit 'mode-line-buffer-id :weight 'bold) | |||||
(doom-modeline-buffer-path :inherit 'mode-line-emphasis :weight 'bold) | |||||
(doom-modeline-buffer-project-root :foreground magenta :weight 'bold) | |||||
;;;; ivy | |||||
(ivy-current-match :background dark-blue :distant-foreground base0 :weight 'normal) | |||||
;;;; LaTeX-mode | |||||
(font-latex-math-face :foreground magenta) | |||||
;;;; markdown-mode | |||||
(markdown-markup-face :foreground base5) | |||||
(markdown-header-face :inherit 'bold :foreground red) | |||||
((markdown-code-face &override) :background (doom-lighten base3 0.05)) | |||||
;;;; rjsx-mode | |||||
) | |||||
;;;; Base theme variable overrides- | |||||
()) | |||||
;;; doom-catppuccin-theme.el ends here |