Blob


1 ;; get rid of custom from my init file
2 (setq custom-file "~/.emacs.d/emacs-custom.el")
3 (load custom-file)
5 (setq-default abbrev-mode t)
6 (setq abbrev-file-name
7 (expand-file-name "~/dotsnew/emacs/abbrev_defs"))
9 (defconst op/backup-dir
10 (expand-file-name "backups" user-emacs-directory))
11 (unless (file-exists-p op/backup-dir)
12 (make-directory op/backup-dir))
13 (setq backup-directory-alist `(("." . ,op/backup-dir)))
15 (setq use-dialog-box nil
16 x-stretch-cursor t
17 require-final-newline t
18 visible-bell nil
19 load-prefer-newer t
20 tab-bar-show 1
21 enable-recursive-minibuffers t
22 imenu-auto-rescan 1
23 use-short-answers t
24 next-error-message-highlight t
25 read-minibuffer-restore-windows nil
26 isearch-allow-motion t
27 calc-make-windows-dedicated t
28 user-mail-address "op@omarpolo.com")
30 (setq completion-ignore-case t
31 read-file-name-completion-ignore-case t
32 read-buffer-completion-ignore-case t)
34 ;; I don't like how compile uses `make -k' by default, I want to stop
35 ;; on errors / warnings.
36 (setq compile-command "make")
38 ;; "diff refinement", i.e. highlighting the changes in a more granular
39 ;; way, is quite awful to have it enabled by default. sometimes is
40 ;; useful, but for me it's more of a visual noise most of the times.
41 (setq diff-refine nil)
43 ;; disable also the syntax highlighting in the diff buffers
44 (setq diff-font-lock-syntax nil)
46 (define-key global-map (kbd "C-x C-b") #'ibuffer)
47 (define-key global-map (kbd "M-g i") #'imenu)
49 (defun op/imenu ()
50 "Just like `imenu', but always flattened!"
51 (interactive ))
53 ;; mg-like
54 (define-key minibuffer-mode-map (kbd "C-w") #'backward-kill-word)
56 (defun op/reverse-other-window ()
57 "Like `other-window', but reverse."
58 (interactive "")
59 (other-window -1))
60 (define-key global-map (kbd "C-x O") #'op/reverse-other-window)
62 (define-key global-map (kbd "C-x v f") #'vc-pull)
64 (setq uniquify-buffer-name-style 'forward
65 uniquify-strip-common-suffix t)
67 (setq-default scroll-up-aggressively 0.0
68 scroll-down-aggressively 0.0
69 scroll-preserve-screen-position t
70 next-screen-context-lines 1)
72 (define-key global-map (kbd "M-z") #'zap-up-to-char)
74 (require 'whitespace)
75 (setq whitespace-style '(face trailing)
76 backward-delete-char-untabify-method 'hungry
77 tab-always-indent 'complete
78 tab-width 8
79 sentence-end-double-space t)
80 (setq-default indent-tabs-mode t)
82 (defun op/enable-tabs ()
83 "Enable `indent-tabs-mode' in the current buffer."
84 (interactive)
85 (setq-local indent-tabs-mode t))
87 (defun op/disable-tabs ()
88 "Disable `indent-tabs-mode' in the current buffer."
89 (interactive)
90 (setq-local indent-tabs-mode nil))
92 (add-hook 'conf-mode-hook #'op/enable-tabs)
93 (add-hook 'text-mode-hook #'op/enable-tabs)
94 (add-hook 'prog-mode-hook #'op/enable-tabs)
95 (add-hook 'prog-mode-hook #'whitespace-mode)
96 (add-hook 'text-mode-hook #'whitespace-mode)
98 (dolist (hook '(emacs-lisp-mode-hook
99 clojure-mode-hook
100 clojurescript-mode-hook
101 clojurec-mode-hook
102 scss-mode-hook))
103 (add-hook hook #'op/disable-tabs))
105 (with-eval-after-load 'log-edit
106 (add-hook 'log-edit-mode #'auto-fill-mode))
108 ;; free the c-z binding
109 (define-key global-map (kbd "C-z") nil)
110 (define-key global-map (kbd "C-z V") #'variable-pitch-mode)
111 (define-key global-map (kbd "C-z n") #'display-line-numbers-mode)
113 (define-key global-map (kbd "M-SPC") #'cycle-spacing)
114 (define-key global-map (kbd "M-u") #'upcase-dwim)
115 (define-key global-map (kbd "M-l") #'downcase-dwim)
116 (define-key global-map (kbd "M-c") #'capitalize-dwim)
118 (let ((font "-misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso10646-1"))
119 (set-frame-font font nil t)
120 (add-to-list 'default-frame-alist `(font . ,font)))
122 ;; fix the emojis too
123 (set-fontset-font t 'emoji '("Noto Emoji" . "iso10646-1")
124 nil 'prepend)
126 ;; some cool stuff
127 (save-place-mode +1)
128 (savehist-mode +1)
129 (setq history-delete-duplicates t
130 history-length 1000
131 savehist-save-minibuffer-history t)
132 (electric-pair-mode +1)
134 (define-key global-map (kbd "M-/") #'hippie-expand)
135 (setq hippie-expand-try-functions-list
136 '(try-expand-dabbrev
137 try-expand-dabbrev-all-buffers
138 try-expand-dabbrev-from-kill
139 try-complete-file-name-partially
140 try-complete-file-name
141 try-expand-all-abbrevs
142 try-expand-list
143 try-expand-line
144 try-complete-lisp-symbol-partially
145 try-complete-lisp-symbol))
147 (setq isearch-lazy-count t
148 search-whitespace-regexp ".*?"
149 isearch-allow-scroll 'unlimited)
151 (defun op/buffer-to-side-window (place)
152 "Place the current buffer in the side window at PLACE."
153 (interactive (list (intern
154 (completing-read "Which side: "
155 '(top left right bottom)))))
156 (let ((buf (current-buffer)))
157 (display-buffer-in-side-window
158 buf `((window-height . 0.15)
159 (side . ,place)
160 (slot . -1)
161 (window-parameters . ((no-delete-other-windows . t)))))
162 (delete-window)))
164 (defun op/visit-new-migration-file (name)
165 "Visit a new SQL migration file named after NAME."
166 (interactive "Mname: ")
167 (let* ((name (replace-regexp-in-string " " "-" (string-trim name)))
168 (f (format "%s-%s.sql"
169 (format-time-string "%Y%m%d%H%M")
170 name)))
171 (find-file f)))
173 (defun op/fill-or-unfill (fn &optional justify region)
174 "Meant to be an adviced :around `fill-paragraph'.
175 FN is the original `fill-column'. If `last-command' is
176 `fill-paragraph', unfill it, fill it otherwise. Inspired from a
177 post on endless parentheses. Optional argument JUSTIFY and
178 REGION are passed to `fill-paragraph'."
179 (let ((fill-column
180 (if (eq last-command 'fill-paragraph)
181 (progn (setq this-command nil)
182 (point-max))
183 fill-column)))
184 (funcall fn justify region)))
185 (advice-add 'fill-paragraph :around #'op/fill-or-unfill)
187 (defmacro op/deftranspose (name scope key doc)
188 "Macro to produce transposition functions.
189 NAME is the function's symbol. SCOPE is the text object to
190 operate on. Optional DOC is the function's docstring.
192 Transposition over an active region will swap the object at
193 mark (region beginning) with the one at point (region end).
195 It can optionally define a key for the defined function in the
196 `global-map' if KEY is passed.
198 Originally from protesilaos' dotemacs."
199 (declare (indent defun))
200 `(progn
201 (defun ,name (arg)
202 ,doc
203 (interactive "p")
204 (let ((x (intern (format "transpose-%s" ,scope))))
205 (if (use-region-p)
206 (funcall x 0)
207 (funcall x arg))))
208 ,(when key
209 `(define-key global-map (kbd ,key) #',name))))
211 (op/deftranspose op/transpose-lines "lines" "C-x C-t"
212 "Transpose lines or swap over active region.")
214 (op/deftranspose op/transpose-paragraphs "paragraphs" "C-S-t"
215 "Transpose paragraph or swap over active region.")
217 (op/deftranspose op/transpose-sentences "sentences" "C-x M-t"
218 "Transpose sentences or swap over active region.")
220 (op/deftranspose op/transpose-sexps "sexps" "C-M-t"
221 "Transpose sexps or swap over active region.")
223 (op/deftranspose op/transpose-words "words" "M-t"
224 "Transpose words or swap over active region.")
226 (defun op/narrow-or-widen-dwim (p)
227 "Widen if the buffer is narrowed, narrow-dwim otherwise.
228 Dwim means: region, org-src-block, org-subtree or defun,
229 whichever applies first. Narrowing to org-src-blocks actually
230 calls `org-edit-src-code'.
232 With prefix P, don't widen, just narrow even if buffer is already
233 narrowed. With P being -, narrow to page instead of to defun.
235 Taken from endless parentheses."
236 (interactive "P")
237 (declare (interactive-only))
238 (cond ((and (buffer-narrowed-p) (not p)) (widen))
239 ((region-active-p)
240 (narrow-to-region (region-beginning)
241 (region-end)))
242 ((derived-mode-p 'org-mode)
243 ;; `org-edit-src-code' isn't a real narrowing
244 (cond ((ignore-errors (org-edit-src-code) t))
245 ((ignore-errors (org-narrow-to-block) t))
246 (t (org-narrow-to-subtree))))
247 ((eql p '-) (narrow-to-page))
248 (t (narrow-to-defun))))
250 (define-key global-map (kbd "C-c w") #'op/narrow-or-widen-dwim)
252 (with-eval-after-load 'dired
253 (add-hook 'dired-mode-hook #'dired-hide-details-mode)
254 (add-hook 'dired-mode-hook #'dired-omit-mode)
256 (define-key dired-mode-map (kbd "C-c w") #'wdired-change-to-wdired-mode)
258 (require 'dired-x)
259 (setq dired-listing-switches "-lahF"
260 dired-dwim-target t
261 dired-deletion-confirmer #'y-or-n-p
262 dired-do-revert-buffer t))
264 ;; just like telescope!
265 (with-eval-after-load 'diff-mode
266 (define-key diff-mode-map (kbd "M-SPC") #'scroll-down-command))
268 (with-eval-after-load 'elisp-mode
269 (add-hook 'emacs-lisp-mode-hook #'checkdoc-minor-mode)
270 (add-hook 'emacs-lisp-mode-hook #'prettify-symbols-mode)
271 (let ((map emacs-lisp-mode-map))
272 (define-key map (kbd "C-c C-k") #'eval-buffer)
273 (define-key map (kbd "C-c k") #'op/ert-all)
274 (define-key map (kbd "C-c C-z") #'op/ielm-repl)))
276 (with-eval-after-load 'help
277 (add-hook 'help-mode-hook #'visual-line-mode))
279 ;; add melpa
280 (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
282 ;; packages that i want to be installed
283 (dolist (pkg '(vc-got pdf-tools eglot nameless sly cider go-mode web-mode
284 lua-mode markdown-mode yaml-mode gemini-mode elfeed
285 form-feed shackle embark consult mct puni))
286 (unless (package-installed-p pkg)
287 (message "Installing %s" pkg)
288 (package-install pkg)))
290 (global-form-feed-mode +1)
292 (add-hook 'text-mode-hook #'puni-mode)
293 (add-hook 'prog-mode-hook #'puni-mode)
294 (define-key puni-mode-map (kbd "C-)") #'puni-slurp-forward)
295 (define-key puni-mode-map (kbd "C-(") #'puni-barf-forward)
297 (setq completion-styles '(basic substring initials flex partial-completion))
299 (require 'consult) ;; some stuff lacks an autoload and i don't want to debug it
301 (cl-loop for (key . func) in '(("C-x :" . consult-complex-command)
302 ("C-x b" . consult-buffer)
303 ("C-x 4 b" . consult-buffer-other-window)
304 ("C-x 5 b" . consult-buffer-other-frame)
305 ("C-x r b" . consult-bookmark)
306 ("C-x p b" . consult-project-buffer)
307 ("M-y" . consult-yank-pop)
308 ("M-g g" . consult-goto-line)
309 ("M-g M-g" . consult-goto-line)
310 ("M-g m" . consult-mark)
311 ("M-g i" . consult-imenu)
312 ("M-s l" . consult-line)
313 ("M-s L" . consult-line-multi)
314 ("M-s m" . consult-multi-occur))
315 do (define-key global-map (kbd key) func))
316 (add-hook 'completion-list-mode-hook #'consult-preview-at-point-mode)
318 (setq completions-detailed t)
319 (mct-minibuffer-mode +1)
320 (mct-region-mode +1)
322 ;; override the binding for the annoying mct-backward-updir.
323 (define-key mct-minibuffer-local-filename-completion-map
324 (kbd "DEL") #'backward-delete-char)
326 (setq mct-remove-shadowed-file-names t
327 mct-completions-format 'one-column
328 mct-completion-passlist '(Info-goto-node
329 Info-index
330 Info-menu
331 vc-retrieve-tag
332 imenu
333 file
334 buffer
335 consult-project-buffer
336 kill-ring
337 consult-buffer))
339 (with-eval-after-load 'cider
340 (define-key cider-repl-mode-map (kbd "C-c M-o") #'cider-repl-clear-buffer))
342 (with-eval-after-load 'go-mode
343 (add-hook 'go-mode-hook #'subword-mode))
345 (with-eval-after-load 'eglot
346 (define-key eglot-mode-map (kbd "<f1>") #'eglot-code-actions)
347 (define-key eglot-mode-map (kbd "<f2>") #'eglot-format)
348 (add-to-list 'eglot-ignored-server-capabilites
349 :documentHighlightProvider)
350 (add-to-list 'eglot-server-programs
351 '(c-mode . ("clangd" "--header-insertion=never"))))
353 (add-hook 'emacs-lisp-mode #'nameless-mode)
354 (with-eval-after-load 'nameless
355 (setq nameless-private-prefix t
356 nameless-affect-indentation-and-filling nil)
357 (define-key emacs-lisp-mode-map (kbd "_") #'nameless-insert-name-or-self-insert))
359 (add-to-list 'auto-mode-alist '("\\.html\\'" . web-mode))
360 (with-eval-after-load 'web-mode
361 (setq web-mode-markup-indent-offset 2
362 web-mode-css-indent-offset 2
363 web-mode-style-padding 0
364 web-mode-enable-engine-detection t)
365 (add-hook 'web-mode-hook #'op/disable-tabs)
367 ;; fix .dir-locals.el
368 (defun op/web-mode-fix-dir-locals ()
369 (when (derived-mode-p major-mode 'web-mode)
370 (web-mode-guess-engine-and-content-type)))
371 (add-hook 'hack-local-variables-hook #'op/web-mode-fix-dir-locals))
373 (with-eval-after-load 'css-mode
374 (add-hook 'css-mode-hook #'op/disable-tabs))
376 (with-eval-after-load 'flymake
377 (define-key prog-mode-map (kbd "C-c ! n") #'flymake-goto-next-error)
378 (define-key prog-mode-map (kbd "C-c ! p") #'flymake-goto-prev-error))
380 (with-eval-after-load 'cc-mode
381 (setq c-basic-offset 8
382 c-default-style "K&R")
383 (dolist (hook '(c-mode-hook c++-mode-hook))
384 (add-hook hook #'abbrev-mode)
385 (add-hook hook #'subword-mode))
386 (defun op/c-indent ()
387 (interactive)
388 (c-set-offset 'arglist-intro '+)
389 (c-set-offset 'arglist-cont-nonempty '*))
390 (add-hook 'c-mode-hook #'op/c-indent)
391 ;; TODO: improve it!
392 (defun op/c-add-include (path &optional localp)
393 "Include PATH at the start of the file.
394 If LOCALP is non-nil, the include will be \"local\"."
395 (interactive "Mheader to include: \nP")
396 (save-excursion
397 (let ((re (if localp
398 "^#[ \t]*include[ \t]*\""
399 "^#[ \t]*include[ \t]*<"))
400 (ignore-re "^#include \"compat.h\"")
401 start)
402 (goto-char (point-min))
403 (while (not (or (and (looking-at re)
404 (not (looking-at ignore-re)))
405 (eobp)))
406 (forward-line))
407 (when (eobp)
408 (error "Don't know where to insert the header"))
409 (open-line 1)
410 (insert "#include " (if localp "\"\"" "<>"))
411 (backward-char)
412 (insert path)
413 (move-beginning-of-line 1)
414 (setq start (point))
415 (forward-line)
416 (while (and (looking-at re)
417 (not (eobp)))
418 (forward-line))
419 (sort-lines nil start (point)))))
420 (define-key c-mode-map (kbd "C-c C-a") #'op/c-add-include))
422 (with-eval-after-load 'perl-mode
423 (setq perl-indent-level 8))
425 (with-eval-after-load 'sh-script
426 (setq sh-basic-offset 8
427 sh-indent-after-loop-construct 8
428 sh-indent-after-continuation nil))
432 (setq eshell-hist-ignoredups t)
434 (defun op/eshell-bufname (dir)
435 (concat "*eshell " (expand-file-name dir) "*"))
437 (defun op/eshell (arg)
438 "Run or jump to eshell in current project.
439 If called with prefix argument ARG always create a new eshell
440 buffer."
441 (interactive "P")
442 (let* ((proj (project-current))
443 (dir (if (and proj (not arg))
444 (project-root proj)
445 default-directory))
446 (default-directory dir)
447 (eshell-buffer-name (let ((name (op/eshell-bufname dir)))
448 (if arg
449 (generate-new-buffer name)
450 name))))
451 (eshell)))
452 (define-key global-map (kbd "C-c e") #'op/eshell)
454 (with-eval-after-load 'eshell
455 (setq eshell-save-history-on-exit t
456 eshell-history-size 1024
458 eshell-compl-dir-ignore
459 "\\`\\(\\.\\.?\\|CVS\\|\\.svn\\|\\.git\\|\\.got\\)/\\'")
461 (defun op/eshell-after-cd (&rest _)
462 (rename-buffer (op/eshell-bufname default-directory) t))
464 (advice-add #'eshell/cd :after #'op/eshell-after-cd))
466 (with-eval-after-load 'esh-mode
467 (defun op/clear-eshell ()
468 (interactive "")
469 (let ((inhibit-read-only t))
470 (erase-buffer)
471 (eshell-send-input)))
473 (define-key eshell-command-map (kbd "M-o") #'op/clear-eshell))
476 ;; sndio.el
477 (unless (package-installed-p 'sndio)
478 (package-install-file "~/w/sndio.el/sndio.el"))
481 ;; saturn
482 (unless (package-installed-p 'saturn)
483 (package-install-file "~/w/saturn/GUI/saturn.el"))
486 ;; simple-pass
487 (unless (package-installed-p 'simple-pass)
488 (package-install-file "~/.emacs.d/simple-pass.el"))
489 (define-key global-map (kbd "C-z p") #'simple-pass-copy)
493 ;; elfeed
495 (define-key global-map (kbd "C-x w") #'elfeed)
496 (with-eval-after-load 'elfeed
497 (define-key elfeed-show-mode-map (kbd "q") #'delete-window)
498 (define-key elfeed-show-mode-map (kbd "S-SPC") #'scroll-down-command)
499 (define-key elfeed-show-mode-map (kbd "M-SPC") #'scroll-down-command)
500 (setq elfeed-show-entry-switch #'pop-to-buffer
501 elfeed-feeds
502 '("https://undeadly.org/cgi?action=rss&full=yes&items=10"
503 "http://www.tedunangst.com/flak/rss"
504 "https://www.dragonflydigest.com/feed"
505 "https://www.mirbsd.org/news.rss"
506 "https://www.mirbsd.org/announce.rss"
507 "https://bentsukun.ch/index.xml"
508 "https://drewdevault.com/feed.xml"
509 "https://www.cambus.net/atom.xml"
510 "https://dataswamp.org/~solene/rss.xml"
511 "https://briancallahan.net/blog/feed.xml"
512 "https://www.poolp.org/index.xml"
513 "https://jcs.org/rss"
514 "https://sanctum.geek.nz/arabesque/feed/"
515 "https://tech.toryanderson.com/"
516 "https://alexschroeder.ch/wiki?action=journal;search=-tag:rpg -tag:rsp;lang=en;title=English Diary without RPG Pages"
517 "http://boston.conman.org/bostondiaries.rss"
518 "https://emacsninja.com/feed.atom"
519 "https://bsdly.blogspot.com/feeds/posts/default"
520 "https://crawshaw.io/atom.xml"
521 "https://nullprogram.com/feed/"
522 "http://pragmaticemacs.com/feed/"
523 "https://emacsnotes.wordpress.com/feed/"
524 "https://metaredux.com/feed.xml"
525 "https://emacsredux.com/atom.xml"
526 "https://endlessparentheses.com/atom.xml"
527 "https://www.masteringemacs.org/feed"
528 "https://cestlaz.github.io/rss.xml"
529 "https://utcc.utoronto.ca/~cks/space/blog/?atom"
530 "https://irreal.org/blog/?feed=rss2"
531 "https://jao.io/blog/rss.xml"
532 "https://planet.lisp.org/rss20.xml"
533 "https://insideclojure.org/feed.xml"
534 "https://tech.toryanderson.com/index.xml"
535 "https://vermaden.wordpress.com/feed/"
536 "https://www.arp242.net/feed.xml"
537 "https://tymoon.eu/api/reader/atom"
538 "https://venam.nixers.net/blog/feed.xml"
539 "https://www.omarpolo.com/rss.xml"
540 "https://owarisubs.lacumpa.biz/feed/"
541 "https://asenshi.moe/feed/"
542 "https://godotengine.org/rss.xml"
544 "https://adventofcomputing.libsyn.com/rss"
546 "https://github.com/go-gitea/gitea/releases.atom"
548 "https://nitter.pussthecat.org/NanoRaptor/rss"
550 "https://github.com/yshui/picom/releases.atom"
551 "https://github.com/vslavik/poedit/releases.atom"
552 "https://github.com/TokTok/c-toxcore/releases.atom"
553 "https://github.com/alexander-akhmetov/python-telegram/releases.atom"
554 "https://github.com/paul-nameless/tg/releases.atom"
555 "https://github.com/YACReader/yacreader/releases.atom"
556 "https://github.com/luarocks/luarocks/releases.atom"
557 "https://github.com/okbob/pspg/releases.atom"
558 "https://github.com/taisei-project/taisei/releases.atom"
559 "https://github.com/recp/cglm/releases.atom"
560 "https://github.com/SCons/scons/releases.atom"
561 "https://git.sr.ht/~rjarry/aerc/refs/rss.xml"
563 "https://causal.agency/list/pounce.atom"
565 "https://www.crimsonmagic.me/feed/"
566 "https://fullybookedtls.wordpress.com/feed/"
568 "https://draculadaily.substack.com/feed")))
570 (setq shackle-default-rule nil
571 shackle-rules
572 (let ((repls "\\*\\(cider-repl\\|sly-mrepl\\|ielm\\)")
573 (godot "\\*godot - .*\\*")
574 (vcs "\\*\\(Flymake\\|Package-Lint\\|vc-\\(git\\|got\\) :\\).*")
575 (elfeed "\\*elfeed-entry\\*")
576 (vmd "\\*vmd console .*"))
577 `(("*Async Shell Command*" :ignore t)
578 (,repls :regexp t
579 :align below
580 :size 0.3)
581 (,godot :regexp t
582 :align t
583 :size 0.3)
584 (occur-mode :select t
585 :align right
586 :size 0.3)
587 (diff-mode :select t)
588 (help-mode :select t
589 :align left
590 :size 0.3)
591 (,vcs :regexp t
592 :align above
593 :size 0.15
594 :select t)
595 (,elfeed :regexp t
596 :align t
597 :select t
598 :size 0.75)
599 (,vmd :regexp t
600 :align below
601 :select t
602 :size 0.3))))
603 (shackle-mode +1)
605 ;; (setq display-buffer-alist nil)
607 (define-key global-map (kbd "M-g e") #'embark-act)
609 (with-eval-after-load 'embark
610 (defun op/target-filename+line ()
611 "Target a file with optional line number: file[:number]."
612 (save-excursion
613 (let* ((beg (progn (skip-chars-backward "^[:space:]\n")
614 (point)))
615 (end (progn (skip-chars-forward "^[:space:]\n")
616 (point)))
617 (str (buffer-substring-no-properties beg end)))
618 (save-match-data
619 (when (and (progn (goto-char beg)
620 (ffap-file-at-point))
621 (string-match ".+\\(:[[:digit:]]+\\)?:?" str))
622 `(file ,str ,beg . ,end))))))
624 (add-to-list 'embark-target-finders #'op/target-filename+line)
626 (defun op/acme-find-file (filename)
627 "Visit FILENAME like `find-file', but also jump to line if provided."
628 (save-match-data
629 (if (not (string-match "\\(.+\\):\\([[:digit:]]+\\)" filename))
630 (find-file filename)
631 (let ((path (match-string 1 filename))
632 (line (string-to-number (match-string 2 filename))))
633 (with-current-buffer (find-file path)
634 (goto-line line))))))
636 (define-key embark-file-map (kbd "RET") #'op/acme-find-file))