modular features
This commit is contained in:
parent
b4d972d618
commit
9ce4016802
|
|
@ -34,13 +34,9 @@
|
|||
;; If you edit it by hand, you could mess it up, so be careful.
|
||||
;; Your init file should contain only one such instance.
|
||||
;; If there is more than one, they won't work right.
|
||||
'(custom-safe-themes
|
||||
'("9c22d1654fbfed0285a519541b5ea76462d9b03d778d1dc34779fd38613bf7c8" "9fb561389e5ac5b9ead13a24fb4c2a3544910f67f12cfcfe77b75f36248017d0" "88f7ee5594021c60a4a6a1c275614103de8c1435d6d08cc58882f920e0cec65e" "aec7b55f2a13307a55517fdf08438863d694550565dee23181d2ebd973ebd6b8" "014cb63097fc7dbda3edf53eb09802237961cbb4c9e9abd705f23b86511b0a69" "81f53ee9ddd3f8559f94c127c9327d578e264c574cda7c6d9daddaec226f87bb" "3770d0ae70172461ee0a02edcff71b7d480dc54066e8960d8de9367d12171efb" "f64189544da6f16bab285747d04a92bd57c7e7813d8c24c30f382f087d460a33" "f079ef5189f9738cf5a2b4507bcaf83138ad22d9c9e32a537d61c9aae25502ef" "835d934a930142d408a50b27ed371ba3a9c5a30286297743b0d488e94b225c5f" default))
|
||||
'(elfeed-feeds '("https://hnrss.org/newest"))
|
||||
'(mc/always-run-for-all t)
|
||||
'(org-agenda-files nil)
|
||||
'(package-selected-packages
|
||||
'(org-journal plan9-theme parchment-theme acme-theme wrap-region surround go-playground dired-sidebar consult persistent-scratch scratch cape kind-icon corfu eat eshell-toggle eshell-git-prompt eshell-bookmark eshell-autojump eshell-atuin elfeed vertico orderless plz ace-mc ace-jump-mode flycheck fic-mode kotlin-mode rego-mode protobuf-mode multi-web-mode mmm-mode python-mode php-mode json-mode yaml-mode go-mode plantuml-mode graphviz-dot-mode magit denote unicode-fonts nerd-icons-ibuffer nerd-icons-completion nerd-icons-dired doom-modeline which-key multiple-cursors dash async-status async consult-projectile))
|
||||
'(safe-local-variable-values
|
||||
'((flycheck-disabled-checkers emacs-lisp-checkdoc emacs-lisp)))
|
||||
'(tab-width 2))
|
||||
(custom-set-faces
|
||||
;; custom-set-faces was added by Custom.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
(defun ensure-alioth-mounted ()
|
||||
"Check if ~/alioth is mounted, and if not, mount it."
|
||||
(unless (file-exists-p "~/alioth/.exists")
|
||||
(mount-alioth-sshfs)))
|
||||
|
||||
(defun umount-alioth-sshfs ()
|
||||
"Unmount Alioth Uberspace using SSHFS."
|
||||
(interactive)
|
||||
(let ((default-directory "~"))
|
||||
(shell-command "umount ~/alioth")))
|
||||
|
||||
(defun mount-alioth-sshfs ()
|
||||
"Mount Alioth Uberspace using SSHFS."
|
||||
(interactive)
|
||||
(let ((default-directory "~"))
|
||||
(shell-command "sshfs lkn@alioth.uberspace.de:/home/lkn/ ~/alioth")))
|
||||
|
||||
(add-hook 'find-file-hook
|
||||
(lambda ()
|
||||
(when (string-prefix-p (expand-file-name "~/alioth/")
|
||||
(expand-file-name (buffer-file-name)))
|
||||
(ensure-alioth-mounted))))
|
||||
|
||||
(add-hook 'dired-mode-hook
|
||||
(lambda ()
|
||||
(when (string-prefix-p (expand-file-name "~/alioth/")
|
||||
(expand-file-name default-directory))
|
||||
(ensure-alioth-mounted))))
|
||||
|
||||
|
||||
|
||||
(provide 'feature-alioth)
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
(require 'feature-pkg)
|
||||
|
||||
(pkg/require 'plz)
|
||||
|
||||
(provide 'feature-apitest)
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
(pkg/require 'async)
|
||||
(pkg/require 'async-status)
|
||||
|
||||
(provide 'feature-async)
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
(defun ensure-alioth-mounted ()
|
||||
"Check if ~/alioth is mounted, and if not, mount it."
|
||||
(unless (file-exists-p "~/alioth/.exists")
|
||||
(mount-alioth-sshfs)))
|
||||
|
||||
(defun umount-alioth-sshfs ()
|
||||
"Unmount Alioth Uberspace using SSHFS."
|
||||
(interactive)
|
||||
(let ((default-directory "~"))
|
||||
(shell-command "umount ~/alioth")))
|
||||
|
||||
(defun mount-alioth-sshfs ()
|
||||
"Mount Alioth Uberspace using SSHFS."
|
||||
(interactive)
|
||||
(let ((default-directory "~"))
|
||||
(shell-command "sshfs lkn@alioth.uberspace.de:/home/lkn/ ~/alioth")))
|
||||
|
||||
(provide 'feature-alioth)
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
(require 'feature-pkg)
|
||||
|
||||
(pkg/require 'avy)
|
||||
|
||||
(avy-setup-default)
|
||||
(setq avy-background t)
|
||||
|
||||
(global-set-key (kbd "C-x j j") #'avy-goto-char)
|
||||
(global-set-key (kbd "C-x j c") #'avy-goto-char-2)
|
||||
(global-set-key (kbd "C-x j l") #'avy-goto-line)
|
||||
(global-set-key (kbd "C-x j w") #'avy-goto-word-1)
|
||||
(global-set-key (kbd "C-x j .") #'avy-resume)
|
||||
|
||||
(provide 'feature-avy)
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
;;; cfg-emacs.el -- configure emacs behavior and user interface
|
||||
;;;
|
||||
;;; Commentary:
|
||||
;;; Exactly what it looks like.
|
||||
;;;
|
||||
;;; Code:
|
||||
|
||||
(message "Loading base features...")
|
||||
|
||||
|
||||
(defun copy-file-path-to-clipboard ()
|
||||
"Copy the current buffer's file path to the clipboard."
|
||||
(interactive)
|
||||
(let ((filepath (buffer-file-name)))
|
||||
(when filepath
|
||||
(kill-new filepath)
|
||||
(message "Copied file path: %s" filepath))))
|
||||
|
||||
(defun my-compile-init-file ()
|
||||
"Compile the init file."
|
||||
(let ((init-file (file-truename user-init-file)))
|
||||
(when (string= (buffer-file-name) init-file)
|
||||
(byte-compile-file init-file))))
|
||||
|
||||
(defun my/setup-elisp-formatting-key ()
|
||||
"Set up the formatting key for Emacs Lisp buffers."
|
||||
(local-set-key (kbd "C-c f") 'my/format-elisp-buffer))
|
||||
(add-hook 'emacs-lisp-mode-hook #'my/setup-elisp-formatting-key)
|
||||
|
||||
(defun my/reload-init-file ()
|
||||
"Reload the Emacs init file."
|
||||
(interactive)
|
||||
(load-file user-init-file))
|
||||
|
||||
(defun my/format-elisp-buffer ()
|
||||
"Format the whole elisp buffer."
|
||||
(interactive)
|
||||
(save-excursion
|
||||
(indent-region (point-min) (point-max))))
|
||||
|
||||
(tool-bar-mode -1)
|
||||
(setq backup-by-copying t
|
||||
completion-cycle-threshold 3
|
||||
create-lockfiles nil
|
||||
delete-old-versions t
|
||||
enable-recursive-minibuffers t
|
||||
focus-follows-mouse t
|
||||
indent-tabs-mode nil
|
||||
inhibit-startup-screen t
|
||||
kept-new-versions 20
|
||||
kept-old-versions 2
|
||||
minibuffer-prompt-properties '(read-only t cursor-intangible t
|
||||
face minibuffer-prompt)
|
||||
mouse-autoselect-window t
|
||||
read-extended-command-predicate #'command-completion-default-include-p
|
||||
read-process-output-max (* 1024 1024)
|
||||
tab-always-indent 'complete
|
||||
tab-width 4
|
||||
use-short-answers t
|
||||
version-control t
|
||||
backup-directory-alist `((".*" . ,(concat user-emacs-directory "backup")))
|
||||
read-extended-command-predicate #'command-completion-default-include-p
|
||||
gc-cons-threshold 100000000
|
||||
auth-sources '("~/.authinfo.gpg")
|
||||
warning-minimum-level :emergency
|
||||
text-mode-ispell-word-completion nil
|
||||
tramp-persistency-file-name "~/.config/emacs/tramp"
|
||||
tramp-inline-compress-start-size 1000)
|
||||
|
||||
;; load custom file
|
||||
(setq custom-file (expand-file-name "custom.el" user-emacs-directory))
|
||||
(when (file-exists-p custom-file)
|
||||
(load custom-file))
|
||||
|
||||
;; compile init.el on save
|
||||
(add-hook 'after-save-hook #'my-compile-init-file)
|
||||
|
||||
;; setup base key bindings
|
||||
(global-set-key (kbd "M-/") 'dabbrev-expand)
|
||||
(global-set-key (kbd "M-s r") 'replace-regexp)
|
||||
(global-set-key (kbd "M-s M-r") 'replace-string)
|
||||
(global-set-key (kbd "C-x E n p") #'narrow-to-page)
|
||||
(global-set-key (kbd "C-x E n f") #'narrow-to-defun)
|
||||
(global-set-key (kbd "C-x E n r") #'narrow-to-region)
|
||||
(global-set-key (kbd "C-x E w") #'widen)
|
||||
(global-set-key (kbd "C-x c r") #'my/reload-init-file)
|
||||
(global-set-key (kbd "C-x y b p") 'copy-file-path-to-clipboard)
|
||||
|
||||
(provide 'feature-base)
|
||||
|
||||
;;; feature-base.el ends here.
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
(require 'eww)
|
||||
(setq shr-max-image-proportion 0.7)
|
||||
(setq shr-image-animate nil)
|
||||
(setq browse-url-browser-function 'eww-browse-url)
|
||||
|
||||
;; for pages that require JS for some stupid reason...
|
||||
(defun browse-url-xdg-open (url &optional _new-window)
|
||||
"Open URL using the default browser via `xdg-open'."
|
||||
(interactive (browse-url-interactive-arg "URL: "))
|
||||
(call-process "xdg-open" nil 0 nil url))
|
||||
|
||||
(defun eww-open-in-default-browser ()
|
||||
"Open the current EWW page in the default system browser."
|
||||
(interactive)
|
||||
(browse-url-xdg-open (eww-current-url)))
|
||||
|
||||
(define-key eww-mode-map (kbd "C-c o") 'eww-open-in-default-browser)
|
||||
|
||||
(provide 'feature-browser)
|
||||
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
;;; feature-consult-projectile.el --- consult/projectile integration
|
||||
;;; Commentary:
|
||||
;;; Integrate consult and projectile.
|
||||
;;;
|
||||
;;; Code:
|
||||
|
||||
(require 'feature-pkg)
|
||||
(require 'feature-consult)
|
||||
(require 'feature-projectile)
|
||||
|
||||
(defun my-consult-projectile-find-file ()
|
||||
"Use consult-projectile-find-file, consult-find-file outside of project."
|
||||
(interactive)
|
||||
(if (projectile-project-p)
|
||||
(consult-projectile-find-file)
|
||||
(consult-projectile)))
|
||||
|
||||
(pkg/with-eval-after-load
|
||||
(consult projectile)
|
||||
|
||||
(advice-add 'projectile-find-file :override #'consult-projectile-find-file)
|
||||
(advice-add 'projectile-find-dir :override #'consult-projectile-find-dir)
|
||||
(advice-add 'projectile-switch-to-buffer :override #'consult-projectile-switch-to-buffer)
|
||||
(advice-add 'projectile-switch-project :override #'consult-projectile-switch-project))
|
||||
|
||||
(global-set-key (kbd "C-x p") projectile-command-map)
|
||||
(define-key projectile-command-map (kbd "f") #'consult-projectile-find-file)
|
||||
(define-key projectile-command-map (kbd "d") #'consult-projectile-find-dir)
|
||||
(define-key projectile-command-map (kbd "b") #'consult-projectile-switch-to-buffer)
|
||||
(define-key projectile-command-map (kbd "s") #'consult-projectile-switch-project)
|
||||
(define-key projectile-command-map (kbd "p") #'consult-projectile)
|
||||
(define-key projectile-command-map (kbd "/") #'consult-ripgrep)
|
||||
(define-key projectile-command-map (kbd "f") #'my-consult-projectile-find-file)
|
||||
|
||||
(provide 'feature-consult-projectile)
|
||||
|
||||
;;; feature-consult-projectile.el ends here.
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
;;; feature-consult.el --- setup consult for emacs
|
||||
;;; Commentary:
|
||||
;;; Setup consult for Emacs.
|
||||
;;;
|
||||
;;; Code:
|
||||
|
||||
(require 'feature-pkg)
|
||||
(pkg/require 'consult)
|
||||
|
||||
(setq consult-preview-key nil)
|
||||
|
||||
;; use ripgrep
|
||||
(setq consult-ripgrep-command "rg --null --line-buffered --color=ansi --max-columns=1000 --no-heading --line-number . -e ARG OPTS")
|
||||
(setq consult-grep-command "rg --null --line-buffered --color=ansi --max-columns=1000 --no-heading --line-number . -e ARG OPTS")
|
||||
|
||||
;; mode-specific histories
|
||||
(setq consult-mode-histories
|
||||
'((comint-mode . comint-input-ring)
|
||||
(eshell-mode . eshell-history-ring)
|
||||
(geiser-repl-mode . geiser-repl--history)
|
||||
(inferior-python-mode . comint-input-ring)
|
||||
(minibuffer-local-map . consult-history)))
|
||||
|
||||
(consult-customize
|
||||
consult-theme
|
||||
:preview-key '(:debounce 0.2 any)
|
||||
consult-ripgrep consult-git-grep consult-grep
|
||||
consult-bookmark consult-recent-file consult-xref
|
||||
consult--source-bookmark consult--source-recent-file
|
||||
consult--source-project-recent-file
|
||||
:preview-key '(:debounce 0.4 any))
|
||||
|
||||
;; async search
|
||||
(setq consult-async-min-input 2
|
||||
consult-async-refresh-delay 0.15
|
||||
consult-async-input-throttle 0.2
|
||||
consult-async-input-debounce 0.1)
|
||||
|
||||
;; select xref locations with preview
|
||||
(setq xref-show-xrefs-function #'consult-xref
|
||||
xref-show-definitions-function #'consult-xref)
|
||||
|
||||
(global-set-key (kbd "C-s") #'consult-line)
|
||||
(global-set-key (kbd "C-r") #'consult-line-multi)
|
||||
(global-set-key (kbd "C-c h") #'consult-history)
|
||||
(global-set-key (kbd "C-c m") #'consult-mode-command)
|
||||
(global-set-key (kbd "C-c k") #'consult-kmacro)
|
||||
(global-set-key (kbd "C-c s") #'consult-ripgrep)
|
||||
|
||||
|
||||
(provide 'feature-consult)
|
||||
|
||||
;;; feature-consult.el ends here.
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
(defun generate-tags-for-directory (directory)
|
||||
"Generate CTAGS for the specified DIRECTORY."
|
||||
(interactive
|
||||
(list (read-directory-name "Generate tags for directory: " default-directory nil t)))
|
||||
(let ((default-directory directory))
|
||||
(shell-command "ctags -e -R .")
|
||||
(message "Tags generated for %s" directory)))
|
||||
|
||||
(global-set-key (kbd "C-x E t") 'generate-tags-for-directory)
|
||||
|
||||
(provide 'feature-ctags)
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
;;; feature-denote-index.el -- index and metadata for denote notes
|
||||
;;;
|
||||
;;; Commentary: Provides a mechanism for maintaining an index of
|
||||
;;; denote notes with useful metadata to facilitate search.
|
||||
;;;
|
||||
;;; Code:
|
||||
|
||||
(require 'feature-denote)
|
||||
|
||||
(defvar my/denote-metadata-index-file (concat denote-directory "../denote-metadata.org")
|
||||
"Path to the metadata index file.")
|
||||
|
||||
(defun my/extract-date-from-filename (file)
|
||||
"Extract date from FILE name. Assumes first 8 characters are YYYYMMDD."
|
||||
(substring (file-name-nondirectory file) 0 8))
|
||||
|
||||
(defun my/format-date (date-string)
|
||||
"Format DATE-STRING (YYYYMMDD) as YYYY-MM-DD."
|
||||
(format "%s-%s-%s"
|
||||
(substring date-string 0 4)
|
||||
(substring date-string 4 6)
|
||||
(substring date-string 6 8)))
|
||||
|
||||
(defun my/extract-summary (file)
|
||||
"Extract summary from FILE."
|
||||
(with-temp-buffer
|
||||
(insert-file-contents file)
|
||||
(goto-char (point-min))
|
||||
(when (re-search-forward "^\\* Summary$" nil t)
|
||||
(forward-line)
|
||||
(let ((start (point)))
|
||||
(if (re-search-forward "^\\*" nil t)
|
||||
(string-trim (buffer-substring-no-properties start (line-beginning-position)))
|
||||
(string-trim (buffer-substring-no-properties start (point-max))))))))
|
||||
|
||||
(defun my/update-denote-metadata-index ()
|
||||
"Update the metadata index for Denote notes in Org format."
|
||||
(interactive)
|
||||
(with-temp-file my/denote-metadata-index-file
|
||||
(insert "#+TITLE: Denote Metadata Index\n")
|
||||
(insert "#+AUTHOR: Your Name\n")
|
||||
(insert "#+DATE: " (format-time-string "%Y-%m-%d") "\n\n")
|
||||
(dolist (file (directory-files-recursively denote-directory "\\.org$"))
|
||||
(let ((file-contents (with-temp-buffer
|
||||
(insert-file-contents file)
|
||||
(buffer-string))))
|
||||
(with-temp-buffer
|
||||
(insert file-contents)
|
||||
(goto-char (point-min))
|
||||
(when (re-search-forward "^#\\+title: \\(.+\\)$" nil t)
|
||||
(let* ((title (string-trim (match-string 1)))
|
||||
(keywords (denote-extract-keywords-from-path file))
|
||||
(date-string (my/extract-date-from-filename file))
|
||||
(formatted-date (my/format-date date-string))
|
||||
(is-journal (and (listp keywords) (member "journal" keywords)))
|
||||
(summary (if is-journal
|
||||
(format "Journal entry for [%s]" formatted-date)
|
||||
(my/extract-summary file))))
|
||||
(with-current-buffer (find-file-noselect my/denote-metadata-index-file)
|
||||
(goto-char (point-max))
|
||||
(insert (format "* [[file:%s][%s]]\n" file title))
|
||||
(insert " :PROPERTIES:\n")
|
||||
(insert (format " :KEYWORDS: %s\n" keywords))
|
||||
(insert (format " :DATE: [%s]\n" formatted-date))
|
||||
(insert " :END:\n\n")
|
||||
(insert (if summary
|
||||
summary
|
||||
"No summary provided."))
|
||||
(unless (string-suffix-p "\n\n" (or summary ""))
|
||||
(insert "\n\n"))))))))))
|
||||
|
||||
|
||||
(defun my/search-denote-notes ()
|
||||
"Use consult-ripgrep to search only the Denote metadata index file."
|
||||
(interactive)
|
||||
(let* ((index-file my/denote-metadata-index-file)
|
||||
(default-directory (file-name-directory index-file))
|
||||
(file-name (file-name-nondirectory index-file))
|
||||
(consult-ripgrep-args
|
||||
(concat "rg --null --ignore-case --type org --line-buffered --color=never "
|
||||
"--max-columns=500 --no-heading --line-number "
|
||||
"--max-depth 0 "
|
||||
(shell-quote-argument file-name))))
|
||||
(if (file-exists-p index-file)
|
||||
(consult-ripgrep default-directory)
|
||||
(message "Metadata index file not found: %s" index-file))))
|
||||
|
||||
(global-set-key (kbd "C-x n /") #'my/search-denote-notes)
|
||||
|
||||
(provide 'feature-denote-index)
|
||||
|
||||
;;; feature-denote-index.el ends here
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
;;; feature-denote-multidir.el --- denote with multi-dir support
|
||||
;;; Commentary:
|
||||
;;; Extend denote with support for multiple notes directories.
|
||||
;;;
|
||||
;;; Code:
|
||||
|
||||
(require 'feature-denote)
|
||||
(require 'feature-denote-index)
|
||||
(require 'feature-alioth) ;; depends on alioth for some functions
|
||||
|
||||
(defvar my/denote-local-notes-directory "~/notes/")
|
||||
(defvar my/denote-remote-notes-directory "~/alioth/notes/")
|
||||
|
||||
(setq denote-directory my/denote-local-notes-directory)
|
||||
|
||||
(defun my/denote-open-or-create ()
|
||||
"Ensure alioth is mounted before creating or opening a note."
|
||||
(interactive)
|
||||
(ensure-alioth-mounted)
|
||||
(let ((target (denote-file-prompt nil nil :no-require-match)))
|
||||
(if (and target (file-exists-p target))
|
||||
(find-file target)
|
||||
(denote--command-with-features (denote-command-prompt) :use-file-prompt-as-def-title nil nil nil))))
|
||||
|
||||
(defun my/denote-echo-current-directory ()
|
||||
"Echo the current value of denote-directory."
|
||||
(declare (interactive-only t))
|
||||
(interactive)
|
||||
(message "Current Denote directory: %s" denote-directory))
|
||||
|
||||
(defun my/denote-directory-segment ()
|
||||
"Return the current Denote directory for the mode line."
|
||||
(when (bound-and-true-p denote-directory)
|
||||
(format " Denote:%s " (file-name-nondirectory (directory-file-name denote-directory)))))
|
||||
|
||||
(defun my/denote-switch-directory ()
|
||||
"Switch current denote working directory."
|
||||
(interactive)
|
||||
(let ((new-dir (if (string= denote-directory my/denote-local-notes-directory)
|
||||
my/denote-remote-notes-directory
|
||||
my/denote-local-notes-directory)))
|
||||
(setq denote-directory new-dir)
|
||||
(setq my/denote-metadata-index-file (concat denote-directory "../denote-metadata.org"))
|
||||
(message "Denote directory switched to %s" new-dir)))
|
||||
|
||||
(defun my/denote-use-both-directories (orig-fun &rest args)
|
||||
"Temporarily use both directories for a given ORIG-FUN and ARGS."
|
||||
(let ((original-dir denote-directory)
|
||||
(result nil))
|
||||
(setq denote-directory my/denote-local-notes-directory)
|
||||
(setq result (apply orig-fun args))
|
||||
(setq denote-directory my/denote-remote-notes-directory)
|
||||
(setq result (append result (apply orig-fun args)))
|
||||
(setq denote-directory original-dir)
|
||||
result))
|
||||
|
||||
(defun my/denote-create-note ()
|
||||
"Create a note in directory of choice."
|
||||
(interactive)
|
||||
(let* ((dirs (list my/denote-local-notes-directory my/denote-remote-notes-directory))
|
||||
(chosen-dir (completing-read "Choose directory: " dirs)))
|
||||
(let ((denote-directory chosen-dir))
|
||||
(call-interactively #'denote))))
|
||||
|
||||
(advice-add 'denote-directory-files
|
||||
:around #'my/denote-use-both-directories)
|
||||
(advice-add 'denote-directory-subdirectories
|
||||
:around #'my/denote-use-both-directories)
|
||||
|
||||
(global-set-key (kbd "C-x n f") #'my/denote-open-or-create)
|
||||
(global-set-key (kbd "C-x n n") #'my/denote-create-note)
|
||||
(global-set-key (kbd "C-x n d s") #'my/denote-switch-directory)
|
||||
(global-set-key (kbd "C-x n d d") #'my/denote-echo-current-directory)
|
||||
|
||||
(provide 'feature-denote-multidir)
|
||||
|
||||
;;; feature-denote-multidir.el ends here.
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
;;; feature-denote.el --- note taking
|
||||
;;; Commentary:
|
||||
;;; Configure denote for note taking purposes.
|
||||
;;;
|
||||
;;; Code:
|
||||
|
||||
(require 'feature-pkg)
|
||||
(require 'feature-dired)
|
||||
|
||||
(pkg/require 'denote)
|
||||
|
||||
(denote-rename-buffer-mode 1)
|
||||
|
||||
(setq denote-save-buffers nil
|
||||
denote-known-keywords '("emacs" "golang" "dev")
|
||||
denote-infer-keywords t
|
||||
denote-sort-keywords t
|
||||
denote-file-type nil
|
||||
denote-history-completion-in-prompts nil
|
||||
denote-prompts '(title keywords)
|
||||
denote-excluded-directories-regexp nil
|
||||
denote-excluded-keywords-regexp nil
|
||||
denote-rename-confirmations '(rewrite-front-matter modify-file-name)
|
||||
denote-date-prompt-use-org-read-date t
|
||||
denote-date-format nil
|
||||
denote-backlinks-show-context t)
|
||||
|
||||
(global-unset-key (kbd "C-x n"))
|
||||
(global-set-key (kbd "C-x n c") #'denote-region)
|
||||
(global-set-key (kbd "C-x n !") #'denote-date)
|
||||
(global-set-key (kbd "C-x n z") #'denote-signature)
|
||||
(global-set-key (kbd "C-x n s") #'denote-subdirectory)
|
||||
(global-set-key (kbd "C-x n S-n") #'denote-type)
|
||||
(global-set-key (kbd "C-x n t") #'denote-template)
|
||||
(global-set-key (kbd "C-x n l l") #'denote-link)
|
||||
(global-set-key (kbd "C-x n l a") #'denote-add-links)
|
||||
(global-set-key (kbd "C-x n l f") #'denote-find-link)
|
||||
(global-set-key (kbd "C-x n b l") #'denote-backlinks)
|
||||
(global-set-key (kbd "C-x n b f") #'denote-find-backlink)
|
||||
(global-set-key (kbd "C-x n r r") #'denote-rename-file)
|
||||
(global-set-key (kbd "C-x n r f") #'denote-rename-file-using-front-matter)
|
||||
(let ((map dired-mode-map))
|
||||
(define-key map (kbd "C-x n d") #'denote-dired-mode)
|
||||
(define-key map (kbd "C-x n i") #'denote-link-dired-marked-notes)
|
||||
(define-key map (kbd "C-x n k") #'denote-dired-rename-marked-files-with-keywords)
|
||||
(define-key map (kbd "C-x n r r") #'denote-dired-rename-files)
|
||||
(define-key map (kbd "C-x n r f") #'denote-dired-rename-marked-files-using-front-matter))
|
||||
|
||||
|
||||
(provide 'feature-denote)
|
||||
|
||||
;;; feature-denote.el ends here.
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
;;; feature-detached.el --- dtach for Emacs
|
||||
;;; Commentary:
|
||||
;;; Setup dtach and Emacs integration.
|
||||
;;;
|
||||
;;; Code:
|
||||
|
||||
(require 'feature-pkg)
|
||||
|
||||
(pkg/require 'detached)
|
||||
|
||||
(setq detached-terminal-data-command system-type)
|
||||
|
||||
(detached-init)
|
||||
|
||||
(global-set-key [remap async-shell-command] 'detached-shell-command)
|
||||
(global-set-key [remap compile] 'detached-compile)
|
||||
(global-set-key [remap recompile] 'detached-compile-recompile)
|
||||
(global-set-key [remap detached-open-session] 'detached-consult-session)
|
||||
|
||||
(provide 'feature-detached)
|
||||
|
||||
;;; feature-detached.el ends here.
|
||||
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
;;; feature-dired.el --- dired stuff
|
||||
;;; Commentary:
|
||||
;;; Configure Dired stuff.
|
||||
;;;
|
||||
;;; Code:
|
||||
|
||||
(require 'feature-pkg)
|
||||
(require 'dired)
|
||||
|
||||
(pkg/require 'dired-sidebar)
|
||||
|
||||
(defun my/dired-duplicate-file (file)
|
||||
"Duplicate the current FILE in Dired."
|
||||
(interactive "p")
|
||||
(let ((filename (dired-get-filename))
|
||||
(target '()))
|
||||
(setq target (concat (file-name-sans-extension filename)
|
||||
"-old"
|
||||
(if (> file 1) (number-to-string file))
|
||||
(file-name-extension filename t)))
|
||||
(if (file-directory-p filename)
|
||||
(copy-file filename target))))
|
||||
|
||||
(global-set-key (kbd "<f12>") 'dired-sidebar-toggle-sidebar)
|
||||
(define-key dired-mode-map (kbd "C-c d") 'my/dired-duplicate-file)
|
||||
|
||||
(provide 'feature-dired)
|
||||
|
||||
;;; feature-dired.el ends here.
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
(require 'feature-pkg)
|
||||
(pkg/require 'embark)
|
||||
|
||||
(setq prefix-help-command #'embark-prefix-help-command)
|
||||
|
||||
(add-to-list 'display-buffer-alist
|
||||
'("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
|
||||
nil
|
||||
(window-parameters (mode-line-format . none))))
|
||||
|
||||
(global-set-key (kbd "C-.") #'embark-act)
|
||||
(global-set-key (kbd "C-;") #'embark-dwim)
|
||||
(global-set-key (kbd "C-h B") #'embark-bindings)
|
||||
|
||||
(provide 'feature-embark)
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
;;; feature-eshell.el --- eshell enhancements.
|
||||
;;; Commentary:
|
||||
;;; Configure eshell enhancements.
|
||||
;;;
|
||||
;;; Code:
|
||||
|
||||
(require 'feature-pkg)
|
||||
|
||||
(pkg/require 'eshell)
|
||||
(pkg/require 'eshell-autojump)
|
||||
(pkg/require 'eshell-bookmark)
|
||||
(pkg/require 'eshell-git-prompt)
|
||||
(pkg/require 'eshell-toggle)
|
||||
|
||||
(global-set-key (kbd "C-<escape>") #'eshell-toggle)
|
||||
|
||||
(provide 'feature-eshell)
|
||||
|
||||
;;; feature-eshell.el ends here.
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
;; themes
|
||||
(pkg/require 'acme-theme)
|
||||
|
||||
;; modeline
|
||||
(pkg/require 'doom-modeline)
|
||||
(doom-modeline-mode 1)
|
||||
|
||||
;; icons
|
||||
(pkg/require 'nerd-icons)
|
||||
(pkg/require 'nerd-icons-dired)
|
||||
(pkg/require 'nerd-icons-completion)
|
||||
(pkg/require 'nerd-icons-ibuffer)
|
||||
(pkg/require 'kind-icon)
|
||||
|
||||
(add-hook 'dired-mode-hook #'nerd-icons-dired-mode)
|
||||
|
||||
;; fonts
|
||||
(pkg/require 'unicode-fonts)
|
||||
|
||||
(provide 'feature-eyecandy)
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
(pkg/require 'go-playground)
|
||||
|
||||
(provide 'feature-golang-playground)
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
(pkg/require 'go-mode)
|
||||
|
||||
(add-to-list 'auto-mode-alist '("\\.go$" . go-mode))
|
||||
(add-hook 'before-save-hook #'gofmt-before-save)
|
||||
|
||||
(provide 'feature-golang)
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
(pkg/require 'graphviz-dot-mode)
|
||||
|
||||
(with-eval-after-load 'org
|
||||
(org-babel-do-load-languages
|
||||
'org-babel-load-languages '((dot . t))))
|
||||
|
||||
(provide 'feature-graphviz)
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
(pkg/require 'json-mode)
|
||||
|
||||
(add-to-list 'auto-mode-alist '("\\.json$" . json-mode))
|
||||
|
||||
(provide 'feature-json)
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
(pkg/require 'kotlin-mode)
|
||||
|
||||
;;(add-to-list 'auto-mode-alist ("\\.kt$" . kotlin-mode))
|
||||
|
||||
(provide 'feature-kotlin)
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
(require 'feature-pkg)
|
||||
|
||||
(pkg/require 'ellama)
|
||||
(require 'llm-ollama)
|
||||
|
||||
(setq ellama-language "English")
|
||||
(setq ellama-provider 'ollama)
|
||||
(setq ellama-ollama-binary "/usr/local/bin/ollama")
|
||||
|
||||
(setopt ellama-provider
|
||||
(make-llm-ollama
|
||||
:chat-model "codellama:latest"
|
||||
:embedding-model "nomic-embed-text"
|
||||
:default-chat-non-standard-params '(("num_ctx" . 8192))))
|
||||
|
||||
(setq ellama-keymap-prefix "C-x A e")
|
||||
(with-eval-after-load 'ellama
|
||||
(ellama-setup-keymap))
|
||||
|
||||
|
||||
(pkg/require 'org-ai)
|
||||
(add-hook 'org-mode-hook #'org-ai-mode)
|
||||
|
||||
(provide 'feature-llm)
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
(require 'feature-pkg)
|
||||
|
||||
(straight-use-package
|
||||
'(lmtf :type git :host github :repo "lneely/lmtf"))
|
||||
|
||||
(with-eval-after-load 'lmtf
|
||||
(define-key emacs-lisp-mode-map (kbd "C-c t !") #'lmtf-run-all-tests)
|
||||
(define-key emacs-lisp-mode-map (kbd "C-c t r") #'lmtf-show-results))
|
||||
|
||||
(provide 'feature-lmtf)
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
;;; feature-magit.el --- git integration
|
||||
;;; Commentary:
|
||||
;;; Setup git integration with Emacs.
|
||||
;;;
|
||||
;;; Code:
|
||||
|
||||
(require 'feature-pkg)
|
||||
|
||||
(pkg/require 'magit)
|
||||
|
||||
(setq magit-display-buffer-function
|
||||
#'magit-display-buffer-same-window-except-diff-v1)
|
||||
|
||||
;; git reset --soft $(git merge-base branch1 branch2)
|
||||
(defun magit-reset-to-merge-base ()
|
||||
"Reset to merge-base of two branches using Magit's branch selection."
|
||||
(interactive)
|
||||
(require 'magit)
|
||||
(let* ((branch1 (magit-read-branch "Select first branch: "))
|
||||
(branch2 (magit-read-branch "Select second branch: "))
|
||||
(merge-base (magit-git-string "merge-base" branch1 branch2)))
|
||||
(if merge-base
|
||||
(progn
|
||||
(magit-reset-internal "--soft" merge-base)
|
||||
(message "Reset to merge-base of %s and %s" branch1 branch2))
|
||||
(user-error "No merge-base found between %s and %s" branch1 branch2))))
|
||||
|
||||
;; git reset --soft @{u}
|
||||
(defun magit-reset-to-upstream ()
|
||||
"Reset to upstream of the current branch using Magit."
|
||||
(interactive)
|
||||
(require 'magit)
|
||||
(let ((current-branch (magit-get-current-branch)))
|
||||
(if current-branch
|
||||
(let ((upstream (magit-get-upstream-branch current-branch)))
|
||||
(if upstream
|
||||
(progn
|
||||
(magit-reset-internal "--soft" "@{u}")
|
||||
(message "Reset to upstream of %s (%s)" current-branch upstream))
|
||||
(user-error "No upstream branch set for %s" current-branch)))
|
||||
(user-error "Not on a branch"))))
|
||||
|
||||
(defvar my/magit-prefix-map (make-sparse-keymap))
|
||||
(define-key ctl-x-map "g" my/magit-prefix-map)
|
||||
(define-key my/magit-prefix-map "g" #'magit-status)
|
||||
(define-key my/magit-prefix-map "rb" #'magit-reset-to-merge-base)
|
||||
(define-key my/magit-prefix-map "ru" #'magit-reset-to-upstream)
|
||||
(define-key my/magit-prefix-map "ll" #'magit-log)
|
||||
(define-key my/magit-prefix-map "la" #'magit-log-all)
|
||||
(define-key my/magit-prefix-map "lf" #'magit-log-buffer-file)
|
||||
(define-key my/magit-prefix-map "Rs" #'magit-reset-soft)
|
||||
(define-key my/magit-prefix-map "Rh" #'magit-reset-hard)
|
||||
(define-key my/magit-prefix-map "!" #'magit-run)
|
||||
(define-key my/magit-prefix-map "bb" #'magit-branch)
|
||||
(define-key my/magit-prefix-map "bc" #'magit-branch-create)
|
||||
(define-key my/magit-prefix-map "bs" #'magit-branch-checkout)
|
||||
(define-key my/magit-prefix-map "mm" #'magit-merge)
|
||||
(define-key my/magit-prefix-map "dd" #'magit-diff)
|
||||
|
||||
(provide 'feature-magit)
|
||||
|
||||
;;; feature-magit.el ends here.
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
;;; feature-multi-cursor.el --- multiple cursors
|
||||
;;; Commentary:
|
||||
;;; Multiple cursor support for Emacs.
|
||||
;;;
|
||||
;;; Code:
|
||||
|
||||
(require 'feature-pkg)
|
||||
(pkg/require 'multiple-cursors)
|
||||
|
||||
(multiple-cursors-mode 1)
|
||||
|
||||
(global-set-key (kbd "C-x C-<") 'mc/edit-lines)
|
||||
(global-set-key (kbd "C->") 'mc/mark-next-like-this)
|
||||
(global-set-key (kbd "C-<") 'mc/mark-previous-like-this)
|
||||
(global-set-key (kbd "C-x C->") 'mc/mark-all-like-this)
|
||||
|
||||
(provide 'feature-multi-cursor)
|
||||
|
||||
;;; feature-multi-cursor.el ends here.
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
;;; feature-orderless.el --- fuzzy search
|
||||
;;; Commentary:
|
||||
;;; Setup fuzzy search for Emacs.
|
||||
;;;
|
||||
;;; Code:
|
||||
|
||||
(require 'feature-pkg)
|
||||
(pkg/require 'orderless)
|
||||
|
||||
(setq completion-styles '(orderless basic)
|
||||
completion-category-overrides '((file (styles . (partial-completion))))
|
||||
orderless-matching-styles '(orderless-flex orderless-prefixes orderless-initialism)
|
||||
orderless-component-separator #'orderless-escapable-split-on-space)
|
||||
|
||||
(provide 'feature-orderless)
|
||||
;;; feature-orderless.el ends here.
|
||||
|
|
@ -0,0 +1,133 @@
|
|||
;;; feature-org.el --- org-mode
|
||||
;;; Commentary:
|
||||
;;; Setup org-mode for Emacs.
|
||||
;;;
|
||||
;;; Code:
|
||||
|
||||
(require 'feature-pkg)
|
||||
(pkg/require 'org)
|
||||
|
||||
(defun my-org-agenda-format-item (item)
|
||||
"Format an agenda or to-do ITEM without the filename, but keep the keyword."
|
||||
(let* ((marker (or (get-text-property 0 'org-marker item)
|
||||
(get-text-property 0 'org-hd-marker item)))
|
||||
(line (when marker
|
||||
(org-with-point-at marker
|
||||
(buffer-substring (line-beginning-position) (line-end-position)))))
|
||||
(todo-keyword (when marker
|
||||
(org-with-point-at marker
|
||||
(org-get-todo-state))))
|
||||
(truncated-line (when line
|
||||
(replace-regexp-in-string "^\\[#[A-Z]\\] " "" line))))
|
||||
(if truncated-line
|
||||
(let ((clean-item (replace-regexp-in-string "^\\(\\*+ \\)" "" truncated-line)))
|
||||
(if todo-keyword
|
||||
(concat todo-keyword " " (replace-regexp-in-string (concat "^" todo-keyword " ?") "" clean-item))
|
||||
clean-item))
|
||||
item)))
|
||||
|
||||
(defun my/add-remote-todo-file ()
|
||||
"Add remote TODO.org file to org-agenda-files."
|
||||
(interactive)
|
||||
(unless org-agenda-files
|
||||
(setq org-agenda-files
|
||||
(list "~/alioth/TODO.org"))))
|
||||
|
||||
(defun my/org-config ()
|
||||
"Setup personal 'org-mode' configuration."
|
||||
(setq org-agenda-inhibit-startup t
|
||||
org-adapt-indentation nil
|
||||
org-todo-keywords '((sequence "HOLD(h)" "TODO(t)" "WAIT(w)" "|"
|
||||
"DONE(d)" "CNCL(x)"))
|
||||
org-todo-keyword-faces
|
||||
'(("HOLD" . (:foreground "orange" :weight bold))
|
||||
("TODO" . (:foreground "red" :weight bold))
|
||||
("DONE" . (:foreground "green" :weight bold))
|
||||
("CNCL" . (:foreground "gray" :weight bold)))
|
||||
org-agenda-prefix-format '((agenda . "%i %?-12t% s ")
|
||||
(todo . " %i ")
|
||||
(tags . " %i ")
|
||||
(search . " %i "))
|
||||
org-agenda-hide-tags-regexp "."
|
||||
org-agenda-todo-keyword-format "%s"
|
||||
org-archive-location "%s_archive::datetree/"
|
||||
org-log-done 'note
|
||||
org-agenda-hide-tags-regexp nil
|
||||
org-agenda-tags-column -80
|
||||
org-log-into-drawer t)
|
||||
(setq org-stuck-projects
|
||||
'("+prj/-maybe-someday" ("TODO" "WAIT" "CNCL" "prj") nil ""))
|
||||
(setq org-tags-exclude-from-inheritance '("prj")))
|
||||
|
||||
(defun my/org-refile-config ()
|
||||
"Setup org-refile targets."
|
||||
(defvar org-refile-targets)
|
||||
(defvar org-refile-use-outline-path)
|
||||
(defvar org-outline-path-complete-in-steps)
|
||||
(defvar org-refile-allow-creating-parent-nodes)
|
||||
(setq org-refile-targets
|
||||
'((nil :maxlevel . 9)
|
||||
("~/alioth/lkn/TODO.org" :maxlevel . 9))
|
||||
org-refile-use-outline-path 'file
|
||||
org-outline-path-complete-in-steps nil
|
||||
org-refile-allow-creating-parent-nodes 'confirm))
|
||||
|
||||
(defun my/org-capture-config ()
|
||||
"Setup org-capture."
|
||||
(setq org-capture-templates
|
||||
'(("t" "TODO" entry (file "~/alioth/TODO.org")
|
||||
"* TODO %?\n %i" :prepend t)))
|
||||
(with-eval-after-load 'denote
|
||||
(defvar denote-org-capture-specifiers)
|
||||
(setq denote-org-capture-specifiers "%l\n%i\n%?")
|
||||
(add-to-list 'org-capture-templates
|
||||
'("n" "New note (with denote.el)" plain
|
||||
(file denote-last-path)
|
||||
#'denote-org-capture
|
||||
:no-save t
|
||||
:immediate-finish nil
|
||||
:kill-buffer t
|
||||
:jump-to-captured t))))
|
||||
|
||||
(defun my/reload-org-config ()
|
||||
"Reload the org configuration."
|
||||
(interactive)
|
||||
(my/org-config)
|
||||
(message "Org configuration reloaded"))
|
||||
|
||||
(defun my/visit-todo ()
|
||||
"Visit TODO.org in home."
|
||||
(interactive)
|
||||
(find-file "~/alioth/TODO.org"))
|
||||
|
||||
(defun my/kill-all-org-agenda-buffers ()
|
||||
"Close all org-agenda-related buffers."
|
||||
(interactive)
|
||||
(dolist (buffer (buffer-list))
|
||||
(with-current-buffer buffer
|
||||
(when (or (derived-mode-p 'org-agenda-mode)
|
||||
(and (buffer-file-name)
|
||||
(member (buffer-file-name) (org-agenda-files))))
|
||||
(kill-buffer buffer))))
|
||||
(message "Closed all org-agenda-related buffers."))
|
||||
|
||||
(add-to-list 'auto-mode-alist '("\\.org\\'" . org-mode))
|
||||
(advice-add 'org-agenda :before #'my/add-remote-todo-file)
|
||||
(advice-add 'org-agenda-format-item-line
|
||||
:filter-return #'my-org-agenda-format-item)
|
||||
(advice-add 'org-agenda-format-item
|
||||
:filter-return #'my-org-agenda-format-item)
|
||||
(org-babel-do-load-languages 'org-babel-load-languages
|
||||
'((shell . t)))
|
||||
|
||||
|
||||
;; key bindings
|
||||
(global-set-key (kbd "C-x c O") 'my/reload-org-config)
|
||||
(global-set-key (kbd "C-x O a") 'org-agenda)
|
||||
(global-set-key (kbd "C-x O c") 'org-capture)
|
||||
(global-set-key (kbd "C-x O t") 'my/visit-todo)
|
||||
(global-set-key (kbd "C-x O k") 'my/kill-all-org-agenda-buffers)
|
||||
|
||||
(provide 'feature-org)
|
||||
|
||||
;;; feature-org.el ends here.
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
(require 'package)
|
||||
(with-eval-after-load 'package
|
||||
(add-to-list 'package-archives
|
||||
'("melpa" . "https://melpa.org/packages/")
|
||||
'("nongnu" . "https://elpa.nongnu.org/nongnu/")))
|
||||
(package-initialize)
|
||||
|
||||
;; install straight.el
|
||||
(defvar bootstrap-version)
|
||||
(let ((bootstrap-file
|
||||
(expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
|
||||
(bootstrap-version 5))
|
||||
(unless (file-exists-p bootstrap-file)
|
||||
(with-current-buffer
|
||||
(url-retrieve-synchronously
|
||||
"https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
|
||||
'silent 'inhibit-cookies)
|
||||
(goto-char (point-max))
|
||||
(eval-print-last-sexp)))
|
||||
(load bootstrap-file nil 'nomessage))
|
||||
|
||||
(defun pkg/ensure-installed (package)
|
||||
"Ensure that PACKAGE is installed."
|
||||
(unless (package-installed-p package)
|
||||
(package-refresh-contents)
|
||||
(package-install package)))
|
||||
|
||||
(defmacro pkg/require (feature &optional filename noerror)
|
||||
"Ensure FEATURE is installed, then require it.
|
||||
FILENAME and NOERROR are passed to `require'."
|
||||
`(progn
|
||||
(pkg/ensure-installed ,feature)
|
||||
(require ,feature ,filename ,noerror)))
|
||||
|
||||
(defmacro pkg/require-defer (feature &optional filename noerror)
|
||||
"Defer loading of FEATURE until it's actually needed.
|
||||
Ensure FEATURE is installed first.
|
||||
FILENAME, if non-nil, is the file to load to provide FEATURE.
|
||||
If NOERROR is non-nil, don't signal an error if the file is not found."
|
||||
`(progn
|
||||
(pkg/ensure-installed ,feature)
|
||||
(unless (featurep ',feature)
|
||||
(autoload #',(intern (format "%s-autoloaded" feature))
|
||||
,(or filename (symbol-name feature))
|
||||
nil t)
|
||||
(defalias ',feature #',(intern (format "%s-autoloaded" feature))))
|
||||
',feature))
|
||||
|
||||
(defun pkg/require-defer-load (feature)
|
||||
"Check if a deferred FEATURE is already loaded."
|
||||
(unless (featurep feature)
|
||||
(unload-feature feature t)
|
||||
(require feature)
|
||||
(fmakunbound (intern (format "%s-autoloaded" feature))))
|
||||
feature)
|
||||
|
||||
(defmacro pkg/require-defer-timer (feature seconds)
|
||||
"Ensure FEATURE is installed, then defer its loading by SECONDS idle time."
|
||||
`(progn
|
||||
(pkg/ensure-installed ,feature)
|
||||
(run-with-idle-timer ,seconds nil #'require ',feature)))
|
||||
|
||||
(defun pkg/packages-loaded-p (&rest packages)
|
||||
"Return t if all PACKAGES are loaded."
|
||||
(cl-every #'featurep packages))
|
||||
|
||||
(defmacro pkg/with-eval-after-load (packages &rest body)
|
||||
"Run BODY after all PACKAGES are loaded."
|
||||
`(if (apply #'pkg/packages-loaded-p ',packages)
|
||||
(progn ,@body)
|
||||
(eval-after-load (car (last ',packages))
|
||||
'(pkg/run-after-packages-load ',packages ,@body))))
|
||||
|
||||
(provide 'feature-pkg)
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
(pkg/require 'plantuml-mode)
|
||||
|
||||
(setq plantuml-default-exec-mode 'jar
|
||||
plantuml-jar-path "/usr/share/plantuml/plantuml.jar"
|
||||
org-plantuml-jar-path (expand-file-name
|
||||
"/usr/share/plantuml/plantuml.jar"))
|
||||
|
||||
(with-eval-after-load 'org
|
||||
(org-babel-do-load-languages
|
||||
'org-babel-load-languages '((plantuml . t))))
|
||||
|
||||
(provide 'feature-plantuml)
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
;;; feature-projectile.el --- project management
|
||||
;;; Commentary:
|
||||
;;; Project management for Emacs nerds.
|
||||
;;;
|
||||
;;; Code:
|
||||
|
||||
(require 'feature-pkg)
|
||||
(pkg/require 'projectile)
|
||||
|
||||
(projectile-mode +1)
|
||||
|
||||
(provide 'feature-projectile)
|
||||
|
||||
;;; feature-projectile.el ends here.
|
||||
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
(pkg/require 'protobuf-mode)
|
||||
|
||||
(add-to-list 'auto-mode-alist '("\\.proto$" . protobuf-mode))
|
||||
|
||||
(provide 'feature-protobuf)
|
||||
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
(pkg/require 'python-mode)
|
||||
(pkg/require 'python-environment)
|
||||
|
||||
(add-to-list 'auto-mode-alist '("\\.py$" . python-mode))
|
||||
(add-to-list 'auto-mode-alist '("BUILD\\'" . python-mode))
|
||||
|
||||
(provide 'feature-python)
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
(pkg/require 'rego-mode)
|
||||
|
||||
(provide 'feature-rego)
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
;;; feature-orderless.el --- rss feeds in emacs
|
||||
;;; Commentary:
|
||||
;;; Read RSS feeds in Emacs, stop browsing the web.
|
||||
;;;
|
||||
;;; Code:
|
||||
(require 'feature-pkg)
|
||||
|
||||
(pkg/require 'elfeed)
|
||||
|
||||
(provide 'feature-rss)
|
||||
|
||||
;;; feature-rss.el ends here.
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
;;; feature-scratch.el --- scratch buffer enhancements
|
||||
;;; Commentary:
|
||||
;;; Scratch buffer enhancements for Emacs.
|
||||
;;;
|
||||
;;; Code:
|
||||
|
||||
(require 'feature-pkg)
|
||||
(pkg/require 'scratch)
|
||||
(pkg/require 'persistent-scratch)
|
||||
|
||||
(defun my-set-scratch-mode ()
|
||||
"Set default scratch mode."
|
||||
(funcall 'text-mode))
|
||||
|
||||
(persistent-scratch-setup-default)
|
||||
(setq persistent-scratch-directory "~/.local/state/emacs/"
|
||||
persistent-scratch-autosave-interval 30
|
||||
persistent-scratch-what-to-save '(((:current . "*scratch*") .
|
||||
(major-mode point narrowing)))
|
||||
persistent-scratch-save-file (expand-file-name
|
||||
"scratch" persistent-scratch-directory))
|
||||
|
||||
(unless (file-exists-p persistent-scratch-directory)
|
||||
(make-directory persistent-scratch-directory t))
|
||||
|
||||
(add-hook 'scratch-create-buffer-hook 'my-set-scratch-mode)
|
||||
(add-hook 'after-init-hook #'persistent-scratch-autosave-mode)
|
||||
|
||||
(global-set-key (kbd "C-c s") #'persistent-scratch-save)
|
||||
(global-set-key (kbd "C-c r") #'persistent-scratch-restore)
|
||||
|
||||
(provide 'feature-scratch)
|
||||
|
||||
;;; feature-scratch.el ends here.
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
(require 'feature-pkg)
|
||||
|
||||
(pkg/require 'yasnippet)
|
||||
(pkg/require 'yasnippet-snippets)
|
||||
|
||||
(setq yas-snippet-dirs '("~/.config/emacs/snippets/"))
|
||||
(yas-global-mode 1)
|
||||
|
||||
(global-set-key (kbd "C-x y i") #'yas-insert-snippet)
|
||||
(global-set-key (kbd "C-x y n") #'yas-new-snippet)
|
||||
(global-set-key (kbd "C-x y v") #'yas-visit-snippet-file)
|
||||
|
||||
(add-hook 'prog-mode-hook #'yas-minor-mode)
|
||||
(add-hook 'org-mode-hook #'yas-minor-mode)
|
||||
|
||||
(provide 'feature-snippets)
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
;;; feature-syntax.el --- syntax related stuff
|
||||
;;; Commentary:
|
||||
;;; Configure syntax-related settings.
|
||||
;;;
|
||||
;;; Code:
|
||||
|
||||
(require 'feature-pkg)
|
||||
|
||||
(pkg/require 'fic-mode)
|
||||
(pkg/require 'flycheck)
|
||||
|
||||
(global-flycheck-mode)
|
||||
(setq flycheck-emacs-lisp-load-path 'inherit)
|
||||
|
||||
(provide 'feature-syntax)
|
||||
|
||||
;;; feature-syntax.el ends here.
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
;;; feature-vertico.el --- better minibuffer
|
||||
;;; Commentary:
|
||||
;;; Better minibuffer for emacs.
|
||||
;;;
|
||||
;;; Code:
|
||||
|
||||
(require 'feature-pkg)
|
||||
(pkg/require 'vertico)
|
||||
|
||||
|
||||
(vertico-mode)
|
||||
(setq vertico-cycle t
|
||||
vertico-count 13
|
||||
read-file-name-completion-ignore-case t
|
||||
read-buffer-completion-ignore-case t
|
||||
completion-ignore-case t
|
||||
completion-styles '(orderless basic)
|
||||
completion-category-defaults nil
|
||||
completion-category-overrides '((file (styles partial-completion))))
|
||||
|
||||
(pkg/with-eval-after-load
|
||||
(vertico)
|
||||
|
||||
(require 'vertico-quick)
|
||||
(define-key vertico-map (kbd "C-q") #'vertico-quick-insert)
|
||||
(define-key vertico-map (kbd "M-q") #'vertico-quick-exit))
|
||||
|
||||
(provide 'feature-vertico)
|
||||
;;; feature-vertico.el ends here.
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
(pkg/require 'mmm-mode)
|
||||
(pkg/require 'multi-web-mode)
|
||||
(pkg/require 'php-mode)
|
||||
(pkg/require 'emmet-mode)
|
||||
|
||||
(add-to-list 'auto-mode-alist '("\\.php$" . php-mode))
|
||||
|
||||
(provide 'feature-web)
|
||||
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
(pkg/require 'which-key)
|
||||
|
||||
(which-key-mode)
|
||||
|
||||
(provide 'feature-which-key)
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
(pkg/require 'yaml-mode)
|
||||
|
||||
(add-to-list 'auto-mode-alist '("\\.yml$" . yaml-mode))
|
||||
|
||||
(provide 'feature-yaml)
|
||||
1098
emacs/init.el
1098
emacs/init.el
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 02a43259e357846372672b58ba9416093493b3fb
|
||||
|
|
@ -7,4 +7,4 @@
|
|||
("aicld" "* ${1:What}\n\n#+begin_ai :service anthropic :model claude-3-5-sonnet-20240620\n[SYS]: ${2:You are a helpful assistant.}\n\n[ME]: ${0}\n#+end_ai\n" "aicld" nil nil nil "/home/lkn/.config/emacs/snippets/org-mode/aicld" nil nil)))
|
||||
|
||||
|
||||
;;; Do not edit! File generated at Tue Sep 10 15:15:33 2024
|
||||
;;; Do not edit! File generated at Sat Sep 14 15:30:36 2024
|
||||
|
|
|
|||
Loading…
Reference in New Issue