Skip to content

Commit c8ad38a

Browse files
authored
Merge pull request #19 from mcraveiro/feature/new_work
Ongoing changes
2 parents 34ad8af + d4327f8 commit c8ad38a

9 files changed

Lines changed: 474 additions & 80 deletions

File tree

config/development.org

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,11 @@ Display indicators in the left fringe for Git changes.
8181
;; (setq git-gutter:update-interval 0.02))
8282

8383
(use-package git-gutter-fringe
84+
:ensure t
85+
:hook
86+
;; Only enable for file buffers in version control
87+
((find-file . git-gutter-mode)
88+
(after-revert-hook . git-gutter-mode))
8489
:config
8590
(define-fringe-bitmap 'git-gutter-fr:added [224] nil nil '(center repeated))
8691
(define-fringe-bitmap 'git-gutter-fr:modified [224] nil nil '(center repeated))
@@ -94,6 +99,15 @@ Display indicators in the left fringe for Git changes.
9499
:config
95100
(setq git-messenger:show-detail t
96101
git-messenger:use-magit-popup t))
102+
103+
104+
;; (use-package forge
105+
;; :ensure t
106+
;; :after magit
107+
;; :config
108+
;; ;; Optional: Add your GitHub token if you want to avoid frequent authentication
109+
;; ;; (setq forge-alist (append forge-alist '((github "api.github.com" "github.com" forge-github-repository))))
110+
;; )
97111
#+end_src
98112

99113
Major modes for Git-specific files.
@@ -814,6 +828,20 @@ START and END mark the region."
814828
(use-package cmake-mode)
815829
#+end_src
816830

831+
* Common Lisp
832+
833+
#+begin_src emacs-lisp
834+
;; Load SLIME
835+
(load (expand-file-name "/home/marco/.quicklisp/slime-helper.el"))
836+
837+
;; Set up SLIME
838+
(setq inferior-lisp-program "sbcl")
839+
(setq slime-contribs '(slime-fancy))
840+
841+
;; Basic preferences
842+
(show-paren-mode 1)
843+
#+end_src
844+
817845
* Statistics
818846

819847
#+begin_src emacs-lisp
@@ -1202,6 +1230,14 @@ Uses `*compilation: <project-name>*` if in a project, otherwise `*compilation*`.
12021230

12031231
(setq sql-ms-program "/opt/mssql-tools18/bin/sqlcmd")
12041232
(setq sql-ms-options '("-C")) ; trust self-signed cert
1233+
1234+
(add-hook 'sql-interactive-mode-hook
1235+
(lambda ()
1236+
(run-at-time "0.1 sec" nil
1237+
(lambda (buf)
1238+
(with-current-buffer buf
1239+
(setq-local truncate-lines t)))
1240+
(current-buffer))))
12051241
#+end_src
12061242

12071243
* Yaml
@@ -1280,6 +1316,121 @@ Uses `*compilation: <project-name>*` if in a project, otherwise `*compilation*`.
12801316
:config
12811317
(setq claude-code-ide-cli-path "~/.local/bin/claude")
12821318
(claude-code-ide-emacs-tools-setup))
1319+
1320+
(defvar-local cunene/claude-prompt-edit--target-buffer nil
1321+
"The Claude Code terminal buffer that this edit buffer is associated with.")
1322+
1323+
(defvar cunene/claude-prompt-edit-mode-map
1324+
(let ((map (make-sparse-keymap)))
1325+
(define-key map (kbd "C-c '") #'cunene/claude-prompt-edit-send)
1326+
(define-key map (kbd "C-c C-c") #'cunene/claude-prompt-edit-send-and-submit)
1327+
(define-key map (kbd "C-c C-k") #'cunene/claude-prompt-edit-cancel)
1328+
map)
1329+
"Keymap for `cunene/claude-prompt-edit-mode'.")
1330+
1331+
(define-minor-mode cunene/claude-prompt-edit-mode
1332+
"Minor mode for editing Claude Code prompts in a dedicated buffer.
1333+
1334+
\\{cunene/claude-prompt-edit-mode-map}"
1335+
:lighter " Claude-Edit"
1336+
:keymap cunene/claude-prompt-edit-mode-map
1337+
(when cunene/claude-prompt-edit-mode
1338+
(setq header-line-format
1339+
(substitute-command-keys
1340+
"Edit prompt. \\[cunene/claude-prompt-edit-send]: send \
1341+
\\[cunene/claude-prompt-edit-send-and-submit]: send+submit \
1342+
\\[cunene/claude-prompt-edit-cancel]: cancel"))))
1343+
1344+
(defun cunene/claude-prompt-edit--buffer-name (terminal-buffer)
1345+
"Return the name for the prompt edit buffer associated with TERMINAL-BUFFER."
1346+
(format "*claude-prompt-edit[%s]*"
1347+
(replace-regexp-in-string
1348+
"\\*claude-code\\[\\(.*\\)\\]\\*" "\\1"
1349+
(buffer-name terminal-buffer))))
1350+
1351+
(defun cunene/claude-prompt-edit--send-text (text &optional submit)
1352+
"Send TEXT to the terminal, optionally pressing return if SUBMIT is non-nil.
1353+
Handles multi-line text by converting newlines to backslash+return sequences."
1354+
(let ((lines (split-string text "\n")))
1355+
(dotimes (i (length lines))
1356+
(let ((line (nth i lines)))
1357+
(claude-code-ide--terminal-send-string line)
1358+
(when (< i (1- (length lines)))
1359+
(claude-code-ide--terminal-send-string "\\")
1360+
(sit-for 0.05)
1361+
(claude-code-ide--terminal-send-return)
1362+
(sit-for 0.05)))))
1363+
(when submit
1364+
(sit-for 0.1)
1365+
(claude-code-ide--terminal-send-return)))
1366+
1367+
(defun cunene/claude-prompt-edit--close-buffer ()
1368+
"Close the current prompt edit buffer and its window."
1369+
(let ((edit-window (get-buffer-window (current-buffer))))
1370+
(kill-buffer (current-buffer))
1371+
(when (window-live-p edit-window)
1372+
(delete-window edit-window))))
1373+
1374+
(defun cunene/claude-prompt-edit-send ()
1375+
"Send the edited prompt to the terminal without pressing return."
1376+
(interactive)
1377+
(unless cunene/claude-prompt-edit-mode
1378+
(user-error "Not in a Claude prompt edit buffer"))
1379+
(let ((text (string-trim (buffer-string)))
1380+
(target-buffer cunene/claude-prompt-edit--target-buffer))
1381+
(unless (and target-buffer (buffer-live-p target-buffer))
1382+
(user-error "Target Claude buffer no longer exists"))
1383+
(cunene/claude-prompt-edit--close-buffer)
1384+
(with-current-buffer target-buffer
1385+
(cunene/claude-prompt-edit--send-text text nil))
1386+
(message "Sent prompt to Claude (no submit)")))
1387+
1388+
(defun cunene/claude-prompt-edit-send-and-submit ()
1389+
"Send the edited prompt to the terminal and press return to submit."
1390+
(interactive)
1391+
(unless cunene/claude-prompt-edit-mode
1392+
(user-error "Not in a Claude prompt edit buffer"))
1393+
(let ((text (string-trim (buffer-string)))
1394+
(target-buffer cunene/claude-prompt-edit--target-buffer))
1395+
(unless (and target-buffer (buffer-live-p target-buffer))
1396+
(user-error "Target Claude buffer no longer exists"))
1397+
(cunene/claude-prompt-edit--close-buffer)
1398+
(with-current-buffer target-buffer
1399+
(cunene/claude-prompt-edit--send-text text t))
1400+
(message "Sent and submitted prompt to Claude")))
1401+
1402+
(defun cunene/claude-prompt-edit-cancel ()
1403+
"Cancel editing and close the prompt edit buffer without sending."
1404+
(interactive)
1405+
(unless cunene/claude-prompt-edit-mode
1406+
(user-error "Not in a Claude prompt edit buffer"))
1407+
(cunene/claude-prompt-edit--close-buffer)
1408+
(message "Prompt edit cancelled"))
1409+
1410+
(defun cunene/claude-prompt-edit ()
1411+
"Open a buffer to compose a prompt for Claude Code.
1412+
The prompt can be edited with full Emacs editing capabilities.
1413+
1414+
Keybindings in the edit buffer:
1415+
C-c ' - Send prompt to terminal (for review, no submit)
1416+
C-c C-c - Send prompt and submit (press Return)
1417+
C-c C-k - Cancel and close without sending"
1418+
(interactive)
1419+
(let ((buffer-name (claude-code-ide--get-buffer-name)))
1420+
(if-let ((terminal-buffer (get-buffer buffer-name)))
1421+
(let* ((edit-buffer-name (cunene/claude-prompt-edit--buffer-name terminal-buffer))
1422+
(edit-buffer (get-buffer-create edit-buffer-name)))
1423+
(with-current-buffer edit-buffer
1424+
(erase-buffer)
1425+
(text-mode)
1426+
(cunene/claude-prompt-edit-mode 1)
1427+
(setq-local cunene/claude-prompt-edit--target-buffer terminal-buffer))
1428+
(display-buffer edit-buffer
1429+
'((display-buffer-below-selected)
1430+
(window-height . 10)))
1431+
(select-window (get-buffer-window edit-buffer))
1432+
(message "Compose your prompt. C-c ' to send, C-c C-c to send+submit, C-c C-k to cancel"))
1433+
(user-error "No Claude Code session for this project"))))
12831434
#+end_src
12841435

12851436
* Eldoc

config/external.org

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,49 @@ any directory proferred by `consult-dir'."
180180
(define-key project-prefix-map (kbd "t") 'eat-project)
181181
(define-key project-prefix-map (kbd "T") 'eat-project-other-window))
182182

183+
(defun cunene/projectile--eat (&optional new-process other-window)
184+
"Invoke `eat' in the project's root.
185+
186+
Use argument NEW-PROCESS to indicate creation of a new process instead.
187+
Use argument OTHER-WINDOW to indicate whether the buffer should
188+
be displayed in a different window.
189+
190+
Switch to the project-specific eat buffer if it already exists."
191+
(let* ((project (projectile-acquire-root))
192+
(buffer-name (projectile-generate-process-name "eat" new-process project)))
193+
(unless (require 'eat nil 'noerror)
194+
(error "Package 'eat' is not available"))
195+
(if (buffer-live-p (get-buffer buffer-name))
196+
(if other-window
197+
(switch-to-buffer-other-window buffer-name)
198+
(switch-to-buffer buffer-name))
199+
;; Start a new eat process with the desired buffer name
200+
(let ((eat-buffer-name buffer-name)) ; ← This is the key!
201+
(projectile-with-default-dir project
202+
(eat))) ; ← eat uses eat-buffer-name internally
203+
;; After starting, ensure we're in the right buffer/window
204+
(if other-window
205+
(switch-to-buffer-other-window buffer-name)
206+
(switch-to-buffer buffer-name)))))
207+
208+
(defun cunene/projectile-run-eat (&optional arg)
209+
"Invoke `eat' in the project's root.
210+
211+
Switch to the project specific term buffer if it already exists.
212+
213+
Use a prefix argument ARG to indicate creation of a new process instead."
214+
(interactive "P")
215+
(cunene/projectile--eat arg))
216+
217+
(defun cunene/projectile-run-eat-other-window (&optional arg)
218+
"Invoke `eat' in the project's root.
219+
220+
Switch to the project specific term buffer if it already exists.
221+
222+
Use a prefix argument ARG to indicate creation of a new process instead."
223+
(interactive "P")
224+
(cunene/projectile--eat arg 'other-window))
225+
183226
(use-package vterm
184227
:ensure t
185228
:config
@@ -364,6 +407,33 @@ URL should be a valid web address."
364407
:config
365408
;; (load "~/.config/emacs/services.el" 'noerror)
366409
)
410+
411+
(defun cunene/prodigy-filter-by-tag (tag)
412+
"Open a Prodigy buffer showing only services with TAG."
413+
(interactive
414+
(list (intern (completing-read "Tag: "
415+
(delete-dups
416+
(mapcar #'symbol-name
417+
(apply #'append
418+
(mapcar (lambda (s)
419+
(plist-get s :tags))
420+
prodigy-services))))))))
421+
(let ((buffer-name (format "*prodigy - %s*" tag)))
422+
(with-current-buffer (get-buffer-create buffer-name)
423+
(prodigy-mode)
424+
(setq-local prodigy--filtered-tag tag)
425+
(prodigy-refresh))
426+
(switch-to-buffer buffer-name)))
427+
428+
(defun cunene/prodigy--filter-services-by-tag (orig-fun)
429+
(if (bound-and-true-p prodigy--filtered-tag)
430+
(cl-remove-if-not
431+
(lambda (svc)
432+
(member prodigy--filtered-tag (plist-get svc :tags)))
433+
prodigy-services)
434+
(funcall orig-fun)))
435+
436+
(advice-add #'prodigy-services :around #'cunene/prodigy--filter-services-by-tag)
367437
#+end_src
368438

369439
* Mongo

config/features.org

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -898,6 +898,31 @@ authoring documents with a fast and effective plain-text system.
898898
:config
899899
(setq org-fancy-priorities-list '("🅰" "🅱" "🅲" "🅳" "🅴")))
900900

901+
(with-eval-after-load 'ol
902+
(org-link-set-parameters
903+
"proj"
904+
:follow (lambda (path)
905+
"Follow a `proj:' link, opening the file relative to the project root."
906+
(require 'project) ; Ensure project.el is loaded
907+
(let* ((proj (project-current))
908+
(root (if proj (project-root proj) default-directory)))
909+
(org-mark-ring-push) ; Allow jumping back with C-c &
910+
(find-file (expand-file-name path root))))
911+
:face '(:foreground "SkyBlue" :underline t) ; Make them look distinct
912+
:help-echo "Open project-relative file")) ; Tooltip text
913+
914+
;; (use-package ox-taskjuggler
915+
;; :ensure t
916+
;; :after org)
917+
918+
(use-package org-transclusion
919+
:ensure t
920+
:commands (org-transclusion-mode))
921+
922+
; (with-eval-after-load 'org
923+
; (require `org-transclusion-font-lock)
924+
; (org-transclusion-font-lock-mode +1))
925+
901926
(use-package hl-todo
902927
:ensure t
903928
:bind (:map hl-todo-mode-map
@@ -950,6 +975,43 @@ authoring documents with a fast and effective plain-text system.
950975
'(display-buffer-use-some-window
951976
(main)))))
952977

978+
(defun cunene/org-roam-validate-id-links ()
979+
"Validate all org-roam ID links by checking the database.
980+
Reports any 'id' links that point to non-existent nodes."
981+
(interactive)
982+
(let ((broken-links '())
983+
;; Query the database for ALL links of type 'id'
984+
(id-links-query "SELECT source, dest FROM links WHERE type = 'id'"))
985+
(message "Querying org-roam database for broken ID links...")
986+
(dolist (link (org-roam-db-query id-links-query))
987+
(pcase-let ((`(,source-id ,dest-id) link))
988+
;; For each link, check if the destination node exists
989+
(unless (org-roam-node-from-id dest-id)
990+
;; If it doesn't exist, add it to our list of broken links
991+
(let* ((source-node (org-roam-node-from-id source-id))
992+
(source-file (when source-node (org-roam-node-file source-node))))
993+
(push (list source-file source-id dest-id) broken-links)))))
994+
995+
;; Display the results
996+
(if (null broken-links)
997+
(message "All org-roam ID links are valid! 🎉")
998+
(let ((buf (get-buffer-create "*Org-Roam Broken ID Links*")))
999+
(with-current-buffer buf
1000+
(setq buffer-read-only nil)
1001+
(erase-buffer)
1002+
(insert "=== Org-Roam Broken ID Links Report ===\n\n")
1003+
(dolist (link (nreverse broken-links))
1004+
(pcase-let ((`(,source-file ,source-id ,dest-id) link))x
1005+
(insert (format "In file: %s\n" (or source-file "Unknown")))
1006+
(insert (format " Source Node ID: %s\n" source-id))
1007+
(insert (format " Points to non-existent ID: %s\n" dest-id))
1008+
(insert "----------------------------------------\n")))
1009+
(goto-char (point-min))
1010+
(special-mode)
1011+
(setq buffer-read-only t))
1012+
(pop-to-buffer buf)
1013+
(message (format "Found %d broken ID link(s). See '*Org-Roam Broken ID Links*' buffer." (length broken-links)))))))
1014+
9531015
(defun cunene/occur-non-ascii ()
9541016
"Find any non-ascii characters in the current buffer."
9551017
(interactive)
@@ -1068,9 +1130,10 @@ ARGUMENT determines the visible heading."
10681130
(setq result (seq-take result 1000)))
10691131
result))
10701132

1133+
;; FIXME: does not work well. use only when having performance issues.
10711134
;; Apply safety wrapper to completion functions
1072-
(advice-add 'completion-pcm--all-completions :around #'cunene/safe-completion)
1073-
(advice-add 'all-completions :around #'cunene/safe-completion)
1135+
;; (advice-add 'completion-pcm--all-completions :around #'cunene/safe-completion)
1136+
;;(advice-add 'all-completions :around #'cunene/safe-completion)
10741137

10751138
(defun debug-completions ()
10761139
"Debug completion behavior."

0 commit comments

Comments
 (0)