emacs/lisp/init-tools.el 5.6 K raw
1
;;; init-tools.el -*- lexical-binding: t; -*-
2
3
(use-package magit
4
  :defer t)
5
6
(use-package diff-hl
7
  :hook ((after-init . global-diff-hl-mode)
8
         (dired-mode . diff-hl-dired-mode)
9
         (magit-pre-refresh . diff-hl-magit-pre-refresh)
10
         (magit-post-refresh . diff-hl-magit-post-refresh))
11
  :custom
12
  (diff-hl-margin-symbols-alist
13
   '((insert . "+") (delete . "-") (change . "~")
14
     (unknown . "?") (ignored . "i") (reference . " ")))
15
  (diff-hl-draw-borders nil)
16
  :config
17
  (diff-hl-flydiff-mode 1)
18
  (diff-hl-margin-mode 1)
19
  ;; base16-theme already defines these faces, so the theme file can't
20
  ;; override them; set them here instead.
21
  (custom-set-faces
22
   '(diff-hl-insert ((t (:foreground "#fbcb97" :background "#fbcb97"))))
23
   '(diff-hl-change ((t (:foreground "#e78a53" :background "#e78a53"))))
24
   '(diff-hl-delete ((t (:foreground "#aa6c6c" :background "#aa6c6c"))))
25
   ;; margin text: color the symbol only, no filled background
26
   '(diff-hl-margin-insert ((t (:foreground "#fbcb97" :background unspecified :weight bold))))
27
   '(diff-hl-margin-change ((t (:foreground "#e78a53" :background unspecified :weight bold))))
28
   '(diff-hl-margin-delete ((t (:foreground "#aa6c6c" :background unspecified :weight bold))))))
29
30
(use-package elfeed
31
  :defer t
32
  :config
33
  (setq-default elfeed-search-filter "@6-months-ago")
34
35
  (defvar my/elfeed-feeds-url "https://feeds.stevedylan.dev/feeds?format=json"
36
    "Endpoint returning my subscriptions as JSON.")
37
38
  (defun my/elfeed-refresh-feeds ()
39
    "Replace `elfeed-feeds' with the list from `my/elfeed-feeds-url'.
40
Keeps the current list if the fetch fails."
41
    (interactive)
42
    (condition-case err
43
        (let ((buf (url-retrieve-synchronously my/elfeed-feeds-url t t 10)))
44
          (unless buf (error "no response"))
45
          (with-current-buffer buf
46
            (goto-char (point-min))
47
            (re-search-forward "\n\n")
48
            (let* ((data (json-parse-buffer :object-type 'alist :array-type 'list))
49
                   (urls (mapcar (lambda (s) (alist-get 'url s))
50
                                 (alist-get 'subscriptions data))))
51
              (kill-buffer buf)
52
              (setq elfeed-feeds urls)
53
              (message "elfeed: loaded %d feeds" (length urls)))))
54
      (error (message "elfeed: feed refresh failed (%s), keeping existing list"
55
                      (error-message-string err)))))
56
57
  (advice-add 'elfeed-update :before #'my/elfeed-refresh-feeds)
58
59
  (defun my/elfeed-show-font ()
60
    (face-remap-add-relative 'variable-pitch :family "BerkeleyMono Nerd Font Mono" :height 140)
61
    (face-remap-add-relative 'default :family "BerkeleyMono Nerd Font Mono" :height 140))
62
  (add-hook 'elfeed-show-mode-hook #'my/elfeed-show-font))
63
64
(use-package ob-go
65
  :defer t)
66
67
(use-package org
68
  :ensure nil
69
  :defer t
70
  :config
71
  (require 'ob-go)
72
  (org-babel-do-load-languages
73
   'org-babel-load-languages
74
   '((js    . t)
75
     (shell . t)
76
     (go    . t)))
77
78
  (setq org-directory "~/org/"
79
        org-default-notes-file (expand-file-name "inbox.org" org-directory)
80
        org-capture-templates
81
        '(("t" "Todo" entry (file+headline "inbox.org" "Tasks")
82
           "* TODO %?\n%i\n%a" :empty-lines 1)
83
          ("n" "Note" entry (file+headline "inbox.org" "Notes")
84
           "* %?\n%U\n%i" :empty-lines 1)
85
          ("j" "Journal" entry (file+olp+datetree "journal.org")
86
           "* %U %?\n%i" :empty-lines 1)
87
          ("b" "Bookmark" entry (file "bookmarks.org")
88
           "* [[%^{URL}][%^{Title}]] %^g\n:PROPERTIES:\n:ADDED: %U\n:END:\n%?"
89
           :empty-lines 1))))
90
91
(use-package dired
92
  :ensure nil
93
  :custom
94
  (dired-kill-when-opening-new-dired-buffer t)  ; reuse one buffer
95
  (dired-dwim-target t)
96
  :hook (dired-mode . dired-omit-mode)          ; hide dotfiles by default
97
  :config
98
  (require 'dired-x)
99
  (setq dired-omit-files "\\`[.][^.]")          ; dotfiles, but keep ".."
100
  (evil-collection-define-key 'normal 'dired-mode-map
101
    "." 'dired-omit-mode                        ; toggle dotfiles
102
    "h" 'dired-up-directory
103
    "l" 'dired-find-file
104
    "q" 'quit-window))
105
106
(autoload 'posts-compose "posts" nil t)
107
(autoload 'uguu-upload-file "uguu" nil t)
108
(autoload 'uguu-upload-clipboard "uguu" nil t)
109
110
(defgroup openrouter nil
111
  "OpenRouter backend for gptel."
112
  :group 'gptel)
113
114
(defcustom openrouter-pass-entry "openrouter/openrouter-api-key"
115
  "Name of the `pass' entry holding the API key."
116
  :type 'string
117
  :group 'openrouter)
118
119
(defun openrouter--api-key ()
120
  "Return the OpenRouter API key from password-store."
121
  (require 'auth-source-pass)       ; autoloaded in Emacs 28+, but cheap to be explicit
122
  (let ((key (auth-source-pass-get 'secret openrouter-pass-entry)))
123
    (or (and key (string-trim key))
124
        (user-error "No pass entry `%s'" openrouter-pass-entry))))
125
126
(use-package gptel
127
  :defer t
128
  :config
129
  (setq gptel-backend
130
        (gptel-make-openai "OpenRouter"
131
          :host "openrouter.ai"
132
          :endpoint "/api/v1/chat/completions"
133
          :stream t
134
          :key #'openrouter--api-key
135
          :request-params '(:tools [(:type "openrouter:web_search")
136
                                    (:type "openrouter:web_fetch")])
137
          :models '(z-ai/glm-5.3
138
                    z-ai/glm-5.3-flash
139
                    z-ai/glm-5.3-flashx))))
140
141
(defun gptel-model (model)
142
  "Set the gptel model in the current buffer."
143
  (interactive
144
   (list (intern (completing-read "Model: "
145
                                  '("z-ai/glm-5.3"
146
                                    "z-ai/glm-5.3-flash"
147
                                    "z-ai/glm-5.3-flashx")))))
148
  (setq-local gptel-model model))
149
150
(use-package markdown-mode
151
  :defer t)
152
153
154
(provide 'init-tools)