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 (with-eval-after-load 'log-edit
61 (add-hook 'log-edit-mode #'auto-fill-mode))
63 ;; free the c-z binding
64 (define-key global-map (kbd "C-z") nil)
65 (define-key global-map (kbd "C-z V") #'variable-pitch-mode)
66 (define-key global-map (kbd "C-z n") #'display-line-numbers-mode)
68 (define-key global-map (kbd "M-SPC") #'cycle-spacing)
69 (define-key global-map (kbd "M-u") #'upcase-dwim)
70 (define-key global-map (kbd "M-l") #'downcase-dwim)
71 (define-key global-map (kbd "M-c") #'capitalize-dwim)
73 (let ((font "-misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso10646-1"))
74 (set-frame-font font nil t)
75 (add-to-list 'default-frame-alist `(font . ,font)))
77 ;; some cool stuff
78 (save-place-mode +1)
79 (savehist-mode +1)
80 (setq history-delete-duplicates t
81 history-length 1000
82 savehist-save-minibuffer-history t)
83 (electric-pair-mode +1)
85 (define-key global-map (kbd "M-/") #'hippie-expand)
86 (setq hippie-expand-try-functions-list
87 '(try-expand-dabbrev
88 try-expand-dabbrev-all-buffers
89 try-expand-dabbrev-from-kill
90 try-complete-file-name-partially
91 try-complete-file-name
92 try-expand-all-abbrevs
93 try-expand-list
94 try-expand-line
95 try-complete-lisp-symbol-partially
96 try-complete-lisp-symbol))
98 (setq isearch-lazy-count t
99 search-whitespace-regexp ".*?"
100 isearch-allow-scroll 'unlimited)
102 (defun op/buffer-to-side-window (place)
103 "Place the current buffer in the side window at PLACE."
104 (interactive (list (intern
105 (completing-read "Which side: "
106 '(top left right bottom)))))
107 (let ((buf (current-buffer)))
108 (display-buffer-in-side-window
109 buf `((window-height . 0.15)
110 (side . ,place)
111 (slot . -1)
112 (window-parameters . ((no-delete-other-windows . t)))))
113 (delete-window)))
115 (defun op/fill-or-unfill (fn &optional justify region)
116 "Meant to be an adviced :around `fill-paragraph'.
117 FN is the original `fill-column'. If `last-command' is
118 `fill-paragraph', unfill it, fill it otherwise. Inspired from a
119 post on endless parentheses. Optional argument JUSTIFY and
120 REGION are passed to `fill-paragraph'."
121 (let ((fill-column
122 (if (eq last-command 'fill-paragraph)
123 (progn (setq this-command nil)
124 (point-max))
125 fill-column)))
126 (funcall fn justify region)))
127 (advice-add 'fill-paragraph :around #'op/fill-or-unfill)
129 (defmacro op/deftranspose (name scope key doc)
130 "Macro to produce transposition functions.
131 NAME is the function's symbol. SCOPE is the text object to
132 operate on. Optional DOC is the function's docstring.
134 Transposition over an active region will swap the object at
135 mark (region beginning) with the one at point (region end).
137 It can optionally define a key for the defined function in the
138 `global-map' if KEY is passed.
140 Originally from protesilaos' dotemacs."
141 (declare (indent defun))
142 `(progn
143 (defun ,name (arg)
144 ,doc
145 (interactive "p")
146 (let ((x (intern (format "transpose-%s" ,scope))))
147 (if (use-region-p)
148 (funcall x 0)
149 (funcall x arg))))
150 ,(when key
151 `(define-key global-map (kbd ,key) #',name))))
153 (op/deftranspose op/transpose-lines "lines" "C-x C-t"
154 "Transpose lines or swap over active region.")
156 (op/deftranspose op/transpose-paragraphs "paragraphs" "C-S-t"
157 "Transpose paragraph or swap over active region.")
159 (op/deftranspose op/transpose-sentences "sentences" "C-x M-t"
160 "Transpose sentences or swap over active region.")
162 (op/deftranspose op/transpose-sexps "sexps" "C-M-t"
163 "Transpose sexps or swap over active region.")
165 (op/deftranspose op/transpose-words "words" "M-t"
166 "Transpose words or swap over active region.")
168 (defun op/narrow-or-widen-dwim (p)
169 "Widen if the buffer is narrowed, narrow-dwim otherwise.
170 Dwim means: region, org-src-block, org-subtree or defun,
171 whichever applies first. Narrowing to org-src-blocks actually
172 calls `org-edit-src-code'.
174 With prefix P, don't widen, just narrow even if buffer is already
175 narrowed. With P being -, narrow to page instead of to defun.
177 Taken from endless parentheses."
178 (interactive "P")
179 (declare (interactive-only))
180 (cond ((and (buffer-narrowed-p) (not p)) (widen))
181 ((region-active-p)
182 (narrow-to-region (region-beginning)
183 (region-end)))
184 ((derived-mode-p 'org-mode)
185 ;; `org-edit-src-code' isn't a real narrowing
186 (cond ((ignore-errors (org-edit-src-code) t))
187 ((ignore-errors (org-narrow-to-block) t))
188 (t (org-narrow-to-subtree))))
189 ((eql p '-) (narrow-to-page))
190 (t (narrow-to-defun))))
192 (define-key global-map (kbd "C-c w") #'op/narrow-or-widen-dwim)
194 (with-eval-after-load 'dired
195 (add-hook 'dired-mode-hook #'dired-hide-details-mode)
196 (add-hook 'dired-mode-hook #'dired-omit-mode)
198 (define-key dired-mode-map (kbd "C-c w") #'wdired-change-to-wdired-mode)
200 (require 'dired-x)
201 (setq dired-listing-switches "-lahF"
202 dired-dwim-target t
203 dired-deletion-confirmer #'y-or-n-p))
205 ;; just like telescope!
206 (with-eval-after-load 'diff-mode
207 (define-key diff-mode-map (kbd "M-SPC") #'scroll-down-command))
209 (with-eval-after-load 'elisp-mode
210 (add-hook 'emacs-lisp-mode-hook #'checkdoc-minor-mode)
211 (add-hook 'emacs-lisp-mode-hook #'prettify-symbols-mode)
212 (let ((map emacs-lisp-mode-map))
213 (define-key map (kbd "C-c C-k") #'eval-buffer)
214 (define-key map (kbd "C-c k") #'op/ert-all)
215 (define-key map (kbd "C-c C-z") #'op/ielm-repl)))
217 (with-eval-after-load 'help
218 (add-hook 'help-mode-hook #'visual-line-mode))
220 ;; add melpa
221 (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
223 ;; packages that i want to be installed
224 (dolist (pkg '(vc-got pdf-tools eglot nameless sly cider go-mode web-mode
225 lua-mode markdown-mode elfeed form-feed shackle
226 embark mct marginalia))
227 (unless (package-installed-p pkg)
228 (message "Installing %s" pkg)
229 (package-install pkg)))
231 (global-form-feed-mode +1)
233 (setq completion-styles '(basic substring initials flex partial-completion))
235 (marginalia-mode +1)
236 (mct-minibuffer-mode +1)
237 (mct-region-mode +1)
238 (setq mct-remove-shadowed-file-names t
239 mct-completions-format 'one-column
240 mct-completion-passlist '(Info-goto-node
241 Info-index
242 Info-menu
243 vc-retrieve-tag
244 imenu
245 file
246 buffer
247 kill-ring))
249 (with-eval-after-load 'eglot
250 (define-key eglot-mode-map (kbd "<f1>") #'eglot-code-actions)
251 (define-key eglot-mode-map (kbd "<f2>") #'eglot-format)
252 (add-to-list 'eglot-ignored-server-capabilites
253 :documentHighlightProvider)
254 (add-to-list 'eglot-server-programs
255 '(c-mode . ("clangd" "--header-insertion=never"))))
257 (with-eval-after-load 'nameless
258 (add-hook 'emacs-lisp-mode #'nameless-mode)
259 (setq nameless-private-prefix t
260 nameless-affect-indentation-and-filling nil)
261 (define-key emacs-lisp-mode-map (kbd "_") #'nameless-insert-name-or-self-insert))
263 (with-eval-after-load 'web-mode
264 (setq web-mode-markup-indent-offset 2
265 web-mode-css-indent-offset 2
266 web-mode-style-padding 0
267 web-mode-enable-engine-detection t)
268 (add-hook 'web-mode-hook #'op/disable-tabs))
270 (with-eval-after-load 'css-mode
271 (add-hook 'css-mode-hook #'op/disable-tabs))
273 (with-eval-after-load 'cc-mode
274 (setq c-basic-offset 8
275 c-default-style "K&R"
276 c-file-offsets '((arglist-intro . +)
277 (arglist-cont-nonempty . *)))
278 (dolist (hook '(c-mode-hook c++-mode-hook))
279 (add-hook hook #'abbrev-mode)
280 (add-hook hook #'subword-mode))
282 ;; TODO: improve it!
283 (defun op/c-add-include (path &optional localp)
284 "Include PATH at the start of the file.
285 If LOCALP is non-nil, the include will be \"local\"."
286 (interactive "Mheader to include: \nP")
287 (save-excursion
288 (let ((re (if localp
289 "^#[ \t]*include[ \t]*\""
290 "^#[ \t]*include[ \t]*<"))
291 (ignore-re "^#include \"compat.h\"")
292 start)
293 (goto-char (point-min))
294 (while (not (or (and (looking-at re)
295 (not (looking-at ignore-re)))
296 (eobp)))
297 (forward-line))
298 (when (eobp)
299 (error "Don't know where to insert the header"))
300 (open-line 1)
301 (insert "#include " (if localp "\"\"" "<>"))
302 (backward-char)
303 (insert path)
304 (move-beginning-of-line 1)
305 (setq start (point))
306 (forward-line)
307 (while (and (looking-at re)
308 (not (eobp)))
309 (forward-line))
310 (sort-lines nil start (point)))))
311 (define-key c-mode-map (kbd "C-c C-a") #'op/c-add-include))
313 (with-eval-after-load 'perl-mode
314 (setq perl-indent-level 8))
316 (with-eval-after-load 'sh-script
317 (setq sh-basic-offset 8
318 sh-indent-after-loop-construct 8
319 sh-indent-after-continuation nil))
323 (defun op/eshell-bufname (dir)
324 (concat "*eshell " (expand-file-name dir) "*"))
326 (defun op/eshell (arg)
327 "Run or jump to eshell in current project.
328 If called with prefix argument ARG always create a new eshell
329 buffer."
330 (interactive "P")
331 (let* ((proj (project-current))
332 (dir (if (and proj (not arg))
333 (project-root proj)
334 default-directory))
335 (default-directory dir)
336 (eshell-buffer-name (let ((name (op/eshell-bufname dir)))
337 (if arg
338 (generate-new-buffer name)
339 name))))
340 (eshell)))
341 (define-key global-map (kbd "C-c e") #'op/eshell)
343 (with-eval-after-load 'eshell
344 (setq eshell-save-history-on-exit t
345 eshell-history-size 1024
347 eshell-compl-dir-ignore
348 "\\`\\(\\.\\.?\\|CVS\\|\\.svn\\|\\.git\\|\\.got\\)/\\'")
350 (defun op/eshell-after-cd (&rest _)
351 (rename-buffer (op/eshell-bufname default-directory) t))
353 (advice-add #'eshell/cd :after #'op/eshell-after-cd)
355 (defun op/clear-eshell ()
356 (interactive "")
357 (let ((inhibit-read-only t))
358 (erase-buffer)
359 (eshell-send-input)))
361 (defun op/eshell-hook ()
362 "Because eshell is stupid."
363 (define-key eshell-mode-map (kbd "C-x M-o") #'op/clear-eshell))
364 (add-hook 'eshell-mode-hook #'op/eshell-hook))
367 ;; sndio.el
368 (unless (package-installed-p 'sndio)
369 (package-install-file "~/w/sndio.el/sndio.el"))
372 ;; saturn
373 (unless (package-installed-p 'saturn)
374 (package-install-file "~/w/saturn/GUI/saturn.el"))
377 ;; simple-pass
378 (unless (package-installed-p 'simple-pass)
379 (package-install-file "~/.emacs.d/simple-pass.el"))
380 (define-key global-map (kbd "C-z p") #'simple-pass-copy)
384 ;; elfeed
386 (define-key global-map (kbd "C-x w") #'elfeed)
387 (with-eval-after-load 'elfeed
388 (define-key elfeed-show-mode-map (kbd "q") #'delete-window)
389 (define-key elfeed-show-mode-map (kbd "S-SPC") #'scroll-down-command)
390 (define-key elfeed-show-mode-map (kbd "M-SPC") #'scroll-down-command)
391 (setq elfeed-show-entry-switch #'pop-to-buffer
392 elfeed-feeds
393 '("https://undeadly.org/cgi?action=rss&full=yes&items=10"
394 "http://www.tedunangst.com/flak/rss"
395 "https://www.dragonflydigest.com/feed"
396 "https://www.mirbsd.org/news.rss"
397 "https://www.mirbsd.org/announce.rss"
398 "https://bentsukun.ch/index.xml"
399 "https://drewdevault.com/feed.xml"
400 "https://www.cambus.net/atom.xml"
401 "https://dataswamp.org/~solene/rss.xml"
402 "https://briancallahan.net/blog/feed.xml"
403 "https://www.poolp.org/index.xml"
404 "https://jcs.org/rss"
405 "https://sanctum.geek.nz/arabesque/feed/"
406 "https://tech.toryanderson.com/"
407 "https://alexschroeder.ch/wiki?action=journal;search=-tag:rpg -tag:rsp;lang=en;title=English Diary without RPG Pages"
408 "http://boston.conman.org/bostondiaries.rss"
409 "https://emacsninja.com/feed.atom"
410 "https://bsdly.blogspot.com/feeds/posts/default"
411 "https://crawshaw.io/atom.xml"
412 "https://nullprogram.com/feed/"
413 "http://pragmaticemacs.com/feed/"
414 "https://emacsnotes.wordpress.com/feed/"
415 "https://metaredux.com/feed.xml"
416 "https://emacsredux.com/atom.xml"
417 "https://endlessparentheses.com/atom.xml"
418 "https://www.masteringemacs.org/feed"
419 "https://cestlaz.github.io/rss.xml"
420 "https://utcc.utoronto.ca/~cks/space/blog/?atom"
421 "https://irreal.org/blog/?feed=rss2"
422 "https://jao.io/blog/rss.xml"
423 "https://planet.lisp.org/rss20.xml"
424 "https://insideclojure.org/feed.xml"
425 "https://tech.toryanderson.com/index.xml"
426 "https://vermaden.wordpress.com/feed/"
427 "https://www.arp242.net/feed.xml"
428 "https://tymoon.eu/api/reader/atom"
429 "https://venam.nixers.net/blog/feed.xml"
430 "https://www.omarpolo.com/rss.xml"
431 "https://owarisubs.lacumpa.biz/feed/"
432 "https://asenshi.moe/feed/"
433 "https://godotengine.org/rss.xml"
435 "https://adventofcomputing.libsyn.com/rss"
437 "https://github.com/go-gitea/gitea/releases.atom"
439 "https://nitter.pussthecat.org/NanoRaptor/rss"
441 "https://github.com/yshui/picom/releases.atom"
442 "https://github.com/vslavik/poedit/releases.atom"
443 "https://github.com/TokTok/c-toxcore/releases.atom"
444 "https://github.com/alexander-akhmetov/python-telegram/releases.atom"
445 "https://github.com/paul-nameless/tg/releases.atom"
446 "https://github.com/YACReader/yacreader/releases.atom"
447 "https://github.com/luarocks/luarocks/releases.atom"
448 "https://github.com/okbob/pspg/releases.atom"
449 "https://github.com/taisei-project/taisei/releases.atom"
450 "https://github.com/recp/cglm/releases.atom"
452 "https://causal.agency/list/pounce.atom"
454 "https://www.crimsonmagic.me/feed/"
455 "https://fullybookedtls.wordpress.com/feed/")))
457 (setq shackle-default-rule nil
458 shackle-rules
459 (let ((repls "\\*\\(cider-repl\\|sly-mrepl\\|ielm\\)")
460 (godot "\\*godot - .*\\*")
461 (vcs "\\*\\(Flymake\\|Package-Lint\\|vc-\\(git\\|got\\) :\\).*")
462 (elfeed "\\*elfeed-entry\\*")
463 (vmd "\\*vmd console .*"))
464 `((compilation-mode :noselect t
465 :align above
466 :size 0.2)
467 ("*Async Shell Command*" :ignore t)
468 (,repls :regexp t
469 :align below
470 :size 0.3)
471 (,godot :regexp t
472 :align t
473 :size 0.3)
474 (occur-mode :select t
475 :align right
476 :size 0.3)
477 (diff-mode :select t)
478 (help-mode :select t
479 :align left
480 :size 0.3)
481 (,vcs :regexp t
482 :align above
483 :size 0.15
484 :select t)
485 (,elfeed :regexp t
486 :align t
487 :select t
488 :size 0.75)
489 (,vmd :regexp t
490 :align below
491 :select t
492 :size 0.3))))
493 (shackle-mode +1)
495 (define-key global-map (kbd "M-g e") #'embark-act)