Blob


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
8 x-stretch-cursor t
9 require-final-newline t
10 visible-bell nil
11 load-prefer-newer t
12 tab-bar-show 1
13 enable-recursive-minibuffers t
14 imenu-auto-rescan 1)
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)
23 ;; mg-like
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)
36 (require 'whitespace)
37 (setq whitespace-style '(face trailing)
38 backward-delete-char-untabify-method 'hungry
39 tab-always-indent 'complete
40 tab-width 8
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."
46 (interactive)
47 (setq-local indent-tabs-mode t))
49 (defun op/disable-tabs ()
50 "Disable `indent-tabs-mode' in the current buffer."
51 (interactive)
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
61 clojure-mode-hook
62 clojurescript-mode-hook
63 clojurec-mode-hook
64 scss-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)))
84 ;; some cool stuff
85 (save-place-mode +1)
86 (savehist-mode +1)
87 (setq history-delete-duplicates t
88 history-length 1000
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
94 '(try-expand-dabbrev
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
100 try-expand-list
101 try-expand-line
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)
117 (side . ,place)
118 (slot . -1)
119 (window-parameters . ((no-delete-other-windows . t)))))
120 (delete-window)))
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'."
128 (let ((fill-column
129 (if (eq last-command 'fill-paragraph)
130 (progn (setq this-command nil)
131 (point-max))
132 fill-column)))
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))
149 `(progn
150 (defun ,name (arg)
151 ,doc
152 (interactive "p")
153 (let ((x (intern (format "transpose-%s" ,scope))))
154 (if (use-region-p)
155 (funcall x 0)
156 (funcall x arg))))
157 ,(when key
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."
185 (interactive "P")
186 (declare (interactive-only))
187 (cond ((and (buffer-narrowed-p) (not p)) (widen))
188 ((region-active-p)
189 (narrow-to-region (region-beginning)
190 (region-end)))
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)
207 (require 'dired-x)
208 (setq dired-listing-switches "-lahF"
209 dired-dwim-target t
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))
227 ;; add melpa
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))
247 (marginalia-mode +1)
248 (mct-minibuffer-mode +1)
249 (mct-region-mode +1)
250 (setq mct-remove-shadowed-file-names t
251 mct-completions-format 'one-column
252 mct-completion-passlist '(Info-goto-node
253 Info-index
254 Info-menu
255 vc-retrieve-tag
256 imenu
257 file
258 buffer
259 kill-ring))
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))
297 ;; TODO: improve it!
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")
302 (save-excursion
303 (let ((re (if localp
304 "^#[ \t]*include[ \t]*\""
305 "^#[ \t]*include[ \t]*<"))
306 (ignore-re "^#include \"compat.h\"")
307 start)
308 (goto-char (point-min))
309 (while (not (or (and (looking-at re)
310 (not (looking-at ignore-re)))
311 (eobp)))
312 (forward-line))
313 (when (eobp)
314 (error "Don't know where to insert the header"))
315 (open-line 1)
316 (insert "#include " (if localp "\"\"" "<>"))
317 (backward-char)
318 (insert path)
319 (move-beginning-of-line 1)
320 (setq start (point))
321 (forward-line)
322 (while (and (looking-at re)
323 (not (eobp)))
324 (forward-line))
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
344 buffer."
345 (interactive "P")
346 (let* ((proj (project-current))
347 (dir (if (and proj (not arg))
348 (project-root proj)
349 default-directory))
350 (default-directory dir)
351 (eshell-buffer-name (let ((name (op/eshell-bufname dir)))
352 (if arg
353 (generate-new-buffer name)
354 name))))
355 (eshell)))
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 ()
371 (interactive "")
372 (let ((inhibit-read-only t))
373 (erase-buffer)
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))
382 ;; sndio.el
383 (unless (package-installed-p 'sndio)
384 (package-install-file "~/w/sndio.el/sndio.el"))
387 ;; saturn
388 (unless (package-installed-p 'saturn)
389 (package-install-file "~/w/saturn/GUI/saturn.el"))
392 ;; simple-pass
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)
399 ;; elfeed
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
407 elfeed-feeds
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
473 shackle-rules
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
480 :align above
481 :size 0.2)
482 ("*Async Shell Command*" :ignore t)
483 (,repls :regexp t
484 :align below
485 :size 0.3)
486 (,godot :regexp t
487 :align t
488 :size 0.3)
489 (occur-mode :select t
490 :align right
491 :size 0.3)
492 (diff-mode :select t)
493 (help-mode :select t
494 :align left
495 :size 0.3)
496 (,vcs :regexp t
497 :align above
498 :size 0.15
499 :select t)
500 (,elfeed :regexp t
501 :align t
502 :select t
503 :size 0.75)
504 (,vmd :regexp t
505 :align below
506 :select t
507 :size 0.3))))
508 (shackle-mode +1)
510 (define-key global-map (kbd "M-g e") #'embark-act)