mirror of
https://github.com/fscotto/infra.git
synced 2026-09-28 03:03:49 +00:00
Refactor Emacs for authoring workflows
This commit is contained in:
@@ -1,39 +0,0 @@
|
||||
;; c.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; C / C++ fallback style (Linux-like)
|
||||
(setq c-default-style "linux"
|
||||
c-basic-offset 4
|
||||
tab-width 8)
|
||||
|
||||
(add-hook 'c-mode-common-hook
|
||||
(lambda ()
|
||||
(setq indent-tabs-mode t)))
|
||||
|
||||
;; Tree-sitter C/C++
|
||||
(setq c-ts-mode-indent-offset 4)
|
||||
(setq c++-ts-mode-indent-offset 4)
|
||||
|
||||
(with-eval-after-load 'lsp
|
||||
;; Clangd configurations
|
||||
(setq lsp-clients-clangd-args
|
||||
'("--background-index"
|
||||
"--clang-tidy"
|
||||
"--completion-style=detailed"
|
||||
"--header-insertion=never"
|
||||
"--header-insertion-decorators"
|
||||
"--pch-storage=memory"
|
||||
"--log=error"
|
||||
"--ranking-model=heuristics"
|
||||
"--malloc-trim"
|
||||
"--limit-results=500"
|
||||
"--limit-references=2000")))
|
||||
|
||||
(with-eval-after-load 'dap-mode
|
||||
(require 'dap-cpptools))
|
||||
|
||||
(add-hook 'c-ts-mode-hook #'fscotto/disable-c-formatting)
|
||||
(add-hook 'c-mode-hook #'fscotto/disable-c-formatting)
|
||||
|
||||
(provide 'c)
|
||||
|
||||
;;; c.el ends here
|
||||
@@ -1,8 +0,0 @@
|
||||
;;; docker.el -*- lexical-binding: t; -*-
|
||||
|
||||
(use-package dockerfile-mode
|
||||
:ensure t)
|
||||
|
||||
(provide 'docker)
|
||||
|
||||
;;; docker.el ends here
|
||||
@@ -1,89 +0,0 @@
|
||||
;;=================================================================
|
||||
;; Go Language Support
|
||||
;;=================================================================
|
||||
|
||||
(use-package go-ts-mode
|
||||
:ensure nil
|
||||
:mode "\\.go\\'"
|
||||
:hook
|
||||
((go-ts-mode . lsp-deferred)
|
||||
(go-ts-mode . fscotto/go-format-on-save)))
|
||||
|
||||
(use-package go-mod-ts-mode
|
||||
:ensure nil
|
||||
:mode
|
||||
(("/go\\.mod\\'" . go-mod-ts-mode)
|
||||
("/go\\.sum\\'" . go-mod-ts-mode))
|
||||
:hook
|
||||
((go-mod-ts-mode . lsp-deferred)
|
||||
;; restart gopls only when go.mod/go.sum are saved (buffer-local)
|
||||
(go-mod-ts-mode . (lambda ()
|
||||
(add-hook 'after-save-hook
|
||||
(lambda ()
|
||||
(when (lsp-workspaces)
|
||||
(lsp-restart-workspace)))
|
||||
nil t)))))
|
||||
|
||||
(with-eval-after-load 'project
|
||||
(add-to-list 'project-vc-extra-root-markers "go.mod"))
|
||||
|
||||
(with-eval-after-load 'lsp-mode
|
||||
;; gopls settings (single source of truth)
|
||||
(lsp-register-custom-settings
|
||||
'(("gopls.staticcheck" t)
|
||||
("gopls.gofumpt" t)
|
||||
;; ("gopls.experimentalWorkspaceModule" t)
|
||||
("gopls.expandWorkspaceToModule" t)
|
||||
("gopls.directoryFilters" ["-vendor"])
|
||||
("gopls.analyses.unusedparams" t)
|
||||
("gopls.analyses.shadow" t)
|
||||
("gopls.analyses.nilness" t)
|
||||
("gopls.analyses.useany" t)
|
||||
("gopls.env" ((GO111MODULE . "on"))))))
|
||||
|
||||
(with-eval-after-load 'flycheck
|
||||
;; Usa golangci-lint in Go
|
||||
(add-hook 'go-ts-mode-hook
|
||||
(lambda ()
|
||||
(setq-local flycheck-checker 'golangci-lint)
|
||||
(setq-local flycheck-check-syntax-automatically '(save mode-enabled))
|
||||
(flycheck-mode 1))))
|
||||
|
||||
(use-package dap-dlv-go
|
||||
:after (dap-mode go-ts-mode))
|
||||
|
||||
(with-eval-after-load 'dap-dlv-go
|
||||
;; Debug all tests in module
|
||||
(dap-register-debug-template
|
||||
"Go :: Debug all tests"
|
||||
(list :type "go"
|
||||
:request "launch"
|
||||
:name "Go :: Debug all tests"
|
||||
:mode "test"
|
||||
:program "${workspaceFolder}"
|
||||
:cwd "${workspaceFolder}"))
|
||||
|
||||
;; Debug tests in current package
|
||||
(dap-register-debug-template
|
||||
"Go :: Debug package tests"
|
||||
(list :type "go"
|
||||
:request "launch"
|
||||
:name "Go :: Debug package tests"
|
||||
:mode "test"
|
||||
:program "${fileDirname}"
|
||||
:cwd "${fileDirname}"))
|
||||
|
||||
;; Debug test at point
|
||||
(dap-register-debug-template
|
||||
"Go :: Debug test at point"
|
||||
(list :type "go"
|
||||
:request "launch"
|
||||
:name "Go :: Debug test at point"
|
||||
:mode "test"
|
||||
:program "${fileDirname}"
|
||||
:cwd "${fileDirname}"
|
||||
:args (list "-test.run" "${input:testName}"))))
|
||||
|
||||
(add-hook 'dap-terminated-hook
|
||||
(lambda (_)
|
||||
(delete-other-windows)))
|
||||
@@ -1,24 +0,0 @@
|
||||
;;; json.el -*- lexical-binding: t -*-
|
||||
|
||||
(defun fscotto/json-maybe-start-lsp ()
|
||||
"Start LSP for JSON buffers when lsp-mode is available."
|
||||
(when (fboundp 'lsp-deferred)
|
||||
(lsp-deferred)))
|
||||
|
||||
(use-package json-mode
|
||||
:ensure t
|
||||
:mode
|
||||
(("\\.json\\'" . json-mode)
|
||||
("\\.jsonc\\'" . json-mode))
|
||||
:hook
|
||||
(json-mode . fscotto/json-maybe-start-lsp))
|
||||
|
||||
(with-eval-after-load 'json-ts-mode
|
||||
(add-hook 'json-ts-mode-hook #'fscotto/json-maybe-start-lsp))
|
||||
|
||||
(with-eval-after-load 'jsonc-mode
|
||||
(add-hook 'jsonc-mode-hook #'fscotto/json-maybe-start-lsp))
|
||||
|
||||
(provide 'json)
|
||||
|
||||
;;; json.el ends here
|
||||
@@ -1,15 +0,0 @@
|
||||
;;; markdown.el -*- lexical-binding: t; -*-
|
||||
|
||||
(use-package markdown-mode
|
||||
:ensure t
|
||||
:mode ("\\.md\\'" . gfm-mode)
|
||||
:config
|
||||
(setq markdown-fontify-code-blocks-natively t)
|
||||
(setq markdown-live-preview-mode t))
|
||||
|
||||
(use-package markdown-toc
|
||||
:ensure t)
|
||||
|
||||
(provide 'lang/markdown)
|
||||
|
||||
;;; markdown.el ends here
|
||||
@@ -1,167 +1,69 @@
|
||||
;;; org.el -*- lexical-binding: t; -*-
|
||||
;;; org.el --- Org authoring workflow -*- lexical-binding: t; -*-
|
||||
|
||||
(use-package htmlize
|
||||
:ensure t)
|
||||
(require 'org)
|
||||
(require 'org-capture)
|
||||
(require 'org-agenda)
|
||||
(require 'org-id)
|
||||
(require 'org-tempo)
|
||||
(require 'ox)
|
||||
(require 'ox-html)
|
||||
(require 'ox-latex)
|
||||
(require 'ox-md)
|
||||
(require 'ox-odt)
|
||||
|
||||
;; Setting default directory for Org files.
|
||||
(setq org-directory "~/Org")
|
||||
(setq org-directory (expand-file-name "Org" (getenv "HOME"))
|
||||
org-default-notes-file (expand-file-name "inbox.org" org-directory)
|
||||
org-agenda-files (list org-default-notes-file
|
||||
(expand-file-name "agenda.org" org-directory)
|
||||
(expand-file-name "notes.org" org-directory)
|
||||
(expand-file-name "meetings" org-directory)
|
||||
(expand-file-name "projects" org-directory))
|
||||
org-todo-keywords '((sequence "TODO(t)" "NEXT(n)" "WAIT(w)" "|" "DONE(d)" "CANCELLED(c)"))
|
||||
org-tag-alist '((:startgroup) ("work" . ?w) ("personal" . ?p) ("meeting" . ?m)
|
||||
("documentation" . ?d) (:endgroup))
|
||||
org-startup-indented t
|
||||
org-startup-folded 'content
|
||||
org-hide-leading-stars t
|
||||
org-hide-emphasis-markers t
|
||||
org-return-follows-link t
|
||||
org-src-fontify-natively t
|
||||
org-src-tab-acts-natively t
|
||||
org-fontify-quote-and-verse-blocks t
|
||||
org-export-with-smart-quotes t
|
||||
org-html-doctype "html5"
|
||||
org-html-html5-fancy t
|
||||
org-html-head-include-default-style nil
|
||||
org-html-head "<link rel=\"stylesheet\" href=\"org.css\" type=\"text/css\" />"
|
||||
org-latex-compiler "lualatex"
|
||||
org-latex-pdf-process '("latexmk -lualatex -interaction=nonstopmode -output-directory=%o %f"))
|
||||
|
||||
(defvar org-notes-file (expand-file-name "notes.org" org-directory)
|
||||
"Default Org notes file.")
|
||||
;; Keep the LuaLaTeX dependency set small while retaining text, tables, links,
|
||||
;; and images in exported documents.
|
||||
(setq org-latex-default-packages-alist
|
||||
'(("" "amsmath" t ("lualatex" "xetex"))
|
||||
("" "fontspec" t ("lualatex" "xetex"))
|
||||
("" "graphicx" t)
|
||||
("" "longtable" nil)
|
||||
("" "hyperref" nil)))
|
||||
|
||||
(defvar org-calendar-file (expand-file-name "calendar.org" org-directory)
|
||||
"Default Org calendar file.")
|
||||
(setq org-capture-templates
|
||||
`(("t" "TODO" entry (file ,org-default-notes-file)
|
||||
"* TODO %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n")
|
||||
("n" "Note" entry (file ,(expand-file-name "notes.org" org-directory))
|
||||
"* %U %?\n")
|
||||
("m" "Meeting" entry (file+olp+datetree ,(expand-file-name "meetings/meetings.org" org-directory))
|
||||
"* %^{Title} :meeting:\n%U\n%?\n")
|
||||
("d" "Document idea" entry (file ,(expand-file-name "documentation/ideas.org" org-directory))
|
||||
"* IDEA %? :documentation:\n%U\n")))
|
||||
|
||||
(defface +org-todo-active
|
||||
'((t (:foreground "#51afef" :weight bold)))
|
||||
"Face for active Org TODO states.")
|
||||
(add-hook 'org-mode-hook #'org-indent-mode)
|
||||
(add-hook 'org-mode-hook #'visual-line-mode)
|
||||
(add-hook 'org-mode-hook #'flyspell-mode)
|
||||
|
||||
(defface +org-todo-project
|
||||
'((t (:foreground "#c678dd" :weight bold)))
|
||||
"Face for project Org TODO states.")
|
||||
|
||||
(defface +org-todo-onhold
|
||||
'((t (:foreground "#ECBE7B" :weight bold)))
|
||||
"Face for waiting Org TODO states.")
|
||||
|
||||
(defface +org-todo-cancel
|
||||
'((t (:foreground "#ff6c6b" :weight bold)))
|
||||
"Face for cancelled Org TODO states.")
|
||||
|
||||
(use-package org
|
||||
:init
|
||||
(setq org-clock-mode-line-total 'today
|
||||
org-fontify-done-headline t
|
||||
org-fontify-quote-and-verse-blocks t
|
||||
org-indent-mode t
|
||||
org-agenda-skip-unavailable-files t
|
||||
org-return-follows-link t
|
||||
org-src-fontify-natively t
|
||||
org-src-tab-acts-natively t
|
||||
org-startup-folded 'content
|
||||
org-hide-leading-stars t
|
||||
org-hide-emphasis-markers t
|
||||
org-id-link-to-org-use-this t
|
||||
org-id-track-globally t
|
||||
org-todo-keywords
|
||||
'((sequence
|
||||
"TODO(t)"
|
||||
"PROJ(p)"
|
||||
"LOOP(r)"
|
||||
"STRT(s)"
|
||||
"WAIT(w)"
|
||||
"HOLD(h)"
|
||||
"IDEA(i)"
|
||||
"|"
|
||||
"DONE(d)"
|
||||
"KILL(k)")
|
||||
(sequence
|
||||
"[ ](T)"
|
||||
"[-](S)"
|
||||
"[?](W)"
|
||||
"|"
|
||||
"[X](D)")
|
||||
(sequence
|
||||
"|"
|
||||
"OKAY(o)"
|
||||
"YES(y)"
|
||||
"NO(n)"))
|
||||
org-todo-keyword-faces
|
||||
'(("[-]" . +org-todo-active)
|
||||
("STRT" . +org-todo-active)
|
||||
("[?]" . +org-todo-onhold)
|
||||
("WAIT" . +org-todo-onhold)
|
||||
("HOLD" . +org-todo-onhold)
|
||||
("PROJ" . +org-todo-project)
|
||||
("NO" . +org-todo-cancel)
|
||||
("KILL" . +org-todo-cancel))
|
||||
org-export-backends '(html latex odt md ascii icalendar)
|
||||
org-latex-pdf-process '("pdflatex -interaction nonstopmode %f"
|
||||
"pdflatex -interaction nonstopmode %f")
|
||||
org-latex-default-class "article"
|
||||
org-html-doctype "html5"
|
||||
org-html-html5-fancy t
|
||||
org-default-notes-file (expand-file-name "inbox.org" org-directory)
|
||||
org-agenda-files (mapcar (lambda (file)
|
||||
(expand-file-name file org-directory))
|
||||
'("inbox.org" "tasks.org" "calendar.org" "notes.org"))
|
||||
org-capture-templates
|
||||
'(("t" "Task" entry
|
||||
(file org-default-notes-file)
|
||||
"* TODO %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n")
|
||||
("n" "Note" entry
|
||||
(file org-notes-file)
|
||||
"* %U %?\n")
|
||||
("e" "Event" entry
|
||||
(file org-calendar-file)
|
||||
"* %?\nSCHEDULED: %^T\n")))
|
||||
:config
|
||||
(require 'org-tempo)
|
||||
(require 'org-id)
|
||||
(require 'org-protocol)
|
||||
(add-to-list 'org-src-lang-modes '("go" . go-ts))
|
||||
(add-to-list 'org-src-lang-modes '("rust" . rust-ts))
|
||||
(add-hook 'org-mode-hook 'org-indent-mode))
|
||||
|
||||
(use-package org-appear
|
||||
:ensure t
|
||||
:hook (org-mode . org-appear-mode))
|
||||
|
||||
(use-package org-bullets
|
||||
:ensure t
|
||||
:init
|
||||
(setq org-bullets-bullet-list '("❯" "❯❯" "❯❯❯" "❯❯❯❯" "❯❯❯❯❯"))
|
||||
:config
|
||||
(add-hook 'org-mode-hook 'org-bullets-mode))
|
||||
|
||||
(use-package org-re-reveal
|
||||
:ensure t
|
||||
:init
|
||||
(setq org-re-reveal-transition 'none
|
||||
org-re-reveal-theme "dracula"))
|
||||
|
||||
(use-package org-alert
|
||||
:ensure t
|
||||
:after org
|
||||
:config
|
||||
(setq alert-default-style 'libnotify
|
||||
org-alert-interval 300
|
||||
org-alert-notify-cutoff 5
|
||||
org-alert-notify-after-event-cutoff 10
|
||||
org-alert-notification-title "Org Agenda")
|
||||
(add-hook 'org-agenda-mode-hook #'org-alert-enable))
|
||||
|
||||
(use-package ob-mermaid
|
||||
:ensure t
|
||||
:init
|
||||
(setq ob-mermaid-cli-path (or (executable-find "mmdc") "mmdc")))
|
||||
|
||||
(use-package ob-go
|
||||
:ensure t
|
||||
:after org)
|
||||
|
||||
(use-package ob-rust
|
||||
:ensure t
|
||||
:after org)
|
||||
(org-babel-do-load-languages
|
||||
'org-babel-load-languages
|
||||
'((shell . t)
|
||||
(python . t)
|
||||
(C . t)))
|
||||
|
||||
(provide 'lang/org)
|
||||
|
||||
(with-eval-after-load 'org
|
||||
(require 'ob-C)
|
||||
(require 'ob-emacs-lisp)
|
||||
(require 'ob-go)
|
||||
(require 'ob-perl)
|
||||
(require 'ob-python)
|
||||
(require 'ob-rust)
|
||||
(require 'ob-shell)
|
||||
(org-babel-do-load-languages
|
||||
'org-babel-load-languages
|
||||
'((C . t)
|
||||
(emacs-lisp . t)
|
||||
(go . t)
|
||||
(perl . t)
|
||||
(python . t)
|
||||
(rust . t)
|
||||
(shell . t))))
|
||||
|
||||
;;; org.el ends here
|
||||
|
||||
@@ -1,111 +0,0 @@
|
||||
;;; python.el -*- lexical-binding: t; -*-
|
||||
|
||||
(use-package reformatter
|
||||
:ensure t
|
||||
:demand t)
|
||||
|
||||
(with-eval-after-load 'project
|
||||
(add-to-list 'project-vc-extra-root-markers "pyproject.toml")
|
||||
(add-to-list 'project-vc-extra-root-markers "uv.lock")
|
||||
(add-to-list 'project-vc-extra-root-markers ".venv"))
|
||||
|
||||
(defun fscotto/python-project-root ()
|
||||
"Return project root for Python projects, nil otherwise."
|
||||
(when (and (featurep 'project)
|
||||
(project-current))
|
||||
(let ((root (project-root (project-current))))
|
||||
(when (or (file-exists-p (expand-file-name "pyproject.toml" root))
|
||||
(file-exists-p (expand-file-name "uv.lock" root)))
|
||||
root))))
|
||||
|
||||
(defun fscotto/python-project-has-uv-p ()
|
||||
"Return t if current project uses uv (pyproject.toml or uv.lock)."
|
||||
(when-let ((root (fscotto/python-project-root)))
|
||||
(or (file-exists-p (expand-file-name "uv.lock" root))
|
||||
(file-exists-p (expand-file-name "pyproject.toml" root)))))
|
||||
|
||||
(defun fscotto/python-project-bin (tool)
|
||||
"Return path to TOOL in .venv/bin if it exists, else nil."
|
||||
(when-let ((root (fscotto/python-project-root)))
|
||||
(let ((venv-bin (expand-file-name (concat ".venv/bin/" tool) root)))
|
||||
(when (and (file-exists-p venv-bin)
|
||||
(file-executable-p venv-bin))
|
||||
venv-bin))))
|
||||
|
||||
(defun fscotto/python-activate-project-tools ()
|
||||
"Prefer tools from the project virtualenv when available."
|
||||
(when-let* ((root (fscotto/python-project-root))
|
||||
(venv-bin (expand-file-name ".venv/bin" root))
|
||||
((file-directory-p venv-bin)))
|
||||
(make-local-variable 'exec-path)
|
||||
(add-to-list 'exec-path venv-bin)
|
||||
(setq-local process-environment (copy-sequence process-environment))
|
||||
(setenv "PATH" (concat venv-bin path-separator (getenv "PATH")))))
|
||||
|
||||
(defun fscotto/resolve-pylsp ()
|
||||
"Return the pylsp binary path if found, else nil.
|
||||
Checks: project .venv, uv tool install path, and PATH."
|
||||
(or (fscotto/python-project-bin "pylsp")
|
||||
(let ((uv-pylsp (expand-file-name "pylsp"
|
||||
(concat (getenv "HOME")
|
||||
"/.local/share/uv/tools/python-lsp-server/bin"))))
|
||||
(when (and (file-exists-p uv-pylsp)
|
||||
(file-executable-p uv-pylsp))
|
||||
uv-pylsp))
|
||||
(executable-find "pylsp")))
|
||||
|
||||
(defun fscotto/python-lsp-server-available-p ()
|
||||
"Return non-nil when a supported Python LSP server is available."
|
||||
(fscotto/resolve-pylsp))
|
||||
|
||||
(defun fscotto/python-ensure-lsp-server ()
|
||||
"Start Python LSP when its Ansible-managed pylsp executable is available."
|
||||
(cond
|
||||
((not (fboundp 'lsp-deferred))
|
||||
(message "python: lsp-mode not available"))
|
||||
((fscotto/python-lsp-server-available-p)
|
||||
(setq lsp-pylsp-server-command (fscotto/resolve-pylsp))
|
||||
(lsp-deferred))
|
||||
(t
|
||||
(message "python: pylsp not found; run the desktop Ansible profile"))))
|
||||
|
||||
(defun fscotto/python-maybe-start-lsp ()
|
||||
"Start Python LSP when pylsp is available."
|
||||
(fscotto/python-ensure-lsp-server))
|
||||
|
||||
(defun fscotto/python-setup-check-command ()
|
||||
"Use Ruff for the built-in Python check command."
|
||||
(setq-local python-check-command "ruff check"))
|
||||
|
||||
(reformatter-define fscotto/ruff-format
|
||||
:program (or (fscotto/python-project-bin "ruff") (executable-find "ruff"))
|
||||
:args '("format" "-")
|
||||
:lighter " ruff")
|
||||
|
||||
(with-eval-after-load 'python
|
||||
(add-hook 'python-mode-hook #'fscotto/python-activate-project-tools)
|
||||
(add-hook 'python-mode-hook #'fscotto/python-setup-check-command)
|
||||
(add-hook 'python-mode-hook #'fscotto/ruff-format-on-save-mode)
|
||||
(add-hook 'python-mode-hook #'fscotto/python-maybe-start-lsp))
|
||||
|
||||
(with-eval-after-load 'python-ts-mode
|
||||
(add-hook 'python-ts-mode-hook #'fscotto/python-activate-project-tools)
|
||||
(add-hook 'python-ts-mode-hook #'fscotto/python-setup-check-command)
|
||||
(add-hook 'python-ts-mode-hook #'fscotto/ruff-format-on-save-mode)
|
||||
(add-hook 'python-ts-mode-hook #'fscotto/python-maybe-start-lsp))
|
||||
|
||||
(with-eval-after-load 'lsp-mode
|
||||
(add-to-list 'lsp-language-id-configuration '(python-mode . "python"))
|
||||
(add-to-list 'lsp-language-id-configuration '(python-ts-mode . "python"))
|
||||
(setq lsp-pylsp-server-command (fscotto/resolve-pylsp))
|
||||
(setq lsp-pylsp-plugins
|
||||
'((pycodestyle nil)
|
||||
(pyflakes nil)
|
||||
(mccabe nil)
|
||||
(autopep8 nil)
|
||||
(yapf nil)))
|
||||
(add-to-list 'lsp-disabled-clients 'pyls))
|
||||
|
||||
(provide 'lang/python)
|
||||
|
||||
;;; python.el ends here
|
||||
@@ -1,11 +0,0 @@
|
||||
(with-eval-after-load 'flycheck
|
||||
(add-hook 'bash-ts-mode-hook 'flycheck-mode))
|
||||
|
||||
(use-package reformatter
|
||||
:ensure t
|
||||
:config
|
||||
(reformatter-define shfmt-format
|
||||
:program "shfmt"
|
||||
:args '("-i" "2" "-ci")))
|
||||
|
||||
(add-hook 'bash-ts-mode-hook #'shfmt-format-on-save-mode)
|
||||
@@ -1,8 +0,0 @@
|
||||
;;; yaml.el -*- lexical-binding: t; -*-
|
||||
|
||||
(use-package yaml-mode
|
||||
:ensure t)
|
||||
|
||||
(provide 'yaml)
|
||||
|
||||
;;; yaml.el ends here
|
||||
Reference in New Issue
Block a user