You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1987 lines
60 KiB

5 years ago
1 year ago
3 years ago
3 years ago
7 months ago
7 months ago
7 months ago
6 years ago
7 months ago
7 months ago
6 years ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
1 year ago
7 months ago
7 months ago
7 months ago
6 years ago
6 years ago
6 years ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
1 year ago
7 months ago
7 months ago
1 year ago
7 months ago
7 months ago
7 months ago
7 months ago
1 year ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
6 years ago
7 months ago
7 months ago
7 months ago
7 months ago
6 years ago
7 months ago
7 months ago
6 years ago
6 years ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
1 year ago
7 months ago
1 year ago
  1. #+TITLE: Emacs configuration file
  2. #+AUTHOR: Marc
  3. #+BABEL: :cache yes
  4. #+PROPERTY: header-args :tangle init.el
  5. #+OPTIONS: ^:nil
  6. * TODOS
  7. - early-init.el? What to outsource here?
  8. - Paket exec-path-from-shell, um PATH aus Linux auch in emacs zu haben
  9. - Smart mode line?
  10. - Theme
  11. - flymake instead of flycheck?
  12. - Hydra
  13. - General
  14. - (defalias 'list-buffers 'ibuffer) ;; change default to ibuffer
  15. - ido?
  16. - treemacs (for linux)
  17. windmove?
  18. - tramp (in linux)
  19. - visual-regexp
  20. - org configuration: paths
  21. - org custom agenda
  22. - org-ql (related to org agendas)
  23. - org configuration: everything else
  24. - beancount configuration from config.org
  25. - CONTINUE TODO from config.org at Programming
  26. - all-the-icons?
  27. - lispy? [[https://github.com/abo-abo/lispy]]
  28. * Header
  29. Emacs variables are dynamically scoped. That's unusual for most languages, so disable it here, too
  30. #+begin_src emacs-lisp
  31. ;;; init.el --- -*- lexical-binding: t -*-
  32. #+end_src
  33. * First start
  34. These functions updates config.el whenever changes in config.org are made. The update will be active after saving.
  35. #+BEGIN_SRC emacs-lisp
  36. (defun my/tangle-config ()
  37. "Export code blocks from the literate config file."
  38. (interactive)
  39. ;; prevent emacs from killing until tangle-process has finished
  40. (add-to-list 'kill-emacs-query-functions
  41. (lambda ()
  42. (or (not (process-live-p (get-process "tangle-process")))
  43. (y-or-n-p "\"my/tangle-config\" is running; kill it? "))))
  44. (org-babel-tangle-file config-org init-el)
  45. (message "reloading user-init-file")
  46. (load-file init-el))
  47. (add-hook 'org-mode-hook
  48. (lambda ()
  49. (if (equal (buffer-file-name) config-org)
  50. (my--add-local-hook 'after-save-hook 'my/tangle-config))))
  51. (defun my--add-local-hook (hook function)
  52. "Add buffer-local hook."
  53. (add-hook hook function :local t))
  54. #+END_SRC
  55. A small function to measure start up time.
  56. Compare that to
  57. emacs -q --eval='(message "%s" (emacs-init-time))'
  58. (roughly 0.27s)
  59. https://blog.d46.us/advanced-emacs-startup/
  60. #+begin_src emacs-lisp
  61. (add-hook 'emacs-startup-hook
  62. (lambda ()
  63. (message "Emacs ready in %s with %d garbage collections."
  64. (format "%.2f seconds"
  65. (float-time
  66. (time-subtract after-init-time before-init-time)))
  67. gcs-done)))
  68. ;(setq gc-cons-threshold (* 50 1000 1000))
  69. #+end_src
  70. * Package Management
  71. ** Elpaca
  72. Boilerplate for Elpaca
  73. #+begin_src emacs-lisp
  74. (defvar elpaca-installer-version 0.6)
  75. (defvar elpaca-directory (expand-file-name "elpaca/" user-emacs-directory))
  76. (defvar elpaca-builds-directory (expand-file-name "builds/" elpaca-directory))
  77. (defvar elpaca-repos-directory (expand-file-name "repos/" elpaca-directory))
  78. (defvar elpaca-order '(elpaca :repo "https://github.com/progfolio/elpaca.git"
  79. :ref nil
  80. :files (:defaults "elpaca-test.el" (:exclude "extensions"))
  81. :build (:not elpaca--activate-package)))
  82. (let* ((repo (expand-file-name "elpaca/" elpaca-repos-directory))
  83. (build (expand-file-name "elpaca/" elpaca-builds-directory))
  84. (order (cdr elpaca-order))
  85. (default-directory repo))
  86. (add-to-list 'load-path (if (file-exists-p build) build repo))
  87. (unless (file-exists-p repo)
  88. (make-directory repo t)
  89. (when (< emacs-major-version 28) (require 'subr-x))
  90. (condition-case-unless-debug err
  91. (if-let ((buffer (pop-to-buffer-same-window "*elpaca-bootstrap*"))
  92. ((zerop (call-process "git" nil buffer t "clone"
  93. (plist-get order :repo) repo)))
  94. ((zerop (call-process "git" nil buffer t "checkout"
  95. (or (plist-get order :ref) "--"))))
  96. (emacs (concat invocation-directory invocation-name))
  97. ((zerop (call-process emacs nil buffer nil "-Q" "-L" "." "--batch"
  98. "--eval" "(byte-recompile-directory \".\" 0 'force)")))
  99. ((require 'elpaca))
  100. ((elpaca-generate-autoloads "elpaca" repo)))
  101. (progn (message "%s" (buffer-string)) (kill-buffer buffer))
  102. (error "%s" (with-current-buffer buffer (buffer-string))))
  103. ((error) (warn "%s" err) (delete-directory repo 'recursive))))
  104. (unless (require 'elpaca-autoloads nil t)
  105. (require 'elpaca)
  106. (elpaca-generate-autoloads "elpaca" repo)
  107. (load "./elpaca-autoloads")))
  108. (add-hook 'after-init-hook #'elpaca-process-queues)
  109. (elpaca `(,@elpaca-order))
  110. #+end_src
  111. For Windows it might be necessary to disable symlink creations
  112. #+begin_src emacs-lisp
  113. ;;(elpaca-no-symlink-mode)
  114. #+end_src
  115. use-package integration
  116. #+begin_src emacs-lisp
  117. (elpaca elpaca-use-package
  118. ;; enable :elpaca use-package keyword
  119. (elpaca-use-package-mode)
  120. ;; assume :elpaca t unless otherwise specified
  121. (setq elpaca-use-package-by-default t))
  122. ;; block until current queue processed.
  123. (elpaca-wait)
  124. #+end_src
  125. #+begin_src emacs-lisp
  126. (defun +elpaca-unload-seq (e)
  127. (and (featurep 'seq) (unload-feature 'seq t))
  128. (elpaca--continue-build e))
  129. ;; You could embed this code directly in the reicpe, I just abstracted it into a function.
  130. (defun +elpaca-seq-build-steps ()
  131. (append (butlast (if (file-exists-p (expand-file-name "seq" elpaca-builds-directory))
  132. elpaca--pre-built-steps elpaca-build-steps))
  133. (list '+elpaca-unload-seq 'elpaca--activate-package)))
  134. ;;(elpaca `(seq :build ,(+elpaca-seq-build-steps)))
  135. (use-package seq :elpaca `(seq :build ,(+elpaca-seq-build-steps)))
  136. #+end_src
  137. ** COMMENT Rest of the stuff
  138. #+BEGIN_SRC emacs-lisp
  139. (require 'package)
  140. (add-to-list 'package-archives '("elpa" . "https://elpa.gnu.org/packages/") t)
  141. (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
  142. (add-to-list 'package-archives '("melpa-stable" . "https://stable.melpa.org/packages/") t)
  143. (add-to-list 'package-archives '("nongnu" . "https://elpa.nongnu.org/nongnu/") t)
  144. ; fix for bug 34341
  145. (setq gnutls-algorithm-priority "NORMAL:-VERS-TLS1.3")
  146. (when (< emacs-major-version 27)
  147. (package-initialize))
  148. #+END_SRC
  149. #+BEGIN_SRC emacs-lisp
  150. (unless (package-installed-p 'use-package)
  151. (package-refresh-contents)
  152. (package-install 'use-package))
  153. (eval-when-compile
  154. (setq use-package-enable-imenu-support t)
  155. (require 'use-package))
  156. (require 'bind-key)
  157. (setq use-package-verbose t)
  158. (use-package diminish
  159. :ensure t)
  160. #+END_SRC
  161. cl is deprecated in favor for cl-lib, some packages like emmet still depend on cl.
  162. Shut off the compiler warning about it.
  163. Maybe turn it on again at some point before the next major emacs upgrade
  164. #+begin_src emacs-lisp
  165. (setq byte-compile-warnings '(cl-functions))
  166. #+end_src
  167. * use-package keywords general / diminish
  168. Needs to be loaded before any other package which uses the :general keyword
  169. #+BEGIN_SRC emacs-lisp
  170. (use-package general
  171. :ensure t
  172. :demand t)
  173. (use-package diminish
  174. :ensure t
  175. :demand t)
  176. (elpaca-wait)
  177. #+END_SRC
  178. * Performance Optimization
  179. ** Garbage Collection
  180. Make startup faster by reducing the frequency of garbage collection.
  181. Set gc-cons-threshold (default is 800kb) to maximum value available, to prevent any garbage collection from happening during load time.
  182. #+BEGIN_SRC emacs-lisp :tangle early-init.el
  183. (setq gc-cons-threshold most-positive-fixnum)
  184. #+END_SRC
  185. Restore it to reasonable value after init. Also stop garbage collection during minibuffer interaction (helm etc.)
  186. #+begin_src emacs-lisp
  187. (defconst 1mb 1048576)
  188. (defconst 20mb 20971520)
  189. (defconst 30mb 31457280)
  190. (defconst 50mb 52428800)
  191. (defun my--defer-garbage-collection ()
  192. (setq gc-cons-threshold most-positive-fixnum))
  193. (defun my--restore-garbage-collection ()
  194. (run-at-time 1 nil (lambda () (setq gc-cons-threshold 30mb))))
  195. (add-hook 'emacs-startup-hook 'my--restore-garbage-collection 100)
  196. (add-hook 'minibuffer-setup-hook 'my--defer-garbage-collection)
  197. (add-hook 'minibuffer-exit-hook 'my--restore-garbage-collection)
  198. (setq read-process-output-max 1mb) ;; lsp-mode's performance suggest
  199. #+end_src
  200. ** File Handler
  201. #+begin_src emacs-lisp :tangle early-init.el
  202. (defvar default-file-name-handler-alist file-name-handler-alist)
  203. (setq file-name-handler-alist nil)
  204. (add-hook 'emacs-startup-hook
  205. (lambda ()
  206. (setq file-name-handler-alist default-file-name-handler-alist)) 100)
  207. #+end_src
  208. ** Others
  209. #+begin_src emacs-lisp :tangle early-init.el
  210. ;; Resizing the emacs frame can be a terriblu expensive part of changing the font.
  211. ;; By inhibiting this, we easily hale startup times with fonts that are larger
  212. ;; than the system default.
  213. (setq frame-inhibit-implied-resize t)
  214. #+end_src
  215. * Default settings
  216. ** paths
  217. #+BEGIN_SRC emacs-lisp
  218. (defconst *sys/gui*
  219. (display-graphic-p)
  220. "Is emacs running in a gui?")
  221. (defconst *sys/linux*
  222. (string-equal system-type 'gnu/linux)
  223. "Is the system running Linux?")
  224. (defconst *sys/windows*
  225. (string-equal system-type 'windows-nt)
  226. "Is the system running Windows?")
  227. (defconst *home_desktop*
  228. (string-equal (system-name) "marc")
  229. "Is emacs running on my desktop?")
  230. (defconst *home_laptop*
  231. (string-equal (system-name) "laptop")
  232. "Is emacs running on my laptop?")
  233. (defconst *work_local*
  234. (string-equal (system-name) "PMPCNEU08")
  235. "Is emacs running at work on the local system?")
  236. (defconst *work_remote*
  237. (or (string-equal (system-name) "PMTS01")
  238. (string-equal (system-name) "PMTSNEU01"))
  239. "Is emacs running at work on the remote system?")
  240. #+END_SRC
  241. #+BEGIN_SRC emacs-lisp
  242. (defvar MY--PATH_USER_LOCAL (concat user-emacs-directory "user-local/"))
  243. (defvar MY--PATH_USER_GLOBAL (concat user-emacs-directory "user-global/"))
  244. (add-to-list 'custom-theme-load-path (concat MY--PATH_USER_GLOBAL "themes"))
  245. (when *sys/linux*
  246. (defconst MY--PATH_ORG_FILES (expand-file-name "~/Archiv/Organisieren/"))
  247. (defconst MY--PATH_ORG_FILES_MOBILE (expand-file-name "~/Archiv/Organisieren/mobile/"))
  248. (defconst MY--PATH_ORG_JOURNAl (expand-file-name "~/Archiv/Organisieren/Journal/"))
  249. (defconst MY--PATH_ORG_ROAM (file-truename "~/Archiv/Organisieren/")))
  250. (when *work_remote*
  251. (defconst MY--PATH_ORG_FILES "p:/Eigene Dateien/Notizen/")
  252. (defconst MY--PATH_ORG_FILES_MOBILE nil) ;; hacky way to prevent "free variable" compiler error
  253. (defconst MY--PATH_ORG_JOURNAL nil) ;; hacky way to prevent "free variable" compiler error
  254. (defconst MY--PATH_START "p:/Eigene Dateien/Notizen/")
  255. (defconst MY--PATH_ORG_ROAM (expand-file-name "p:/Eigene Dateien/Notizen/")))
  256. (setq custom-file (concat MY--PATH_USER_LOCAL "custom.el")) ;; don't spam init.e with saved customization settings
  257. (setq backup-directory-alist `((".*" . ,temporary-file-directory)))
  258. (setq auto-save-file-name-transforms `((".*" ,temporary-file-directory)))
  259. (customize-set-variable 'auth-sources (list (concat MY--PATH_USER_LOCAL "authinfo")
  260. (concat MY--PATH_USER_LOCAL "authinfo.gpg")
  261. (concat MY--PATH_USER_LOCAL "netrc")))
  262. #+end_src
  263. ** sane defaults
  264. #+begin_src emacs-lisp
  265. (setq-default create-lockfiles nil) ;; disable lock files, can cause trouble in e.g. lsp-mode
  266. (defalias 'yes-or-no-p 'y-or-n-p) ;; answer with y and n
  267. (setq custom-safe-themes t) ;; don't ask me if I want to load a theme
  268. (setq sentence-end-double-space nil) ;; don't coun two spaces after a period as the end of a sentence.
  269. (delete-selection-mode t) ;; delete selected region when typing
  270. (use-package saveplace
  271. :elpaca nil
  272. :config
  273. (save-place-mode 1) ;; saves position in file when it's closed
  274. :custom
  275. (save-place-file (concat MY--PATH_USER_LOCAL "places")))
  276. (setq save-place-forget-unreadable-files nil) ;; checks if file is readable before saving position
  277. (global-set-key (kbd "RET") 'newline-and-indent) ;; indent after newline
  278. (setq save-interprogram-paste-before-kill t) ;; put replaced text into killring
  279. ;; https://emacs.stackexchange.com/questions/3673/how-to-make-vc-and-magit-treat-a-symbolic-link-to-a-real-file-in-git-repo-just
  280. (setq find-file-visit-truename t) ;; some programs like lsp have trouble following symlinks, maybe vc-follow-symlinks would be enough
  281. #+END_SRC
  282. ** Browser
  283. #+begin_src emacs-lisp
  284. (setq browse-url-function 'browse-url-generic
  285. browse-url-generic-program "firefox")
  286. #+end_src
  287. * Appearance
  288. ** Defaults
  289. #+begin_src emacs-lisp
  290. (set-charset-priority 'unicode)
  291. (setq-default locale-coding-system 'utf-8
  292. default-process-coding-system '(utf-8-unix . utf-8-unix))
  293. (set-terminal-coding-system 'utf-8)
  294. (set-keyboard-coding-system 'utf-8)
  295. (set-selection-coding-system 'utf-8)
  296. (if *sys/windows*
  297. (prefer-coding-system 'utf-8-dos)
  298. (prefer-coding-system 'utf-8))
  299. (setq-default bidi-paragraph-direction 'left-to-right
  300. bidi-inhibit-bpa t ;; both settings reduce line rescans
  301. uniquify-buffer-name-style 'forward
  302. indent-tabs-mode nil ;; avoid tabs in place of multiple spaces (they look bad in tex)
  303. indicate-empty-lines t ;; show empty lines
  304. scroll-margin 5 ;; smooth scrolling
  305. scroll-conservatively 10000
  306. scroll-preserve-screen-position 1
  307. scroll-step 1
  308. ring-bell-function 'ignore ;; disable pc speaker bell
  309. visible-bell t)
  310. (global-hl-line-mode t) ;; highlight current line
  311. (blink-cursor-mode -1) ;; turn off blinking cursor
  312. (column-number-mode t)
  313. #+end_src
  314. ** Remove redundant UI
  315. #+begin_src emacs-lisp :tangle early-init.el
  316. (menu-bar-mode -1) ;; disable menu bar
  317. (tool-bar-mode -1) ;; disable tool bar
  318. (scroll-bar-mode -1) ;; disable scroll bar
  319. #+end_src
  320. ** Font
  321. #+BEGIN_SRC emacs-lisp
  322. (when *sys/linux*
  323. (set-face-font 'default "Hack-10"))
  324. (when *work_remote*
  325. (set-face-font 'default "Lucida Sans Typewriter-11"))
  326. #+END_SRC
  327. ** Themes
  328. #+BEGIN_SRC emacs-lisp
  329. (defun my/toggle-theme ()
  330. (interactive)
  331. (when (or *sys/windows* *sys/linux*)
  332. (if (eq (car custom-enabled-themes) 'tango-dark)
  333. (progn (disable-theme 'tango-dark)
  334. (load-theme 'tango))
  335. (progn
  336. (disable-theme 'tango)
  337. (load-theme 'tango-dark)))))
  338. (bind-key "C-c t" 'my/toggle-theme)
  339. #+END_SRC
  340. Windows Theme:
  341. #+BEGIN_SRC emacs-lisp
  342. (when *sys/windows*
  343. (load-theme 'tango))
  344. (when *sys/linux*
  345. (load-theme 'plastic))
  346. #+END_SRC
  347. ** line wrappings
  348. #+BEGIN_SRC emacs-lisp
  349. (global-visual-line-mode)
  350. ;(diminish 'visual-line-mode)
  351. (use-package adaptive-wrap
  352. :ensure t
  353. :hook
  354. (visual-line-mode . adaptive-wrap-prefix-mode))
  355. ; :init
  356. ; (when (fboundp 'adaptive-wrap-prefix-mode)
  357. ; (defun me/activate-adaptive-wrap-prefix-mode ()
  358. ; "Toggle `visual-line-mode' and `adaptive-wrap-prefix-mode' simultaneously."
  359. ; (adaptive-wrap-prefix-mode (if visual-line-mode 1 -1)))
  360. ; (add-hook 'visual-line-mode-hook 'me/activate-adaptive-wrap-prefix-mode)))
  361. #+END_SRC
  362. ** line numbers
  363. #+BEGIN_SRC emacs-lisp
  364. (use-package display-line-numbers
  365. :elpaca nil
  366. :init
  367. :hook
  368. ((prog-mode
  369. org-src-mode) . display-line-numbers-mode)
  370. :config
  371. (setq-default display-line-numbers-type 'visual
  372. display-line-numbers-current-absolute t
  373. display-line-numbers-with 4
  374. display-line-numbers-widen t))
  375. #+END_SRC
  376. ** misc
  377. Delight can replace mode names with custom names ,
  378. e.g. python-mode with just "π ".
  379. #+BEGIN_SRC emacs-lisp
  380. (use-package rainbow-mode
  381. :ensure t
  382. :diminish
  383. :hook
  384. ((org-mode
  385. emacs-lisp-mode) . rainbow-mode))
  386. (use-package delight
  387. :if *sys/linux*
  388. :ensure t)
  389. (show-paren-mode t) ;; show other part of brackets
  390. (setq blink-matching-paren nil) ;; not necessary with show-paren-mode, bugs out on C-s counsel-line
  391. (use-package rainbow-delimiters
  392. :ensure t
  393. :hook
  394. (prog-mode . rainbow-delimiters-mode))
  395. #+END_SRC
  396. * Bookmarks
  397. Usage:
  398. - C-x r m (bookmark-set): add bookmark
  399. - C-x r l (list-bookmark): list bookmarks
  400. - C-x r b (bookmark-jump): open bookmark
  401. Edit bookmarks (while in bookmark file):
  402. - d: mark current item
  403. - x: delete marked items
  404. - r: rename current item
  405. - s: save changes
  406. #+begin_src emacs-lisp
  407. (use-package bookmark
  408. :elpaca nil
  409. :custom
  410. (bookmark-default-file (concat MY--PATH_USER_LOCAL "bookmarks")))
  411. #+end_src
  412. Some windows specific stuff
  413. #+BEGIN_SRC emacs-lisp
  414. (when *sys/windows*
  415. (remove-hook 'find-file-hook 'vc-refresh-state)
  416. ; (progn
  417. ; (setq gc-cons-threshold (* 511 1024 1024)
  418. ; gc-cons-percentage 0.5
  419. ; garbage-collection-messages t
  420. ; (run-with-idle-timer 5 t #'garbage-collect))
  421. (when (boundp 'w32-pipe-read-delay)
  422. (setq w32-pipe-read-delay 0))
  423. (when (boundp 'w32-get-true-file-attributes)
  424. (setq w32-get-true-file-attributes nil)))
  425. #+END_SRC
  426. * recentf
  427. Exclude some dirs from spamming recentf
  428. #+begin_src emacs-lisp
  429. (use-package recentf
  430. :elpaca nil
  431. ; :defer 1
  432. :config
  433. (recentf-mode)
  434. :custom
  435. (recentf-exclude '(".*-autoloads\\.el\\'"
  436. "[/\\]\\elpa/"
  437. "COMMIT_EDITMSG\\'"))
  438. (recentf-save-file (concat MY--PATH_USER_LOCAL "recentf"))
  439. (recentf-max-menu-items 600)
  440. (recentf-max-saved-items 600))
  441. #+end_src
  442. * savehist
  443. #+begin_src emacs-lisp
  444. (use-package savehist
  445. :elpaca nil
  446. :config
  447. (savehist-mode)
  448. :custom
  449. (savehist-file (concat MY--PATH_USER_LOCAL "history")))
  450. #+end_src
  451. * undo
  452. #+BEGIN_SRC emacs-lisp
  453. (use-package undo-tree
  454. :ensure t
  455. :diminish undo-tree-mode
  456. :init
  457. (global-undo-tree-mode 1)
  458. :custom
  459. (undo-tree-auto-save-history nil))
  460. #+END_SRC
  461. * COMMENT ace-window (now avy)
  462. #+begin_src emacs-lisp
  463. (use-package ace-window
  464. :ensure t
  465. :bind
  466. (:map global-map
  467. ("C-x o" . ace-window)))
  468. #+end_src
  469. * which-key
  470. #+BEGIN_SRC emacs-lisp
  471. (use-package which-key
  472. :ensure t
  473. :diminish which-key-mode
  474. :defer t
  475. :hook
  476. (after-init . which-key-mode)
  477. :custom
  478. (which-key-idle-delay 0.5)
  479. (which-key-sort-order 'which-key-description-order)
  480. :config
  481. (which-key-setup-side-window-bottom))
  482. #+END_SRC
  483. * abbrev
  484. #+begin_src emacs-lisp
  485. (use-package abbrev
  486. :elpaca nil
  487. :diminish abbrev-mode
  488. :hook
  489. ((text-mode org-mode) . abbrev-mode)
  490. :init
  491. (setq abbrev-file-name (concat MY--PATH_USER_GLOBAL "abbrev_tables.el"))
  492. :config
  493. (if (file-exists-p abbrev-file-name)
  494. (quietly-read-abbrev-file))
  495. (setq save-abbrevs 'silently)) ;; don't bother me with asking for abbrev saving
  496. #+end_src
  497. * imenu-list
  498. A minor mode to show imenu in a sidebar.
  499. Call imenu-list-smart-toggle.
  500. [[https://github.com/bmag/imenu-list][Source]]
  501. #+BEGIN_SRC emacs-lisp
  502. (use-package imenu-list
  503. :ensure t
  504. :demand t ; otherwise mode loads too late and won't work on first file it's being activated on
  505. :config
  506. (setq imenu-list-focus-after-activation t
  507. imenu-list-auto-resize t
  508. imenu-list-position 'right)
  509. :general
  510. ([f9] 'imenu-list-smart-toggle)
  511. (:states '(normal insert)
  512. :keymaps 'imenu-list-major-mode-map
  513. "RET" '(imenu-list-goto-entry :which-key "goto")
  514. "TAB" '(hs-toggle-hiding :which-key "collapse")
  515. "v" '(imenu-list-display-entry :which-key "show") ; also prevents visual mode
  516. "q" '(imenu-list-quit-window :which-key "quit"))
  517. :custom
  518. (org-imenu-depth 4))
  519. #+END_SRC
  520. * COMMENT Evil
  521. See also
  522. https://github.com/noctuid/evil-guide
  523. Use C-z (evil-toggle-key) to switch between evil and emacs keybindings,
  524. in case evil is messing something up.
  525. #+BEGIN_SRC emacs-lisp
  526. (use-package evil
  527. :ensure t
  528. :defer .1
  529. :custom
  530. (evil-want-C-i-jump nil) ;; prevent evil from blocking TAB in org tree expanding
  531. (evil-want-integration t)
  532. (evil-want-keybinding nil)
  533. :config
  534. ;; example for using emacs default key map in a certain mode
  535. ;; (evil-set-initial-state 'dired-mode 'emacs)
  536. (evil-mode 1))
  537. #+END_SRC
  538. * Eldoc
  539. use builtin version
  540. #+begin_src emacs-lisp
  541. (use-package eldoc
  542. :elpaca nil
  543. :diminish eldoc-mode
  544. :defer t)
  545. #+end_src
  546. * COMMENT Eldoc Box
  547. Currently corfu-popupinfo displays eldoc in highlighted completion candidate. Maybe that's good enough.
  548. #+begin_src emacs-lisp
  549. (use-package eldoc-box
  550. :ensure t)
  551. #+end_src
  552. * Meow
  553. #+begin_src emacs-lisp
  554. (use-package meow
  555. :ensure t
  556. :config
  557. (setq meow-cheatsheet-layout meow-cheatsheet-layout-qwerty)
  558. (meow-motion-overwrite-define-key
  559. '("j" . meow-next)
  560. '("k" . meow-prev)
  561. '("<escape>" . ignore))
  562. (meow-leader-define-key
  563. ;; SPC j/k will run the original command in MOTION state.
  564. '("j" . "H-j")
  565. '("k" . "H-k")
  566. ;; Use SPC (0-9) for digit arguments.
  567. '("1" . meow-digit-argument)
  568. '("2" . meow-digit-argument)
  569. '("3" . meow-digit-argument)
  570. '("4" . meow-digit-argument)
  571. '("5" . meow-digit-argument)
  572. '("6" . meow-digit-argument)
  573. '("7" . meow-digit-argument)
  574. '("8" . meow-digit-argument)
  575. '("9" . meow-digit-argument)
  576. '("0" . meow-digit-argument)
  577. '("/" . meow-keypad-describe-key)
  578. '("?" . meow-cheatsheet))
  579. (meow-normal-define-key
  580. '("0" . meow-expand-0)
  581. '("9" . meow-expand-9)
  582. '("8" . meow-expand-8)
  583. '("7" . meow-expand-7)
  584. '("6" . meow-expand-6)
  585. '("5" . meow-expand-5)
  586. '("4" . meow-expand-4)
  587. '("3" . meow-expand-3)
  588. '("2" . meow-expand-2)
  589. '("1" . meow-expand-1)
  590. '("-" . negative-argument)
  591. '(";" . meow-reverse)
  592. '("," . meow-inner-of-thing)
  593. '("." . meow-bounds-of-thing)
  594. '("[" . meow-beginning-of-thing)
  595. '("]" . meow-end-of-thing)
  596. '("a" . meow-append)
  597. '("A" . meow-open-below)
  598. '("b" . meow-back-word)
  599. '("B" . meow-back-symbol)
  600. '("c" . meow-change)
  601. '("d" . meow-delete)
  602. '("D" . meow-backward-delete)
  603. '("e" . meow-next-word)
  604. '("E" . meow-next-symbol)
  605. '("f" . meow-find)
  606. '("g" . meow-cancel-selection)
  607. '("G" . meow-grab)
  608. '("h" . meow-left)
  609. '("H" . meow-left-expand)
  610. '("i" . meow-insert)
  611. '("I" . meow-open-above)
  612. '("j" . meow-next)
  613. '("J" . meow-next-expand)
  614. '("k" . meow-prev)
  615. '("K" . meow-prev-expand)
  616. '("l" . meow-right)
  617. '("L" . meow-right-expand)
  618. '("m" . meow-join)
  619. '("n" . meow-search)
  620. '("o" . meow-block)
  621. '("O" . meow-to-block)
  622. '("p" . meow-yank)
  623. '("q" . meow-quit)
  624. '("Q" . meow-goto-line)
  625. '("r" . meow-replace)
  626. '("R" . meow-swap-grab)
  627. '("s" . meow-kill)
  628. '("t" . meow-till)
  629. '("u" . meow-undo)
  630. '("U" . meow-undo-in-selection)
  631. '("v" . meow-visit)
  632. '("w" . meow-mark-word)
  633. '("W" . meow-mark-symbol)
  634. '("x" . meow-line)
  635. '("X" . meow-goto-line)
  636. '("y" . meow-save)
  637. '("Y" . meow-sync-grab)
  638. '("z" . meow-pop-selection)
  639. '("'" . repeat)
  640. '("<escape>" . ignore))
  641. ; :config
  642. (meow-global-mode t))
  643. #+end_src
  644. * avy
  645. Search, move, copy, delete text within all visible buffers.
  646. Also replaces ace-window for buffer switching.
  647. [[https://github.com/abo-abo/avy]]
  648. #+BEGIN_SRC emacs-lisp
  649. (use-package avy
  650. :ensure t
  651. :general
  652. (:prefix "M-s"
  653. "" '(:ignore t :which-key "avy")
  654. "w" '(avy-goto-char-2 :which-key "avy-jump")
  655. "c" '(:ignore t :which-key "avy copy")
  656. "c l" '(avy-copy-line :which-key "avy copy line")
  657. "c r" '(avy-copy-region :which-key "avy copy region")
  658. "m" '(:ignore t :which-key "avy move")
  659. "m l" '(avy-move-line :which-key "avy move line")
  660. "m r" '(avy-move-region :which-key "avy move region")))
  661. #+END_SRC
  662. * Vertico
  663. Vertico is a completion ui for the minibuffer and replaced selectrum.
  664. [[https://github.com/minad/vertico][Vertico Github]]
  665. #+begin_src emacs-lisp
  666. ;; completion ui
  667. (use-package vertico
  668. :ensure t
  669. :init
  670. (vertico-mode))
  671. #+end_src
  672. * Corfu
  673. Completion ui, replaces company.
  674. [[https://github.com/minad/corfu][Corfu Github]]
  675. #+begin_src emacs-lisp
  676. (use-package corfu
  677. :ensure t
  678. :after savehist
  679. :custom
  680. (corfu-popupinfo-delay t)
  681. (corfu-auto t)
  682. (corfu-cycle t)
  683. (corfu-auto-delay 0.3)
  684. (corfu-preselect-first nil)
  685. (corfu-popupinfo-delay '(1.0 . 0.0)) ;1s for first popup, instant for subsequent popups
  686. (corfu-popupinfo-max-width 70)
  687. (corfu-popupinfo-max-height 20)
  688. :init
  689. (global-corfu-mode)
  690. ; (corfu-popupinfo-mode) ; causes corfu window to stay
  691. (corfu-history-mode)
  692. ;; belongs to emacs
  693. (add-to-list 'savehist-additional-variables 'corfu-history)
  694. :hook
  695. (corfu-mode . corfu-popupinfo-mode))
  696. ; :bind
  697. ; (:map corfu-map
  698. ; ("TAB" . corfu-next)
  699. ; ("<C-return>" . corfu-insert)
  700. ; ("C-TAB" . corfu-popupinfo-toggle)))
  701. ;; (general-define-key
  702. ;; :states 'insert
  703. ;; :definer 'minor-mode
  704. ;; :keymaps 'completion-in-region-mode
  705. ;; :predicate 'corfu-mode
  706. ;; "C-d" 'corfu-info-documentation)
  707. (use-package emacs
  708. :elpaca nil
  709. :init
  710. ;; hide commands in M-x which do not apply to current mode
  711. (setq read-extended-command-predicate #'command-completion-default-include-p)
  712. ;; enable indentation + completion using TAB
  713. (setq tab-always-indent 'complete))
  714. #+end_src
  715. * Cape
  716. Adds completions for corfu
  717. [[https://github.com/minad/cape][Cape Github]]
  718. Available functions:
  719. dabbrev, file, history, keyword, tex, sgml, rfc1345, abbrev, ispell, dict, symbol, line
  720. #+begin_src emacs-lisp
  721. (use-package cape
  722. :ensure t
  723. :bind
  724. (("C-c p p" . completion-at-point) ;; capf
  725. ("C-c p t" . complete-tag) ;; etags
  726. ("C-c p d" . cape-dabbrev)
  727. ("C-c p h" . cape-history)
  728. ("C-c p f" . cape-file))
  729. :init
  730. (advice-add #'lsp-completion-at-point :around #'cape-wrap-noninterruptible) ;; for performance issues with lsp
  731. (add-to-list 'completion-at-point-functions #'cape-dabbrev)
  732. (add-to-list 'completion-at-point-functions #'cape-file)
  733. (add-to-list 'completion-at-point-functions #'cape-history))
  734. #+end_src
  735. * kind-icon
  736. Make corfu pretty
  737. [[https://github.com/jdtsmith/kind-icon][kind-icon Github]]
  738. #+begin_src emacs-lisp
  739. (use-package kind-icon
  740. :ensure t
  741. :after corfu
  742. :custom
  743. (kind-icon-default-face 'corfu-default) ;; to compute blended backgrounds correctly
  744. :config
  745. (add-to-list 'corfu-margin-formatters #'kind-icon-margin-formatter))
  746. #+end_src
  747. * Orderless
  748. [[https://github.com/oantolin/orderless][Orderless Github]]
  749. Orderless orders the suggestions by recency. The package prescient orders by frequency.
  750. #+begin_src emacs-lisp
  751. (use-package orderless
  752. :ensure t
  753. :init
  754. (setq completion-styles '(orderless partial-completion basic)
  755. completion-category-defaults nil
  756. completion-category-overrides nil))
  757. ; completion-category-overrides '((file (styles partial-completion)))))
  758. #+end_src
  759. * Consult
  760. [[https://github.com/minad/consult][Github]]
  761. #+begin_src emacs-lisp
  762. (use-package consult
  763. :ensure t
  764. :bind
  765. (("C-x C-r" . consult-recent-file)
  766. ("C-x b" . consult-buffer)
  767. ("C-s" . consult-line))
  768. :config
  769. ;; disable preview for some commands and buffers
  770. ;; and enable it by M-.
  771. ;; see https://github.com/minad/consult#use-package-example
  772. (consult-customize
  773. consult-theme
  774. :preview-key '(debounce 0.2 any)
  775. consult-ripgrep consult-git-grep consult-grep
  776. consult-bookmark consult-recent-file consult-xref
  777. consult--source-bookmark consult--source-file-register
  778. consult--source-recent-file consult--source-project-recent-file
  779. :preview-key "M-."))
  780. #+end_src
  781. * Marginalia
  782. [[https://github.com/minad/marginalia/][Github]]
  783. Adds additional information to the minibuffer
  784. #+begin_src emacs-lisp
  785. (use-package marginalia
  786. :ensure t
  787. :init
  788. (marginalia-mode)
  789. :bind
  790. (:map minibuffer-local-map
  791. ("M-A" . marginalia-cycle))
  792. :custom
  793. ;; switch by 'marginalia-cycle
  794. (marginalia-annotators '(marginalia-annotators-heavy
  795. marginalia-annotators-light
  796. nil)))
  797. #+end_src
  798. * Embark
  799. Does stuff in the minibuffer results
  800. #+begin_src emacs-lisp
  801. (use-package embark
  802. :ensure t
  803. :bind
  804. (("C-S-a" . embark-act)
  805. ("C-h B" . embark-bindings))
  806. :init
  807. (setq prefix-help-command #'embark-prefix-help-command)
  808. :config
  809. ;; hide modeline of the embark live/completions buffers
  810. (add-to-list 'display-buffer-alist
  811. '("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
  812. nil
  813. (window-parameters (mode-line-format . none)))))
  814. (use-package embark-consult
  815. :ensure t
  816. :after (embark consult)
  817. :demand t
  818. :hook
  819. (embark-collect-mode . embark-consult-preview-minor-mode))
  820. #+end_src
  821. * Org-ql
  822. [[https://github.com/alphapapa/org-ql][org-ql]]
  823. Run queries on org files
  824. #+begin_src emacs-lisp
  825. (use-package org-ql
  826. :ensure t
  827. )
  828. #+end_src
  829. * COMMENT Xeft (needs xapian, not really windows compatible)
  830. Fast full text search for stuff org-ql cannot cover
  831. #+begin_src emacs-lisp
  832. (use-package xeft
  833. :ensure t
  834. :custom
  835. (xeft-recursive 'follow-symlinks))
  836. #+end_src
  837. * COMMENT Helm
  838. As an alternative if I'm not happy with selectrum & co
  839. #+begin_src emacs-lisp
  840. (use-package helm
  841. :ensure t
  842. :hook
  843. (helm-mode . helm-autoresize-mode)
  844. ;; :bind
  845. ;; (("M-x" . helm-M-x)
  846. ;; ("C-s" . helm-occur)
  847. ;; ("C-x C-f" . helm-find-files)
  848. ;; ("C-x C-b" . helm-buffers-list)
  849. ;; ("C-x b" . helm-buffers-list)
  850. ;; ("C-x C-r" . helm-recentf)
  851. ;; ("C-x C-i" . helm-imenu))
  852. :config
  853. (helm-mode)
  854. :custom
  855. (helm-split-window-inside-p t) ;; open helm buffer inside current window
  856. (helm-move-to-line-cycle-in-source t)
  857. (helm-echo-input-in-header-line t)
  858. (helm-autoresize-max-height 20)
  859. (helm-autoresize-min-height 5)
  860. )
  861. #+end_src
  862. * COMMENT ivy / counsel / swiper
  863. #+BEGIN_SRC emacs-lisp
  864. ; (require 'ivy)
  865. (use-package ivy
  866. :ensure t
  867. :diminish
  868. (ivy-mode . "")
  869. :defer t
  870. :init
  871. (ivy-mode 1)
  872. :bind
  873. ("C-r" . ivy-resume) ;; overrides isearch-backwards binding
  874. :config
  875. (setq ivy-use-virtual-buffers t ;; recent files and bookmarks in ivy-switch-buffer
  876. ivy-height 20 ;; height of ivy window
  877. ivy-count-format "%d/%d" ;; current and total number
  878. ivy-re-builders-alist ;; regex replaces spaces with *
  879. '((t . ivy--regex-plus))))
  880. ; make counsel-M-x more descriptive
  881. (use-package ivy-rich
  882. :ensure t
  883. :defer t
  884. :init
  885. (ivy-rich-mode 1))
  886. (use-package counsel
  887. :ensure t
  888. :defer t
  889. :bind
  890. (("M-x" . counsel-M-x)
  891. ("C-x C-f" . counsel-find-file)
  892. ("C-x C-r" . counsel-recentf)
  893. ("C-x b" . counsel-switch-buffer)
  894. ("C-c C-f" . counsel-git)
  895. ("C-c h f" . counsel-describe-function)
  896. ("C-c h v" . counsel-describe-variable)
  897. ("M-i" . counsel-imenu)))
  898. ; :map minibuffer-local-map ;;currently mapped to evil-redo
  899. ; ("C-r" . 'counsel-minibuffer-history)))
  900. (use-package swiper
  901. :ensure t
  902. :bind
  903. ("C-s" . swiper))
  904. (use-package ivy-hydra
  905. :ensure t)
  906. #+END_SRC
  907. * outlook
  908. In outlook a macro is necessary, also a reference to FM20.DLL
  909. (Microsoft Forms 2.0 Object Library, in c:\windows\syswow64\fm20.dll)
  910. The macro copies the GUID of the email to the clipboard
  911. Attention: the GUID changes when the email is moved to another folder!
  912. The macro:
  913. #+BEGIN_SRC
  914. Sub AddLinkToMessageInClipboard()
  915. 'Adds a link to the currently selected message to the clipboard
  916. Dim objMail As Outlook.MailItem
  917. Dim doClipboard As New DataObject
  918. 'One and ONLY one message muse be selected
  919. If Application.ActiveExplorer.Selection.Count <> 1 Then
  920. MsgBox ("Select one and ONLY one message.")
  921. Exit Sub
  922. End If
  923. Set objMail = Application.ActiveExplorer.Selection.Item(1)
  924. doClipboard.SetText "[[outlook:" + objMail.EntryID + "][MESSAGE: " + objMail.Subject + " (" + objMail.SenderName + ")]]"
  925. doClipboard.PutInClipboard
  926. End Sub
  927. #+END_SRC
  928. #+BEGIN_SRC emacs-lisp
  929. ;(org-add-link-type "outlook" 'my--org-outlook-open)
  930. (defun my--org-outlook-open (id)
  931. (w32-shell-execute "open" "outlook" (concat " /select outlook:" id)))
  932. (defun my/org-outlook-open-test ()
  933. (interactive)
  934. (w32-shell-execute "open" "outlook" " /select outlook:000000008A209C397CEF2C4FBA9E54AEB5B1F97F0700846D043B407C5B43A0C05AFC46DC5C630587BE5E020900006E48FF8F6027694BA6593777F542C19E0002A6434D000000"))'
  935. #+END_SRC
  936. * misc
  937. #+begin_src emacs-lisp
  938. (use-package autorevert
  939. :diminish auto-revert-mode)
  940. #+end_src
  941. * COMMENT company (now corfu)
  942. #+BEGIN_SRC emacs-lisp
  943. (use-package company
  944. :defer 1
  945. :diminish
  946. :defer t
  947. :bind
  948. (("C-<tab>" . company-complete)
  949. :map company-active-map
  950. ("RET" . nil)
  951. ([return] . nil)
  952. ("TAB" . company-complete-selection)
  953. ([tab] . company-complete-selection)
  954. ("<right>" . company-complete-common)
  955. ("<escape>" . company-abort))
  956. :hook
  957. (after-init . global-company-mode)
  958. (emacs-lisp-mode . my--company-elisp)
  959. (org-mode . my--company-org)
  960. :config
  961. (defun my--company-elisp ()
  962. (message "set up company for elisp")
  963. (set (make-local-variable 'company-backends)
  964. '(company-capf ;; capf needs to be before yasnippet, or lsp fucks up completion for elisp
  965. company-yasnippet
  966. company-dabbrev-code
  967. company-files)))
  968. (defun my--company-org ()
  969. (set (make-local-variable 'company-backends)
  970. '(company-capf company-files))
  971. ;; (add-hook 'completion-at-point-functions 'pcomplete-completions-at-point nil t)
  972. (message "setup company for org"))
  973. (setq company-idle-delay .2
  974. company-minimum-prefix-length 1
  975. company-require-match nil
  976. company-show-numbers t
  977. company-tooltip-align-annotations t))
  978. (use-package company-statistics
  979. :ensure t
  980. :after company
  981. :defer t
  982. :init
  983. (setq company-statistics-file (concat MY--PATH_USER_LOCAL "company-statistics-cache.el"));~/.emacs.d/user-dir/company-statistics-cache.el")
  984. :config
  985. (company-statistics-mode 1))
  986. (use-package company-dabbrev
  987. :ensure nil
  988. :after company
  989. :defer t
  990. :config
  991. (setq-default company-dabbrev-downcase nil))
  992. ;; adds a info box right of the cursor with doc of the function
  993. (use-package company-box
  994. :ensure t
  995. :diminish
  996. :defer t
  997. :hook
  998. (company-mode . company-box-mode))
  999. ; :init
  1000. ; (add-hook 'company-mode-hook 'company-box-mode))
  1001. #+END_SRC
  1002. * orgmode
  1003. ** some notes
  1004. *** copy file path within emacs
  1005. Enter dired-other-window
  1006. place cursor on the file
  1007. M-0 w (copy absolute path)
  1008. C-u w (copy relative path)
  1009. *** Archiving
  1010. C-c C-x C-a
  1011. To keep the subheading structure when archiving, set the properties of the superheading.
  1012. #+begin_src org :tangle no
  1013. ,* FOO
  1014. :PROPERTIES:
  1015. :ARCHIVE: %s_archive::* FOO
  1016. ,** DONE BAR
  1017. ,** TODO BAZ
  1018. #+end_src
  1019. When moving BAR to archive, it will go to FILENAME.org_archive below the heading FOO.
  1020. [[http://doc.endlessparentheses.com/Var/org-archive-location.html][Other examples]]
  1021. ** org
  1022. This seems necessary to prevent 'org is already installed' error
  1023. https://github.com/jwiegley/use-package/issues/319
  1024. #+begin_src emacs-lisp
  1025. ;(assq-delete-all 'org package--builtins)'
  1026. ;(assq-delete-all 'org package--builtin-versions)
  1027. #+end_src
  1028. #+BEGIN_SRC emacs-lisp
  1029. (defun my--buffer-prop-set (name value)
  1030. "Set a file property called NAME to VALUE in buffer file.
  1031. If the property is already set, replace its value."
  1032. (setq name (downcase name))
  1033. (org-with-point-at 1
  1034. (let ((case-fold-search t))
  1035. (if (re-search-forward (concat "^#\\+" name ":\\(.*\\)")
  1036. (point-max) t)
  1037. (replace-match (concat "#+" name ": " value) 'fixedcase)
  1038. (while (and (not (eobp))
  1039. (looking-at "^[#:]"))
  1040. (if (save-excursion (end-of-line) (eobp))
  1041. (progn
  1042. (end-of-line)
  1043. (insert "\n"))
  1044. (forward-line)
  1045. (beginning-of-line)))
  1046. (insert "#+" name ": " value "\n")))))
  1047. (defun my--buffer-prop-remove (name)
  1048. "Remove a buffer property called NAME."
  1049. (org-with-point-at 1
  1050. (when (re-search-forward (concat "\\(^#\\+" name ":.*\n?\\)")
  1051. (point-max) t)
  1052. (replace-match ""))))
  1053. (use-package org
  1054. :ensure t
  1055. :pin gnu
  1056. :mode (("\.org$" . org-mode))
  1057. :diminish org-indent-mode
  1058. :defer 1
  1059. :hook
  1060. (org-mode . org-indent-mode)
  1061. (org-source-mode . smartparens-mode)
  1062. :bind (("C-c l" . org-store-link)
  1063. ("C-c c" . org-capture)
  1064. ("C-c a" . org-agenda)
  1065. :map org-mode-map ("S-<right>" . org-shiftright)
  1066. ("S-<left>" . org-shiftleft))
  1067. :init
  1068. (defun my--org-agenda-files-set ()
  1069. "Sets default agenda files.
  1070. Necessary when updating roam agenda todos."
  1071. (setq org-agenda-files (list (concat MY--PATH_ORG_FILES "notes.org")
  1072. (concat MY--PATH_ORG_FILES "projects.org")
  1073. (concat MY--PATH_ORG_FILES "tasks.org")))
  1074. (when *sys/linux*
  1075. (nconc org-agenda-files
  1076. (directory-files-recursively MY--PATH_ORG_FILES_MOBILE "\\.org$"))))
  1077. (my--org-agenda-files-set)
  1078. (defun my--org-skip-subtree-if-priority (priority)
  1079. "Skip an agenda subtree if it has a priority of PRIORITY.
  1080. PRIORITY may be one of the characters ?A, ?B, or ?C."
  1081. (let ((subtree-end (save-excursion (org-end-of-subtree t)))
  1082. (pri-value (* 1000 (- org-lowest-priority priority)))
  1083. (pri-current (org-get-priority (thing-at-point 'line t))))
  1084. (if (= pri-value pri-current)
  1085. subtree-end
  1086. nil)))
  1087. :config
  1088. (when *work_remote*
  1089. (org-add-link-type "outlook" 'my--org-outlook-open))
  1090. :custom
  1091. (when *work_remote*
  1092. (org-todo-keywords
  1093. '((sequence "OPEN" "TODO" "UNCLEAR" "|" "DONE" "IMPOSSIBLE" "CANCELLED"))))
  1094. (when *sys/linux*
  1095. (org-pretty-entities t))
  1096. (org-startup-truncated t)
  1097. (org-startup-align-all-tables t)
  1098. (org-src-fontify-natively t) ;; use syntax highlighting in code blocks
  1099. (org-src-preserve-indentation t) ;; no extra indentation
  1100. (org-src-window-setup 'current-window) ;; C-c ' opens in current window
  1101. (org-modules (quote (org-id
  1102. org-habit
  1103. org-tempo))) ;; easy templates
  1104. (org-default-notes-file (concat MY--PATH_ORG_FILES "notes.org"))
  1105. (org-id-locations-file (concat MY--PATH_USER_LOCAL ".org-id-locations"))
  1106. (org-log-into-drawer "LOGBOOK")
  1107. (org-log-done 'time) ;; create timestamp when task is done
  1108. (org-blank-before-new-entry '((heading) (plain-list-item))) ;; prevent new line before new item
  1109. (org-src-tab-acts-natively t)
  1110. ;;Sort agenda by deadline and priority
  1111. (org-agenda-sorting-strategy
  1112. (quote
  1113. ((agenda deadline-up priority-down)
  1114. (todo priority-down category-keep)
  1115. (tags priority-down category-keep)
  1116. (search category-keep))))
  1117. (org-agenda-custom-commands
  1118. '(("c" "Simple agenda view"
  1119. ((tags "PRIORITY=\"A\""
  1120. ((org-agenda-skip-function '(org-agenda-skip-entry-if 'todo 'done))
  1121. (org-agenda-overriding-header "Hohe Priorität:")))
  1122. (agenda ""
  1123. ((org-agenda-skip-function '(org-agenda-skip-entry-if 'todo 'done))
  1124. (org-agenda-span 7)
  1125. (org-agenda-start-on-weekday nil)
  1126. (org-agenda-overriding-header "Nächste 7 Tage:")))
  1127. (alltodo ""
  1128. ((org-agenda-skip-function '(or (my--org-skip-subtree-if-priority ?A)
  1129. (org-agenda-skip-if nil '(scheduled deadline))))
  1130. (org-agenda-overriding-header "Sonstige Aufgaben:"))))))))
  1131. #+END_SRC
  1132. ** COMMENT languages
  1133. Set some languages and disable confirmation for evaluating code blocks C-c C-c
  1134. Elpaca cant find it, though it's built in org
  1135. #+begin_src emacs-lisp
  1136. (use-package ob-python
  1137. ; :elpaca nil
  1138. :defer t
  1139. :after org
  1140. ; :ensure org-contrib
  1141. :commands
  1142. (org-babel-execute:python))
  1143. #+end_src
  1144. ** COMMENT habits
  1145. #+BEGIN_SRC emacs-lisp
  1146. (require 'org-habit) ;;TODO Lösung ohne require finden, scheint mir nicht ideal zu sein, nur um ein org-modul zu aktivieren
  1147. ;; (add-to-list 'org-modules "org-habit")
  1148. (setq org-habit-graph-column 80
  1149. org-habit-preceding-days 30
  1150. org-habit-following-days 7
  1151. org-habit-show-habits-only-for-today nil)
  1152. #+END_SRC
  1153. ** *TODO*
  1154. [[https://github.com/nobiot/org-transclusion][org-transclusion]]?
  1155. ** COMMENT journal
  1156. [[https://github.com/bastibe/org-journal][Source]]
  1157. Ggf. durch org-roam-journal ersetzen
  1158. #+BEGIN_SRC emacs-lisp
  1159. (use-package org-journal
  1160. :if *sys/linux*
  1161. :ensure t
  1162. :defer t
  1163. :config
  1164. ;; feels hacky, but this way compiler error "assignment to free variable" disappears
  1165. (when (and (boundp 'org-journal-dir)
  1166. (boundp 'org-journal-enable-agenda-integration))
  1167. (setq org-journal-dir MY--PATH_ORG_JOURNAl
  1168. org-journal-enable-agenda-integration t)))
  1169. #+END_SRC
  1170. ** org-roam
  1171. [[https://github.com/org-roam/org-roam][Github]]
  1172. Um Headings innerhalb einer Datei zu verlinken:
  1173. - org-id-get-create im Heading,
  1174. - org-roam-node-insert in der verweisenden Datei
  1175. Bei Problemen wie unique constraint
  1176. org-roam-db-clear-all
  1177. org-roam-db-sync
  1178. #+BEGIN_SRC emacs-lisp
  1179. (use-package org-roam
  1180. :ensure t
  1181. :defer 2
  1182. :after org
  1183. :init
  1184. (setq org-roam-v2-ack t)
  1185. (defun my--roamtodo-p ()
  1186. "Return non-nil if current buffer has any todo entry.
  1187. TODO entries marked as done are ignored, meaning this function
  1188. returns nil if current buffer contains only completed tasks."
  1189. (seq-find
  1190. (lambda (type)
  1191. (eq type 'todo))
  1192. (org-element-map
  1193. (org-element-parse-buffer 'headline)
  1194. 'headline
  1195. (lambda (h)
  1196. (org-element-property :todo-type h)))))
  1197. (defun my--roamtodo-update-tag ()
  1198. "Update ROAMTODO tag in the current buffer."
  1199. (when (and (not (active-minibuffer-window))
  1200. (my--buffer-roam-note-p))
  1201. (save-excursion
  1202. (goto-char (point-min))
  1203. (let* ((tags (my--buffer-tags-get))
  1204. (original-tags tags))
  1205. (if (my--roamtodo-p)
  1206. (setq tags (cons "roamtodo" tags))
  1207. (setq tags (remove "roamtodo" tags)))
  1208. ;;cleanup duplicates
  1209. (when (or (seq-difference tags original-tags)
  1210. (seq-difference original-tags tags))
  1211. (apply #'my--buffer-tags-set tags))))))
  1212. (defun my--buffer-tags-get ()
  1213. "Return filetags value in current buffer."
  1214. (my--buffer-prop-get-list "filetags" "[ :]"))
  1215. (defun my--buffer-tags-set (&rest tags)
  1216. "Set TAGS in current buffer.
  1217. If filetags value is already set, replace it."
  1218. (if tags
  1219. (my--buffer-prop-set
  1220. "filetags" (concat ":" (string-join tags ":") ":"))
  1221. (my--buffer-prop-remove "filetags")))
  1222. (defun my--buffer-tags-add (tag)
  1223. "Add a TAG to filetags in current buffer."
  1224. (let* ((tags (my--buffer-tags-get))
  1225. (tags (append tags (list tag))))
  1226. (apply #'my--buffer-tags-set tags)))
  1227. (defun my--buffer-tags-remove (tag)
  1228. "Remove a TAG from filetags in current buffer."
  1229. (let* ((tags (my--buffer-tags-get))
  1230. (tags (delete tag tags)))
  1231. (apply #'my--buffer-tags-set tags)))
  1232. (defun my--buffer-prop-set (name value)
  1233. "Set a file property called NAME to VALUE in buffer file.
  1234. If the property is already set, replace its value."
  1235. (setq name (downcase name))
  1236. (org-with-point-at 1
  1237. (let ((case-fold-search t))
  1238. (if (re-search-forward (concat "^#\\+" name ":\\(.*\\)")
  1239. (point-max) t)
  1240. (replace-match (concat "#+" name ": " value) 'fixedcase)
  1241. (while (and (not (eobp))
  1242. (looking-at "^[#:]"))
  1243. (if (save-excursion (end-of-line) (eobp))
  1244. (progn
  1245. (end-of-line)
  1246. (insert "\n"))
  1247. (forward-line)
  1248. (beginning-of-line)))
  1249. (insert "#+" name ": " value "\n")))))
  1250. (defun my--buffer-prop-set-list (name values &optional separators)
  1251. "Set a file property called NAME to VALUES in current buffer.
  1252. VALUES are quoted and combined into single string using
  1253. `combine-and-quote-strings'.
  1254. If SEPARATORS is non-nil, it should be a regular expression
  1255. matching text that separates, but is not part of, the substrings.
  1256. If nil it defaults to `split-string-and-unquote', normally
  1257. \"[ \f\t\n\r\v]+\", and OMIT-NULLS is forced to t.
  1258. If the property is already set, replace its value."
  1259. (my--buffer-prop-set
  1260. name (combine-and-quote-strings values separators)))
  1261. (defun my--buffer-prop-get (name)
  1262. "Get a buffer property called NAME as a string."
  1263. (org-with-point-at 1
  1264. (when (re-search-forward (concat "^#\\+" name ": \\(.*\\)")
  1265. (point-max) t)
  1266. (buffer-substring-no-properties
  1267. (match-beginning 1)
  1268. (match-end 1)))))
  1269. (defun my--buffer-prop-get-list (name &optional separators)
  1270. "Get a buffer property NAME as a list using SEPARATORS.
  1271. If SEPARATORS is non-nil, it should be a regular expression
  1272. matching text that separates, but is not part of, the substrings.
  1273. If nil it defaults to `split-string-default-separators', normally
  1274. \"[ \f\t\n\r\v]+\", and OMIT-NULLS is forced to t."
  1275. (let ((value (my--buffer-prop-get name)))
  1276. (when (and value (not (string-empty-p value)))
  1277. (split-string-and-unquote value separators))))
  1278. (defun my--buffer-prop-remove (name)
  1279. "Remove a buffer property called NAME."
  1280. (org-with-point-at 1
  1281. (when (re-search-forward (concat "\\(^#\\+" name ":.*\n?\\)")
  1282. (point-max) t)
  1283. (replace-match ""))))
  1284. (defun my--buffer-roam-note-p ()
  1285. "Return non-nil if the currently visited buffer is a note."
  1286. (and buffer-file-name
  1287. (string-prefix-p
  1288. (expand-file-name (file-name-as-directory MY--PATH_ORG_ROAM))
  1289. (file-name-directory buffer-file-name))))
  1290. (defun my--org-roam-filter-by-tag (tag-name)
  1291. (lambda (node)
  1292. (member tag-name (org-roam-node-tags node))))
  1293. (defun my--org-roam-list-notes-by-tag (tag-name)
  1294. (mapcar #'org-roam-node-file
  1295. (seq-filter
  1296. (my--org-roam-filter-by-tag tag-name)
  1297. (org-roam-node-list))))
  1298. (defun my/org-roam-refresh-agenda-list ()
  1299. "Add all org roam files with #+filetags: roamtodo"
  1300. (interactive)
  1301. (my--org-agenda-files-set)
  1302. (nconc org-agenda-files
  1303. (my--org-roam-list-notes-by-tag "roamtodo"))
  1304. (setq org-agenda-files (delete-dups org-agenda-files)))
  1305. (add-hook 'find-file-hook #'my--roamtodo-update-tag)
  1306. (add-hook 'before-save-hook #'my--roamtodo-update-tag)
  1307. (advice-add 'org-agenda :before #'my/org-roam-refresh-agenda-list)
  1308. (advice-add 'org-todo-list :before #'my/org-roam-refresh-agenda-list)
  1309. (add-to-list 'org-tags-exclude-from-inheritance "roamtodo")
  1310. :config
  1311. (require 'org-roam-dailies) ;; ensure the keymap is available
  1312. (org-roam-db-autosync-mode)
  1313. ;; build the agenda list the first ime for the session
  1314. (my/org-roam-refresh-agenda-list)
  1315. :custom
  1316. (org-roam-directory MY--PATH_ORG_ROAM)
  1317. (org-roam-completion-everywhere t)
  1318. (org-roam-capture-templates
  1319. '(("n" "note" plain
  1320. "%?"
  1321. :if-new (file+head "notes/%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n")
  1322. :unnarrowed t)
  1323. ("i" "idea" plain
  1324. "%?"
  1325. :if-new (file+head "ideas/%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n")
  1326. :unnarrowed t)
  1327. ))
  1328. :bind (("C-c n l" . org-roam-buffer-toggle)
  1329. ("C-c n f" . org-roam-node-find)
  1330. ("C-c n i" . org-roam-node-insert)
  1331. :map org-mode-map
  1332. ("C-M-i" . completion-at-point)
  1333. :map org-roam-dailies-map
  1334. ("Y" . org-roam-dailies-capture-yesterday)
  1335. ("T" . org-roam-dailies-capture-tomorrow))
  1336. :bind-keymap
  1337. ("C-c n d" . org-roam-dailies-map))
  1338. (when *sys/windows*
  1339. (use-package emacsql-sqlite3
  1340. :ensure t
  1341. :init
  1342. (setq emacsql-sqlite3-binary "P:/Tools/sqlite/sqlite3.exe"
  1343. exec-path (append exec-path '("P:/Tools/sqlite"))))
  1344. (use-package org-roam
  1345. :requires emacsql-sqlite3
  1346. :init
  1347. :config
  1348. (add-to-list 'org-roam-capture-templates
  1349. '("ß""telephone call" plain
  1350. "*** [%<%Y-%m-%d %H:%M>] ${title}\n :PROPERTIES:\n :ID: %(org-id-uuid)\n:END:\n"
  1351. :target (file+olp "p:/Eigene Dateien/Notizen/phone_calls.org"
  1352. ("2023" "11"))))
  1353. (add-to-list 'org-roam-capture-templates
  1354. '("x" "telephone call" plain
  1355. "%?"
  1356. :target (file+head "telephone/%<%Y%m%d%H%M>-${slug}.org" "#+title: CALL %<%Y-%m-%d %H:%M> ${title}\n")
  1357. :unnarrowed t) t)
  1358. (add-to-list 'org-roam-capture-templates
  1359. '("p" "project" plain
  1360. "%?"
  1361. :target (file+head "projects/${slug}.org" "#+title: ${title}\n#+filetags: :project:\n")
  1362. :unnarrowed t) t)
  1363. (add-to-list 'org-roam-capture-templates
  1364. '("s" "Sicherheitenmeldung" plain
  1365. "*** TODO [#A] Sicherheitenmeldung ${title}\n :PROPERTIES:\n :ID: %(org-id-uuid)\n:END:\n%u\n"
  1366. :target (file+olp "tasks.org" ("Todos" "Sicherheitenmeldungen"))) t)
  1367. (add-to-list 'org-roam-capture-templates
  1368. '("m" "Monatsbericht" plain
  1369. "*** TODO [#A] Monatsbericht ${title}\n :PROPERTIES:\n :ID: %(org-id-uuid)\n:END:\n%u\n"
  1370. :target (file+olp "tasks.org" ("Todos" "Monatsberichte"))) t)
  1371. :custom
  1372. (org-roam-database-connector 'sqlite3)))
  1373. #+END_SRC
  1374. *** TODO Verzeichnis außerhalb roam zum Archivieren (u.a. für erledigte Monatsmeldungen etc.)
  1375. * Programming
  1376. ** Magit / Git
  1377. Little crash course in magit:
  1378. - magit-init to init a git project
  1379. - magit-status (C-x g) to call the status window
  1380. In status buffer:
  1381. - s stage files
  1382. - u unstage files
  1383. - U unstage all files
  1384. - a apply changes to staging
  1385. - c c commit (type commit message, then C-c C-c to commit)
  1386. - b b switch to another branch
  1387. - P u git push
  1388. - F u git pull
  1389. #+BEGIN_SRC emacs-lisp
  1390. (use-package magit
  1391. :ensure t
  1392. ; :pin melpa-stable
  1393. :defer t
  1394. :init
  1395. ; set git-path in work environment
  1396. (if (string-equal user-login-name "POH")
  1397. (setq magit-git-executable "P:/Tools/Git/bin/git.exe")
  1398. )
  1399. :bind (("C-x g" . magit-status)))
  1400. #+END_SRC
  1401. ** COMMENT Eglot (can't do dap-mode, maybe dape?)
  1402. for python pyls (in env: pip install python-language-server) seems to work better than pyright (npm install -g pyright),
  1403. at least pandas couldnt be resolved in pyright
  1404. #+begin_src emacs-lisp
  1405. (use-package eglot
  1406. :ensure t
  1407. :init
  1408. (setq completion-category-overrides '((eglot (styles orderless))))
  1409. :config
  1410. (add-to-list 'eglot-server-programs '(python-mode . ("pyright-langserver" "--stdio")))
  1411. (with-eval-after-load 'eglot
  1412. (load-library "project"))
  1413. :hook
  1414. (python-mode . eglot-ensure)
  1415. :custom
  1416. (eglot-ignored-server-capabilities '(:documentHighlightProvider))
  1417. (eglot-autoshutdown t)
  1418. (eglot-events-buffer-size 0)
  1419. )
  1420. ;; performance stuff if necessary
  1421. ;(fset #'jsonrpc--log-event #'ignore)
  1422. #+end_src
  1423. ** LSP-Mode
  1424. #+begin_src emacs-lisp
  1425. (defun corfu-lsp-setup ()
  1426. (setf (alist-get 'styles (alist-get 'lsp-capf completion-category-defaults))
  1427. '(orderless)))
  1428. (use-package lsp-mode
  1429. :ensure t
  1430. ; :hook
  1431. ; ((python-mode . lsp))
  1432. :custom
  1433. (lsp-completion-provider :none)
  1434. (lsp-enable-suggest-server-download nil)
  1435. :hook
  1436. (lsp-completion-mode #'corfu-lsp-setup))
  1437. ;(use-package lsp-ui
  1438. ; :ensure t
  1439. ; :commands lsp-ui-mode)
  1440. (use-package lsp-pyright
  1441. :ensure t
  1442. :after (python lsp-mode)
  1443. :custom
  1444. (lsp-pyright-multi-root nil)
  1445. :hook
  1446. (python-mode-hook . (lambda ()
  1447. (require 'lsp-pyright) (lsp))))
  1448. #+end_src
  1449. ** flymake
  1450. python in venv: pip install pyflake (or ruff?)
  1451. TODO: if ruff active, sideline stops working
  1452. #+begin_src emacs-lisp
  1453. (setq python-flymake-command '("ruff" "--quiet" "--stdin-filename=stdin" "-"))
  1454. #+end_src
  1455. ** sideline
  1456. show flymake errors on the right of code window
  1457. #+begin_src emacs-lisp
  1458. (use-package sideline
  1459. :ensure t)
  1460. (use-package sideline-flymake
  1461. :ensure t
  1462. :requires sideline
  1463. :hook
  1464. (flymake-mode . sideline-mode)
  1465. :init
  1466. (setq sideline-flymake-display-mode 'line ; 'point or 'line
  1467. ; sideline-backends-left '(sideline-lsp)
  1468. sideline-backends-right '(sideline-flymake)))
  1469. #+end_src
  1470. ** yasnippet
  1471. For useful snippet either install yasnippet-snippets or get them from here
  1472. [[https://github.com/AndreaCrotti/yasnippet-snippets][Github]]
  1473. #+begin_src emacs-lisp
  1474. (use-package yasnippet
  1475. :ensure t
  1476. :defer t
  1477. :diminish yas-minor-mode
  1478. :config
  1479. (setq yas-snippet-dirs (list (concat MY--PATH_USER_GLOBAL "snippets")))
  1480. (yas-global-mode t)
  1481. (yas-reload-all)
  1482. (unbind-key "TAB" yas-minor-mode-map)
  1483. (unbind-key "<tab>" yas-minor-mode-map))
  1484. #+end_src
  1485. ** hippie expand
  1486. With hippie expand I am able to use yasnippet and emmet at the same time with the same key.
  1487. #+begin_src emacs-lisp
  1488. (use-package hippie-exp
  1489. :elpaca nil
  1490. :defer t
  1491. :bind
  1492. ("C-<return>" . hippie-expand)
  1493. :config
  1494. (setq hippie-expand-try-functions-list
  1495. '(yas-hippie-try-expand emmet-expand-line)))
  1496. #+end_src
  1497. ** COMMENT flycheck (now flymake)
  1498. #+BEGIN_SRC emacs-lisp
  1499. (use-package flycheck
  1500. :ensure t
  1501. :hook
  1502. ((css-mode . flycheck-mode)
  1503. (emacs-lisp-mode . flycheck-mode)
  1504. (python-mode . flycheck-mode))
  1505. :defer 1.0
  1506. :init
  1507. (setq flycheck-emacs-lisp-load-path 'inherit)
  1508. :config
  1509. (setq-default
  1510. flycheck-check-synta-automatically '(save mode-enabled)
  1511. flycheck-disable-checkers '(emacs-lisp-checkdoc)
  1512. eldoc-idle-delay .1 ;; let eldoc echo faster than flycheck
  1513. flycheck-display-errors-delay .3)) ;; this way any errors will override eldoc messages
  1514. #+END_SRC
  1515. ** smartparens
  1516. #+BEGIN_SRC emacs-lisp
  1517. (use-package smartparens
  1518. :ensure t
  1519. :diminish smartparens-mode
  1520. :bind
  1521. (:map smartparens-mode-map
  1522. ("C-M-f" . sp-forward-sexp)
  1523. ("C-M-b" . sp-backward-sexp)
  1524. ("C-M-a" . sp-backward-down-sexp)
  1525. ("C-M-e" . sp-up-sexp)
  1526. ("C-M-w" . sp-copy-sexp)
  1527. ("M-k" . sp-kill-sexp)
  1528. ("C-M-<backspace>" . sp-slice-sexp-killing-backward)
  1529. ("C-S-<backspace>" . sp-slice-sexp-killing-around)
  1530. ("C-]" . sp-select-next-thing-exchange))
  1531. :config
  1532. (setq sp-show-pair-from-inside nil
  1533. sp-escape-quotes-after-insert nil)
  1534. (require 'smartparens-config))
  1535. #+END_SRC
  1536. ** lisp
  1537. #+BEGIN_SRC emacs-lisp
  1538. (use-package elisp-mode
  1539. :elpaca nil
  1540. :defer t)
  1541. #+END_SRC
  1542. ** web
  1543. apt install npm
  1544. sudo npm install -g vscode-html-languageserver-bin
  1545. evtl alternativ typescript-language-server?
  1546. Unter Windows:
  1547. Hier runterladen: https://nodejs.org/dist/latest/
  1548. und in ein Verzeichnis entpacken.
  1549. Optional: PATH erweitern unter Windows (so kann exec-path-from-shell den Pfad ermitteln):
  1550. PATH=P:\path\to\node;%path%
  1551. *** web-mode
  1552. #+BEGIN_SRC emacs-lisp
  1553. (use-package web-mode
  1554. :ensure t
  1555. :defer t
  1556. :mode
  1557. ("\\.phtml\\'"
  1558. "\\.tpl\\.php\\'"
  1559. "\\.djhtml\\'"
  1560. "\\.[t]?html?\\'")
  1561. :hook
  1562. (web-mode . smartparens-mode)
  1563. :init
  1564. (if *work_remote*
  1565. (setq exec-path (append exec-path '("P:/Tools/node"))))
  1566. :config
  1567. (setq web-mode-enable-auto-closing t
  1568. web-mode-enable-auto-pairing t))
  1569. #+END_SRC
  1570. Emmet offers snippets, similar to yasnippet.
  1571. Default completion is C-j
  1572. [[https://github.com/smihica/emmet-mode#usage][Github]]
  1573. #+begin_src emacs-lisp
  1574. (use-package emmet-mode
  1575. :ensure t
  1576. :defer t
  1577. :hook
  1578. ((web-mode . emmet-mode)
  1579. (css-mode . emmet-mode))
  1580. :config
  1581. (unbind-key "C-<return>" emmet-mode-keymap))
  1582. #+end_src
  1583. *** JavaScript
  1584. npm install -g typescript-language-server typescript
  1585. maybe only typescript?
  1586. npm install -g prettier
  1587. #+begin_src emacs-lisp
  1588. (use-package rjsx-mode
  1589. :ensure t
  1590. :mode ("\\.js\\'"
  1591. "\\.jsx'"))
  1592. ; :config
  1593. ; (setq js2-mode-show-parse-errors nil
  1594. ; js2-mode-show-strict-warnings nil
  1595. ; js2-basic-offset 2
  1596. ; js-indent-level 2)
  1597. ; (setq-local flycheck-disabled-checkers (cl-union flycheck-disable-checkers
  1598. ; '(javascript-jshint)))) ; jshint doesn"t work for JSX
  1599. (use-package tide
  1600. :ensure t
  1601. :after (rjsx-mode company flycheck)
  1602. ; :hook (rjsx-mode . setup-tide-mode)
  1603. :config
  1604. (defun setup-tide-mode ()
  1605. "Setup function for tide."
  1606. (interactive)
  1607. (tide-setup)
  1608. (flycheck-mode t)
  1609. (setq flycheck-check-synta-automatically '(save mode-enabled))
  1610. (tide-hl-identifier-mode t)))
  1611. ;; needs npm install -g prettier
  1612. (use-package prettier-js
  1613. :ensure t
  1614. :after (rjsx-mode)
  1615. :defer t
  1616. :diminish prettier-js-mode
  1617. :hook ((js2-mode rsjx-mode) . prettier-js-mode))
  1618. #+end_src
  1619. ** YAML
  1620. #+begin_src emacs-lisp
  1621. (use-package yaml-mode
  1622. :if *sys/linux*
  1623. :ensure t
  1624. :defer t
  1625. :mode ("\\.yml$" . yaml-mode))
  1626. #+end_src
  1627. ** R
  1628. #+BEGIN_SRC emacs-lisp
  1629. (use-package ess
  1630. :ensure t
  1631. :defer t
  1632. :init
  1633. (if *work_remote*
  1634. (setq exec-path (append exec-path '("P:/Tools/R/bin/x64"))
  1635. org-babel-R-command "P:/Tools/R/bin/x64/R --slave --no-save")))
  1636. #+END_SRC
  1637. ** project.el
  1638. #+begin_src emacs-lisp
  1639. (use-package project
  1640. :custom
  1641. (project-vc-extra-root-markers '(".project.el" ".project" )))
  1642. #+end_src
  1643. ** Python
  1644. Preparations:
  1645. - Install language server in *each* projects venv
  1646. source ./bin/activate
  1647. pip install pyright
  1648. - in project root:
  1649. touch .project.el
  1650. echo "((nil . (pyvenv-activate . "/path/to/project/.env")))" >> .dir-locals.el
  1651. für andere language servers
  1652. https://github.com/emacs-lsp/lsp-mode#install-language-server
  1653. TODO if in a project, set venv automatically
  1654. (when-let ((project (project-current))) (project-root project))
  1655. returns project path from project.el
  1656. to recognize a project, either have git or
  1657. place a .project.el file in project root and
  1658. (setq project-vc-extra-root-markers '(".project.el" "..." ))
  1659. #+begin_src emacs-lisp
  1660. (use-package python
  1661. :if *sys/linux*
  1662. :delight "π "
  1663. :defer t
  1664. :bind (("M-[" . python-nav-backward-block)
  1665. ("M-]" . python-nav-forward-block))
  1666. :mode
  1667. (("\\.py\\'" . python-mode)))
  1668. (use-package pyvenv
  1669. ; :if *sys/linux*
  1670. :ensure t
  1671. :defer t
  1672. :after python
  1673. :hook
  1674. (python-mode . pyvenv-mode)
  1675. :custom
  1676. (pyvenv-default-virtual-env-name ".env")
  1677. (pyvenv-mode-line-indicator '(pyvenv-virtual-env-name ("[venv:" pyvenv-virtual-env-name "]"))))
  1678. ;; formatting to pep8
  1679. ;; requires pip install black
  1680. ;(use-package blacken
  1681. ; :ensure t)
  1682. #+end_src
  1683. TODO python mode hook:
  1684. - activate venv
  1685. - activate eglot with proper ls
  1686. - activate tree-sitter?
  1687. - have some fallback if activations fail
  1688. * beancount
  1689. ** Installation
  1690. #+BEGIN_SRC shell :tangle no
  1691. sudo su
  1692. cd /opt
  1693. python3 -m venv beancount
  1694. source ./beancount/bin/activate
  1695. pip3 install wheel
  1696. pip3 install beancount
  1697. sleep 100
  1698. echo "shell running!"
  1699. deactivate
  1700. #+END_SRC
  1701. #+begin_src emacs-lisp
  1702. (use-package beancount
  1703. :elpaca nil
  1704. :if *sys/linux*
  1705. :load-path "user-global/elisp/"
  1706. ; :ensure t
  1707. :defer t
  1708. :mode
  1709. ("\\.beancount$" . beancount-mode)
  1710. :hook
  1711. (beancount-mode . my/beancount-company)
  1712. :config
  1713. (defun my/beancount-company ()
  1714. (setq-local completion-at-point-functions #'beancount-completion-at-point))
  1715. (setq beancount-filename-main "/home/marc/Archiv/Finanzen/Transaktionen/transactions.beancount"))
  1716. #+end_src
  1717. +BEGIN_SRC emacs-lisp
  1718. (use-package beancount
  1719. :if *sys/linux*
  1720. :load-path "user-global/elisp"
  1721. ; :ensure t
  1722. :defer t
  1723. :mode
  1724. ("\\.beancount$" . beancount-mode)
  1725. ; :hook
  1726. ; (beancount-mode . my/beancount-company)
  1727. ; :init
  1728. ; (add-hook 'beancount-mode-hook 'company/beancount-mode-hook)
  1729. :config
  1730. (defun my/beancount-company ()
  1731. (setq-local completion-at-point-functions #'beancount-complete-at-point nil t))
  1732. ; (mapcar #'cape-company-to-capf
  1733. ; (list #'company-beancount #'company-dabbrev))))
  1734. (defun my--beancount-companyALT ()
  1735. (set (make-local-variable 'company-backends)
  1736. '(company-beancount)))
  1737. (setq beancount-filename-main "/home/marc/Archiv/Finanzen/Transaktionen/transactions.beancount"))
  1738. +END_SRC
  1739. To support org-babel, check if it can find the symlink to ob-beancount.el
  1740. #+BEGIN_SRC shell :tangle no
  1741. orgpath=`find /home/marc/.emacs.d/elpa/ -type d -name "org-plus*" -print`
  1742. beansym="$orgpath/ob-beancount.el
  1743. bean="/home/marc/Archiv/Programmierprojekte/Lisp/beancount-mode/ob-beancount.el"
  1744. if [ -h "$beansym" ]
  1745. then
  1746. echo "$beansym found"
  1747. elif [ -e "$bean" ]
  1748. then
  1749. echo "creating symlink"
  1750. ln -s "$bean" "$beansym"
  1751. else
  1752. echo "$bean not found, symlink creation aborted"
  1753. fi
  1754. #+END_SRC
  1755. Fava is strongly recommended.
  1756. #+BEGIN_SRC shell :tangle no
  1757. cd /opt
  1758. python3 -m venv fava
  1759. source ./fava/bin/activate
  1760. pip3 install wheel
  1761. pip3 install fava
  1762. deactivate
  1763. #+END_SRC
  1764. Start fava with fava my_file.beancount
  1765. It is accessable on this URL: [[http://127.0.0.1:5000][Fava]]
  1766. Beancount-mode can start fava and open the URL right away.
  1767. * Stuff after everything else
  1768. Set garbage collector to a smaller value to let it kick in faster.
  1769. Maybe a problem on Windows?
  1770. #+begin_src emacs-lisp
  1771. ;(setq gc-cons-threshold (* 2 1000 1000))
  1772. #+end_src
  1773. Rest of early-init.el
  1774. #+begin_src emacs-lisp :tangle early-init.el
  1775. (defconst config-org (expand-file-name "config.org" user-emacs-directory))
  1776. (defconst init-el (expand-file-name "init.el" user-emacs-directory))
  1777. (unless (file-exists-p init-el)
  1778. (require 'org)
  1779. (org-babel-tangle-file config-org init-el))
  1780. #+end_src