3079 lines
92 KiB
Org Mode
3079 lines
92 KiB
Org Mode
#+title: Emacs Configuration
|
|
:preamble:
|
|
#+setupfile: ~/git_repos/dot_files/docs/html_themes/theme-readtheorg.setup
|
|
#+latex_header: \input{/home/andreas/nextcloud/10_documents/99_archive/0000/settings/latex/style}
|
|
#+author: Andreas Zweili
|
|
#+options: todo:t toc:nil
|
|
:end:
|
|
|
|
* Enable Options
|
|
|
|
This example code can be used to wrap a code section to dis-/enable it with a
|
|
variable.
|
|
|
|
#+begin_example
|
|
(when (boundp 'enable-ox-pandoc)
|
|
|
|
)
|
|
#+end_example
|
|
|
|
This file contains all the variables. It gets ignored by git so that the user
|
|
can modify it's content. However it's default state is commited.
|
|
|
|
#+begin_src emacs-lisp
|
|
(load-file "~/.emacs.d/variables.el")
|
|
#+end_src
|
|
|
|
* Detect Environment
|
|
|
|
With these functions its possible to create configuration sections
|
|
which only run on a specific system. The can be used like this:
|
|
|
|
#+begin_example
|
|
(when (is-mac-p)
|
|
(set-face-attribute 'default nil :height 165))
|
|
|
|
|
|
(add-hook 'after-make-frame-functions
|
|
(lambda ()
|
|
(if window-system
|
|
|
|
)))
|
|
#+end_example
|
|
|
|
Taken from this configuration:
|
|
|
|
- https://github.com/mwfogleman/.emacs.d/blob/master/michael.org
|
|
|
|
#+begin_src emacs-lisp
|
|
(defun is-mac-p ()
|
|
(eq system-type 'darwin))
|
|
|
|
(defun is-linux-p ()
|
|
(eq system-type 'gnu/linux))
|
|
|
|
(defun is-windows-p ()
|
|
(or (eq system-type 'ms-dos)
|
|
(eq system-type 'windows-nt)
|
|
(eq system-type 'cygwin)))
|
|
|
|
(defun is-bsd-p ()
|
|
(eq system-type 'gnu/kfreebsd))
|
|
#+end_src
|
|
|
|
* Packages
|
|
** Repositories
|
|
*** MELPA
|
|
|
|
Melpa is an alternative repository for Emacs packages. Usually they
|
|
are comming directly from a git repository. This can make them
|
|
sometimes a bit unstable.
|
|
|
|
- https://melpa.org/#/
|
|
|
|
#+begin_src emacs-lisp
|
|
;; MELPA
|
|
(add-to-list 'package-archives
|
|
'("melpa" . "https://melpa.org/packages/"))
|
|
#+end_src
|
|
|
|
*** Org-mode
|
|
|
|
Even though org-mode comes with Emacs by default I would like to use
|
|
the newever version from it's repository.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; org-mode
|
|
;(add-to-list 'package-archives '("org" . "https://orgmode.org/elpa/") t)
|
|
#+end_src
|
|
|
|
** use-package
|
|
|
|
Use-package is a very handy package which can automatically download
|
|
specified packages. This helps with reinstalling Emacs. In addition it
|
|
allows you to load the packages and their configuration only when they
|
|
are needed. This helps with Emacs' startup time.
|
|
|
|
#+begin_src emacs-lisp
|
|
(unless (package-installed-p 'use-package)
|
|
(package-refresh-contents)
|
|
(package-install 'use-package))
|
|
(require 'use-package)
|
|
(use-package use-package-ensure-system-package
|
|
:ensure t)
|
|
#+end_src
|
|
|
|
** evil-mode
|
|
|
|
Evil-mode is a package which emulates Vim in Emacs.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; evil-mode allows to use vim keybindings
|
|
(use-package evil
|
|
:ensure t
|
|
:config
|
|
;; Start these modes in emacs mode
|
|
(add-to-list 'evil-emacs-state-modes 'deft-mode)
|
|
(add-to-list 'evil-emacs-state-modes 'neotree-mode)
|
|
(add-to-list 'evil-emacs-state-modes 'helpful-mode)
|
|
(setq global-evil-search-highlight-persist t)
|
|
|
|
;; Start these modes in insert mode
|
|
(evil-set-initial-state 'mu4e-compose-mode 'insert)
|
|
|
|
;; Add vim keybindings to the bookmark menu
|
|
(evil-add-hjkl-bindings bookmark-bmenu-mode-map 'emacs
|
|
;; (kbd "/") 'evil-search-forward
|
|
(kbd "n") 'evil-search-next
|
|
(kbd "N") 'evil-search-previous
|
|
(kbd "C-d") 'evil-scroll-down
|
|
(kbd "C-u") 'evil-scroll-up
|
|
(kbd "C-w C-w") 'other-window)
|
|
|
|
;; Add vim keybindings to the ibuffer
|
|
(evil-add-hjkl-bindings ibuffer-mode-map 'emacs
|
|
;; (kbd "/") 'evil-search-forward
|
|
(kbd "n") 'evil-search-next
|
|
(kbd "N") 'evil-search-previous
|
|
(kbd "C-d") 'evil-scroll-down
|
|
(kbd "C-u") 'evil-scroll-up
|
|
(kbd "C-w C-w") 'other-window)
|
|
|
|
;; Add vim keybindings to the package mode
|
|
(evil-add-hjkl-bindings package-menu-mode-map 'emacs
|
|
;; (kbd "/") 'evil-search-forward
|
|
(kbd "n") 'evil-search-next
|
|
(kbd "N") 'evil-search-previous
|
|
(kbd "C-d") 'evil-scroll-down
|
|
(kbd "C-u") 'evil-scroll-up
|
|
(kbd "C-w C-w") 'other-window)
|
|
|
|
(evil-add-hjkl-bindings helpful-mode-map 'emacs
|
|
;; (kbd "/") 'evil-search-forward
|
|
(kbd "n") 'evil-search-next
|
|
(kbd "N") 'evil-search-previous
|
|
(kbd "C-d") 'evil-scroll-down
|
|
(kbd "C-u") 'evil-scroll-up
|
|
(kbd "C-w C-w") 'other-window)
|
|
|
|
;; vim keybindings for mu4e
|
|
(evil-add-hjkl-bindings mu4e-headers-mode-map 'emacs
|
|
(kbd "/") 'evil-search-forward
|
|
(kbd "n") 'evil-search-next
|
|
(kbd "N") 'evil-search-previous
|
|
(kbd "C-d") 'evil-scroll-down
|
|
(kbd "C-u") 'evil-scroll-up
|
|
(kbd "C-w C-w") 'other-window)
|
|
|
|
(evil-add-hjkl-bindings mu4e-view-mode-map 'emacs
|
|
(kbd "C-d") 'evil-scroll-down
|
|
(kbd "C-u") 'evil-scroll-up
|
|
(kbd "C-w C-w") 'other-window)
|
|
|
|
;; evilificate calendar in org-mode
|
|
(define-key org-read-date-minibuffer-local-map (kbd "M-h")
|
|
(lambda ()
|
|
(interactive) (org-eval-in-calendar '(calendar-backward-day 1))))
|
|
(define-key org-read-date-minibuffer-local-map (kbd "M-l")
|
|
(lambda ()
|
|
(interactive) (org-eval-in-calendar '(calendar-forward-day 1))))
|
|
(define-key org-read-date-minibuffer-local-map (kbd "M-k")
|
|
(lambda ()
|
|
(interactive) (org-eval-in-calendar '(calendar-backward-week 1))))
|
|
(define-key org-read-date-minibuffer-local-map (kbd "M-j")
|
|
(lambda ()
|
|
(interactive) (org-eval-in-calendar '(calendar-forward-week 1))))
|
|
(define-key org-read-date-minibuffer-local-map (kbd "M-H")
|
|
(lambda ()
|
|
(interactive) (org-eval-in-calendar '(calendar-backward-month 1))))
|
|
(define-key org-read-date-minibuffer-local-map (kbd "M-L")
|
|
(lambda ()
|
|
(interactive) (org-eval-in-calendar '(calendar-forward-month 1))))
|
|
(define-key org-read-date-minibuffer-local-map (kbd "M-K")
|
|
(lambda ()
|
|
(interactive) (org-eval-in-calendar '(calendar-backward-year 1))))
|
|
(define-key org-read-date-minibuffer-local-map (kbd "M-J")
|
|
(lambda ()
|
|
(interactive) (org-eval-in-calendar '(calendar-forward-year 1))))
|
|
|
|
(defun az-dired-up-directory ()
|
|
"Take dired up one directory, but behave like dired-find-alternate-file"
|
|
(interactive)
|
|
(let ((old (current-buffer)))
|
|
(dired-up-directory)
|
|
(kill-buffer old)))
|
|
|
|
;; evil keybindings for dired
|
|
(with-eval-after-load 'dired
|
|
(evil-define-key 'normal dired-mode-map "h" 'az-dired-up-directory)
|
|
(evil-define-key 'normal dired-mode-map "l" 'dired-find-alternate-file)
|
|
(evil-define-key 'normal dired-mode-map "o" 'dired-sort-toggle-or-edit)
|
|
(evil-define-key 'normal dired-mode-map "v" 'dired-toggle-marks)
|
|
(evil-define-key 'normal dired-mode-map "m" 'dired-mark)
|
|
(evil-define-key 'normal dired-mode-map "u" 'dired-unmark)
|
|
(evil-define-key 'normal dired-mode-map "U" 'dired-unmark-all-marks)
|
|
(evil-define-key 'normal dired-mode-map "c" 'dired-create-directory)
|
|
(evil-define-key 'normal dired-mode-map "n" 'evil-search-next)
|
|
(evil-define-key 'normal dired-mode-map "N" 'evil-search-previous))
|
|
|
|
;; evil keybindings for window movement
|
|
(global-set-key (kbd "M-h") 'windmove-left)
|
|
(global-set-key (kbd "M-l") 'windmove-right)
|
|
(global-set-key (kbd "M-k") 'windmove-up)
|
|
(global-set-key (kbd "M-j") 'windmove-down)
|
|
|
|
(evil-mode 1))
|
|
#+end_src
|
|
|
|
*** esc quits everything
|
|
|
|
Comming from Vim it's a bit annoying to not be able to use ESC to quit
|
|
basically everything. This code fixes this.
|
|
|
|
#+begin_src emacs-lisp
|
|
;;; esc quits
|
|
(defun minibuffer-keyboard-quit ()
|
|
"Abort recursive edit.
|
|
In Delete Selection mode, if the mark is active, just deactivate it;
|
|
then it takes a second \\[keyboard-quit] to abort the minibuffer."
|
|
(interactive)
|
|
(if (and delete-selection-mode transient-mark-mode mark-active)
|
|
(setq deactivate-mark t)
|
|
(when (get-buffer "*Completions*")
|
|
(delete-windows-on "*Completions*"))
|
|
(abort-recursive-edit)))
|
|
(define-key evil-normal-state-map [escape] 'keyboard-quit)
|
|
(define-key evil-visual-state-map [escape] 'keyboard-quit)
|
|
(define-key minibuffer-local-map [escape] 'minibuffer-keyboard-quit)
|
|
(define-key minibuffer-local-ns-map [escape] 'minibuffer-keyboard-quit)
|
|
(define-key minibuffer-local-completion-map [escape] 'minibuffer-keyboard-quit)
|
|
(define-key minibuffer-local-must-match-map [escape] 'minibuffer-keyboard-quit)
|
|
(define-key minibuffer-local-isearch-map [escape] 'minibuffer-keyboard-quit)
|
|
#+end_src
|
|
|
|
*** evil-surround
|
|
|
|
evil-surround emulates the vim-surround plugin for vim. Both plugins
|
|
allow you to surround objects with an input of your choice. E.g.
|
|
surround a word with ~"~. Which would be: ~ysiw"~
|
|
|
|
- https://github.com/emacs-evil/evil-surround/blob/master/readme.org
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package evil-surround
|
|
:ensure t
|
|
:after evil
|
|
:config
|
|
(global-evil-surround-mode 1))
|
|
#+end_src
|
|
|
|
** UI
|
|
|
|
Various packages related to UI changes.
|
|
|
|
*** color-theme
|
|
|
|
This settings provides the color-theme package and sets a color-theme
|
|
which I store in my sourec directory as the current theme.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; Color theme
|
|
;; disable background in terminal
|
|
(defun on-after-init ()
|
|
(unless (display-graphic-p (selected-frame))
|
|
(set-face-background 'default "unspecified-bg" (selected-frame))))
|
|
|
|
(add-hook 'window-setup-hook 'on-after-init)
|
|
|
|
(when (boundp 'enable-color-theme)
|
|
;; load solarized color theme
|
|
(use-package solarized-theme
|
|
:ensure t
|
|
:config
|
|
(setq solarized-use-variable-pitch nil)
|
|
(setq solarized-scale-org-headlines nil)
|
|
(setq solarized-high-contrast-mode-line t)
|
|
(set-face-inverse-video 'region nil)
|
|
(load-theme 'solarized-light t)))
|
|
#+end_src
|
|
|
|
** smooth-scrolling
|
|
|
|
I can't recall what this package does exactly, however it has to do
|
|
with scrolling in comparison to Vim.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; smooth scrolling
|
|
(use-package smooth-scrolling
|
|
:ensure t
|
|
:config
|
|
(setq scroll-margin 1
|
|
scroll-conservatively 9999
|
|
scroll-step 1))
|
|
#+end_src
|
|
|
|
** Various Tools
|
|
*** deft
|
|
|
|
Deft is a mode which lets you quickly search and create notes. It
|
|
works similarly to Notational Velocity. I configured it to use org
|
|
files and open org-mode to edit. In addition it should search in all
|
|
my org files. I search through all my org files and open deft with
|
|
~F5~.
|
|
|
|
- https://github.com/jrblevin/deft
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package deft
|
|
:ensure t
|
|
:bind ("<f5>" . deft)
|
|
:commands (deft)
|
|
:config
|
|
(setq deft-extensions '("md")
|
|
deft-default-extension "md"
|
|
deft-auto-save-interval 300.0
|
|
deft-use-filename-as-title nil
|
|
deft-use-filter-string-for-filename t
|
|
deft-recursive t)
|
|
(setq deft-file-naming-rules
|
|
'((noslash . "-")
|
|
(nospace . "_")
|
|
(case-fn . downcase)))
|
|
(setq deft-directory "~/nextcloud/10_documents/"))
|
|
#+end_src
|
|
|
|
*** dash
|
|
|
|
Is required by many packages. I've added it specifically because it's
|
|
required by the org-insert-image function.
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package dash
|
|
:defer t
|
|
:ensure t)
|
|
#+end_src
|
|
|
|
*** swiper
|
|
|
|
Another dependency for the org-insert-image function.
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package swiper
|
|
:defer t
|
|
:ensure t)
|
|
#+end_src
|
|
|
|
*** s
|
|
|
|
The last depency for the org-insert-image function.
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package s
|
|
:defer t
|
|
:ensure t)
|
|
#+end_src
|
|
|
|
*** pdf-tools
|
|
|
|
pdf-tools is an alternativ for doc-view which works very nicely with
|
|
AUCTex.
|
|
https://github.com/politza/pdf-tools/blob/master/README.org
|
|
The config line is required so that a AUCTex compiled PDF gets updated
|
|
after each compilation.
|
|
|
|
#+begin_src emacs-lisp
|
|
(when (boundp 'enable-pdf-tools)
|
|
(use-package pdf-tools
|
|
:ensure t
|
|
:mode ("\\.pdf\\'" . pdf-view-mode)
|
|
:config
|
|
(pdf-tools-install)
|
|
(setq-default pdf-view-display-size 'fit-page)
|
|
;; turn off cua so copy works
|
|
(add-hook 'pdf-view-mode-hook (lambda () (cua-mode 0)))
|
|
;; keyboard shortcuts
|
|
(define-key pdf-view-mode-map (kbd "C-w C-w") 'other-window)
|
|
(define-key pdf-view-mode-map (kbd "j") 'pdf-view-next-page-command)
|
|
(define-key pdf-view-mode-map (kbd "k") 'pdf-view-previous-page-command)
|
|
(define-key pdf-view-mode-map (kbd "h") 'pdf-annot-add-highlight-markup-annotation)
|
|
(define-key pdf-view-mode-map (kbd "t") 'pdf-annot-add-text-annotation)
|
|
(define-key pdf-view-mode-map (kbd "D") 'pdf-annot-delete)
|
|
(add-hook 'TeX-after-compilation-finished-functions #'TeX-revert-document-buffer)))
|
|
#+end_src
|
|
|
|
*** treemacs
|
|
|
|
Treemacs is a tool which display a file explorer in a little buffer on
|
|
the side of your main buffer. This is very useful if you're working on
|
|
a project which consists of multiple files. It even understands some
|
|
files and can display their sections (org-mode), or classes (python).
|
|
|
|
- https://github.com/Alexander-Miller/treemacs
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package treemacs
|
|
:ensure t
|
|
:bind ("<f12>" . treemacs)
|
|
:config
|
|
(progn
|
|
(use-package treemacs-evil
|
|
:ensure t
|
|
:demand t)))
|
|
#+end_src
|
|
|
|
*** yasnippet
|
|
|
|
Yasnippet is a package with which you can insert code or text snippets
|
|
based on templates. It already comes with a wide variety of snippets
|
|
and you can easily define your own.
|
|
|
|
- https://github.com/joaotavora/yasnippet
|
|
|
|
#+begin_src emacs-lisp
|
|
;; enable yasnippet
|
|
(use-package yasnippet
|
|
:ensure t
|
|
:config
|
|
(yas-global-mode 1))
|
|
#+end_src
|
|
|
|
**** yasnippet-snippets
|
|
|
|
The default snippets got moved into their seperate package. I'm
|
|
loading it after the main yasnippet package.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; enable yasnippet
|
|
(use-package yasnippet-snippets
|
|
:ensure t
|
|
:after yasnippet
|
|
:config
|
|
(yas-global-mode 1))
|
|
#+end_src
|
|
|
|
**** org-mode snippets
|
|
|
|
| key | function |
|
|
|-----------+-----------------------------------------|
|
|
| img_ | insert an html snippet for images |
|
|
|-----------+-----------------------------------------|
|
|
| pic_ | inserts a snippet for latex images |
|
|
|-----------+-----------------------------------------|
|
|
| orgtemp | inserts a template for org files |
|
|
|-----------+-----------------------------------------|
|
|
| orgrev | template for org-reveal |
|
|
|-----------+-----------------------------------------|
|
|
| orgbeamer | template for beamer presentations |
|
|
|-----------+-----------------------------------------|
|
|
| clk | template for a clock report |
|
|
|-----------+-----------------------------------------|
|
|
| orgconf | template for config files writen in org |
|
|
|-----------+-----------------------------------------|
|
|
| _project | inserts a section for a new project |
|
|
|-----------+-----------------------------------------|
|
|
|
|
*** which-key
|
|
|
|
Displays a small buffer which shows all the possible key combinations
|
|
you can press at the current moment.
|
|
|
|
- https://github.com/justbur/emacs-which-key
|
|
|
|
#+begin_src emacs-lisp
|
|
;; which key is a package to show which keys can be pressed
|
|
(use-package which-key
|
|
:ensure t
|
|
:diminish which-key-mode
|
|
:config
|
|
(which-key-mode))
|
|
#+end_src
|
|
|
|
*** discover-my-major
|
|
|
|
discover-my-major is a package which shows you all the keybindings
|
|
related to the current major mode. While you can get this information
|
|
with the ~C-h m~ keybindings it's a bit easier to view in this mode.
|
|
|
|
- https://github.com/steckerhalter/discover-my-major
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package discover-my-major
|
|
:ensure t
|
|
:bind ("C-h C-m" . discover-my-major))
|
|
#+end_src
|
|
|
|
*** langtool
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(when (boundp 'enable-langtool)
|
|
(use-package langtool
|
|
:ensure t
|
|
:defer t
|
|
:config
|
|
(setq langtool-language-tool-jar "~/.emacs.d/languagetool/languagetool-commandline.jar")))
|
|
#+END_SRC
|
|
|
|
*** hydra
|
|
|
|
This code has been taken from this post:
|
|
https://sam217pa.github.io/2016/09/23/keybindings-strategies-in-emacs/
|
|
I should read it again to get a better understanding of hydra and general.
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package hydra
|
|
:ensure t)
|
|
|
|
(defhydra hydra-buffer (:color red :columns 3)
|
|
"
|
|
Buffers :
|
|
"
|
|
("n" next-buffer "next")
|
|
("b" ivy-switch-buffer "switch")
|
|
("B" ibuffer "ibuffer")
|
|
("p" previous-buffer "prev")
|
|
("C-b" buffer-menu "buffer menu")
|
|
("N" evil-buffer-new "new")
|
|
("d" kill-this-buffer "delete")
|
|
;; don't come back to previous buffer after delete
|
|
("D" (progn (kill-this-buffer) (next-buffer)) "Delete")
|
|
("s" save-buffer "save"))
|
|
|
|
(defhydra hydra-window-operations (:color red :columns 3)
|
|
"
|
|
Windows :
|
|
"
|
|
("h" windmove-left "left")
|
|
("l" windmove-right "right")
|
|
("j" windmove-down "down")
|
|
("k" windmove-up "up")
|
|
("w" (lambda () (interactive) (other-window 1)) "Unkown")
|
|
("h" split-window-vertically "horizontal split")
|
|
("v" split-window-horizontally "vertical split")
|
|
("o" delete-other-windows "Delete all other")
|
|
("X" delete-window "Delete this")
|
|
("x" (lambda ()
|
|
(interactive)
|
|
(ace-window 16)
|
|
(add-hook 'ace-window-end-once-hook
|
|
'hydra-window/body)) "Unknown")
|
|
("z" (lambda ()
|
|
(interactive)
|
|
(ace-window 4)
|
|
(add-hook 'ace-window-end-once-hook
|
|
'hydra-window/body)) "Swap")
|
|
("=" balance-windows "Balance")
|
|
("K" kill-this-buffer "Kill Buffer")
|
|
("D" kill-all-dired-buffers "Kill all dired")
|
|
("a" ace-window "Ace")
|
|
("S" toggle-window-split "Toggle Split"))
|
|
|
|
;https://www.reddit.com/r/emacs/comments/931la6/tip_how_to_adopt_flycheck_as_your_new_best_friend/
|
|
(defhydra hydra-flycheck (:color blue)
|
|
"
|
|
^
|
|
^Flycheck^ ^Errors^ ^Checker^
|
|
^────────^──────────^──────^────────────^───────^─────
|
|
_q_ quit _<_ previous _?_ describe
|
|
_M_ manual _>_ next _d_ disable
|
|
_v_ verify setup _f_ check _m_ mode
|
|
^^ _l_ list _s_ select
|
|
^^ ^^ ^^
|
|
"
|
|
("q" nil)
|
|
("<" flycheck-previous-error :color pink)
|
|
(">" flycheck-next-error :color pink)
|
|
("?" flycheck-describe-checker)
|
|
("M" flycheck-manual)
|
|
("d" flycheck-disable-checker)
|
|
("f" flycheck-buffer)
|
|
("l" flycheck-list-errors)
|
|
("m" flycheck-mode)
|
|
("s" flycheck-select-checker)
|
|
("v" flycheck-verify-setup))
|
|
|
|
(defhydra hydra-ediff (:color blue :columns 3)
|
|
"
|
|
Ediff :
|
|
"
|
|
("b" ediff-buffers "buffers")
|
|
("B" ediff-buffers3 "buffers 3-way")
|
|
("f" ediff-files "files")
|
|
("F" ediff-files3 "files 3-way")
|
|
("c" ediff-current-file "current file")
|
|
("r" ediff-revision "revision")
|
|
("l" ediff-regions-linewise "linewise")
|
|
("w" ediff-regions-wordwise "wordwise"))
|
|
|
|
(defhydra hydra-yasnippet (:color blue :columns 3)
|
|
"
|
|
Yasnippet:
|
|
"
|
|
("d" yas-load-directory "directory")
|
|
("e" yas-activate-extra-mode "extra")
|
|
("i" yas-insert-snippet "insert")
|
|
("f" yas-visit-snippet-file "file")
|
|
("n" yas-new-snippet "new")
|
|
("t" yas-tryout-snippet "tryout")
|
|
("l" yas-describe-tables "list")
|
|
("a" yas-reload-all "reload"))
|
|
|
|
(defhydra hydra-apropos (:color blue :columns 3)
|
|
"Apropos"
|
|
("a" apropos "apropos")
|
|
("c" apropos-command "cmd")
|
|
("d" apropos-documentation "doc")
|
|
("e" apropos-value "val")
|
|
("l" apropos-library "lib")
|
|
("o" apropos-user-option "option")
|
|
("v" apropos-variable "var")
|
|
("i" info-apropos "info")
|
|
("t" tags-apropos "tags")
|
|
("z" hydra-customize-apropos/body "customize"))
|
|
|
|
(defhydra hydra-customize-apropos (:color blue :columns 3)
|
|
"Apropos (customize)"
|
|
("a" customize-apropos "apropos")
|
|
("f" customize-apropos-faces "faces")
|
|
("g" customize-apropos-groups "groups")
|
|
("o" customize-apropos-options "options"))
|
|
|
|
(define-key Info-mode-map (kbd "?") #'hydra-info/body)
|
|
(defhydra hydra-info (:color blue
|
|
:hint nil)
|
|
"
|
|
Info-mode:
|
|
|
|
^^_]_ forward (next logical node) ^^_l_ast (←) _u_p (↑) _f_ollow reference _T_OC
|
|
^^_[_ backward (prev logical node) ^^_r_eturn (→) _m_enu (↓) (C-u for new window) _i_ndex _d_irectory
|
|
^^_n_ext (same level only) ^^_H_istory _g_oto (C-u for new window) _,_ next index item _c_opy node name
|
|
^^_p_rev (same level only) _<_/_t_op _b_eginning of buffer virtual _I_ndex _C_lone buffer
|
|
regex _s_earch (_S_ case sensitive) ^^_>_ final _e_nd of buffer ^^ _a_propos
|
|
|
|
_1_ .. _9_ Pick first .. ninth item in the node's menu.
|
|
|
|
"
|
|
("]" Info-forward-node)
|
|
("[" Info-backward-node)
|
|
("n" Info-next)
|
|
("p" Info-prev)
|
|
("s" Info-search)
|
|
("S" Info-search-case-sensitively)
|
|
|
|
("l" Info-history-back)
|
|
("r" Info-history-forward)
|
|
("H" Info-history)
|
|
("t" Info-top-node)
|
|
("<" Info-top-node)
|
|
(">" Info-final-node)
|
|
|
|
("u" Info-up)
|
|
("^" Info-up)
|
|
("m" Info-menu)
|
|
("g" Info-goto-node)
|
|
("b" beginning-of-buffer)
|
|
("e" end-of-buffer)
|
|
|
|
("f" Info-follow-reference)
|
|
("i" Info-index)
|
|
("," Info-index-next)
|
|
("I" Info-virtual-index)
|
|
|
|
("T" Info-toc)
|
|
("d" Info-directory)
|
|
("c" Info-copy-current-node-name)
|
|
("C" clone-buffer)
|
|
("a" info-apropos)
|
|
|
|
("1" Info-nth-menu-item)
|
|
("2" Info-nth-menu-item)
|
|
("3" Info-nth-menu-item)
|
|
("4" Info-nth-menu-item)
|
|
("5" Info-nth-menu-item)
|
|
("6" Info-nth-menu-item)
|
|
("7" Info-nth-menu-item)
|
|
("8" Info-nth-menu-item)
|
|
("9" Info-nth-menu-item)
|
|
|
|
("?" Info-summary "Info summary")
|
|
("h" Info-help "Info help"))
|
|
|
|
(defhydra hydra-spellchecking (:color blue :columns 3)
|
|
"
|
|
Spell Checking
|
|
"
|
|
("g" langtool-check "Check grammar")
|
|
("q" langtool-check-done "Finish grammar check")
|
|
("l" langtool-switch-default-language "Switch grammar language")
|
|
("m" langtool-show-message-at-point "unkown")
|
|
("b" langtool-correct-buffer "Correct grammar in buffer")
|
|
("s" ispell "Correct Spelling")
|
|
("d" ispell-change-dictionary "Change dictionary"))
|
|
|
|
;(define-key dired-mode-map (kbd "'") #'hydra-dired/body)
|
|
;https://github.com/abo-abo/hydra/wiki/Dired
|
|
(defhydra hydra-dired (:hint nil :color pink)
|
|
"
|
|
_+_ mkdir _v_iew _m_ark _(_ details _i_nsert-subdir wdired
|
|
_C_opy _O_ view other _U_nmark all _)_ omit-mode _$_ hide-subdir C-x C-q : edit
|
|
_D_elete _o_pen other _u_nmark _l_ redisplay _w_ kill-subdir C-c C-c : commit
|
|
_R_ename _M_ chmod _t_oggle _g_ revert buf _e_ ediff C-c ESC : abort
|
|
_Y_ rel symlink _G_ chgrp _E_xtension mark _s_ort _=_ pdiff
|
|
_S_ymlink ^ ^ _F_ind marked _._ toggle hydra \\ flyspell
|
|
_r_sync ^ ^ ^ ^ ^ ^ _?_ summary
|
|
_z_ compress-file _A_ find regexp
|
|
_Z_ compress _Q_ repl regexp
|
|
|
|
T - tag prefix
|
|
"
|
|
("\\" dired-do-ispell)
|
|
("(" dired-hide-details-mode)
|
|
(")" dired-omit-mode)
|
|
("+" dired-create-directory)
|
|
("=" diredp-ediff) ;; smart diff
|
|
("?" dired-summary)
|
|
("$" diredp-hide-subdir-nomove)
|
|
("A" dired-do-find-regexp)
|
|
("C" dired-do-copy) ;; Copy all marked files
|
|
("D" dired-do-delete)
|
|
("E" dired-mark-extension)
|
|
("e" dired-ediff-files)
|
|
("F" dired-do-find-marked-files)
|
|
("G" dired-do-chgrp)
|
|
("g" revert-buffer) ;; read all directories again (refresh)
|
|
("i" dired-maybe-insert-subdir)
|
|
("l" dired-do-redisplay) ;; relist the marked or singel directory
|
|
("M" dired-do-chmod)
|
|
("m" dired-mark)
|
|
("O" dired-display-file)
|
|
("o" dired-find-file-other-window)
|
|
("Q" dired-do-find-regexp-and-replace)
|
|
("R" dired-do-rename)
|
|
("r" dired-do-rsynch)
|
|
("S" dired-do-symlink)
|
|
("s" dired-sort-toggle-or-edit)
|
|
("t" dired-toggle-marks)
|
|
("U" dired-unmark-all-marks)
|
|
("u" dired-unmark)
|
|
("v" dired-view-file) ;; q to exit, s to search, = gets line #
|
|
("w" dired-kill-subdir)
|
|
("Y" dired-do-relsymlink)
|
|
("z" diredp-compress-this-file)
|
|
("Z" dired-do-compress)
|
|
("q" nil)
|
|
("." nil :color blue))
|
|
|
|
;https://github.com/abo-abo/hydra/wiki/PDF-Tools
|
|
(defhydra hydra-pdftools (:color blue :hint nil)
|
|
"
|
|
╭───────────┐
|
|
Move History Scale/Fit Annotations Search/Link Do │ PDF Tools │
|
|
╭──────────────────────────────────────────────────────────────────┴───────────╯
|
|
^^_g_^^ _B_ ^↧^ _+_ ^ ^ [_al_] list [_s_] search [_u_] revert buffer
|
|
^^^↑^^^ ^↑^ _H_ ^↑^ ↦ _W_ ↤ [_am_] markup [_o_] outline [_i_] info
|
|
^^_p_^^ ^ ^ ^↥^ _0_ ^ ^ [_at_] text [_F_] link [_d_] dark mode
|
|
^^^↑^^^ ^↓^ ╭─^─^─┐ ^↓^ ╭─^ ^─┐ [_ad_] delete [_f_] search link
|
|
_h_ ←pag_e_→ _l_ _N_ │ _P_ │ _-_ _b_ [_aa_] dired
|
|
^^^↓^^^ ^ ^ ╰─^─^─╯ ^ ^ ╰─^ ^─╯ [_y_] yank
|
|
^^_n_^^ ^ ^ _r_eset slice box
|
|
^^^↓^^^
|
|
^^_G_^^
|
|
--------------------------------------------------------------------------------
|
|
"
|
|
("\\" hydra-master/body "back")
|
|
("<ESC>" nil "quit")
|
|
("al" pdf-annot-list-annotations)
|
|
("ad" pdf-annot-delete)
|
|
("aa" pdf-annot-attachment-dired)
|
|
("am" pdf-annot-add-markup-annotation)
|
|
("at" pdf-annot-add-text-annotation)
|
|
("y" pdf-view-kill-ring-save)
|
|
("+" pdf-view-enlarge :color red)
|
|
("-" pdf-view-shrink :color red)
|
|
("0" pdf-view-scale-reset)
|
|
("H" pdf-view-fit-height-to-window)
|
|
("W" pdf-view-fit-width-to-window)
|
|
("P" pdf-view-fit-page-to-window)
|
|
("n" pdf-view-next-page-command :color red)
|
|
("p" pdf-view-previous-page-command :color red)
|
|
("d" pdf-view-dark-minor-mode)
|
|
("b" pdf-view-set-slice-from-bounding-box)
|
|
("r" pdf-view-reset-slice)
|
|
("g" pdf-view-first-page)
|
|
("G" pdf-view-last-page)
|
|
("e" pdf-view-goto-page)
|
|
("o" pdf-outline)
|
|
("s" pdf-occur)
|
|
("i" pdf-misc-display-metadata)
|
|
("u" pdf-view-revert-buffer)
|
|
("F" pdf-links-action-perfom)
|
|
("f" pdf-links-isearch-link)
|
|
("B" pdf-history-backward :color red)
|
|
("N" pdf-history-forward :color red)
|
|
("l" image-forward-hscroll :color red)
|
|
("h" image-backward-hscroll :color red))
|
|
|
|
(defhydra hydra-elpy (:color red)
|
|
"
|
|
Navigate errors
|
|
"
|
|
("n" next-error "next error")
|
|
("p" previous-error "previous error")
|
|
("d" (progn (call-interactively 'elpy-test-django-runner) (elpy-nav-errors/body)) "current test, Django runner" :color blue)
|
|
("t" (progn (call-interactively 'elpy-test-pytest-runner) (elpy-nav-errors/body)) "current test, pytest runner" :color blue)
|
|
("s" (progn
|
|
(switch-to-buffer-other-window "*compilation*")
|
|
(goto-char (point-max))) "switch to compilation buffer" :color blue)
|
|
("w" (venv-workon) "Workon venv…")
|
|
("q" nil "quit")
|
|
("Q" (kill-buffer "*compilation*") "quit and kill compilation buffer" :color blue)
|
|
)
|
|
#+end_src
|
|
|
|
*** NEXT general-define-key
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package general
|
|
:ensure t
|
|
:config
|
|
(general-def
|
|
:states '(normal visual insert emacs)
|
|
:prefix "SPC"
|
|
:non-normal-prefix "M-SPC"
|
|
"b" '(hydra-buffer/body t :which-key "Buffer")
|
|
"w" '(hydra-window-operations/body t :which-key "Windows")
|
|
"r" '(hydra-restclient/body t :which-key "Restclient")
|
|
"f" '(hydra-flycheck/body t :which-key "Flycheck")
|
|
"s" '(hydra-spellchecking/body t :which-key "Spell Checking")
|
|
"e" '(hydra-ediff/body t :which-key "Diffing")
|
|
"i" '(hydra-yasnippet/body t :which-key "Yasnippets")
|
|
"p" '(hydra-pdftools/body t :which-key "PDF Tools")
|
|
"y" '(hydra-elpy/body t :which-key "Elpy")
|
|
"a" '(hydra-apropos/body t :which-key "Apropos Commands")))
|
|
#+end_src
|
|
|
|
*** helpful
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(use-package helpful
|
|
:ensure t
|
|
:bind (("C-h f" . helpful-function)
|
|
("C-h v" . helpful-variable)
|
|
("C-h s" . helpful-symbol)
|
|
("C-h k" . helpful-key)
|
|
("C-c h f" . helpful-function)
|
|
("C-c h v" . helpful-variable)
|
|
("C-c h c" . helpful-command)
|
|
("C-c h m" . helpful-macro)
|
|
("<C-tab>" . backward-button)
|
|
:map helpful-mode-map
|
|
("M-?" . helpful-at-point)
|
|
:map emacs-lisp-mode-map
|
|
("M-?" . helpful-at-point)
|
|
:map lisp-interaction-mode-map ; Scratch buffer
|
|
("M-?" . helpful-at-point)))
|
|
#+END_SRC
|
|
|
|
*** ivy/swiper/counsel
|
|
|
|
This packages provide a much better experience in the minibuffer.
|
|
http://oremacs.com/swiper/
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(use-package amx
|
|
:ensure t
|
|
:config
|
|
(amx-mode t))
|
|
(use-package counsel
|
|
:ensure t
|
|
:config
|
|
(ivy-mode 1)
|
|
(counsel-mode 1)
|
|
(setq ivy-use-virtual-buffers t)
|
|
(setq ivy-count-format "(%d/%d) ")
|
|
(setq ivy-initial-inputs-alist nil)
|
|
(with-eval-after-load 'org
|
|
(define-key org-mode-map (kbd "C-c C-q") #'counsel-org-tag))
|
|
(global-set-key (kbd "C-c v") 'ivy-push-view)
|
|
(global-set-key (kbd "C-c V") 'ivy-pop-view)
|
|
;; (global-set-key (kbd "C-s") 'swiper-isearch)
|
|
(evil-define-key 'normal 'global "/" 'swiper-isearch)
|
|
(global-set-key (kbd "C-c g") 'counsel-git)
|
|
(global-set-key (kbd "C-c j") 'counsel-git-grep)
|
|
(global-set-key (kbd "C-c k") 'counsel-ag)
|
|
(define-key ivy-minibuffer-map (kbd "S-SPC") (lambda () (interactive) (insert " ")))
|
|
(global-set-key (kbd "C-c C-r") 'ivy-resume))
|
|
#+END_SRC
|
|
|
|
*** eyebrowse
|
|
|
|
The eyebrowse package is a very helpful package which gives you workspaces in
|
|
Emacs. The work very similar to the desktops in i3wm.
|
|
https://github.com/wasamasa/eyebrowse
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(use-package eyebrowse
|
|
:ensure t
|
|
:init
|
|
(setq eyebrowse-keymap-prefix (kbd "C-c M-e"))
|
|
(global-unset-key (kbd "C-c C-w"))
|
|
(define-key evil-normal-state-map "gt" 'eyebrowse-next-window-config)
|
|
(define-key evil-normal-state-map "gT" 'eyebrowse-prev-window-config)
|
|
(define-key evil-normal-state-map "gr" 'eyebrowse-rename-window-config)
|
|
(define-key evil-normal-state-map "gc" 'eyebrowse-close-window-config)
|
|
:config
|
|
(setq eyebrowse-new-workspace t)
|
|
(setq eyebrowse-switch-back-and-forth t)
|
|
(setq eyebrowse-wrap-around t)
|
|
(eyebrowse-setup-opinionated-keys)
|
|
(eyebrowse-mode 1))
|
|
#+END_SRC
|
|
|
|
*** move-text
|
|
|
|
https://github.com/emacsfodder/move-text
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package move-text
|
|
:ensure t
|
|
:config
|
|
(move-text-default-bindings))
|
|
#+end_src
|
|
|
|
*** gnu-elpa-keyring-update
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package gnu-elpa-keyring-update
|
|
:ensure t)
|
|
#+end_src
|
|
|
|
** Language Support
|
|
|
|
The following package provide an improved support for their
|
|
corresponding language.
|
|
|
|
*** web-mode
|
|
|
|
#+begin_src emacs-lisp
|
|
;; web-mode for general web development
|
|
(use-package web-mode
|
|
:ensure t
|
|
:mode
|
|
(("\\.phtml\\'" . web-mode)
|
|
("\\.tpl\\'" . web-mode)
|
|
("\\.[agj]sp\\'" . web-mode)
|
|
("\\.as[cp]x\\'" . web-mode)
|
|
("\\.erb\\'" . web-mode)
|
|
("\\.mustache\\'" . web-mode)
|
|
("\\.djhtml\\'" . web-mode)
|
|
("\\.html?\\'" . web-mode))
|
|
:config
|
|
(add-to-list 'auto-mode-alist '("\\.php$" . my/php-setup))
|
|
(add-to-list 'auto-mode-alist '("\\.phpi$" . my/php-setup)))
|
|
#+end_src
|
|
|
|
*** markdown-mode
|
|
|
|
Provides syntax highlighting and other functions for markdown.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; add markdown-mode to edit markdown files
|
|
(use-package markdown-mode
|
|
:ensure t
|
|
:commands (markdown-mode gfm-mode)
|
|
:mode (("README\\.md\\'" . gfm-mode)
|
|
("\\.md\\'" . markdown-mode)
|
|
("\\.markdown\\'" . markdown-mode))
|
|
:init (setq markdown-command "multimarkdown"))
|
|
#+end_src
|
|
|
|
*** powershell
|
|
|
|
Provides syntax highlighting and other functions for powershell
|
|
scripts.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; enable powershell-mode
|
|
(use-package powershell
|
|
:ensure t
|
|
:mode
|
|
(("\\.ps1\\'" . powershell-mode)
|
|
("\\.psm1\\'" . powershell-mode)))
|
|
#+end_src
|
|
|
|
*** auctex
|
|
|
|
Auctex is a great package which helps you a lot when you're writing
|
|
LaTeX documents.
|
|
|
|
#+begin_src emacs-lisp
|
|
(when (boundp 'enable-auctex)
|
|
;; auctex a greate plugin for latex writing
|
|
(use-package latex
|
|
:if (is-linux-p)
|
|
:ensure auctex
|
|
:mode ("\\.tex\\'" . latex-mode)
|
|
:ensure-system-package
|
|
(pdflatex . texlive-full)
|
|
:config
|
|
(setq-default TeX-master nil)
|
|
(setq TeX-auto-save t)
|
|
(setq TeX-parse-self t)
|
|
(setq TeX-electric-math (quote ("\\(" . "\\)")))
|
|
(setq LaTeX-electric-left-right-brace t)
|
|
(setq TeX-view-program-selection
|
|
(quote
|
|
(((output-dvi has-no-display-manager)
|
|
"dvi2tty")
|
|
((output-dvi style-pstricks)
|
|
"dvips and gv")
|
|
(output-dvi "xdvi")
|
|
(output-pdf "PDF Tools")
|
|
(output-html "xdg-open"))))))
|
|
#+end_src
|
|
|
|
*** yaml-mode
|
|
|
|
A mode to work with yaml files.
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package yaml-mode
|
|
:defer t
|
|
:mode
|
|
(("\\.yml\\'" . yaml-mode)
|
|
("\\.yaml\\'" . yaml-mode))
|
|
:interpreter ("yml" . yml-mode)
|
|
:ensure t)
|
|
#+end_src
|
|
|
|
*** python-mode
|
|
|
|
While Emacs comes by default with python-mode installed. I want to use
|
|
the updated version from Melpa.
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package python-mode
|
|
:ensure t
|
|
:defer t
|
|
:config
|
|
(setq python-shell-interpreter "python3"))
|
|
#+end_src
|
|
|
|
*** elpy
|
|
|
|
elpy is a package which helps you greatly with writing Python code. It
|
|
provides all the things you would wish from an IDE.
|
|
|
|
- https://github.com/jorgenschaefer/elpy
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package elpy
|
|
:ensure t
|
|
:config
|
|
(setq elpy-rpc-python-command "python3")
|
|
(setq elpy-test-runner 'elpy-test-pytest-runner)
|
|
(setq eldoc-idle-delay 1)
|
|
(add-hook 'python-mode-hook (lambda () (highlight-indentation-mode -1)))
|
|
(elpy-enable))
|
|
#+end_src
|
|
|
|
** Coding Tools
|
|
|
|
*** company-mode
|
|
|
|
company-mode is a package to provide auto-complete functionality.
|
|
|
|
- https://company-mode.github.io/
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package company
|
|
:ensure t
|
|
:bind
|
|
("C-<tab>" . company-complete)
|
|
:config
|
|
(setq company-idle-delay 0)
|
|
(define-key company-active-map (kbd "TAB") 'company-complete-common-or-cycle)
|
|
(define-key company-active-map (kbd "<tab>") 'company-complete-common-or-cycle)
|
|
(setq company-dabbrev-downcase nil)
|
|
(add-hook 'after-init-hook 'global-company-mode)
|
|
|
|
;; Add yasnippet support for all company backends
|
|
(defvar company-mode/enable-yas t
|
|
"Enable yasnippet for all backends.")
|
|
(defun company-mode/backend-with-yas (backend)
|
|
(if (or (not company-mode/enable-yas) (and (listp backend) (member 'company-yasnippet backend)))
|
|
backend
|
|
(append (if (consp backend) backend (list backend))
|
|
'(:with company-yasnippet))))
|
|
(setq company-backends (mapcar #'company-mode/backend-with-yas company-backends)))
|
|
#+end_src
|
|
|
|
**** company-auctex
|
|
|
|
Auctex support for company-mode.
|
|
- https://github.com/alexeyr/company-auctex/
|
|
|
|
#+begin_src emacs-lisp
|
|
(when (boundp 'enable-auctex)
|
|
(use-package company-auctex
|
|
:if (is-linux-p)
|
|
:ensure t
|
|
:after auctex
|
|
:defer t
|
|
:init
|
|
(add-hook 'LaTeX-mode-hook 'company-auctex-init)))
|
|
#+end_src
|
|
|
|
**** company-web
|
|
|
|
https://github.com/dakra/dmacs/blob/master/init.org
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(use-package company-web
|
|
:ensure t
|
|
:after web-mode
|
|
:commands company-web-html
|
|
:config
|
|
(require 'company-web-html)
|
|
|
|
;; Tide completion support in web-mode with company-mode
|
|
(defun my-web-mode-hook ()
|
|
"Hook for `web-mode'."
|
|
(set (make-local-variable 'company-backends)
|
|
'(company-tide company-web-html company-yasnippet company-files)))
|
|
|
|
(add-hook 'web-mode-hook 'my-web-mode-hook)
|
|
|
|
;; Enable JavaScript completion between <script>...</script> etc.
|
|
(defadvice company-tide (before web-mode-set-up-ac-sources activate)
|
|
"Set `tide-mode' based on current language before running company-tide."
|
|
(if (equal major-mode 'web-mode)
|
|
(let ((web-mode-cur-language
|
|
(web-mode-language-at-pos)))
|
|
(if (or (string= web-mode-cur-language "javascript")
|
|
(string= web-mode-cur-language "jsx"))
|
|
(unless tide-mode (tide-mode))
|
|
(if tide-mode (tide-mode -1)))))))
|
|
#+END_SRC
|
|
|
|
**** company-restclient
|
|
|
|
https://github.com/dakra/dmacs/blob/master/init.org
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(use-package company-restclient
|
|
:ensure t
|
|
:after (restclient company)
|
|
:config (add-to-list 'company-backends 'company-restclient))
|
|
#+END_SRC
|
|
|
|
*** magit
|
|
|
|
Magit is a package which allows you to control git from within Emacs.
|
|
It's really great and makes using git so much easier. Thanks to Magit
|
|
alone I think I became a much better git user.
|
|
|
|
- https://magit.vc/
|
|
|
|
#+begin_src emacs-lisp
|
|
;; enable magit a great git porcelain.
|
|
(use-package magit
|
|
:ensure t
|
|
:commands magit-status
|
|
:bind
|
|
("<f10>" . magit-status))
|
|
#+end_src
|
|
|
|
*** rainbow-delimiters
|
|
|
|
Each level of parantheses has it's own colour to differentiate them
|
|
more easily.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; change the colours of parenthesis the further out they are
|
|
(use-package rainbow-delimiters
|
|
:ensure t
|
|
:config
|
|
(add-hook 'prog-mode-hook #'rainbow-delimiters-mode))
|
|
#+end_src
|
|
|
|
*** elisp-bug-hunter
|
|
|
|
This package let's you debug your Emacs config which makes it easier
|
|
to find bugs before you restart Emacs.
|
|
|
|
https://github.com/Malabarba/elisp-bug-hunter/blob/master/README.org
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package bug-hunter
|
|
:defer t
|
|
:ensure t)
|
|
#+end_src
|
|
|
|
*** flycheck
|
|
|
|
flycheck is a handy tool to provide syntax checking on the fly.
|
|
|
|
- http://www.flycheck.org/en/latest/
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package flycheck
|
|
:ensure t)
|
|
#+end_src
|
|
|
|
*** highlight-indent-guides
|
|
|
|
This mode shows lines to display the current level of indentation. I've enabled
|
|
it in text- and prog-modes.
|
|
https://github.com/DarthFennec/highlight-indent-guides
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(use-package highlight-indent-guides
|
|
:ensure t
|
|
:config
|
|
(setq highlight-indent-guides-method 'character
|
|
hightlight-indentation-mode nil
|
|
highlight-indent-guides-auto-enabled nil)
|
|
(set-face-background 'highlight-indent-guides-odd-face "darkgray")
|
|
(set-face-background 'highlight-indent-guides-even-face "gray")
|
|
(set-face-foreground 'highlight-indent-guides-character-face "gray")
|
|
(add-hook 'text-mode-hook 'highlight-indent-guides-mode)
|
|
(add-hook 'prog-mode-hook 'highlight-indent-guides-mode))
|
|
#+END_SRC
|
|
|
|
*** direnv
|
|
|
|
Enable direnv support.
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package direnv
|
|
:config
|
|
(direnv-mode))
|
|
#+end_src
|
|
|
|
*** format-all
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package format-all
|
|
:ensure t
|
|
:hook
|
|
((prog-mode . format-all-ensure-formatter)
|
|
(yaml-mode . format-all-ensure-formatter)
|
|
(prog-mode . format-all-mode))
|
|
:preface
|
|
(defun nebucatnetzer/format-code ()
|
|
"format buffer."
|
|
(interactive)
|
|
(format-all-buffer))
|
|
:config
|
|
(global-set-key (kbd "C-c C-f") #'nebucatnetzer/format-code)
|
|
(setq format-all-show-errors 'errors))
|
|
#+end_src
|
|
* Email
|
|
|
|
Requires the following packages to be installed:
|
|
|
|
#+BEGIN_EXAMPLE
|
|
offlineimap mu4e w3m
|
|
#+END_EXAMPLE
|
|
|
|
After a fresh installation you have to first sync your emails with ~offlineimap
|
|
|
|
-o~. Afterwards run ~mu index --maildir=~/Maildir~.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(when (boundp 'enable-email)
|
|
(use-package mu4e
|
|
:if (is-linux-p)
|
|
:config
|
|
(require 'smtpmail)
|
|
|
|
;; use msmtp
|
|
(setq message-send-mail-function 'message-send-mail-with-sendmail)
|
|
(setq sendmail-program "msmtp")
|
|
|
|
(require 'mu4e)
|
|
(require 'org-mu4e)
|
|
|
|
(setq mu4e-completing-read-function (quote ivy-completing-read))
|
|
(setq mail-user-agent 'mu4e-user-agent)
|
|
|
|
(setq mu4e-drafts-folder "/personal/Drafts")
|
|
(setq mu4e-sent-folder "/personal/Sent")
|
|
(setq mu4e-trash-folder "/personal/Trash")
|
|
(setq mu4e-refile-folder "/personal/Archive")
|
|
|
|
(setq browse-url-browser-function 'browse-url-generic
|
|
browse-url-generic-program "firefox")
|
|
|
|
(require 'mu4e-contrib)
|
|
(setq mu4e-html2text-command 'mu4e-shr2text)
|
|
(add-to-list 'mu4e-view-actions
|
|
'("ViewInBrowser" . mu4e-action-view-in-browser) t)
|
|
|
|
(setq mu4e-headers-fields
|
|
'((:date . 10) ;; alternatively, use :human-date
|
|
(:flags . 5)
|
|
(:from . 22)
|
|
(:subject . nil))) ;; alternatively, use :thread-subject
|
|
|
|
(setq mu4e-get-mail-command "offlineimap -qo"
|
|
mu4e-update-interval 120
|
|
mu4e-headers-auto-update t
|
|
mu4e-compose-format-flowed t
|
|
mu4e-index-update-in-background t
|
|
mu4e-compose-dont-reply-to-self t
|
|
mu4e-attachment-dir "~/nextcloud/10_documents/01_inbox"
|
|
mu4e-compose-signature-auto-include nil)
|
|
|
|
(add-hook 'mu4e-view-mode-hook 'visual-line-mode)
|
|
|
|
(setq mu4e-maildir-shortcuts
|
|
'(("/personal/INBOX" . ?i)
|
|
("/personal/Sent" . ?s)
|
|
("/personal/Trash" . ?t)
|
|
("/personal/Archive" . ?a)
|
|
("/personal/Drafts" . ?d)))
|
|
|
|
;; show images
|
|
(setq mu4e-show-images t)
|
|
|
|
;; general emacs mail settings; used when composing e-mail
|
|
;; the non-mu4e-* stuff is inherited from emacs/message-mode
|
|
(setq mu4e-reply-to-address "andreas@zweili.ch")
|
|
|
|
(setq message-kill-buffer-on-exit t)
|
|
;; Don't ask for a 'context' upon opening mu4e
|
|
(setq mu4e-context-policy 'pick-first)
|
|
;; Don't ask to quit
|
|
(setq mu4e-confirm-quit nil)
|
|
|
|
;; spell check
|
|
(add-hook 'mu4e-compose-mode-hook
|
|
(defun my-do-compose-stuff ()
|
|
"My settings for message composition."
|
|
(setq mu4e-compose-format-flowed t)
|
|
(use-hard-newlines -1)
|
|
(turn-off-auto-fill)
|
|
(flyspell-mode)))))
|
|
#+END_SRC
|
|
|
|
* UI Changes
|
|
|
|
** Hide the menu and toolbar
|
|
|
|
I like to work in a distraction free editor that's why I hide all the
|
|
menues, toolbars and scrollbars.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; disable menu and toolbar
|
|
(tool-bar-mode -1)
|
|
(menu-bar-mode -99)
|
|
(when (boundp 'enable-scroll-bar)
|
|
(scroll-bar-mode -1))
|
|
#+end_src
|
|
|
|
** Line wrapping
|
|
|
|
By default Emacs doesn't do line wrapping. Instead it shows you on the
|
|
edge of the buffer a marker to indicate that the line continues
|
|
further. I'm not really a fan of this behaviour, that's why I disable
|
|
it and enable proper line wrapping.
|
|
|
|
*** enable line wrapping
|
|
|
|
#+begin_src emacs-lisp
|
|
; Proper line wrapping
|
|
(global-visual-line-mode 1)
|
|
#+end_src
|
|
|
|
*** disable fringe mode
|
|
|
|
fringe-mode are the little markers on the side of the buffer which
|
|
show when a line continues over the edge. Since I use visual-line-mode
|
|
this settings isn't required anymore.
|
|
|
|
#+begin_src emacs-lisp
|
|
(when (boundp 'disable-fringe)
|
|
; Disable fringe because I use visual-line-mode
|
|
(set-fringe-mode '(0 . 0)))
|
|
#+end_src
|
|
|
|
** Disable the splash screen
|
|
|
|
Emacs usually displays a splash screen with some helpful information
|
|
for beginners. I don't really need that anymore.
|
|
|
|
#+begin_src emacs-lisp
|
|
; Disable splash screen
|
|
(setq inhibit-splash-screen t)
|
|
#+end_src
|
|
|
|
** Disable tooltips
|
|
|
|
Can't remember how they look like but I've disabled them
|
|
probably for a reason :).
|
|
|
|
#+begin_src emacs-lisp
|
|
(tooltip-mode -1)
|
|
(setq tooltip-use-echo-area t)
|
|
#+end_src
|
|
|
|
** Prompts
|
|
*** Y and N are enough
|
|
|
|
I don't want to type the whole word. The starting characters should be
|
|
enough.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; disable or reconfigure prompts
|
|
(fset 'yes-or-no-p 'y-or-n-p) ;; remap yes or no to y or n
|
|
#+end_src
|
|
|
|
*** Don't prompt on buffer creation
|
|
|
|
"Yes I'm sure that I want to create a new buffer.", options.
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq confirm-nonexistent-file-or-buffer nil);; just create buffers don't ask
|
|
(setq ido-create-new-buffer 'always)
|
|
#+end_src
|
|
|
|
** Hightlight whitespace
|
|
|
|
This options shows you where you accidentally left some bad
|
|
whitespace.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; highlight bad whitespace
|
|
(use-package whitespace
|
|
:ensure t
|
|
:config
|
|
(setq whitespace-style '(face lines-tail tabs trailing))
|
|
(set-face-attribute 'whitespace-line nil :foreground "#af005f")
|
|
(global-whitespace-mode t))
|
|
#+end_src
|
|
|
|
** Font
|
|
|
|
Set the font to the nice Source Code Pro. I think it works quite well for coding
|
|
as well as writing text.
|
|
|
|
#+begin_src emacs-lisp
|
|
(when (boundp 'enable-font)
|
|
(set-face-attribute 'default nil
|
|
:family "Source Code Pro"
|
|
:height 120
|
|
:weight 'normal
|
|
:width 'normal))
|
|
#+end_src
|
|
|
|
** Doc-view resolution
|
|
|
|
By default the doc-view looks a bit fuzzy. With a resolution of 200
|
|
it's much more comfortable to read a PDF.
|
|
|
|
#+begin_src emacs-lisp
|
|
(when (boundp 'enable-pdf-tools)
|
|
;; improve the resolution of doc-view
|
|
(setq doc-view-resolution 200))
|
|
#+end_src
|
|
|
|
** Start Emacs maximized
|
|
|
|
I always want to run Emacs maximized. The easiest solution to this problem
|
|
is the following code. The downside of this is, that if Emacs is already
|
|
maximized it will switch to windowed mode.
|
|
|
|
#+begin_src emacs-lisp
|
|
(toggle-frame-maximized)
|
|
#+end_src
|
|
|
|
** mode-line settings
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq-default mode-line-format
|
|
'("%e"
|
|
mode-line-front-space
|
|
;; mode-line-mule-info
|
|
mode-line-client
|
|
mode-line-modified
|
|
mode-line-remote
|
|
mode-line-frame-identification
|
|
mode-line-buffer-identification
|
|
" "
|
|
mode-line-position
|
|
(vc-mode vc-mode)
|
|
;; " "
|
|
;; mode-line-modes
|
|
" "
|
|
mode-line-misc-info
|
|
;; battery-mode-line-string
|
|
;; mode-line-end-spaces
|
|
))
|
|
#+end_src
|
|
|
|
** display line numbers
|
|
|
|
Since I'm an evil user I would like to display the line numbers relativ to the
|
|
cursor position and only show the line numbers for the visible content.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(setq display-line-numbers-type 'visual)
|
|
(add-hook 'prog-mode-hook (lambda ()
|
|
(when (version<= "26.0.50" emacs-version )
|
|
(display-line-numbers-mode))))
|
|
#+END_SRC
|
|
|
|
** inhibit-compacting-font-caches
|
|
|
|
Should improve performance a bit when working with org-mode and in general
|
|
|
|
#+begin_src elisp
|
|
(setq inhibit-compacting-font-caches t)
|
|
#+end_src
|
|
|
|
* Org-mode
|
|
*Please be aware that the whole org-mode configuration is one code block.*
|
|
*While I've splitted it here for a better understanding it needs to be used*
|
|
*in it's entirety or it won't work.*
|
|
|
|
** Additional Packages
|
|
*** org-superstar
|
|
|
|
Provides prettier bullets for org-mode headings.
|
|
https://github.com/integral-dw/org-superstar-mode
|
|
|
|
#+begin_src emacs-lisp
|
|
(when (boundp 'enable-org-bullets)
|
|
;; Enable pretty bullets in org mode
|
|
(use-package org-superstar
|
|
:ensure t
|
|
:config
|
|
(add-hook 'org-mode-hook (lambda ()
|
|
(org-superstar-mode 1)))))
|
|
#+end_src
|
|
|
|
*** htmlize
|
|
|
|
This package is needed to export the current agenda view to a HTML file.
|
|
The command to do so is ~C-x C-w~.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; add a package to convert the agenda view to HTML
|
|
(use-package htmlize
|
|
:ensure t
|
|
:after org)
|
|
#+end_src
|
|
|
|
*** org-man
|
|
|
|
Allows to link to man pages in an org-mode file. This can be quite
|
|
useful for taking notes about a Unix system. The code is taken from here:
|
|
https://orgmode.org/manual/Adding-hyperlink-types.html
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(when (is-linux-p)
|
|
;;; org-man.el - Support for links to manpages in Org
|
|
|
|
(org-add-link-type "man" 'org-man-open)
|
|
(add-hook 'org-store-link-functions 'org-man-store-link)
|
|
|
|
(defcustom org-man-command 'man
|
|
"The Emacs command to be used to display a man page."
|
|
:group 'org-link
|
|
:type '(choice (const man) (const woman)))
|
|
|
|
(defun org-man-open (path)
|
|
"Visit the manpage on PATH.
|
|
PATH should be a topic that can be thrown at the man command."
|
|
(funcall org-man-command path))
|
|
|
|
(defun org-man-store-link ()
|
|
"Store a link to a manpage."
|
|
(when (memq major-mode '(Man-mode woman-mode))
|
|
;; This is a man page, we do make this link
|
|
(let* ((page (org-man-get-page-name))
|
|
(link (concat "man:" page))
|
|
(description (format "Manpage for %s" page)))
|
|
(org-store-link-props
|
|
:type "man"
|
|
:link link
|
|
:description description))))
|
|
|
|
(defun org-man-get-page-name ()
|
|
"Extract the page name from the buffer name."
|
|
;; This works for both `Man-mode' and `woman-mode'.
|
|
(if (string-match " \\(\\S-+\\)\\*" (buffer-name))
|
|
(match-string 1 (buffer-name))
|
|
(error "Cannot create link to this man page")))
|
|
|
|
(provide 'org-man)
|
|
|
|
;;; org-man.el ends here
|
|
(require 'org-man))
|
|
#+END_SRC
|
|
|
|
*** org-ref
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(use-package org-ref
|
|
:ensure t
|
|
:after org
|
|
:init
|
|
(setq org-ref-completion-library 'org-ref-ivy-cite)
|
|
:config
|
|
(setq org-ref-default-citation-link "footcite")
|
|
(setq reftex-default-bibliography '("~/nextcloud/03_documents/org/notes/_resources/references.bib"))
|
|
(setq org-ref-bibliography-notes "~/nextcloud/03_documents/org/notes/bibliography_notes.org"
|
|
org-ref-default-bibliography '("~/nextcloud/03_documents/org/notes/_resources/references.bib")
|
|
org-ref-pdf-directory "~/nextcloud/03_documents/org/notes/_resources/"))
|
|
#+END_SRC
|
|
|
|
*** org-pandoc
|
|
|
|
Provides pandoc support for org-mode.
|
|
https://github.com/kawabata/ox-pandoc
|
|
|
|
#+begin_src emacs-lisp
|
|
(when (boundp 'enable-ox-pandoc)
|
|
(use-package ox-pandoc
|
|
:ensure t
|
|
:after org))
|
|
#+end_src
|
|
|
|
** General config
|
|
*** Enable org-mode
|
|
|
|
This settings make sure the org-mode is downloaded from the org
|
|
repository.
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package org
|
|
:ensure t
|
|
:pin gnu
|
|
:config
|
|
#+end_src
|
|
|
|
*** Main keybindings
|
|
|
|
This defines org-modes main keybindings which are:
|
|
|
|
- Open the agenda ~C-c a~
|
|
- Capture a task ~C-c c~
|
|
- Switch org buffer ~C-c b~
|
|
|
|
#+begin_src emacs-lisp
|
|
;; enable org-mode keys
|
|
(when (or (boundp 'enable-personal-agenda)
|
|
(boundp 'enable-work-agenda))
|
|
(define-key global-map "\C-ca" 'org-agenda))
|
|
|
|
(global-set-key "\C-cl" 'org-store-link)
|
|
(global-set-key "\C-cc" 'org-capture)
|
|
(global-set-key "\C-cb" 'org-iswitchb)
|
|
|
|
;; evil keybindings for the org-agenda
|
|
(evil-add-hjkl-bindings org-agenda-mode-map 'emacs
|
|
;;(kbd "/") 'evil-search-forward
|
|
(kbd "n") 'evil-search-next
|
|
(kbd "N") 'evil-search-previous
|
|
(kbd "C-d") 'evil-scroll-down
|
|
(kbd "C-u") 'evil-scroll-up
|
|
(kbd "c") 'org-capture
|
|
(kbd "C-w C-w") 'other-window)
|
|
#+end_src
|
|
|
|
*** Disable line split
|
|
|
|
By default the command ~M-RET~ enters a new heading which
|
|
splits the current line at the cursor position.
|
|
This can get very annoying at times that's why I disable
|
|
this behaviour.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; disable line split with M-RET
|
|
(setq org-M-RET-may-split-line (quote ((default))))
|
|
#+end_src
|
|
|
|
*** Correct indentation in code blocks
|
|
|
|
Indentation in source code blocks should match the
|
|
corresponding language in the code block.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; enable the correct intdentation for source code blocks
|
|
(setq org-edit-src-content-indentation 0)
|
|
(setq org-src-tab-acts-natively t)
|
|
(setq org-src-preserve-indentation t)
|
|
#+end_src
|
|
|
|
*** Archive location
|
|
|
|
I've configured the archive function so that when I archive a tasks it
|
|
gets archived into an archive folder and put into a monthly file.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; archive files to a monthly file
|
|
(when (boundp 'enable-personal-agenda)
|
|
(when (is-linux-p)
|
|
(setq org-archive-location
|
|
(concat "~/nextcloud/10_documents/99_archive/2022/projects/"
|
|
(format-time-string "%Y-%m" (current-time)) "-%s::datetree/"))))
|
|
(when (boundp 'enable-work-agenda)
|
|
(when (is-windows-p)
|
|
(setq org-archive-location
|
|
(concat "~/nextcloud/03_documents/org/archive/work/"
|
|
(format-time-string "%Y-%m" (current-time)) "-%s::datetree/"))))
|
|
#+end_src
|
|
|
|
*** Todo depencies
|
|
|
|
This settings only lets you close a parent task if you closed all it's
|
|
parents.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; enable todo and checkbox depencies
|
|
(setq org-enforce-todo-dependencies t)
|
|
(setq org-enforce-todo-checkbox-dependencies t)
|
|
#+end_src
|
|
|
|
*** Workflow states
|
|
|
|
This configuration defines the TODO and DONE keywords one can use for headings.
|
|
*TODO keywords*
|
|
- TODO
|
|
- NEXT
|
|
- WAITING
|
|
*DONE keywords*
|
|
- DONE
|
|
- CANCELLED
|
|
|
|
If you want to change the TODO states of a heading you have to toggle
|
|
through all of them which can be quite annoying if you want to use a
|
|
state which is somewhere at the end of the list. With this setting
|
|
Emacs shows you the complete list and you can select the corresponding
|
|
key to apply your desired TODO state.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; quick access for todo states
|
|
(setq org-todo-keywords
|
|
'((sequence "TODO(t)" "NEXT(n)" "WAITING(w!)" "PROJECT(p)" "|" "DONE(d)")
|
|
(sequence "|" "CANCELLED(c)")))
|
|
#+end_src
|
|
|
|
*** Log workflow states
|
|
|
|
In order to keep track when I finished a tasks I would like to have a
|
|
timestamp which records this information for me.
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq org-log-done 'time)
|
|
#+end_src
|
|
|
|
In addition I would like to record when I set a WAITING state for a task. This
|
|
way I know when I started waiting. This allows me for example to get back to a
|
|
person if I haven't back from them for two weeks.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(setq org-log-into-drawer t)
|
|
#+END_SRC
|
|
|
|
*** Cleaner outline view
|
|
|
|
This option replaces the heading stars with indents.
|
|
Which makes the outline more readable and gives a better overview.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; enable org-indent
|
|
(setq org-startup-indented t)
|
|
#+end_src
|
|
|
|
*** Capture templates
|
|
|
|
Capture templates are templates with which you can predefine tasks/projects.
|
|
Each template gets it's own keybinding which you can call from ~C-c c~.
|
|
|
|
Since I'm required to report my working hours at my job I've added
|
|
some clocking functionality to my work related capture templates. The
|
|
one I like the most ist the daily clock. This adds an entry with the
|
|
current date as a heading and starts a clock on it. This makes it very
|
|
easy to start the clock at the beginning of the day.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; capture templates
|
|
(defun my/org-capture-read-file-name ()
|
|
(concat (expand-file-name (read-file-name "PROMPT: " "~/nextcloud/12_tasks/")) ".org"))
|
|
|
|
(when (boundp 'enable-personal-agenda)
|
|
(when (is-linux-p)
|
|
(setq org-capture-templates
|
|
(quote
|
|
(("t" "Adds a Next entry" entry
|
|
(file+headline "~/nextcloud/12_tasks/personal.org" "Capture")
|
|
(file "~/nextcloud/10_documents/99_archive/0000/settings/templates/temp_personal_todo.txt")
|
|
:empty-lines 1)
|
|
("n" "Add note" plain (file my/org-capture-read-file-name)
|
|
(file "~/nextcloud/10_documents/99_archive/0000/settings/templates/temp_note.txt"))
|
|
)))))
|
|
|
|
(when (boundp 'enable-work-agenda)
|
|
(when (is-windows-p)
|
|
(setq org-capture-templates
|
|
(quote
|
|
(("j" "Journal Entry" entry
|
|
(file+headline "~/nextcloud/03_documents/org/agenda/work/work.org" "Clock")
|
|
(file "~/nextcloud/10_documents/99_archive/0000/settings/templates/temp_clock_note.txt")
|
|
:empty-lines 1)
|
|
("c" "Phone call" entry (file+headline "~/nextcloud/03_documents/org/agenda/work/work.org" "Clock")
|
|
"* %U PHONE %?" :clock-in t :clock-resume t)
|
|
("t" "Adds a Next entry" entry
|
|
(file+headline "~/nextcloud/03_documents/org/agenda/work/work.org" "Capture")
|
|
(file "~/nextcloud/10_documents/99_archive/0000/settings/templates/temp_work_todo.txt")
|
|
:clock-in t :clock-resume t)
|
|
("p" "Small Project" entry
|
|
(file+headline "~/nextcloud/03_documents/org/agenda/work/work.org" "Capture")
|
|
(file "~/nextcloud/10_documents/99_archive/0000/settings/templates/temp_work_small_project.txt"))
|
|
("m" "Meeting" entry (file+headline "~/nextcloud/03_documents/org/agenda/work/work.org" "Capture")
|
|
"* %U MEETING: with %?\n" :clock-in t :clock-resume t :empty-lines 1)
|
|
("n" "Add note" plain (file my/org-capture-read-file-name)
|
|
(file "~/nextcloud/10_documents/99_archive/0000/settings/templates/temp_note.txt"))
|
|
)))))
|
|
#+end_src
|
|
|
|
*** Columns format
|
|
|
|
Adjust the format of the org-columns.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; org-columns format
|
|
(setq org-columns-default-format
|
|
"%40ITEM(Task) %8Effort(Estimated Effort){:} %8CLOCKSUM %10TAGS")
|
|
#+end_src
|
|
|
|
*** Efforts
|
|
|
|
Configuration of the available effort times.
|
|
You can set efforts with ~C-c C-x e~.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; available effort times
|
|
(setq org-global-properties
|
|
(quote
|
|
(("Effort_ALL" . "0 0:10 0:30 1:00 2:00 3:00 4:00 5:00 6:00 7:00"))))
|
|
#+end_src
|
|
|
|
*** Refile options
|
|
|
|
The refile option lets you move headings to other headings or into
|
|
different files. I configured org-mode so that it allows to create
|
|
parent headings and looks 6 levels deep for headings to file under.
|
|
In addition I changed the way the refile menu works. It's a bit slower
|
|
this way but gives in my opinion a better overview.
|
|
|
|
The implementation of ~nebucatnetzer-org-files-list~ has been found here:
|
|
https://emacs.stackexchange.com/questions/22128/how-to-org-refile-to-a-target-within-the-current-file
|
|
|
|
#+begin_src emacs-lisp
|
|
;; org-refile options
|
|
(setq org-refile-allow-creating-parent-nodes (quote confirm))
|
|
(setq org-refile-use-outline-path 'file
|
|
org-outline-path-complete-in-steps nil)
|
|
|
|
(defun nebucatnetzer-org-files-list ()
|
|
(delq nil
|
|
(mapcar (lambda (buffer)
|
|
(buffer-file-name buffer))
|
|
(org-buffer-list 'files t))))
|
|
|
|
(setq org-refile-targets '((nebucatnetzer-org-files-list :maxlevel . 6)))
|
|
#+end_src
|
|
|
|
*** Syntax highlighting in code blocks
|
|
|
|
By default syntax highlighting is not enabled for code blocks however
|
|
it's very nice to have that's why I enabled it.
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq org-src-fontify-natively t)
|
|
#+end_src
|
|
|
|
*** Syntax highlighting for latex code
|
|
|
|
To make latex code in org-mode stand out a bit more we can enable
|
|
syntax highlighting for it.
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq org-highlight-latex-and-related '(latex))
|
|
#+end_src
|
|
|
|
*** Show inline images
|
|
|
|
I want to display images in org-mode.
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq org-image-actual-width (quote (500)))
|
|
(setq org-startup-with-inline-images t)
|
|
#+end_src
|
|
|
|
*** create custom id for links
|
|
|
|
When creating an internal org link this code creates a unique ID to
|
|
the heading. This allows the links to continue working even when the
|
|
file is in a new location.
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq org-id-link-to-org-use-id 'create-if-interactive-and-no-custom-id
|
|
org-clone-delete-id t)
|
|
#+end_src
|
|
|
|
*** separate headings by an empty line
|
|
|
|
Headings should be separated by their content by an empty line. This
|
|
way the files are easier to read.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(setq org-blank-before-new-entry
|
|
(quote ((heading . t)
|
|
(plain-list-item . auto))))
|
|
#+END_SRC
|
|
|
|
*** Footnotes heading
|
|
|
|
I wan't to use footnotes as references. Therefore I want the footnotes to get
|
|
stored under a heading called ressources.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(setq org-footnote-section "Resources")
|
|
#+END_SRC
|
|
|
|
*** update footnotes
|
|
|
|
After a change to the footnotes in a document org-mode should update the labels.
|
|
|
|
#+BEGIN_SRC emacs-lips
|
|
(setq org-footnote-auto-adjust t)
|
|
#+END_SRC
|
|
|
|
*** org-attach-directory
|
|
|
|
Since all my org-files live in a git directory and I don't want to polute the
|
|
repository with a ton of binary files I save the attachements into a directory
|
|
synchronised by Nextcloud.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(setq org-attach-directory "~/nextcloud/10_documents/99_archive/2022/resources/")
|
|
#+END_SRC
|
|
|
|
*** Faces
|
|
|
|
This section defines how org-mode looks like.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(setq org-todo-keyword-faces
|
|
`(("WAITING" :foreground "#0087ff" :weight bold)
|
|
("TODO" :foreground "#d75f00" :weight bold)
|
|
("PROJECT" :foreground "#626262" :weight bold)
|
|
("NEXT" :foreground "#d70000" :weight bold)))
|
|
|
|
|
|
(set-face-attribute 'org-agenda-structure nil :inherit 'default :height 1.00)
|
|
(set-face-attribute 'org-agenda-date-weekend nil :height 1.00 :weight 'medium)
|
|
(set-face-attribute 'org-agenda-calendar-event nil :weight 'medium)
|
|
(set-face-attribute 'org-agenda-date nil :inherit 'default :height 1.00 :weight 'bold)
|
|
(set-face-attribute 'org-agenda-date-today nil :slant 'normal :weight 'bold :height 1.00)
|
|
(set-face-attribute 'org-done nil :foreground "#5f8700" :weight 'bold)
|
|
(set-face-attribute 'org-link nil :foreground "#0087ff" :underline t)
|
|
(set-face-attribute 'org-scheduled nil :foreground "#5f8700" :slant 'italic :weight 'normal)
|
|
(set-face-attribute 'org-scheduled-previously nil :foreground "#d70000" :weight 'normal)
|
|
(set-face-attribute 'org-scheduled-today nil :foreground "#5f8700" :slant 'italic :weight 'normal)
|
|
(set-face-attribute 'org-todo nil :background "nil" :foreground "#d70000" :weight 'bold)
|
|
(set-face-attribute 'org-upcoming-deadline nil :foreground "#d70000" :weight 'normal)
|
|
(set-face-attribute 'org-warning nil :foreground "#d70000" :weight 'normal)
|
|
#+END_SRC
|
|
|
|
*** org-startup-shrink-all-tables
|
|
|
|
Org-mode should display all tables in shrinked mode if the table contains a
|
|
width cookie.
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq org-startup-shrink-all-tables t)
|
|
#+end_src
|
|
|
|
** Exports
|
|
|
|
*** TODO Export formats
|
|
|
|
This is currently not working correctly that's why I customized
|
|
it through org-customize.
|
|
Configures the available export formats.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; org-export formats
|
|
;;(setq org-export-backends (quote (beamer html latex md odt reveal)))
|
|
#+end_src
|
|
|
|
*** html export doctype
|
|
|
|
Since we live in the 21st century org-mode should use HTML5.
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq org-html-html5-fancy t
|
|
org-html-doctype "html5")
|
|
#+end_src
|
|
|
|
*** Disable TODO keywords
|
|
|
|
Usually I don't want the TODO states being dispayed in the exported files.
|
|
If i still want to have them displayed I can add the option:
|
|
|
|
#+begin_example
|
|
#+options: todo:t
|
|
#+end_example
|
|
|
|
To the beginning of the file.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; disable the Todo keywords in the export
|
|
(setq org-export-with-todo-keywords nil)
|
|
#+end_src
|
|
|
|
*** Disable Tags
|
|
|
|
As with the TODO states I want to disable the tags as well.
|
|
The per file option for this setting is:
|
|
|
|
#+begin_example
|
|
#+options: tags:t
|
|
#+end_example
|
|
|
|
#+begin_src emacs-lisp
|
|
;; disable the tags in the export
|
|
(setq org-export-with-tags nil)
|
|
#+end_src
|
|
|
|
*** Place captions under tables
|
|
|
|
I want captions to appear below tables and not above.
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq org-latex-caption-above nil)
|
|
#+end_src
|
|
|
|
*** Disable susb superscript
|
|
|
|
The default settings export text like ~10^2~ or ~this_file~ as 10^{2}
|
|
and this_{file}. Since I often use underline in filenames and
|
|
variables it's easiert for me to use ~10^{2}~ and ~this_{file}~ to
|
|
achieve this.
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq org-export-with-sub-superscripts nil)
|
|
#+end_src
|
|
|
|
*** Smart quotes
|
|
|
|
Different languages use different types of quotes. With this option
|
|
org-mode tries to be smart about it and export the correct quotes.
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq org-export-with-smart-quotes t)
|
|
#+end_src
|
|
|
|
*** Headline levels
|
|
|
|
By default org-mode exports headings down to level 3 as headings and
|
|
the rest as lists. I want it to export headings down to level 5.
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq org-export-headline-levels 5)
|
|
#+end_src
|
|
|
|
*** Beamer settings
|
|
|
|
This specifies my options for Beamer exports. Level 1 headings
|
|
generate title pages, the table of contents should be called "Inhalt"
|
|
and the theme I'm using is metropolis.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; options for beamer exports
|
|
(setq org-beamer-frame-level 2)
|
|
(setq org-beamer-outline-frame-options "")
|
|
(setq org-beamer-outline-frame-title "Inhalt")
|
|
(setq org-beamer-theme "metropolis")
|
|
#+end_src
|
|
|
|
*** LaTeX settings
|
|
|
|
Various LaTeX export settings. The most important one ist that I use
|
|
my own class and customize the look of the title page.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; options for latex exports
|
|
(setq org-latex-classes
|
|
(quote
|
|
(("beamer" "\\documentclass{beamer}"
|
|
("\\section{%s}" . "\\section*{%s}")
|
|
("\\subsection{%s}" . "\\subsection*{%s}")
|
|
("\\subsubsection{%s}" . "\\subsubsection*{%s}"))
|
|
("article" "\\documentclass{article}"
|
|
("\\section{%s}" . "\\section*{%s}")
|
|
("\\subsection{%s}" . "\\subsection*{%s}")
|
|
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
|
|
("\\paragraph{%s}" . "\\paragraph*{%s}")
|
|
("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
|
|
("report" "\\documentclass[11pt]{report}"
|
|
("\\part{%s}" . "\\part*{%s}")
|
|
("\\chapter{%s}" . "\\chapter*{%s}")
|
|
("\\section{%s}" . "\\section*{%s}")
|
|
("\\subsection{%s}" . "\\subsection*{%s}")
|
|
("\\subsubsection{%s}" . "\\subsubsection*{%s}"))
|
|
("book" "\\documentclass[11pt]{book}"
|
|
("\\part{%s}" . "\\part*{%s}")
|
|
("\\chapter{%s}" . "\\chapter*{%s}")
|
|
("\\section{%s}" . "\\section*{%s}")
|
|
("\\subsection{%s}" . "\\subsection*{%s}")
|
|
("\\subsubsection{%s}" . "\\subsubsection*{%s}")))))
|
|
(setq org-latex-default-packages-alist nil)
|
|
(setq org-latex-listings 'listings)
|
|
(setq org-latex-title-command "\\maketitle\\newpage")
|
|
(setq org-latex-toc-command "\\tableofcontents
|
|
\\newpage
|
|
")
|
|
#+end_src
|
|
|
|
** Agenda
|
|
|
|
*** Keybinding
|
|
|
|
To have easy access to my agenda view I've bound the
|
|
F9 key to that function. Now I can access it with just
|
|
one simple key press.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
;; Set the agenda separator to a space character.
|
|
(setq org-agenda-block-separator " ")
|
|
|
|
;; a function to call the custom agenda view.
|
|
(defun az/custom-agenda (&optional arg)
|
|
(interactive "P")
|
|
(org-agenda arg "A"))
|
|
#+END_SRC
|
|
|
|
#+begin_src emacs-lisp
|
|
(global-set-key [f9] 'az/custom-agenda)
|
|
#+end_src
|
|
|
|
*** Hide tasks with a DONE state
|
|
|
|
Tasks which are scheduled, have a deadline or have a timestamp but are
|
|
marked DONE shouldn't get displayed in the Agenda. I usually clean
|
|
them out at the end of the week.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; hide done tasks in the agenda
|
|
(setq org-agenda-skip-deadline-if-done t)
|
|
(setq org-agenda-skip-scheduled-if-done t)
|
|
(setq org-agenda-skip-timestamp-if-done t)
|
|
#+end_src
|
|
|
|
*** Custom agenda commands
|
|
|
|
When you open the agenda command selection with ~C-c a~ you can choose
|
|
these settings. They allow you to filter the current file for the TODO
|
|
state corresponding to their keybinding. This is very useful for my
|
|
weekly review.
|
|
*Sorting Strategy*
|
|
By default org-mode sorts the agenda by the category. While this is
|
|
great it mixes the NEXT actions with the WAITING actions which have a
|
|
far lower priority than the NEXT actions. With this code the WAITING
|
|
actions get sorted to the bottom.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; Custom agenda command to list the stuck projects in the normal
|
|
;; agenda view.
|
|
(setq org-stuck-projects '("/PROJECT" ("NEXT") nil ""))
|
|
(setq org-agenda-custom-commands
|
|
(quote (("A" "Custom Agenda"
|
|
((agenda "" nil)
|
|
(stuck ""
|
|
((org-agenda-overriding-header "Stuck Projects")
|
|
(org-agenda-sorting-strategy
|
|
'(category-up))))
|
|
(tags-todo "TODO=\"PROJECT\" "
|
|
((org-agenda-overriding-header "Projects")
|
|
(org-agenda-sorting-strategy
|
|
'(category-up))))
|
|
nil))
|
|
;; Show all headings with the corresponding TODO state
|
|
("N" occur-tree "NEXT")
|
|
("O" occur-tree "TODO")
|
|
("W" occur-tree "WAITING"))))
|
|
#+end_src
|
|
|
|
*** Hide deadline prewarnings for scheduled tasks
|
|
|
|
By default the agenda shows you prewarnings for tasks which have a deadline.
|
|
However those don't make much sense when I already have scheduled that item
|
|
for this reason I disable the warnings for scheduled tasks.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; don't show the warnings for deadlines if the item is scheduled
|
|
(setq org-agenda-skip-deadline-prewarning-if-scheduled t)
|
|
#+end_src
|
|
|
|
*** Default agenda settings
|
|
|
|
My default agenda view starts on the current day and shows the next 14
|
|
days. This gives me a good overview of whats comming and helps greatly
|
|
with scheduling tasks. In addition I added an option to better display
|
|
the tags in the agenda. With the new default settings they always get
|
|
wrapped on a new line which is quite annoying.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; start the agenda on the current day and show the next 13 days
|
|
(setq org-agenda-span 14
|
|
org-agenda-start-on-weekday nil)
|
|
(setq org-agenda-tags-column -80)
|
|
(setq org-agenda-show-future-repeats (quote next))
|
|
(setq org-agenda-sorting-strategy
|
|
(quote
|
|
((agenda todo-state-up priority-down category-up))))
|
|
#+end_src
|
|
|
|
*** Dim blocked tasks
|
|
|
|
Blocked tasks are apparently dimmed by default however I still have
|
|
this setting enabled.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; dimm open tasks
|
|
(setq org-agenda-dim-blocked-tasks t)
|
|
#+end_src
|
|
|
|
*** Refresh agenda after capturing a task
|
|
|
|
This function updates the agenda after you've captured a new task.
|
|
Otherwise this would be a two step process.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; automatically refresh the agenda after adding a task
|
|
(add-hook 'org-capture-after-finalize-hook 'nebucatnetzer:org-agenda-redo)
|
|
|
|
(defun nebucatnetzer:org-agenda-redo ()
|
|
(interactive)
|
|
(when (get-buffer "*Org Agenda*")
|
|
(with-current-buffer "*Org Agenda*"
|
|
(org-agenda-redo t)
|
|
(message "[org agenda] refreshed!"))))
|
|
#+end_src
|
|
|
|
** Clocking
|
|
|
|
*** Remove clocks with a duration of 0
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq org-clock-out-remove-zero-time-clocks t)
|
|
#+end_src
|
|
|
|
*** define clocking heading
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(when (boundp 'enable-clocking)
|
|
(defun start-heading-clock (id file)
|
|
"Start clock programmatically for heading with ID in FILE."
|
|
(require 'org-id)
|
|
(if-let (marker (org-id-find-id-in-file id file t))
|
|
(save-current-buffer
|
|
(save-excursion
|
|
(set-buffer (marker-buffer marker))
|
|
(goto-char (marker-position marker))
|
|
(org-clock-in)))
|
|
(warn "Clock not started (Could not find ID '%s' in file '%s')" id file)))
|
|
|
|
(defun start-main-clock ()
|
|
"This functions always clocks in to the * Clock heading"
|
|
(interactive)
|
|
(start-heading-clock "e9f71012-4370-4dd2-af8e-9ae14d86508a" "~/nextcloud/03_documents/org/agenda/work/work.org"))
|
|
|
|
(global-set-key (kbd "<f6>") 'start-main-clock))
|
|
#+END_SRC
|
|
|
|
*** Resume a running clock when emacs restarts
|
|
|
|
#+begin_src emacs-lisp
|
|
(org-clock-persistence-insinuate)
|
|
#+end_src
|
|
|
|
*** Clock out when moving task to a done state
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq org-clock-out-when-done t)
|
|
#+end_src
|
|
|
|
*** Save the running clock when exiting Emacs
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq org-clock-persist t)
|
|
;; Do not prompt to resume an active clock
|
|
(setq org-clock-persist-query-resume nil)
|
|
#+end_src
|
|
|
|
*** Clocking Keybindings
|
|
|
|
Clock in with ~C-x C-i~ and out with ~C-x C-o~ and ~C-x C-d~ to mark a
|
|
task as the default task.
|
|
|
|
#+begin_src emacs-lisp
|
|
(global-set-key (kbd "<f7>") 'org-clock-in)
|
|
(global-set-key (kbd "<f8>") 'org-clock-out)
|
|
(global-set-key (kbd "C-x C-d") 'org-clock-mark-default-task)
|
|
#+end_src
|
|
|
|
*** Clock table time format
|
|
|
|
At my job we have to report the times in decimal format. Therefore
|
|
it's a bit difficult when org-mode displays the time in the normal
|
|
format. This code snippets let's you display the time in decimal
|
|
format in the clock table.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(setq org-duration-format (quote (("h") (special . 2))))
|
|
#+END_SRC
|
|
|
|
*** org agenda clock report
|
|
|
|
For quite some time I've used a clock table in my main org file. However I
|
|
noticed that on Windows Emacs got very slow with complicated org files.
|
|
Therefore I've looked for a way to replicate the clock table in the agenda
|
|
because it pulls from multiple files.
|
|
This way I can split the tasks over many files.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(setq org-agenda-clockreport-parameter-plist
|
|
(quote (:link t :maxlevel 4 :tcolumns 3)))
|
|
#+END_SRC
|
|
|
|
** org-insert-image
|
|
|
|
This function allows to quickly insert a picture into the current org
|
|
file. The file will get renamed and moved to the file location.
|
|
I found this code on this blog post:
|
|
http://pragmaticemacs.com/emacs/a-workflow-to-quickly-add-photos-to-org-mode-notes/
|
|
|
|
#+begin_src emacs-lisp
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; add image from conference phone upload ;;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; use case is taking a photo of a slide in a conference and uploading
|
|
;; it to google drive or dropbox or whatever to get it on your
|
|
;; computer. You then want to embed it in an org-mode document by
|
|
;; moving it to the same folder and renaming according to the current
|
|
;; section of the org file, avoiding name clashes
|
|
|
|
;; required libraries
|
|
(require 'dash)
|
|
(require 'swiper)
|
|
(require 's)
|
|
|
|
(global-set-key (kbd "C-c i") 'org-insert-image)
|
|
;; start directory
|
|
(defvar bjm/conference-image-dir (expand-file-name "~/Downloads/"))
|
|
|
|
(defun org-insert-image ()
|
|
"Insert image from conference directory, rename and add link in current file.
|
|
The file is taken from a start directory set by
|
|
`bjm/conference-image-dir' and moved to the current directory, renamed
|
|
and embedded at the point as an org-mode link. The user is presented
|
|
with a list of files in the start directory, from which to select the
|
|
file to move, sorted by most recent first."
|
|
(interactive)
|
|
(let (file-list target-dir file-list-sorted start-file start-file-full file-ext end-file end-file-base end-file-full file-number)
|
|
;; clean directories from list but keep times
|
|
(setq file-list
|
|
(-remove (lambda (x) (nth 1 x))
|
|
(directory-files-and-attributes bjm/conference-image-dir)))
|
|
|
|
;; get target directory
|
|
(setq target-dir (concat (file-name-directory buffer-file-name) "_resources/"))
|
|
(unless (file-exists-p target-dir)
|
|
(make-directory target-dir))
|
|
;; sort list by most recent
|
|
;; http://stackoverflow.com/questions/26514437/emacs-sort-list-of-directories-files-by-modification-date
|
|
(setq file-list-sorted
|
|
(mapcar #'car
|
|
(sort file-list
|
|
#'(lambda (x y) (time-less-p (nth 6 y) (nth 6 x))))))
|
|
|
|
;; use ivy to select start-file
|
|
(setq start-file (ivy-read
|
|
(concat "Move selected file to " target-dir ":")
|
|
file-list-sorted
|
|
:re-builder #'ivy--regex
|
|
:sort nil
|
|
:initial-input nil))
|
|
|
|
;; add full path to start file and end-file
|
|
(setq start-file-full
|
|
(expand-file-name start-file bjm/conference-image-dir))
|
|
;; generate target file name from current org section
|
|
(setq file-ext
|
|
(file-name-extension start-file t))
|
|
|
|
;; get section heading and clean it up
|
|
(setq end-file-base (s-downcase (s-dashed-words (nth 4 (org-heading-components)))))
|
|
;; shorten to first 40 chars to avoid long file names
|
|
(setq end-file-base (s-left 40 end-file-base))
|
|
;; number to append to ensure unique name
|
|
(setq file-number 1)
|
|
(setq end-file (concat
|
|
end-file-base
|
|
(format "-%s" file-number)
|
|
file-ext))
|
|
|
|
;; increment number at end of name if file exists
|
|
(while (file-exists-p (concat "_resources/" end-file))
|
|
;; increment
|
|
(setq file-number (+ file-number 1))
|
|
(setq end-file (concat
|
|
end-file-base
|
|
(format "-%s" file-number)
|
|
file-ext)))
|
|
|
|
;; final file name including path
|
|
(setq end-file-full
|
|
(expand-file-name end-file target-dir))
|
|
;; rename file
|
|
(rename-file start-file-full end-file-full)
|
|
(message "moved %s to _resources/%s" start-file-full end-file)
|
|
;; insert link
|
|
(insert (org-make-link-string (format "file:_resources/%s" end-file)))
|
|
;; display image
|
|
(org-display-inline-images t t)))
|
|
#+end_src
|
|
|
|
** Agenda file
|
|
|
|
This settings tells Emacs where to look for agenda files.
|
|
All the files in this directories and its sub directories count as
|
|
agenda files.
|
|
|
|
#+begin_src emacs-lisp
|
|
(load-library "find-lisp")
|
|
(when (boundp 'enable-personal-agenda)
|
|
(when (is-linux-p)
|
|
(setq org-agenda-files
|
|
(find-lisp-find-files "~/nextcloud/12_tasks" "\.org$"))))
|
|
(when (boundp 'enable-work-agenda)
|
|
(when (is-windows-p)
|
|
(setq org-agenda-files
|
|
(find-lisp-find-files "~/nextcloud/03_documents/org/agenda/work" "\.org$"))))
|
|
#+end_src
|
|
|
|
** org-update-cookies-after-save
|
|
|
|
It can happen that statistic cookies in an org-mode buffer don't get
|
|
updated. This function updates all the statistic cookies before the
|
|
buffer gets saved.
|
|
|
|
#+begin_src emacs-lisp
|
|
(defun org-update-cookies-after-save()
|
|
(interactive)
|
|
(let ((current-prefix-arg '(4)))
|
|
(org-update-statistics-cookies "ALL")))
|
|
|
|
(add-hook 'org-mode-hook
|
|
(lambda ()
|
|
(add-hook 'before-save-hook 'org-update-cookies-after-save nil 'make-it-local)))
|
|
#+end_src
|
|
|
|
** mark-task-as-done
|
|
|
|
This function sets a parent to the DONE state when the last of it's
|
|
children gets changed to DONE. This is especially usefull in
|
|
combination with org-edna.
|
|
|
|
- https://orgmode.org/manual/Breaking-down-tasks.html
|
|
|
|
#+begin_src emacs-lisp
|
|
(defun org-summary-todo (n-done n-not-done)
|
|
"Switch entry to DONE when all subentries are done, to TODO otherwise."
|
|
(let (org-log-done org-log-states) ; turn off logging
|
|
(org-todo (if (= n-not-done 0) "DONE" "TODO"))))
|
|
|
|
(add-hook 'org-after-todo-statistics-hook 'org-summary-todo))
|
|
#+end_src
|
|
|
|
** Personal org file
|
|
|
|
I defined ~C-c p~ to quickly jump to my personal org file.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; keymap for my personal.org file
|
|
(when (boundp 'enable-personal-agenda)
|
|
(when (is-linux-p)
|
|
(global-set-key (kbd "C-c p")
|
|
(lambda () (interactive) (find-file "~/nextcloud/12_tasks/personal.org")))))
|
|
(when (boundp 'enable-work-agenda)
|
|
(when (is-windows-p)
|
|
(global-set-key (kbd "C-c p")
|
|
(lambda () (interactive) (find-file "~/nextcloud/03_documents/org/agenda/work/work.org")))))
|
|
#+end_src
|
|
|
|
* General
|
|
** User data
|
|
|
|
#+begin_src emacs-lisp
|
|
;; My details
|
|
|
|
(setq user-full-name "Andreas Zweili")
|
|
(setq user-mail-address "andreas@zweili.ch")
|
|
#+end_src
|
|
|
|
** Toggle window splits
|
|
|
|
Sometimes when emacs opens a buffer it's in a wrong orientation. With
|
|
the keybinding ~C-x 4~ I can toggle between horizontal and vertical
|
|
split.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; a function to toggle the splits
|
|
(defun toggle-window-split ()
|
|
(interactive)
|
|
(if (= (count-windows) 2)
|
|
(let* ((this-win-buffer (window-buffer))
|
|
(next-win-buffer (window-buffer (next-window)))
|
|
(this-win-edges (window-edges (selected-window)))
|
|
(next-win-edges (window-edges (next-window)))
|
|
(this-win-2nd (not (and (<= (car this-win-edges)
|
|
(car next-win-edges))
|
|
(<= (cadr this-win-edges)
|
|
(cadr next-win-edges)))))
|
|
(splitter
|
|
(if (= (car this-win-edges)
|
|
(car (window-edges (next-window))))
|
|
'split-window-horizontally
|
|
'split-window-vertically)))
|
|
(delete-other-windows)
|
|
(let ((first-win (selected-window)))
|
|
(funcall splitter)
|
|
(if this-win-2nd (other-window 1))
|
|
(set-window-buffer (selected-window) this-win-buffer)
|
|
(set-window-buffer (next-window) next-win-buffer)
|
|
(select-window first-win)
|
|
(if this-win-2nd (other-window 1))))))
|
|
|
|
(define-key ctl-x-map "4" 'toggle-window-split)
|
|
#+end_src
|
|
|
|
** Split Windows and move cursor into it
|
|
|
|
Usually when I want to split the window I want the cursor to be place
|
|
into the new window because I need to manipulate that window. Emacs
|
|
doesn't do this by default but we can add that functionality.
|
|
|
|
#+begin_src emacs-lisp
|
|
(defun nebucatnetzer:split-window-below-and-move-cursor ()
|
|
(interactive)
|
|
(split-window-below)
|
|
(other-window 1))
|
|
|
|
(defun nebucatnetzer:split-window-right-and-move-cursor ()
|
|
(interactive)
|
|
(split-window-right)
|
|
(other-window 1))
|
|
|
|
(global-set-key (kbd "C-x 2") 'nebucatnetzer:split-window-below-and-move-cursor)
|
|
(global-set-key (kbd "C-x 3") 'nebucatnetzer:split-window-right-and-move-cursor)
|
|
#+end_src
|
|
|
|
** Use spaces instead of tabs
|
|
|
|
#+begin_src emacs-lisp
|
|
;; Spaces instead of TABs
|
|
(setq-default indent-tabs-mode nil)
|
|
(setq-default tab-width 4)
|
|
(setq indent-line-function 'insert-tab)
|
|
#+end_src
|
|
|
|
** Key bindings
|
|
*** buffer switching
|
|
|
|
ibuffer is a much better way to give an overview than the standard buffer
|
|
view in emacs. Interestingly it's already built in but not configured.
|
|
You can open it with ~C-x C-b~. Ivy is a nice tool for completions I configured
|
|
~C-x b~ to open Ivy for switching buffers.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; keymap for buffer switching
|
|
(global-set-key (kbd "C-x C-b") 'ibuffer)
|
|
(global-set-key (kbd "C-x b") 'ivy-switch-buffer)
|
|
#+end_src
|
|
|
|
*** kill current buffer
|
|
|
|
Don't ask which buffer to kill, kill the current buffer with ~C-x C-k~.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; kill THIS buffer
|
|
(global-set-key (kbd "C-x C-k") 'kill-this-buffer)
|
|
#+end_src
|
|
|
|
*** Copy buffer to clipboard
|
|
|
|
Sometimes it's handy to be able the complete buffer into the clipboard.
|
|
E.g. when you write an email in Emacs an want to copy it into Outlook.
|
|
This function is bound to ~C-S-c~.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; copy the complete buffer to the clipboard
|
|
(defun copy-all ()
|
|
"Copy entire buffer to clipboard"
|
|
(interactive)
|
|
(clipboard-kill-ring-save (point-min) (point-max)))
|
|
|
|
(global-set-key (kbd "C-S-c") 'copy-all)
|
|
#+end_src
|
|
|
|
*** Frame Controls
|
|
|
|
This keybindings allow to create and navigate frames.
|
|
Frames are in a desktop environment usually called windows.
|
|
However because Emacs is so old it has it's own terminology.
|
|
|
|
- New frame :: ~C-x N~
|
|
|
|
- Switch to the other frame :: ~C-x O~
|
|
|
|
- Kill frame :: ~C-x K~
|
|
|
|
#+begin_src emacs-lisp
|
|
;; keybinding for new frame
|
|
(global-set-key (kbd "C-x N") 'make-frame)
|
|
|
|
;; switch to frame
|
|
(global-set-key (kbd "C-x O") 'other-frame)
|
|
|
|
;; kill frame
|
|
(global-set-key (kbd "C-x K") 'delete-frame)
|
|
#+end_src
|
|
|
|
*** Hippie Expand
|
|
|
|
This option enables hippie expand which allows for path complition and
|
|
more. You can execute it with ~M-Space~.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; enable hippie expand on M-Space
|
|
(global-set-key "\M- " 'hippie-expand)
|
|
#+end_src
|
|
|
|
*** jump to minibuffer
|
|
|
|
#+begin_src emacs-lisp
|
|
(defun switch-to-minibuffer () "Switch to minibuffer window."
|
|
(interactive) (if (active-minibuffer-window)
|
|
(select-window
|
|
(active-minibuffer-window)) (error "Minibuffer is not active")))
|
|
|
|
(bind-key "M-m" 'switch-to-minibuffer)
|
|
#+end_src
|
|
|
|
** File encoding
|
|
*** Prefer Unix encoding.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; file encodings
|
|
(prefer-coding-system 'utf-8-unix)
|
|
#+end_src
|
|
|
|
** Move backup files to the temp folder
|
|
|
|
With this configuration Emacs saves the backup files into the temp
|
|
directory. Otherwise they get created in the current directory which
|
|
IMO is unneeded clutter.
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq backup-directory-alist
|
|
`((".*" . ,temporary-file-directory)))
|
|
(setq auto-save-file-name-transforms
|
|
`((".*" ,temporary-file-directory t)))
|
|
#+end_src
|
|
|
|
** ibuffer, buffer groups
|
|
|
|
This function groups buffers depending on their mode which gives an
|
|
even better overview. In addition it hides temporary buffers from the
|
|
ibuffer view.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; hide temporary buffers
|
|
(add-hook 'ibuffer-mode-hook
|
|
(lambda ()
|
|
(ibuffer-filter-by-name "^[^*]")))
|
|
|
|
(setq ibuffer-saved-filter-groups
|
|
(quote (("default"
|
|
("Org" ;; all org-related buffers
|
|
(mode . org-mode))
|
|
("Programming" ;; prog stuff not already in MyProjectX
|
|
(or
|
|
(mode . python-mode)
|
|
(mode . web-mode)
|
|
(mode . php-mode)
|
|
(mode . csharp-mode)
|
|
(mode . javascript-mode)
|
|
(mode . sql-mode)
|
|
(mode . powershell-mode)
|
|
(mode . emacs-lisp-mode)))
|
|
;; etc
|
|
("Dired"
|
|
(mode . dired-mode))))))
|
|
|
|
(add-hook 'ibuffer-mode-hook
|
|
(lambda ()
|
|
(ibuffer-switch-to-saved-filter-groups "default")))
|
|
#+end_src
|
|
|
|
** Initial buffer mode
|
|
|
|
When I create a new buffer it should start in text-mode.
|
|
By default Emacs uses elisp-mode.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; initial buffers should use text-mode
|
|
(setq-default major-mode 'text-mode)
|
|
#+end_src
|
|
|
|
** Localization
|
|
*** First day of the week
|
|
|
|
In Switzerland weeks start on Monday not Sunday.
|
|
|
|
#+begin_src emacs-lisp
|
|
; Calender should start on Monday
|
|
(setq calendar-week-start-day 1)
|
|
#+end_src
|
|
|
|
*** Spell checking
|
|
|
|
Since I write both in English and in German I need two dictionaries.
|
|
This code configures Emacs to use the Linux dictionaries en_US and
|
|
de_CH. If you want to switch languages you need the function:
|
|
~ispell-change-dictionary~
|
|
|
|
#+begin_src emacs-lisp
|
|
;; ispell settings
|
|
(setenv "DICTIONARY" "en_US")
|
|
(setq ispell-program-name "hunspell")
|
|
(setq ispell-local-dictionary "en_US")
|
|
(setq ispell-local-dictionary-alist
|
|
'(("en_US" "[[:alpha:]]" "[^[:alpha:]]" "[']" nil ("-d" "en_US") nil utf-8)
|
|
("de_CH" "[[:alpha:]]" "[^[:alpha:]]" "[']" nil ("-d" "de_CH") nil utf-8)))
|
|
#+end_src
|
|
|
|
*** Spaces after periods.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; insert only one space after a period
|
|
(setq sentence-end-double-space nil)
|
|
#+end_src
|
|
|
|
** Parantheses
|
|
*** Math parantheses
|
|
|
|
This setting shows matching parantheses and hightlights the ones which
|
|
don't have a counter part.
|
|
|
|
#+begin_src emacs-lisp
|
|
; Matches parentheses and such in every mode
|
|
(show-paren-mode 1)
|
|
#+end_src
|
|
|
|
*** Electric parantheses
|
|
|
|
When you insert a parenthesis it's counter pair gets inserted automatically.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; pair parentheses
|
|
(electric-pair-mode 1)
|
|
#+end_src
|
|
|
|
** Auto-fill
|
|
|
|
This enables auto-fill which is basically line wrapping.
|
|
|
|
#+begin_src emacs-lisp
|
|
(add-hook 'text-mode-hook 'turn-on-auto-fill)
|
|
#+end_src
|
|
|
|
** Suppressing ad-handle-definition Warnings
|
|
|
|
This settings surpresses the following warning which shows up when
|
|
Emacs starts:
|
|
|
|
#+begin_example
|
|
ad-handle-definition: `tramp-read-passwd' got redefined
|
|
#+end_example
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq ad-redefinition-action 'accept)
|
|
#+end_src
|
|
|
|
** remove bad whitespace when saving
|
|
|
|
#+begin_src emacs-lisp
|
|
(add-hook 'before-save-hook 'whitespace-cleanup)
|
|
#+end_src
|
|
|
|
** Autorefresh buffers if the file changes on disk
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(global-auto-revert-mode t)
|
|
#+END_SRC
|
|
|
|
** 80 characters line width
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(setq-default fill-column 79)
|
|
#+END_SRC
|
|
|
|
** show column number
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(setq column-number-mode 1)
|
|
#+END_SRC
|
|
|
|
** display emojis
|
|
|
|
Display Emoji requires the ~fonts-symbola~ Debian package.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(when (boundp 'enable-emojis)
|
|
(when (is-linux-p)
|
|
(set-fontset-font t nil "Symbola" nil 'prepend)))
|
|
#+END_SRC
|
|
|
|
** kill all buffers
|
|
|
|
This function is helpful to "clean up" emacs without having to restart it.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(defun kill-other-buffers ()
|
|
"Kill all other buffers."
|
|
(interactive)
|
|
(mapc 'kill-buffer
|
|
(delq
|
|
(current-buffer)
|
|
(buffer-list))))
|
|
#+END_SRC
|
|
|
|
** insert date
|
|
|
|
#+begin_src emacs-lisp
|
|
(defun insert-date ()
|
|
"Insert the current date."
|
|
(interactive)
|
|
(let ((format "%d.%m.%Y")
|
|
(system-time-locale "de_CH"))
|
|
(insert (format-time-string format))))
|
|
|
|
(defun insert-iso-date ()
|
|
"Insert the current date in the ISO format."
|
|
(interactive)
|
|
(let ((format "%Y-%m-%d")
|
|
(system-time-locale "de_CH"))
|
|
(insert (format-time-string format))))
|
|
|
|
(defun insert-full-date ()
|
|
"Insert the current date, write out the day and month name."
|
|
(interactive)
|
|
(let ((format "%A, %d. %B %Y")
|
|
(system-time-locale "de_CH"))
|
|
(insert (format-time-string format))))
|
|
#+end_src
|
|
|
|
** handling large files
|
|
|
|
Taken from here:
|
|
https://github.com/jhallen/joes-sandbox/issues/29
|
|
|
|
#+begin_src emacs-lisp
|
|
(defun buffer-too-big-p ()
|
|
(or (> (buffer-size) (* 5000 64))
|
|
(> (line-number-at-pos (point-max)) 5000)))
|
|
(defun generic-setup ()
|
|
;; turn off `linum-mode' when there are more than 5000 lines
|
|
(if (buffer-too-big-p) (display-line-numbers-mode -1)))
|
|
|
|
(add-hook 'prog-mode-hook 'generic-setup)
|
|
(add-hook 'text-mode-hook 'generic-setup)
|
|
#+end_src
|
|
|
|
** remove duplicates from history
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq history-delete-duplicates t)
|
|
#+end_src
|
|
|
|
** enable mouse support in terminal
|
|
|
|
#+begin_src emacs-lisp
|
|
(xterm-mouse-mode 1)
|
|
#+end_src
|
|
|
|
* Eshell
|
|
|
|
** General
|
|
|
|
Make the tab completion behave like in Bash.
|
|
|
|
#+begin_src emacs-lisp
|
|
(add-hook 'eshell-mode-hook
|
|
(lambda ()
|
|
(setq pcomplete-cycle-completions nil)))
|
|
#+end_src
|
|
|
|
* Tramp
|
|
|
|
** default-tramp-method
|
|
|
|
To improve the perfomance of tramp I use SSH instead of scp.
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq tramp-default-method "ssh")
|
|
#+end_src
|
|
|
|
* LaTex
|
|
** Align Tables
|
|
|
|
This is a nice function to work with LaTeX tables. I've got it from
|
|
here: https://thenybble.de/projects/inhibit-auto-fill.html
|
|
|
|
#+begin_src emacs-lisp
|
|
(when (boundp 'enable-auctex)
|
|
(defun LaTeX-collapse-table ()
|
|
(interactive)
|
|
(save-excursion
|
|
(LaTeX-mark-environment)
|
|
(while (re-search-forward "[[:space:]]+\\(&\\|\\\\\\\\\\)" (region-end) t)
|
|
(replace-match " \\1"))))
|
|
|
|
(defun LaTeX-align-environment (arg)
|
|
(interactive "P")
|
|
(if arg
|
|
(LaTeX-collapse-table)
|
|
(save-excursion
|
|
(LaTeX-mark-environment)
|
|
(align (region-beginning) (region-end))))))
|
|
#+end_src
|
|
|
|
** Inhibiting auto-fill
|
|
|
|
"Auto-fill is nice. Filling to 80 columns (as god intended) makes code
|
|
or any other text easier to read.
|
|
|
|
However, it's not so nice for large latex tables that you want to
|
|
align properly (perhaps using align). This is why I hacked together
|
|
some elisp to inhibit auto-fill when the cursor is in a table (or any
|
|
other environment that doesn't need to be auto-filled, according to
|
|
your whims."
|
|
|
|
Taken from here:
|
|
https://thenybble.de/projects/inhibit-auto-fill.html
|
|
|
|
#+begin_src emacs-lisp
|
|
(when (boundp 'enable-auctex)
|
|
(defcustom LaTeX-inhibited-auto-fill-environments
|
|
'("tabular" "tikzpicture") "For which LaTeX environments not to run auto-fill.")
|
|
|
|
(defun LaTeX-limited-auto-fill ()
|
|
(let ((environment (LaTeX-current-environment)))
|
|
(when (not (member environment LaTeX-inhibited-auto-fill-environments))
|
|
(do-auto-fill)))))
|
|
#+end_src
|
|
|
|
** Enable the LaTeX tweaks
|
|
|
|
#+begin_src emacs-lisp
|
|
(when (boundp 'enable-auctex)
|
|
(global-set-key (kbd "C-c f") 'LaTeX-align-environment)
|
|
(setq auto-fill-function 'LaTeX-limited-auto-fill))
|
|
#+end_src
|
|
|
|
* Dired
|
|
** open a folder in the same buffer
|
|
|
|
By default dired obens a buffer for every folder one opens. With this setting
|
|
it's possible open a folder in the current buffer when pressing ~a~ on it.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(put 'dired-find-alternate-file 'disabled nil)
|
|
#+END_SRC
|
|
|
|
** use human readable formats
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(setq-default dired-listing-switches "-alh")
|
|
#+END_SRC
|
|
|
|
** Keybindings
|
|
*** open
|
|
|
|
You can open dired with ~C-c d~
|
|
|
|
#+begin_src emacs-lisp
|
|
;; keymap for dired
|
|
(global-set-key (kbd "C-c d") 'dired-jump)
|
|
#+end_src
|
|
|
|
*** kill
|
|
|
|
By default ~q~ in dired just hides the dired buffer. However I prefer
|
|
the buffer to get killed completely.
|
|
|
|
#+begin_src emacs-lisp
|
|
(bind-keys :map dired-mode-map ("q" . az-kill-dired-buffers))
|
|
#+end_src
|
|
|
|
** Kill all dired buffers
|
|
|
|
Dired opens a lot of buffers when you use it. This functions helps to
|
|
clean up afterwards.
|
|
|
|
#+begin_src emacs-lisp
|
|
;;a function to kill all dired buffers
|
|
(defun az-kill-dired-buffers ()
|
|
(interactive)
|
|
(mapc (lambda (buffer)
|
|
(when (eq 'dired-mode (buffer-local-value 'major-mode buffer))
|
|
(kill-buffer buffer)))
|
|
(buffer-list)))
|
|
#+end_src
|
|
|
|
** dired hide dot folders
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(use-package dired-hide-dotfiles
|
|
:ensure t
|
|
:init
|
|
(defun my-dired-mode-hook ()
|
|
"My `dired' mode hook."
|
|
;; To hide dot-files by default
|
|
(dired-hide-dotfiles-mode)
|
|
|
|
;; To toggle hiding
|
|
|
|
(add-hook 'dired-mode-hook #'my-dired-mode-hook))
|
|
:bind
|
|
(:map dired-mode-map
|
|
("." . dired-hide-dotfiles-mode)))
|
|
#+END_SRC
|