emacs: Track required *.el files
So the language breakdown of my dotfiles as a repo doesn't look like I have that little elisp files :') Regardless of my recent activity in the neovim space I still love emacs, especially consult.el and org mode.
This commit is contained in:
parent
237637c653
commit
39b5aae9f5
|
@ -0,0 +1,99 @@
|
|||
;;; init-highlight.el --- Highlighting stuff
|
||||
;;; Commentary:
|
||||
;; Highlighting symbols, indentation, brackets, TODO/REVIEW/FIXME/HACK/XXX
|
||||
|
||||
;;; Code:
|
||||
|
||||
;; TODO: do I need hl-line package??
|
||||
|
||||
;; Highlight indentions
|
||||
(use-package highlight-indent-guides
|
||||
:diminish
|
||||
:hook ((prog-mode yaml-mode) . highlight-indent-guides-mode)
|
||||
:init (setq highlight-indent-guides-method 'character
|
||||
highlight-indent-guides-responsive 'top
|
||||
highlight-indent-guides-suppress-auto-error t)
|
||||
:custom-face
|
||||
(highlight-indent-guides-character-face ((t (:foreground "dim gray"))))
|
||||
:config
|
||||
(with-no-warnings
|
||||
;; Don't display first level of indentation
|
||||
(defun my-indent-guides-for-all-but-first-column (level responsive display)
|
||||
(unless (< level 1)
|
||||
(highlight-indent-guides--highlighter-default level responsive display)))
|
||||
(setq highlight-indent-guides-highlighter-function
|
||||
#'my-indent-guides-for-all-but-first-column)
|
||||
|
||||
;; Disable in `macrostep' expanding
|
||||
(with-eval-after-load 'macrostep
|
||||
(advice-add #'macrostep-expand
|
||||
:after (lambda (&rest _)
|
||||
(when highlight-indent-guides-mode
|
||||
(highlight-indent-guides-mode -1))))
|
||||
(advice-add #'macrostep-collapse
|
||||
:after (lambda (&rest _)
|
||||
(when (derived-mode-p 'prog-mode 'yaml-mode)
|
||||
(highlight-indent-guides-mode 1)))))
|
||||
|
||||
;; Don't display indentations in `swiper'
|
||||
;; https://github.com/DarthFennec/highlight-indent-guides/issues/40
|
||||
(with-eval-after-load 'ivy
|
||||
(defun my-ivy-cleanup-indentation (str)
|
||||
"Clean up indentation highlighting in ivy minibuffer."
|
||||
(let ((pos 0)
|
||||
(next 0)
|
||||
(limit (length str))
|
||||
(prop 'highlight-indent-guides-prop))
|
||||
(while (and pos next)
|
||||
(setq next (text-property-not-all pos limit prop nil str))
|
||||
(when next
|
||||
(setq pos (text-property-any next limit prop nil str))
|
||||
(ignore-errors
|
||||
(remove-text-properties next pos '(display nil face nil) str))))))
|
||||
(advice-add #'ivy-cleanup-string :after #'my-ivy-cleanup-indentation))))
|
||||
|
||||
|
||||
;; Colorize color names in buffers
|
||||
(use-package rainbow-mode
|
||||
:diminish
|
||||
:bind (:map special-mode-map
|
||||
("w" . rainbow-mode))
|
||||
:hook ((html-mode php-mode) . rainbow-mode)
|
||||
:config
|
||||
(with-no-warnings
|
||||
;; HACK: Use overlay instead of text properties to override `hl-line' faces.
|
||||
;; @see https://emacs.stackexchange.com/questions/36420
|
||||
(defun my-rainbow-colorize-match (color &optional match)
|
||||
(let* ((match (or match 0))
|
||||
(ov (make-overlay (match-beginning match) (match-end match))))
|
||||
(overlay-put ov 'ovrainbow t)
|
||||
(overlay-put ov 'face `((:foreground ,(if (> 0.5 (rainbow-x-color-luminance color))
|
||||
"white" "black"))
|
||||
(:background ,color)))))
|
||||
(advice-add #'rainbow-colorize-match :override #'my-rainbow-colorize-match)
|
||||
|
||||
(defun my-rainbow-clear-overlays ()
|
||||
"Clear all rainbow overlays."
|
||||
(remove-overlays (point-min) (point-max) 'ovrainbow t))
|
||||
(advice-add #'rainbow-turn-off :after #'my-rainbow-clear-overlays)))
|
||||
|
||||
;; Highlight brackets according to their depth
|
||||
(use-package rainbow-delimiters
|
||||
:hook (prog-mode . rainbow-delimiters-mode))
|
||||
|
||||
;; Highlight TODO and similar keywords in comments and strings
|
||||
(use-package hl-todo
|
||||
:demand t
|
||||
:config
|
||||
(global-hl-todo-mode 1)
|
||||
(dolist (keyword '("REVIEW" "HACK"))
|
||||
(cl-pushnew `(,keyword . ,(face-foreground 'warning)) hl-todo-keyword-faces))
|
||||
:bind (:map hl-todo-mode-map
|
||||
([C-f3] . hl-todo-occur)
|
||||
("C-c t p" . hl-todo-previous)
|
||||
("C-c t n" . hl-todo-next)
|
||||
("C-c t o" . hl-todo-occur))
|
||||
;;:hook (after-init . global-hl-todo-mode)
|
||||
)
|
||||
(provide 'init-highlight)
|
||||
;;; init-highlight.el ends here
|
|
@ -0,0 +1,778 @@
|
|||
;; NOTE:
|
||||
;; This file is generated from packages.org
|
||||
|
||||
(defconst IS-MAC (eq system-type 'darwin))
|
||||
(defconst IS-LINUX (memq system-type '(gnu gnu/linux gnu/kfreebsd berkeley-unix)))
|
||||
(defconst IS-WINDOWS (memq system-type '(cygwin windows-nt ms-dos)))
|
||||
(defconst IS-BSD (memq system-type '(darwin berkeley-unix gnu/kfreebsd)))
|
||||
(defconst HAS-EMACS28+ (> emacs-major-version 27))
|
||||
(defconst HAS-EMACS29+ (> emacs-major-version 28))
|
||||
(defconst HAS-DYNMODULES (featurep 'dynamic-modules))
|
||||
(defconst HAS-NATIVECOMP (featurep 'native-compile))
|
||||
|
||||
(set-face-attribute 'completions-first-difference nil :weight 'normal)
|
||||
|
||||
(defvar ./corfu-bar-color "gray20" ;; Default value is for dark themes
|
||||
"Color for the corfu scroll bar.")
|
||||
(defvar ./cursor-color "white"
|
||||
"Color for cursor")
|
||||
(defvar ./theme-type "dark"
|
||||
"Dark or light")
|
||||
|
||||
(use-package ef-themes
|
||||
:config
|
||||
(load-theme 'ef-elea-dark t)
|
||||
(set-face-attribute 'cursor nil :background "white")
|
||||
(set-face-attribute 'font-lock-builtin-face nil :weight 'normal)
|
||||
(set-face-attribute 'font-lock-keyword-face nil :weight 'normal)
|
||||
(set-face-attribute 'font-lock-variable-name-face nil :foreground "white")
|
||||
(set-face-attribute 'font-lock-property-name-face nil :foreground "white")
|
||||
(set-face-attribute 'font-lock-constant-face nil :foreground "white")
|
||||
|
||||
(set-face-attribute 'window-divider nil :foreground "gray20")
|
||||
(set-face-attribute 'window-divider-first-pixel nil :foreground "black")
|
||||
(set-face-attribute 'window-divider-last-pixel nil :foreground "black")
|
||||
)
|
||||
|
||||
(setq ./theme-type (symbol-name (frame-parameter nil 'background-mode)))
|
||||
(setq ./cursor-color (if (string= ./theme-type "dark") "white" "black"))
|
||||
(set-face-attribute 'cursor nil :background ./cursor-color)
|
||||
;; TODO: Do this for window divider and corfu UI items, and magit diff backgrounds.
|
||||
;; and org-link
|
||||
|
||||
(setq tab-bar-auto-width-max nil)
|
||||
|
||||
(setq tab-bar-new-tab-choice "*scratch*")
|
||||
|
||||
;; FIXME: Doesn't work
|
||||
(set-face-attribute 'tab-bar-tab-inactive nil :background "textBackgroundColor")
|
||||
|
||||
(use-package evil
|
||||
:demand t
|
||||
:init
|
||||
(setq evil-search-module 'evil-search
|
||||
evil-ex-search-vim-style-regexp t)
|
||||
(setq evil-ex-visual-char-range t ; column range for ex commands
|
||||
evil-mode-line-format 'nil
|
||||
;; more vim-like behavior
|
||||
evil-symbol-word-search t)
|
||||
(setq evil-default-cursor 'box
|
||||
evil-normal-state-cursor 'box
|
||||
evil-emacs-state-cursor 'bar
|
||||
evil-insert-state-cursor 'bar
|
||||
evil-visual-state-cursor 'hollow)
|
||||
;; Only do highlighting in selected window so that Emacs has less work
|
||||
;; to do highlighting them all.
|
||||
(setq evil-ex-interactive-search-highlight 'selected-window
|
||||
;; It's infuriating that innocuous "beginning of line" or "end of line"
|
||||
;; errors will abort macros, so suppress them:
|
||||
evil-kbd-macro-suppress-motion-error t)
|
||||
(setq evil-want-C-u-scroll t) ; must be set in :init
|
||||
;; REVIEW: Is this needed if evil-redo-function is set?
|
||||
(setq evil-undo-system 'undo-redo) ;; 'undo-redo from Emacs 28
|
||||
(setq evil-undo-function 'undo)
|
||||
(setq evil-redo-function 'undo-redo)
|
||||
|
||||
:config
|
||||
(setq evil-visual-update-x-selection-p nil)
|
||||
(setq evil-shift-width 2)
|
||||
(setq evil-cross-lines t)
|
||||
|
||||
;; Emacs keybindings in evil insert state - must be set in :config
|
||||
(setq evil-insert-state-map (make-sparse-keymap))
|
||||
(define-key evil-insert-state-map (kbd "<escape>") 'evil-normal-state)
|
||||
(define-key evil-emacs-state-map (kbd "<escape>") 'evil-normal-state)
|
||||
(define-key evil-insert-state-map (kbd "S-C-e") 'evil-scroll-line-down)
|
||||
(define-key evil-emacs-state-map (kbd "S-C-e") 'evil-scroll-line-down)
|
||||
(define-key evil-insert-state-map (kbd "S-C-y") 'evil-scroll-line-up)
|
||||
(define-key evil-emacs-state-map (kbd "S-C-y") 'evil-scroll-line-up)
|
||||
;; Don't put vim yanks into system clipboard
|
||||
;; But use shift C-v / C-c to paste/copy from system clipboard instead
|
||||
(setq select-enable-clipboard nil)
|
||||
(global-set-key (kbd "S-C-c") #'clipboard-kill-ring-save)
|
||||
(global-set-key (kbd "S-C-v") #'clipboard-yank)
|
||||
|
||||
(global-set-key (kbd "<escape>") 'keyboard-escape-quit)
|
||||
;; FIXME
|
||||
(evil-set-leader nil (kbd "S-C-SPC")) ;; C-SPC is mark set
|
||||
(evil-set-leader 'normal (kbd "SPC"))
|
||||
|
||||
(define-key evil-command-line-map "\C-a" 'move-beginning-of-line)
|
||||
(define-key evil-command-line-map "\C-e" 'move-end-of-line)
|
||||
;; (define-key evil-command-line-map "\C-d" nil t)
|
||||
;; (define-key evil-command-line-map "\C-l" nil t)
|
||||
|
||||
(global-set-key (kbd "s-<left>") #'previous-buffer)
|
||||
(global-set-key (kbd "s-<right>") #'next-buffer)
|
||||
(global-set-key (kbd "S-s-<down>") #'evil-window-down)
|
||||
(global-set-key (kbd "S-s-<up>") #'evil-window-up)
|
||||
(global-set-key (kbd "S-s-<left>") #'evil-window-left)
|
||||
(global-set-key (kbd "S-s-<right>") #'evil-window-right)
|
||||
(defvar ./leader-map (make-sparse-keymap)
|
||||
"Keymap for leader shortcuts")
|
||||
(define-key evil-normal-state-map (kbd "SPC") ./leader-map)
|
||||
(define-key ./leader-map "q" #'evil-quit)
|
||||
(define-key ./leader-map "w" #'save-buffer)
|
||||
(define-key ./leader-map "x" #'evil-save-modified-and-close)
|
||||
(define-key ./leader-map "1" #'delete-other-windows)
|
||||
|
||||
(defvar ./leader-buffer-map (make-sparse-keymap)
|
||||
"Keymap for leader shortcuts for buffers")
|
||||
(define-key ./leader-map "b" ./leader-buffer-map)
|
||||
(define-key ./leader-buffer-map "b" #'consult-buffer)
|
||||
(define-key ./leader-buffer-map "s" #'save-buffer)
|
||||
(define-key ./leader-buffer-map "d" #'evil-delete-buffer)
|
||||
|
||||
(defvar ./leader-file-map (make-sparse-keymap)
|
||||
"Keymap for leader shortcuts for files")
|
||||
(define-key ./leader-map "f" ./leader-file-map)
|
||||
(define-key ./leader-file-map "f" #'find-file)
|
||||
(define-key ./leader-file-map "r" #'consult-recent-file)
|
||||
(define-key ./leader-file-map "p" #'project-find-file)
|
||||
|
||||
(defvar ./leader-frame-map (make-sparse-keymap)
|
||||
"Keymap for leader shortcuts for frames")
|
||||
(define-key ./leader-map "F" ./leader-frame-map)
|
||||
(define-key ./leader-frame-map "q" #'delete-frame)
|
||||
(define-key ./leader-frame-map "d" #'delete-frame)
|
||||
(define-key ./leader-frame-map "u" #'undelete-frame)
|
||||
(define-key ./leader-frame-map "R" #'rename-frame)
|
||||
(define-key ./leader-frame-map "o" #'other-frame)
|
||||
(define-key ./leader-frame-map "c" #'clone-frame)
|
||||
|
||||
(defun ./evil-off ()
|
||||
"Call `turn-off-evil-mode' and show a message"
|
||||
(interactive)
|
||||
(turn-off-evil-mode)
|
||||
(message "Evil mode is turned off"))
|
||||
|
||||
;; Disable evil in some modes
|
||||
(dolist (mode '(elpaca-ui-mode
|
||||
dired-mode
|
||||
magit-mode))
|
||||
(evil-set-initial-state mode 'emacs))
|
||||
|
||||
(evil-mode 1)
|
||||
)
|
||||
|
||||
(use-package elpher)
|
||||
;; eww is part of emacs now?!!
|
||||
;;(use-package eww)
|
||||
|
||||
(use-package visual-fill-column
|
||||
:init
|
||||
(setq-default visual-fill-column-center-text t))
|
||||
|
||||
(use-package imenu-list
|
||||
:config
|
||||
(setq imenu-list-auto-resize t)
|
||||
;; Auto-update Ilist buffer
|
||||
:hook (imenu-list-major-mode . (lambda ()
|
||||
(imenu-list-minor-mode 1)
|
||||
(visual-line-mode 1) ;; REVIEW
|
||||
(display-line-numbers-mode -1)
|
||||
(evil-insert-state 1))))
|
||||
|
||||
(use-package math-symbol-lists
|
||||
:after cape
|
||||
:config
|
||||
;; This is actually for C-\, then select input "math",
|
||||
;; then the Ω will show in the status bar.
|
||||
(quail-define-package "math" "UTF-8" "Ω" t)
|
||||
;; (quail-define-rules ; add whatever extra rules you want to define here...
|
||||
;; ("\\from" #X2190)
|
||||
;; ("\\to" #X2192)
|
||||
;; ("\\lhd" #X22B2)
|
||||
;; ("\\rhd" #X22B3)
|
||||
;; ("\\unlhd" #X22B4)
|
||||
;; ("\\unrhd" #X22B5))
|
||||
(mapc (lambda (x)
|
||||
(if (cddr x)
|
||||
(quail-defrule (cadr x) (car (cddr x)))))
|
||||
(append math-symbol-list-basic math-symbol-list-extended))
|
||||
)
|
||||
|
||||
;; (use-package dired
|
||||
;; :elpaca nil
|
||||
;; :config
|
||||
(setq delete-by-moving-to-trash t
|
||||
;; Emacs 29
|
||||
dired-make-directory-clickable t
|
||||
dired-mouse-drag-files t
|
||||
)
|
||||
|
||||
;;:hook
|
||||
;; FIXME: replicate evil state cursor style switching here
|
||||
(defun ./cursor-toggle-readonly ()
|
||||
(if buffer-read-only
|
||||
(progn
|
||||
(setq cursor-type 'box)
|
||||
(set-cursor-color "orange"))
|
||||
(setq cursor-type 'bar)
|
||||
(set-cursor-color ./cursor-color)))
|
||||
|
||||
(add-hook 'read-only-mode-hook #'./cursor-toggle-readonly)
|
||||
(add-hook 'dired-mode-hook (lambda () (hl-line-mode) (./cursor-toggle-readonly)))
|
||||
;; )
|
||||
|
||||
(add-hook 'minibuffer-setup-hook (lambda () (setq cursor-type 'bar)))
|
||||
(add-hook 'minibuffer-exit-hook (lambda () (setq cursor-type 'box)))
|
||||
|
||||
(use-package wrap-region
|
||||
:config
|
||||
(wrap-region-add-wrappers
|
||||
'(("/* " " */" "#" (java-mode javascript-mode css-mode))
|
||||
("`" "`" nil (markdown-mode org-mode))
|
||||
("=" "=" nil (org-mode))
|
||||
("~" "~" nil (org-mode))
|
||||
("*" "*" nil (markdown-mode org-mode))))
|
||||
:hook
|
||||
((org-mode markdown-mode) . wrap-region-mode)
|
||||
)
|
||||
|
||||
(use-package magit)
|
||||
|
||||
(use-package breadcrumb
|
||||
:diminish breadcrumb-mode
|
||||
:init
|
||||
(breadcrumb-mode 1))
|
||||
|
||||
(use-package vertico
|
||||
:init
|
||||
(vertico-mode)
|
||||
;; Grow and shrink the Vertico minibuffer
|
||||
(setq vertico-resize t)
|
||||
;; Optionally enable cycling for `vertico-next' and `vertico-previous'.
|
||||
(setq vertico-cycle t)
|
||||
:hook
|
||||
;; For find-file, remove old file path if I start typing a new one
|
||||
('rfn-eshadow-update-overlay-hook . #'vertico-directory-tidy)
|
||||
)
|
||||
|
||||
(use-package orderless
|
||||
:init
|
||||
(setq completion-styles '(orderless)
|
||||
completion-category-defaults nil
|
||||
completion-category-overrides '((file (styles partial-completion)))))
|
||||
;; Persist history over Emacs restarts. Vertico sorts by history position.
|
||||
(use-package savehist
|
||||
:elpaca nil
|
||||
:init
|
||||
(savehist-mode))
|
||||
;; Pasted from vertico
|
||||
(use-package emacs
|
||||
:elpaca nil
|
||||
:init
|
||||
;; Add prompt indicator to `completing-read-multiple'.
|
||||
;; Alternatively try `consult-completing-read-multiple'.
|
||||
(defun crm-indicator (args)
|
||||
(cons (concat "[CRM] " (car args)) (cdr args)))
|
||||
(advice-add #'completing-read-multiple :filter-args #'crm-indicator)
|
||||
;; Do not allow the cursor in the minibuffer prompt
|
||||
(setq minibuffer-prompt-properties
|
||||
'(read-only t cursor-intangible t face minibuffer-prompt))
|
||||
(add-hook 'minibuffer-setup-hook #'cursor-intangible-mode)
|
||||
;; Emacs 28: Hide commands in M-x which do not work in the current mode.
|
||||
;; Vertico commands are hidden in normal buffers.
|
||||
;; (setq read-extended-command-predicate
|
||||
;; #'command-completion-default-include-p)
|
||||
;; Enable recursive minibuffers
|
||||
(setq enable-recursive-minibuffers t)
|
||||
;; From corfu
|
||||
;; TAB cycle if there are only few candidates
|
||||
(setq completion-cycle-threshold 3)
|
||||
|
||||
;; Emacs 28: Hide commands in M-x which do not apply to the current mode.
|
||||
;; Corfu commands are hidden, since they are not supposed to be used via M-x.
|
||||
;; (setq read-extended-command-predicate
|
||||
;; #'command-completion-default-include-p)
|
||||
)
|
||||
|
||||
(use-package marginalia
|
||||
:diminish
|
||||
:config
|
||||
(setq marginalia-annotators '(marginalia-annotators-heavy marginalia-annotators-light nil))
|
||||
(marginalia-mode 1)
|
||||
)
|
||||
|
||||
(use-package consult
|
||||
:config
|
||||
(global-set-key (kbd "C-s") 'consult-line)
|
||||
(define-key evil-insert-state-map (kbd "C-s") 'isearch-forward)
|
||||
(define-key evil-emacs-state-map (kbd "C-s") 'isearch-forward)
|
||||
(global-set-key (kbd "C-c g") 'consult-org-heading)
|
||||
(global-set-key (kbd "C-x C-b") 'consult-buffer)
|
||||
;; Doesn't work?
|
||||
(global-set-key [?\C-\t] 'consult-buffer)
|
||||
(define-key minibuffer-local-map (kbd "C-r") 'consult-history)
|
||||
|
||||
(setq completion-in-region-function #'consult-completion-in-region)
|
||||
)
|
||||
|
||||
(use-package corfu
|
||||
:custom
|
||||
(corfu-cycle t) ;; Enable cycling for `corfu-next/previous'
|
||||
;; Default is M-SPC, if M-SPC is bound like I have on my Mac (Alfred) S-M-SPC also works
|
||||
;;(corfu-separator ?\s) ;; Orderless separator
|
||||
;; separator: Quit at boundary if no `corfu-separator' inserted
|
||||
(corfu-quit-at-boundary 'separator)
|
||||
;; separator: only stay alive if no match and `corfu-separator' inserted
|
||||
(corfu-quit-no-match 'separator)
|
||||
;; Don't change what I typed to what I selected when previewing completions
|
||||
(corfu-preview-current nil)
|
||||
(corfu-preselect 'first)
|
||||
;; Default = #'insert. Options: quit, nil
|
||||
;;(corfu-on-exact-match nil)
|
||||
;; Prevent last/first item being hidden behind windows
|
||||
;; FIXME: Doesn't work
|
||||
(corfu-scroll-margin 2)
|
||||
(corfu-right-margin-width 2)
|
||||
|
||||
;; Enable Corfu only for certain modes.
|
||||
;; :hook ((prog-mode . corfu-mode)
|
||||
;; (shell-mode . corfu-mode)
|
||||
;; (eshell-mode . corfu-mode))
|
||||
|
||||
;; FIXME: doesn't work: evil insert/emacs keybinds takes higher precendence it seems
|
||||
(define-key corfu-map (kbd "<escape>") 'corfu-quit)
|
||||
|
||||
:custom-face
|
||||
(corfu-border ((t (:background "gray20" :weight bold))))
|
||||
(corfu-default ((t (:inherit fixed-pitch))))
|
||||
|
||||
:init
|
||||
;; Recommended: Enable Corfu globally.
|
||||
;; This is recommended since Dabbrev can be used globally (M-/).
|
||||
;; See also `global-corfu-modes'.
|
||||
(global-corfu-mode)
|
||||
(corfu-popupinfo-mode 1)
|
||||
|
||||
:config
|
||||
(setq corfu-bar-width 0.8)
|
||||
(set-face-attribute 'corfu-bar nil :background ./corfu-bar-color)
|
||||
(defun corfu-enable-always-in-minibuffer ()
|
||||
"Enable Corfu in the minibuffer if Vertico/Mct are not active."
|
||||
(unless (or (bound-and-true-p mct--active)
|
||||
(bound-and-true-p vertico--input)
|
||||
(eq (current-local-map) read-passwd-map))
|
||||
;; (setq-local corfu-auto nil) ;; Enable/disable auto completion
|
||||
(setq-local corfu-echo-delay nil ;; Disable automatic echo and popup
|
||||
corfu-popupinfo-delay '(0 . 0)) ;; Use popupinfo in minibuffer too, why not?
|
||||
(corfu-mode 1)))
|
||||
(add-hook 'minibuffer-setup-hook #'corfu-enable-always-in-minibuffer 1)
|
||||
|
||||
(setq corfu-popupinfo-delay '(0 . 0))
|
||||
)
|
||||
|
||||
(use-package kind-icon
|
||||
:after corfu
|
||||
:custom
|
||||
(kind-icon-mapping ;; These are fetched (and cached) from pictogrammers.com/library/mdi
|
||||
'((array "ar" :icon "code-brackets" :face font-lock-type-face)
|
||||
(boolean "b" :face font-lock-builtin-face)
|
||||
(class "C" :face font-lock-type-face) ;; family-tree could be used. but too dense
|
||||
(color "#" :icon "palette" :face success)
|
||||
(command ">_" :face default)
|
||||
(constant "cn" :icon "lock-remove-outline" :face font-lock-constant-face)
|
||||
(constructor "C+" :icon "plus-circle-multiple" :face font-lock-function-name-face)
|
||||
(enummember "em" :icon "order-bool-ascending-variant" :face font-lock-builtin-face)
|
||||
(enum-member "em" :icon "order-bool-ascending-variant" :face font-lock-builtin-face)
|
||||
(enum "e" :icon "format-list-bulleted-square" :face font-lock-builtin-face)
|
||||
(event "ev" :icon "lightning-bolt-outline" :face font-lock-warning-face)
|
||||
(field "fd" :face font-lock-variable-name-face)
|
||||
(file "F" :icon "file-document-outline" :face font-lock-string-face)
|
||||
(folder "D" :icon "folder" :face font-lock-doc-face)
|
||||
(interface "if" :icon "application-brackets-outline" :face font-lock-type-face)
|
||||
(keyword "kw" :face font-lock-keyword-face)
|
||||
(macro "mc" :icon "lambda" :face font-lock-keyword-face)
|
||||
(magic "ma" :icon "shimmer" :face font-lock-builtin-face)
|
||||
(method "me" :face font-lock-function-name-face)
|
||||
(function "f" :icon "function" :face font-lock-function-name-face)
|
||||
(module "mo" :icon "package-variant-closed" :face font-lock-preprocessor-face)
|
||||
(numeric "0" :icon "numeric" :face font-lock-builtin-face)
|
||||
(operator "÷" :icon "division" :face font-lock-comment-delimiter-face)
|
||||
(param "pa" :icon "cog-outline" :face default)
|
||||
(property "pr" :icon "wrench" :face font-lock-variable-name-face)
|
||||
(reference "rf" :icon "library" :face font-lock-variable-name-face)
|
||||
(snippet "S" :face font-lock-string-face)
|
||||
(string "\"" :icon "text-box" :face font-lock-string-face)
|
||||
(struct "{}" :icon "code-braces" :face font-lock-variable-name-face)
|
||||
(text " " :face font-lock-doc-face) ; text-short could be used
|
||||
(typeparameter "tp" :icon "format-list-bulleted-type" :face font-lock-type-face)
|
||||
(type-parameter "tp" :icon "format-list-bulleted-type" :face font-lock-type-face)
|
||||
(unit "u" :icon "square-rounded-outline" :face font-lock-constant-face)
|
||||
(value "vl" :icon "plus-circle-outline" :face font-lock-builtin-face)
|
||||
(variable "v" :face font-lock-variable-name-face)
|
||||
(t "?" :face font-lock-warning-face)))
|
||||
(kind-icon-blend-background nil)
|
||||
:custom-face
|
||||
(kind-icon-default-face ((t (:background nil))))
|
||||
|
||||
:config
|
||||
;;(setq kind-icon-default-face 'corfu-default) ; to compute blended backgrounds correctly
|
||||
(add-to-list 'corfu-margin-formatters #'kind-icon-margin-formatter))
|
||||
|
||||
(use-package cape
|
||||
;;:after math-symbol-lists
|
||||
:config
|
||||
;; Add useful defaults completion sources from cape
|
||||
;; (add-to-list 'completion-at-point-functions #'cape-file)
|
||||
;; ;;(add-to-list 'completion-at-point-functions #'cape-dabbrev)
|
||||
;;(add-to-list 'completion-at-point-functions #'cape-tex)
|
||||
(add-to-list 'completion-at-point-functions #'cape-emoji)
|
||||
|
||||
;; Silence the pcomplete capf, no errors or messages!
|
||||
;; Important for corfu
|
||||
(advice-add 'pcomplete-completions-at-point :around #'cape-wrap-silent)
|
||||
|
||||
;; Ensure that pcomplete does not write to the buffer
|
||||
;; and behaves as a pure `completion-at-point-function'.
|
||||
(advice-add 'pcomplete-completions-at-point :around #'cape-wrap-purify)
|
||||
|
||||
(define-key evil-insert-state-map (kbd "C-x C-f") 'cape-file)
|
||||
(define-key evil-insert-state-map (kbd "C-x C-d") 'cape-dict)
|
||||
(define-key evil-insert-state-map (kbd "C-x C-w") 'cape-dabbrev)
|
||||
(define-key evil-insert-state-map (kbd "C-x C-:") 'cape-emoji)
|
||||
|
||||
(cape-char--define math "math" ?\\)
|
||||
(add-to-list 'completion-at-point-functions #'cape-math)
|
||||
(define-key evil-insert-state-map (kbd "C-x C-$") 'cape-math)
|
||||
|
||||
:hook (eshell-mode-hook . (lambda () (setq-local corfu-quit-at-boundary t
|
||||
corfu-quit-no-match t
|
||||
corfu-auto nil)
|
||||
(corfu-mode)))
|
||||
|
||||
)
|
||||
|
||||
(use-package corfu-candidate-overlay
|
||||
:config
|
||||
(corfu-candidate-overlay-mode 1) ;; This is global
|
||||
(set-face-attribute 'corfu-candidate-overlay-face nil :foreground "dim grey")
|
||||
;; Use TAB to accept a completion, how cool is that!
|
||||
(defun ./insert-state-tab ()
|
||||
"Handle TAB key in insert state.
|
||||
|
||||
If corfu-candidate-overlay's overlay is active, calls
|
||||
`corfu-candidate-overlay--get-overlay-property', otherwise
|
||||
`evil-toggle-fold'. See my packages.org for this section for why I
|
||||
didn't use `org-cycle' here."
|
||||
(interactive)
|
||||
(if (overlayp corfu-candidate-overlay--overlay)
|
||||
(progn
|
||||
;; This check is taken exactly from the implementation of
|
||||
;; `corfu-candidate-overlay-complete-at-point's (as of
|
||||
;; writing).
|
||||
(corfu-candidate-overlay--show)
|
||||
(if (and (overlayp corfu-candidate-overlay--overlay)
|
||||
(not (string= (corfu-candidate-overlay--get-overlay-property 'after-string) "")))
|
||||
(corfu-candidate-overlay-complete-at-point)
|
||||
(if (string-match-p
|
||||
"^\*+ "
|
||||
(buffer-substring-no-properties
|
||||
(line-beginning-position)
|
||||
(line-end-position)))
|
||||
(evil-toggle-fold)
|
||||
(indent)
|
||||
)
|
||||
))
|
||||
(if (string-match-p
|
||||
"^\*+ "
|
||||
(buffer-substring-no-properties
|
||||
(line-beginning-position)
|
||||
(line-end-position)))
|
||||
(evil-toggle-fold)
|
||||
(indent-for-tab-command)
|
||||
)))
|
||||
(define-key evil-insert-state-map (kbd "TAB") './insert-state-tab)
|
||||
)
|
||||
|
||||
(use-package which-key
|
||||
:diminish
|
||||
:config
|
||||
(which-key-setup-side-window-right)
|
||||
(which-key-mode 1))
|
||||
|
||||
(use-package org
|
||||
:elpaca nil
|
||||
:config
|
||||
(setq org-startup-indented t)
|
||||
(setq org-edit-src-content-indentation 0)
|
||||
(setq org-list-indent-offset 2)
|
||||
|
||||
;; (dolist (item '( ;; Newline used to add prefix to tangled file
|
||||
;; '(org-block ((t (:inherit fixed-pitch))))
|
||||
;; '(org-code ((t (:inherit (shadow fixed-pitch)))))
|
||||
;; '(org-document-info ((t (:foreground "dark orange"))))
|
||||
;; '(org-document-info-keyword ((t (:inherit (shadow fixed-pitch)))))
|
||||
;; '(org-indent ((t (:inherit (org-hide fixed-pitch)))))
|
||||
;; '(org-link ((t (:foreground "deep sky blue" :underline t))))
|
||||
;; '(org-meta-line ((t (:inherit (font-lock-comment-face fixed-pitch)))))
|
||||
;; '(org-property-value ((t (:inherit fixed-pitch))) t)
|
||||
;; '(org-block-begin-line ((t (:inherit (font-lock-comment-face fixed-pitch)))) t)
|
||||
;; '(org-block-end-line ((t (:inherit (font-lock-comment-face fixed-pitch)))) t)
|
||||
;; '(org-drawer ((t (:inherit fixed-pitch))) t)
|
||||
;; '(org-special-keyword ((t (:inherit (font-lock-comment-face fixed-pitch)))))
|
||||
;; '(org-table ((t (:inherit fixed-pitch))))
|
||||
;; '(org-tag ((t (:inherit (shadow fixed-pitch) :weight bold :height 0.8))))
|
||||
;; '(org-verbatim ((t (:inherit (shadow fixed-pitch)))))))
|
||||
;; (apply #'set-face-attribute item))
|
||||
(custom-theme-set-faces
|
||||
'user
|
||||
'(org-block ((t (:inherit fixed-pitch))))
|
||||
'(org-code ((t (:inherit (shadow fixed-pitch)))))
|
||||
'(org-document-info ((t (:foreground "dark orange"))))
|
||||
'(org-document-info-keyword ((t (:inherit (shadow fixed-pitch)))))
|
||||
'(org-indent ((t (:inherit (org-hide fixed-pitch)))))
|
||||
'(org-link ((t (:foreground "deep sky blue" :underline t))))
|
||||
'(org-meta-line ((t (:inherit (font-lock-comment-face fixed-pitch)))))
|
||||
'(org-property-value ((t (:inherit fixed-pitch))) t)
|
||||
'(org-block-begin-line ((t (:inherit (font-lock-comment-face fixed-pitch)))) t)
|
||||
'(org-block-end-line ((t (:inherit (font-lock-comment-face fixed-pitch)))) t)
|
||||
'(org-drawer ((t (:inherit fixed-pitch))) t)
|
||||
'(org-special-keyword ((t (:inherit (font-lock-comment-face fixed-pitch)))))
|
||||
'(org-table ((t (:inherit fixed-pitch))))
|
||||
'(org-tag ((t (:inherit (shadow fixed-pitch) :weight bold :height 0.8))))
|
||||
'(org-verbatim ((t (:inherit (shadow fixed-pitch)))))
|
||||
)
|
||||
|
||||
(org-babel-do-load-languages
|
||||
'org-babel-load-languages
|
||||
'((emacs-lisp . t)
|
||||
(python . t)
|
||||
(lua . t)
|
||||
(js . t)))
|
||||
|
||||
(defun org-babel-execute:nim (body params)
|
||||
"Execute a block of Nim code with org-babel."
|
||||
(let ((in-file (org-babel-temp-file "n" ".nim"))
|
||||
(verbosity (or (cdr (assq :verbosity params)) 0)))
|
||||
(with-temp-file in-file
|
||||
(insert body))
|
||||
(org-babel-eval
|
||||
(format "nim compile --verbosity=%d --run %s" verbosity
|
||||
(org-babel-process-file-name in-file))
|
||||
"")))
|
||||
|
||||
(defun org-babel-execute:moonscript (body params)
|
||||
"Execute a block of MoonScript code with org-babel."
|
||||
(let ((in-file (org-babel-temp-file "m" ".moon")))
|
||||
(with-temp-file in-file
|
||||
(insert body))
|
||||
(org-babel-eval
|
||||
(format "moon %s" (org-babel-process-file-name in-file)) "")))
|
||||
|
||||
:hook
|
||||
(org-mode . (lambda () (visual-line-mode 1)
|
||||
(variable-pitch-mode)
|
||||
(display-line-numbers-mode -1)))
|
||||
)
|
||||
|
||||
(use-package org-superstar
|
||||
:config
|
||||
(setq org-superstar-configure-like-org-bullets t)
|
||||
:hook
|
||||
(org-mode . (lambda () (org-superstar-mode 1))))
|
||||
|
||||
(use-package org-auto-tangle
|
||||
:defer t
|
||||
:hook (org-mode . org-auto-tangle-mode)
|
||||
:config
|
||||
(setq org-auto-tangle-babel-safelist '(
|
||||
"~/.config/emacs/packages.org"
|
||||
"~/.config/emacs/init.org")))
|
||||
|
||||
(use-package lua-mode)
|
||||
(use-package moonscript)
|
||||
(use-package nim-mode)
|
||||
|
||||
(use-package eglot
|
||||
:elpaca nil
|
||||
:defer t
|
||||
:hook
|
||||
((python-ts-mode go-ts-mode lua-mode) . eglot-ensure)
|
||||
)
|
||||
|
||||
;; Open python files in tree-sitter mode.
|
||||
(add-to-list 'major-mode-remap-alist '(python-mode . python-ts-mode))
|
||||
(add-to-list 'major-mode-remap-alist '(c++-mode . c++-ts-mode))
|
||||
(add-to-list 'auto-mode-alist
|
||||
'("\\.go\\'" . (lambda ()
|
||||
(go-ts-mode)
|
||||
)))
|
||||
(add-to-list 'auto-mode-alist
|
||||
'("go.mod\\'" . (lambda ()
|
||||
(go-mod-ts-mode)
|
||||
)))
|
||||
|
||||
;; FIXME
|
||||
(use-package diminish
|
||||
:config
|
||||
(diminish 'buffer-face-mode)
|
||||
(diminish 'org-auto-tangle-mode)
|
||||
(diminish 'eldoc-mode)
|
||||
(diminish 'auto-revert-mode)
|
||||
(diminish 'visual-line-mode)
|
||||
(diminish 'org-indent-mode)
|
||||
(diminish 'subword-mode)
|
||||
)
|
||||
|
||||
(defun ./eshell-fn-on-files (fun1 fun2 args)
|
||||
"Call FUN1 on the first element in list, ARGS.
|
||||
Call FUN2 on all the rest of the elements in ARGS."
|
||||
(unless (null args)
|
||||
(let ((filenames (flatten-list args)))
|
||||
(funcall fun1 (car filenames))
|
||||
(when (cdr filenames)
|
||||
(mapcar fun2 (cdr filenames))))
|
||||
;; Return an empty string, as the return value from `fun1'
|
||||
;; probably isn't helpful to display in the `eshell' window.
|
||||
""))
|
||||
|
||||
(defun eshell/ff (&rest files)
|
||||
"find-file on first arg, find-file-other-window on rest"
|
||||
(./eshell-fn-on-files 'find-file 'find-file-other-window files))
|
||||
|
||||
(defun eshell/f (&rest files)
|
||||
"Edit one or more files in another window."
|
||||
(./eshell-fn-on-files 'find-file-other-window 'find-file-other-window files))
|
||||
|
||||
(defalias 'eshell/emacs 'eshell/ff)
|
||||
(defalias 'eshell/vi 'eshell/ff)
|
||||
(defalias 'eshell/vim 'eshell/ff)
|
||||
(defalias 'eshell/nv 'eshell/ff)
|
||||
(defalias 'eshell/nvim 'eshell/ff)
|
||||
|
||||
(defun eshell/less (&rest files)
|
||||
"view-file-other-window"
|
||||
(view-file-other-window files))
|
||||
|
||||
(defalias 'eshell/more 'eshell/less)
|
||||
|
||||
(defun ./eshell-exit-with-window ()
|
||||
(when (not (one-window-p))
|
||||
(delete-window)))
|
||||
|
||||
(advice-add 'eshell-life-is-too-much :after './eshell-exit-with-window)
|
||||
|
||||
(defun eshell/do (&rest args)
|
||||
"Execute a command sequence over a collection of file elements.
|
||||
Separate the sequence and the elements with a `::' string.
|
||||
For instance:
|
||||
|
||||
do chown _ angela :: *.org(u'oscar')
|
||||
|
||||
The function substitutes the `_' sequence to a single filename
|
||||
element, and if not specified, it appends the file name to the
|
||||
command. So the following works as expected:
|
||||
|
||||
do chmod a+x :: *.org"
|
||||
(seq-let (forms elements) (-split-on "::" args)
|
||||
(dolist (element (-flatten (-concat elements)))
|
||||
(message "Working on %s ... %s" element forms)
|
||||
(let* ((form (if (-contains? forms "_")
|
||||
(-replace "_" element forms)
|
||||
(-snoc forms element)))
|
||||
(cmd (car form))
|
||||
(args (cdr form)))
|
||||
(eshell-named-command cmd args)))))
|
||||
|
||||
(defun ./eshell--buffer-from-dir (dir)
|
||||
"Return buffer name of an Eshell based on DIR."
|
||||
(format "*eshell: %s*"
|
||||
(thread-first dir
|
||||
(split-string "/" t)
|
||||
(last)
|
||||
(car))))
|
||||
|
||||
(defun ./eshell-there (parent)
|
||||
"Open an eshell session in a PARENT directory.
|
||||
The window is smaller and named after this directory.
|
||||
If an Eshell is already present that has been named
|
||||
after PARENT, pop to that buffer instead."
|
||||
(if-let* ((term-name (./eshell--buffer-from-dir parent))
|
||||
(buf-name (seq-contains (buffer-list) term-name
|
||||
(lambda (a b) (string-equal (buffer-name b) a)))))
|
||||
(pop-to-buffer buf-name)
|
||||
|
||||
(let* ((default-directory parent)
|
||||
(height (/ (window-total-height) 3)))
|
||||
(split-window-vertically (- height))
|
||||
(other-window 1)
|
||||
(setq eshell-buffer-name term-name)
|
||||
(eshell))))
|
||||
|
||||
(defun ./eshell-here ()
|
||||
"Opens a new shell in the directory of the current buffer.
|
||||
Renames the eshell buffer to match that directory to allow more
|
||||
than one eshell window."
|
||||
(interactive)
|
||||
(./eshell-there (if (buffer-file-name)
|
||||
(file-name-directory (buffer-file-name))
|
||||
default-directory)))
|
||||
|
||||
(bind-key "C-`" './eshell-here)
|
||||
|
||||
(defun ./eshell-send (command &optional dir)
|
||||
"Send COMMAND to the Eshell buffer named with DIR.
|
||||
The Eshell may have moved away from the directory originally
|
||||
opened with DIR, but it should have the name of the buffer.
|
||||
See `eshell--buffer-from-dir'."
|
||||
(interactive "sCommand to Send: ")
|
||||
(unless dir
|
||||
(setq dir (projectile-project-root)))
|
||||
(save-window-excursion
|
||||
(eshell-there dir)
|
||||
(goto-char (point-max))
|
||||
(insert command)
|
||||
(eshell-send-input)))
|
||||
|
||||
(defun ./execute-command-on-file-buffer (cmd)
|
||||
"Executes a shell command, CMD, on the current buffer's file.
|
||||
Appends the filename to the command if not specified, so:
|
||||
|
||||
chmod a+x
|
||||
|
||||
Works as expected. We replace the special variable `$$' with the
|
||||
filename of the buffer. Note that `eshell-command' executes this
|
||||
command, so eshell modifiers are available, for instance:
|
||||
|
||||
mv $$ $$(:r).txt
|
||||
|
||||
Will rename the current file to now have a .txt extension.
|
||||
See `eshell-display-modifier-help' for details on that."
|
||||
(interactive "sExecute command on File Buffer: ")
|
||||
(let* ((file-name (buffer-file-name))
|
||||
(full-cmd (cond ((string-match (rx "$$") cmd)
|
||||
(replace-regexp-in-string (rx "$$") file-name cmd))
|
||||
((and file-name (string-match (rx (literal file-name)) cmd))
|
||||
cmd)
|
||||
(t
|
||||
(concat cmd " " file-name)))))
|
||||
(message "Executing: %s" full-cmd)
|
||||
(eshell-command full-cmd)))
|
||||
|
||||
(use-package eshell
|
||||
:elpaca nil
|
||||
:init
|
||||
(setq eshell-error-if-no-glob t
|
||||
;; This jumps back to the prompt:
|
||||
eshell-scroll-to-bottom-on-input 'all
|
||||
eshell-hist-ignoredups t
|
||||
eshell-save-history-on-exit t
|
||||
|
||||
;; Since eshell starts fast, let's dismiss it on exit:
|
||||
eshell-kill-on-exit t
|
||||
eshell-destroy-buffer-when-process-dies t
|
||||
|
||||
;; Parameter differences could be hard to remember. Maybe next time
|
||||
eshell-prefer-lisp-functions nil))
|
||||
|
||||
(use-package eat
|
||||
:config
|
||||
(define-key eat-mode-map (kbd "C-c C-d") #'eat-self-input)
|
||||
;; :hook
|
||||
;; (eshell-mode . #'eat-eshell-mode)
|
||||
)
|
||||
|
||||
(provide 'packages)
|
|
@ -0,0 +1,287 @@
|
|||
;; NOTE:
|
||||
;; This file is generated from init.org
|
||||
|
||||
(defvar ./variable-pitch-display-font
|
||||
"Fira Sans"
|
||||
"Font used for titles")
|
||||
|
||||
(defvar ./face-fixed-pitch
|
||||
'(:foundry "apple" :family "Fira Code" :height 160)
|
||||
"Contents to be passed to (`set-face-attribute' 'fixed-pitch nil [...]) ")
|
||||
(defvar ./face-variable-pitch
|
||||
'(:foundry "apple" :family "Inter" :height 170)
|
||||
"Contents to be passed to (`set-face-attribute' 'variable-pitch nil [...]) ")
|
||||
|
||||
(load (locate-user-emacs-file "dotslash-local-pre.el") :no-error :no-message)
|
||||
|
||||
(setq custom-file (expand-file-name "custom.el" user-emacs-directory))
|
||||
(defun display-startup-echo-area-message ()
|
||||
(message (format "Emacs %s loaded from %s in %s"
|
||||
emacs-version user-emacs-directory (emacs-init-time))))
|
||||
|
||||
(setq initial-scratch-message
|
||||
(concat ";; *SCRATCH*\n"
|
||||
";; C-c C-b (eval-buffer) C-c C-r (eval-region)\n"
|
||||
";; C-x C-s will let you choose where to save\n\n; "))
|
||||
|
||||
;; Setting this in early-init doesn't seem to work
|
||||
(set-frame-position (selected-frame) 100 10)
|
||||
(set-face-attribute 'default nil :height 160)
|
||||
|
||||
(add-to-list 'bdf-directory-list "~/Library/Fonts")
|
||||
|
||||
;; (custom-theme-set-faces
|
||||
;; 'user
|
||||
;; '(variable-pitch ((t (:inherit ./face-variable-pitch))))
|
||||
;; '(fixed-pitch ((t (:inherit ./face-fixed-pitch)))))
|
||||
|
||||
(apply #'set-face-attribute 'variable-pitch nil ./face-variable-pitch)
|
||||
(apply #'set-face-attribute 'fixed-pitch nil ./face-fixed-pitch)
|
||||
(apply #'set-face-attribute 'default nil ./face-fixed-pitch)
|
||||
|
||||
;;(global-display-line-numbers-mode 1)
|
||||
(add-hook 'prog-mode-hook (lambda () (display-line-numbers-mode 1)))
|
||||
(add-hook 'text-mode-hook (lambda () (display-line-numbers-mode 1)))
|
||||
|
||||
;; I think this saves the last cursor pos or something
|
||||
;; FIXME: doesn't work
|
||||
(require 'saveplace)
|
||||
(setq-default save-place t)
|
||||
(setq save-place-file (expand-file-name ".places" user-emacs-directory))
|
||||
|
||||
(setq make-backup-files nil)
|
||||
(setq auto-save-default nil)
|
||||
(setq-default major-mode 'text-mode)
|
||||
(setq sentence-end-double-space nil)
|
||||
|
||||
;; Always tabs except for *.go?
|
||||
;; TODO: set up language mode packages
|
||||
(setq-default c-basic-offset 4
|
||||
tab-width 4
|
||||
indent-tabs-mode nil)
|
||||
;; Some modes
|
||||
(recentf-mode 1)
|
||||
(show-paren-mode 1)
|
||||
(setq electric-pair-inhibit-predicate 'electric-pair-conservative-inhibit)
|
||||
(electric-pair-mode 1)
|
||||
(winner-mode 1)
|
||||
(delete-selection-mode 1) ;; Select and type would replace the selected text
|
||||
|
||||
;; IDK
|
||||
(add-hook 'prog-mode-hook #'subword-mode)
|
||||
(add-hook 'minibuffer-setup-hook #'subword-mode)
|
||||
|
||||
(add-hook 'elisp-mode-hook
|
||||
(lambda ()
|
||||
;; These are never used...
|
||||
;; (local-set-key (kbd "C-c C-x") #'ielm)
|
||||
;; (local-set-key (kbd "C-c C-c") #'eval-defun)
|
||||
(local-set-key (kbd "C-c C-r") 'eval-region)
|
||||
(local-set-key (kbd "C-c C-b") #'eval-buffer)))
|
||||
|
||||
(setq window-divider-default-right-width 8)
|
||||
(setq window-divider-default-places 'right-only)
|
||||
(window-divider-mode 1)
|
||||
|
||||
(defun ./org-insert-src (beg end)
|
||||
"Insert (or wrap region with, or cancel) src block.
|
||||
|
||||
If cursor currently on an empty line, it is wrapped in src block, with
|
||||
no other content in the src block other than the empty line, then the
|
||||
src block together with the line after it (if empty) is deleted. This
|
||||
undoes the effect of ./org-insert-src without active region, and
|
||||
cancelling org-edit-src with C-c C-k.
|
||||
|
||||
Code type is prompted and `org-edit-src-code' called only for insert,
|
||||
not for wrap.
|
||||
|
||||
Uses 'elisp' if currently in user-emacs-directory."
|
||||
(interactive (if (use-region-p)
|
||||
(list (region-beginning) (region-end))
|
||||
(list (point-min) (point-min))))
|
||||
(let ((selection (buffer-substring-no-properties beg end))
|
||||
(code-type '(if (string=
|
||||
(file-truename user-emacs-directory)
|
||||
(file-name-directory (buffer-file-name)))
|
||||
"elisp"
|
||||
(read-from-minibuffer "#+BEGIN_SRC "))))
|
||||
(if (< (length selection) 2)
|
||||
(if (./org-empty-src-p)
|
||||
;; Delete empty src block and exit
|
||||
(progn
|
||||
(previous-line)
|
||||
(delete-line) ;; Newline also deleted
|
||||
(delete-line)
|
||||
(delete-line)
|
||||
;; Delete empty line inserted by ./org-insert-src itself
|
||||
(if (./match-line-p "")
|
||||
(delete-line)))
|
||||
;; Otherwise:
|
||||
;; Insert src block with given code type and edit
|
||||
(progn
|
||||
(setq code-type (eval code-type))
|
||||
(deactivate-mark)
|
||||
(beginning-of-line)
|
||||
(newline)
|
||||
(insert (format "#+BEGIN_SRC %s\n" code-type))
|
||||
(newline)
|
||||
(insert "#+END_SRC\n")
|
||||
(previous-line 2)
|
||||
(org-edit-src-code)))
|
||||
;; Wrap selected region
|
||||
;;(setq code-type (eval code-type))
|
||||
(goto-char beg)
|
||||
(previous-line) (end-of-line)
|
||||
(newline)
|
||||
(insert "#+BEGIN_SRC ")
|
||||
;; save-excursion doesn't seem to work here
|
||||
(goto-char (+ end 11)) (end-of-line)
|
||||
(newline)
|
||||
(insert "#+END_SRC")
|
||||
;; FIXME: putting cursor at the begin src part afterwards doesn't work
|
||||
(re-search-backward "^\\s-*#\\+BEGIN_SRC")
|
||||
(end-of-line))))
|
||||
|
||||
(defun ./match-line-p (regexp &optional move keep-pos start)
|
||||
"Wrapper around string-match-p to use contents of current line.
|
||||
|
||||
Returns whether current line, after moving down by MOVE lines, can be
|
||||
matched with REGEXP.
|
||||
|
||||
If REGEXP is an empty string, return t for empty line, nil otherwise.
|
||||
MOVE argument is passed to `next-line'.
|
||||
|
||||
If REGEXP and is non-nil, REGEXP and START is passed to
|
||||
`string-match-p' with no changes, and its return-value is returned
|
||||
as-is.
|
||||
|
||||
MOVE argument is passed as-is to `next-line' immediately.
|
||||
|
||||
If KEEP-POS is non-nil, pass MOVE argument to `previous-line' after obtaining
|
||||
contents of the required line."
|
||||
(next-line move)
|
||||
(let ((line (buffer-substring-no-properties (line-beginning-position) (line-end-position))))
|
||||
(if keep-pos
|
||||
(previous-line move))
|
||||
(if (= (length regexp) 0)
|
||||
(if (= (length line) 0)
|
||||
t nil)
|
||||
(string-match-p regexp line start))))
|
||||
|
||||
(defun ./org-empty-src-p ()
|
||||
"Return whether point is within a org src block with a single empty line."
|
||||
(let ((line))
|
||||
(save-excursion
|
||||
(if (./match-line-p "^\\s-*#\\+begin_src" -1)
|
||||
(if (./match-line-p "" +1)
|
||||
(if (./match-line-p "^\\s-*#\\+end_src" +1)
|
||||
t nil) nil) nil))))
|
||||
|
||||
(defun ./org-split-src ()
|
||||
"Split current src block into two blocks at point.
|
||||
|
||||
Retains src properties."
|
||||
(interactive)
|
||||
(insert "#+END_SRC\n\n")
|
||||
(save-excursion
|
||||
(re-search-backward "^\\s-*#\\+begin_src")
|
||||
(defvar beginsrc (buffer-substring-no-properties (line-beginning-position) (line-end-position))))
|
||||
(insert beginsrc)
|
||||
(previous-line))
|
||||
|
||||
(defun ./load-directory (dir)
|
||||
"Load *.el files in a given directory"
|
||||
(let ((load-it (lambda (f)
|
||||
(load-file (concat (file-name-as-directory dir) f)))))
|
||||
(mapc load-it (directory-files dir nil "\\.el$"))))
|
||||
|
||||
(defun ./load-file-if-exists (file)
|
||||
"Same as load-file but NOP if file does not exist"
|
||||
(if (file-exists-p file)
|
||||
(load-file file)))
|
||||
|
||||
(defun toggle-window-split ()
|
||||
(interactive)
|
||||
(if (= (count-windows) 2)
|
||||
(let* ((this-win-buffer (window-buffer))
|
||||
(next-win-buffer (window-buffer (next-window)))
|
||||
(this-win-edges (window-edges (selected-window)))
|
||||
(next-win-edges (window-edges (next-window)))
|
||||
(this-win-2nd (not (and (<= (car this-win-edges)
|
||||
(car next-win-edges))
|
||||
(<= (cadr this-win-edges)
|
||||
(cadr next-win-edges)))))
|
||||
(splitter
|
||||
(if (= (car this-win-edges)
|
||||
(car (window-edges (next-window))))
|
||||
'split-window-horizontally
|
||||
'split-window-vertically)))
|
||||
(delete-other-windows)
|
||||
(let ((first-win (selected-window)))
|
||||
(funcall splitter)
|
||||
(if this-win-2nd (other-window 1))
|
||||
(set-window-buffer (selected-window) this-win-buffer)
|
||||
(set-window-buffer (next-window) next-win-buffer)
|
||||
(select-window first-win)
|
||||
(if this-win-2nd (other-window 1))))))
|
||||
|
||||
(defvar elpaca-installer-version 0.5)
|
||||
(defvar elpaca-directory (expand-file-name "elpaca/" user-emacs-directory))
|
||||
(defvar elpaca-builds-directory (expand-file-name "builds/" elpaca-directory))
|
||||
(defvar elpaca-repos-directory (expand-file-name "repos/" elpaca-directory))
|
||||
(defvar elpaca-order '(elpaca :repo "https://github.com/progfolio/elpaca.git"
|
||||
:ref nil
|
||||
:files (:defaults (:exclude "extensions"))
|
||||
:build (:not elpaca--activate-package)))
|
||||
(let* ((repo (expand-file-name "elpaca/" elpaca-repos-directory))
|
||||
(build (expand-file-name "elpaca/" elpaca-builds-directory))
|
||||
(order (cdr elpaca-order))
|
||||
(default-directory repo))
|
||||
(add-to-list 'load-path (if (file-exists-p build) build repo))
|
||||
(unless (file-exists-p repo)
|
||||
(make-directory repo t)
|
||||
(when (< emacs-major-version 28) (require 'subr-x))
|
||||
(condition-case-unless-debug err
|
||||
(if-let ((buffer (pop-to-buffer-same-window "*elpaca-bootstrap*"))
|
||||
((zerop (call-process "git" nil buffer t "clone"
|
||||
(plist-get order :repo) repo)))
|
||||
((zerop (call-process "git" nil buffer t "checkout"
|
||||
(or (plist-get order :ref) "--"))))
|
||||
(emacs (concat invocation-directory invocation-name))
|
||||
((zerop (call-process emacs nil buffer nil "-Q" "-L" "." "--batch"
|
||||
"--eval" "(byte-recompile-directory \".\" 0 'force)")))
|
||||
((require 'elpaca))
|
||||
((elpaca-generate-autoloads "elpaca" repo)))
|
||||
(progn (message "%s" (buffer-string)) (kill-buffer buffer))
|
||||
(error "%s" (with-current-buffer buffer (buffer-string))))
|
||||
((error) (warn "%s" err) (delete-directory repo 'recursive))))
|
||||
(unless (require 'elpaca-autoloads nil t)
|
||||
(require 'elpaca)
|
||||
(elpaca-generate-autoloads "elpaca" repo)
|
||||
(load "./elpaca-autoloads")))
|
||||
(add-hook 'after-init-hook #'elpaca-process-queues)
|
||||
(elpaca `(,@elpaca-order))
|
||||
|
||||
;; Install use-package support
|
||||
(elpaca elpaca-use-package
|
||||
;; Enable :elpaca use-package keyword.
|
||||
(elpaca-use-package-mode)
|
||||
;; Assume :elpaca t unless otherwise specified.
|
||||
(setq elpaca-use-package-by-default t))
|
||||
|
||||
;; Block until current queue processed.
|
||||
(elpaca-wait)
|
||||
|
||||
;;When installing a package which modifies a form used at the top-level
|
||||
;;(e.g. a package which adds a use-package key word),
|
||||
;;use `elpaca-wait' to block until that package has been installed/configured.
|
||||
;;For example:
|
||||
;;(use-package general :demand t)
|
||||
;;(elpaca-wait)
|
||||
|
||||
(dolist (path '("dotslash-lisp" "dotslash-modules"))
|
||||
(add-to-list 'load-path (locate-user-emacs-file path)))
|
||||
(require 'packages)
|
||||
(require 'init-highlight)
|
||||
|
||||
(load (locate-user-emacs-file "dotslash-local-post.el") :no-error :no-message)
|
|
@ -2,6 +2,11 @@
|
|||
#+PROPERTY: header-args:elisp :tangle ~/.config/emacs/init.el
|
||||
#+auto_tangle: t
|
||||
|
||||
#+BEGIN_SRC elisp
|
||||
;; NOTE:
|
||||
;; This file is generated from init.org
|
||||
#+END_SRC
|
||||
|
||||
* Variables
|
||||
|
||||
#+BEGIN_SRC elisp
|
||||
|
|
|
@ -2,6 +2,13 @@
|
|||
#+PROPERTY: header-args:elisp :tangle ~/.config/emacs/dotslash-modules/packages.el
|
||||
#+auto_tangle: t
|
||||
|
||||
|
||||
#+BEGIN_SRC elisp
|
||||
;; NOTE:
|
||||
;; This file is generated from packages.org
|
||||
#+END_SRC
|
||||
|
||||
|
||||
* Helpers
|
||||
|
||||
Helper variables adopted from Doom Emacs I'm not sure if I'll ever use.
|
||||
|
|
Loading…
Reference in New Issue