Browse Source

28 May 2022 19:10:46

main
Jack Foltz 2 years ago
parent
commit
7f3c027a8d
No known key found for this signature in database GPG Key ID: 79C872C088D157D1
9 changed files with 2269 additions and 0 deletions
  1. +580
    -0
      .doom.d/config.el
  2. +733
    -0
      .doom.d/config.org
  3. +2
    -0
      .doom.d/env.el
  4. +189
    -0
      .doom.d/init.el
  5. +546
    -0
      .doom.d/lisp/emacs-everywhere.el
  6. +57
    -0
      .doom.d/packages.el
  7. +0
    -0
      .doom.d/snippets/org-config-mode/.yas-parents
  8. +8
    -0
      .doom.d/snippets/org-mode/src_elisp
  9. +154
    -0
      .doom.d/themes/doom-catppuccin-theme.el

+ 580
- 0
.doom.d/config.el View File

@@ -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))))

+ 733
- 0
.doom.d/config.org View File

@@ -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

+ 2
- 0
.doom.d/env.el View File

@@ -0,0 +1,2 @@
("DISPLAY=:0"
"SSH_AUTH_SOCK=/run/user/1000/gnupg/S.gpg-agent.ssh")

+ 189
- 0
.doom.d/init.el View File

@@ -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

:email
;;(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))

+ 546
- 0
.doom.d/lisp/emacs-everywhere.el View File

@@ -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

+ 57
- 0
.doom.d/packages.el View File

@@ -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
.doom.d/snippets/org-config-mode/.yas-parents View File


+ 8
- 0
.doom.d/snippets/org-mode/src_elisp View File

@@ -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

+ 154
- 0
.doom.d/themes/doom-catppuccin-theme.el View File

@@ -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

Loading…
Cancel
Save