This is my Emacs config. You need to tangle this into a file that
then gets loaded by Emacs: C-c C-v t
[org-babel-tangle].
Below, I also explain how this tangling is automated.
Find extensive documentation about how to do this here.
I regularly try out new packages, this is my current list of things being evaluated.
They usually live temporarily in my ~/.emacs
until I am happy, in
which case I move their config into this file so that it gets replicated on all
machines I work on with Emacs.
- org-gcal
- yankpad + yasnippet
- ox-reveal (see installation)
I have my config in directory ~/Emacs
which is where I clone this repository.
The config setup is maintained purely in the ~/Emacs/emacs_setup.org
file.
In your ~/.emacs
file, all you need to add is
;; Loads PAF's emacs setup with bootstrap
(load-file "~/Emacs/emacs_setup.el")
Initially when cloning this repository, you have the emacs_setup.org
file,
that contains the config that you adapt to your specific setup, and an
emacs_setup.el
with a bootstrap content that will tangle and compile the org
file, and replace itself. This is useful the very first time.
After that, the config itself should have the hook to re-tangle and re-compile the setup at each save.
Therefore my setup is very easy to install, and it needs these steps:
- clone this repo into
~/Emacs
- add the one line in you
~/.emacs
- make sure Emacs re-interprets its init (you could restart it)
It may be that use-package is not installed on your setup, so it will first try to install that. After that step, it will also start installing any package that is marked as needed in this config automatically.
The original content of the emacs_setup.el
is as follows:
;; This is the initial state of the file to be loaded.
;; It will replace itself with the actual configuration at first run.
(require 'org) ; We can't tangle without org!
(setq config_base (expand-file-name "emacs_setup"
(file-name-directory
(or load-file-name buffer-file-name))))
(find-file (concat config_base ".org")) ; Open the configuration
(org-babel-tangle) ; tangle it
(load-file (concat config_base ".el")) ; load it
(byte-compile-file (concat config_base ".el")) ; finally byte-compile it
To preserve the original state of this file when updating the git repos
with new config settings, execute the following block once (C-c C-c
):
#!/bin/bash
# Make git ignore the tangled & updated emacs_setup.el
GIT_ROOT=$(dirname $0)
(cd ${GIT_ROOT} && git update-index --skip-worktree emacs_setup.el)
# Maybe this is a new install, .emacs does not exist
test -e ~/.emacs || touch ~/.emacs
# Add the load-file as the first thing in the user's ~/.emacs
declare lines=$(grep emacs_setup ~/.emacs | wc -l)
if (( lines < 1 )); then
echo "Added loading the config in your ~/.emacs"
cat > ~/.emacs.new <<EOF
<<emacs_bootstrap>>
EOF
cat ~/.emacs >> ~/.emacs.new
mv ~/.emacs.new ~/.emacs
else
echo "Config in your ~/.emacs already set up!"
fi
This will force-recompile everything in ~/.emacs.d/elpa/…
Just run M-:
and then enter this:
(byte-recompile-directory package-user-dir nil 'force)
or simply C-x C-e
at the end of that line.
This section sets up Emacs so it can tangle the config, find use-package
,
and find the ELPA repositories where to get the new packes from.
Just to add a little information in the tangled file.
;; ===== this file was auto-tangled, only edit the emacs_setup.org =====
Make sure we have the package system initialized before we load anything.
(require 'package)
(package-initialize)
Adding my choice of packages repositories. #+NAME melpa-setup
(setq package-archives '(("org" . "https://orgmode.org/elpa/")
("melpa" . "https://stable.melpa.org/packages/")
; ("melpa" . "https://melpa.org/packages/")
("gnu" . "https://elpa.gnu.org/packages/")
; ("marmalade" . "https://marmalade-repo.org/packages/")
))
I use use-package
for most configuration, and that needs to be at the top of
the file. use-package
verifies the presence of the requested package, otherwise
installs it, and presents convenient sections for configs of variables, key
bindings etc. that happen only if the package is actually loaded.
First, make sure it gets installed if it is not there yet.
;; make sure use-package is installed
(unless (package-installed-p 'use-package)
(unless package-archive-contents
(package-refresh-contents))
(package-install 'use-package))
(eval-when-compile (require 'use-package))
I set this up to tangle the init org-mode file into the actual Emacs init file as soon as I save it.
(defun tangle-init ()
"If the current buffer is 'init.org' the code-blocks are
tangled, and the tangled file is compiled."
(when (equal (buffer-file-name)
(expand-file-name "~/Emacs/emacs_setup.org"))
;; Avoid running hooks when tangling.
(let ((prog-mode-hook nil))
(org-babel-tangle)
(byte-compile-file "~/Emacs/emacs_setup.el"))))
(add-hook 'after-save-hook 'tangle-init)
Remove C-p
that I want to use for me personally as a prefix.
(global-set-key (kbd "C-p") nil) ;; was 'previous-line'
Use instead of add-hook to run it a single time. found here
(defmacro add-hook-run-once (hook function &optional append local)
"Like add-hook, but remove the hook after it is called"
(let ((sym (make-symbol "#once")))
`(progn
(defun ,sym ()
(remove-hook ,hook ',sym ,local)
(funcall ,function))
(add-hook ,hook ',sym ,append ,local))))
(setq browse-url-generic-program (executable-find "google-chrome")
browse-url-browser-function 'browse-url-generic)
Start the background server, so we can use emacsclient.
(server-start)
Make Emacs request UTF-8 first when pasting stuff.
(use-package unicode-escape
:ensure t
:init
(setq x-select-request-type '(UTF8_STRING COMPOUND_TEXT TEXT STRING)))
(set-language-environment "UTF-8")
This should automatically convert any files with dos or Mac line endings into Unix style ones. Code found here.
(defun no-junk-please-we-are-unixish ()
(let ((coding-str (symbol-name buffer-file-coding-system)))
(when (string-match "-\\(?:dos\\|mac\\)$" coding-str)
(set-buffer-file-coding-system 'unix))))
(add-hook 'find-file-hooks 'no-junk-please-we-are-unixish)
I really like the high-contract Zenburn theme.
(use-package zenburn-theme
:ensure t)
Use auto-revert
, which reloads a file if it’s updated on disk
and not modified in the buffer.
(global-auto-revert-mode 1)
(put 'upcase-region 'disabled nil)
(put 'narrow-to-region 'disabled nil)
Enables winner-mode
.
Navigate buffer-window configs with C-c left
and C-c right
.
(winner-mode 1)
This is supposed to be a better window manager.
(use-package eyebrowse
:ensure t)
Temporarily maximize a buffer. found here
(defun toggle-maximize-buffer () "Maximize buffer"
(interactive)
(if (= 1 (length (window-list)))
(jump-to-register '_)
(progn
(window-configuration-to-register '_)
(delete-other-windows))))
Map it to a key.
(global-set-key [M-f8] 'toggle-maximize-buffer)
This gets the font coloring switched on for all buffers.
- State “TODO” from [2018-11-07 Wed 22:29]
(global-font-lock-mode t)
(when (display-graphic-p)
(set-background-color "#ffffff")
(set-foreground-color "#141312"))
(setq frame-title-format "emacs @ %b - %f")
(when window-system
(mwheel-install) ;; enable wheelmouse support by default
(set-selection-coding-system 'compound-text-with-extensions))
(use-package uniquify
:init
(setq uniquify-buffer-name-style 'post-forward-angle-brackets))
Setup the visual cues about the current editing buffer
(column-number-mode 1)
(setq visible-bell t)
(setq scroll-step 1)
(setq-default transient-mark-mode t) ;; highlight selection
(use-package nyan-mode
:ensure t
:bind ("C-p n" . 'nyan-mode))
The cursor is displayed in different colors, depending on overwrite or insert mode.
(setq hcz-set-cursor-color-color "")
(setq hcz-set-cursor-color-buffer "")
(defun hcz-set-cursor-color-according-to-mode ()
"change cursor color according to some minor modes."
;; set-cursor-color is somewhat costly, so we only call it when needed:
(let ((color
(if buffer-read-only "orange"
(if overwrite-mode "red"
"green"))))
(unless (and
(string= color hcz-set-cursor-color-color)
(string= (buffer-name) hcz-set-cursor-color-buffer))
(set-cursor-color (setq hcz-set-cursor-color-color color))
(setq hcz-set-cursor-color-buffer (buffer-name)))))
(add-hook 'post-command-hook 'hcz-set-cursor-color-according-to-mode)
Letting one enter chars that are otherwise difficult in e.g. the minibuffer.
(global-set-key (kbd "C-m") 'newline-and-indent)
(global-set-key (kbd "C-j") 'newline)
(global-set-key [delete] 'delete-char)
(global-set-key [kp-delete] 'delete-char)
(global-set-key [f3] 'start-kbd-macro)
(global-set-key [f4] 'end-kbd-macro)
(global-set-key [f5] 'call-last-kbd-macro)
Increase/decrease text size
(define-key global-map (kbd "C-+") 'text-scale-increase)
(define-key global-map (kbd "C--") 'text-scale-decrease)
(global-set-key (kbd "C-M-i") 'iedit-mode)
(global-set-key (kbd "C-c <C-left>") 'windmove-left)
(global-set-key (kbd "C-c <C-right>") 'windmove-right)
(global-set-key (kbd "C-c <C-up>") 'windmove-up)
(global-set-key (kbd "C-c <C-down>") 'windmove-down)
(global-set-key (kbd "C-c C-g") 'goto-line)
Configure the shortcuts for multiple cursors
(use-package multiple-cursors
:ensure t
:bind (("C-S-c C-S-c" . 'mc/edit-lines)
("C->" . 'mc/mark-next-like-this)
("C-<" . 'mc/mark-previous-like-this)
("C-c C->" . 'mc/mark-all-like-this)))
Let’s one jump around text
(use-package ace-jump-mode
:ensure t
:bind (("C-c C-SPC" . 'ace-jump-mode)
("C-c C-DEL" . 'ace-jump-mode-pop-mark)))
(setq-default indent-tabs-mode nil)
(setq require-final-newline t)
(setq next-line-add-newlines nil)
(add-hook 'before-save-hook 'delete-trailing-whitespace)
(use-package column-marker
:load-path "~/Emacs"
:config
(add-hook 'c-mode-common-hook (lambda () (interactive) (column-marker-1 80)))
:bind ("C-c m" . 'column-marker-1))
Seen demonstrated by Uncle Dave
(use-package popup-kill-ring
:ensure t
:bind ("M-y" . popup-kill-ring))
This should highlight bad style in writing.
(use-package artbollocks-mode
:ensure t
:config
;; Modify the mapping so it does not clash with Hyperbole's window management.
(define-key artbollocks-mode-keymap (kbd "C-c \\") nil)
(define-key artbollocks-mode-keymap (kbd "C-c %") 'artbollocks-readability-index)
(add-hook 'text-mode-hook 'artbollocks-mode))
Start using projectile. It has the documentation here.
(use-package projectile
:ensure t
:config
(define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map)
(projectile-mode +1))
(use-package helm-projectile
:ensure t
:requires projectile
:config
(helm-projectile-on))
Also make sure we do have the faster silver searcher version. This may need you to install the corresponding tool for this, with the following snippet:
# helm-ag uses this for faster grepping
sudo apt-get install silversearcher-ag
Search the entire project with C-c p s s
for a regexp.
This let’s you turn the matching results into an editable buffer using
C-c C-e
. Other keys are listed here.
(use-package helm-ag
:ensure t)
Switch from header to implementation file quickly.
(add-hook 'c-mode-common-hook
(lambda ()
(local-set-key (kbd "C-c o") 'ff-find-other-file)))
This enables searching recursively in projects.
# This can be used by helm-ag for faster grepping
sudo apt-get install ripgrep
(use-package ripgrep
:ensure t)
(use-package projectile-ripgrep
:ensure t
:requires (ripgrep projectile))
Easy commenting out of lines.
(autoload 'comment-out-region "comment" nil t)
(global-set-key (kbd "C-c q") 'comment-out-region)
Help cleanup the includes and using lists. found here
(defun uniquify-region-lines (beg end)
"Remove duplicate adjacent lines in region."
(interactive "*r")
(save-excursion
(goto-char beg)
(while (re-search-forward "^\\(.*\n\\)\\1+" end t)
(replace-match "\\1"))))
(defun paf/sort-and-uniquify-region ()
"Remove duplicates and sort lines in region."
(interactive)
(sort-lines nil (region-beginning) (region-end))
(uniquify-region-lines (region-beginning) (region-end)))
Simplify cleanup of #include
/ typedef
/ using
blocks.
(global-set-key (kbd "C-p s") 'paf/sort-and-uniquify-region)
vdiff let’s one compare buffers or files.
(use-package vdiff
:ensure t
:config
; This binds commands under the prefix when vdiff is active.
(define-key vdiff-mode-map (kbd "C-c") vdiff-mode-prefix-map))
(use-package yasnippet
:ensure t)
(use-package auto-yasnippet
:ensure t
:config
(bind-key "C-p C-s c" 'aya-create)
(bind-key "C-p C-s e" 'aya-expand))
(use-package yankpad
:ensure t
:init
(setq yankpad-file "~/OrgFiles/yankpad.org")
:config
(bind-key "C-p y m" 'yankpad-map)
(bind-key "C-p y e" 'yankpad-expand))
Will fold all text indented more than the position of the cursor at the time the keys are pressed.
(defun set-selective-display-dlw (&optional level)
"Fold text indented more than the cursor.
If level is set, set the indent level to level.
0 displays the entire buffer."
(interactive "P")
(set-selective-display (or level (current-column))))
(global-set-key "\C-x$" 'set-selective-display-dlw)
This is bound to change in Emacs 26, as it has built-in support for this and is more efficient.
(global-set-key (kbd "C-c C-n") 'linum-mode)
(use-package git-gutter-fringe+
:ensure t
:if window-system
:bind ("C-c g" . 'git-gutter+-mode))
Regexp matching directory names that are not under VC’s control. The default regexp prevents fruitless and time-consuming attempts to determine the VC status in directories in which filenames are interpreted as hostnames.
(defvar locate-dominating-stop-dir-regexp
"\\`\\(?:[\\/][\\/][^\\/]+\\|/\\(?:net\\|afs\\|\\.\\.\\.\\)/\\)\\'")
(setq gdb-many-windows t)
Simple way to increase/decrease a number in code.
(use-package shift-number
:ensure t
:bind (("M-+" . shift-number-up)
("M-_" . shift-number-down)))
Add the powerful Magit
(use-package magit
:ensure t
:config
(global-set-key (kbd "C-x g") 'magit-status))
(use-package magit-todos
:ensure t)
Add the Magit-copy for Mercurial ‘monky’
(use-package monky
:ensure t
:config
(global-set-key (kbd "C-x m") 'monky-status))
Have a single binding to call the most appropriate tool given the repository.
(defun paf/vcs-status ()
(interactive)
(condition-case nil
(magit-status-setup-buffer)
(error (monky-status))))
(global-set-key (kbd "C-p v") 'paf/vcs-status)
The file-annotations are store externally.
Seems to fail with args-out-of-range
and then Emacs is confused.
(filed issue for this)
Also, it seems to interfere with colorful modes like magit
or org-agenda-mode
so that I went with a whitelist instead of the wish of a blacklist of modes.
(use-package annotate
:ensure t
:bind ("C-c C-A" . 'annotate-annotate) ;; for ledger-mode, as 'C-c C-a' is taken there.
:config
(add-hook 'org-mode 'annotate-mode)
(add-hook 'csv-mode 'annotate-mode)
(add-hook 'c-mode 'annotate-mode)
(add-hook 'c++-mode 'annotate-mode)
(add-hook 'sh-mode 'annotate-mode)
(add-hook 'ledger-mode 'annotate-mode)
;;; (define-globalized-minor-mode global-annotate-mode annotate-mode
;;; (lambda () (annotate-mode 1)))
;;; (global-annotate-mode 1)
)
web-mode with config for Polymer editing
(use-package web-mode
:ensure t
:mode "\\.html\\'"
:config
(setq web-mode-markup-indent-offset 2)
(setq web-mode-css-indent-offset 2)
(setq web-mode-code-indent-offset 2))
mode to edit CSV files.
(use-package csv-mode
:ensure t
:mode "\\.csv\\'")
Trying out Helm instead of icicles, as it is available on ELPA.
I just took over the config described in this helm intro.
(use-package helm
:ensure t
:config
(require 'helm-config)
;; The default "C-x c" is quite close to "C-x C-c", which quits Emacs.
;; Changed to "C-c h". Note: We must set "C-c h" globally, because we
;; cannot change `helm-command-prefix-key' once `helm-config' is loaded.
(global-set-key (kbd "C-c h") 'helm-command-prefix)
(global-unset-key (kbd "C-x c"))
(define-key helm-map (kbd "<tab>") 'helm-execute-persistent-action) ; rebind tab to run persistent action
(define-key helm-map (kbd "C-i") 'helm-execute-persistent-action) ; make TAB work in terminal
(define-key helm-map (kbd "C-z") 'helm-select-action) ; list actions using C-z
(when (executable-find "curl")
(setq helm-google-suggest-use-curl-p t))
(setq helm-split-window-inside-p t ; open helm buffer inside current window, not occupy whole other window
helm-move-to-line-cycle-in-source t ; move to end or beginning of source when reaching top or bottom of source.
helm-ff-search-library-in-sexp t ; search for library in `require' and `declare-function' sexp.
helm-scroll-amount 8 ; scroll 8 lines other window using M-<next>/M-<prior>
helm-ff-file-name-history-use-recentf t
helm-echo-input-in-header-line t)
(setq helm-autoresize-max-height 0)
(setq helm-autoresize-min-height 20)
(helm-autoresize-mode 1)
(helm-mode 1)
(global-set-key (kbd "M-x") 'helm-M-x))
(defun spacemacs//helm-hide-minibuffer-maybe ()
"Hide minibuffer in Helm session if we use the header line as input field."
(when (with-helm-buffer helm-echo-input-in-header-line)
(let ((ov (make-overlay (point-min) (point-max) nil nil t)))
(overlay-put ov 'window (selected-window))
(overlay-put ov 'face
(let ((bg-color (face-background 'default nil)))
`(:background ,bg-color :foreground ,bg-color)))
(setq-local cursor-type nil))))
(add-hook 'helm-minibuffer-set-up-hook
'spacemacs//helm-hide-minibuffer-maybe)
Useful abbreviations when codng in HTML.
(use-package emmet-mode
:ensure t)
Colorize color names and codes in the correct color.
(use-package rainbow-mode
:ensure t)
(use-package tj3-mode
:ensure t)
(use-package writeroom-mode
:ensure t
:init
(global-set-key (kbd "C-p w") 'writeroom-mode))
(use-package wgrep
:ensure t)
(defun single-lines-only ()
"replace multiple blank lines with a single one"
(interactive)
(goto-char (point-min))
(while (re-search-forward "\\(^\\s-*$\\)\n" nil t)
(replace-match "\n")
(forward-char 1)))
(defun paf/cleanup-ledger-buffer ()
"Cleanup the ledger file"
(interactive)
(delete-trailing-whitespace)
(single-lines-only)
(ledger-mode-clean-buffer)
(ledger-sort-buffer))
(use-package ledger-mode
:ensure nil
:pin manual
:mode "\\.ledger\\'"
:bind ("<f6>" . 'paf/cleanup-ledger-buffer)
:config
(setq ledger-reconcile-default-commodity "CHF"))
Let’s try this too, even though I do not quite get the point of this whole package yet.
NOTE assigns hui-search-web
to C-c C-/
to not clobber the later used
C-c /
from OrgMode (org-mode sparse trees)
This works because hyperbole will first check if the function
is already bound to some key before binding it to the coded
default.
(use-package hyperbole
:ensure t
:config
(bind-key "C-c C-/" 'hui-search-web) ;; bind before calling require
(require 'hyperbole))
A tree-view navigation of files, with diff tool for directories.
(use-package ztree
:ensure t)
Load all my org stuff, but first org-mode itself.
If variable org-directory
is not set yet, map it to my home’s files.
You may set this in the ~/.emacs
to another value, e.g.
(setq org-directory "/ssh:fleury@machine.site.com:OrgFiles")
NEXT This does not seem to work, check out doc about defcustom
- State “NEXT” from [2019-06-24 Mon 10:10]
(use-package org
:ensure nil
:config
(if (not (boundp 'org-directory))
(setq org-directory "~/OrgFiles")))
Let’s bind this to a key, so I can open remote dirs. I suually put
this in my .emacs
as it is host- and user-specific.
(defun paf/open-remote-org-dir ()
(interactive)
(dired "/ssh:remote.host.com:OrgFiles"))
(global-set-key (kbd "C-p r o") 'paf/open-remote-org-dir)
In your .emacs
just add this to configure the location:
(setq remote-org-directory "/ssh:fleury@my.hostname.com:OrgFiles")
Then you can use the keyboard shortcut to open that dir.
(defcustom remote-org-directory "~/OrgFiles"
"Location of remove OrgFile directory, should you have one."
:type 'string
:group 'paf)
(defun paf/open-remote-org-directory ()
(interactive)
(find-file remote-org-directory))
(global-set-key (kbd "C-p r o") 'paf/open-remote-org-directory)
Let other tools use emacs client to interact
(require 'org-protocol)
(defun org-relative-file (filename)
"Compute an expanded absolute file path for org files"
(expand-file-name filename org-directory))
Make sure archiving preserves the same tree structure, including when archiving subtrees. source on worg
(defun my-org-inherited-no-file-tags ()
(let ((tags (org-entry-get nil "ALLTAGS" 'selective))
(ltags (org-entry-get nil "TAGS")))
(mapc (lambda (tag)
(setq tags
(replace-regexp-in-string (concat tag ":") "" tags)))
(append org-file-tags (when ltags (split-string ltags ":" t))))
(if (string= ":" tags) nil tags)))
This used to work, but org-extract-archive-file
is no longer defined.
(defadvice org-archive-subtree
(around my-org-archive-subtree-low-level activate)
(let ((tags (my-org-inherited-no-file-tags))
(org-archive-location
(if (save-excursion (org-back-to-heading)
(> (org-outline-level) 1))
(concat (car (split-string org-archive-location "::"))
"::* "
(car (org-get-outline-path)))
org-archive-location)))
ad-do-it
(with-current-buffer (find-file-noselect (org-extract-archive-file))
(save-excursion
(while (org-up-heading-safe))
(org-set-tags tags)))))
Dynamically adjust tag position source on worg
(defun ba/org-adjust-tags-column-reset-tags ()
"In org-mode buffers it will reset tag position according to
`org-tags-column'."
(when (and
(not (string= (buffer-name) "*Remember*"))
(eql major-mode 'org-mode))
(let ((b-m-p (buffer-modified-p)))
(condition-case nil
(save-excursion
(goto-char (point-min))
(command-execute 'outline-next-visible-heading)
;; disable (message) that org-set-tags generates
(cl-letf (((symbol-function 'message) #'format))
(org-set-tags 1 t))
(set-buffer-modified-p b-m-p))
(error nil)))))
(defun ba/org-adjust-tags-column-now ()
"Right-adjust `org-tags-column' value, then reset tag position."
(set (make-local-variable 'org-tags-column)
(- (- (window-width) (length org-ellipsis))))
(ba/org-adjust-tags-column-reset-tags))
(defun ba/org-adjust-tags-column-maybe ()
"If `ba/org-adjust-tags-column' is set to non-nil, adjust tags."
(when ba/org-adjust-tags-column
(ba/org-adjust-tags-column-now)))
(defun ba/org-adjust-tags-column-before-save ()
"Tags need to be left-adjusted when saving."
(when ba/org-adjust-tags-column
(setq org-tags-column 1)
(ba/org-adjust-tags-column-reset-tags)))
(defun ba/org-adjust-tags-column-after-save ()
"Revert left-adjusted tag position done by before-save hook."
(ba/org-adjust-tags-column-maybe)
(set-buffer-modified-p nil))
;; between invoking org-refile and displaying the prompt (which
;; triggers window-configuration-change-hook) tags might adjust,
;; which invalidates the org-refile cache
(defadvice org-refile (around org-refile-disable-adjust-tags)
"Disable dynamically adjusting tags"
(let ((ba/org-adjust-tags-column nil))
ad-do-it))
(ad-activate 'org-refile)
;; Now set it up
(setq ba/org-adjust-tags-column t)
;; automatically align tags on right-hand side
;; TODO(fleury): Does not seem to work as of 2017/12/18
;; Seems to work again 2018/11/01
(add-hook 'window-configuration-change-hook
'ba/org-adjust-tags-column-maybe)
(add-hook 'before-save-hook 'ba/org-adjust-tags-column-before-save)
(add-hook 'after-save-hook 'ba/org-adjust-tags-column-after-save)
(add-hook 'org-agenda-mode-hook (lambda ()
(setq org-agenda-tags-column (- (window-width)))))
- State “TODO” from [2019-01-12 Sat 12:08]
org-set-tags
with > 1 args is not working.
Not sure what to replace it with though…
Refresh org-mode agenda regularly. source on worg There are two functions that supposedly do the same.
(defun kiwon/org-agenda-redo-in-other-window ()
"Call org-agenda-redo function even in the non-agenda buffer."
(interactive)
(let ((agenda-window (get-buffer-window org-agenda-buffer-name t)))
(when agenda-window
(with-selected-window agenda-window (org-agenda-redo)))))
(defun update-agenda-if-visible ()
(interactive)
(let ((buf (get-buffer "*Org Agenda*"))
wind)
(if buf
(org-agenda-redo))))
Show the agenda when emacs left idle. source on worg
(defun jump-to-org-agenda ()
(interactive)
(let ((buf (get-buffer "*Org Agenda*"))
wind)
(if buf
(if (setq wind (get-buffer-window buf))
(select-window wind)
(if (called-interactively-p 'any)
(progn
(select-window (display-buffer buf t t))
(org-fit-window-to-buffer)
(org-agenda-redo)
)
(with-selected-window (display-buffer buf)
(org-fit-window-to-buffer)
;;(org-agenda-redo)
)))
(call-interactively 'org-agenda-list)))
;;(let ((buf (get-buffer "*Calendar*")))
;; (unless (get-buffer-window buf)
;; (org-agenda-goto-calendar)))
)
From some help on this page I think this could work:
(defun paf/org-agenda-get-location()
"Gets the value of the LOCATION property"
(let ((loc (org-entry-get (point) "LOCATION")))
(if (> (length loc) 0)
loc
"")))
Also, to set this after org-mode has loaded (see here):
(with-eval-after-load 'org-agenda
(add-to-list 'org-agenda-prefix-format
'(agenda . " %-12:c%?-12t %(paf/org-agenda-get-location)% s"))
Should follow this git repo: org-gtasks I have copied a version of the file here, it’s not yet available on MELPA.
(use-package request
:ensure t)
(load-file "~/Emacs/org-gtasks.el")
I have this currently in my `~/.emacs`:
(use-package org-gtasks
:init
(org-gtasks-register-account
:name "pascal"
:directory "~/OrgFiles/GTasks/"
:client-id "XXX"
:client-secret "XXX"))
Collect properties into tables. See documentation in the file.
(load-file "~/Emacs/org-collector.el")
These are mostly org-config specific to me, myself and I.
(global-set-key (kbd "C-c l") 'org-store-link)
(global-set-key (kbd "C-c c") 'org-capture)
(global-set-key (kbd "C-c a") 'org-agenda)
(global-set-key (kbd "C-c b") 'org-iswitchb)
(add-hook 'org-mode-hook
(lambda ()
(local-set-key (kbd "C-<up>") 'org-move-subtree-up)
(local-set-key (kbd "C-<down>") 'org-move-subtree-down)
(local-set-key (kbd "C-c l") 'org-store-link)
(local-set-key (kbd "C-c C-l") 'org-insert-link)))
Some config for display.
(setq org-hide-leading-stars 't)
(setq org-log-done 't)
(setq org-startup-folded 't)
(setq org-startup-indented 't)
(setq org-startup-folded 't)
(setq org-ellipsis "...")
; Don't really like the new bullets though.
;;(use-package 'org-bullets
;; :config
;; (add-hook 'org-mode-hook (lambda () (org-bullets-mode 1))))
(use-package org-habit
:config
(setq org-habit-graph-column 38)
(setq org-habit-preceding-days 35)
(setq org-habit-following-days 10)
(setq org-habit-show-habits-only-for-today nil))
(setq org-babel-sh-command "bash")
clock stuff into a drawer.
(setq org-clock-into-drawer t)
(setq org-log-into-drawer t)
(setq org-clock-int-drawer "CLOCK")
config for org-mobile-*
(setq org-mobile-directory (org-relative-file "Mobile"))
(setq org-mobile-inbox-for-pull (org-relative-file "mobileorg.org"))
F12 open the first agenda file
(defun org-get-first-agenda-file ()
(interactive)
(find-file (elt org-agenda-files 0)))
(global-set-key [f12] 'org-get-first-agenda-file)
; F12 on Mac OSX displays the dashboard....
(global-set-key [C-f12] 'org-get-first-agenda-file)
This will start serving the org files through the emacs-based webbrowser when pressing M-f12 (on localhost:55555)
(use-package org-ehtml
:ensure t
:config
(setq org-ehtml-docroot (expand-file-name org-directory))
(setq org-ehtml-everything-editable t)
(setq org-ehtml-allow-agenda t))
(defun paf/start-web-server ()
(interactive)
(ws-start org-ehtml-handler 55555))
(global-set-key (kbd "<M-f12>") 'paf/start-web-server)
This lets one write links as e.g. [ [b:123457] ]
(setq org-link-abbrev-alist
'(("b" . "http://b/")
("go" . "http://go/")
("cl" . "http://cr/")))
(use-package org-secretary
:ensure org-plus-contrib
:config
(setq org-sec-me "paf")
(setq org-tag-alist '(("PRJ" . ?p)
("DESIGNDOC" . ?D)
("Milestone" . ?m)
("DESK" . ?d)
("HOME" . ?h)
("VC" . ?v))))
Track task dependencies, and dim them in in the agenda.
(setq org-enforce-todo-dependencies t)
(setq org-agenda-dim-blocked-tasks 'invisible)
(setq org-global-properties
'(("Effort_ALL". "0 0:10 0:30 1:00 2:00 4:00 8:00 16:00")))
(setq org-columns-default-format
"%TODO %30ITEM %3PRIORITY %6Effort{:} %10DEADLINE")
(setq org-todo-keywords
'((sequence "TODO(t!)" "NEXT(n!)" "STARTED(s!)" "WAITING(w!)" "AI(a!)" "|" "DONE(d!)" "CANCELLED(C@)" "DEFERRED(D@)" "SOMEDAY(S!)" "FAILED(F!)" "REFILED(R!)")
(sequence "APPLIED(A!)" "WAITING(w!)" "ACCEPTED" "|" "REJECTED" "PUBLISHED")
(sequence "TASK(m!)" "|" "DONE(d!)" "CANCELLED(C@)" )))
(setq org-tags-exclude-from-inheritance '("PRJ")
org-use-property-inheritance '("PRIORITY")
org-stuck-projects '("+PRJ/-DONE-CANCELLED"
; it is considered stuck if there is no next action
(;"TODO"
"NEXT" "STARTED" "TASK") ()))
(setq org-todo-keyword-faces '(
("TODO" . (:foreground "purple" :weight bold))
("TASK" . (:foreground "steelblue" :weight bold))
("NEXT" . (:foreground "red" :weight bold))
("STARTED" . (:foreground "darkgreen" :weight bold))
("WAITING" . (:foreground "orange" :weight bold))
("FLAG_GATED" . (:foreground "orange" :weight bold))
("SOMEDAY" . (:foreground "steelblue" :weight bold))
("MAYBE" . (:foreground "steelblue" :weight bold))
("AI" . (:foreground "red" :weight bold))
("NEW" . (:foreground "orange" :weight bold))
("RUNNING" . (:foreground "orange" :weight bold))
("WORKED" . (:foreground "green" :weight bold))
("FAILED" . (:foreground "red" :weight bold))
("REFILED" . (:foreground "gray"))
; For publications
("APPLIED" . (:foreground "orange" :weight bold))
("ACCEPTED" . (:foreground "orange" :weight bold))
("REJECTED" . (:foreground "red" :weight bold))
("PUBLISHED" . (:foreground "green" :weight bold))
))
(setq org-agenda-custom-commands
'(("t" "Hot Today" ((agenda "" ((org-agenda-span 'day)))
(tags-todo "/NEXT")
(tags-todo "-dowith={.+}/STARTED")
(tags-todo "-dowith={.+}/WAITING")))
("n" "Agenda and all TODO's" ((agenda "") (alltodo "")))
("N" "Next actions" tags-todo
"-personal-doat={.+}-dowith={.+}/!-TASK-TODO"
((org-agenda-todo-ignore-scheduled t)))
("h" "Work todos" tags-todo
"-personal-doat={.+}-dowith={.+}/!-TASK"
((org-agenda-todo-ignore-scheduled t)))
("H" "All work todos" tags-todo "-personal/!-TASK-CANCELLED"
((org-agenda-todo-ignore-scheduled nil)))
("A" "Work todos with doat or dowith" tags-todo
"-personal+doat={.+}|dowith={.+}/!-TASK"
((org-agenda-todo-ignore-scheduled nil)))
("j" "TODO dowith and TASK with"
((org-sec-with-view "TODO dowith")
(org-sec-where-view "TODO doat")
(org-sec-assigned-with-view "TASK with")
(org-sec-stuck-with-view "STUCK with")
(todo "STARTED")))
("J" "Interactive TODO dowith and TASK with"
((org-sec-who-view "TODO dowith")))))
Make the calendar day info a bit more visible. Move this into the custom-set-faces in ~/.emacs
;; '(org-agenda-date ((t (:inherit org-agenda-structure :background "pale green" :foreground "black" :weight bold))) t)
;; '(org-agenda-date-weekend ((t (:inherit org-agenda-date :background "light blue" :weight bold))) t)
;; '(org-agenda-current-time ((t (:inherit org-time-grid :foreground "yellow" :weight bold))))
A more visible current-time marker in the agenda
(setq org-agenda-current-time-string ">>>>>>>>>> NOW <<<<<<<<<<")
;; will refresh it only if already visible
(run-at-time nil 180 'update-agenda-if-visible)
;;(add-hook 'org-mode-hook
;; (lambda () (run-at-time nil 180 'kiwon/org-agenda-redo-in-other-window)))
This would open the agenda if any org file was opened. In the end, I don’t like this feature, so it is disabled by not tangling it.
;; Make this happen only if we open an org file.
(add-hook 'org-mode-hook
(lambda () (run-with-idle-timer 600 t 'jump-to-org-agenda)))
This will save them regularly when the idle for more than a minute.
(add-hook 'org-mode-hook
(lambda () (run-with-idle-timer 180 t 'org-save-all-org-buffers)))
That’s the export function to update the agenda view.
(setq org-agenda-exporter-settings
'((ps-number-of-columns 2)
(ps-portrait-mode t)
(org-agenda-add-entry-text-maxlines 5)
(htmlize-output-type 'font)))
(defun dmg-org-update-agenda-file (&optional force)
(interactive)
(save-excursion
(save-window-excursion
(let ((file "~/www/agenda/agenda.html"))
(org-agenda-list)
(org-agenda-write file)))))
(use-package org-duration
:config
(setq org-duration-units
`(("min" . 1)
("h" . 60)
("d" . ,(* 60 8))
("w" . ,(* 60 8 5))
("m" . ,(* 60 8 5 4))
("y" . ,(* 60 8 5 4 10)))
)
(org-duration-set-regexps))
Capture and refile stuff, with some templates that I think are useful.
(setq org-default-notes-file (org-relative-file "refile.org"))
(setq org-capture-templates
`(("a" "Action Item" entry (file+headline ,(org-relative-file "refile.org") "Tasks")
"* AI %?\n %U")
("m" "Meeting" entry (file+headline ,(org-relative-file "refile.org") "Meetings")
"* %U :MTG:\n %^{with}p\n%?")
("n" "Note" entry (file+headline ,(org-relative-file "refile.org") "Notes")
"* %?\n%U")
("j" "Journal" entry (file+datetree ,(org-relative-file "journal.org"))
"* %?\n %U")))
; show up to 2 levels for refile targets, in all agenda files
(setq org-refile-targets '((org-agenda-files . (:maxlevel . 2))))
(setq org-log-refile t) ;; will add timestamp when refiled.
; from: http://doc.norang.ca/org-mode.html
; Exclude DONE state tasks from refile targets
(defun bh/verify-refile-target ()
"Exclude todo keywords with a done state from refile targets"
(not (member (nth 2 (org-heading-components)) org-done-keywords)))
(setq org-refile-target-verify-function 'bh/verify-refile-target)
This presentation generator is still under review (by me).
NOTE Currently problematic as it depends on org-20190225 which does not display the calendar right.
;;(add-to-list 'org-structure-template-alist
;; (list "n" . "#+BEGIN_NOTES\n\?\n#+END_NOTES"))
;; disable the addition in the lib that does not do it right for Org 9.2
(setq org-reveal-note-key-char nil)
;; import as usual.
(use-package ox-reveal
:ensure t)
What kind of code block languages do I need
(setq org-confirm-babel-evaluate 'nil) ; Don't ask before executing
(org-babel-do-load-languages
'org-babel-load-languages
'(
(R . t)
(dot . t)
(emacs-lisp . t)
(gnuplot . t)
(python . t)
(ledger . t)
;;(sh . t)
(latex . t)
(plantuml . t)
(shell . t)
))
Add a few formats to the export functionality of org-mode.
(use-package ox-odt)
(use-package ox-taskjuggler)
Tell where PlantUML is to be found. This needs to be downloaded and installed separately, see the PlantUML website.
You could install the PlantUML JAR file with this snippet:
URL='http://sourceforge.net/projects/plantuml/files/plantuml.jar/download'
DIR="${HOME}/Apps"
[[ -d "${DIR}" ]] || mkdir -p "${DIR}"
(cd "${DIR}" && curl -o plantuml.jar "${URL}")
ls -l "${DIR}/plantuml.jar"
(use-package plantuml-mode
:ensure t
:config
(setq plantuml-jar-path "~/Apps/plantuml.jar")
(setq org-plantuml-jar-path "~/Apps/plantuml.jar")
;; Let us edit PlantUML snippets in plantuml-mode within orgmode
(add-to-list 'org-src-lang-modes '("plantuml" . plantuml))
;; Enable plantuml-mode for PlantUML files
(add-to-list 'auto-mode-alist '("\\.plantuml\\'" . plantuml-mode)))
Make the display of images a simple key-stroke away.
(use-package iimage
:config
(add-to-list 'iimage-mode-image-regex-alist
(cons (concat "\\[\\[file:\\(~?" iimage-mode-image-filename-regex
"\\)\\]") 1))
(defun org-toggle-iimage-in-org ()
"display images in your org file"
(interactive)
(if (face-underline-p 'org-link)
(set-face-underline 'org-link nil)
(set-face-underline 'org-link t))
(iimage-mode 'toggle))
(add-hook 'org-mode-hook (lambda ()
;; display images
(local-set-key "\M-I" 'org-toggle-iimage-in-org)
)))
A bit difficult to find the docs of how to use it, but it seems quite useful.
Disabled, as it causes only trouble to me, and I am not really using it anyway.
(use-package pdf-tools
:if (and (eq system-type 'gnu/linux) ;; Set it up on Linux
(not (string-prefix-p "aarch64" system-configuration))) ;; but not mobile devices
:pin manual ;; update only manually
:config
;; initialize
(pdf-tools-install)
(setq-default pdf-view-display-size 'fit-page) ;; Fit to page when opening
(add-hook 'pdf-view-mode-hook (lambda () (cua-mode 0))) ;; turn off cua so copy works
(setq pdf-view-resize-factor 1.1) ;; more fine-grained zoom control
;; keyboard shortcuts
(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))
(use-package org-pdfview
:after (pdf-tools)
:init
(add-to-list 'org-file-apps '("\\.pdf\\'" . org-pdfview-open))
(add-to-list 'org-file-apps '("\\.pdf::\\([[:digit:]]+\\)\\'" . org-pdfview-open)))
# for all the native apps related to PDF tools
sudo apt-get install pdf-tools
This is a note-taking packages inspired by the principles of the Zettelkasten
(use-package deft
:ensure t)
(use-package avy
:ensure t)
(use-package zetteldeft
:ensure nil
:after (org deft avy)
:config
(setq deft-extensions '("org" "md" "txt"))
(setq deft-directory (concat org-directory "/Zettelkasten"))
(setq deft-recursive t)
:bind (("C-p C-k d" . deft)
("C-p C-k D" . zetteldeft-deft-new-search)
("C-p C-k R" . deft-refresh)
("C-p C-k s" . zetteldeft-search-at-point)
("C-p C-k c" . zetteldeft-search-current-id)
("C-p C-k f" . zetteldeft-follow-link)
("C-p C-k F" . zetteldeft-avy-file-search-ace-window)
("C-p C-k l" . zetteldeft-avy-link-search)
("C-p C-k t" . zetteldeft-avy-tag-search)
("C-p C-k T" . zetteldeft-tag-buffer)
("C-p C-k i" . zetteldeft-find-file-id-insert)
("C-p C-k I" . zetteldeft-find-file-full-title-insert)
("C-p C-k o" . zetteldeft-find-file)
("C-p C-k n" . zetteldeft-new-file)
("C-p C-k N" . zetteldeft-new-file-and-link)
("C-p C-k r" . zetteldeft-file-rename))
)
Update the version by downloading the latest version here:
wget https://raw.githubusercontent.com/EFLS/zetteldeft/master/zetteldeft.el -O ~/Emacs/zetteldeft.el