commit - 53b6364d5d04cee453e08bdb4300c821032b5a18
commit + c0b2845152c10034030887c686f96eab8b3c7a94
blob - b3d04c243e01df2c0d661a0edb46dbabb9d065af
blob + a5eda36186d27caae165593cf5f2ad7607941b1e
--- .gitignore
+++ .gitignore
/straight
/undo-fu-session/
/*.elc
+/fontaine-latest-state.eld
blob - 3ead197b17b7252ef3b872d0955548377ea4a1e2
blob + e958d042b0a62b7c0ebfbc7fd4f7f7ace78b9b58
--- config.org
+++ config.org
:header-args:emacs-lisp: :tangle init.el
:END:
-#+title: Emacs Configuration
+#+title: Literate Emacs configuration
#+date: 2026-07-20
#+filetags: :emacs:
;; Crank GC and disable the file-name handler for the duration of startup;
;; both are restored to sane runtime values on `emacs-startup-hook' below.
(setq bedrock--initial-gc-threshold gc-cons-threshold
- bedrock--initial-file-name-handler-alist file-name-handler-alist
+ bedrock--initial-file-name-handler-alist
+ file-name-handler-alist
gc-cons-threshold most-positive-fixnum
gc-cons-percentage 0.6
file-name-handler-alist nil
frame-resize-pixelwise t
package-enable-at-startup nil
straight-repository-branch "develop"
- straight-check-for-modifications '(check-on-save find-when-checking)
+ straight-check-for-modifications
+ '(check-on-save find-when-checking)
straight-use-package-by-default nil
straight-vc-git-default-clone-depth 1
default-frame-alist '((fullscreen . maximized)
- (font . "Go Mono-14")
(internal-border-width . 0)
(undecorated . t)))
"Restore GC threshold, GC percentage, and `file-name-handler-alist'."
(setq gc-cons-threshold (* 128 1024 1024)
gc-cons-percentage 0.1
- file-name-handler-alist bedrock--initial-file-name-handler-alist))
+ file-name-handler-alist
+ bedrock--initial-file-name-handler-alist))
(add-hook 'emacs-startup-hook #'bedrock--restore-startup-defaults)
(defvar bootstrap-version)
(let ((bootstrap-file
- (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
+ (expand-file-name "straight/repos/straight.el/bootstrap.el"
+ user-emacs-directory))
(bootstrap-version 6))
(unless (file-exists-p bootstrap-file)
(with-current-buffer
* Core settings
#+begin_src emacs-lisp
- (when (< emacs-major-version 29)
- (error "Emacs configuration only works with Emacs 29 and newer; you have version %s"
+(when (< emacs-major-version 30)
+ (error
+ "Emacs configuration only works with Emacs 30 and newer; you have version %s"
emacs-major-version))
(setopt initial-major-mode 'fundamental-mode
(menu-bar-mode -1)
(scroll-bar-mode -1))
- ;; Use Go Mono everywhere. `default' is set directly here; `fixed-pitch'
- ;; and `variable-pitch' must be pointed at it explicitly so that e.g.
- ;; `variable-pitch-mode' in org-mode still renders in Go Mono.
- (set-face-attribute 'default nil :family "Go Mono" :height 140)
- (set-face-attribute 'fixed-pitch nil :family "Go Mono" :height 1.0)
- (set-face-attribute 'variable-pitch nil :family "Go Mono" :height 1.0)
-
(unless (display-graphic-p)
(xterm-mouse-mode 1))
#+begin_src emacs-lisp
(defun bedrock--backup-file-name (fpath)
"Return a backup path for FPATH, creating parent dirs if needed."
- (let* ((backup-root-dir (concat user-emacs-directory "emacs-backup/"))
+ (let*
+ ((backup-root-dir
+ (concat user-emacs-directory "emacs-backup/"))
(file-path (replace-regexp-in-string "[A-Za-z]:" "" fpath))
(backup-file-path (replace-regexp-in-string
"//" "/"
backup-file-path))
(setopt make-backup-file-name-function #'bedrock--backup-file-name)
- (let ((auto-save-dir (expand-file-name "auto-saves/" "~/.cache/emacs"))
+ (let
+ ((auto-save-dir
+ (expand-file-name "auto-saves/" "~/.cache/emacs"))
(lock-dir (expand-file-name "locks/" "~/.cache/emacs")))
(make-directory auto-save-dir t)
(make-directory lock-dir t)
lock-file-name-transforms `((".*" ,lock-dir t))))
#+end_src
+* Fonts
+
+#+begin_src emacs-lisp
+ (use-package fontaine
+ :straight
+ t
+ :demand t
+ :bind ("C-c F" . fontaine-set-preset)
+ :init
+ (setq fontaine-latest-state-file
+ (locate-user-emacs-file "fontaine-latest-state.eld"))
+ :config
+ (setq fontaine-presets
+ '((comic-code
+ :default-family "Comic Code"
+ :default-height 120)
+ (comic-code-large
+ :default-family "Comic Code"
+ :default-height 170)
+ (codelia
+ :default-family "Codelia"
+ :default-height 130)
+ (droid-sans-mono
+ :default-family "Droid Sans Mono Dotted"
+ :default-height 130)
+ (fragment-mono
+ :default-family "Fragment Mono"
+ :default-height 130)
+ (fantasque-sans-mono
+ :default-family "Fantasque Sans Mono"
+ :default-height 140)
+ (go-mono
+ :default-family "Go Mono"
+ :default-height 120)
+ (inconsolata
+ :default-family "Inconsolata"
+ :default-weight medium
+ :default-height 120)
+ (input-mono
+ :default-family "Input Mono"
+ :default-height 120)
+ (ioskeley
+ :default-family "Ioskeley Mono Term"
+ :default-height 120)
+ (pragmatapro
+ :default-family "PragmataPro"
+ :default-height 130)
+ (0xproto
+ :default-family "0xProto"
+ :default-height 120)
+ (sudo
+ :default-family "Sudo"
+ :default-height 140)
+ (ttyp0
+ :default-family "Ttyp0 OTB"
+ :default-height 130)
+ (t
+ :default-weight regular
+ :default-slant normal
+ :fixed-pitch-family nil
+ :variable-pitch-family nil
+ :bold-weight bold
+ :italic-slant italic)))
+ (defun bedrock--fontaine-sync-variable-pitch (&rest _)
+ (set-face-attribute 'variable-pitch nil
+ :family (face-attribute 'default :family)
+ :height 1.0))
+ (add-hook 'fontaine-set-preset-hook
+ #'bedrock--fontaine-sync-variable-pitch)
+ (fontaine-mode 1)
+ (fontaine-set-preset
+ (or (fontaine-restore-latest-preset) 'go-mono)))
+#+end_src
+
* UI
#+begin_src emacs-lisp
- (use-package modus-themes
- :straight t
- :demand t
- :config
- (load-theme 'modus-operandi t))
+ (use-package modus-themes
+ :straight
+ t
+ :demand t
+ :config)
- (use-package ef-themes
- :straight t
- :commands ef-themes-select)
+ (use-package ef-themes
+ :straight
+ t
+ :demand t
+ :config)
- (use-package which-key
- :straight t
- :defer 1
- :config (which-key-mode))
+ (use-package plan9-theme
+ :straight
+ t
+ :demand t
+ :config)
- (use-package smart-mode-line
- :straight t
- :demand t
- :custom
- (sml/no-confirm-load-theme t)
- (sml/theme 'respectful)
- :config
- (sml/setup))
+ (use-package which-key
+ :straight
+ t
+ :defer 1
+ :config (which-key-mode))
- (use-package minions
- :straight t
- :demand t
- :config
- (minions-mode))
+ (use-package minions
+ :straight
+ t
+ :demand t
+ :config
+ (minions-mode))
+ (use-package mood-line
+ :straight
+ t
+ :demand t
+ :config
+ (mood-line-mode))
+
+
;; Lets `:diminish' hide minor-mode lighters from the mode line.
(use-package diminish
- :straight t
+ :straight
+ t
:demand t)
(add-to-list 'tab-bar-format 'tab-bar-format-align-right 'append)
(add-to-list 'tab-bar-format 'tab-bar-format-global 'append)
- (setopt display-time-format "%a %F %T"
+ (setopt display-time-format "%T"
display-time-interval 1)
- (display-time-mode 1)
+ (display-time-mode 0)
#+end_src
* Scrolling
#+begin_src emacs-lisp
(use-package lin
- :straight t
+ :straight
+ t
:hook ((eshell-mode . lin-mode)
(dired-mode . lin-mode)
(org-mode . lin-mode)))
(use-package pulsar
- :straight t
+ :straight
+ t
:config
(pulsar-global-mode))
(use-package diff-hl
- :straight t
+ :straight
+ t
:hook ((prog-mode . diff-hl-mode)
(org-mode . diff-hl-mode))
:config
(global-diff-hl-show-hunk-mouse-mode))
(use-package circadian
- :straight (circadian :type git :host github :repo "guidoschmidt/circadian.el")
+ :straight
+ (circadian :type git :host github :repo
+ "guidoschmidt/circadian.el")
:demand t
:config
(setopt calendar-latitude 48.1386
calendar-longitude 17.1053
- circadian-themes '((:sunrise . ef-orange)
- (:sunset . modus-vivendi)))
+ circadian-themes '((:sunrise . plan9)
+ (:sunset . plan9)))
+ ;; (:sunset . ef-tritanopia-dark)))
(circadian-setup))
#+end_src
(keymap-set minibuffer-mode-map "TAB" #'minibuffer-complete)
(use-package vertico
- :straight t
+ :straight
+ t
:init (vertico-mode))
(with-eval-after-load 'vertico
(keymap-set vertico-map "M-DEL" #'vertico-directory-delete-word))
(use-package marginalia
- :straight t
+ :straight
+ t
:config (marginalia-mode))
(use-package orderless
- :straight t
+ :straight
+ t
:config (setopt completion-styles '(orderless)))
(use-package consult
- :straight t
+ :straight
+ t
:bind (("C-x b" . consult-buffer)
("M-y" . consult-yank-pop)
("M-s r" . consult-ripgrep)
(consult-narrow-key "<"))
(use-package embark
- :straight t
+ :straight
+ t
:after consult
:bind (("C-c a" . embark-act)))
(use-package embark-consult
- :straight t
+ :straight
+ t
:after (embark consult))
(use-package corfu
- :straight t
+ :straight
+ t
:init (global-corfu-mode)
:bind (:map corfu-map
("SPC" . corfu-insert-separator)))
(corfu-popupinfo-mode))
(use-package corfu-terminal
- :straight t
+ :straight
+ t
:if (not (display-graphic-p))
:config (corfu-terminal-mode))
(use-package cape
- :straight t
+ :straight
+ t
:init
(add-to-list 'completion-at-point-functions #'cape-dabbrev)
(add-to-list 'completion-at-point-functions #'cape-file))
(use-package kind-icon
- :straight t
+ :straight
+ t
:if (display-graphic-p)
:after corfu
:config
(add-to-list 'corfu-margin-formatters #'kind-icon-margin-formatter))
(use-package wgrep
- :straight t
+ :straight
+ t
:config (setopt wgrep-auto-save-buffer t))
#+end_src
#+begin_src emacs-lisp
(use-package avy
- :straight t
+ :straight
+ t
:bind (("C-c j" . avy-goto-line)
("s-j" . avy-goto-char-timer))
:config
(select-window
(cdr (ring-ref avy-ring 0))))
t)
- (setf (alist-get ?. avy-dispatch-alist) #'bedrock-avy-action-embark))
+ (setf (alist-get ?. avy-dispatch-alist)
+ #'bedrock-avy-action-embark))
#+end_src
* Evil
#+begin_src emacs-lisp
(use-package evil
- :straight t
+ :straight
+ t
:custom
(evil-want-keybinding nil)
(evil-respect-visual-line-mode t)
(evil-set-initial-state 'eat-mode 'emacs))
(use-package evil-collection
- :straight t
+ :straight
+ t
:after evil
:config (evil-collection-init))
(use-package evil-surround
- :straight t
+ :straight
+ t
:after evil
:config (global-evil-surround-mode))
(use-package evil-commentary
- :straight t
+ :straight
+ t
:after evil
:config (evil-commentary-mode))
(use-package evil-org
- :straight t
+ :straight
+ t
:after org
:hook (org-mode . evil-org-mode)
:config
#+begin_src emacs-lisp
(use-package undo-fu
- :straight t
+ :straight
+ t
:custom
(undo-fu-allow-undo-in-region t)
(undo-fu-undo-command 'undo-fu-only-undo)
("M-/" . undo-fu-only-redo-all)))
(use-package undo-fu-session
- :straight t
+ :straight
+ t
:custom
(undo-fu-session-incompatible-files '("\\.gpg$"))
(undo-fu-session-directory
(undo-fu-session-global-mode))
(use-package vundo
- :straight t
+ :straight
+ t
:bind ("C-c u" . vundo))
(with-eval-after-load 'evil
#+begin_src emacs-lisp
(use-package helpful
- :straight t
+ :straight
+ t
:bind (("C-h f" . helpful-callable)
("C-h v" . helpful-variable)
("C-h k" . helpful-key)
#+begin_src emacs-lisp
(use-package eshell
- :straight (:type built-in)
+ :straight
+ (:type built-in)
:init
(defun bedrock-setup-eshell ()
"Bind `C-r' to `consult-history' in `eshell-mode'."
:hook (eshell-mode . bedrock-setup-eshell))
(use-package eat
- :straight t
+ :straight
+ t
:after eshell
:custom
;; A universally-installed TERM, so shells eat spawns never look up the
#+begin_src emacs-lisp
(use-package tramp
- :straight (:type built-in)
+ :straight
+ (:type built-in)
:defer t
:custom
(tramp-default-method "ssh")
#+begin_src emacs-lisp
(use-package treesit-auto
- :straight t
+ :straight
+ t
:demand t
:custom
(treesit-auto-install t)
(add-hook 'prog-mode-hook #'electric-pair-mode)
(use-package project
- :straight (:type built-in)
+ :straight
+ (:type built-in)
:custom (project-mode-line t))
(use-package magit
- :straight t
+ :straight
+ t
:bind (("C-x g" . magit-status)))
#+end_src
#+begin_src emacs-lisp
(use-package yaml-mode
- :straight t
+ :straight
+ t
:mode "\\.ya?ml\\'")
(use-package json-mode
- :straight t
+ :straight
+ t
:mode "\\.json\\'")
(use-package nix-mode
- :straight t
+ :straight
+ t
:mode "\\.nix\\'")
(use-package go-mode
- :straight t
+ :straight
+ t
:mode "\\.go\\'")
(use-package zig-mode
- :straight t
+ :straight
+ t
:mode "\\.zig\\'")
(use-package rust-mode
- :straight t
+ :straight
+ t
:mode "\\.rs\\'")
(use-package elixir-mode
- :straight t
+ :straight
+ t
:mode ("\\.exs?\\'" "mix\\.lock\\'"))
+
+ (use-package markdown-mode
+ :straight
+ t
+ :mode "\\.md\\'"
+ :hook (markdown-mode . visual-line-mode))
+
#+end_src
* LSP
#+begin_src emacs-lisp
(use-package eglot
- :straight (:type built-in)
+ :straight
+ (:type built-in)
:custom
(eglot-send-changes-idle-time 0.1)
(eglot-extend-to-xref t)
#+begin_src emacs-lisp
(use-package tempel
- :straight t
+ :straight
+ t
:bind (("M-*" . tempel-insert)
("M-+" . tempel-complete)
:map tempel-map
:init
(defun tempel-setup-capf ()
"Add `tempel-expand' to `completion-at-point-functions' locally."
- (add-hook 'completion-at-point-functions #'tempel-expand -1 'local))
+ (add-hook 'completion-at-point-functions #'tempel-expand -1
+ 'local))
(add-hook 'prog-mode-hook #'tempel-setup-capf)
(add-hook 'text-mode-hook #'tempel-setup-capf))
#+end_src
#+begin_src emacs-lisp
(use-package slime
- :straight t
+ :straight
+ t
:custom
(inferior-lisp-program "sbcl")
(slime-lisp-implementations '((sbcl ("sbcl"))))
(setopt denote-directory (expand-file-name "~/.nb/notes"))
(use-package denote
- :straight t
+ :straight
+ t
:custom
(denote-file-type 'org)
(denote-known-keywords '("daily" "comp" "music" "misc"))
(denote-rename-buffer-mode))
(use-package denote-journal
- :straight t
+ :straight
+ t
:after denote
:custom
(denote-journal-keyword "journal")
(denote-journal-file-type 'org))
(use-package denote-org
- :straight t
+ :straight
+ t
:after denote)
#+end_src
#+begin_src emacs-lisp
(setopt org-directory (expand-file-name "~/.nb/notes")
org-agenda-files (list org-directory)
- org-default-notes-file (expand-file-name "todo.org" org-directory))
+ org-default-notes-file
+ (expand-file-name "todo.org" org-directory))
(setopt org-refile-targets '((org-agenda-files :maxlevel . 3))
org-refile-use-outline-path 'file
org-outline-path-complete-in-steps nil)
(setopt org-todo-keywords
- '((sequence "TODO(t)" "WAITING(w@/!)" "STARTED(s!)" "|" "DONE(d!)" "OBSOLETE(o@)"))
+ '((sequence "TODO(t)" "WAITING(w@/!)" "STARTED(s!)" "|"
+ "DONE(d!)" "OBSOLETE(o@)"))
org-log-done 'time
org-log-into-drawer t)
(setopt org-capture-templates
- '(("t" "task" entry (file+headline org-default-notes-file "Inbox")
+ '(("t" "task" entry
+ (file+headline org-default-notes-file "Inbox")
"* TODO %?\n%U\n%i")
- ("j" "journal" plain (file denote-journal-path-to-new-or-existing-entry)
+ ("j" "journal" plain
+ (file denote-journal-path-to-new-or-existing-entry)
"%?\n%U\n%i")))
(setopt org-agenda-start-with-log-mode 'clockcheck
org-startup-with-inline-images t
org-hide-emphasis-markers t)
- (setopt org-id-link-to-org-use-id 'create-if-interactive-and-no-custom-id)
+ (setopt org-id-link-to-org-use-id
+ 'create-if-interactive-and-no-custom-id)
(setopt org-export-with-smart-quotes t)
(use-package org
- :straight (:type built-in)
+ :straight
+ (:type built-in)
:hook ((org-mode . visual-line-mode)
(org-mode . variable-pitch-mode))
:bind (:map global-map
org-cycle-separator-lines 2))
(use-package org-appear
- :straight t
+ :straight
+ t
:hook (org-mode . org-appear-mode))
(use-package org-super-agenda
- :straight t
+ :straight
+ t
:after org
:config
(org-super-agenda-mode))
#+end_src
-* Markdown
-
-#+begin_src emacs-lisp
- (use-package markdown-mode
- :straight t
- :hook (markdown-mode . visual-line-mode))
-#+end_src
-
* Key bindings
#+begin_src emacs-lisp
:doc "Prefix map for denote commands.")
(keymap-set global-map "C-c n" denote-prefix-map)
(keymap-set denote-prefix-map "n" #'denote)
- (keymap-set denote-prefix-map "j" #'denote-journal-new-or-existing-entry)
+ (keymap-set denote-prefix-map "j"
+ #'denote-journal-new-or-existing-entry)
(keymap-set denote-prefix-map "l" #'denote-insert-link)
(keymap-set denote-prefix-map "L" #'denote-add-links)
(keymap-set denote-prefix-map "o" #'denote-open-or-create)
(with-eval-after-load 'evil
(evil-set-leader '(normal visual) (kbd "SPC"))
- (evil-define-key '(normal visual) 'global (kbd "<leader>fh") #'consult-recent-file))
+ (evil-define-key '(normal visual) 'global
+ (kbd "<leader>fh") #'consult-recent-file)
+ (evil-define-key '(normal visual) 'global
+ (kbd "<leader>ff") #'project-find-file)
+ (evil-define-key '(normal visual) 'global
+ (kbd "<leader>fs") #'save-buffer))
#+end_src
* Personal extras
save-interprogram-text-before-kill t)
(use-package clipetty
- :straight t
+ :straight
+ t
:hook (after-init . clipetty-mode))
(with-eval-after-load 'eglot
(add-to-list 'eglot-server-programs
- '(purescript-mode . ("pnpx" "purescript-language-server" "--stdio")))
+ '(purescript-mode
+ . ("pnpx" "purescript-language-server" "--stdio")))
(add-to-list 'eglot-server-programs
- '((markdown-mode text-mode tex-mode typst-mode org-mode)
+ '((markdown-mode text-mode tex-mode typst-mode
+ org-mode)
. ("harper-ls" "--stdio"))))
(use-package zoom-window
- :straight t
+ :straight
+ t
:bind ("C-x z" . zoom-window-zoom))
#+end_src
#+begin_src emacs-lisp
(use-package tmr
- :straight t
+ :straight
+ t
:bind (("C-c t c" . tmr)
("C-c t l" . tmr-tabulated-view)
("C-c t k" . tmr-remove)
LLMs in Emacs. A single backend talks to Ollama Cloud over its
OpenAI-compatible endpoint; the API key is read from `auth-source'
-(default `~/.authinfo.gpg'), so no secret lives in this repository. On
+(default `~/.authinfo.gpg'), so no secret lives in this repository
+. On
top of that we register web, filesystem and Emacs tools, and a set of
presets (`@research', `@agent', per-model `@qwen' …) selectable per
request.
(defun mine/ollama-api-key ()
"Return the Ollama Cloud API key stored in auth-source.
Expects a line in `auth-sources' for host ollama.com, user apikey."
- (or (auth-source-pick-first-password :host "ollama.com" :user "apikey")
- (user-error "No Ollama API key in auth-source for host ollama.com")))
+ (or
+ (auth-source-pick-first-password :host "ollama.com" :user
+ "apikey")
+ (user-error
+ "No Ollama API key in auth-source for host ollama.com")))
(defun mine/ollama-api-post (path payload)
"POST PAYLOAD (an alist) as JSON to Ollama API PATH, return parsed JSON.
(let* ((url-request-method "POST")
(url-request-extra-headers
`(("Content-Type" . "application/json")
- ("Authorization" . ,(concat "Bearer " (mine/ollama-api-key)))))
- (url-request-data (encode-coding-string (json-encode payload) 'utf-8))
- (buf (url-retrieve-synchronously (concat "https://ollama.com" path)
+ ("Authorization"
+ . ,(concat "Bearer " (mine/ollama-api-key)))))
+ (url-request-data
+ (encode-coding-string (json-encode payload) 'utf-8))
+ (buf (url-retrieve-synchronously
+ (concat "https://ollama.com" path)
'silent nil 60)))
(unless buf (error "Ollama API request to %s timed out" path))
(unwind-protect
(with-current-buffer buf
(goto-char (point-min))
- (let ((status (and (re-search-forward "^HTTP/[0-9.]+ \\([0-9]+\\)" nil t)
+ (let ((status (and
+ (re-search-forward
+ "^HTTP/[0-9.]+ \\([0-9]+\\)" nil t)
(string-to-number (match-string 1)))))
(unless (re-search-forward "\n\n" nil t)
(error "Malformed response from Ollama API"))
(json-key-type 'symbol)
(body (json-read)))
(when (and status (>= status 400))
- (error "Ollama API %s failed (HTTP %d): %s" path status
+ (error "Ollama API %s failed (HTTP %d): %s" path
+ status
(or (alist-get 'error body) body)))
body)))
(kill-buffer buf))))
#+begin_src emacs-lisp
(use-package gptel
- :straight (gptel :type git :host github :repo "karthink/gptel")
+ :straight
+ (gptel :type git :host github :repo "karthink/gptel")
:demand t
:bind (:map gptel-mode-map
("C-c RET" . gptel-send)
(gptel-use-header-line t)
(gptel-org-ignore-elements '(property-drawer))
(gptel-directives
- '((default . "You are a large language model living in Emacs and a helpful assistant. Respond concisely.")
- (programming . "You are a careful programmer working from inside Emacs. Provide code, with minimal surrounding prose.")
- (reviewing . "You are reviewing code or text in Emacs. Be terse, point out concrete issues, and suggest fixes.")
- (literate . "You are helping with a literate configuration in an Org file. Prefer Org markup and explain only what is non-obvious.")
- (chat . "You are a conversation partner. Respond concisely.")))
+ '((default
+ . "You are a large language model living in Emacs and a helpful assistant. Respond concisely.")
+ (programming
+ . "You are a careful programmer working from inside Emacs. Provide code, with minimal surrounding prose.")
+ (reviewing
+ . "You are reviewing code or text in Emacs. Be terse, point out concrete issues, and suggest fixes.")
+ (literate
+ . "You are helping with a literate configuration in an Org file. Prefer Org markup and explain only what is non-obvious.")
+ (chat
+ . "You are a conversation partner. Respond concisely.")))
(gptel-use-tools t)
(gptel-confirm-tool-calls 'auto)
(gptel-include-tool-results 'auto)
(gptel-make-tool
:name "web_search"
:category "web"
- :description (concat "Search the web and return a list of results, each with a "
+ :description (concat
+ "Search the web and return a list of results, each with a "
"title, URL and a content snippet. Use this for current "
"events or anything outside your training data, then call "
"`web_fetch' on a promising URL to read it in full.")
:args (list '(:name "query" :type string
:description "The search query.")
'(:name "max_results" :type integer :optional t
- :description "How many results to return (1-10, default 5)."))
+ :description
+ "How many results to return (1-10, default 5)."))
:function
(lambda (query &optional max_results)
(let* ((payload `(("query" . ,query)
- ,@(when (and (integerp max_results) (> max_results 0))
+ ,@(when
+ (and (integerp max_results)
+ (> max_results 0))
`(("max_results" . ,(min max_results 10))))))
- (results (alist-get 'results (mine/ollama-api-post "/api/web_search" payload))))
+ (results
+ (alist-get 'results
+ (mine/ollama-api-post "/api/web_search"
+ payload))))
(if (null results)
"No results found."
(mapconcat
(lambda (r)
(format "## %s\n%s\n\n%s"
- (alist-get 'title r) (alist-get 'url r) (alist-get 'content r)))
+ (alist-get 'title r) (alist-get 'url r)
+ (alist-get 'content r)))
results "\n\n---\n\n")))))
(gptel-make-tool
:name "web_fetch"
:category "web"
- :description "Fetch and return the main text content of a web page, given its URL."
+ :description
+ "Fetch and return the main text content of a web page, given its URL."
:args (list '(:name "url" :type string
- :description "The full URL of the page to fetch."))
+ :description
+ "The full URL of the page to fetch."))
:function
(lambda (url)
- (let* ((resp (mine/ollama-api-post "/api/web_fetch" `(("url" . ,url))))
+ (let*
+ ((resp
+ (mine/ollama-api-post "/api/web_fetch" `(("url" . ,url))))
(content (alist-get 'content resp)))
(if (and (stringp content) (not (string-empty-p content)))
- (format "# %s\n\n%s" (or (alist-get 'title resp) url) content)
+ (format "# %s\n\n%s" (or (alist-get 'title resp) url)
+ content)
"Could not extract any content from that URL."))))
(gptel-make-tool
:name "read_url"
:category "web"
- :description (concat "Fetch a URL directly (no API) and return its rendered text. "
+ :description (concat
+ "Fetch a URL directly (no API) and return its rendered text. "
"A fallback for `web_fetch'.")
- :args (list '(:name "url" :type string :description "The URL to read."))
+ :args
+ (list '(:name "url" :type string :description "The URL to read."))
:function
(lambda (url)
(with-current-buffer (url-retrieve-synchronously url t t 30)
:category "emacs"
:description "Return the full contents of a live Emacs buffer."
:args (list '(:name "buffer" :type string
- :description "The name of the buffer to read."))
+ :description
+ "The name of the buffer to read."))
:function
(lambda (buffer)
(unless (buffer-live-p (get-buffer buffer))
:category "filesystem"
:description "Read and return the contents of a file on disk."
:args (list '(:name "filepath" :type string
- :description "Path to the file. Supports relative paths and ~."))
+ :description
+ "Path to the file. Supports relative paths and ~."))
:function
(lambda (filepath)
(with-temp-buffer
:category "filesystem"
:description "List the entries in a directory."
:args (list '(:name "directory" :type string
- :description "The path to the directory to list."))
+ :description
+ "The path to the directory to list."))
:function
(lambda (directory)
- (mapconcat #'identity (directory-files (expand-file-name directory)) "\n")))
+ (mapconcat #'identity
+ (directory-files (expand-file-name directory)) "\n")))
(gptel-make-tool
:name "run_command"
:category "command"
- :description "Execute a shell command and return its combined output."
+ :description
+ "Execute a shell command and return its combined output."
:args (list '(:name "command" :type string
- :description "The complete shell command to run.")
+ :description
+ "The complete shell command to run.")
'(:name "working_dir" :type string :optional t
- :description "Directory to run in (default: current)."))
+ :description
+ "Directory to run in (default: current)."))
:function
(lambda (command &optional working_dir)
(with-temp-message (format "Executing: %s" command)
(let ((default-directory
- (if (and working_dir (not (string-empty-p working_dir)))
+ (if
+ (and working_dir
+ (not (string-empty-p working_dir)))
(expand-file-name working_dir)
default-directory)))
(shell-command-to-string command))))
(gptel-make-tool
:name "obscura_scrape"
:category "web"
- :description (concat "Scrape a web page with the Obscura headless browser "
+ :description (concat
+ "Scrape a web page with the Obscura headless browser "
"(real JS rendering, stealth). Use this instead of "
"`web_fetch'/`read_url' for JavaScript-heavy or "
"bot-protected pages. Returns the page as markdown by "
:args (list '(:name "url" :type string
:description "The URL to scrape.")
'(:name "format" :type string :optional t
- :description "Output: markdown (default), text, html, or links.")
+ :description
+ "Output: markdown (default), text, html, or links.")
'(:name "selector" :type string :optional t
- :description "Optional CSS selector to wait for before extracting."))
+ :description
+ "Optional CSS selector to wait for before extracting."))
:function
(lambda (url &optional format selector)
(if-let* ((exe (executable-find "obscura")))
(with-temp-message (format "Obscura scraping %s" url)
(with-output-to-string
- (apply #'call-process exe nil (list standard-output nil) nil
+ (apply #'call-process exe nil
+ (list standard-output nil) nil
"fetch" url
- "--dump" (if (member format '("text" "html" "links" "markdown"))
- format "markdown")
+ "--dump" (if
+ (member format
+ '("text" "html" "links"
+ "markdown"))
+ format
+ "markdown")
"--wait-until" "networkidle0"
- (when (and selector (not (string-empty-p selector)))
+ (when
+ (and selector
+ (not (string-empty-p selector)))
(list "--selector" selector)))))
"Error: the `obscura' binary is not on PATH. Install it (https://github.com/h4ckf0r0day/obscura) or use `web_fetch'/`read_url' instead."))
:confirm t
;; Presets: apply with `C-c L p' or an `@name' cookie at the start of a prompt.
(gptel-make-preset 'research
- :description "Web research: search, fetch and scrape, then synthesise."
- :system (concat "You are a research assistant working inside Emacs. Use the "
+ :description
+ "Web research: search, fetch and scrape, then synthesise."
+ :system (concat
+ "You are a research assistant working inside Emacs. Use the "
"web tools to gather up-to-date information before answering: "
"`web_search' to find sources, `web_fetch'/`read_url' to read "
"them, and `obscura_scrape' for JavaScript-heavy or protected "
:confirm-tool-calls nil)
(gptel-make-preset 'agent
- :description "Coding agent: read files/buffers and run commands in Emacs."
- :system (concat "You are a careful coding agent operating inside Emacs. Use "
+ :description
+ "Coding agent: read files/buffers and run commands in Emacs."
+ :system (concat
+ "You are a careful coding agent operating inside Emacs. Use "
"the filesystem and buffer tools to inspect the project, and "
"`run_command' to build, test or inspect the repo. Explain "
"what you will do, then act. Prefer minimal, surgical changes.")
- :tools '("read_file" "read_buffer" "list_directory" "run_command")
+ :tools
+ '("read_file" "read_buffer" "list_directory" "run_command")
:confirm-tool-calls t)
(gptel-make-preset 'full
:description "Everything: web + filesystem + Emacs + commands."
:system 'default
:tools '("web_search" "web_fetch" "read_url" "obscura_scrape"
- "read_file" "read_buffer" "list_directory" "run_command"))
+ "read_file" "read_buffer" "list_directory"
+ "run_command"))
(gptel-make-preset 'chat
:description "Plain conversation, no tools."
(minimax . minimax-m3:cloud)
(minimax2 . minimax-m2.7:cloud)))
(gptel-make-preset (car spec)
- :description (format "Use the %s model on Ollama Cloud." (cdr spec))
+ :description
+ (format "Use the %s model on Ollama Cloud." (cdr spec))
:backend "Ollama Cloud"
:model (cdr spec))))
;; Bundled with gptel (same repo, already on `load-path'); no recipe needed.
(use-package gptel-transient
- :after gptel
+ :after
+ gptel
:commands (gptel-menu gptel-system-prompt gptel-tools))
#+end_src
* Literate programming
-Tools for working with infrastructure and configuration files in a literate
-way: Dockerfiles, Compose files, shell scripts, REST clients, and org-babel
+Tools for working with infrastructure and configuration files in a
+literate
+way: Dockerfiles, Compose files, shell scripts, REST clients, and
+org-babel
sources so we can tangle and run code blocks from this very file.
** Languages and file modes
#+begin_src emacs-lisp
(use-package dockerfile-mode
- :straight t
+ :straight
+ t
:mode (("\\.Dockerfile\\'" . dockerfile-mode)
("/Dockerfile\\'" . dockerfile-mode)))
(use-package docker
- :straight t
+ :straight
+ t
:commands (docker docker-compose))
(use-package nginx-mode
- :straight t
+ :straight
+ t
:mode "\\.nginx\\'")
(use-package toml-mode
- :straight t
+ :straight
+ t
:mode "\\.toml\\'")
(use-package ini-mode
- :straight t
+ :straight
+ t
:mode (("\\.ini\\'" . ini-mode)
- ("/\\.env\\.\\(?:local\\|development\\|production\\)?\\'" . ini-mode)))
+ ("/\\.env\\.\\(?:local\\|development\\|production\\)?\\'"
+ . ini-mode)))
(use-package restclient
- :straight t
+ :straight
+ t
:mode (("\\.http\\'" . restclient-mode)
("\\.rest\\'" . restclient-mode)))
(use-package graphql-mode
- :straight t
+ :straight
+ t
:mode "\\.gql\\(?:s\\)?\\'")
(use-package docker-compose-mode
- :straight t
- :mode (("docker-compose\\(?:\\..*\\)?\\.ya?ml\\'" . docker-compose-mode)
- ("compose\\.ya?ml\\'" . docker-compose-mode)))
+ :straight
+ t
+ :mode
+ (("docker-compose\\(?:\\..*\\)?\\.ya?ml\\'" . docker-compose-mode)
+ ("compose\\.ya?ml\\'"
+ . docker-compose-mode)))
#+end_src
** Org-babel languages
-These give us executable Org source blocks for shell scripts, REST calls,
-and inline LLM completions. `ob-async' lets long blocks (model downloads,
-container pulls) run in the background.
+These give us executable Org source blocks for shell scripts, REST
+calls,
+and inline LLM completions. `ob-async' lets long blocks (model
+ downloads,
+container pulls)
+run in the background.
#+begin_src emacs-lisp
(use-package ob-async
- :straight t
+ :straight
+ t
:after org)
(use-package ob-restclient
- :straight t
+ :straight
+ t
:after org)
(use-package ob-http
- :straight t
+ :straight
+ t
:after org)
(use-package ob-graphql
- :straight t
+ :straight
+ t
:after org)
(use-package ob-mermaid
- :straight t
+ :straight
+ t
:after org
:config
(setopt ob-mermaid-cli-path (or (executable-find "mmdc") "npx")))
(use-package ob-d2
- :straight t
+ :straight
+ t
:after org)
(use-package ob-llm
- :straight t
+ :straight
+ t
:after org
:config
;; Send babel blocks through gptel rather than a hosted API directly.
ob-llm-stream t))
(use-package ob-tmux
- :straight t
+ :straight
+ t
:after org
:config
(setopt ob-tmux-location-alist
("work" . "/var/tmp"))))
#+end_src
-Enable a useful default set of babel languages and configure evaluation
-safety so we can run trusted devops blocks without per-block confirmation.
+Enable a useful default set of babel languages and configure
+evaluation
+safety so we can run trusted devops blocks without per-block
+confirmation.
#+begin_src emacs-lisp
(with-eval-after-load 'org
(setopt org-babel-default-languages
- '(emacs-lisp shell python docker dockerfile restclient http graphql mermaid d2 tmux llm))
+ '(emacs-lisp shell python docker dockerfile restclient
+ http graphql mermaid d2 tmux llm))
(setopt org-confirm-babel-evaluate nil
- org-babel-default-header-args:shell '((:results . "output") (:async . "yes"))
- org-babel-default-header-args:tmux '((:results . "output") (:async . "yes"))
- org-babel-default-header-args:restclient '((:results . "raw"))
- org-babel-default-header-args:http '((:results . "raw"))))
+ org-babel-default-header-args:shell
+ '((:results . "output") (:async . "yes"))
+ org-babel-default-header-args:tmux
+ '((:results . "output") (:async . "yes"))
+ org-babel-default-header-args:restclient
+ '((:results . "raw"))
+ org-babel-default-header-args:http
+ '((:results . "raw"))))
#+end_src
blob - 736348b6f623f178e6de6dbcd8331734e36fa044
blob + 5790f308de1e06dbb180de0353aab35010b8d345
--- early-init.el
+++ early-init.el
;; Crank GC and disable the file-name handler for the duration of startup;
;; both are restored to sane runtime values on `emacs-startup-hook' below.
(setq bedrock--initial-gc-threshold gc-cons-threshold
- bedrock--initial-file-name-handler-alist file-name-handler-alist
+ bedrock--initial-file-name-handler-alist
+ file-name-handler-alist
gc-cons-threshold most-positive-fixnum
gc-cons-percentage 0.6
file-name-handler-alist nil
frame-resize-pixelwise t
package-enable-at-startup nil
straight-repository-branch "develop"
- straight-check-for-modifications '(check-on-save find-when-checking)
+ straight-check-for-modifications
+ '(check-on-save find-when-checking)
straight-use-package-by-default nil
straight-vc-git-default-clone-depth 1
default-frame-alist '((fullscreen . maximized)
- (font . "Go Mono-14")
(internal-border-width . 0)
(undecorated . t)))
"Restore GC threshold, GC percentage, and `file-name-handler-alist'."
(setq gc-cons-threshold (* 128 1024 1024)
gc-cons-percentage 0.1
- file-name-handler-alist bedrock--initial-file-name-handler-alist))
+ file-name-handler-alist
+ bedrock--initial-file-name-handler-alist))
(add-hook 'emacs-startup-hook #'bedrock--restore-startup-defaults)
(defvar bootstrap-version)
(let ((bootstrap-file
- (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
+ (expand-file-name "straight/repos/straight.el/bootstrap.el"
+ user-emacs-directory))
(bootstrap-version 6))
(unless (file-exists-p bootstrap-file)
(with-current-buffer
blob - 818c440582ccc4c765cfb3a11da03af6330409bb
blob + 289e83347397d30fc667e9af53a23b451d1ba42b
--- init.el
+++ init.el
-(when (< emacs-major-version 29)
- (error "Emacs configuration only works with Emacs 29 and newer; you have version %s"
- emacs-major-version))
+(when (< emacs-major-version 30)
+ (error
+ "Emacs configuration only works with Emacs 30 and newer; you have version %s"
+ emacs-major-version))
-(setopt initial-major-mode 'fundamental-mode
- inhibit-startup-screen t
- initial-scratch-message nil
- display-time-default-load-average nil
- sentence-end-double-space nil
- use-short-answers t)
+ (setopt initial-major-mode 'fundamental-mode
+ inhibit-startup-screen t
+ initial-scratch-message nil
+ display-time-default-load-average nil
+ sentence-end-double-space nil
+ use-short-answers t)
-(setopt auto-revert-avoid-polling t
- auto-revert-interval 5
- auto-revert-check-vc-info t)
-(global-auto-revert-mode 1)
+ (setopt auto-revert-avoid-polling t
+ auto-revert-interval 5
+ auto-revert-check-vc-info t)
+ (global-auto-revert-mode 1)
-(savehist-mode 1)
-(recentf-mode 1)
+ (savehist-mode 1)
+ (recentf-mode 1)
-(windmove-default-keybindings 'control)
+ (windmove-default-keybindings 'control)
-(when (display-graphic-p)
- (context-menu-mode -1)
- (tool-bar-mode -1)
- (menu-bar-mode -1)
- (scroll-bar-mode -1))
+ (when (display-graphic-p)
+ (context-menu-mode -1)
+ (tool-bar-mode -1)
+ (menu-bar-mode -1)
+ (scroll-bar-mode -1))
-;; Use Go Mono everywhere. `default' is set directly here; `fixed-pitch'
-;; and `variable-pitch' must be pointed at it explicitly so that e.g.
-;; `variable-pitch-mode' in org-mode still renders in Go Mono.
-(set-face-attribute 'default nil :family "Go Mono" :height 140)
-(set-face-attribute 'fixed-pitch nil :family "Go Mono" :height 1.0)
-(set-face-attribute 'variable-pitch nil :family "Go Mono" :height 1.0)
+ (unless (display-graphic-p)
+ (xterm-mouse-mode 1))
-(unless (display-graphic-p)
- (xterm-mouse-mode 1))
+ (cua-mode 1)
-(cua-mode 1)
+ (keymap-set global-map "C-x k" #'kill-current-buffer)
+ (add-hook 'before-save-hook #'whitespace-cleanup)
-(keymap-set global-map "C-x k" #'kill-current-buffer)
-(add-hook 'before-save-hook #'whitespace-cleanup)
+ (setopt display-line-numbers-width 3
+ tab-bar-show 1)
+ (add-hook 'prog-mode-hook #'display-line-numbers-mode)
+ (add-hook 'text-mode-hook #'visual-line-mode)
+ (dolist (hook '(text-mode-hook prog-mode-hook))
+ (add-hook hook #'hl-line-mode))
-(setopt display-line-numbers-width 3
- tab-bar-show 1)
-(add-hook 'prog-mode-hook #'display-line-numbers-mode)
-(add-hook 'text-mode-hook #'visual-line-mode)
-(dolist (hook '(text-mode-hook prog-mode-hook))
- (add-hook hook #'hl-line-mode))
+ (require 'server)
+ (unless (server-running-p)
+ (server-start))
+ (add-hook 'kill-emacs-hook #'server-force-delete)
-(require 'server)
-(unless (server-running-p)
- (server-start))
-(add-hook 'kill-emacs-hook #'server-force-delete)
-
(defun bedrock--backup-file-name (fpath)
"Return a backup path for FPATH, creating parent dirs if needed."
- (let* ((backup-root-dir (concat user-emacs-directory "emacs-backup/"))
+ (let*
+ ((backup-root-dir
+ (concat user-emacs-directory "emacs-backup/"))
(file-path (replace-regexp-in-string "[A-Za-z]:" "" fpath))
(backup-file-path (replace-regexp-in-string
"//" "/"
backup-file-path))
(setopt make-backup-file-name-function #'bedrock--backup-file-name)
-(let ((auto-save-dir (expand-file-name "auto-saves/" "~/.cache/emacs"))
+(let
+ ((auto-save-dir
+ (expand-file-name "auto-saves/" "~/.cache/emacs"))
(lock-dir (expand-file-name "locks/" "~/.cache/emacs")))
(make-directory auto-save-dir t)
(make-directory lock-dir t)
(setopt auto-save-file-name-transforms `((".*" ,auto-save-dir t))
lock-file-name-transforms `((".*" ,lock-dir t))))
+(use-package fontaine
+ :straight
+ t
+ :demand t
+ :bind ("C-c F" . fontaine-set-preset)
+ :init
+ (setq fontaine-latest-state-file
+ (locate-user-emacs-file "fontaine-latest-state.eld"))
+ :config
+ (setq fontaine-presets
+ '((comic-code
+ :default-family "Comic Code"
+ :default-height 120)
+ (comic-code-large
+ :default-family "Comic Code"
+ :default-height 170)
+ (codelia
+ :default-family "Codelia"
+ :default-height 130)
+ (droid-sans-mono
+ :default-family "Droid Sans Mono Dotted"
+ :default-height 130)
+ (fragment-mono
+ :default-family "Fragment Mono"
+ :default-height 130)
+ (fantasque-sans-mono
+ :default-family "Fantasque Sans Mono"
+ :default-height 140)
+ (go-mono
+ :default-family "Go Mono"
+ :default-height 120)
+ (inconsolata
+ :default-family "Inconsolata"
+ :default-weight medium
+ :default-height 120)
+ (input-mono
+ :default-family "Input Mono"
+ :default-height 120)
+ (ioskeley
+ :default-family "Ioskeley Mono Term"
+ :default-height 120)
+ (pragmatapro
+ :default-family "PragmataPro"
+ :default-height 130)
+ (0xproto
+ :default-family "0xProto"
+ :default-height 120)
+ (sudo
+ :default-family "Sudo"
+ :default-height 140)
+ (ttyp0
+ :default-family "Ttyp0 OTB"
+ :default-height 130)
+ (t
+ :default-weight regular
+ :default-slant normal
+ :fixed-pitch-family nil
+ :variable-pitch-family nil
+ :bold-weight bold
+ :italic-slant italic)))
+ (defun bedrock--fontaine-sync-variable-pitch (&rest _)
+ (set-face-attribute 'variable-pitch nil
+ :family (face-attribute 'default :family)
+ :height 1.0))
+ (add-hook 'fontaine-set-preset-hook
+ #'bedrock--fontaine-sync-variable-pitch)
+ (fontaine-mode 1)
+ (fontaine-set-preset
+ (or (fontaine-restore-latest-preset) 'go-mono)))
+
(use-package modus-themes
- :straight t
- :demand t
- :config
- (load-theme 'modus-operandi t))
+ :straight
+ t
+ :demand t
+ :config)
-(use-package ef-themes
- :straight t
- :commands ef-themes-select)
+ (use-package ef-themes
+ :straight
+ t
+ :demand t
+ :config)
-(use-package which-key
- :straight t
- :defer 1
- :config (which-key-mode))
+ (use-package plan9-theme
+ :straight
+ t
+ :demand t
+ :config)
-(use-package smart-mode-line
- :straight t
- :demand t
- :custom
- (sml/no-confirm-load-theme t)
- (sml/theme 'respectful)
- :config
- (sml/setup))
+ (use-package which-key
+ :straight
+ t
+ :defer 1
+ :config (which-key-mode))
-(use-package minions
- :straight t
- :demand t
- :config
- (minions-mode))
+ (use-package minions
+ :straight
+ t
+ :demand t
+ :config
+ (minions-mode))
+ (use-package mood-line
+ :straight
+ t
+ :demand t
+ :config
+ (mood-line-mode))
+
+
;; Lets `:diminish' hide minor-mode lighters from the mode line.
(use-package diminish
- :straight t
+ :straight
+ t
:demand t)
(add-to-list 'tab-bar-format 'tab-bar-format-align-right 'append)
(add-to-list 'tab-bar-format 'tab-bar-format-global 'append)
-(setopt display-time-format "%a %F %T"
+(setopt display-time-format "%T"
display-time-interval 1)
-(display-time-mode 1)
+(display-time-mode 0)
(setopt mouse-wheel-tilt-scroll t
mouse-wheel-flip-direction t
(pixel-scroll-precision-mode 1)
(use-package lin
- :straight t
+ :straight
+ t
:hook ((eshell-mode . lin-mode)
(dired-mode . lin-mode)
(org-mode . lin-mode)))
(use-package pulsar
- :straight t
+ :straight
+ t
:config
(pulsar-global-mode))
(use-package diff-hl
- :straight t
+ :straight
+ t
:hook ((prog-mode . diff-hl-mode)
(org-mode . diff-hl-mode))
:config
(global-diff-hl-show-hunk-mouse-mode))
(use-package circadian
- :straight (circadian :type git :host github :repo "guidoschmidt/circadian.el")
+ :straight
+ (circadian :type git :host github :repo
+ "guidoschmidt/circadian.el")
:demand t
:config
(setopt calendar-latitude 48.1386
calendar-longitude 17.1053
- circadian-themes '((:sunrise . ef-orange)
- (:sunset . modus-vivendi)))
+ circadian-themes '((:sunrise . plan9)
+ (:sunset . plan9)))
+ ;; (:sunset . ef-tritanopia-dark)))
(circadian-setup))
(setopt completion-cycle-threshold 3
(keymap-set minibuffer-mode-map "TAB" #'minibuffer-complete)
(use-package vertico
- :straight t
+ :straight
+ t
:init (vertico-mode))
(with-eval-after-load 'vertico
(keymap-set vertico-map "M-DEL" #'vertico-directory-delete-word))
(use-package marginalia
- :straight t
+ :straight
+ t
:config (marginalia-mode))
(use-package orderless
- :straight t
+ :straight
+ t
:config (setopt completion-styles '(orderless)))
(use-package consult
- :straight t
+ :straight
+ t
:bind (("C-x b" . consult-buffer)
("M-y" . consult-yank-pop)
("M-s r" . consult-ripgrep)
(consult-narrow-key "<"))
(use-package embark
- :straight t
+ :straight
+ t
:after consult
:bind (("C-c a" . embark-act)))
(use-package embark-consult
- :straight t
+ :straight
+ t
:after (embark consult))
(use-package corfu
- :straight t
+ :straight
+ t
:init (global-corfu-mode)
:bind (:map corfu-map
("SPC" . corfu-insert-separator)))
(corfu-popupinfo-mode))
(use-package corfu-terminal
- :straight t
+ :straight
+ t
:if (not (display-graphic-p))
:config (corfu-terminal-mode))
(use-package cape
- :straight t
+ :straight
+ t
:init
(add-to-list 'completion-at-point-functions #'cape-dabbrev)
(add-to-list 'completion-at-point-functions #'cape-file))
(use-package kind-icon
- :straight t
+ :straight
+ t
:if (display-graphic-p)
:after corfu
:config
(add-to-list 'corfu-margin-formatters #'kind-icon-margin-formatter))
(use-package wgrep
- :straight t
+ :straight
+ t
:config (setopt wgrep-auto-save-buffer t))
(use-package avy
- :straight t
+ :straight
+ t
:bind (("C-c j" . avy-goto-line)
("s-j" . avy-goto-char-timer))
:config
(select-window
(cdr (ring-ref avy-ring 0))))
t)
- (setf (alist-get ?. avy-dispatch-alist) #'bedrock-avy-action-embark))
+ (setf (alist-get ?. avy-dispatch-alist)
+ #'bedrock-avy-action-embark))
(use-package evil
- :straight t
+ :straight
+ t
:custom
(evil-want-keybinding nil)
(evil-respect-visual-line-mode t)
(evil-set-initial-state 'eat-mode 'emacs))
(use-package evil-collection
- :straight t
+ :straight
+ t
:after evil
:config (evil-collection-init))
(use-package evil-surround
- :straight t
+ :straight
+ t
:after evil
:config (global-evil-surround-mode))
(use-package evil-commentary
- :straight t
+ :straight
+ t
:after evil
:config (evil-commentary-mode))
(use-package evil-org
- :straight t
+ :straight
+ t
:after org
:hook (org-mode . evil-org-mode)
:config
(evil-org-agenda-set-keys))
(use-package undo-fu
- :straight t
+ :straight
+ t
:custom
(undo-fu-allow-undo-in-region t)
(undo-fu-undo-command 'undo-fu-only-undo)
("M-/" . undo-fu-only-redo-all)))
(use-package undo-fu-session
- :straight t
+ :straight
+ t
:custom
(undo-fu-session-incompatible-files '("\\.gpg$"))
(undo-fu-session-directory
(undo-fu-session-global-mode))
(use-package vundo
- :straight t
+ :straight
+ t
:bind ("C-c u" . vundo))
(with-eval-after-load 'evil
(keymap-set evil-normal-state-map "C-r" #'undo-fu-only-redo))
(use-package helpful
- :straight t
+ :straight
+ t
:bind (("C-h f" . helpful-callable)
("C-h v" . helpful-variable)
("C-h k" . helpful-key)
("C-h d" . helpful-at-point)))
(use-package eshell
- :straight (:type built-in)
+ :straight
+ (:type built-in)
:init
(defun bedrock-setup-eshell ()
"Bind `C-r' to `consult-history' in `eshell-mode'."
:hook (eshell-mode . bedrock-setup-eshell))
(use-package eat
- :straight t
+ :straight
+ t
:after eshell
:custom
;; A universally-installed TERM, so shells eat spawns never look up the
(eat-eshell-visual-command-mode))
(use-package tramp
- :straight (:type built-in)
+ :straight
+ (:type built-in)
:defer t
:custom
(tramp-default-method "ssh")
(add-to-list 'tramp-remote-path 'tramp-own-remote-path))
(use-package treesit-auto
- :straight t
+ :straight
+ t
:demand t
:custom
(treesit-auto-install t)
(add-hook 'prog-mode-hook #'electric-pair-mode)
(use-package project
- :straight (:type built-in)
+ :straight
+ (:type built-in)
:custom (project-mode-line t))
(use-package magit
- :straight t
+ :straight
+ t
:bind (("C-x g" . magit-status)))
(use-package yaml-mode
- :straight t
+ :straight
+ t
:mode "\\.ya?ml\\'")
(use-package json-mode
- :straight t
+ :straight
+ t
:mode "\\.json\\'")
(use-package nix-mode
- :straight t
+ :straight
+ t
:mode "\\.nix\\'")
(use-package go-mode
- :straight t
+ :straight
+ t
:mode "\\.go\\'")
(use-package zig-mode
- :straight t
+ :straight
+ t
:mode "\\.zig\\'")
(use-package rust-mode
- :straight t
+ :straight
+ t
:mode "\\.rs\\'")
(use-package elixir-mode
- :straight t
+ :straight
+ t
:mode ("\\.exs?\\'" "mix\\.lock\\'"))
+(use-package markdown-mode
+ :straight
+ t
+ :mode "\\.md\\'"
+ :hook (markdown-mode . visual-line-mode))
+
(use-package eglot
- :straight (:type built-in)
+ :straight
+ (:type built-in)
:custom
(eglot-send-changes-idle-time 0.1)
(eglot-extend-to-xref t)
process-adaptive-read-buffering nil)
(use-package tempel
- :straight t
+ :straight
+ t
:bind (("M-*" . tempel-insert)
("M-+" . tempel-complete)
:map tempel-map
:init
(defun tempel-setup-capf ()
"Add `tempel-expand' to `completion-at-point-functions' locally."
- (add-hook 'completion-at-point-functions #'tempel-expand -1 'local))
+ (add-hook 'completion-at-point-functions #'tempel-expand -1
+ 'local))
(add-hook 'prog-mode-hook #'tempel-setup-capf)
(add-hook 'text-mode-hook #'tempel-setup-capf))
(use-package slime
- :straight t
+ :straight
+ t
:custom
(inferior-lisp-program "sbcl")
(slime-lisp-implementations '((sbcl ("sbcl"))))
(setopt denote-directory (expand-file-name "~/.nb/notes"))
(use-package denote
- :straight t
+ :straight
+ t
:custom
(denote-file-type 'org)
(denote-known-keywords '("daily" "comp" "music" "misc"))
(denote-rename-buffer-mode))
(use-package denote-journal
- :straight t
+ :straight
+ t
:after denote
:custom
(denote-journal-keyword "journal")
(denote-journal-file-type 'org))
(use-package denote-org
- :straight t
+ :straight
+ t
:after denote)
(setopt org-directory (expand-file-name "~/.nb/notes")
org-agenda-files (list org-directory)
- org-default-notes-file (expand-file-name "todo.org" org-directory))
+ org-default-notes-file
+ (expand-file-name "todo.org" org-directory))
(setopt org-refile-targets '((org-agenda-files :maxlevel . 3))
org-refile-use-outline-path 'file
org-outline-path-complete-in-steps nil)
(setopt org-todo-keywords
- '((sequence "TODO(t)" "WAITING(w@/!)" "STARTED(s!)" "|" "DONE(d!)" "OBSOLETE(o@)"))
+ '((sequence "TODO(t)" "WAITING(w@/!)" "STARTED(s!)" "|"
+ "DONE(d!)" "OBSOLETE(o@)"))
org-log-done 'time
org-log-into-drawer t)
(setopt org-capture-templates
- '(("t" "task" entry (file+headline org-default-notes-file "Inbox")
+ '(("t" "task" entry
+ (file+headline org-default-notes-file "Inbox")
"* TODO %?\n%U\n%i")
- ("j" "journal" plain (file denote-journal-path-to-new-or-existing-entry)
+ ("j" "journal" plain
+ (file denote-journal-path-to-new-or-existing-entry)
"%?\n%U\n%i")))
(setopt org-agenda-start-with-log-mode 'clockcheck
org-startup-with-inline-images t
org-hide-emphasis-markers t)
-(setopt org-id-link-to-org-use-id 'create-if-interactive-and-no-custom-id)
+(setopt org-id-link-to-org-use-id
+ 'create-if-interactive-and-no-custom-id)
(setopt org-export-with-smart-quotes t)
(use-package org
- :straight (:type built-in)
+ :straight
+ (:type built-in)
:hook ((org-mode . visual-line-mode)
(org-mode . variable-pitch-mode))
:bind (:map global-map
org-cycle-separator-lines 2))
(use-package org-appear
- :straight t
+ :straight
+ t
:hook (org-mode . org-appear-mode))
(use-package org-super-agenda
- :straight t
+ :straight
+ t
:after org
:config
(org-super-agenda-mode))
-(use-package markdown-mode
- :straight t
- :hook (markdown-mode . visual-line-mode))
-
(defvar-keymap file-prefix-map
:doc "Prefix map for file commands.")
(keymap-set global-map "C-c f" file-prefix-map)
:doc "Prefix map for denote commands.")
(keymap-set global-map "C-c n" denote-prefix-map)
(keymap-set denote-prefix-map "n" #'denote)
-(keymap-set denote-prefix-map "j" #'denote-journal-new-or-existing-entry)
+(keymap-set denote-prefix-map "j"
+ #'denote-journal-new-or-existing-entry)
(keymap-set denote-prefix-map "l" #'denote-insert-link)
(keymap-set denote-prefix-map "L" #'denote-add-links)
(keymap-set denote-prefix-map "o" #'denote-open-or-create)
(with-eval-after-load 'evil
(evil-set-leader '(normal visual) (kbd "SPC"))
- (evil-define-key '(normal visual) 'global (kbd "<leader>fh") #'consult-recent-file))
+ (evil-define-key '(normal visual) 'global
+ (kbd "<leader>fh") #'consult-recent-file)
+ (evil-define-key '(normal visual) 'global
+ (kbd "<leader>ff") #'project-find-file)
+ (evil-define-key '(normal visual) 'global
+ (kbd "<leader>fs") #'save-buffer))
(setopt select-enable-clipboard t
select-enable-primary t
save-interprogram-text-before-kill t)
(use-package clipetty
- :straight t
+ :straight
+ t
:hook (after-init . clipetty-mode))
(with-eval-after-load 'eglot
(add-to-list 'eglot-server-programs
- '(purescript-mode . ("pnpx" "purescript-language-server" "--stdio")))
+ '(purescript-mode
+ . ("pnpx" "purescript-language-server" "--stdio")))
(add-to-list 'eglot-server-programs
- '((markdown-mode text-mode tex-mode typst-mode org-mode)
+ '((markdown-mode text-mode tex-mode typst-mode
+ org-mode)
. ("harper-ls" "--stdio"))))
(use-package zoom-window
- :straight t
+ :straight
+ t
:bind ("C-x z" . zoom-window-zoom))
(use-package tmr
- :straight t
+ :straight
+ t
:bind (("C-c t c" . tmr)
("C-c t l" . tmr-tabulated-view)
("C-c t k" . tmr-remove)
(defun mine/ollama-api-key ()
"Return the Ollama Cloud API key stored in auth-source.
Expects a line in `auth-sources' for host ollama.com, user apikey."
- (or (auth-source-pick-first-password :host "ollama.com" :user "apikey")
- (user-error "No Ollama API key in auth-source for host ollama.com")))
+ (or
+ (auth-source-pick-first-password :host "ollama.com" :user
+ "apikey")
+ (user-error
+ "No Ollama API key in auth-source for host ollama.com")))
(defun mine/ollama-api-post (path payload)
"POST PAYLOAD (an alist) as JSON to Ollama API PATH, return parsed JSON.
(let* ((url-request-method "POST")
(url-request-extra-headers
`(("Content-Type" . "application/json")
- ("Authorization" . ,(concat "Bearer " (mine/ollama-api-key)))))
- (url-request-data (encode-coding-string (json-encode payload) 'utf-8))
- (buf (url-retrieve-synchronously (concat "https://ollama.com" path)
+ ("Authorization"
+ . ,(concat "Bearer " (mine/ollama-api-key)))))
+ (url-request-data
+ (encode-coding-string (json-encode payload) 'utf-8))
+ (buf (url-retrieve-synchronously
+ (concat "https://ollama.com" path)
'silent nil 60)))
(unless buf (error "Ollama API request to %s timed out" path))
(unwind-protect
(with-current-buffer buf
(goto-char (point-min))
- (let ((status (and (re-search-forward "^HTTP/[0-9.]+ \\([0-9]+\\)" nil t)
+ (let ((status (and
+ (re-search-forward
+ "^HTTP/[0-9.]+ \\([0-9]+\\)" nil t)
(string-to-number (match-string 1)))))
(unless (re-search-forward "\n\n" nil t)
(error "Malformed response from Ollama API"))
(json-key-type 'symbol)
(body (json-read)))
(when (and status (>= status 400))
- (error "Ollama API %s failed (HTTP %d): %s" path status
+ (error "Ollama API %s failed (HTTP %d): %s" path
+ status
(or (alist-get 'error body) body)))
body)))
(kill-buffer buf))))
(use-package gptel
- :straight (gptel :type git :host github :repo "karthink/gptel")
+ :straight
+ (gptel :type git :host github :repo "karthink/gptel")
:demand t
:bind (:map gptel-mode-map
("C-c RET" . gptel-send)
(gptel-use-header-line t)
(gptel-org-ignore-elements '(property-drawer))
(gptel-directives
- '((default . "You are a large language model living in Emacs and a helpful assistant. Respond concisely.")
- (programming . "You are a careful programmer working from inside Emacs. Provide code, with minimal surrounding prose.")
- (reviewing . "You are reviewing code or text in Emacs. Be terse, point out concrete issues, and suggest fixes.")
- (literate . "You are helping with a literate configuration in an Org file. Prefer Org markup and explain only what is non-obvious.")
- (chat . "You are a conversation partner. Respond concisely.")))
+ '((default
+ . "You are a large language model living in Emacs and a helpful assistant. Respond concisely.")
+ (programming
+ . "You are a careful programmer working from inside Emacs. Provide code, with minimal surrounding prose.")
+ (reviewing
+ . "You are reviewing code or text in Emacs. Be terse, point out concrete issues, and suggest fixes.")
+ (literate
+ . "You are helping with a literate configuration in an Org file. Prefer Org markup and explain only what is non-obvious.")
+ (chat
+ . "You are a conversation partner. Respond concisely.")))
(gptel-use-tools t)
(gptel-confirm-tool-calls 'auto)
(gptel-include-tool-results 'auto)
(gptel-make-tool
:name "web_search"
:category "web"
- :description (concat "Search the web and return a list of results, each with a "
+ :description (concat
+ "Search the web and return a list of results, each with a "
"title, URL and a content snippet. Use this for current "
"events or anything outside your training data, then call "
"`web_fetch' on a promising URL to read it in full.")
:args (list '(:name "query" :type string
:description "The search query.")
'(:name "max_results" :type integer :optional t
- :description "How many results to return (1-10, default 5)."))
+ :description
+ "How many results to return (1-10, default 5)."))
:function
(lambda (query &optional max_results)
(let* ((payload `(("query" . ,query)
- ,@(when (and (integerp max_results) (> max_results 0))
+ ,@(when
+ (and (integerp max_results)
+ (> max_results 0))
`(("max_results" . ,(min max_results 10))))))
- (results (alist-get 'results (mine/ollama-api-post "/api/web_search" payload))))
+ (results
+ (alist-get 'results
+ (mine/ollama-api-post "/api/web_search"
+ payload))))
(if (null results)
"No results found."
(mapconcat
(lambda (r)
(format "## %s\n%s\n\n%s"
- (alist-get 'title r) (alist-get 'url r) (alist-get 'content r)))
+ (alist-get 'title r) (alist-get 'url r)
+ (alist-get 'content r)))
results "\n\n---\n\n")))))
(gptel-make-tool
:name "web_fetch"
:category "web"
- :description "Fetch and return the main text content of a web page, given its URL."
+ :description
+ "Fetch and return the main text content of a web page, given its URL."
:args (list '(:name "url" :type string
- :description "The full URL of the page to fetch."))
+ :description
+ "The full URL of the page to fetch."))
:function
(lambda (url)
- (let* ((resp (mine/ollama-api-post "/api/web_fetch" `(("url" . ,url))))
+ (let*
+ ((resp
+ (mine/ollama-api-post "/api/web_fetch" `(("url" . ,url))))
(content (alist-get 'content resp)))
(if (and (stringp content) (not (string-empty-p content)))
- (format "# %s\n\n%s" (or (alist-get 'title resp) url) content)
+ (format "# %s\n\n%s" (or (alist-get 'title resp) url)
+ content)
"Could not extract any content from that URL."))))
(gptel-make-tool
:name "read_url"
:category "web"
- :description (concat "Fetch a URL directly (no API) and return its rendered text. "
+ :description (concat
+ "Fetch a URL directly (no API) and return its rendered text. "
"A fallback for `web_fetch'.")
- :args (list '(:name "url" :type string :description "The URL to read."))
+ :args
+ (list '(:name "url" :type string :description "The URL to read."))
:function
(lambda (url)
(with-current-buffer (url-retrieve-synchronously url t t 30)
:category "emacs"
:description "Return the full contents of a live Emacs buffer."
:args (list '(:name "buffer" :type string
- :description "The name of the buffer to read."))
+ :description
+ "The name of the buffer to read."))
:function
(lambda (buffer)
(unless (buffer-live-p (get-buffer buffer))
:category "filesystem"
:description "Read and return the contents of a file on disk."
:args (list '(:name "filepath" :type string
- :description "Path to the file. Supports relative paths and ~."))
+ :description
+ "Path to the file. Supports relative paths and ~."))
:function
(lambda (filepath)
(with-temp-buffer
:category "filesystem"
:description "List the entries in a directory."
:args (list '(:name "directory" :type string
- :description "The path to the directory to list."))
+ :description
+ "The path to the directory to list."))
:function
(lambda (directory)
- (mapconcat #'identity (directory-files (expand-file-name directory)) "\n")))
+ (mapconcat #'identity
+ (directory-files (expand-file-name directory)) "\n")))
(gptel-make-tool
:name "run_command"
:category "command"
- :description "Execute a shell command and return its combined output."
+ :description
+ "Execute a shell command and return its combined output."
:args (list '(:name "command" :type string
- :description "The complete shell command to run.")
+ :description
+ "The complete shell command to run.")
'(:name "working_dir" :type string :optional t
- :description "Directory to run in (default: current)."))
+ :description
+ "Directory to run in (default: current)."))
:function
(lambda (command &optional working_dir)
(with-temp-message (format "Executing: %s" command)
(let ((default-directory
- (if (and working_dir (not (string-empty-p working_dir)))
+ (if
+ (and working_dir
+ (not (string-empty-p working_dir)))
(expand-file-name working_dir)
default-directory)))
(shell-command-to-string command))))
(gptel-make-tool
:name "obscura_scrape"
:category "web"
- :description (concat "Scrape a web page with the Obscura headless browser "
+ :description (concat
+ "Scrape a web page with the Obscura headless browser "
"(real JS rendering, stealth). Use this instead of "
"`web_fetch'/`read_url' for JavaScript-heavy or "
"bot-protected pages. Returns the page as markdown by "
:args (list '(:name "url" :type string
:description "The URL to scrape.")
'(:name "format" :type string :optional t
- :description "Output: markdown (default), text, html, or links.")
+ :description
+ "Output: markdown (default), text, html, or links.")
'(:name "selector" :type string :optional t
- :description "Optional CSS selector to wait for before extracting."))
+ :description
+ "Optional CSS selector to wait for before extracting."))
:function
(lambda (url &optional format selector)
(if-let* ((exe (executable-find "obscura")))
(with-temp-message (format "Obscura scraping %s" url)
(with-output-to-string
- (apply #'call-process exe nil (list standard-output nil) nil
+ (apply #'call-process exe nil
+ (list standard-output nil) nil
"fetch" url
- "--dump" (if (member format '("text" "html" "links" "markdown"))
- format "markdown")
+ "--dump" (if
+ (member format
+ '("text" "html" "links"
+ "markdown"))
+ format
+ "markdown")
"--wait-until" "networkidle0"
- (when (and selector (not (string-empty-p selector)))
+ (when
+ (and selector
+ (not (string-empty-p selector)))
(list "--selector" selector)))))
"Error: the `obscura' binary is not on PATH. Install it (https://github.com/h4ckf0r0day/obscura) or use `web_fetch'/`read_url' instead."))
:confirm t
;; Presets: apply with `C-c L p' or an `@name' cookie at the start of a prompt.
(gptel-make-preset 'research
- :description "Web research: search, fetch and scrape, then synthesise."
- :system (concat "You are a research assistant working inside Emacs. Use the "
+ :description
+ "Web research: search, fetch and scrape, then synthesise."
+ :system (concat
+ "You are a research assistant working inside Emacs. Use the "
"web tools to gather up-to-date information before answering: "
"`web_search' to find sources, `web_fetch'/`read_url' to read "
"them, and `obscura_scrape' for JavaScript-heavy or protected "
:confirm-tool-calls nil)
(gptel-make-preset 'agent
- :description "Coding agent: read files/buffers and run commands in Emacs."
- :system (concat "You are a careful coding agent operating inside Emacs. Use "
+ :description
+ "Coding agent: read files/buffers and run commands in Emacs."
+ :system (concat
+ "You are a careful coding agent operating inside Emacs. Use "
"the filesystem and buffer tools to inspect the project, and "
"`run_command' to build, test or inspect the repo. Explain "
"what you will do, then act. Prefer minimal, surgical changes.")
- :tools '("read_file" "read_buffer" "list_directory" "run_command")
+ :tools
+ '("read_file" "read_buffer" "list_directory" "run_command")
:confirm-tool-calls t)
(gptel-make-preset 'full
:description "Everything: web + filesystem + Emacs + commands."
:system 'default
:tools '("web_search" "web_fetch" "read_url" "obscura_scrape"
- "read_file" "read_buffer" "list_directory" "run_command"))
+ "read_file" "read_buffer" "list_directory"
+ "run_command"))
(gptel-make-preset 'chat
:description "Plain conversation, no tools."
(minimax . minimax-m3:cloud)
(minimax2 . minimax-m2.7:cloud)))
(gptel-make-preset (car spec)
- :description (format "Use the %s model on Ollama Cloud." (cdr spec))
+ :description
+ (format "Use the %s model on Ollama Cloud." (cdr spec))
:backend "Ollama Cloud"
:model (cdr spec))))
;; Bundled with gptel (same repo, already on `load-path'); no recipe needed.
(use-package gptel-transient
- :after gptel
+ :after
+ gptel
:commands (gptel-menu gptel-system-prompt gptel-tools))
(use-package dockerfile-mode
- :straight t
+ :straight
+ t
:mode (("\\.Dockerfile\\'" . dockerfile-mode)
("/Dockerfile\\'" . dockerfile-mode)))
(use-package docker
- :straight t
+ :straight
+ t
:commands (docker docker-compose))
(use-package nginx-mode
- :straight t
+ :straight
+ t
:mode "\\.nginx\\'")
(use-package toml-mode
- :straight t
+ :straight
+ t
:mode "\\.toml\\'")
(use-package ini-mode
- :straight t
+ :straight
+ t
:mode (("\\.ini\\'" . ini-mode)
- ("/\\.env\\.\\(?:local\\|development\\|production\\)?\\'" . ini-mode)))
+ ("/\\.env\\.\\(?:local\\|development\\|production\\)?\\'"
+ . ini-mode)))
(use-package restclient
- :straight t
+ :straight
+ t
:mode (("\\.http\\'" . restclient-mode)
("\\.rest\\'" . restclient-mode)))
(use-package graphql-mode
- :straight t
+ :straight
+ t
:mode "\\.gql\\(?:s\\)?\\'")
(use-package docker-compose-mode
- :straight t
- :mode (("docker-compose\\(?:\\..*\\)?\\.ya?ml\\'" . docker-compose-mode)
- ("compose\\.ya?ml\\'" . docker-compose-mode)))
+ :straight
+ t
+ :mode
+ (("docker-compose\\(?:\\..*\\)?\\.ya?ml\\'" . docker-compose-mode)
+ ("compose\\.ya?ml\\'"
+ . docker-compose-mode)))
(use-package ob-async
- :straight t
+ :straight
+ t
:after org)
(use-package ob-restclient
- :straight t
+ :straight
+ t
:after org)
(use-package ob-http
- :straight t
+ :straight
+ t
:after org)
(use-package ob-graphql
- :straight t
+ :straight
+ t
:after org)
(use-package ob-mermaid
- :straight t
+ :straight
+ t
:after org
:config
(setopt ob-mermaid-cli-path (or (executable-find "mmdc") "npx")))
(use-package ob-d2
- :straight t
+ :straight
+ t
:after org)
(use-package ob-llm
- :straight t
+ :straight
+ t
:after org
:config
;; Send babel blocks through gptel rather than a hosted API directly.
ob-llm-stream t))
(use-package ob-tmux
- :straight t
+ :straight
+ t
:after org
:config
(setopt ob-tmux-location-alist
(with-eval-after-load 'org
(setopt org-babel-default-languages
- '(emacs-lisp shell python docker dockerfile restclient http graphql mermaid d2 tmux llm))
+ '(emacs-lisp shell python docker dockerfile restclient
+ http graphql mermaid d2 tmux llm))
(setopt org-confirm-babel-evaluate nil
- org-babel-default-header-args:shell '((:results . "output") (:async . "yes"))
- org-babel-default-header-args:tmux '((:results . "output") (:async . "yes"))
- org-babel-default-header-args:restclient '((:results . "raw"))
- org-babel-default-header-args:http '((:results . "raw"))))
+ org-babel-default-header-args:shell
+ '((:results . "output") (:async . "yes"))
+ org-babel-default-header-args:tmux
+ '((:results . "output") (:async . "yes"))
+ org-babel-default-header-args:restclient
+ '((:results . "raw"))
+ org-babel-default-header-args:http
+ '((:results . "raw"))))