1 (defconst op/backup-dir
2 (expand-file-name "backups" user-emacs-directory))
3 (unless (file-exists-p op/backup-dir)
4 (make-directory op/backup-dir))
5 (setq backup-directory-alist `(("." . ,op/backup-dir)))
7 (setq use-dialog-box nil
9 require-final-newline t
13 enable-recursive-minibuffers t
16 (setq completion-ignore-case t
17 read-file-name-completion-ignore-case t
18 read-buffer-completion-ignore-case t)
20 (define-key global-map (kbd "C-x C-b") #'ibuffer)
21 (define-key global-map (kbd "M-g i") #'imenu)
24 (define-key minibuffer-mode-map (kbd "C-w") #'backward-kill-word)
26 (setq uniquify-buffer-name-style 'forward
27 uniquify-strip-common-suffix t)
29 (setq-default scroll-up-aggressively 0.0
30 scroll-down-aggressively 0.0
31 scroll-preserve-screen-position t
32 next-screen-context-lines 1)
34 (define-key global-map (kbd "M-z") #'zap-up-to-char)
37 (setq whitespace-style '(face trailing)
38 backward-delete-char-untabify-method 'hungry
39 tab-always-indent 'complete
41 sentence-end-double-space t)
42 (setq-default indent-tabs-mode t)
44 (defun op/enable-tabs ()
45 "Enable `indent-tabs-mode' in the current buffer."
47 (setq-local indent-tabs-mode t))
49 (defun op/disable-tabs ()
50 "Disable `indent-tabs-mode' in the current buffer."
52 (setq-local indent-tabs-mode nil))
54 (add-hook 'conf-mode-hook #'op/enable-tabs)
55 (add-hook 'text-mode-hook #'op/enable-tabs)
56 (add-hook 'prog-mode-hook #'op/enable-tabs)
57 (add-hook 'prog-mode-hook #'whitespace-mode)
58 (add-hook 'text-mode-hook #'whitespace-mode)
60 (dolist (hook '(emacs-lisp-mode-hook
62 clojurescript-mode-hook
65 (add-hook hook #'op/disable-tabs))
67 (with-eval-after-load 'log-edit
68 (add-hook 'log-edit-mode #'auto-fill-mode))
70 ;; free the c-z binding
71 (define-key global-map (kbd "C-z") nil)
72 (define-key global-map (kbd "C-z V") #'variable-pitch-mode)
73 (define-key global-map (kbd "C-z n") #'display-line-numbers-mode)
75 (define-key global-map (kbd "M-SPC") #'cycle-spacing)
76 (define-key global-map (kbd "M-u") #'upcase-dwim)
77 (define-key global-map (kbd "M-l") #'downcase-dwim)
78 (define-key global-map (kbd "M-c") #'capitalize-dwim)
80 (let ((font "-misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso10646-1"))
81 (set-frame-font font nil t)
82 (add-to-list 'default-frame-alist `(font . ,font)))
87 (setq history-delete-duplicates t
89 savehist-save-minibuffer-history t)
90 (electric-pair-mode +1)
92 (define-key global-map (kbd "M-/") #'hippie-expand)
93 (setq hippie-expand-try-functions-list
95 try-expand-dabbrev-all-buffers
96 try-expand-dabbrev-from-kill
97 try-complete-file-name-partially
98 try-complete-file-name
99 try-expand-all-abbrevs
102 try-complete-lisp-symbol-partially
103 try-complete-lisp-symbol))
105 (setq isearch-lazy-count t
106 search-whitespace-regexp ".*?"
107 isearch-allow-scroll 'unlimited)
109 (defun op/buffer-to-side-window (place)
110 "Place the current buffer in the side window at PLACE."
111 (interactive (list (intern
112 (completing-read "Which side: "
113 '(top left right bottom)))))
114 (let ((buf (current-buffer)))
115 (display-buffer-in-side-window
116 buf `((window-height . 0.15)
119 (window-parameters . ((no-delete-other-windows . t)))))
122 (defun op/fill-or-unfill (fn &optional justify region)
123 "Meant to be an adviced :around `fill-paragraph'.
124 FN is the original `fill-column'. If `last-command' is
125 `fill-paragraph', unfill it, fill it otherwise. Inspired from a
126 post on endless parentheses. Optional argument JUSTIFY and
127 REGION are passed to `fill-paragraph'."
129 (if (eq last-command 'fill-paragraph)
130 (progn (setq this-command nil)
133 (funcall fn justify region)))
134 (advice-add 'fill-paragraph :around #'op/fill-or-unfill)
136 (defmacro op/deftranspose (name scope key doc)
137 "Macro to produce transposition functions.
138 NAME is the function's symbol. SCOPE is the text object to
139 operate on. Optional DOC is the function's docstring.
141 Transposition over an active region will swap the object at
142 mark (region beginning) with the one at point (region end).
144 It can optionally define a key for the defined function in the
145 `global-map' if KEY is passed.
147 Originally from protesilaos' dotemacs."
148 (declare (indent defun))
153 (let ((x (intern (format "transpose-%s" ,scope))))
158 `(define-key global-map (kbd ,key) #',name))))
160 (op/deftranspose op/transpose-lines "lines" "C-x C-t"
161 "Transpose lines or swap over active region.")
163 (op/deftranspose op/transpose-paragraphs "paragraphs" "C-S-t"
164 "Transpose paragraph or swap over active region.")
166 (op/deftranspose op/transpose-sentences "sentences" "C-x M-t"
167 "Transpose sentences or swap over active region.")
169 (op/deftranspose op/transpose-sexps "sexps" "C-M-t"
170 "Transpose sexps or swap over active region.")
172 (op/deftranspose op/transpose-words "words" "M-t"
173 "Transpose words or swap over active region.")
175 (defun op/narrow-or-widen-dwim (p)
176 "Widen if the buffer is narrowed, narrow-dwim otherwise.
177 Dwim means: region, org-src-block, org-subtree or defun,
178 whichever applies first. Narrowing to org-src-blocks actually
179 calls `org-edit-src-code'.
181 With prefix P, don't widen, just narrow even if buffer is already
182 narrowed. With P being -, narrow to page instead of to defun.
184 Taken from endless parentheses."
186 (declare (interactive-only))
187 (cond ((and (buffer-narrowed-p) (not p)) (widen))
189 (narrow-to-region (region-beginning)
191 ((derived-mode-p 'org-mode)
192 ;; `org-edit-src-code' isn't a real narrowing
193 (cond ((ignore-errors (org-edit-src-code) t))
194 ((ignore-errors (org-narrow-to-block) t))
195 (t (org-narrow-to-subtree))))
196 ((eql p '-) (narrow-to-page))
197 (t (narrow-to-defun))))
199 (define-key global-map (kbd "C-c w") #'op/narrow-or-widen-dwim)
201 (with-eval-after-load 'dired
202 (add-hook 'dired-mode-hook #'dired-hide-details-mode)
203 (add-hook 'dired-mode-hook #'dired-omit-mode)
205 (define-key dired-mode-map (kbd "C-c w") #'wdired-change-to-wdired-mode)
208 (setq dired-listing-switches "-lahF"
210 dired-deletion-confirmer #'y-or-n-p))
212 ;; just like telescope!
213 (with-eval-after-load 'diff-mode
214 (define-key diff-mode-map (kbd "M-SPC") #'scroll-down-command))
216 (with-eval-after-load 'elisp-mode
217 (add-hook 'emacs-lisp-mode-hook #'checkdoc-minor-mode)
218 (add-hook 'emacs-lisp-mode-hook #'prettify-symbols-mode)
219 (let ((map emacs-lisp-mode-map))
220 (define-key map (kbd "C-c C-k") #'eval-buffer)
221 (define-key map (kbd "C-c k") #'op/ert-all)
222 (define-key map (kbd "C-c C-z") #'op/ielm-repl)))
224 (with-eval-after-load 'help
225 (add-hook 'help-mode-hook #'visual-line-mode))
228 (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
230 ;; packages that i want to be installed
231 (dolist (pkg '(vc-got pdf-tools eglot nameless sly cider go-mode web-mode
232 lua-mode markdown-mode elfeed form-feed shackle
233 embark mct marginalia puni))
234 (unless (package-installed-p pkg)
235 (message "Installing %s" pkg)
236 (package-install pkg)))
238 (global-form-feed-mode +1)
240 (add-hook 'text-mode-hook #'puni-mode)
241 (add-hook 'prog-mode-hook #'puni-mode)
242 (define-key puni-mode-map (kbd "C-)") #'puni-slurp-forward)
243 (define-key puni-mode-map (kbd "C-(") #'puni-barf-forward)
245 (setq completion-styles '(basic substring initials flex partial-completion))
248 (mct-minibuffer-mode +1)
250 (setq mct-remove-shadowed-file-names t
251 mct-completions-format 'one-column
252 mct-completion-passlist '(Info-goto-node
261 (with-eval-after-load 'go-mode
262 (add-hook 'go-mode-hook #'subword-mode))
264 (with-eval-after-load 'eglot
265 (define-key eglot-mode-map (kbd "<f1>") #'eglot-code-actions)
266 (define-key eglot-mode-map (kbd "<f2>") #'eglot-format)
267 (add-to-list 'eglot-ignored-server-capabilites
268 :documentHighlightProvider)
269 (add-to-list 'eglot-server-programs
270 '(c-mode . ("clangd" "--header-insertion=never"))))
272 (with-eval-after-load 'nameless
273 (add-hook 'emacs-lisp-mode #'nameless-mode)
274 (setq nameless-private-prefix t
275 nameless-affect-indentation-and-filling nil)
276 (define-key emacs-lisp-mode-map (kbd "_") #'nameless-insert-name-or-self-insert))
278 (with-eval-after-load 'web-mode
279 (setq web-mode-markup-indent-offset 2
280 web-mode-css-indent-offset 2
281 web-mode-style-padding 0
282 web-mode-enable-engine-detection t)
283 (add-hook 'web-mode-hook #'op/disable-tabs))
285 (with-eval-after-load 'css-mode
286 (add-hook 'css-mode-hook #'op/disable-tabs))
288 (with-eval-after-load 'cc-mode
289 (setq c-basic-offset 8
290 c-default-style "K&R"
291 c-file-offsets '((arglist-intro . +)
292 (arglist-cont-nonempty . *)))
293 (dolist (hook '(c-mode-hook c++-mode-hook))
294 (add-hook hook #'abbrev-mode)
295 (add-hook hook #'subword-mode))
298 (defun op/c-add-include (path &optional localp)
299 "Include PATH at the start of the file.
300 If LOCALP is non-nil, the include will be \"local\"."
301 (interactive "Mheader to include: \nP")
304 "^#[ \t]*include[ \t]*\""
305 "^#[ \t]*include[ \t]*<"))
306 (ignore-re "^#include \"compat.h\"")
308 (goto-char (point-min))
309 (while (not (or (and (looking-at re)
310 (not (looking-at ignore-re)))
314 (error "Don't know where to insert the header"))
316 (insert "#include " (if localp "\"\"" "<>"))
319 (move-beginning-of-line 1)
322 (while (and (looking-at re)
325 (sort-lines nil start (point)))))
326 (define-key c-mode-map (kbd "C-c C-a") #'op/c-add-include))
328 (with-eval-after-load 'perl-mode
329 (setq perl-indent-level 8))
331 (with-eval-after-load 'sh-script
332 (setq sh-basic-offset 8
333 sh-indent-after-loop-construct 8
334 sh-indent-after-continuation nil))
338 (defun op/eshell-bufname (dir)
339 (concat "*eshell " (expand-file-name dir) "*"))
341 (defun op/eshell (arg)
342 "Run or jump to eshell in current project.
343 If called with prefix argument ARG always create a new eshell
346 (let* ((proj (project-current))
347 (dir (if (and proj (not arg))
350 (default-directory dir)
351 (eshell-buffer-name (let ((name (op/eshell-bufname dir)))
353 (generate-new-buffer name)
356 (define-key global-map (kbd "C-c e") #'op/eshell)
358 (with-eval-after-load 'eshell
359 (setq eshell-save-history-on-exit t
360 eshell-history-size 1024
362 eshell-compl-dir-ignore
363 "\\`\\(\\.\\.?\\|CVS\\|\\.svn\\|\\.git\\|\\.got\\)/\\'")
365 (defun op/eshell-after-cd (&rest _)
366 (rename-buffer (op/eshell-bufname default-directory) t))
368 (advice-add #'eshell/cd :after #'op/eshell-after-cd)
370 (defun op/clear-eshell ()
372 (let ((inhibit-read-only t))
374 (eshell-send-input)))
376 (defun op/eshell-hook ()
377 "Because eshell is stupid."
378 (define-key eshell-mode-map (kbd "C-x M-o") #'op/clear-eshell))
379 (add-hook 'eshell-mode-hook #'op/eshell-hook))
383 (unless (package-installed-p 'sndio)
384 (package-install-file "~/w/sndio.el/sndio.el"))
388 (unless (package-installed-p 'saturn)
389 (package-install-file "~/w/saturn/GUI/saturn.el"))
393 (unless (package-installed-p 'simple-pass)
394 (package-install-file "~/.emacs.d/simple-pass.el"))
395 (define-key global-map (kbd "C-z p") #'simple-pass-copy)
401 (define-key global-map (kbd "C-x w") #'elfeed)
402 (with-eval-after-load 'elfeed
403 (define-key elfeed-show-mode-map (kbd "q") #'delete-window)
404 (define-key elfeed-show-mode-map (kbd "S-SPC") #'scroll-down-command)
405 (define-key elfeed-show-mode-map (kbd "M-SPC") #'scroll-down-command)
406 (setq elfeed-show-entry-switch #'pop-to-buffer
408 '("https://undeadly.org/cgi?action=rss&full=yes&items=10"
409 "http://www.tedunangst.com/flak/rss"
410 "https://www.dragonflydigest.com/feed"
411 "https://www.mirbsd.org/news.rss"
412 "https://www.mirbsd.org/announce.rss"
413 "https://bentsukun.ch/index.xml"
414 "https://drewdevault.com/feed.xml"
415 "https://www.cambus.net/atom.xml"
416 "https://dataswamp.org/~solene/rss.xml"
417 "https://briancallahan.net/blog/feed.xml"
418 "https://www.poolp.org/index.xml"
419 "https://jcs.org/rss"
420 "https://sanctum.geek.nz/arabesque/feed/"
421 "https://tech.toryanderson.com/"
422 "https://alexschroeder.ch/wiki?action=journal;search=-tag:rpg -tag:rsp;lang=en;title=English Diary without RPG Pages"
423 "http://boston.conman.org/bostondiaries.rss"
424 "https://emacsninja.com/feed.atom"
425 "https://bsdly.blogspot.com/feeds/posts/default"
426 "https://crawshaw.io/atom.xml"
427 "https://nullprogram.com/feed/"
428 "http://pragmaticemacs.com/feed/"
429 "https://emacsnotes.wordpress.com/feed/"
430 "https://metaredux.com/feed.xml"
431 "https://emacsredux.com/atom.xml"
432 "https://endlessparentheses.com/atom.xml"
433 "https://www.masteringemacs.org/feed"
434 "https://cestlaz.github.io/rss.xml"
435 "https://utcc.utoronto.ca/~cks/space/blog/?atom"
436 "https://irreal.org/blog/?feed=rss2"
437 "https://jao.io/blog/rss.xml"
438 "https://planet.lisp.org/rss20.xml"
439 "https://insideclojure.org/feed.xml"
440 "https://tech.toryanderson.com/index.xml"
441 "https://vermaden.wordpress.com/feed/"
442 "https://www.arp242.net/feed.xml"
443 "https://tymoon.eu/api/reader/atom"
444 "https://venam.nixers.net/blog/feed.xml"
445 "https://www.omarpolo.com/rss.xml"
446 "https://owarisubs.lacumpa.biz/feed/"
447 "https://asenshi.moe/feed/"
448 "https://godotengine.org/rss.xml"
450 "https://adventofcomputing.libsyn.com/rss"
452 "https://github.com/go-gitea/gitea/releases.atom"
454 "https://nitter.pussthecat.org/NanoRaptor/rss"
456 "https://github.com/yshui/picom/releases.atom"
457 "https://github.com/vslavik/poedit/releases.atom"
458 "https://github.com/TokTok/c-toxcore/releases.atom"
459 "https://github.com/alexander-akhmetov/python-telegram/releases.atom"
460 "https://github.com/paul-nameless/tg/releases.atom"
461 "https://github.com/YACReader/yacreader/releases.atom"
462 "https://github.com/luarocks/luarocks/releases.atom"
463 "https://github.com/okbob/pspg/releases.atom"
464 "https://github.com/taisei-project/taisei/releases.atom"
465 "https://github.com/recp/cglm/releases.atom"
467 "https://causal.agency/list/pounce.atom"
469 "https://www.crimsonmagic.me/feed/"
470 "https://fullybookedtls.wordpress.com/feed/")))
472 (setq shackle-default-rule nil
474 (let ((repls "\\*\\(cider-repl\\|sly-mrepl\\|ielm\\)")
475 (godot "\\*godot - .*\\*")
476 (vcs "\\*\\(Flymake\\|Package-Lint\\|vc-\\(git\\|got\\) :\\).*")
477 (elfeed "\\*elfeed-entry\\*")
478 (vmd "\\*vmd console .*"))
479 `((compilation-mode :noselect t
482 ("*Async Shell Command*" :ignore t)
489 (occur-mode :select t
492 (diff-mode :select t)
510 (define-key global-map (kbd "M-g e") #'embark-act)