This is the GNU/Emacs config file of Karl Voit.
This file is named config.org. My init.el got some nifty Elisp
code that converts/tangles (only) the Elisp blocks into the
config.el. And here I explained how this is done. This generated
file is interpreted by my GNU/Emacs on startup.
Note that all Elisp blocks part of a DISABLED heading or which are
marked with :tangle no won’t be tangled to the config.el file.
Unfortunately, within the Org-mode rendering of GitHub, you won’t see
the =DISABLED= keyword nor the =:tangle no= parameter of the babel
blocks. Please get the Org-mode file and open it in your Emacs
directly.
Originally, I found this process on this web page. However, I adapted its code and write additional features.
Links that start with id: won’t work for you because they link to my
personal Org-mode files.
Some tasks I plan to do with my config.org:
- [ ] FIXXME: think of merging the default dir
.emacs.d/quelpa/with.emacs.d/contrib/ - [ ] FIXXME: migrate existing GitHub projects to quelpa
- [ ] FIXXME: check why Python “auto-complete mode” is disabled in my config
- [ ] FIXXME: check why Python > Ropemacs (for refactoring) is disabled in my config
- [ ] FIXXME: add a table to each package with its history in my config:
2020-01-13 installed because of X 2020-01-15 disabled because issue Y 2020-01-19 enabled again after fixing with Z
What Solution I Am Using for Which I Consider My Main Use-Cases
Corresponding to my general blog article What App am I Using for What and How? I maintain this brief overview of my most important workflows for Emacs and what package solution I am using for it. If you want to learn more about my workflows, I recommend reading and following my Blog Series: Using Org Mode Features (UOMF).
If you want to read how my init.el is auto-generated from this Org
mode file, read this article.
I do not maintain links to the sections below since this would be a very fragile task anyway considering the way GitHub links work for now. Therefore: if you are interested in details on a certain workflow, please do search for corresponding keywords. There are seldom multiple search hits except for separate key binding definitions or hydras.
| Workflow | Solution | Notes |
|---|---|---|
| Installing software packages | use-package with packages and git repositories | |
| “Window management” | eyebrowse with a decent hydra-buffers | top feature |
| Remembering bindings; cheatcheat | a hydra on F1 for each major mode; which-key | top feature |
| Naked and full-screen Emacs | my-toggle-naked-emacs() | unclutter screen |
| Getting rid of scrollbar | nyan-mode | Get more horizontal screen space |
| Reducing clutter in mode line | smart-mode-line, mode-icons | |
| Filter Org files | sparse trees | |
| Focus on Org sub-hierarchy | customized org-tree-to-indirect-buffer | |
| Enhanced search/selection usability | swiper, counsel, helm, helm-org-rifle | |
| Switching buffers | ibuffer | |
| Desktop notifications | alert | |
| Inserting date/time-stamps | my-insert-timestamp(), my-insert-datestamp(), | |
| Inserting characters | char-menu, M-x insert-char | |
| Copying region to Org property | my-org-region-to-property() | very handy for org-contacts |
| Org to PDF export | normal Org mode export via LaTeX (not pandoc) | |
| Passwords | org-crypt on Org mode headings | |
| Coding python | elpy, flycheck | |
| Coding: Highlighting lines/words | bm, highlight-symbol | |
| Coding: Folding/unfolding | yafolding | |
| Versioning files | magit | |
| Snippet management | yankpad with yasnippet | advanced workflows |
| Spell checking | flyspell with aspell | |
| Formatting paragraphs | my-fill-or-unfill() | |
| Formatting headings | my-title-capitalization() | |
| File management | dired with some very cool extensions | I’m still getting used to |
| Quickly jumping to a directory | my-dired-recent-dirs() | top featurel; based on frecency |
| PDF reading | pdf-tools | I’m still getting used to |
| PDF annotating | pdf-tools | I’m still getting used to |
| Record screencasts | gif-screencast and non-emacs methods |
What I’m not using at the moment:
- projectile or other source code project management tools
- vim bindings (evil, …)
- configuration frameworks
- reading and managing emails: I’d love to use
notmuchbut I can’t
You might want to take a look at the next section where I list my most
important generic hydras in contrast to the F1-mapped mode hydras.
bug-hunter
;; remove comment characters when using but-hunter to bi-sect this file:
; -------------------------------------------------------------------------------------------
; (package-initialize)
; (defvar my-init-el-start-time (current-time) "Time when init.el was started")
; (setq my-user-emacs-directory "~/.emacs.d/")
; (add-to-list 'load-path (concat my-user-emacs-directory "contrib/org-mode/contrib/lisp"))
; (add-to-list 'load-path (concat my-user-emacs-directory "contrib/org-mode/lisp"))
; (require 'org)
; -------------------------------------------------------------------------------------------literate test 1
Testing the noweb principle as shown on this page: https://www.hhyu.org/posts/literate_config/
- [2021-02-05 Fri 11:09] issue: my (very fast) custom function to tangle does not handle noweb syntax and Holger’s page (the original author of the tangle function) doesn’t exist any more.
;; nowebtest3
(setq nowebtest3 t);; nowebtest1
<<nowebtest>>Function keys
Here are my function-key-mappings that are included in most hydra help screens:
(setq my-f-key-settings (concat
"⇧ Git ←change→ ┃ yp-exp yp-map ┃ Project minimap Beginner Bright
" (propertize
" F1 F2 F3 F4 ┃ F5 F6 F7 F8 ┃ F9 F10 F11 F12
" 'face '(:foreground "green"))
" Hydra Windows ★ ┃ spell (←) error → fix ┃ Search Menu maximize naked
"))General settings
Here, I do set some very general settings for my GNU/Emacs.
profiling:
(defvar my-config-el-start-time (current-time) "Time when config.el was started")
;(profiler-start 'cpu);; test startup performance - create report with M-x profiler-report
;; from http://ergoemacs.org/emacs/elisp_datetime.html
(setq my-config-el-start-time-iso (concat
(format-time-string "%Y-%m-%dT%T")
((lambda (x) (concat (substring x 0 3) ":" (substring x 3 5)))
(format-time-string "%z"))))2011-04-20: turn off backup files
(setq-default backup-inhibited t)set start of week to Monday (not sunday) http://sunsite.univie.ac.at/textbooks/emacs/emacs_33.html
(setq-default calendar-week-start-day 1)omit usage of TAB for C-x r o: indent-tabs-mode
(setq-default indent-tabs-mode nil)append and update time-stamps for Time-stamp: <> in headers:
(add-hook 'write-file-hooks 'time-stamp)set warning of opening large files to 100MB
(setq-default large-file-warning-threshold 100000000)do not add double space after periods Real sentence in Emacs : emacs
(setq-default sentence-end-double-space nil)https://www.emacswiki.org/emacs/TruncateLines M-x toggle-truncate-lines
(setq-default truncate-lines t)elisp - Emacs truncate lines in all buffers - Stack Overflow
(setq-default global-visual-line-mode t)inhibit the startup screen
(setq inhibit-startup-screen t)English time-stamps in Org-mode (instead of localized German ones):
- http://lists.gnu.org/archive/html/emacs-orgmode/2011-10/msg01046.html
- «system locale to use for formatting time values (e.g., timestamps in Org mode files)»
- “en_US.utf8” did not work for the weekday in the agenda!
(setq system-time-locale "C")Adaptive cursor width | Pragmatic Emacs: make cursor the width of the character it is under; i.e. full width of a TAB:
(setq x-stretch-cursor t)Remember the position of a buffer and go to that position when re-opening the file: (2018-07-26 disabled because it is not always a good thing to do)
(setq-default save-place t)
(setq save-place-file (expand-file-name ".places" user-emacs-directory))
(save-place-mode 1)(load-file (concat my-user-emacs-directory "private.el"))Tip via irreal. I share the same rationale: I never answer anything different to “y”. So I disabled it:
(setq confirm-kill-processes nil)Moves the mouse cursor out of the way when the text cursor seems to crash: documentation.
Possible values: banish, exile, jump, animate, proteus
(when (display-mouse-p) (setq mouse-avoidance-mode "animate"))A tip from this wonderful blog article: map scroll-lock mode to the corresponding scroll-lock key:
(global-set-key (kbd "<Scroll_Lock>") 'scroll-lock-mode)To avoid “Error saving to X clipboard manager.” as well as endless loop on exiting (see this):
(setq x-select-enable-clipboard-manager nil)Turn off header when printing with M-x ps-print-buffer-with-faces and format according to this page:
(setq ps-paper-type 'a4
ps-font-size 9.0
ps-print-header nil
ps-landscape-mode nil
ps-number-of-columns 1)Open file system read-only files as read-only in Emacs as well: (via this article)
(setq view-read-only t)I’m not using abbrev mode and get annoyed by its questions:
;(save-abbrevs 'silently) ;; Silently save abbrevs: http://ergoemacs.org/emacs/emacs_abbrev_mode_tutorial.html
(setq save-abbrevs nil) ;; not saving abbrevs
(setq-default abbrev-mode nil)Guru mode
(defun disable-guru-mode ()
(guru-mode -1)
)
(add-hook 'prelude-prog-mode-hook 'disable-guru-mode t)Package
Configure the package manager(s) of my GNU/Emacs.
MELPA
http://www.reddit.com/r/emacs/comments/2u1bml/gnu_or_melpa_version_of_yasnippet_both_in_mx/
MELPA packages are usually built automatically from a project’s repository; the GNU repository has stable releases that are explicitly submitted to it.
package-user-dir holds the directory where Emacs package manager
installs its local copies of the packages:
(setq gnutls-algorithm-priority "NORMAL:-VERS-TLS1.3") ;; from https://irreal.org/blog/?p=8243
(setq package-user-dir (concat my-user-emacs-directory "elpa"))
(require 'package)
(package-initialize)
;;2019-12-07;; ;;(add-to-list 'package-archives '("marmalade" . "https://marmalade-repo.org/packages/"))
;;2019-12-07;; ;;OLD:(add-to-list 'package-archives '("melpa" . "http://melpa.milkbox.net/packages/"));; moved to stable.melpa.org https://www.reddit.com/r/emacs/comments/4zqbz0/whats_up_with_melpa_stable/
;;2019-12-07;; (add-to-list 'package-archives '("melpa" . "http://stable.melpa.org/packages/"))
;;2019-12-07;; ;;unstable;; (add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/"))
;;2019-12-07;;
;;2019-12-07;; ;; 2017-03-26: from https://www.reddit.com/r/emacs/comments/61jsvy/melpa_stopped_working_over_https_for_me_any_ideas/
;;2019-12-07;; (add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/"))
;;2019-12-07;; (add-to-list 'package-archives '("gnu" . "http://elpa.gnu.org/packages/"))
;; 2019-12-07: severe issues with old package versions brings me to remove old config and start with this from docu:
(setq package-archives '(
("melpa" . "https://melpa.org/packages/")
("gnu" . "https://elpa.gnu.org/packages/")
))- 2020-04-16: Some statistics about MELPA
Elpy
Add elpy repository:
(add-to-list 'package-archives '("elpy" . "https://jorgenschaefer.github.io/packages/"))fix certificate issue
Bugfixing: 2016-01-26: fix certificate issue: “gnutls.c: [0] (Emacs) fatal error: The TLS connection was non-properly terminated.”
- https://github.com/nicferrier/elmarmalade/issues/55#issuecomment-166271364
- 2016-11-05: got «(void-function gnutls-available-p)» on floyd (after org upgrade)
(if (fboundp 'gnutls-available-p)
(fmakunbound 'gnutls-available-p))
(setq tls-program '("gnutls-cli --tofu -p %p %h")
imap-ssl-program '("gnutls-cli --tofu -p %p %s")
smtpmail-stream-type 'starttls
starttls-extra-arguments '("--tofu")
)Initialize misc packages
;; 2015-11-25: https://github.com/jwiegley/use-package
;(when (string-equal system-type "windows-nt")
; (add-to-list 'load-path (concat package-user-dir "/use-package-20190405.2047"))
;)
(eval-when-compile
(require 'use-package))
;(require 'diminish)
(require 'bind-key)
;; http://www.lunaryorn.com/2015/01/06/my-emacs-configuration-with-use-package.html
(setq package-enable-at-startup nil)
(unless (package-installed-p 'use-package)
(package-refresh-contents)
(package-install 'use-package))
(use-package f
:ensure t
)
(use-package ivy
:ensure t
:config
;; 2019-12-07: this is found in https://github.com/abo-abo/swiper/blob/master/ivy.el (Version: 0.13.0)
;; but not in the elpa package version 0.13.0 on my disk. Don't know why/how, just adding it as a workaround:
(defcustom ivy-use-group-face-if-no-groups t
"If t, and the expression has no subgroups, highlight whole match as a group.
It will then use the second face (first of the \"group\" faces)
of `ivy-minibuffer-faces'. Otherwise, always use the first face
in this case."
:type 'boolean)
)
(use-package ht
:ensure t
)Quelpa
DISABLED because of:
Debugger entered--Lisp error: (file-error "Cannot open load file" "No such file or directory" "use-package-core")
require(use-package-core)
eval-buffer(#<buffer *load*-463556> nil "/home/vk/.emacs.d/elpa/quelpa-use-package-20190210.1938/quelpa-use-package.el" nil t) ; Reading at buffer position 1691
load-with-code-conversion("/home/vk/.emacs.d/elpa/quelpa-use-package-20190210.1938/quelpa-use-package.el" "/home/vk/.emacs.d/elpa/quelpa-use-package-20190210.1938/quelpa-use-package.el" nil t)
require(quelpa-use-package)
eval-buffer(#<buffer *load*-218457> nil "/home/vk/.emacs.d/config.el" nil t) ; Reading at buffer position 4033
load-with-code-conversion("/home/vk/.emacs.d/config.el" "/home/vk/.emacs.d/config.el" nil nil)
load("/home/vk/.emacs.d/config.el" nil nil t)
load-file("~/.emacs.d/config.el")
… including auto-update:
(if (require 'quelpa nil t)
(quelpa-self-upgrade)
(with-temp-buffer
(url-insert-file-contents "https://framagit.org/steckerhalter/quelpa/raw/master/bootstrap.el")
(eval-buffer)))(quelpa
'(quelpa-use-package
:fetcher git
:url "https://framagit.org/steckerhalter/quelpa-use-package.git"))
(require 'quelpa-use-package)After that it is possible to call use-package with the :quelpa keyword:
EXAMPLES:
;; installs abc-mode with quelpa
(use-package abc-mode :quelpa)
;; does the same (`t' is optional)
(use-package abc-mode :quelpa t)
;; again... (if the package would have another name)
(use-package abc-mode :quelpa abc-mode)
;; passes upgrade parameter to quelpa
(use-package abc-mode :quelpa (:upgrade t))
;; uses the given recipe
(use-package abc-mode
:quelpa (abc-mode :fetcher github :repo "mkjunker/abc-mode"))
;; recipe with plist arguments
(use-package abc-mode
:quelpa ((abc-mode :fetcher github :repo "mkjunker/abc-mode") :upgrade t))Read https://github.com/alphapapa/unpackaged.el#upgrade-a-quelpa-use-package-forms-package for upgrading quelpa packages.
Upper/lower-case
Many times, I do need to uppercase or lowercase a word. Those commands offer me quick shortcuts to do so.
See: id:2014-03-04-M-l-subword
(global-set-key [M-l] 'downcase-word)
(global-set-key [M-u] 'upcase-word)
(global-set-key [M-c] 'capitalize-word)yes-or-no-p: prefer y/n
«True #Emacs Knights are lazy and hate typing yes/no - they prefer y/n instead. Use this (fset ‘yes-or-no-p ‘y-or-n-p) in your config.» … from: http://twitter.com/emacs_knight/status/128339316417101825
(fset 'yes-or-no-p 'y-or-n-p)Deletes duplicate entries of the history of the minibuffer
«If the value of this variable is t, that means when adding a new history element, all previous identical elements are deleted.» from: http://www.gnu.org/software/emacs/manual/html_node/elisp/Minibuffer-History.html
(setq history-delete-duplicates t)This is also necessary to avoid duplicate entries when searching with
helm on Emacs 27 as shown here.
Pasting with the mouse without moving the point
«middle-clicking pastes at the current location instead of moving it» from: http://sachachua.com/blog/2017/04/emacs-pasting-with-the-mouse-without-moving-the-point-mouse-yank-at-point/
(setq mouse-yank-at-point t)Un-setting some keys
Here, I do unset some keys I don’t use so that they are not in my way when I accidentially use them:
;; \C-v scroll up
;; \C-t transpose-chars
(dolist (key '("\C-v" "\C-t"))
(global-unset-key key))delete-trailing-whitespace before saving
I don’t see any use of trailing whitespace. Previously, I had a
function to remove them mapped to my-map SPC but then I found out
that adding this as a general before-save-hook does the job
automatically:
2019-12-14: disabled because it consumed 20-40% of the time when saving large files. 22% on http://paste.grml.org/hidden/27a87675/
;;(bind-key (kbd "SPC") #'delete-trailing-whitespace my-map)
; (define-key org-mode-map (kbd "C-c C-, SPC") #'delete-trailing-whitespace);; workaround since line above doesn't work
;; 2016-02-06: https://www.reddit.com/r/emacs/comments/445w6s/whats_some_small_thing_in_your_dotemacs_that_you/
(add-hook 'before-save-hook 'delete-trailing-whitespace)Maximize frame window
Details: id:2016-03-27-maximize-window-init.el
[2020-12-10 Thu] Good read: Maximize the Emacs Frame on Startup | Emacs Redux
(toggle-frame-maximized)Alternative from: Tip: Setting initial frame size and position
;; Set initial frame size and position
(defun my/set-initial-frame ()
(let* ((base-factor 0.70)
(a-width (* (display-pixel-width) base-factor))
(a-height (* (display-pixel-height) base-factor))
(a-left (truncate (/ (- (display-pixel-width) a-width) 2)))
(a-top (truncate (/ (- (display-pixel-height) a-height) 2))))
(set-frame-position (selected-frame) a-left a-top)
(set-frame-size (selected-frame) (truncate a-width) (truncate a-height) t)))
(setq frame-resize-pixelwise t)
(my/set-initial-frame)Also mentioned:
I believe this works both in windows and in character terminals:
(setq default-frame-alist '((left . 0) (width . 141) (fullscreen . fullheight)))(You might have to change 141 to something larger if you have a huge monitor.)
Window Management
See hydra-buffers() near the end of this file for a nice summary.
See GitHub - karthink/popper: Emacs minor-mode to summon and dismiss buffers easily for defining pop-up buffers.
my-vsplit-last-buffer() my-hsplit-last-buffer ()
This is using the last buffer for splitting windows instead of the current one:
From this emacs config which stole it from Sacha and reddit:
(defun my-vsplit-last-buffer ()
(interactive)
(split-window-vertically)
(other-window 1 nil)
(switch-to-next-buffer))
(defun my-hsplit-last-buffer ()
(interactive)
(split-window-horizontally)
(other-window 1 nil)
(switch-to-next-buffer))
(bind-key "C-x 2" 'my-vsplit-last-buffer)
(bind-key "C-x 3" 'my-hsplit-last-buffer)my-frame-is-landscape() my-frame-is-portrait()
Following frame-width and frame-height values are returned when the Emacs frame (the thing which is called “window” on OS-level) is either higher or wider:
(frame-width) ;; portrait frame: 73; landscape frame: 190; quadratic frame: 47
(frame-height);; portrait frame: 56; landscape frame: 60 ; quadratic frame: 47In order to find out whether or not there is more space in the
horizontal or in the vertical line, I divide the width by two. This is
because characters (the measure returned by (frame-width) and
(frame-height)) are higher than wide approximately by factor two as
well:
(if (< (/ (frame-width) 2) (frame-height))
(message "portrait frame")
(message "landscape frame")
)So I define functions to check the frame aspect that return boolean values:
(defun my-frame-is-landscape ()
"Return true if Emacs frame is landscape and not portrait mode"
(< (/ (frame-width) 2) (frame-height))
)
;; (if (my-frame-is-landscape)
;; (message "portrait frame")
;; (message "landscape frame")
;; )
(defun my-frame-is-portrait ()
"Return true if Emacs frame is portrait and not landscape mode"
(not (my-frame-is-landscape))
)
(if (my-frame-is-portrait)
(message "The frame is in landscape mode")
(message "The frame is in portrait mode")
)Default split direction according to frame aspect ratio
On wide screens, I want my default split direction being side-by-side (vertical split). On tilted/high screens, the default split should be up/down (horizontal split). (Source)
Note: this might be no good idea when you are not working with single/maximized windows like I prefer for now.
The values of the thresholds on sting (30”, landscape) before I started overwriting them here:
split-width-threshold ;; Its value is 9999; Original value was 160 split-height-threshold ;; Its value is 80
(if (my-frame-is-landscape)
(setq split-width-threshold nil);; for vertical split
(setq split-width-threshold 1) ;; for horizontal split
)bookmarks
| 2021-06-05 | started to use bookmarks after watching this video |
(setq bookmark-save-flag 1) ;; save bookmarks on every change
(setq bookmark-default-file (concat my-user-emacs-directory "/var/bookmark-default.el")) ;; this was set somewhere else; I did not look how/why. I just set it here again to make it explicit.use-package and quelpa
My setup is using John Wiegley’s use-package for configuration and startup of external libraries. This has many advantages: flexibility, startup performance, readability.
Bootstrap use-package is stolen from this file:
(unless (package-installed-p 'use-package)
(package-refresh-contents)
(package-install 'use-package))
(eval-when-compile
(require 'use-package))
(use-package use-package
:ensure t
;;:pin MELPA
:config
(require 'use-package))Until 2020-06-30, I only used use-package and manually cloned git
repositories I included with hard-coded path. The latter were seldomly
updated (if ever). With quelpa, there seems to be a much better way.
(use-package quelpa
:ensure t
:config
(setq quelpa-upgrade-interval 7);; upgrade all packages once a week according to https://github.com/quelpa/quelpa
(add-hook #'after-init-hook #'quelpa-upgrade-all-maybe)
)The quelpa-use-package package offers a more or less transparent
bridge between sites like GitHub and the use-package features.
(use-package quelpa-use-package
:ensure t
)Examples
Here are some examples for future reference:
A very simple example for installing a package via package management and ensure it is installed when Emacs launches:
(use-package dumb-jump
:ensure t
:defer 110
)An example of loading a local package (not from Melpa or other package service):
(use-package define-word
:if (my-system-type-is-gnu)
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/mypackage/")))
:after org
)Key binding example from docu:
(use-package helm
:bind (("M-x" . helm-M-x)
("M-<f5>" . helm-find-files)
([f10] . helm-buffers-list)
([S-f10] . helm-recentf)))more binding examples:
:bind (:map my-map ("SPC" . yankpad-insert))
:bind (("M-f" . sp-forward-sexp)
("M-b" . sp-backward-sexp)
)
OR:
(bind-keys :map pdf-view-mode-map
("f9" . hydra-pdftools/body)
("<s-spc>" . pdf-view-scroll-down-or-next-page)
("g" . pdf-view-first-page)
("G" . pdf-view-last-page)
("l" . image-forward-hscroll)
("h" . image-backward-hscroll)
("j" . pdf-view-next-page)
("k" . pdf-view-previous-page)
("e" . pdf-view-goto-page)
("u" . pdf-view-revert-buffer)
("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)
("i" . pdf-misc-display-metadata)
("s" . pdf-occur)
("b" . pdf-view-set-slice-from-bounding-box)
("r" . pdf-view-reset-slice))Use of :defer
:defer also accepts an optional numeric argument which causes the
package to be loaded after N seconds of idle time.
From: https://www.gnu.org/software/emacs/manual/html_node/elisp/Idle-Timers.html
Emacs becomes idle when it starts waiting for user input, and it remains idle until the user provides some input.
My GNU/Emacs 26 takes approximately 70s to start. This is very long but it includes all my many “autostart” activities that also cover visibility settings in opened Org mode files and my complex agenda.
Therefore, my defer times start with 90s which is clearly after the startup.
Ocurrences in config.el (without disabled or not tangled code):
grep ":defer " ~/.emacs.d/config.el | # extract all occurrences of ":defer" from the tangled init file
sed 's/;;.*//' | # remove emacs-lisp comments
sed 's/ //g' | # remove all space characters to normalize strings
sed 's/defer/defer /' | # add space character again only after ":defer"
sort | # sort the resulting strings alphabetically
uniq -c ; # uniq them and count their occurrences
date # add the current time stamp in order to know how recent this output is 1 :defer 110
21 :defer 110
6 :defer 120
11 :defer 90
Tue Apr 16 10:31:52 WEDT 2019
no-littering
From:
It sets some default paths in order to separate automatically created files and directories.
(use-package no-littering
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/no-littering/")))
)
(require 'no-littering)Logging
host-specific log file: my-log-hostspecific()
Here’s the idea: on every Emacs startup, a file like
~/.emacs.d/var/log/HOSTNAME.txt is overwritten with the current
time-stamp and emacs-version. The path scheme follows the
no-littering package I’m using as well.
While loading miscellaneous packages, I might decide to append a version string.
This way, I get a list of files from all of my hosts sharing the same Emacs configuration. Each of these files hold the time of the last startup and the version strings of interesting packages. This simplifies generating bug reports and finding issues with version conflicts.
Here is an example file content for one host:
Started on 2019-04-16T14:35:04+02:00 emacs-version 26.0.90 cygwin-mount-version 1.4.8 yas--version 0.11.0 org-version 9.1.6 plantuml-mode-version 1.2.3 magit-version 2.10.3
So how is it done? Here we go. Let’s define the common file name, one per host:
(setq my-var-log-hostname-file (concat no-littering-var-directory "log/host-" system-name ".txt"))At Emacs startup, overwrite the file content and initializing it with the current time stamp:
(write-region (concat "Started on " my-config-el-start-time-iso "\n") nil my-var-log-hostname-file)Define the function that is called to append lines to the file:
(defun my-log-hostspecific (mystring mycommand)
"append a string and the result of a command to the my-var-log-hostname-file file"
(interactive)
(write-region (concat mystring " " mycommand "\n") nil my-var-log-hostname-file t)
)And let’s use this new function to log the version of the GNU/Emacs that is starting:
(my-log-hostspecific "emacs-version" emacs-version)general log file: my-log-misc()
I’m using a central logging file for all kind of logging messages. I started with my agenda genreation performance.
Where do I log to?
(setq my-log-file (concat no-littering-var-directory "log/misc.log"))How do I log?
(defun my-log-misc (message)
(interactive)
(let ((current-timestamp
(concat
(format-time-string "%Y-%m-%dT%T")
((lambda (x) (concat (substring x 0 3) ":" (substring x 3 5)))
(format-time-string "%z")))
))
(write-region
(concat (format-message "%s %s: %s\n" current-timestamp system-name message))
nil my-log-file "append"))
)Example:
(my-log "foo bar")my-load-local-el()
Using this function, I am able to easily load lisp files within my Emacs config hierarchy. It contains minimal error handling for a missing file.
from: http://www.zonix.de/html40/linux/emacsgnus.html
(defun my-load-local-el (part)
"load lisp file and warn if not found"
(let ((fullname (concat my-user-emacs-directory part)))
(if (file-exists-p fullname)
(load fullname)
(message (format "Loading %s (source)...failed" fullname)))))Server mode
Start Emacs as a server process: new files can be visited via
emacsclient (instead of parallel emacs instances). Therefore, I
don’t have to run multiple instances (which occupies RAM storage) and
I am able to open new files instantly.
(server-start)my-system-is-FOOBAR
Emacs config switch depending on hostname or operating system: Idea found here: Single dot emacs file and per-computer configuration | SIGQUIT
This is so cool: with those functions, I am able to maintain one single Emacs configuration for all of my hosts. If there is something I want to do or do not on a specific platform or host, those functions allow me to express my restrictions easily:
;; Get current system's name
(defun my-insert-system-name()
(interactive)
"Get current system's name"
(insert (format "%s" system-name))
)
;; Get current system type
(defun my-insert-system-type()
(interactive)
"Get current system type"
(insert (format "%s" system-type))
)
;; Check if system is Darwin/Mac OS X
(defun my-system-type-is-darwin ()
"Return true if system is darwin-based (Mac OS X)"
(string-equal system-type "darwin")
)
;; Check if system is Microsoft Windows
(defun my-system-type-is-windows ()
"Return true if system is Windows-based (at least up to Win7)"
(string-equal system-type "windows-nt")
)
;; Check if system is GNU/Linux
(defun my-system-type-is-gnu ()
"Return true if system is GNU/Linux-based"
(string-equal system-type "gnu/linux")
)Here are host-specific functions which I should not use if possible because with them, I lose some generic approach:
(defun my-system-is-floyd-or-sting ()
"Return true if the system we are running on is floyd or sting"
(or
(string-equal system-name "floyd")
(string-equal system-name "floyd.lan")
(string-equal system-name "sting")
(string-equal system-name "sting.lan")
)
)
(defun my-system-is-sting ()
"Return true if the system we are running on is sting"
(or
(string-equal system-name "sting")
(string-equal system-name "sting.lan")
)
)
(defun my-system-is-floyd ()
"Return true if the system we are running on is floyd"
(or
(string-equal system-name "floyd")
(string-equal system-name "floyd.lan")
)
)
(defun my-system-is-rise ()
"Return true if the system we are running on is floyd"
(or
(string-equal system-name "rise")
)
)
(defun my-system-is-blanche ()
"Return true if the system we are running on is blanche"
(or (string-equal system-name "blanche") (string-equal system-name "blanche.lan"))
)
(defun my-system-is-karl-voit-at ()
"Return true if the system we are running on is karl-voit.at"
(string-equal system-name "friends.grml.info")
)
(defun my-system-is-powerplantlinux ()
"Return true if the system we are running on is powerplant"
(or
(string-equal system-name "powerplant")
(string-equal system-name "powerplant.lan")
)
)System-specific paths
The system PATH variable provides access to executables. However, I do
tend to use programs which are not part of the PATH variable of the
operating system as well. Therefore, I do extend the Emacs variable
exec-path (further down and following headings).
http://www.emacswiki.org/emacs/MacOSTweaks#toc13
;; setting path so that Emacs finds aspell and such
(when (my-system-type-is-darwin)
(setenv "PATH"
(concat (getenv "PATH")
":/Users/vk/bin:/usr/local/texlive/2010/bin/x86_64-darwin:/opt/local/bin:/opt/local/sbin"))
(setq exec-path (append exec-path
'("/opt/local/bin"
"/usr/local/texlive/2010/bin/x86_64-darwin"
"/usr/local/teTeX/bin/powerpc-apple-darwin-current"
)))
(add-to-list 'load-path "/opt/local/share/emacs/site-lisp")
;; 2011-04-20: allow typing of german umlauts in OS X by Alt-u followed by u,o,a,...
(setq mac-option-modifier nil)
(setq org-ditaa-jar-path "~/data/hosts/blanche/config/ditaa.jar")
;; setting path to color-theme-mode.el from MacPorts
(add-to-list 'load-path "/opt/local/share/emacs/site-lisp/color-theme-6.6.0")
)ditaa
(when (my-system-type-is-gnu)
(setq org-ditaa-jar-path "/usr/share/ditaa/ditaa.jar")
)setting path so that Emacs finds aspell and such:
(if (my-system-type-is-windows)
;;disabled;(setenv "PATH"
;;disabled; (concat (getenv "PATH")
;;disabled; ":/Users/vk/bin:/usr/local/texlive/2010/bin/x86_64-darwin:/opt/local/bin:/opt/local/sbin"))
(setq exec-path (append exec-path
'("C:/Program Files (x86)/Aspell/bin"
"C:/ProgramData/chocolatey/bin"
;;disabled; "/usr/local/texlive/2010/bin/x86_64-darwin"
;;disabled; "/usr/local/teTeX/bin/powerpc-apple-darwin-current"
)))
;;disabled;(add-to-list 'load-path "/opt/local/share/emacs/site-lisp")
(
;; on all other systems:
)
)Where my Org mode files reside. They are used all over this config and therefore, this has to be defined early:
(cond ((string-equal system-name "GRZN17009")
(setq my-org-files-path "c:/Users/karl.voit/org/"))
((string-equal system-name "Cosmo")
(setq my-org-files-path "c:/Users/John/AppData/Roaming/org/")
)
(t
(setq my-org-files-path "~/org/"))
)
;;(message (format "Set \"my-org-files-path\" to: %s" my-org-files-path))Setting the system-specific path for my-webarchive-tsfile-dir-path
;; different hosts do have the dir at different locations:
(setq my-webarchive-tsfile-dir-path (cond ((my-system-is-sting) "/home/vk/archive/backup/sting/webarchive")
((my-system-is-rise) "/home/vk/Downloads/webarchive")
(t "/home/vk/Downloads/");; fallback path (should NOT be used)
))Emax64 settings
2019-11-09: settings according to the emax64 default .emacs file:
(when (my-system-type-is-windows)
;; ;; Set repositories
;; (require 'package)
;; (setq-default
;; load-prefer-newer t
;; package-enable-at-startup nil)
;; (add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/") t)
;; (add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/") t)
;; (setq package-user-dir "~/emax/elpa")
;; (package-initialize)
;; ;; Install dependencies
;; (unless (and (package-installed-p 'delight)
;; (package-installed-p 'use-package))
;; (package-refresh-contents)
;; (package-install 'delight t)
;; (package-install 'use-package t))
;; (setq-default
;; use-package-always-defer t
;; use-package-always-ensure t)
;; ;; Use latest Org
;; (use-package org
;; ;;:pin org
;; :ensure org-plus-contrib)
(defvar emax-root (concat (expand-file-name "~") "/emax"))
(defvar emax-bin (concat emax-root "/bin"))
(defvar emax-bin64 (concat emax-root "/bin64"))
(defvar emax-mingw64 (concat emax-root "/mingw64/bin"))
(defvar emax-lisp (concat emax-root "/lisp"))
(setq exec-path (cons emax-bin exec-path))
(setenv "PATH" (concat emax-bin ";" (getenv "PATH")))
(setq exec-path (cons emax-bin64 exec-path))
(setenv "PATH" (concat emax-bin64 ";" (getenv "PATH")))
(setq exec-path (cons emax-mingw64 exec-path))
(setenv "PATH" (concat emax-mingw64 ";" (getenv "PATH")))
(setenv "PATH" (concat "C:\\msys64\\usr\\bin;C:\\msys64\\mingw64\\bin;" (getenv "PATH")))
(dolist (dir '("~/emax/" "~/emax/bin/" "~/emax/bin64/" "~/emax/mingw64/bin/" "~/emax/lisp/" "~/emax/elpa/" "~/bin/"))
(add-to-list 'load-path dir))
(set-language-environment 'utf-8)
(setq locale-coding-system 'utf-8)
(set-default-coding-systems 'utf-8)
(set-terminal-coding-system 'utf-8)
(prefer-coding-system 'utf-8)
;; Tangle configuration
(org-babel-load-file (expand-file-name "~/emax/emax.org" user-emacs-directory))
;;(garbage-collect)
)from emax.org:
(when (my-system-type-is-windows)
; (setq-default
; (defvar mp/font-family "Consolas" "The font to use.")
; )
;; Running Windows Powershell from within Emacs
; (setq explicit-shell-file-name "c:\\windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe")
; (setq explicit-powershell.exe-args '("-Command" "-" )) ; interactive, but no command prompt
; (autoload 'powershell "powershell" "Run powershell as a shell within emacs." t)
;; Changes made for Aspell
;; (setq-default ispell-program-name "~/emax/mingw64/bin/aspell.exe")
(setq-default ispell-program-name "~/bin/aspell.cmd")
(setq-default ispell-extra-args '("--sug-mode=ultra"))
;; (setq ispell-dictionary "en_US")
;; Set "DICTDIR" variable
(setenv "DICTDIR" (concat emax-mingw64 "/lib/aspell-0.60/"))
;; Automatically enable flyspell-mode in text-mode
;;(require 'flyspell)
;;(add-hook 'text-mode-hook 'flyspell-mode)
(setq text-mode-hook '(lambda() (flyspell-mode t) ))
;;(setq text-mode-hook '(lambda()
;; (flyspell-mode t)))
;;(dolist (hook '(text-mode-hook))
;; (add-hook hook (lambda () (flyspell-mode 1))))
;;(dolist (hook '(change-log-mode-hook log-edit-mode-hook))
;; (add-hook hook (lambda () (flyspell-mode -1))))
;;(setq flyspell-issue-message-flag nil)
;;(require 'auto-dictionary)
;;(add-hook 'flyspell-mode-hook (lambda () (auto-dictionary-mode 1)))
(require 'ispell)
; (setq epg-gpg-home-directory "~/emax/mingw64/bin/")
; (setq epg-gpg-program "~/emax/mingw64/bin/gpg.exe")
; (setq epg-gpgconf-program "~/emax/mingw64/bin/gpgconf.exe")
; (pdf-tools-install :no-query)
)Cygwin Paths (Windows)
As mentioned in the chapter of system-specific paths, I do use programs which are not part of the PATH variable of the operating system. Cygwin executables (in form of babun) are one example of this kind of programs.
Links:
- http://gregorygrubbs.com/emacs/10-tips-emacs-windows/
- id:2014-01-31-cygwin-emacs
- http://www.emacswiki.org/emacs/RobertAdesamConfig
(when (and (my-system-type-is-windows) (string-equal system-name "GRZN17009"))Hard-coding the cygwin install path (for babun):
- id:2016-04-22-magit-not-working-on-windows
(setq cygwin-root-directory "c:/Users/karl.voit/.babun/cygwin/")Check if Cygwin/babun inst found on the install path given:
(if (file-directory-p cygwin-root-directory)
(prognOLD method of extending the path:
(setenv "PATH"
(concat
;;"c:\\cygwin64\\usr\\local\\bin" ";" ;; Cygwin
;;"c:\\cygwin64\\bin" ";" ;; Cygwin
"C:\\Users\\karl.voit\\.babun\\cygwin\\bin" ";"
"C:\\Users\\karl.voit\\.babun\\cygwin\\usr\\local\\bin" ";"
"C:\\Python36\\" ";"
"C:\\Program\ Files\ \(x86\)\\Java\\jre1.8.0_144\\bin" ";"
(getenv "PATH")))Extending the path:
(setq exec-path (cons (concat cygwin-root-directory "bin/") exec-path)) ;; Babun
(setq exec-path (cons (concat cygwin-root-directory "usr/local/bin/") exec-path)) ;; Babun
(setq exec-path (cons "C:/Program Files (x86)/Java/jre1.8.0_144/bin" exec-path)) ;; BabunAdding cygwin mounts:
(use-package cygwin-mount)
(cygwin-mount-activate)Adding cygwin bash shell
;;(setq shell-file-name "c:/cygwin64/bin/bash") ;; Cygwin
(setq shell-file-name (concat cygwin-root-directory "bin/zsh")) ;; Babun
;;(setq shell-file-name (concat cygwin-root-directory "bin/bash")) ;; Babun
(setenv "SHELL" shell-file-name)
(setq explicit-shell-file-name shell-file-name)
(setq ediff-shell shell-file-name)
(setq explicit-shell-args '("--login" "-i"))
(setq w32-quote-process-args ?\")id:2015-11-02-tramp-windows-babel and Docu: help:tramp-methods
(setq tramp-default-method "plink")requires: setup-cygwin.el and cygwin-mount.el in the contrib dir:
(add-to-list 'load-path (concat my-user-emacs-directory "contrib/"))
(require 'setup-cygwin)END of Cygwin/babun configuration
)
(message "»»» I could not locate the cygwin path")
)end of Cygwin config
(my-log-hostspecific "cygwin-mount-version" cygwin-mount-version)
);; end of if-windowsStarting GNU/Emacs on Windows
First, I create a batch file which starts the emacs.exe with
optional Org-mode files as parameters:
C:\Users\Karl.Voit\bin\windows-start-orgmode.bat
REM Here, invoke some syncronization mechanism like Unison: REM "C:\Program Files\bin\unison-2.40.102-gtk.exe" grmlvrs REM As of 2017, I switched from Unison to Syncthing "C:\Program Files\emacs-24.5-bin-i686-mingw32\bin\emacs.exe" REM Re-syncing after leaving Emacs: REM "C:\Program Files\bin\unison-2.40.102-gtk.exe" grmlvrs REM End
This batch file is included in a Visual Basic file. This way, I am able to start my GNU/Emacs using misc app-launcher solutions: batch files are not listed in typical app-launchers whereas VBS files work at least with my Hotstrings:
C:\Users\Karl.Voit\bin\orgmode.vbs or in Cygwin /home/karl.voit/bin/orgmode.vbs
'HideBat.vbs
CreateObject("Wscript.Shell").Run "C:\Users\Karl.Voit\bin\windows-start-orgmode.bat", 0, True
Looking for binaries
Some Emacs configuration snippets relate to external programs such as LaTeX. Instead of (a) blindly evaluating those snippets or (b) using per-host-configuration for them, I do prefer to check whether or not those programs are installed on the local host instead. This is just the sane way of doing those things.
In detail, it gets a bit dirty for Windows, since there are some tools
that are installed but not listed in the PATH environment exec-path.
See below for some workarounds for that.
my-binary-found(binaryname)
my-binary-found(binaryname) returns the path where a binary
executable can be found within the exec-path.
It also checks certain operating system/binary combinations which aren’t likely in the exec-path.
(defun my-binary-found(binaryname)
"Returns the path where a binary executable can be found.
It also checks certain operating system/binary combinations which aren't likely in the exec path."
(cond
((and (my-system-type-is-windows) (string= binaryname "firefox"))
(when (file-exists-p "C:/Program Files/Mozilla Firefox/firefox.exe")
(concat "C:/Program Files/Mozilla Firefox/firefox.exe")
)
)
((and (my-system-type-is-windows) (string= binaryname "python"))
(when (file-exists-p "C:/Python27/python.exe")
(concat "C:/Python27/python.exe")
)
)
((and (my-system-type-is-windows) (string= binaryname "outlook"))
(when (file-exists-p "C:/Program Files/Microsoft Office/Office16/OUTLOOK.EXE")
(concat "C:/Program Files/Microsoft Office/Office16/OUTLOOK.EXE")
)
)
;; this is the default check for all binaries which got no special handling above:
(t
(locate-file binaryname exec-path exec-suffixes 1))
))Examples:
(message (concat "pdflatex found on: " (my-binary-found "pdflatex")))
(if (my-binary-found "pdflatex")
(message "LaTeX found")
(message "LaTeX not found")
)my-binary-not-found-list and my-eval-if-binary-or-warn()
my-eval-if-binary-or-warn (binaryname &optional warningtext) checks
if a binary can be found in the path via my-binary-found().
If not found, a warning message is printed which can be defined as an optional parameter as well. Additionally, the not found binaries are collected in the variable my-binary-not-found-list.
(defvar my-binary-not-found-list nil
"Holds a list of binaries which could not be found via my-eval-if-binary-or-warn()"
)
(defun my-eval-if-binary-or-warn (binaryname &optional warningtext)
"Checks if a binary can be found in the path via my-binary-found().
If not found, a warning message is printed which can be defined as an optional parameter as well.
Additionally, the not found binaries are collected in the variable my-binary-not-found-list."
(or warningtext (setq warningtext (concat "»»» I could not locate the PATH-binary for: " binaryname)))
(let* ((binarypath (my-binary-found binaryname)))
(if binarypath
;; binary was found in exec-path
(concat binarypath)
(progn
;; binary NOT found in exec-path:
(message warningtext)
(if my-binary-not-found-list
(add-to-list 'my-binary-not-found-list binaryname)
(setq my-binary-not-found-list (list binaryname))
)
))))Example usages:
(my-eval-if-binary-or-warn "yyy" "This is a warning text for yyy")
(my-eval-if-binary-or-warn "xxx")
(my-eval-if-binary-or-warn "xxx" "This is a warning text for xxx")
(my-eval-if-binary-or-warn "zzz" "This is a warning text for xxx")
(message "Binaries not found: %s" my-binary-not-found-list)Example output for different hosts
This heading ist just for collecting example outputs:
sting output:
pdflatexTeX binary: /usr/bin/pdflatex python binary: /usr/bin/python firefox binary: /usr/bin/firefox chrome binary: aspell binary: /usr/bin/aspell ispell binary: pandoc binary: /usr/bin/pandoc ditaa binary: /usr/bin/ditaa gnuplot binary: /usr/bin/gnuplot git binary: /usr/bin/git Outlook binary: grep binary: /bin/grep scss binary: /usr/bin/scss ag binary: /usr/bin/ag biber binary: /usr/bin/biber
Windows output:
pdflatex binary: c:/Program Files/MiKTeX_2.9/miktex/bin/pdflatex.exe python binary: ipython binary: firefox binary: chrome binary: aspell binary: ispell binary: pandoc binary: c:/Users/karl.voit/AppData/Local/Pandoc/pandoc.exe ditaa binary: gnuplot binary: git binary: Outlook binary: grep binary: scss binary: ag binary: biber binary: c:/Program Files/MiKTeX_2.9/miktex/bin/biber.exe
Binaries not found in checks above: (ag scss grep Outlook git gnuplot ditaa ispell aspell chrome firefox ipython python)
After moving system-specific paths above this checks: only aspell was found:
Binaries not found in checks above: (ag scss grep Outlook git gnuplot ditaa ispell chrome firefox ipython python)
… but on Windows, there are following things installed:
- [ ] python
- [ ] ipython
- [ ] firefox
- [ ] chrome
- [ ] (a/i?)spell
- [ ] Outlook
- real path: “C:\Program Files (x86)\Microsoft Office\root\Office16\OUTLOOK.EXE”
- also holds for OUTLOOK.EXE and OUTLOOK
where outlookis also unsuccessful :-(
(message "★★★★★★★★★★")
(message (concat "pdflatex binary: " (my-binary-found "pdflatex")))
(message (concat "python binary: " (my-binary-found "python")))
(message (concat "ipython binary: " (my-binary-found "ipython")))
(message (concat "firefox binary: " (my-binary-found "firefox")))
(message (concat "chrome binary: " (my-binary-found "chrome")))
(message (concat "aspell binary: " (my-binary-found "aspell")))
(message (concat "ispell binary: " (my-binary-found "ispell")))
(message (concat "pandoc binary: " (my-binary-found "pandoc")))
(message (concat "ditaa binary: " (my-binary-found "ditaa")))
(message (concat "gnuplot binary: " (my-binary-found "gnuplot")))
(message (concat "git binary: " (my-binary-found "git")))
(message (concat "Outlook binary: " (my-binary-found "Outlook")))
(message (concat "grep binary: " (my-binary-found "grep")))
(message (concat "scss binary: " (my-binary-found "scss")))
(message (concat "ag binary: " (my-binary-found "ag")))
(message (concat "biber binary: " (my-binary-found "biber")))
(message "★★★★★★★★★★")Test queries
Here, I do probe for some tools mostly because I want to test my code above.
When I am using tool-specific settings below, I do add comment characters to disable the check at this stage:
;;(my-eval-if-binary-or-warn "pdflatex")
;;(my-eval-if-binary-or-warn "python")
(my-eval-if-binary-or-warn "ipython")
;;(my-eval-if-binary-or-warn "firefox")
(my-eval-if-binary-or-warn "chrome")
;;(my-eval-if-binary-or-warn "aspell")
;;(my-eval-if-binary-or-warn "pandoc")
(my-eval-if-binary-or-warn "ditaa")
;;(my-eval-if-binary-or-warn "gnuplot")
;;(my-eval-if-binary-or-warn "git")
;;(my-eval-if-binary-or-warn "outlook")
(my-eval-if-binary-or-warn "grep")
;;(my-eval-if-binary-or-warn "scss")
(my-eval-if-binary-or-warn "ag")
(my-eval-if-binary-or-warn "biber")System-specific browse-url-browser
Here, I do hard-code my preferred browser that is used when I open URLs within Emacs:
(setq firefox-path (my-eval-if-binary-or-warn "firefox"))
(setq chrome-path (my-eval-if-binary-or-warn "google-chrome"))
(cond
((my-system-type-is-darwin)
(setq browse-url-browser-function 'browse-url-default-macosx-browser)
)
(firefox-path
(setq browse-url-browser-function 'browse-url-generic
browse-url-generic-program firefox-path)
)
(chrome-path
(setq browse-url-browser-function 'browse-url-generic
browse-url-generic-program chrome-path)
)
)(setq browse-url-browser-function 'browse-url-generic
browse-url-generic-program "chromium-browser")https://chrome.google.com/webstore/detail/ljobjlafonikaiipfkggjbhkghgicgoh?hl=de
- Edit-server for Chrome
;(use-package edit-server)
(my-load-local-el "contrib/edit-server.el")
;won't work; (use-package edit-server
;won't work; :load-path "~/.emacs.d/contrib/"
;won't work; :config
;won't work; (edit-server-start)
;won't work; )
(if (locate-library "edit-server")
(progn
;(use-package edit-server)
(setq edit-server-new-frame nil)
(edit-server-start)))2017-06-20: A little trick with EWW : emacs - presents code to interactively select your browser of choice.
Styling
The (sub-)headings here deal with the visual appeal of my GNU/Emacs. I like dark themes and minimized interfaces. Therefore, I hide everyting I do not use.
Interesting read: http://www.tbray.org/ongoing/When/201x/2012/09/24/Typographic-notes
Show current column: 2020-01-01 disabled because of performance impact (re-drawing modeline at each keystroke)
(setq column-number-mode t)Cursor settings:
;; Prevent the cursor from blinking
;(blink-cursor-mode 0)
(set-cursor-color "IndianRed")Flat mode-line styling: 2014-05-24: from http://www.reddit.com/r/emacs/comments/23l9oi/flat_modeline/
(set-face-attribute 'mode-line nil :box nil)
(set-face-attribute 'mode-line-inactive nil :box nil)Themes
| 2021-01-08 | I switch back to light theme (leuven or default) for now |
Since a couple of major versions, GNU/Emacs has a built-in theme manager. This is for dealing with the themes.
- [2021-01-18 Mon] What parts of your config do you like best? : emacs
- Cool snippet to load and unload theme(s).
- [ ] play around with it myself
- set color theme according to day-time:
(setq calendar-location-name "Graz, AT")
(setq calendar-latitude 47.07)
(setq calendar-longitude 15.43)
(use-package theme-changer)
(change-theme 'whiteboard 'misterioso) ;; day and night themeMy favorite dark themes: wombat, misterioso, zenburn, material
;(load-theme 'wombat t) ;; dark theme
;; (load-theme 'misterioso t)
;; (load-theme 'zenburn t)
;; (load-theme 'material t) ;; from http://www.reddit.com/r/emacs/comments/39dk64/escaping_from_org_mode/
;; issues with *bold* stuff in org-mode :-(My favorite light themes: leuven, whiteboard, solarized-light,
;; (load-theme 'leuven t) ;; from http://www.reddit.com/r/emacs/comments/39dk64/escaping_from_org_mode/
;; (load-theme 'whiteboard t)
;; (load-theme 'solarized-light t)- 2017-03-29: DISABLE a theme: “M-x disable-theme” + theme
(defadvice load-theme (before theme-dont-propagate activate) (mapcar #'disable-theme custom-enabled-themes))Only one window on startup
«Make [current] WINDOW fill its frame.»
(add-hook 'emacs-startup-hook 'delete-other-windows t)Font and Font sizes
- 2011-04-20: increase/set font size
2019-11-15: disabled because not used for a very long time:
(defun my-increase-fontsize ()
(interactive)
"Sets the font to bigger size"
(set-face-attribute 'default (selected-frame) :height 130)
)
(defun my-normal-fontsize ()
(interactive)
"Sets the font to normal size"
(set-face-attribute 'default (selected-frame) :height 100)
)I was using DejaVu Sans Mono a while ago:
(set-face-attribute 'default nil :font "DejaVu Sans Mono-10")
;(add-to-list 'default-frame-alist
; '(font . "DejaVu Sans Mono-10"))- [2021-05-05 Wed] Discussion: What’s your favorite font for emacs? : emacs → https://www.jetbrains.com/lp/mono/
- I’m trying JetBrains Mono for a while
- [2021-05-14 Fri] disabled and moving to FantasqueSansMono-NoLoopK
(add-to-list 'default-frame-alist '(font . "JetBrains Mono-12"))
;; (add-to-list 'default-frame-alist '(line-spacing . 0.2))- [2021-05-14 Fri] I’m switching to FantasqueSansMono-NoLoopK because JetBrains Mono does not emphasize boldface boldly enough for me
(add-to-list 'default-frame-alist '(font . "Fantasque Sans Mono-12"))Host-specific font sizes: values are in 1/10pt → 100 are 10pt
;;(when (my-system-type-is-gnu)
;; (my-increase-fontsize);; increase fonts on some hosts by default
;; )
(when (my-system-type-is-darwin)
(set-face-attribute 'default (selected-frame) :height 170);; 2011-04-20: increase/set font size http://www.emacswiki.org/emacs/SetFonts
)
(when (my-system-type-is-windows)
;;(set-face-attribute 'default (selected-frame) :height 150)
;;(set-face-attribute 'default (selected-frame) :height 130);; 2016-08-19 let's test 130 after 150 seems too big
(set-face-attribute 'default (selected-frame) :height 110);; 2017-09-06 detego
)
(when (my-system-is-floyd)
;; (set-face-attribute 'default (selected-frame) :height 100) ;; 2020-08-20: switched back to 105
;; (set-face-attribute 'default (selected-frame) :height 105);; until 2019-12-23 -> not working
(set-face-attribute 'default nil :height 105);; 2020-08-22 new command from https://stackoverflow.com/questions/294664/how-to-set-the-font-size-in-emacs
)
(when (my-system-is-sting)
;;(set-face-attribute 'default (selected-frame) :height 110) ;; before 2018-02-24 (a bit large)
;;(set-face-attribute 'default (selected-frame) :height 105) ;; before 2019-10-24: I want to try smaller font
;;(set-face-attribute 'default (selected-frame) :height 102) ;; before 2019-12-04: even smaller on reduced resolution
(set-face-attribute 'default (selected-frame) :height 110) ;; 2019-12-04: bigger font on native 30" resolution
)
(when (my-system-is-rise)
(set-face-attribute 'default (selected-frame) :height 100)
)Different font size for mode-line (from this stackexchange page):
(let ((faces '(mode-line
mode-line-buffer-id
mode-line-emphasis
mode-line-highlight
mode-line-inactive)))
(mapc
(lambda (face) (set-face-attribute face nil :font "DejaVu Sans Mono-8"))
faces))Modeline with icons
There are two potentially nice packages in order to beautify my modeline even further:
- https://github.com/dustinlacewell/eyeliner
- https://github.com/domtronn/all-the-icons.el
- requires fonts to be installed
FIXXME: So far, I did not try them because my current modeline is beautiful enough. Maybe in the future.
UTF-8 and codings
Activate UTF-8 mode:
(setq locale-coding-system 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(prefer-coding-system 'utf-8)When I paste from the Windows clipboard, I tend to get messed up Umlauts and special characters. This ought to fix it but I think that this does not work either:
(cond ((my-system-type-is-windows)
;; on Windows, 'utf-8 does not work properly when system
;; clipboard gets yanked
(setq selection-coding-system 'utf-16le-dos)
;; For example: =\344= instead of =ä= on Windows 7:
;;(set-selection-coding-system 'iso-latin-1-dos)
)
((my-system-type-is-gnu)
(set-selection-coding-system 'utf-8)
)
(t
(set-selection-coding-system 'utf-8)
)
)
;; 2013-12-10 IRC #Emacs
(set-clipboard-coding-system 'utf-8)
;; http://www.masteringemacs.org/articles/2012/08/09/working-coding-systems-unicode-emacs/
;; in addition to the lines above:
(set-default-coding-systems 'utf-8)
;; backwards compatibility as default-buffer-file-coding-system
;; is deprecated in 23.2.
(if (boundp 'buffer-file-coding-system)
;; NOTE: default-buffer-file-coding-system is obsolete; use
;; buffer-file-coding-system if found
(setq-default buffer-file-coding-system 'utf-8)
(setq default-buffer-file-coding-system 'utf-8))
;; Treat clipboard input as UTF-8 string first; compound text next, etc.
(setq x-select-request-type '(UTF8_STRING COMPOUND_TEXT TEXT STRING))From: https://www.masteringemacs.org/article/working-coding-systems-unicode-emacs
[…] One problem with the universal coding system argument is that it only cares about Emacs’s settings, not those of your shell or system. That’s a problem, because tools like Python use the environment variable PYTHONIOENCODING to set the coding system for the Python interpreter.
I have written the following code that advises the universal-coding-system-argument function so it also, temporarily for just that command, sets a user-supplied list of environment variables to the coding system. […]
(defvar universal-coding-system-env-list '("PYTHONIOENCODING")
"List of environment variables \\[universal-coding-system-argument] should set")
(defadvice universal-coding-system-argument (around provide-env-handler activate)
"Augments \\[universal-coding-system-argument] so it also sets environment variables
Naively sets all environment variables specified in
`universal-coding-system-env-list' to the literal string
representation of the argument `coding-system'.
No guarantees are made that the environment variables set by this advice support
the same coding systems as Emacs."
(let ((process-environment (copy-alist process-environment)))
(dolist (extra-env universal-coding-system-env-list)
(setenv extra-env (symbol-name (ad-get-arg 0))))
ad-do-it))my-map: my own keyboard shortcut prefix
About defining keys: Emacs: How to Define Keys
If you are not satisfied with the default setup of Emacs keyboard shortcuts, you start with defining your own keyboard shortcuts (bindings).
To avoid binding conflicts with libraries/packages, it is a good habit of using a keyboard shortcut prefix no-one else is using. So if you stick to this prefix, you’ve got your own «name-space» where you are able to define your bindings freely.
My approach is to use my-map as a mapping which is bound to C-c
C-,= . So my personal bindings start with =C-c C-,= such as =C-c C-, -
for decreasing the font size of GNU/Emacs.
2015-11-10: Following code was replaced by bind-key below:
;; 2011-04-20, 2013-04-08: defining «C-c C-,» as my own prefix:
;; http://stackoverflow.com/questions/1024374/how-can-i-make-c-p-an-emacs-prefix-key-for-develperlysense
;; http://stackoverflow.com/questions/5682631/what-are-good-custom-keybindings-in-emacs
;; NOTE: (info "(elisp) Key Binding Conventions") warns about user prefixes other than C-c
(global-unset-key (kbd "C-c C-,")); causes error: "Invalid modifier in string"
;; same as: (global-unset-key (kbd "C-c C-,"))
(define-prefix-command 'my-map)2019-12-04: With Org mode version 9.2, C-c C-,= got mapped to
=org-insert-structure-template. In order to avoid any conflict
situation (also for communication with peers), I switch to a new
binding: C-c C-k which is bound to org-kill-note-or-show-branches
but it’s a less popular function.
Using the bind-key package: (OLD method without use-package:)
(require 'bind-key);; https://github.com/emacsattic/bind-key
;;(org-defkey org-mode-map (kbd "C-c C-,") nil);; clear binding
(bind-keys
:prefix-map my-map
:prefix-docstring "My own keyboard map"
:prefix "C-c C-,"
;; 2013-03-31: http://stackoverflow.com/questions/3124844/what-are-your-favorite-global-key-bindings-in-emacs
("-" . text-scale-decrease)
("+" . text-scale-increase)
("=" . text-scale-increase);; because "+" needs "S-=" and I might forget to press shift
)New method that allows overwriting of bindings (see this comment using the after feature of use-package):
(use-package bind-key
:ensure t
:bind (:prefix-map my-map
:prefix-docstring "My own keyboard map"
:prefix "C-c C-,"
("-" . text-scale-decrease)
("+" . text-scale-increase))
("=" . text-scale-increase);; because "+" needs "S-=" and I might forget to press shift
:after org)Usage example:
(bind-key "m w" #'mark-word my-map)
or:
(bind-keys
:map my-map
("f" . forward-char)
("b" . backward-char))
or for use-package():
:bind (:map my-map ("8" . bm-toggle))
Alternative tipp: in case you run out of keybinding spaces, you can take a look at hydra and the “defhydra hydra-k” method. Hydra lists a menu of options and the hydra-k offers a prefix for it.
See 33min30s of the video linked in: Irreal: Hydra Video
Misc modes/packages (part I)
which-key - displays the available key bindings automatically
https://github.com/justbur/emacs-which-key
I got the recommendation via this reddit thread with the arguments,
that which-key is inferior to guide-key which I used before::
- more active
- more features
- more contributions
when I do press my prefix for my-map and wait a bit,
I get a popup buffer that tells me what bindings I am able to use.
(use-package which-key
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/emacs-which-key/")))
:defer 120
:config ;; executed after loading package
(which-key-setup-side-window-right)
(add-to-list 'which-key-replacement-alist '(("TAB" . nil) . ("↹" . nil)))
(add-to-list 'which-key-replacement-alist '(("RET" . nil) . ("⏎" . nil)))
(add-to-list 'which-key-replacement-alist '(("DEL" . nil) . ("⇤" . nil)))
(add-to-list 'which-key-replacement-alist '(("SPC" . nil) . ("␣" . nil)))
(which-key-mode)
)Please note this pull request that explains why my characters are non-standard ones. It also adds a symbol for ESC.
My helper functions (part I)
Here I defined some functions I am using in the configuration below.
measure-time()
From time to time, I want to measure, how long an Elisp snippet ran. This can be done with following code.
from: http://stackoverflow.com/questions/23622296/emacs-timing-execution-of-function-calls-in-emacs-lisp
(defmacro measure-time (&rest body)
"Measure the time it takes to evaluate BODY."
`(let ((time (current-time)))
,@body
(message " Execution time: %.06f" (float-time (time-since time)))))my-title-capitalization(): Proper English Title Capitalization of a Marked Region → my-map C
Read http://www.karl-voit.at/2015/05/25/elisp-title-capitalization/ where I wrote a verbose description of the topic and my solution.
;; additionally to the list defined in title-capitalization:
(defvar my-do-not-capitalize-words '("lazyblorg" "mutt")
"My personal list of words that doesn't get capitalized in titles.")
(defun title-capitalization (beg end)
"Proper English title capitalization of a marked region"
;; - before: the presentation of this heading of my own from my keyboard and yet
;; - after: The Presentation of This Heading of My Own from My Keyboard and Yet
;; - before: a a a a a a a a
;; - after: A a a a a a a A
(interactive "r")
(save-excursion
(let* (
;; basic list of words which don't get capitalized according to simplified rules:
;; http://karl-voit.at/2015/05/25/elisp-title-capitalization/
(do-not-capitalize-basic-words '("a" "ago" "an" "and" "as" "at" "but" "by" "for"
"from" "in" "into" "it" "next" "nor" "of" "off"
"on" "onto" "or" "over" "past" "so" "the" "till"
"to" "up" "yet"
"n" "t" "es" "s"))
;; if user has defined 'my-do-not-capitalize-words, append to basic list:
(do-not-capitalize-words (if (boundp 'my-do-not-capitalize-words)
(append do-not-capitalize-basic-words my-do-not-capitalize-words )
do-not-capitalize-basic-words
)
)
)
;; go to begin of first word:
(goto-char beg)
(capitalize-word 1)
;; go through the region, word by word:
(while (< (point) end)
(skip-syntax-forward "^w" end)
(let ((word (thing-at-point 'word)))
(if (stringp word)
;; capitalize current word except it is list member:
(if (member (downcase word) do-not-capitalize-words)
(downcase-word 1)
(capitalize-word 1)))))
;; capitalize last word in any case:
(backward-word 1)
(if (and (>= (point) beg)
(not (member (or (thing-at-point 'word) "s")
'("n" "t" "es" "s"))))
(capitalize-word 1))))
)
(ert-deftest my-title-capitalization ()
"Tests proper English title capitalization"
(should (string= (with-temp-buffer
(insert "the presentation of this heading of my own from my keyboard and yet\n")
(goto-char (point-min))
(set-mark-command nil)
(goto-char (point-max))
;(transient-mark-mode 1)
(title-capitalization)
(buffer-string))
"The Presentation of This Heading of My Own from My Keyboard and Yet\n"
)))(bind-key "c" #'title-capitalization my-map)my-toggle-vertical-horizontal-split()
Toggle the windows split between horizontally and vertically. I usually don’t use it though.
From: http://www.emacswiki.org/emacs/ToggleWindowSplit
(defun my-toggle-vertical-horizontal-split ()
"Switch window split from horizontally to vertically, or vice versa.
i.e. change right window to bottom, or change bottom window to right."
(interactive)
(require 'windmove)
(let ((done))
(dolist (dirs '((right . down) (down . right)))
(unless done
(let* ((win (selected-window))
(nextdir (car dirs))
(neighbour-dir (cdr dirs))
(next-win (windmove-find-other-window nextdir win))
(neighbour1 (windmove-find-other-window neighbour-dir win))
(neighbour2 (if next-win (with-selected-window next-win
(windmove-find-other-window neighbour-dir next-win)))))
;;(message "win: %s\nnext-win: %s\nneighbour1: %s\nneighbour2:%s" win next-win neighbour1 neighbour2)
(setq done (and (eq neighbour1 neighbour2)
(not (eq (minibuffer-window) next-win))))
(if done
(let* ((other-buf (window-buffer next-win)))
(delete-window next-win)
(if (eq nextdir 'right)
(split-window-vertically)
(split-window-horizontally))
(set-window-buffer (windmove-find-other-window neighbour-dir) other-buf))))))))
;(bind-key "|" 'my-toggle-split-and-single-window my-map)my-yank-windows → my-map y
Yanking from the windows clipboard results in messed up lists. When using this special yank function, common list formatting is fixed for Org-mode syntax.
- id:2016-05-22-my-yank-windows
(when (my-system-type-is-windows)
(defun my-yank-windows ()
"yanks from clipboard and replaces typical (list) markup"
(interactive)
(let ((mybegin (point))) ;; mark beginning of line as start point
(clipboard-yank)
(save-restriction
(narrow-to-region mybegin (point)) ;; ignore everything outside of region
(recode-region (point-min) (point-max) 'latin-1 'windows-1252); fix char encoding, e.g.: \366 -> ö
(goto-char (point-min))
(while (search-forward "\" " nil t)
(replace-match "- " nil t))
(goto-char (point-min))
(while (search-forward "o " nil t)
(replace-match " - " nil t))
(while (search-forward "�" nil t)
(replace-match "\"" nil t))
(while (search-forward "�" nil t)
(replace-match "\"" nil t))
(while (search-forward "�" nil t)
(replace-match "'" nil t))
(while (search-forward "�" nil t)
(replace-match "-" nil t))
;;(while (search-forward "1. " nil t) ;; FIXXME: replace with regex-methods for numbers in general
;; (replace-match "1. " nil t))
))
)
(bind-key "y" 'my-yank-windows my-map)
)my-fill-or-unfill() paragraph
M-q does fix paragraph formatting and is one of my most favorite
commands in GNU/Emacs. If you need to go back to «one line per
paragraph», this function offers a toggle function for M-q. Applied
twice, it re-formats the current paragraph to one line. Very handy for
copy/paste to web forms or such where you need one paragraph per line.
(defun my-fill-or-unfill ()
"Like `fill-paragraph', but unfill if used twice."
(interactive)
(let ((fill-column
(if (eq last-command 'my-fill-or-unfill)
(progn (setq this-command nil)
(point-max))
fill-column)))
(call-interactively 'fill-paragraph nil (vector nil t))))
(global-set-key [remap fill-paragraph]
'my-fill-or-unfill)my-open-in-external-app()
Some times, I want to use an external application for opening a certain file instead of opening it in Emacs. This can be done using following function:
- http://ergoemacs.org/emacs/emacs_dired_open_file_in_ext_apps.html
- open dired file in external app (specified by the operating system)
- https://www.reddit.com/r/emacs/comments/9iwnwi/w32shellexecute_explore_fails_if_file_type_hasnt/
- interesting reddit discussion with several explanations on w32explore, dired-w32explore, w32-shell-execute, and xah-show-in-desktop()
(defun my-open-in-external-app (&optional file)
"Open the current FILE or dired marked files in external app.
The app is chosen from your OS's preference."
(interactive)
(message "%s" (concat "my-open-in-external-app called with \"" file "\" as argument"))
;; FIXXME: add check if FILE is an existing file; show error message if not
(let ( doIt
(myFileList
(cond
((string-equal major-mode "dired-mode") (dired-get-marked-files))
((not file) (list (buffer-file-name)))
(file (list file)))))
(setq doIt (if (<= (length myFileList) 5)
t
(y-or-n-p "Open more than 5 files? ") ) )
(when doIt
(cond
((my-system-type-is-windows)
(mapc (lambda (fPath) (w32-shell-execute "open" (replace-regexp-in-string "/" "\\" fPath t t)) ) myFileList))
((string-equal system-type "darwin")
(mapc (lambda (fPath) (shell-command (format "open \"%s\"" fPath)) ) myFileList) )
((my-system-type-is-gnu)
(mapc (lambda (fPath) (let ((process-connection-type nil)) (start-process "" nil "xdg-open" fPath)) ) myFileList)
) ) ) ) )my-buffer-exists(bufname)
my-buffer-exists(bufname)
(defun my-buffer-exists (bufname)
(not (eq nil (get-buffer bufname)))
)my-comment-box
I got this code from pragmaticemacs:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; example: ;;
;; from http://irreal.org/blog/?p=374 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun my-comment-box (b e)
"Draw a box comment around the region but arrange for the region to extend to at least the fill column. Place the point after the comment box."
(interactive "r")
(let ((e (copy-marker e t)))
(goto-char b)
(end-of-line)
(insert-char ? (- fill-column (current-column)))
(comment-box b e 1)
(goto-char e)
(set-marker e nil)))my-scroll-up-command() my-scroll-down-command()
Usually, C-p and C-n are mapped to scroll-down-command and
scroll-up-command. Contrary to this, I like to scroll only half of a
screen so that I can follow the content in a better way.
The following implementation was inspired by (and copied from) https://www.emacswiki.org/emacs/HalfScrolling
(defun my-window-half-height ()
(max 1 (/ (1- (window-height (selected-window))) 2)))
(defun my-scroll-up-half ()
(interactive)
(scroll-up (my-window-half-height)))
(defun my-scroll-down-half ()
(interactive)
(scroll-down (my-window-half-height)))my-screnshot-svg
| 2021-03-26 | added to my config after test looks awesome |
(defun my-screenshot-svg ()
"Save a screenshot of the current frame as an SVG image.
Saves to a temp file to /tmp/ and puts the filename in the kill ring."
(interactive)
(let* ((filename (make-temp-file "Emacs" nil ".svg"))
(data (x-export-frames nil 'svg)))
(with-temp-file filename
(insert data))
(kill-new filename)
(message filename)))Resulting image can ge opened, e.g., in inkscape. Using the context menu feature “Enter group #…” you can go as deep into the elements as you wish. It really looks amazing.
Spell checking
«Flyspell enables on-the-fly spell checking in Emacs by the means of a minor mode.»
Please do evaluate this only if “aspell” is found on the system:
(when (my-eval-if-binary-or-warn "aspell")General settings
setting path to flyspell-mode.el from MacPorts:
(when (my-system-type-is-darwin)
(add-to-list 'load-path "/opt/local/share/emacs/lisp/textmodes")
)save to user dictionary without asking:
(setq ispell-silently-savep t)flyspell
flyspell.el http://kaolin.unice.fr/~serrano/
(autoload 'flyspell-mode "flyspell" "On-the-fly spelling checking" t)Dictionary Settings
;(set-default 'ispell-local-dictionary my-german-ispell-dictionary)
;;(autoload 'flyspell-mode "flyspell" "On-the-fly ispell." t)
(setq flyspell-issue-welcome-flag nil)
(when (my-system-type-is-windows)
(setq flyspell-default-dictionary "american")
)
(when (my-system-type-is-gnu)
(setq flyspell-default-dictionary "de_AT")
)from here to my-toggle-ispell-english-deutsch: see id:2014-01-06-aspell-issue
(eval-after-load "ispell"
'(add-to-list 'ispell-dictionary-alist
'("german8"
"[a-zA-ZäöüßÄÖÜ]" "[^a-zA-ZäöüßÄÖÜ]" "[']" t
("-C" "-d" "de_DE-neu.multi")
"~latin1" iso-8859-1)))
(when (my-system-type-is-windows)
;; use english on powerplantwin:
(let ((langs '("american" "german8")))
(setq lang-ring (make-ring (length langs)))
(dolist (elem langs) (ring-insert lang-ring elem)))
)
(when (my-system-type-is-gnu)
;; use US english on powerplantwin:
(let ((langs '("de_AT" "en_US")))
(setq lang-ring (make-ring (length langs)))
(dolist (elem langs) (ring-insert lang-ring elem)))
)
;; ;; use american english on all other systems:
;; (let ((langs '("german8" "american")))
;; (setq lang-ring (make-ring (length langs)))
;; (dolist (elem langs) (ring-insert lang-ring elem)))
;; )my-toggle-ispell-language()
my-toggle-ispell-language() because I use two languages and switch
between them:
(defun my-toggle-ispell-language ()
(interactive)
(let ((lang (ring-ref lang-ring -1)))
(ring-insert lang-ring lang)
(ispell-change-dictionary lang)))auto-dictionary-mode
| 2021-06-20 | disabled since I can’t remember that it did anything for me |
This mode determines the dictionary language for the current buffer according to the text found. It switches language automatically when you switch the language you’re typing.
What a relief for bilingual people like me (German/English).
(use-package auto-dictionary
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/auto-dictionary-mode/")))
)
(require 'auto-dictionary)
;;(add-hook 'text-mode-hook 'flyspell-mode) ;; according to https://github.com/nschum/auto-dictionary-mode/issues/11#issuecomment-557741953
;;(add-hook 'flyspell-mode-hook (lambda () (auto-dictionary-mode 1)))Spellchecking Source Code
Modes for programming languages; check spelling only in comments/strings
(add-hook 'c-mode-hook 'flyspell-prog-mode)
(add-hook 'sh-mode-hook 'flyspell-prog-mode)
(add-hook 'c++-mode-hook 'flyspell-prog-mode)
(add-hook 'ruby-mode-hook 'flyspell-prog-mode)
(add-hook 'cperl-mode-hook 'flyspell-prog-mode)
(add-hook 'python-mode-hook 'flyspell-prog-mode)
(add-hook 'autoconf-mode-hook 'flyspell-prog-mode)
(add-hook 'autotest-mode-hook 'flyspell-prog-mode)
(add-hook 'makefile-mode-hook 'flyspell-prog-mode)
(add-hook 'emacs-lisp-mode-hook 'flyspell-prog-mode)Keybindings
2018-06-19: disabled most bindings because I moved those functions to a hydra with F5
(define-key global-map [(f5)] 'flyspell-mode)
(bind-key "fm" 'flyspell-mode my-map);; also mapped to F5
(bind-key "fr" 'flyspell-region my-map)
(bind-key "fl" 'my-toggle-ispell-language my-map);; also mapped to Shift-F5
(define-key global-map [(shift f5)] 'my-toggle-ispell-language)
(bind-key "ft" 'my-toggle-ispell-language my-map);; can't remember if l(anguage) or t(oggle)
(bind-key "fn" 'flyspell-goto-next-error my-map)
(bind-key "ff" 'flyspell-correct-word-before-point my-map)For quickly correcting text, I keep F7 (next error) and F8 (fix) for going through the findings one by one:
(define-key global-map [(f7)] 'flyspell-goto-next-error)
(define-key global-map [(f8)] 'flyspell-correct-word-before-point)End of aspell
);; when aspell foundflycheck
«Flycheck is a modern on-the-fly syntax checking extension for GNU Emacs, intended as replacement for the older Flymake extension which is part of GNU Emacs.»
- http://www.flycheck.org/en/latest/guide/quickstart.html
- 2016-11-05: converted to use-package according to http://www.flycheck.org/en/latest/user/installation.html#use-package
(use-package flycheck
:ensure t
:init
(global-flycheck-mode)
:config
(setq flycheck-flake8-maximum-line-length 200); http://www.flycheck.org/manual/latest/Configuring-checkers.html#Configuring-checkers
)Snippets
German blog article on snippet systems: http://www.karl-voit.at/Textbausteine/
I do recommend to use snippet systems for quickly inserting static (words/numbers, sentences, paragraphs, …) or dynamic (current date/time) text.
Most snippets, I do define in a system-wide tool so that I am able to use them in every program. Some snippets I do define and use only within Emacs. Yasnippet and yankpad offers me very advanced functionality to define and use most elaborate snippets. Those snippets vary from simple ones (e.g., check-lists for packing for vacations) to rather advanced ones (e.g., a complete lecture organization with many tasks and their dependencies).
yasnippet
Yasnippet is the snippet tool to use within Emacs:
(use-package yasnippet
;:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/yasnippet/")))
:demand t
:mode ("/\\.emacs\\.d/etc/yasnippet/snippets/" . snippet-mode)
:diminish yas-minor-mode
;;:defer 90
:config
(yas-load-directory (concat my-user-emacs-directory "etc/yasnippet/snippets/"))
(yas-global-mode 1)
;; http://yasnippet.googlecode.com/svn/trunk/doc/index.html
;;disabled;(my-load-local-el "contrib/yasnippet/yasnippet.el")
;;(autoload 'yas-minor-mode "yasnippet")
;;disabled 2015-04-01 - issues did not vanish;; ;; https://capitaomorte.github.io/yasnippet/faq.html#sec-4
;;disabled 2015-04-01 - issues did not vanish;; ;; How to I use alternative keys, i.e. not TAB?
;;disabled 2015-04-01 - issues did not vanish;; ;; see id:2015-02-01-yas-expand-not-TAB
;;disabled 2015-04-01 - issues did not vanish;; (define-key yas-minor-mode-map (kbd "<tab>") nil)
;;disabled 2015-04-01 - issues did not vanish;; (define-key yas-minor-mode-map (kbd "TAB") nil)
;;disabled 2015-04-01 - issues did not vanish;; (define-key yas-minor-mode-map (kbd "<f4>") 'yas-expand)
(my-log-hostspecific "yas--version" yas--version)
)As of 2019-12-07, I moved more or less all snippets from plain yasnippet to yankpad.
yankpad
yankpad is an add-on that enables easy management of yasnippet snippets within an Org-mode file. I do define Org-mode-independent snippets with the basic yasnippet methods. Any snippet that is used within Org-mode only is defined in my yankpad file.
- see also: id:2016-08-08-yankpad-test
(use-package yankpad
:ensure t
;;:defer 110
:init
(setq yankpad-file (concat my-org-files-path "yankpad.org"))
:bind (:map my-map ("SPC" . yankpad-insert)
("y" . yankpad-expand)
)
:config
(bind-key "<S-f5>" 'yankpad-expand)
(bind-key "<S-f6>" 'yankpad-map)
(setq yankpad-default-category "org-mode")
)Programming
company (completion)
| 2021-04-04 | stolen config from https://github.com/zamansky/dot-emacs for playing with LSP |
(use-package company
:ensure t
:config
(setq company-idle-delay 0)
(setq company-minimum-prefix-length 3)
(add-hook 'after-init-hook 'global-company-mode)
;; (global-company-mode t)
;; disable company mode in org mode:
(add-hook 'org-mode-hook (lambda () (company-mode -1)))
)Git
This is a section where all Git-related configuration is happening.
magit → my-map g
«Magit is an interface to the version control system Git, implemented as an Emacs package. Magit aspires to be a complete Git porcelain. While we cannot (yet) claim that Magit wraps and improves upon each and every Git command, it is complete enough to allow even experienced Git users to perform almost all of their daily version control tasks directly from within Emacs. While many fine Git clients exist, only Magit and Git itself deserve to be called porcelains.»
Some people start using Emacs just to be able to use this nifty Git interface of Magit.
;;2018-07-09 test when using GitHub version;;(setq with-editor-file-name-history-exclude 1) ;; https://github.com/syl20bnr/spacemacs/issues/7225
(use-package magit
;;2018-07-09 disabled because lots of errors on load;; :load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/magit/lisp/")))
:if (and (my-eval-if-binary-or-warn "git") (my-system-type-is-gnu))
:ensure t ;; install package if not found OR: (setq use-package-always-ensure t)
;; :bind (:map magit-status-mode-map ("q" magit-quit-session))
:config ;; executed after loading package
(setq magit-diff-refine-hunk 'all) ;; enable in-line diff highlighting
;; full screen magit-status
;; http://whattheemacsd.com//setup-magit.el-01.html
(defadvice magit-status (around magit-fullscreen activate)
(window-configuration-to-register :magit-fullscreen)
ad-do-it
(delete-other-windows))
(defun magit-quit-session ()
"restores the previous window configuration and kills the magit buffer"
(interactive)
(kill-buffer)
(jump-to-register :magit-fullscreen))(bind-key "g" #'magit-status my-map)smeargle (highlighting)
Disabled 2020-01-07 because I don’t use it.
- smeargle - Highlighting Regions by Last Updated Time (my-map c)
- https://github.com/syohex/emacs-smeargle/
- M-x smeargle - Highlight regions by last updated time.
- M-x smeargle-age - Highlight regions by age of changes.
- M-x smeargle-clear - Clear overlays in current buffer
(use-package smeargle
:ensure t
:defer 110
:config ;; executed after loading package
;;:bind (:map my-map ("c" . smeargle)) ;; CONFLICTS with my title capitalizationYou can set highlighted colors of smeargle by changing smeargle-colors:
(custom-set-variables
'(smeargle-colors '((older-than-1day . "red")
(older-than-3day . "green")
(older-than-1week . "yellow")
(older-than-2week . nil)
(older-than-1month . "orange")
(older-than-3month . "pink")
(older-than-6month . "cyan")
(older-than-1year . "grey50"))))And you can also set colors of smeargle-commits by smeargle-age-colors:
(custom-set-variables
'(smeargle-age-colors '((0 . nil)
(1 . "grey80")
(2 . "grey70")
(3 . "grey60")
(4 . "grey50")
(5 . "grey40")
(6 . "grey30")
(7 . "grey20")
(8 . "grey10"))))You can specify parameters until smeargle-age-threshold. age is set to
smeargle-age-threshold if actual age of changes is older than
smeargle-age-threshold. Default value of smeargle-age-threshold is 7.
Misc settings:
(global-set-key (kbd "C-x v s") 'smeargle)
(global-set-key (kbd "C-x v c") 'smeargle-commits)
;; Highlight regions at opening file
(add-hook 'find-file-hook 'smeargle)
;; Updating after save buffer
(add-hook 'after-save-hook 'smeargle)End of smeargle:
);; end of smeargleGitGutter
2019-12-31: DISABLED for performance reasons: https://www.reddit.com/r/orgmode/comments/e9p84n/scaling_org_better_to_use_more_medsize_files_or/fcm5bsc/
GitGutter is visualizing modified lines within the source code buffer.
(use-package git-gutter
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/emacs-git-gutter/")))
:configEither you use the global minor mode …
(global-git-gutter-mode +1)
;; inactivate git-gutter-mode in asm-mode and image-mode
(custom-set-variables
'(git-gutter:disabled-modes '(asm-mode image-mode)))… or activate the minor mode for specific modes:
(add-hook 'python-mode-hook 'git-gutter-mode)
(add-hook 'ruby-mode-hook 'git-gutter-mode)Keyboard bindings: Jump to next/previous hunk
(global-set-key (kbd "S-<f2>") 'git-gutter:previous-hunk)
(global-set-key (kbd "S-<f3>") 'git-gutter:next-hunk)More bindings:
(global-set-key (kbd "C-x C-g") 'git-gutter)
(global-set-key (kbd "C-x v =") 'git-gutter:popup-hunk)
;; Jump to next/previous hunk
(global-set-key (kbd "C-x p") 'git-gutter:previous-hunk)
(global-set-key (kbd "C-x n") 'git-gutter:next-hunk)
;; Stage current hunk
(global-set-key (kbd "C-x v s") 'git-gutter:stage-hunk)
;; Revert current hunk
(global-set-key (kbd "C-x v r") 'git-gutter:revert-hunk)
;; Mark current hunk
(global-set-key (kbd "C-x v SPC") #'git-gutter:mark-hunk)If you set git-gutter:update-interval seconds larger than 0, git-gutter updates diff information in real-time by idle timer.
(custom-set-variables
'(git-gutter:update-interval 2))Pass option to ‘git diff’ command: You can pass git diff option to set git-gutter:diff-option.
;; ignore all spaces
(custom-set-variables
'(git-gutter:diff-option "-w"))Customize visualization:
(custom-set-variables
'(git-gutter:modified-sign "~ ") ;; two space
'(git-gutter:added-sign "++") ;; multiple character is OK
'(git-gutter:deleted-sign "--"))
(set-face-background 'git-gutter:modified "purple") ;; background color
(set-face-foreground 'git-gutter:added "green")
(set-face-foreground 'git-gutter:deleted "red")You can change minor-mode name in mode-line to set git-gutter:lighter.
Default is GitGutter. First character should be a space.
(custom-set-variables
'(git-gutter:lighter " GG"))End of git-gutter:
)git-timemachine
2019-12-08: disabled because I was not using it.
Step through historic versions: https://github.com/pidu/git-timemachine (2018-09-02: repo has been removed)
A page with an animated GIF showing its functionality.
Step through historic versions of git controlled file using everyone’s favourite editor
Visit a git-controlled file and issue
M-x git-timemachine(or bind it to a keybinding of your choice). If you just need to toggle the time machine you can useM-x git-timemachine-toggle.Use the following keys to navigate historic version of the file
p Visit previous historic version n Visit next historic version w Copy the abbreviated hash of the current historic version W Copy the full hash of the current historic version g Goto nth revision q Exit the time machine. b Run magit-blame on the currently visited revision (if magit available).
(use-package git-timemachine
:ensure t
:defer 120
:initSource -> start from selected revision instead of HEAD
(defun my-git-timemachine-show-selected-revision ()
"Show last (current) revision of file."
(interactive)
(let (collection)
(setq collection
(mapcar (lambda (rev)
;; re-shape list for the ivy-read
(cons (concat (substring (nth 0 rev) 0 7) "|" (nth 5 rev) "|" (nth 6 rev)) rev))
(git-timemachine--revisions)))
(ivy-read "commits:"
collection
:action (lambda (rev)
(git-timemachine-show-revision rev)))))Open git snapshot with the selected version. Based on ivy-mode:
(defun my-git-timemachine ()
"Open git snapshot with the selected version. Based on ivy-mode."
(interactive)
(unless (featurep 'git-timemachine)
(require 'git-timemachine))
(git-timemachine--start #'my-git-timemachine-show-selected-revision))end of git-timemachine:
);; end of git-timemachinemagit-log–add-date-headers
From: https://github.com/alphapapa/unpackaged.el
This requires ov.el: https://github.com/emacsorphanage/ov
(use-package ov
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/ov/")))
)(defun unpackaged/magit-log--add-date-headers (&rest _ignore)
"Add date headers to Magit log buffers."
(when (derived-mode-p 'magit-log-mode)
(save-excursion
(ov-clear 'date-header t)
(goto-char (point-min))
(cl-loop with last-age
for this-age = (-some--> (ov-in 'before-string 'any (line-beginning-position) (line-end-position))
car
(overlay-get it 'before-string)
(get-text-property 0 'display it)
cadr
(s-match (rx (group (1+ digit) ; number
" "
(1+ (not blank))) ; unit
(1+ blank) eos)
it)
cadr)
do (when (and this-age
(not (equal this-age last-age)))
(ov (line-beginning-position) (line-beginning-position)
'after-string (propertize (concat " " this-age "\n")
'face 'magit-section-heading)
'date-header t)
(setq last-age this-age))
do (forward-line 1)
until (eobp)))))
(define-minor-mode unpackaged/magit-log-date-headers-mode
"Display date/time headers in `magit-log' buffers."
:global t
(if unpackaged/magit-log-date-headers-mode
(progn
;; Enable mode
(add-hook 'magit-post-refresh-hook #'unpackaged/magit-log--add-date-headers)
(advice-add #'magit-setup-buffer-internal :after #'unpackaged/magit-log--add-date-headers))
;; Disable mode
(remove-hook 'magit-post-refresh-hook #'unpackaged/magit-log--add-date-headers)
(advice-remove #'magit-setup-buffer-internal #'unpackaged/magit-log--add-date-headers)))End of Git
) ;; end of magit use-package
;(my-log-hostspecific "magit-version" magit-version) ;; doesn't work (anywhere here) for some reasonhighlight-symbol → my-map h
This package does highlight all occurrences of a given word. Very handy when programming: visualize all occurrences of a variable/function.
Note: This package here somehow overlaps with the “hover” feature of a
LSP server that supports it. In that case, you should disable the
highlight-symbol-mode below.
(use-package highlight-symbol
:ensure t
:defer 110
;;(bind-key (kbd "h") #'highlight-symbol my-map)
:bind (:map my-map ("h" . highlight-symbol))
:hook (python-mode . highlight-symbol-mode)
)
;; original: (global-set-key [(control f3)] 'highlight-symbol)
;; original: (global-set-key [f3] 'highlight-symbol-next)
;; original: (global-set-key [(shift f3)] 'highlight-symbol-prev)
;; original: (global-set-key [(meta f3)] 'highlight-symbol-query-replace)projectile
| 2020-12-10 | initial setup |
(use-package projectile
:ensure t
:defer 110
)Language Server Protocol (LSP) → C-c l
| 2021-04-03 | initial setup for testing with Python/pyls |
Why? Python code completion was always a bit of a drag. I don’t code that often. When there was a long break between my Python sessions, somehow code completion was a fragile thing that often did not work. Because of this thread I do give LSP a try.
lsp-mode:
(use-package lsp-mode
:ensure t
:init
;; set prefix for lsp-command-keymap (few alternatives - "C-l", "C-c l")
(setq lsp-keymap-prefix "C-c l")
:hook ((python-mode . lsp)
;; if you want which-key integration
;; (lsp-mode . lsp-enable-which-key-integration) ;; 2021-04-04: I'm using lsp-deferred instead
)
:commands lsp
)- [ ] FIXXME: maybe customize
- lsp-pyls-plugins-flake8-ignore
- lsp-pyls-plugins-pycodestyle-max-line-length
- lsp-pyls-plugins-flake8-max-line-length
lsp-ui:
(use-package lsp-ui
:ensure t
:commands lsp-ui-mode
:hook (lsp-mode . lsp-ui-mode)
:config
(setq lsp-ui-sideline-enable t)
(setq lsp-ui-sideline-show-hover nil)
(setq lsp-ui-doc-position 'bottom)
;; lsp config stuff
(setq lsp-enable-links t)
(setq lsp-signature-render-documentation t)
(setq lsp-headerline-breadcrumb-enable t)
(setq lsp-ui-doc-enable t)
(setq lsp-completion-enable-additional-text-edit nil)
(setq web-mode-enable-current-element-highlight t)
(lsp-ui-doc-show)
)for helm:
(use-package helm-lsp :ensure t :commands helm-lsp-workspace-symbol)others:
;; ;; if you are ivy user
;; (use-package lsp-ivy :commands lsp-ivy-workspace-symbol)
;; (use-package lsp-treemacs :commands lsp-treemacs-errors-list)
;; optionally if you want to use debugger
;; watch https://www.youtube.com/watch?v=0bilcQVSlbM to get an idea
;; (use-package dap-mode :ensure t)
;; (use-package dap-python :ensure t) ;; to load the dap adapter for your language
;;;; optional if you want which-key integration
;;(use-package which-key
;; :ensure t
;; :config
;; (which-key-mode))Elisp
This heading contains configurations for editing Elisp code.
separate color for highlightning () brackets: http://compgroups.net/comp.emacs/to-use-special-color-for-brackets-in-emacs-lisp-mo/222015
;; ######################################################
(defface paren-face
'((((class color) (background dark))
(:foreground "grey30"))
(((class color) (background light))
(:foreground "grey60")))
"Face used to dim parentheses.")
(defun egoge-dim-parens ()
(font-lock-add-keywords nil
'(("(\\|)" . 'paren-face))))
(add-hook 'emacs-lisp-mode-hook 'egoge-dim-parens)Do not use Auto Fill Mode for Lisp mode:
(add-hook 'emacs-lisp-mode-hook 'turn-off-auto-fill)When editing code that uses parenthesis, enabling this does highlight the matching parenthesis:
(show-paren-mode t)ert
for using unit tests of yasnippet (see id:2013-02-07yasnippetdebuggen and yasnippet-tests.el)
(my-load-local-el "contrib/cl-lib.el")
(my-load-local-el "contrib/ert.el")
(my-load-local-el "contrib/ert-x.el")buttercup - Elisp test suite
Buttercup is a behavior-driven development framework for testing Emacs Lisp code. It allows to group related tests so they can share common set-up and tear-down code, and allows the programmer to “spy” on functions to ensure they are called with the right arguments during testing.
The framework is heavily inspired by Jasmine.
Disabled for now because I do not use it at the moment.
(use-package buttercup
:ensure t
; :if (my-system-is-floyd)
:defer 110
:config
)smartparens - highlight corresponding parens
- nice overview of different hightlight modes: http://danmidwood.com/content/2014/11/21/animated-paredit.html
- nice overview: https://ebzzry.github.io/emacs-pairs.html (Dead link as of 2017-05-26)
(use-package smartparens
:init
(smartparens-global-mode 1)
(show-smartparens-global-mode +1)
:bind (;; ("M-n" . sp-next-sexp)
;; ("M-p" . sp-previous-sexp)
("M-f" . sp-forward-sexp)
("M-b" . sp-backward-sexp)
)
:config
;; Enable smartparens everywhere
(use-package smartparens-config)
;; ;; Require and disable paredit because some packages rely on it.
;; (use-package paredit)
;; (disable-paredit-mode)
(setq
smartparens-strict-mode t
sp-autoinsert-if-followed-by-word t
sp-autoskip-closing-pair 'always
;;sp-base-key-bindings 'paredit
sp-hybrid-kill-entire-symbol nil)
;; (sp-use-paredit-bindings)
;; (sp-with-modes '(markdown-mode gfm-mode rst-mode)
;; (sp-local-pair "*" "*" :bind "C-*")
;; (sp-local-tag "2" "**" "**")
;; (sp-local-tag "s" "```scheme" "```")
;; (sp-local-tag "<" "<_>" "</_>" :transform 'sp-match-sgml-tags))
;; ;; Close a backtick with another backtick in clojure-mode
;; (sp-local-pair 'clojure-mode "`" "`" :when '(sp-in-string-p))
(sp-local-pair 'emacs-lisp-mode "`" nil :when '(sp-in-string-p))
)
s - «The long lost Emacs string manipulation library.»
https://github.com/magnars/s.el
(use-package s
:ensure t
:defer 90
:config
)Elisp: → my-map er|el|ef
Misc bindings for Elisp:
(bind-key "er" #'eval-region my-map)
(bind-key "el" #'find-library my-map)
(bind-key "ef" #'find-function-at-point my-map)macrostep
I found the macrostep package through the Irreal article John Wiegley and Sacha Chua on use-package which links 2015-04-01 Emacs package highlight: use-package from YouTube.
(use-package macrostep
;;:ensure t
:defer 120
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/macrostep/")))
:config ;; executed after loading package
(define-key emacs-lisp-mode-map (kbd "C-c e") 'macrostep-expand)
)From the README:
The standard keybindings in
macrostep-modeare the following:
- e, =, RET
- expand the macro form following point one step
- c, u, DEL
- collapse the form following point
- q, C-c C-c
- collapse all expanded forms and exit macrostep-mode
- n, TAB
- jump to the next macro form in the expansion
- p, M-TAB
- jump to the previous macro form in the expansion
It’s not very useful to enable and disable macrostep-mode directly. Instead, bind
macrostep-expandto a key inemacs-lisp-mode-map, for example C-c e:(define-key emacs-lisp-mode-map (kbd "C-c e") 'macrostep-expand)You can then enter macrostep-mode and expand a macro form completely by typing
C-c e e e ...as many times as necessary.Exit macrostep-mode by typing
qorC-c C-c, or by successively typingcto collapse all surrounding expansions.
lisp-format
| 2021-07-31 | I wanted to test the Elisp formatter for formatting my code |
(use-package elisp-format
:ensure t
:defer 110
)Python
| 2021-04-04 | shift from previous elpy-based setup to a LSB-based setup |
This heading contains configurations for editing Python code. Python is the programming language I prefer for my private projects. I do like its easy-to-read syntax, providing a high level of maintainability. It also ships with a large set of libraries.
Selected keyboard commands (summary): (see defined hydra for python mode!)
| Key | Command | Command |
|---|---|---|
| M-h | hide/show current function | hs-cycle |
| C-c l g g | find definition | lsp-find-definition |
| C-c l g r | find references | lsp-find-references |
| <missing> | function overview |
BEGIN of Python-related stuff
The code blocks here are only executed when python is found on the current system:
(when (my-eval-if-binary-or-warn "python")auto-mode-list for Python files
(add-to-list 'auto-mode-alist '("\\.py$" . python-mode))
(add-to-list 'auto-mode-alist '("\\.py$" . company-mode))
(add-hook 'python-mode-hook
(lambda ()
(lsp-mode)
))
pyls (LSP)
- https://emacs-lsp.github.io/lsp-mode/page/lsp-pyls/
- https://github.com/palantir/python-language-server
- “The base language server requires Jedi to provide Completions, Definitions, Hover, References, Signature Help, and Symbols”
- https://github.com/palantir/python-language-server
sudo python3 -m pip install 'python-language-server[all]'
or even better:
python3 -m pip install --user 'python-language-server[all]'
Optional:
sudo python3 -m pip install pyls-mypy
On [2021-08-27 Fri] my Emacs wrote:
Warning (emacs): The palantir python-language-server (pyls) is unmaintained; a maintained fork is the python-lsp-server (pylsp) project; you can install it with pip via: pip install python-lsp-server Disable showing Disable logging
So I did:
sudo python3 -m pip uninstall 'python-language-server[all]' sudo python3 -m pip install python-lsp-server
jedi (LSP)
[2021-04-04 Sun 16:56] disabled: I want to test pure pyls
Setup according to https://github.com/zamansky/dot-emacs
(use-package lsp-jedi
:ensure t
:config
(with-eval-after-load "lsp-mode"
(add-to-list 'lsp-disabled-clients 'pyls)
(add-to-list 'lsp-enabled-clients 'jedi)))
(setq lsp-ui-doc-show-with-cursor nil)Switch to ipython (NOT YET TESTED)
From this reddit and this solution: NOT TESTED YET! (2017-10-02)
2019-01-20: this reddit thread suggests overwriting
python-shell-interpreter in order to switch to Python 3. (not
tested/confirmed yet)
(if (my-eval-if-binary-or-warn "ipython3")
(setq python-shell-interpreter "ipython3"
python-shell-interpreter-args "--simple-prompt -i")
;; else:
(when (my-eval-if-binary-or-warn "python3")
(setq python-shell-interpreter "python3")
)
)Note: Org mode babel is using org-babel-python-command which is set
elsewhere (to python3 as of 2019-03-05).
flymake, flycheck
| 2021-04-04 | I’m unsure if this is still necessary after switching to LSP/pyls |
FlyMake performs on-the-fly syntax checks on the files being edited using the external syntax check tool (usually the compiler). Highlights erroneous lines and displays associated error messages.
Unfortunately, this project is outdated and last change was 3 years ago.
For a modern alternative, check out Flycheck.
- fix flymake (PEP8): ignore E501 (long lines)
- see id:2015-04-04-flymake and http://stackoverflow.com/a/1393590
- looks similar: http://people.cs.uct.ac.za/~ksmith/2011/better-python-flymake-integration-in-emacs.html
(when (load "flymake" t)
(defun flymake-pyflakes-init ()
(let* ((temp-file (flymake-init-create-temp-buffer-copy
'flymake-create-temp-inplace))
(local-file (file-relative-name
temp-file
(file-name-directory buffer-file-name))))
(list "~/bin/pycheckers" (list local-file))))
(add-to-list 'flymake-allowed-file-name-masks
'("\\.py\\'" flymake-pyflakes-init)))better than flymake (and maintained): http://stackoverflow.com/a/1621489 Flycheck
(add-hook 'python-mode-hook
(lambda ()
(unless (eq buffer-file-name nil) (flymake-mode 1)) ;dont invoke flymake on temporary buffers for the interpreter
(local-set-key [f6] 'flymake-goto-prev-error)
(local-set-key [f7] 'flymake-goto-next-error)
))hideshow-orgmode
I found hideshow-orgmode via this reddit thread. It provides (Python)
code outlining similar to Org-mode TAB visibility cycling. This is a
very nice thing to have. So far, I used yafolding-mode for it.
This needs the hideshow minor mode M-x hideshow-minor-mode enabled
to work.
(use-package hideshow-orgmode
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/hideshow-orgmode")))
:config
(add-hook 'python-mode-hook (lambda ()
(hs-minor-mode 1)
;;(hs-cycle-all)
(global-set-key (kbd "M-h") 'hs-cycle)
(global-set-key (kbd "M-H") 'hs-cycle-all)
))
)sphinx-doc.el
Source: https://github.com/naiquevin/sphinx-doc.el
sphinx-docis an emacs minor mode for inserting docstring skeleton for Python functions and methods. The structure of the docstring is as per the requirement of the Sphinx documentation generator.
(use-package sphinx-doc
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/sphinx-doc.el")))
:ensure t
:config
(add-hook 'python-mode-hook (lambda ()
(require 'sphinx-doc)
(sphinx-doc-mode t)))
)Issue:
let: Symbol’s value as variable is void: sphinx-doc-python-indent
… when applied. I could not find anything related.
elpygen → C-c i
From GitHub: “Generate Python function/method stub for a call-like symbol under point”
Just write a_function_call(first_named, 2, second_named), invoke the
command elpygen-implement and elpygen either jumps to the existing
function or it generates a stub for a new one. The example above
results in def a_function_call(first_named, arg1, second_named):\npass.
(use-package elpygen
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/elpygen")))
:ensure t
:config
(require 'elpygen)
(define-key python-mode-map (kbd "C-c i") 'elpygen-implement)
)END of Python-related stuff
);; if python binary founddired
Usually, I do file management in tmux and zsh. There are my aliases, my functions, the features I like. Having a file manager in Emacs does have some advantages.
Dired tipps from ergoemacs. Mastering Emacs on Dired.
Here are some minor tweaks related to file management in Emacs with dired.
From Emacsrocks #16: two window file management. From the documentation:
If non-nil, Dired tries to guess a default target directory. This means: if there is a Dired buffer displayed in the next window, use its current directory, instead of this Dired buffer’s current directory.
(setq dired-dwim-target t)
;;(setq dired-listing-switches "-al --group-directories-first")from: Marcin Borkowski: 2018-12-10 Lesser known Dired stuff: create parent directories when slashes are used when renaming files:
;(setq wdired-create-parent-directories t) FIXXME: enable when my old installation gets an updatedired-garbage-files-regexp - define garbage file regex
In dired, you can press %& which calls dired-flag-garbage-files().
By default, it uses the regular expression
=”\(?:\.\(?:aux\|bak\|dvi\|log\|orig\|rej\|toc\)\)\’”=
which does not include miscelaneous file extensions I am working with.
Therefore, I overwrite the regex with my own values:
(setq dired-garbage-files-regexp "\\(?:\\.\\(?:aux\\|bak\\|bbl\\|bcf\\|dvi\\|log\\|rej\\|toc\\)\\)\\'")dired-details → (
- [ ] FIXXME 2018-07-06: think of switching to dired-details+ (which offers some functionality I currently do not use).
Also from Emacsrocks #16: hide and show file details with ( and ):
(use-package dired-details
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/")))
;;:defer 90
:config
(setq-default dired-details-hidden-string "… ")
)dired-x, dired+, dired-icon
Enabling already pre-insalled dired-x:
(require 'dired-x)Dired+ has lots of useful features
- Dired plus is not available on MELPA: reddit thread. It needs to be fetched via https://www.emacswiki.org/emacs/download/dired%2b.el. I wrote an update shell script for it.
(use-package dired+
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/dired-plus/")))
;; :ensure t
;;:defer 90
:config
(diredp-toggle-find-file-reuse-dir 1) ;; https://www.emacswiki.org/emacs/DiredReuseDirectoryBuffer
)2019-02-05: disabled because loading a new dired buffer took very long with it although it really looked nicely:
(use-package dired-icon
:ensure t
;;:defer 110
:config
(add-hook 'dired-mode-hook 'dired-icon-mode)
)Bind backspace to visit higher level directory:
(define-key dired-mode-map (kbd "<backspace>") 'diredp-up-directory-reuse-dir-buffer)helm-dired-history
- [ ] ivy-dired-history is an alternative to:
(use-package helm-dired-history
:ensure t
:config
(require 'savehist)
(add-to-list 'savehist-additional-variables 'helm-dired-history-variable)
(savehist-mode 1)
(with-eval-after-load 'dired
(require 'helm-dired-history)
(define-key dired-mode-map "," 'dired))
)dired-recent → C-z
This is one of the killer-features of (any) file-browser application:
offer a quick search of recently visited directories. I never maintain
any directory bookmarks any more. I use a similar feature in my zsh
via z. You might also look into GoTo (on steroids) of fman.
“Press C-x C-d to select a previously visited directory to open.”
(use-package dired-recent
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/dired-recent.el/")))
;;:defer 90
:config
(require 'dired-recent)
(dired-recent-mode 1)
(setq dired-recent-max-directories nil) ;; nil means to remember all
)Make better use of dired-recent-open using ivy:
(defun my-dired-recent-dirs ()
"Present a list of recently used directories and open the selected one in dired"
(interactive)
(let ((dir (ivy-read "Directory: "
dired-recent-directories
:re-builder #'ivy--regex
:sort nil
:initial-input nil)))
(dired dir)))
(global-set-key (kbd "C-z") 'my-dired-recent-dirs)Maybe, this can be optimized by using frecency for scoring entries (like in fman or this feature-request for FreeCommander). So far, I’m quite happy with the current feature.
dired-narrow → /
From http://pragmaticemacs.com/emacs/dynamically-filter-directory-listing-with-dired-narrow/ with https://github.com/Fuco1/dired-hacks
It narrows down the list of files using a pattern. g resets the view.
(use-package dired-narrow
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/dired-hacks/")))
;;:defer 90
:bind (:map dired-mode-map
("/" . dired-narrow)))dired-open
From https://github.com/Fuco1/dired-hacks
Provides:
dired-open-xdgtry to open the file usingxdg-opendired-open-guess-shell-alisttry to open the file by launching applications fromdired-guess-shell-alist-userdired-open-call-function-by-extensioncall an elisp function based on extension.
(use-package dired-open
;;:defer 90
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/dired-hacks/")))
)dired-collapse
From https://github.com/Fuco1/dired-hacks#dired-collapse
Provides:
dired-open-xdgtry to open the file usingxdg-opendired-open-guess-shell-alisttry to open the file by launching applications fromdired-guess-shell-alist-userdired-open-call-function-by-extensioncall an elisp function based on extension.
(use-package dired-collapse
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/dired-hacks/")))
;;:defer 90
:config
;(dired-collapse-mode)
)image-dired+
Image-dired extensions: https://www.emacswiki.org/emacs/ImageDired
- Non-blocking thumbnail creating
- Adjust image to window
- https://www.youtube.com/watch?v=NrY3t3W0_cM → image-dired demo
- basic usage
- open externally
- tag images
To enter Image-Dired, mark the image files you want to look at in the Dired buffer, using
mas usual. Then typeC-t d(image-dired-display-thumbs). This creates and switches to a buffer containing image-dired, corresponding to the marked files.You can also enter Image-Dired directly by typing
M-x image-dired. This prompts for a directory; specify one that has image files. This creates thumbnails for all the images in that directory, and displays them all in the thumbnail buffer. This takes a long time if the directory contains many image files, and it asks for confirmation if the number of image files exceedsimage-dired-show-all-from-dir-max-files.
FIXXME: 2018-06-30: There is a issue on floyd. I get following error
when I mark files and invoke C-t d:
[...] error in process sentinel: image-diredx--invoke-process: Wrong type argument: processp, [nil 23351 46922 931735 nil image-dired-thumb-queue-run nil nil 787000] error in process sentinel: Wrong type argument: processp, [nil 23351 46922 931735 nil image-dired-thumb-queue-run nil nil 787000] [...] Marking files... 377 files newly marked image-diredx--invoke-process: Wrong type argument: processp, [nil 23351 47004 248326 nil image-dired-thumb-queue-run nil nil 669000] [...]
(use-package image-dired+
:ensure t
:defer 110
:config
(require 'image-dired+)
(image-diredx-async-mode 1)
(image-diredx-adjust-mode 1)
(define-key image-dired-thumbnail-mode-map "\C-n" 'image-diredx-next-line)
(define-key image-dired-thumbnail-mode-map "\C-p" 'image-diredx-previous-line)
(define-key image-dired-thumbnail-mode-map "g" 'revert-buffer);; revert all thumbnails if `image-diredx-async-mode' is on
(define-key image-dired-thumbnail-mode-map "x" 'image-diredx-flagged-delete);; Delete confirmation prompt with thumbnails
(setq image-dired-track-movement nil) ;; Suppress unknown cursor movements
(setq image-dired-external-viewer "/usr/bin/geeqie") ;; FIXXME: configure different for Windows
)dired-ranger → M-c; M-v; M-m
From https://github.com/Fuco1/dired-hacks:
With the multi-stage operations, you can gather files from multiple dired buffers into a single “clipboard”, then copy or move all of them to the target location. Another huge advantage is that if the target dired buffer is already opened, switching to it via ido or ibuffer is often faster than selecting the path.
Call
dired-ranger-copyto add marked files (or the file under point if no files are marked) to the “clipboard”. With non-nil prefix argument, add the marked files to the current clipboard.Past clipboards are stored in
dired-ranger-copy-ringso you can repeat the past pastes.Call
dired-ranger-pasteordired-ranger-moveto copy or move the files in the current clipboard to the current dired buffer. With raw prefix argument (usually C-u), the clipboard is not cleared, so you can repeat the copy operation in another dired buffer.
(use-package dired-ranger
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/dired-hacks/")))
:defer 110 ;; has to be after dired+ in able to overwrite its bindings below
:config
(define-key dired-mode-map (kbd "M-c") 'dired-ranger-copy) ;; overwrites: diredp-capitalize-this-file
(define-key dired-mode-map (kbd "M-v") 'dired-ranger-paste) ;; overwrites: scroll-down-command
(define-key dired-mode-map (kbd "M-m") 'dired-ranger-move) ;; overwrites: back-to-indentation
)dired-isearch
Via EmacsWiki and download from http://www.emacswiki.org/emacs/download/dired-isearch.el
(use-package dired-isearch
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/")))
:defer 110
:config
)Not necessary any more. There is built-in functionality which I just
have to re-map to C-s (because I don’t need reverse or RegEx
search):
(define-key dired-mode-map (kbd "C-s") 'dired-isearch-filenames)looking for: filetags, date2name, appendfilename
(setq my-filetags-file (my-binary-found "filetags"))
(when (and (not my-filetags-file) (my-system-type-is-gnu))
(progn (message "using manual src path for \"filetags\"")
(setq my-filetags-file (my-binary-found "/home/vk/src/filetags/filetags/__init__.py"))
)
)
(setq my-date2name-file (my-binary-found "date2name"))
(when (and (not my-date2name-file) (my-system-type-is-gnu))
(progn (message "using manual src path for \"date2name\"")
(setq my-date2name-file (my-binary-found "/home/vk/src/date2name/date2name/__init__.py"))
)
)
(setq my-appendfilename-file (my-binary-found "appendfilename"))
(when (and (not my-appendfilename-file) (my-system-type-is-gnu))
(progn (message "using manual src path for \"appendfilename\"")
(setq my-appendfilename-file (my-binary-found "/home/vk/src/appendfilename/appendfilename/__init__.py"))
)
)my-dired-filetags → M-t
(defun my-dired-filetags ()
"Run \"filetags\" on current or marked files"
(interactive)
(let* ((marked-files (f-uniquify (dired-get-marked-files)))) ;; apply to single file or marked files
(when (string-equal system-name "GRZN17009")
;;works (let ((proc (start-process "cmd" nil "cmd.exe" "/C" "start" "cmd.exe" "/K" "echo \"Hello\"")))
;;(message (concat "CALLING: c:/Users/karl.voit/bin/filetags.bat -sv " marked-files))
(let ((proc (start-process "cmd" nil "cmd.exe" "/C" "start" "cmd.exe" "/C"
"c:/Users/karl.voit/bin/filetags.bat -sv"
(shell-quote-argument marked-files)))
(set-process-query-on-exit-flag proc nil)))
;;(dired-do-shell-command "cmd.exe /K c:/Users/karl.voit/bin/filetags.bat *" nil marked-files)
)
(when (string-equal system-name "cosmo")
(let ((proc (start-process "cmd" nil "cmd.exe" "/C" "start" "cmd.exe" "/C"
"C:/Users/John/AppData/Roaming/filetags.bat -sv"
(shell-quote-argument marked-files)))
(set-process-query-on-exit-flag proc nil)))
)
(when (my-system-type-is-gnu)
;; FIXXME: maybe add check for binary: (when (my-eval-if-binary-or-warn "xfce4-terminal")
;; --disable-server → provides a blocking terminal window (instead of a non-blocking one which swallows the revert-buffer afterward)
(dired-do-shell-command (concat "xfce4-terminal --disable-server --geometry=100x20+330+5 --hide-menubar -x " my-filetags-file " --interactive *") nil marked-files)
)
(revert-buffer nil t t) ;; refresh listing of files
)
)
(define-key dired-mode-map (kbd "M-t") 'my-dired-filetags)my-dired-appendfilename → M-a
(defun my-dired-appendfilename ()
"Run \"appendfilename\" on current or marked files"
(interactive)
(let* ((marked-files (f-uniquify (dired-get-marked-files)))) ;; apply to single file or marked files
(when (my-system-type-is-windows)
(dired-do-shell-command "FIXXME xfce4-terminal --geometry=100x20+330+5 --hide-menubar -x /home/vk/bin/filetags --interactive *" nil marked-files)
)
(when (my-system-type-is-gnu)
;; FIXXME: maybe add check for binary: (when (my-eval-if-binary-or-warn "xfce4-terminal")
;; --disable-server → provides a blocking terminal window (instead of a non-blocking one which swallows the revert-buffer afterward)
(dired-do-shell-command (concat "xfce4-terminal --disable-server --geometry=90x5+330+5 --hide-menubar -x " my-appendfilename-file " *") nil marked-files)
)
)
(revert-buffer nil t t)
)
(define-key dired-mode-map (kbd "M-a") 'my-dired-appendfilename)my-dired-filetags-filter → F1
(defun my-dired-filetags-filter ()
"Run \"filetags --filter\" on current or marked files"
(interactive)
(let* ((marked-files (f-uniquify (dired-get-marked-files)))) ;; apply to single file or marked files
(when (my-system-type-is-windows)
(dired-do-shell-command "FIXXME xfce4-terminal --geometry=100x20+330+5 --hide-menubar -x /home/vk/bin/filetags --interactive *" nil marked-files)
)
(when (my-system-type-is-gnu)
;; FIXXME: maybe add check for binary: (when (my-eval-if-binary-or-warn "xfce4-terminal")
(dired-do-shell-command (concat "xfce4-terminal --geometry=90x5+330+5 --hide-menubar -x " my-filetags-file " --filter *") nil marked-files)
)
)
)my-dired-filetags-filter-recursive → F1
(defun my-dired-filetags-filter-recursive ()
"Run \"filetags --filter --recursive\" on current or marked files"
(interactive)
(let* ((marked-files (f-uniquify (dired-get-marked-files)))) ;; apply to single file or marked files
(when (my-system-type-is-windows)
(dired-do-shell-command "FIXXME xfce4-terminal --geometry=100x20+330+5 --hide-menubar -x /home/vk/bin/filetags --interactive *" nil marked-files)
)
(when (my-system-type-is-gnu)
;; FIXXME: maybe add check for binary: (when (my-eval-if-binary-or-warn "xfce4-terminal")
(dired-do-shell-command (concat "xfce4-terminal --geometry=90x5+330+5 --hide-menubar -x " my-filetags-file " --filter --recursive *") nil marked-files)
)
)
)my-dired-tagtrees → F1
(defun my-dired-tagtrees ()
"Run \"filetags --tagtrees\" on current or marked files"
(interactive)
(let* ((marked-files (f-uniquify (dired-get-marked-files)))) ;; apply to single file or marked files
(when (my-system-type-is-windows)
(dired-do-shell-command "filetags --tagtrees --tagtrees-handle-no-tag no-tags" nil marked-files)
)
(when (my-system-type-is-gnu)
;; FIXXME: maybe add check for binary: (when (my-eval-if-binary-or-warn "xfce4-terminal")
(dired-do-shell-command (concat "xfce4-terminal --geometry=90x5+330+5 --hide-menubar -x " my-filetags-file " --tagtrees --tagtrees-handle-no-tag no-tags *") nil marked-files)
)
)
)my-dired-tagtrees-recursive → F1
(defun my-dired-tagtrees-recursive ()
"Run \"filetags --tagtrees --recursive\" on current or marked files"
(interactive)
(let* ((marked-files (f-uniquify (dired-get-marked-files)))) ;; apply to single file or marked files
(when (my-system-type-is-windows)
(dired-do-shell-command "C:\\Python36\\Scripts\\filetags.exe --tagtrees --recursive --tagtrees-handle-no-tag no-tags *" nil marked-files)
)
(when (my-system-type-is-gnu)
;; FIXXME: maybe add check for binary: (when (my-eval-if-binary-or-warn "xfce4-terminal")
(dired-do-shell-command (concat "xfce4-terminal --geometry=90x5+330+5 --hide-menubar -x " my-filetags-file " --tagtrees --recursive --tagtrees-handle-no-tag no-tags *") nil marked-files)
)
)
)my-dired-date2name → F1
(defun my-dired-date2name ()
"Run \"time2name\" on current or marked files"
(interactive)
(let* ((marked-files (f-uniquify (dired-get-marked-files)))) ;; apply to single file or marked files
(dired-do-shell-command (concat my-date2name-file " *") nil marked-files)
)
(revert-buffer nil t t) ;; refresh listing of files
)my-dired-time2name → F1
(defun my-dired-time2name ()
"Run \"date2name --withtime\" on current or marked files"
(interactive)
(let* ((marked-files (f-uniquify (dired-get-marked-files)))) ;; apply to single file or marked files
(dired-do-shell-command (concat my-date2name-file " --withtime *") nil marked-files)
)
(revert-buffer nil t t) ;; refresh listing of files
)my-open-in-external-app → C-c C-o
from http://ergoemacs.org/emacs/emacs_dired_open_file_in_ext_apps.html
(defun my-dired-open-in-external-app ()
"Open the current file or dired marked files in external app.
The app is chosen from your OS's preference.
URL `http://ergoemacs.org/emacs/emacs_dired_open_file_in_ext_apps.html'
Version 2016-10-15"
(interactive)
(let* (
($file-list
(if (string-equal major-mode "dired-mode")
(dired-get-marked-files)
(list (buffer-file-name))))
($do-it-p (if (<= (length $file-list) 5)
t
(y-or-n-p "Open more than 5 files? "))))
(when $do-it-p
(cond
((string-equal system-type "windows-nt")
(mapc
(lambda ($fpath)
(w32-shell-execute "open" (replace-regexp-in-string "/" "\\" $fpath t t))) $file-list))
((string-equal system-type "darwin")
(mapc
(lambda ($fpath)
(shell-command
(concat "open " (shell-quote-argument $fpath)))) $file-list))
((string-equal system-type "gnu/linux")
(mapc
(lambda ($fpath) (let ((process-connection-type nil))
(start-process "" nil "xdg-open" $fpath))) $file-list))))))(define-key dired-mode-map (kbd "C-c C-o") 'my-dired-open-in-external-app)Alternative: openwith from this GitHub page mentioned by Using Emacs 71 Openwith.
my-dired-open-in-file-manager → F1
This is xah-show-in-desktop() from
http://ergoemacs.org/emacs/emacs_dired_open_file_in_ext_apps.html and
adapted a bit:
- file-truename() to translate relative paths to absolute
- thunar as default manager on Linux
- [ ] FIXXME: OS switching commands
(defun my-dired-open-in-file-manager ()
"Show current file in desktop.
(Mac Finder, Windows Explorer, Linux file manager)
This command can be called when in a file or in `dired'.
URL `http://ergoemacs.org/emacs/emacs_dired_open_file_in_ext_apps.html'
Version 2018-01-13 adapted by Karl Voit 2018-07-01"
(interactive)
(let (($path (file-truename (if (buffer-file-name) (buffer-file-name) default-directory ))))
(cond
((string-equal system-type "windows-nt")
(w32-shell-execute "explore" (replace-regexp-in-string "/" "\\" $path t t)))
((string-equal system-type "darwin")
(if (eq major-mode 'dired-mode)
(let (($files (dired-get-marked-files )))
(if (eq (length $files) 0)
(shell-command
(concat "open " (shell-quote-argument default-directory)))
(shell-command
(concat "open -R " (shell-quote-argument (car (dired-get-marked-files )))))))
(shell-command
(concat "open -R " $path))))
((string-equal system-type "gnu/linux")
(let (
(process-connection-type nil)
(openFileProgram (if (file-exists-p "/usr/bin/thunar")
"/usr/bin/thunar"
"/usr/bin/xdg-open")))
(start-process "" nil openFileProgram $path))
;; (shell-command "xdg-open .") ;; 2013-02-10 this sometimes froze emacs till the folder is closed. eg with nautilus
))))my-dired-mark-images-and-thumbnail → F1
(defun my-dired-mark-images-and-thumbnail ()
"Mark all image files in dired (png, PNG, jpg, JPG, jpeg, JPEG) and start image-dired+."
(interactive)
(dired-mark-extension '("png" "jpg" "PNG" "JPG" "jpeg" "JPEG" "tif" "tiff" "TIF" "TIFF" "gif" "GIF"))
(image-dired-display-thumbs)
)my-dired-copy-filename-as-absolute-link → F1
I often link files in Org mode documents with their full path such as
[[file:c:/Users/karl.voit/2del/2018-07-04T15.35.42 Outlook - changing recurring events deletes all exceptions -- screenshots.png]]
This would require
- select a file
- copy the absolute path name in dired via
M-0 w - switch to the Org buffer
- type
[[file: - yank the kill ring element containing the absolute path
- finish the link with
]]
Following function avoids human error and reduces this process to:
- select a file
- call the function below via my hydra
- switch to a Org buffer
- yank the working link from the kill ring
(defun my-dired-copy-filename-as-absolute-link (&optional arg)
"Copy current file name with absolute path as [[file:<absolute path>]] link.
If the universal argument is given, the path is omitted in the link description."
(interactive "P")
(dired-copy-filename-as-kill 0) ;; current absolute path to kill ring
(let* ((path (current-kill 0))) ;; get topmost kill ring element
(if (equal arg '(4))
;; universal argument is set:
(kill-new (concat "[[file:" path "][" (helm-basename path) "]]")) ;; write back new/modified kill ring element
;; universal argument is not set:
(kill-new (concat "[[file:" path "]]")) ;; write back new/modified kill ring element
)
)
)my-dired-copy-filename-as-tsfile-link → F1
Same explanation as my-dired-copy-filename-as-absolute-link holds
but with the result being a tsfile: link I use to link to
Memacs-indexed files (see Org Mode customized links):
(defun my-dired-copy-filename-as-tsfile-link ()
"Copy current file name with its basename as [[tsfile:<basename>]] custom org-mode link."
(interactive)
(dired-copy-filename-as-kill) ;; current file name to kill ring
(let* ((filename (current-kill 0))) ;; get topmost kill ring element
(kill-new (concat "[[tsfile:" filename "]]")) ;; write back new/modified kill ring element
)
)my-dired-open-here-in-tmux-shell
Sometimes, I need the current directory showed in my tmux session running in background. This is how it’s done.
- [ ] FIXXME: find a working solution for Windows 10
(defun my-dired-open-here-in-tmux-shell()
(interactive)
(cond
((my-system-type-is-windows)
(message (concat "NOT Opening current dir in Windows/Cygwin tmux (NOT IMPLEMENTED AND TESTED YET): " dired-directory))
;; see id:2018-09-02-open-dir-in-tmux for details on the development and Windows issues
;;(mapc (lambda (fPath) (w32-shell-execute "open" (replace-regexp-in-string "/" "\\" fPath t t)) ) myFileList)
)
((string-equal system-type "darwin")
(message (concat "NOT Opening current dir in macOS tmux (NOT IMPLEMENTED AND TESTED YET): " dired-directory))
)
((my-system-type-is-gnu)
(message (concat "Opening current dir in linux tmux: " dired-directory))
;; OLD: (shell-command (concat "tmux new-window 'cd \"" dired-directory "\"; pwd; zsh -i'"))
(dired-smart-shell-command "xfce4-terminal --execute tmux")
)
)
)orly
| 2020-04-13 | setup for testing |
This package got recommended for a specific issue I faced using interactive Python scripts.
(use-package orly
;;:if (my-system-type-is-gnu)
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/orly/")))
;;:defer 110
:after org
)filetags.el → F1
https://github.com/beutelma/filetags.el provides
filetags-dired-update-tags() which is an Elisp-native
re-implementation of my filetags:
(use-package filetags
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/filetags.el/")))
:config
(setq filetags-enforce-controlled-vocabulary nil) ;; let me invent new tags on the fly (might not be a good idea anyway!)
(setq filetags-load-controlled-vocabulary-from-file t) ;; read CV from .filetags files within same or upper directories
;;ignored;; (setq filetags-controlled-vocabulary '("confidential" "restricted" "public" "internal" "internaluse"
;;ignored;; "license" "demos" "proposals" "flipcharts" "data" "draft" "final" "screenshots" "travel"
;;ignored;; "templates" "contracts" "processes"))
)date2name → F1
https://github.com/beutelma/date2name.el provides
date2name-dired-add-date-to-name() which is an Elisp-native
re-implementation of my date2name:
(use-package date2name
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/date2name.el/")))
:config
(setq date2name-enable-smart-separation-character-chooser t)
;; 2018-07-21: https://github.com/DerBeutlin/date2name.el/issues/1#issuecomment-406787333
(defun file-attribute-modification-time (attributes)
"extracts the modification time from ATTRIBUTES"
(nth 5 attributes))
)- [ ] FIXXME: replace date2name.py with it if it is well tested
- [ ] FIXXME: map to a direct key
- [ ] FIXXME: add to cheatsheet (hydra): ask for day when used with universal prefix
- [ ] FIXXME: do for time2name as well
dired-show-readme
| 2020-04-11 | installed for testing purposes |
| 2020-04-11 | disabled because it did not work on my README.org files |
From this reddit thread I found dired-show-readme which displays README files of various formats (using pandoc conversion) within the directory they are located.
Although I don’t need this particular function, I set it up to test it.
(use-package dired-show-readme
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/dired-show-readme/")))
;:defer 110
;:after dired
:config
(setq dired-show-readme-position "bottom")
;; (setq dired-show-readme-pandoc-executable "/usr/bin/pandoc");; on sting, this is the default
(add-hook 'dired-mode-hook 'dired-show-readme-mode)
)isync + notmuch
| 2021-02-13 | disabled since I can’t use business email with Emacs |
This is my email setup for notmuch I use together with isync/mbsync/
(use-package notmuch
:if (my-system-type-is-gnu)
:config
(load-library "smtpmail")
(setq smtpmail-default-smtp-server my-business-mail-server
smtpmail-local-domain my-business-mail-server)
(setq send-mail-function 'smtpmail-send-it
smtpmail-smtp-server my-business-mail-server
smtpmail-stream-type 'starttls
smtpmail-smtp-service 587
mail-host-address my-business-mail-host-address)
;; Somehow, this variable gets overwritten by something to 'message-send-mail-with-outlook
;; and therefore it's been set in "custom variables" as well.
(setq message-send-mail-function 'message-smtpmail-send-it)
(setq notmuch-message-headers '("Subject" "To" "Cc" "Date" "Reply-To"))
(setq notmuch-mua-cite-function 'message-cite-original-without-signature)
(setq notmuch-saved-searches
'((:name "inbox" :query "tag:inbox" :key "i")
(:name "unread" :query "tag:unread" :key "u")
(:name "flagged" :query "tag:flagged" :key "f")
(:name "sent" :query "tag:sent" :key "t")
(:name "drafts" :query "tag:draft" :key "d")
(:name "all mail" :query "*" :key "a")
(:name "Sent" :query "folder:archive")))
(setq message-default-headers "Reply-to: \nCC: \nBCC: \n")
(setq notmuch-fcc-dirs "archive")
;;(when (my-system-is-rise)
;; (setq notmuch-command "notmuch.cmd")
;;)
(add-hook 'notmuch-message-mode-hook #'footnote-mode)
(add-hook 'notmuch-message-mode-hook #'auto-dictionary-mode)
(add-hook 'notmuch-message-mode-hook #'flyspell-mode)
;; ignore email header for flyspell (and thus dictionary mode):
;; https://www-sop.inria.fr/members/Manuel.Serrano/flyspell/flyspell-1.7q.el
;; as of 2019-12-21: doesn't work as it uses in German emails the English one :-(
(add-hook 'notmuch-message-mode-hook
'(lambda () (setq flyspell-generic-check-word-p
'mail-mode-flyspell-verify)))
(defun my-notmuch-sync-and-update-index-and-buffer ()
"Update the index after sync."
(interactive)
(call-process (concat my-user-emacs-directory "bin/mbsync_notmuch.sh") nil nil t "");; necessary to untag my own emails with -new
(notmuch-poll)
(notmuch-refresh-this-buffer))
; (when (not (my-system-is-rise))
(define-key notmuch-hello-mode-map "g" 'my-notmuch-sync-and-update-index-and-buffer)
; )
)switch to open notmuch biffer or open new one:
(defun my-notmuch (&optional arg)
"Opens the already opened notmuch buffer or opens new one instead."
(interactive "P")
(when (my-system-type-is-gnu)
(my-notmuch-sync-and-update-index-and-buffer)
(if (my-buffer-exists "*notmuch-hello*")
(switch-to-buffer "*notmuch-hello*")
(notmuch)
)
)
)
;; (bind-key "n" 'my-notmuch my-map) → within "Key bindings" heading since binding overwrites a standard Org mode bindingfrom: https://gist.github.com/fedxa/fac592424473f1b70ea489cc64e08911
Provides Org mode links to notmuch emails: copy with C-c l (org-notmuch-store-link) + paste with C-c C-l
(use-package org-notmuch
:if (my-system-type-is-gnu)
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/")))
)Adding a key mapping for “d” to add “deleted” tag and remove “inbox” and “unread”: Source
(define-key notmuch-search-mode-map "d"
(lambda ()
"mark message as deleted"
(interactive)
(notmuch-show-tag (list "+deleted" "-inbox" "-unread"))))
(define-key notmuch-show-mode-map "d"
(lambda ()
"mark message as deleted"
(interactive)
(notmuch-show-tag (list "+deleted" "-inbox" "-unread"))))
(define-key notmuch-tree-mode-map "d"
(lambda ()
"mark message as deleted"
(interactive)
(notmuch-show-tag (list "+deleted" "-inbox" "-unread"))))
Open the current email in Thunderbird:
(define-key notmuch-search-mode-map "T"
(lambda ()
"open in Thunderbird"
(interactive)
;; FIXXME: I can't find the appropriate method to get current message ID in search results:
(my-open-message-id-in-thunderbird (notmuch-show-get-message-ids-for-open-messages t))
))
(define-key notmuch-show-mode-map "T"
(lambda ()
"open in Thunderbird"
(interactive)
(my-open-message-id-in-thunderbird (notmuch-show-get-message-id t))
))As of 2021-01-07, I stop using notmuch (again) because of:
- Thunderbird is good enough for now
- I still need Thunderbird in parallel → I prefer to avoid the switching back and forth effort + additional Maildir data for notmuch
- no appointment inviation handling on receiving
- not being able to create standard appointment invitations
- no HTML or rendering HTML content takes some time
- notmuch does not offer an out-of-the-box possibility to delete emails: https://www.reddit.com/r/emacs/comments/6wqfp3/notmuch_delete_mail/
FIXXME: https://www.reddit.com/r/emacs/comments/kqixcg/notmuch_how_to_get_messageid_open_current_email/
In search you are normally looking at threads, not individual messages—that’s why you have notmuch-search-find-thread-id. But if you write a function that picks an appropriate ID from the result of notmuch-search-find-stable-query that should be the easiest way to go.
As /u/oritron explained, in default search view, you get results not in form of message ids, but in form on thread ids, even if there is a single message in that thread.
However, if you use notmuch-tree (see M-x notmuch-tree), you will get message ids, because threads will be represented as a tree. To access message id for highlighted/selected mail, see notmuch-show-stash-message-id function.
For or certain (Confluence notification) emails, rendering the HTML content takes 20-30 seconds, blocking my Emacs instance which is very upsetting at last to me
My approach is to use lynx for rendering html, because it is really fast. If I need to look it further, I open that message part in browser (go with cursor to text/html box, hit . o and notmuch will ask you for viewer. Enter firefox or chromium… You can’t beat html rendering with the real browser :D
To set lynx as default html renderer use this:
(setq mm-text-html-renderer ‘lynx) or check other options.
Thunderbird
| 2021-02-26 | With an unintended upgrade from Thunderbird 68 to 78, the original thunderlink is broken. |
| 2021-02-28 | Setup of cb_thunderlink as a TB 78.x replacement |
| 2021-05-26 | Moved from Thunderbird to GNOME Evolution, disabling this |
I got this workflow from https://vxlabs.com/2019/04/20/link-thunderbird-emails-from-emacs-orgmode/
Internal notes: id:2020-01-09-link-emails-from-to-Thunderbird-Org
Helper function to open any given message-id in Thunderbird:
;; modify this for your system
(setq thunderbird-program "/usr/bin/thunderbird")
(defun my-open-message-id-in-thunderbird (message-id)
"open an email with a given message-ID in Thunderbird"
(interactive)
(start-process
(concat "thunderlink: " message-id)
nil
thunderbird-program
"-thunderlink"
(concat "thunderlink://messageid=" message-id)
)
);; modify this for your system
(setq thunderlink-program "/home/vk/cb_thunderlink/cb_thunderlink")
(defun my-open-message-id-in-thunderbird (message-id)
"open an email with a given message-ID in Thunderbird"
(interactive)
(start-process
(concat "thunderlink: " message-id)
nil
thunderlink-program
(concat "thunderlink://messageid=" message-id)
)
);; with org-mac-link message:// links are handed over to the macOS system,
;; which has built-in handling. On Windows and Linux, we can use thunderlink!
(when (not (string-equal system-type "darwin"))
(defun org-message-thunderlink-open (slash-message-id)
"Handler for org-link-set-parameters that converts a standard message:// link into
a thunderlink and then invokes thunderbird."
;; remove any / at the start of slash-message-id to create real message-id
(let ((message-id
(replace-regexp-in-string (rx bos (* ":"))
""
slash-message-id)))
(my-open-message-id-in-thunderbird message-id)
))
;; on message://aoeu link, this will call handler with //aoeu
(org-link-set-parameters "messageid" :follow #'org-message-thunderlink-open)
)Note that the link colors are set via my-set-linkcolors.
- test link for testing color: 2020-07-27T15:57:45.000Z First Last: Subject
Installation:
- install “Thunderlink” add-on in Thunderbird
- close Thunderbird
- manually add the snippet below to the
prefs.jsof the Thunderbird profile - activate the Elisp code above within Emacs
- start Thunderbird
user_pref("extensions.thunderlink.custom-tl-string-1-title", "Org mode message-ID");
user_pref("extensions.thunderlink.custom-tl-string-1", "[[messageid:<messageid>][<time> <sender>: <subject>]]");
user_pref("extensions.thunderlink.custom-tl-string-1-selection-delimiter", " / ");
user_pref("extensions.thunderlink.custom-tl-string-1-clipboard-checkbox", true);
user_pref("extensions.thunderlink.custom-tl-string-1-tagcheckbox", false);
user_pref("extensions.thunderlink.custom-tl-string-1-tag", 1);
user_pref("extensions.thunderlink.custom-tl-string-1-appendtofile-checkbox", false);
user_pref("extensions.thunderlink.custom-tl-string-1-appendtofile-path", "");
Possible values for the thunderlink template: https://github.com/mikehardy/thunderlink/blob/master/chrome/thunderlink/content/preferences.xul#L108
<thunderlink> <messageid> <subject> <filteredSubject> <sender> <tbexe> <time>
My feature request for more format options: https://github.com/mikehardy/thunderlink/issues/49
Workflow to use it:
- Click on the message with the secondary mouse button (context menu)
- Select: “Thunderlink …” > “Org mode message-ID”
- alternatively:
C-M-1(1 reflecting the format position in the Thunderlink menu)
- alternatively:
- Switch to Emacs and yank from the clipboard
You should then get something similar to:
[[messageid:1578475923.390512.037689999@example.com][[1/9/2020 - 11:30:41 First Last <name@example.com>: Things I wanted to say to you]]
When C-c C-o onto it, Thunderbird should pop up showing the email
with the corresponding message ID.
GNOME Evolution
| 2021-05-26 | migrated from Thunderbird to GNOME Evolution, re-creating the workflow here |
Helper function to open any given message-id in Evolution:
;; modify this for your system
(defun my-open-message-id-in-evolution (message-id)
"open an email with a given message-ID in Evolution"
(interactive)
(start-process
(concat "mid: " message-id)
nil
"/usr/bin/flatpak"
"run" "org.gnome.Evolution" (concat "mid:<" message-id ">")
)
)
(org-link-set-parameters "messageid" :follow #'my-open-message-id-in-evolution)
(defun my-convert-mail-header-to-org-link ()
"Assumes an email header in the killring, parses it and returns an org mode link for it."
(interactive)
(with-temp-buffer
(save-match-data
(yank) ;; yank from clipboard
(goto-char (point-min)) ;; start from top
(re-search-forward "^Message-Id:.+<\\(.+\\)>[ ]*$" nil nil 1)
(setq messageid (match-string 1))
(goto-char (point-min))
(re-search-forward "^From:[ ]+\\(.+?\\)[ ]*$" nil nil 1)
(setq from (string-replace "\"" "" (match-string 1)))
(goto-char (point-min))
(re-search-forward "^Subject:[ ]+\\(.+?\\)[ ]*$" nil nil 1)
(setq subject (match-string 1))
(goto-char (point-min))
(re-search-forward "^Date:[ ]+\\(.+?\\)[ ]*$" nil nil 1)
(setq rawdate (match-string 1))
(setq date
(let ((time (date-to-time rawdate)))
(set-time-zone-rule t) ;; Use Universal time.
(prog1 (format-time-string "%Y-%m-%d %H:%M" time)
(set-time-zone-rule nil))))
;;(message (concat "MID: " messageid " F:" from " S:" subject "RD:" rawdate " D:" date))
))
(insert (concat "[[messageid:" messageid "][" date " " from ": " subject "]]"))
)
(bind-key "e" #'my-convert-mail-header-to-org-link my-map)
Note that the link colors are set via my-set-linkcolors.
- test link for testing color: 2020-07-27T15:57:45.000Z First Last: Subject
Installation:
- install GNOME Evolution in version 3.39+ because Evolution added the command line switch with this version.
flatpak install --user --from https://dl.flathub.org/repo/appstream/org.gnome.Evolution.flatpakref
- if you need the flatpak version (because your distro has only older versions), you should be finished
- If my feature request is implemented, this will get much easier!
- if you did not install Evolution via flatpak, adapt the code above
- Evolution: Account preferences → Receiving Options → [X] Synchronize remote mail locally in all folders
Workflow to use it:
- FIXXME: find a workflow to generate Message-ID links in Evolution
You should then get something similar to:
[[messageid:1578475923.390512.037689999@example.com][[1/9/2020 - 11:30:41 First Last <name@example.com>: Things I wanted to say to you]]
When C-c C-o onto it, Evolution should pop up showing the email
with the corresponding message ID.
LaTeX
LaTeX is a powerful text setting system I use for creating letters, books, presentations, and so forth.
AucTeX is an awesome handy mode for working with TeX code.
BEGIN of LaTeX settings (only if “pdflatex” is found on the system):
(when (my-eval-if-binary-or-warn "pdflatex")General LaTeX settings:
(autoload 'tex-site "tex-site.el") ;; acticate AucTeX and set general preferences
(setq TeX-PDF-mode t) ;; compile to PDF using pdflatex (instead to DVI)
(add-hook 'LaTeX-mode-hook 'turn-on-auto-fill) ;; word-wrap in TeX files
(setq TeX-auto-save nil);; avoid auto directories; read https://emacs.stackexchange.com/questions/32760/how-to-get-rid-of-the-auto-folder-with-el-files
(setq TeX-parse-self t)
;(setq-default TeX-master nil);; 2015-03-22 deactivated because it doesn't seem to have any influence: id:2013-12-31-org-master-file
(make-variable-buffer-local 'TeX-master) ;; I think this is need because the variable is not buffer local until Auctex is activeSynctex is a nice add-on that synchronizes the editing tool (Emacs/AucTeX) with a PDF viewing tool (e.g., Okular): http://www.bleedingmind.com/index.php/2010/06/17/synctex-on-linux-and-mac-os-x-with-emacs/
(when (my-eval-if-binary-or-warn "synctex")
(add-hook 'LaTeX-mode-hook 'TeX-source-correlate-mode)
(setq TeX-source-correlate-method 'synctex)
)Define system-specific PDF viewers and further Synctex settings:
(defun okular-make-url () (concat
"file://"
(expand-file-name (funcall file (TeX-output-extension) t)
(file-name-directory (TeX-master-file)))
"#src:"
(TeX-current-line)
(TeX-current-file-name-master-relative))
"./"
(TeX-current-file-name-master-relative)
)
(defun skim-make-url () (
concat
(TeX-current-line)
" "
(expand-file-name (funcall file (TeX-output-extension) t)
(file-name-directory (TeX-master-file)))
" "
(buffer-file-name))
)
(setq TeX-view-program-list '(
("Okular" "okular --unique %u")
("Skim" "/Applications/Skim.app/Contents/SharedSupport/displayline %q")
)
)
(when (my-system-type-is-gnu)
(setq TeX-view-program-selection '((output-pdf "Okular") (output-dvi "Okular")))
(eval-after-load "tex"
'(add-to-list 'TeX-expand-list '("%u" okular-make-url))
)
)
(when (my-system-type-is-darwin)
(setq TeX-view-program-selection '((output-pdf "Skim")))
(eval-after-load "tex"
'(add-to-list 'TeX-expand-list '("%q" skim-make-url))
)
)(add-hook ‘LaTeX-mode-hook
(lambda ()
(add-to-list ‘TeX-expand-list
‘(“%u” okular-make-url))))I tried it once but do not use it any more.
(when (or (my-system-type-is-gnu) (my-system-is-powerplantlinux))
(my-load-local-el "contrib/cdlatex.el")
)RefTeX is the package for LaTeX that does manage references.
http://www.tug.org/pipermail/macostex-archives/2005-November/018997.html
- reftex
- TeX-fold-mode
(add-hook 'LaTeX-mode-hook 'turn-on-reftex) ; with AUCTeX LaTeX mode
(add-hook 'LaTeX-mode-hook '(lambda () (TeX-fold-mode 1)))BibLaTeX provides bibliographic facilities. Biber is a moder implementation of it. I prefer it for generating references and its indexes.
http://www.mail-archive.com/auctex@gnu.org/msg04137.html
(eval-after-load "tex"
'(add-to-list 'TeX-command-list
'("Biber" "biber %s" TeX-run-Biber nil t :help "Run Biber") t))
(defun TeX-run-Biber (name command file)
"Create a process for NAME using COMMAND to format FILE with Biber."
(let ((process (TeX-run-command name command file)))
(setq TeX-sentinel-function 'TeX-Biber-sentinel)
(if TeX-process-asynchronous
process
(TeX-synchronous-sentinel name file process))))
(defun TeX-Biber-sentinel (process name)
"Cleanup TeX output buffer after running Biber."
(goto-char (point-max))
(cond
;; Check whether Biber reports any warnings or errors.
((re-search-backward (concat
"^(There \\(?:was\\|were\\) \\([0-9]+\\) "
"\\(warnings?\\|error messages?\\))") nil t)
;; Tell the user their number so that she sees whether the
;; situation is getting better or worse.
(message (concat "Biber finished with %s %s. "
"Type `%s' to display output.")
(match-string 1) (match-string 2)
(substitute-command-keys
"\\\\[TeX-recenter-output-buffer]")))
(t
(message (concat "Biber finished successfully. "
"Run LaTeX again to get citations right."))))
(setq TeX-command-next TeX-command-default))- http://www.gnu.org/software/auctex/manual/reftex.html#SEC48
- Specify my bibtex folder
- does not work :-(
- tested with tagstore.org
(setq reftex-bibpath-environment-variables
'("~/archive/library/"))- 2015-03-22 - see also id:2013-12-31-org-master-file
- http://www.emacswiki.org/emacs/AUCTeX
- disabled 2015-03-22 because it did not help
(defun guess-TeX-master (filename)
"Guess the master file for FILENAME from currently open files according to their extension."
(let ((candidate nil)
(filename (file-name-nondirectory filename)))
(save-excursion
(dolist (buffer (buffer-list))
(with-current-buffer buffer
(let ((name (buffer-name))
(file buffer-file-name))
;(if (and file (string-match "\\.\(org\|tex\)$" file))
(if (and file (string-match "\\.org$" file))
(progn
(goto-char (point-min))
(if (re-search-forward (concat "\\\\input{" filename "}") nil t)
(setq candidate file))
(if (re-search-forward (concat "\\\\include{" (file-name-sans-extension filename) "}") nil t)
(setq candidate file))))))))
(if candidate
(message "TeX master document: %s" (file-name-nondirectory candidate)))
candidate))
;; ONLY for special file modes with a recognized extension!
;; Causes Lisp error (that's a afact) when used with buffers like *scratch* (that's my guess)
;;(setq TeX-master (guess-TeX-master (buffer-file-name)))END of LaTeX settings
)GnuPlot
«Gnuplot is a portable command-line driven graphing utility for Linux, OS/2, MS Windows, OSX, VMS, and many other platforms.»
Also very handy when visualizing table data within Org-mode! (see Org-mode/babel configuration)
Example: place the cursor within the table and evaluate
org-plot/gnuplot or use the keyboard shortcut C-c " g
| When | How many |
|---|---|
| [2016-11-17 Thu] | 3 |
| [2016-11-23 Wed] | 4 |
| [2016-12-10 Sat] | 1 |
;; gnuplot
(when (my-eval-if-binary-or-warn "gnuplot")
(use-package gnuplot
:ensure t
:defer 110
:if (my-system-type-is-gnu)
)
)Org mode
Org-mode is my digital life. I do almost anything within Org-mode: http://karl-voit.at/tags/emacs/
I am doing Personal Information Management (PIM) for decades, tried many different methods and tools. With Org-mode my quest for the best PIM-tool out there finally came to an end. It’s an endless pile of Lego-bricks from where I can draw some bricks and assemble it to meet my requirements. Therefore, Org-mode is something different for everybody. It depends, what Lego bricks you took and how you combined them. Org-mode scales well from a simple outliner or todo-list up to something very, very big.
Almost half of my Emacs configuration deals with Org-mode. Fasten your seat belt and dive into my rabbit hole of Org …
Profiling Org-mode config loading time:
(defvar my-org-config-start-time (current-time) "Time when my org-mode config was started")
(message "★→ Org-mode")
(my-log-hostspecific "org-version" org-version)Load Org and misc contrib packages
Since a couple of major releases GNU/Emacs comes with an Org-mode version built in. However, I do prefer the “maint” branch of the Org-mode Git repository instead. See also Installation - The Org Manual.
Note that the Org-mode paths to my manually installed Org-mode are set
within init.el already.
assign file extensions to Org-mode:
(add-to-list 'auto-mode-alist '("\\.\\(org\\|org_archive\\|txt\\)$" . org-mode))2014-10-29 test
(setq org-babel-safe-header-args nil)Loading contributed packages:
(use-package org-checklist
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/org-contrib/lisp/")))
)
(use-package org-expiry
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/org-contrib/lisp/")))
)
;; 2021-11-23: to avoid "org-timestamp-change: Symbol’s function definition is void: org-clock-update-time-maybe"
(use-package org-clock
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/org-contrib/lisp/")))
)
(use-package org-attach
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/org-contrib/lisp/")))
)
(use-package org-element
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/org-contrib/lisp/")))
)
(use-package org-mobile
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/org-contrib/lisp/")))
)
;;disabled 2019-06-26;; (use-package ob-restclient
;;disabled 2019-06-26;; :load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/ob-restclient.el/")))
;;disabled 2019-06-26;; )
(when (my-system-is-rise)
(my-load-local-el "contrib/org-contrib/lisp/ox-confluence.el")
;; https://www.reddit.com/r/emacs/comments/fk5z1b/how_to_remove_foo_barfoo_bar_links_via/fkrbc0e/
;; Do not handle radio links (and generate broken page links):
(defun export-radio-links-as-plain-text (link desc info)
(when (string= "radio" (org-element-property :type link))
desc))
(advice-add #'org-confluence-link :before-until
#'export-radio-links-as-plain-text)
)
;;disabled;; (my-load-local-el "contrib/org-contrib/lisp/ox-freemind.el")
(autoload 'org-checklist "org-checklist.el")
;; http://repo.or.cz/w/org-mode.git?a=blob_plain;f=contrib/lisp/org-expiry.el;hb=HEAD
;; Expiry dates handling
(autoload 'org-expiry "org-expiry.el")
;; managing bookmarks with Org-mode
;; http://orgmode.org/worg/org-contrib/org-protocol.html
(autoload 'org-protocol "org-protocol")Enable misc org modules:
(setq org-modules (quote
(org-crypt
org-id
org-info
org-habit
org-inlinetask
org-protocol
)
)
)2019-12-09: “Problems while trying to load feature” and therefore removed from the list above:
- org-mew
- org-vm
- org-wl
2019-12-09: I’ve got no idea why they are in this list and therefore removed:
- org-bbdb
- org-gnus
- org-bibtex
- org-irc
- org-mhe
- org-rmail
- org-w3m
org-favtable:
I was not able to find the advantage of favtables in comparison to
search or id-links:
(require 'org-favtable)
(setq org-favtable-id "my-favtable")
(global-set-key (kbd "C-+") 'org-favtable)Dependencies between todos
| 2010? | initial setup of org-depend |
| 2019-11-13 | temporary testing phase of org-edna instead of org-depend |
| 2020-01 | issue with org-depend and batch-generation of ICS export of agenda |
| 2020-05-13 | re-enabling after org upgrade: test again |
| 2020-05-18 | disabled again: Variable binding depth exceeds max-specpdl-size persists |
| 2020-07-09 | enabled org-edna for testing |
One of my initial reasons to try Org mode was the ability to define dependencies between tasks.
This article also shows some handy functions related to this topic.
Please do read this page with a very interesting discussion by u/TeMPOraL\_PL on org-edna and task dependency with visualizations and a BLOCKER status.
org-depend
The default method is using org-depend. It has a very simple syntax
based on the :TRIGGER: and :BLOCKER: properties.
(use-package org-depend
; :if (not noninteractive) ;; I do have issues with org-depend
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/org-contrib/lisp/")))
)org-edna
| 2019-11-13 | I’m testing a fork: https://github.com/akirak/org-edna via reddit |
| 2020-09-10 | This fork is discontinued → switched to original org-edna v1.1.2 with issues |
| 2020-10-01 | I migrated all my Org files from org-depend to org-edna using this |
Enable only when org-depend is disabled because both use same
properties and report format errors when other format is detected.
(use-package org-edna
:config
(require 'org-edna)
(org-edna-load)
)org-edna has a syntax that is more complex when compared to
org-depend. However, org-edna also features much more
possibilities. My main driver to switch from org=depend to
org-edna are relative SCHEDULED dates. This way, a follow-up task
could be scheduled for, e.g., three days after the previous task was
finished, whenever that happens.
The more complex syntax does come with no manual effort since I’d like
to define dependencies via Elisp functions instead of manually typing
:TRIGGER: properties which I’ve done so far. For that purpose,
org-linker-edna is a very nice help.
Internal project link: id:2019-11-14-Org-Project-Management-Workflow
General Org-mode settings
http://www.reddit.com/r/emacs/comments/2m4b7j/help_setting_orgmode_as_the_default_major_mode/ - «This will make it that any file without an auto-mode alist entry gets associated with org-mode by default.»
(add-to-list 'auto-mode-alist '("'" . org-mode) t)Might cause performance issues; http://orgmode.org/manual/Clean-view.html
(setq org-startup-indented t)For a more fine-grained control on expanded headings when visiting a Org file, look at org-auto-expand.
(setq org-enforce-todo-dependencies t)
(setq org-insert-heading-respect-content nil)
(setq org-reverse-note-order nil)
(setq org-show-following-heading t)
(setq org-show-hierarchy-above t)
(setq org-show-siblings nil)
(setq org-deadline-warning-days 7)
(setq org-blank-before-new-entry (quote ((heading . t)
(plain-list-item . nil))))- http://orgmode.org/org.html - show blocked tasks in agenda in gray color
- OR: hide blocked tasks completely:
- 2020-07-07: I switched to show any scheduled task, independent of blocking. Because:
- When I forget to schedule an unresolved sub-task, the parent task which is scheduled gets hidden. → Don’t want that.
- Parent tasks that do contain tasks beneath should be marked as projects and should be finished with its last task that closes the project.
- I plan to switch from
org-dependtoorg-ednaand a set of yet to be written functions to make planning easier:- Define dependencies via helm (or simple: add next task below this one)
- Use of relative SCHEDULED date-stamps: e.g., when X is DONE, mark X+1 as TODO and add a relative SCHEDULED for +1d.
;;disabled;(setq org-agenda-dim-blocked-tasks t)
;;disabled 2020-07-07;; (setq org-agenda-dim-blocked-tasks 'invisible)
(setq org-agenda-dim-blocked-tasks nil);; show blocked tasksLogging into drawers: (also do read this blog article)
(setq org-log-done (quote time))
(setq org-log-into-drawer t)
;; record when the deadline or scheduled date of a tasks is modified
;;(setq org-log-redeadline (quote note));; performance risk due to long LOG drawers!
(setq org-log-redeadline nil)
;;(setq org-log-reschedule (quote time));; performance risk due to long LOG drawers!
(setq org-log-reschedule nil)(setq org-return-follows-link t)
(setq org-remove-highlights-with-change nil)
(setq org-read-date-prefer-future nil)
(setq org-list-demote-modify-bullet (quote (("+" . "-")
("*" . "-")
("1." . "-")
("1)" . "-"))))
(setq split-width-threshold 9999);; Minimum width for splitting windows sensibly.
(setq require-final-newline nil)
(setq org-adapt-indentation nil);; do not indent drawers/body according to heading levelPerformance implications! See reddit comment for details:
(setq global-auto-revert-mode t)Default state for repeating/recurring events
(setq org-todo-repeat-to-state "NEXT")Smart navigation: begin/end of line is different for headings, list items, …
(setq org-special-ctrl-a/e t)
(setq org-special-ctrl-k t)Smart yanking: https://www.gnu.org/software/emacs/manual/html_node/org/Structure-editing.html
(setq org-yank-adjusted-subtrees t)- until 2016-11-10, the defaults were OK to me
- with update to Org 9, jumping from agenda to hidden heading reveales only heading but not ancestors as before
(setq org-show-context-detail
'((agenda . lineage) ;; instead of "local"
(bookmark-jump . lineage)
(isearch . lineage)
(default . ancestors))
)Set the timestamps of expiry.el to inactive ones:
http://comments.gmane.org/gmane.emacs.orgmode/20934
(setq org-expiry-inactive-timestamps t)Prevent accidental deleting of hole subtrees or similar
- http://orgmode.org/Changes.html -> New option org-catch-invisible-edits
(setq org-catch-invisible-edits "smart")Use IDO for target completion:
(setq org-completion-use-ido t)Disable property inheritance (in order to seed up)
(setq org-use-property-inheritance nil)https://www.gnu.org/software/emacs/manual/html_node/org/Matching-tags-and-properties.html
(setq org-tags-match-list-sublevels nil)2018-04-08: I now keep org-tags-match-list-sublevels to its default
value (t) because I could not generate sparse trees with all
unscheduled open tasks and setting this to nil (can’t remember why I
did it in the first place) was the reason.
This variable is semi-obsolete and probably should always be true. It is better to limit inheritance to certain tags using the variables ‘org-use-tag-inheritance’ and ‘org-tags-exclude-from-inheritance’.
Prevent auto-filling for source code:
;(setq org-src-prevent-auto-filling t)From: Release Notes v8.1: http://orgmode.org/worg/agenda-optimization.html
(setq org-agenda-ignore-drawer-properties '(effort appt stats));; agenda performanceAutomatically write CREATED properties in the PROPERTIES drawer:
(org-expiry-insinuate)
;; not checked yet: (setq org-expiry-handler-function 'org-expiry-archive-subtree)Checking org-mode syntax:
(require 'org-lint)Open corresponding .org_archive file with ff-find-other-file
https://twitter.com/_wilfredh/status/708046038200950787 « M-x
describe-function shows the docstring, which mentions
ff-other-file-alist.»
;;
(defvar my-cpp-other-file-alist
'(("\\.org\\'" (".org_archive"))
;;("\\.ipp\\'" (".hpp" ".cpp"))
;;("\\.hpp\\'" (".ipp" ".cpp"))
;;("\\.cxx\\'" (".hxx" ".ixx"))
;;("\\.ixx\\'" (".cxx" ".hxx"))
;;("\\.hxx\\'" (".ixx" ".cxx"))
;;("\\.c\\'" (".h"))
;;("\\.h\\'" (".c"))
))
(setq-default ff-other-file-alist 'my-cpp-other-file-alist)Yasnippet settings: http://yasnippet.googlecode.com/svn/trunk/doc/index.html
;;disabled;(my-load-local-el "contrib/yasnippet/yasnippet.el")
(add-hook 'org-mode-hook 'yas-minor-mode)
(setq yas-indent-line 'fixed) ;; fixes Org-mode issue with yasnippets: https://github.com/capitaomorte/yasnippet/issues/362org-bullets on Windows: workaround that significantly improves speed and also from org-superstar-mode readme:
(when (my-system-type-is-windows)
(setq inhibit-compacting-font-caches t)
)Inheritance of checkbox toggling: should parent checkboxes be checked when all children are checked as well?
- Non-nil means checkbox statistics counts only the state of direct children.
- When nil, all boxes below the cookie are counted.
(setq org-checkbox-hierarchical-statistics t)From this blog entry I got the hint that setting the variable
org-cycle-separator-lines to zero will omit empty lines between
headings in the collapsed view, which I prefer:
(setq org-cycle-separator-lines 0)org-inlinetask is a method to define tasks via C-c C-x t anywhere in
the hierarchy by using at least org-inlinetask-min-level number of
asterisks. Since some of my normal heading levels do reach the
standard value for it of 15, I had to extend it to 20 for now:
(setq org-inlinetask-min-level 20)(setq org-id-link-to-org-use-id 'use-existing)Using that setting, _ and ^ are interpreted literally. Except for
cases like _{3} which makes 3 a subscript:
(setq org-use-sub-superscripts "{}")Reverting a changed behavior in indentation (explanation and fix):
(add-hook 'org-mode-hook (lambda () (electric-indent-local-mode -1)))scimax/org-return
Smart return does add new list item, … if appropriate
- http://irreal.org/blog/?p=6131
- http://kitchingroup.cheme.cmu.edu/blog/2017/04/09/A-better-return-in-org-mode/
(require 'org-inlinetask)
(defun scimax/org-return (&optional ignore)
"Add new list item, heading or table row with RET.
A double return on an empty element deletes it.
Use a prefix arg to get regular RET. "
(interactive "P")
(if ignore
(org-return)
(cond
((eq 'line-break (car (org-element-context)))
(org-return-indent))
;; Open links like usual
((eq 'link (car (org-element-context)))
(org-open-at-point-global))
;; It doesn't make sense to add headings in inline tasks. Thanks Anders
;; Johansson!
((org-inlinetask-in-task-p)
(org-return))
;; add checkboxes
((org-at-item-checkbox-p)
(org-insert-todo-heading nil))
;; lists end with two blank lines, so we need to make sure we are also not
;; at the beginning of a line to avoid a loop where a new entry gets
;; created with only one blank line.
((and (org-in-item-p) (not (bolp)))
(if (org-element-property :contents-begin (org-element-context))
(org-insert-heading)
(beginning-of-line)
(setf (buffer-substring
(line-beginning-position) (line-end-position)) "")
(org-return)))
;;disabled;; ((org-at-heading-p)
;;disabled;; (if (not (string= "" (org-element-property :title (org-element-context))))
;;disabled;; (progn (org-end-of-meta-data)
;;disabled;; (org-insert-heading))
;;disabled;; (beginning-of-line)
;;disabled;; (setf (buffer-substring
;;disabled;; (line-beginning-position) (line-end-position)) "")))
((org-at-table-p)
(if (-any?
(lambda (x) (not (string= "" x)))
(nth
(- (org-table-current-dline) 1)
(org-table-to-lisp)))
(org-return)
;; empty row
(beginning-of-line)
(setf (buffer-substring
(line-beginning-position) (line-end-position)) "")
(org-return)))
(t
(org-return)))))
(define-key org-mode-map (kbd "RET")
'scimax/org-return)org-file-apps -> open files in external apps
Here is a list of file extensions that should be openend outside of Emacs:
;;(add-to-list 'org-file-apps '("\\.odp" . system))
;;(add-to-list 'org-file-apps '("\\.odp" . mailcap))
(add-to-list 'org-file-apps '("\\.odp" . "open %s"))
;;(add-to-list 'org-file-apps '("\\.odp" . "/usr/bin/xdg-open %s"))remove spaces from org-link-escape-chars
- Why
- I got issues on Windows when linking to a file which results in
something like this which does not work when visited using
C-c C-o:file:~/my%20dir/my%20file.txt - Something like this works tough:
[[file:~/my dir/my file.txt]]
- I got issues on Windows when linking to a file which results in
something like this which does not work when visited using
This might be dangerous since I neglect any changes of this (internal) variable. So far, it gets the job done. Let’s hope for the best that I don’t get into any nasty side-effects and don’t remember or recognize the reason caused by overwriting this setting here.
(setq org-link-escape-chars
;;%20 %5B %5D %25
'(?\[ ?\] ?%)
)Styling
Omit the headline-asterisks except the last one:
(setq org-hide-leading-stars t)syntax highlighting in source code:
from Eric Schulte <eric.schulte@gmx.com>
Newsgroups: gmane.emacs.orgmode
Subject: Re: org mode in press
Date: Sat, 28 Jan 2012 10:06:08 -0700
Message-ID: <87ipjv92pr.fsf@gmx.com>
- 2014-04-04: set to nil in order to avoid performance issues!
- 2015-12-26: set to t to test again these days
- seems to be OK now
(setq org-src-fontify-natively t)automatically change status of a heading to DONE when all children are done:
- http://orgmode.org/org.html#Breaking-down-tasks
- deactivated because WAITING got changed to TODO
(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)Statistic cookies count ALL subtasks not only direkt ones
(setq org-hierarchical-todo-statistics t)Stop the mouse cursor from highlighting lines in the agenda: http://orgmode.org/worg/org-faq.html Somehow this stopped working with org-super-agenda I guess.
(add-hook 'org-finalize-agenda-hook
(lambda () (remove-text-properties
(point-min) (point-max) '(mouse-face t))))Changing the default ellipsis to something that can’t be mixed up with normal characters: http://endlessparentheses.com/changing-the-org-mode-ellipsis.html
Note: on some computers, this results in higher line height as described on http://emacs.stackexchange.com/questions/251/line-height-with-unicode-characters See: id:2016-08-19-unicode-enlarges-line-height
(setq org-ellipsis "•")From: Bastien <bzg@altern.org> Newsgroups: gmane.emacs.orgmode Subject: Re: scale inline images in orgmode Date: Thu, 30 Aug 2012 15:52:59 +0200 Message-ID: <87a9xcsczo.fsf@altern.org>
:
You can now (from git master) use `org-image-actual-width'.
(setq org-image-actual-width 300)
=> always resize inline images to 300 pixels
(setq org-image-actual-width '(400))
=> if there is a #+ATTR.*: width="200", resize to 200,
otherwise resize to 400
(setq org-image-actual-width nil)
=> if there is a #+ATTR.*: width="200", resize to 200,
otherwise don't resize
(setq org-image-actual-width t)
=> Never resize and use original width (the default)
Set the width of inline images:
(setq org-image-actual-width '(600))Nice looking bullets for headings:
(use-package org-bullets
:ensure t
:config ;; executed after loading package
(add-hook 'org-mode-hook (lambda () (org-bullets-mode 1)))
)An alternative for org-bullets (above) would be:
https://github.com/integral-dw/org-superstar-mode which I did not test
so far. It also affects the simple lists which I do like as they are.
Note to myself: if you include org-superstar-mode you also have to
adapt the beginner mode setting.
org-fancy-priorities replaces, e.g., “[A]” (for “highest priority”) with a nice graphic.
2018-07-23: disabled since it does not seem to work on my side. It somehow messes up my TODO keywords and my Windows font does not feature the icon characters.
(use-package org-fancy-priorities
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/org-fancy-priorities/")))
)Nice symbold instead of keywords. I got this from this config but his UTF-8 symbols were not in my current (Windows) font.
(add-hook 'org-mode-hook
(lambda ()
(push '("TODO" . ?█) prettify-symbols-alist)
(push '("DONE" . ?✓) prettify-symbols-alist)
(push '("WAITING" . ?…) prettify-symbols-alist)
(push '("CANCELLED" . ?×) prettify-symbols-alist)
(push '("SOMEDAY" . ??) prettify-symbols-alist)))- enhanced highlighting of babel blocks: http://orgmode.org/worg/org-contrib/babel/examples/fontify-src-code-blocks.html
- issues when trying to apply face instantly: https://www.reddit.com/r/emacs/comments/3ksen6/noob_question_how_to_make_changes_after/cv0cmko
- M-x describe-face -> show definition
- C-u C-x = -> show all font information
; (face-spec-set 'org-block-begin-line
; '((t (:underline "#FFFFFF" :foreground "#404040" :background "#b3b3b3")))
; "Face used for the line delimiting the begin of source blocks.")
;(defface org-block-begin-line
; '((t (:underline "#FFFFFF" :foreground "#cccccc" :background "#4d4d4d")))
; "Face used for the line delimiting the begin of source blocks.")
(defface org-block
;; defface org-block-background was removed from org:
;; http://emacs.stackexchange.com/questions/14824/org-block-background-font-not-having-effect
;; read also: https://www.reddit.com/r/emacs/comments/415imd/prettier_orgmode_source_code_blocks/
'((t (:background "#1a1a1a")))
"Face used for the source block background.")
;(defface org-block-end-line
; '((t (:overline "#FFFFFF" :foreground "#cccccc" :background "#4d4d4d")))
; "Face used for the line delimiting the end of source blocks.")
;;test: (set-face-background 'org-block-background "#1a1a1a")
General key bindings
Standard key bindings:
(global-set-key "\C-cl" 'org-store-link)
(global-set-key "\C-ca" 'org-agenda)
;;obsolete: (global-set-key "\C-cb" 'org-iswitchb)unset C-c , (org-priority) because I get confused when I mistype C-c C-,
;;(global-unset-key (kbd "C-c ,"))
(global-set-key (kbd "C-c ,") 'my-map)Remembering positions:
(global-set-key (kbd "C-c %") 'org-mark-ring-push)
(global-set-key (kbd "C-c <left>") 'org-mark-ring-goto)
(global-set-key (kbd "C-c <down>") 'org-mark-ring-push)MISC Apple bindings
(setq mac-command-modifier 'apple)
(global-set-key [(<apple> <up>)] 'org-move-subtree-up)
(global-set-key "\S-<down>" 'org-move-subtree-down)
(global-set-key "\S-<left>" 'org-do-promote)
(global-set-key "\S-<right>" 'org-do-demote)Org-mode keys for Mac
- I wanted to map Alt-left|right|… but Alt has to be used by the system in order to type umlauts :-(
(setq mac-command-modifier 'apple)
(global-set-key [(<apple> <up>)] 'org-move-subtree-up)
(global-set-key "\S-<down>" 'org-move-subtree-down)
(global-set-key "\S-<left>" 'org-do-promote)
(global-set-key "\S-<right>" 'org-do-demote)fix broken mapping (because of prelude and so on).
- disabled 2014-01-19
(defun my-org-mode-hook ()
(define-key prelude-mode-map (kbd "C-c +") nil)
(define-key prelude-mode-map (kbd "C-c -") nil)
)
(add-hook 'org-mode-hook 'my-org-mode-hook)(org-defkey org-mode-map (kbd "C-c C-,") nil);; clear binding
(org-defkey org-mode-map (kbd "C-c C-k") nil);; clear binding
(org-defkey org-mode-map (kbd "C-c k") nil);; clear bindingMy general Org helper functions
my-org-startup-visibility()
Sometimes, I get a mess with all kinds of sub-hierarchies openend in my most important Org-mode buffers. When I want to get the startup visibility, I invoke this function to get a fresh environment again.
Take a look at my-reset-org() as well.
(defun my-org-startup-visibility (&optional ignore)
"Sets the startup visibility in my most important buffers"
(interactive "P")
(save-window-excursion ;; Why save-excursion is not sufficient here: https://emacs.stackexchange.com/questions/24133/save-excursion-doesnt-restore-the-currently-visible-buffer
(when (my-buffer-exists "misc.org")
(switch-to-buffer "misc.org")
(org-set-startup-visibility)
)
(when (my-buffer-exists "projects.org")
(switch-to-buffer "projects.org")
(org-set-startup-visibility)
)
(when (my-buffer-exists "issues.org")
(switch-to-buffer "issues.org")
(org-set-startup-visibility)
)
(when (my-buffer-exists "contacts.org")
(switch-to-buffer "contacts.org")
(org-set-startup-visibility)
)
(when (my-buffer-exists "notes.org")
(switch-to-buffer "notes.org")
(org-set-startup-visibility)
)
(when (my-buffer-exists "hardware.org")
(switch-to-buffer "hardware.org")
(org-set-startup-visibility)
)
(when (my-buffer-exists "public_voit.org")
(switch-to-buffer "public_voit.org")
(org-set-startup-visibility)
)
(when (my-buffer-exists "rise.org")
(switch-to-buffer "rise.org")
(org-set-startup-visibility)
)
;; (when (my-system-type-is-windows)
;; (when (my-buffer-exists "detego.org")
;; (switch-to-buffer "detego.org")
;; (org-set-startup-visibility)
;; )
;; (when (my-buffer-exists "ciso.org")
;; (switch-to-buffer "ciso.org")
;; (org-set-startup-visibility)
;; )
;; )
)
)For a more fine-grained control on expanded headings when visiting a Org file, look at org-auto-expand.
my-reset-org() - reset some Org-mode stuff
This function summarizes some other functions that clear up the current Org-mode, re-building some caches and so fort.
Take a look at my-org-startup-visibility() as well.
(defun my-reset-org ()
"Clears all kinds of Org-mode caches and re-builds them if possible"
(interactive)
(measure-time
(org-element-cache-reset)
(org-refile-cache-clear)
(org-refile-get-targets)
(setq org-agenda-tags-column (- (- (window-total-width) 3))) ;; total width minus 3
(when (my-buffer-exists "*Org Agenda*")
(kill-buffer "*Org Agenda*")
(org-agenda-list)
)
)
)when being idle for 15 minutes, run my-reset-org()
- See id:2016-06-05-reset-things-after-15-min-idle
current-idle-time example: (0 420 1000 0)
Disabled because it doesn’t work:
(setq my-reset-org-previous-idle-time-invocation (current-time))
(run-with-idle-timer (* 60 15) t (lambda ()
(if (< 2 (float-time (time-since my-reset-org-previous-idle-time-invocation)))
(sit-for 2)
(when (< (nth 1 (current-idle-time)) (* 60 16));; run only once per idle period
(message "Idle for 15 minutes, invoking my-reset-org in 10 seconds ...")
(sit-for 10);; give user 10s to press a button to prevent this
(when (< (nth 1 (current-idle-time)) (* 60 16));; run only once per idle period
(my-reset-org)
(setq my-reset-org-previous-idle-time-invocation (current-time))
(message (concat "my-reset-org finished at " (current-time-string)))
)
)
)
))
;;(defun mytest ()
;; (when (< (nth 1 (or (current-idle-time) (list 0 0 0 0)))) (* 60 16));; run only once per idle period
;; (message "yes")
;; )
;; )
;;
;;(sit-for 3)
;;(message (or (current-idle-time) (number-to-string 0)))Functions for Working Hour Calculation
I used this code to derive working hours until the company switched to a stupid new tool everybody hates. Yes, even worse than SAP.
This is just for the record because it contains much Elisp sweat from my side:
(defun my-extract-minutes-of-hm-string(hm-string)
"returns the minutes of a string like 9:42 -> 42 (and 0 if there are no minutes)"
(let (
;; minutes is the second element after splitting with ":"
(minutes (nth 1 (split-string hm-string ":")))
)
;; if there is no second element, return "0" (instead of nil)
(if (eq minutes 'nil)
0
(string-to-number minutes)
)
)
)
(defun my-extract-hours-of-hm-string(hm-string)
"returns the hours of a string like 9:42 -> 9"
(string-to-number
(car
(split-string hm-string ":")
)
)
)
(defun my-hm-string-to-minutes(hm-string)
"returns the minutes of a string like 2:42 -> 162"
(let (
;; minutes is the second element after splitting with ":"
(minutes (my-extract-minutes-of-hm-string hm-string))
(hours (my-extract-hours-of-hm-string hm-string))
)
(+ minutes (* hours 60))
)
)
;; EXAMPLE USAGE:
;; | [2015-01-13 Di] | Tue | 08:53-17:23 | | | 8:30 | 8:30 | 100 | Product Development | |
;; | | | | | | | korr | % | Was | Notiz |
;; #+TBLFM: $7=$6::$9=Product Development::$8 = '(my-percentage-of-hm-string-with-day $7 $2)
(defun my-percentage-of-hm-string-with-day(hm-string day)
"percentage of HH:MM when 8h30min (Mon-Thu) or 4h30min (Fri) are 100 percent"
(let (
(hours (my-extract-hours-of-hm-string hm-string));; integer of hours from hm-string
(minutes (my-extract-minutes-of-hm-string hm-string));; integer of minutes from hm-string
(norm-hour-minutes (cond
((string= day "Mon") 8.5)
((string= day "Mo") 8.5)
((string= day "Tue") 8.5)
((string= day "Di") 8.5)
((string= day "Wed") 8.5)
((string= day "Mi") 8.5)
((string= day "Thu") 8.5)
((string= day "Do") 8.5)
((string= day "Fri") 8.5)
((string= day "Fr") 8.5)
)
)
)
;;debug;;(message (concat "norm-hour-minutes for " day " is " (number-to-string norm-hour-minutes)))
(let (
(hoursminutes (+ hours (/ minutes 60.00))) ;; 8h30min -> 8.5h
)
(round (* 100 (/ hoursminutes norm-hour-minutes)));; hoursminutes in relation to norm-hoursminutes
)
)
)
(defun my-calculate-office-hour-total(officestart officeend lunchstart lunchend)
"calculates the total hours:minutes of a work-day depending on time of arrival/leave and lunch break in HH:MM"
(let (
(officestartminutes (my-hm-string-to-minutes officestart));; integer of minutes
(officeendminutes (my-hm-string-to-minutes officeend));; integer of minutes
(lunchstartminutes (my-hm-string-to-minutes lunchstart));; integer of minutes
(lunchendminutes (my-hm-string-to-minutes lunchend));; integer of minutes
)
(let* (
(officeminutes (- (- officeendminutes officestartminutes) (- lunchendminutes lunchstartminutes)))
(officeminutesstring (format-time-string "%H:%M" (seconds-to-time (* 60 officeminutes)) t))
)
;;(message (concat "Minutes epoch: " (number-to-string officeminutes)))
;;(message (concat "Minutes string: " officeminutesstring))
(symbol-value 'officeminutesstring)
)
)
)
;; (my-calculate-office-hour-total "09:57" "17:22" "11:35" "12:08") -> Minutes epoch: 412 | Minutes string: 06:52
;; #############################################################################my-insert-orgmode-url-from-clipboard() → my-map U
Inserts URL from clipboard and retrieves title as Org-mode link
- see id:2014-08-10-bookmarks-with-orgmode
- 2015-05-22: Via email arjan: http://www.rexim.me/emacs-as-bookmark-manager-links.html
- 2021-07-15: on reddit there is this thread where alternative implementations are discussed. They might be more mature than mine. For now, I’m happy with mine. The original thread author refers to https://github.com/vrind-nl/bag.el which also tries to extract a defined set of tags (with their alternatives keywords).
straight-string()
(defun straight-string (s)
"Spliting the string and then concatenating it back."
(mapconcat #'(lambda (x) x) (split-string s) " "))my-cliplink-format-and-trim-title(title) does replace HTML entities
with their Unicode characters and trims the title to 100 characters.
The replacement table is taken from this ErgoEmacs page.
(defun my-cliplink-format-and-trim-title (title)
(let (;; Table of replacements which make this title usable for
;; org-link. Can be extended.
(replace-table '(("\\[" . "{")
("\\]" . "}")
("’" . "’")
("&" . "&") ("'" . "'") ("–" . "–") ("—" . "—")
(" • " . "") (" | heise online • " . " - heise online") (" | heise online • " . " - heise online")
(" " . " ") (" " . " ") (" " . " ") (" " . " ")
("‏" . "") ("‎" . "") ("‍" . "") ("‌" . "")
("¡" . "¡") ("¢" . "¢") ("£" . "£") ("¤" . "¤") ("¥" . "¥") ("¦" . "¦") ("§" . "§")
("¨" . "¨") ("©" . "©") ("ª" . "ª") ("«" . "«") ("¬" . "¬") ("­" . "") ("®" . "®")
("¯" . "¯") ("°" . "°") ("±" . "±") ("²" . "²") ("³" . "³") ("´" . "´") ("µ" . "µ")
("¶" . "¶") ("·" . "·") ("¸" . "¸") ("¹" . "¹") ("º" . "º") ("»" . "»") ("¼" . "¼")
("½" . "½") ("¾" . "¾") ("¿" . "¿") ("À" . "À") ("Á" . "Á") ("Â" . "Â")
("Ã" . "Ã") ("Ä" . "Ä") ("Å" . "Å") ("Æ" . "Æ") ("Ç" . "Ç") ("È" . "È") ("É" . "É")
("Ê" . "Ê") ("Ë" . "Ë") ("Ì" . "Ì") ("Í" . "Í") ("Î" . "Î") ("Ï" . "Ï") ("Ð" . "Ð")
("Ñ" . "Ñ") ("Ò" . "Ò") ("Ó" . "Ó") ("Ô" . "Ô") ("Õ" . "Õ") ("Ö" . "Ö") ("×" . "×")
("Ø" . "Ø") ("Ù" . "Ù") ("Ú" . "Ú") ("Û" . "Û") ("Ü" . "Ü") ("Ý" . "Ý") ("Þ" . "Þ")
("ß" . "ß") ("à" . "à") ("á" . "á") ("â" . "â") ("ã" . "ã") ("ä" . "ä") ("å" . "å")
("æ" . "æ") ("ç" . "ç") ("è" . "è") ("é" . "é") ("ê" . "ê") ("ë" . "ë") ("ì" . "ì")
("í" . "í") ("î" . "î") ("ï" . "ï") ("ð" . "ð") ("ñ" . "ñ") ("ò" . "ò") ("ó" . "ó")
("ô" . "ô") ("õ" . "õ") ("ö" . "ö") ("÷" . "÷") ("ø" . "ø") ("ù" . "ù") ("ú" . "ú")
("û" . "û") ("ü" . "ü") ("ý" . "ý") ("þ" . "þ") ("ÿ" . "ÿ") ("ƒ" . "ƒ") ("Α" . "Α")
("Β" . "Β") ("Γ" . "Γ") ("Δ" . "Δ") ("Ε" . "Ε") ("Ζ" . "Ζ") ("Η" . "Η") ("Θ" . "Θ")
("Ι" . "Ι") ("Κ" . "Κ") ("Λ" . "Λ") ("Μ" . "Μ") ("Ν" . "Ν") ("Ξ" . "Ξ") ("Ο" . "Ο") ("Π" . "Π")
("Ρ" . "Ρ") ("Σ" . "Σ") ("Τ" . "Τ") ("Υ" . "Υ") ("Φ" . "Φ") ("Χ" . "Χ") ("Ψ" . "Ψ")
("Ω" . "Ω") ("α" . "α") ("β" . "β") ("γ" . "γ") ("δ" . "δ") ("ε" . "ε") ("ζ" . "ζ")
("η" . "η") ("θ" . "θ") ("ι" . "ι") ("κ" . "κ") ("λ" . "λ") ("μ" . "μ") ("ν" . "ν") ("ξ" . "ξ")
("ο" . "ο") ("π" . "π") ("ρ" . "ρ") ("ς" . "ς") ("σ" . "σ") ("τ" . "τ") ("υ" . "υ")
("φ" . "φ") ("χ" . "χ") ("ψ" . "ψ") ("ω" . "ω") ("ϑ" . "ϑ") ("ϒ" . "ϒ") ("ϖ" . "ϖ")
("•" . "•") ("…" . "…") ("′" . "′") ("″" . "″") ("‾" . "‾") ("⁄" . "⁄") ("℘" . "℘")
("ℑ" . "ℑ") ("ℜ" . "ℜ") ("™" . "™") ("ℵ" . "ℵ") ("←" . "←") ("↑" . "↑") ("→" . "→")
("↓" . "↓") ("↔" . "↔") ("↵" . "↵") ("⇐" . "⇐") ("⇑" . "⇑") ("⇒" . "⇒") ("⇓" . "⇓") ("⇔" . "⇔")
("∀" . "∀") ("∂" . "∂") ("∃" . "∃") ("∅" . "∅") ("∇" . "∇") ("∈" . "∈") ("∉" . "∉")
("∋" . "∋") ("∏" . "∏") ("∑" . "∑") ("−" . "−") ("∗" . "∗") ("√" . "√") ("∝" . "∝")
("∞" . "∞") ("∠" . "∠") ("∧" . "∧") ("∨" . "∨") ("∩" . "∩") ("∪" . "∪") ("∫" . "∫") ("∴" . "∴")
("∼" . "∼") ("≅" . "≅") ("≈" . "≈") ("≠" . "≠") ("≡" . "≡") ("≤" . "≤") ("≥" . "≥") ("⊂" . "⊂")
("⊃" . "⊃") ("⊄" . "⊄") ("⊆" . "⊆") ("⊇" . "⊇") ("⊕" . "⊕") ("⊗" . "⊗") ("⊥" . "⊥")
("⋅" . "⋅") ("⌈" . "⌈") ("⌉" . "⌉") ("⌊" . "⌊") ("⌋" . "⌋") ("⟨" . "〈") ("⟩" . "〉")
("◊" . "◊") ("♠" . "♠") ("♣" . "♣") ("♥" . "♥") ("♦" . "♦") (""" . "\"") ("Œ" . "Œ")
("œ" . "œ") ("Š" . "Š") ("š" . "š") ("Ÿ" . "Ÿ") ("ˆ" . "ˆ") ("˜" . "˜") ("–" . "–")
("—" . "—") ("‘" . "‘") ("’" . "’") ("‚" . "‚") ("“" . "“") ("”" . "”") ("„" . "„")
("†" . "†") ("‡" . "‡") ("‰" . "‰") ("‹" . "‹") ("›" . "›") ("€" . "€")
))
;; Maximum length of the title.
(max-length 100)
;; Removing redundant whitespaces from the title.
(result (straight-string title)))
;; Applying every element of the replace-table.
(dolist (x replace-table)
(setq result (replace-regexp-in-string (car x) (cdr x) result t t)))
;; Cutting off the title according to its maximum length.
(when (> (length result) max-length)
(setq result (concat (substring result 0 max-length) "…")))
;; Returning result.
result))extract-title-from-html(html)
(defun extract-title-from-html (html)
(let (;; Start index of the title.
(start (string-match "<title>" html))
;; End index of the title.
(end (string-match "</title>" html))
;; Amount of characters to skip the openning title tag.
(chars-to-skip (length "<title>")))
;; If title is found ...
(if (and start end (< start end))
;; ... extract it and return.
(substring html (+ start chars-to-skip) end)
nil)))cliplink-decode-content-and-return-orgmode-link-of-title (buffer url content)
(defun cliplink-decode-content-and-return-orgmode-link-of-title (buffer url content)
(let* (;; Decoding the content from UTF-8.
(decoded-content (decode-coding-string content 'utf-8))
;; Extrating and preparing the title.
(title (my-cliplink-format-and-trim-title
(extract-title-from-html decoded-content))))
;; Inserting org-link.
(with-current-buffer buffer
(insert (format "[[%s][%s]]" url title)))))my-insert-orgmode-url-from-clipboard ()
(defun my-insert-orgmode-url-from-clipboard ()
"It inserts the URL which is taken from the system clipboard in Org-mode"
;; Of course, this function is interactive. :)
(interactive)
(let (;; Remembering the current buffer, 'cause it is a destination
;; buffer we are inserting the org-link to.
(dest-buffer (current-buffer))
;; Getting URL from the clipboard. Since it may contain
;; some text properties we are using substring-no-properties
;; function.
(url (substring-no-properties (current-kill 0))))
;; Retrieving content by URL.
(url-retrieve
url
;; Performing an action on the retrieved content.
`(lambda (s)
(cliplink-decode-content-and-return-orgmode-link-of-title ,dest-buffer ,url
(buffer-string))))))bind to my-map U
(bind-key "U" 'my-insert-orgmode-url-from-clipboard my-map)my-url-linkify() → my-map u
Replaces URL with Org-mode link including description
- see id:2014-03-09-inbox-to-bookmarks
- 2014-03-18: alternative method: http://orgmode.org/worg/org-hacks.html#sec-1-6-3 “Insert link with HTML title as default description”
- see also: http://orgmode.org/worg/org-hacks.html#orgheadline54 (not this method here!)
(defun my-www-get-page-title (url)
"retrieve title of web page.
from: http://www.opensubscriber.com/message/help-gnu-emacs@gnu.org/14332449.html"
(let ((title))
(with-current-buffer (url-retrieve-synchronously url)
(goto-char (point-min))
(re-search-forward "<title>\\([^<]*\\)</title>" nil t 1)
(setq title (match-string 1))
(goto-char (point-min))
(re-search-forward "charset=\\([-0-9a-zA-Z]*\\)" nil t 1)
(string-replace " " " "
;;(decode-coding-string title (intern (match-string 1)))
;; following line fixes charset issues from
;; previous line:
(decode-coding-string title 'utf-8)
))
)
)
(defun my-url-linkify ()
"Make URL at cursor point into an Org-mode link.
If there's a text selection, use the text selection as input.
Example: http://example.com/xyz.htm
becomes
\[\[http://example.com/xyz.htm\]\[Source example.com\]\]
Adapted code from: http://ergoemacs.org/emacs/elisp_html-linkify.html"
(interactive)
(let (resultLinkStr bds p1 p2 domainName)
;; get the boundary of URL or text selection
(if (region-active-p)
(setq bds (cons (region-beginning) (region-end)) )
(setq bds (bounds-of-thing-at-point 'url))
)
;; set URL
(setq p1 (car bds))
(setq p2 (cdr bds))
(let (
(url (buffer-substring-no-properties p1 p2))
)
;; retrieve title
(let ((title (my-cliplink-format-and-trim-title (replace-regexp-in-string "\n" " • " (my-www-get-page-title url)))))
;;(message (concat "title is: " title))
;;(setq url (replace-regexp-in-string "&" "&" url))
(let ((resultLinkStr (concat "[[" url "][" title "]]")))
;; delete url and insert the link
(delete-region p1 p2)
(insert resultLinkStr)
)
)
)
)
)
Bind the key:
(bind-key "u" 'my-url-linkify my-map)my-org-region-to-property() → my-map p
This is ultra-handy for writing properties. For example for my
contact management contacts.org I maintain properties such as phone
numbers. When I mark a (changed) phone number within the body of a
heading and invoke this function, I get asked for an existing property
and the marked region gets the new value for this property.
Please do read my blog article on this topic for all the details. You’re gonna like it. It also features a short screencast where you see this in action.
Internal link: id:2015-05-28-ask-for-properties
Version that tries to read only properties of current entry:
- From: “Antoine R. Dumont” <antoine.romain.dumont@gmail.com>
- http://article.gmane.org/gmane.emacs.orgmode/106364
(defun org-read-entry-property-name ()
"Read a property name from the current entry."
(let ((completion-ignore-case t)
(default-prop (or (and (org-at-property-p)
(org-match-string-no-properties 2))
org-last-set-property)))
(org-completing-read
(format "Property [%s]: " (if default-prop default-prop ""))
(org-entry-properties nil nil)
nil nil nil nil default-prop)))
(defun my-org-region-to-property (&optional property)
"Copies the region as value to an Org-mode property"
(interactive)
;; if no region is defined, do nothing
(if (use-region-p)
;; if a region string is found, ask for a property and set property to
;; the string in the region
(let ((val (replace-regexp-in-string
"\\`[ \t\n]*" ""
(replace-regexp-in-string "[ \t\n]*\\'" ""
(substring (buffer-string)
(- (region-beginning) 1)
(region-end))))
)
;; if none was stated by user, read property from user
(prop (or property
(org-read-entry-property-name))))
;; set property
(org-set-property prop val))))
(bind-key (kbd "p") #'my-org-region-to-property my-map)my-0d() - add a 0 day deadline to a headline
On an agenda entry: add “-0d” to deadline
(fset 'my-0d
[return ?\C-s ?> left ? ?- ?0 ?d ?\C-x ?b return down])my-agenda-cancel-event-and-set-to-inactive() - Change active timestamp to inactive and cancel event in the agenda
(fset 'my-agenda-cancel-event-and-set-to-inactive
(lambda (&optional arg) "Keyboard macro."
(interactive "p")
(kmacro-exec-ring-item (quote ([return S-up 3 20 99] 0 "%d")) arg)
)
)my-cancel-event-and-set-to-inactive() - Change active timestamp to inactive and cancel event outside of the agenda
(fset 'my-cancel-event-and-set-to-inactive
(lambda (&optional arg) "Keyboard macro."
(interactive "p")
(kmacro-exec-ring-item (quote ([5 18 62 13 S-up 3 20 99] 0 "%d")) arg)
)
)my-org-time-string-to-seconds(s)
- 2013-10-11
- From: http://orgmode.org/worg/org-hacks.html#sec-1-4-3
Example 1: normal dates and times
| Date | Start | Lunch | Back | End | Sum |
|---|---|---|---|---|---|
| [2011-03-01 Tue] | 8:00 | 12:00 | 12:30 | 18:15 | 9:45 |
Example 2: my-org-time-string-to-seconds simple case
| 13:59 | 839 |
| 13:59:05 | 50345 |
Example 3: calculating with my-org-time-string-to-seconds results
| 21:42:13 | 21:41:00 | 73 |
(defun my-org-time-string-to-seconds (s)
"Convert a string HH:MM:SS to a number of seconds.
Omitted third element will be interpreted as MM:SS with missing hours."
;; test with:
;; (message (concat "result is: " (number-to-string (my-org-time-string-to-seconds "57:45:03"))))
;; (message (concat "result is: " (number-to-string (my-org-time-string-to-seconds "57:45"))))
(cond
((and (stringp s)
(string-match "\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\)" s))
(let ((hour (string-to-number (match-string 1 s)))
(min (string-to-number (match-string 2 s)))
(sec (string-to-number (match-string 3 s))))
(+ (* hour 3600) (* min 60) sec)))
((and (stringp s)
(string-match "\\([0-9]+\\):\\([0-9]+\\)" s))
(let ((min (string-to-number (match-string 1 s)))
(sec (string-to-number (match-string 2 s))))
(+ (* min 60) sec)))
;;((stringp s) (string-to-number s))
;;(t s)
)
)my-org-time-string-to-hours(s)
| 13:59 | 0.23305555555555554 |
| 13:59:05 | 13.984722222222222 |
(defun my-org-time-string-to-hours (s)
"Convert a string HH:MM:SS to hours (float).
When only two values given, they will be interpreted as MM:SS with missing hours."
;; test via:
;; (message (concat "result is: " (number-to-string (my-org-time-string-to-hours "57:45:03"))))
;; (message (concat "result is: " (number-to-string (my-org-time-string-to-hours "57:45"))))
(/ (my-org-time-string-to-seconds s) 3600.0)
)my-org-time-seconds-to-string(secs)
| 42 | 42 |
| 98765 | 27:26:05 |
(defun my-org-time-seconds-to-string (secs)
"Convert a number of seconds to a time string."
(cond ((>= secs 3600) (format-seconds "%h:%.2m:%.2s" secs))
((>= secs 60) (format-seconds "%m:%.2s" secs))
(t (format-seconds "%s" secs))))with-time() - evaluate formula and return time
(defmacro with-time (time-output-p &rest exprs)
"Evaluate an org-table formula, converting all fields that look
like time data to integer seconds. If TIME-OUTPUT-P then return
the result as a time value."
(list
(if time-output-p 'my-org-time-seconds-to-string 'identity)
(cons 'progn
(mapcar
(lambda (expr)
`,(cons (car expr)
(mapcar
(lambda (el)
(if (listp el)
(list 'with-time nil el)
(my-org-time-string-to-seconds el)))
(cdr expr))))
`,@exprs))))org-decrypt-entries()
I never use org-decrypt-entries() since my Org files tend to be
large and contain several encrypted entries. In order to get a decent
performance, I overwrite org-decrypt-entries() so that I am able to
select org-decrypt-entry() much faster in helm search.
(defun org-decrypt-entries()
(interactive)
(org-decrypt-entry)
)my-sparse-tree-with-tag-filter() - ask for a tag and filter open Org-tasks → my-map F
The code asks for one or more tags and derives a sparse tree with all related open headings.
See: id:2014-11-02-filter-org-tasks-by-tag
(defun my-sparse-tree-with-tag-filter()
"asks for a tag and generates sparse tree for all open tasks in current Org buffer
that are associated with this tag"
(interactive "*")
(setq tag-for-filter
(org-trim
(org-icompleting-read "Tags: "
'org-tags-completion-function
nil nil nil 'org-tags-history))
)
(org-occur
(concat "^\\*+ \\(NEXT\\|TODO\\|WAITING\\|STARTED\\) .+:"
tag-for-filter
":")
)
)
(bind-key "F" #'my-sparse-tree-with-tag-filter my-map)
my-sparse-tree-WAITING()
| 2021-07-11 | created |
(defun my-sparse-tree-WAITING()
"shows org sparse tree with all WAITING tasks of current buffer"
(interactive "*")
(org-occur
(concat "^\\*+ WAITING .+")
)
)my-reddit-export-via-pandoc
This is a simple shortcut because I can not remember which of the many markdown dialects is the one for reddit and ox-pandoc doesn’t show me markdown at all which I have to fix some day.
My workflow is:
- mark the region where the content to export is
M-x my-reddit TAB RET- copy the content from the temporary buffer to my browser window
- destroy the temporary buffer
(defun my-reddit-export-via-pandoc ()
"This is a simple wrapper function that converts the currently
marked region to the markdown dialect that reddit understands."
(interactive)
(org-pandoc-export-to-markdown_mmd-and-open)
)my-org-in-any-block-p()
This is part 1/4 of the soluiton to split up blocks via M-RET:
- Blog article describing the purpose and the implementation
- Repository with the version of the source code I was copying to here
(defun my-org-in-any-block-p ()
"Return non-nil if the point is in any Org block.
The Org block can be *any*: src, example, verse, etc., even any
Org Special block.
This function is heavily adapted from `org-between-regexps-p'."
(save-match-data
(let ((pos (point))
(case-fold-search t)
(block-begin-re "^[[:blank:]]*#\\+begin_\\(?1:.+?\\)\\(?: .*\\)*$")
(limit-up (save-excursion (outline-previous-heading)))
(limit-down (save-excursion (outline-next-heading)))
beg end)
(save-excursion
;; Point is on a block when on BLOCK-BEGIN-RE or if
;; BLOCK-BEGIN-RE can be found before it...
(and (or (org-in-regexp block-begin-re)
(re-search-backward block-begin-re limit-up :noerror))
(setq beg (match-beginning 0))
;; ... and BLOCK-END-RE after it...
(let ((block-end-re (concat "^[[:blank:]]*#\\+end_"
(match-string-no-properties 1)
"\\( .*\\)*$")))
(goto-char (match-end 0))
(re-search-forward block-end-re limit-down :noerror))
(> (setq end (match-end 0)) pos)
;; ... without another BLOCK-BEGIN-RE in-between.
(goto-char (match-beginning 0))
(not (re-search-backward block-begin-re (1+ beg) :noerror))
;; Return value.
(cons beg end))))))my-org-split-block()
This is part 2/4 of the soluiton to split up blocks via M-RET:
- Blog article describing the purpose and the implementation
- Repository with the version of the source code I was copying to here
(defun my-org-split-block ()
"Sensibly split the current Org block at point.
(1) Point in-between a line
#+EXAMPLE+begin_src emacs-lisp #+EXAMPLE+begin_src emacs-lisp
(message▮ \"one\") (message \"one\")
(message \"two\") --> #+EXAMPLE+end_src
#+EXAMPLE+end_src ▮
#+EXAMPLE+begin_src emacs-lisp
(message \"two\")
#+EXAMPLE+end_src
(2) Point at EOL
#+EXAMPLE+begin_src emacs-lisp #+EXAMPLE+begin_src emacs-lisp
(message \"one\")▮ (message \"one\")
(message \"two\") --> #+EXAMPLE+end_src
#+EXAMPLE+end_src ▮
#+EXAMPLE+begin_src emacs-lisp
(message \"two\")
#+EXAMPLE+end_src
(3) Point at BOL
#+EXAMPLE+begin_src emacs-lisp #+EXAMPLE+begin_src emacs-lisp
(message \"one\") (message \"one\")
▮(message \"two\") --> #+EXAMPLE+end_src
#+EXAMPLE+end_src ▮
#+EXAMPLE+begin_src emacs-lisp
(message \"two\")
#+EXAMPLE+end_src
"
(interactive)
(if (my-org-in-any-block-p)
(save-match-data
(save-restriction
(widen)
(let ((case-fold-search t)
(at-bol (bolp))
block-start
block-end)
(save-excursion
(re-search-backward "^\\(?1:[[:blank:]]*#\\+begin_.+?\\)\\(?: .*\\)*$" nil nil 1)
(setq block-start (match-string-no-properties 0))
(setq block-end (replace-regexp-in-string
"begin_" "end_" ;Replaces "begin_" with "end_", "BEGIN_" with "END_"
(match-string-no-properties 1))))
;; Go to the end of current line, if not at the BOL
(unless at-bol
(end-of-line 1))
(insert (concat (if at-bol "" "\n")
block-end
"\n\n"
block-start
(if at-bol "\n" "")))
;; Go to the line before the inserted "#+begin_ .." line
(beginning-of-line (if at-bol -1 0)))))
(message "Point is not in an Org block")))my-org-meta-return-advice()
This is part 3/4 of the soluiton to split up blocks via M-RET:
- Blog article describing the purpose and the implementation
- Repository with the version of the source code I was copying to here
;; When point is in any Org block, make M-return split the block
;; instead of inserting heading.
(defun my-org-meta-return-advice (&rest args)
"Do not call the original function if point is in an Org block."
(let ((do-not-run-orig-fn (my-org-in-any-block-p)))
(when do-not-run-orig-fn
(my-org-split-block))
do-not-run-orig-fn))advice-add: M-RET splits up current block
This is part 4/4 of the soluiton to split up blocks via M-RET:
- Blog article describing the purpose and the implementation
- Repository with the version of the source code I was copying to here
(advice-add 'org-meta-return :before-until #'my-org-meta-return-advice)my-newsrob-capture-fix()
| 2021-07-06 | Situation with NewsRob and capture did change: not needed for quite some time → disabling it |
Currently as of 2019-02-16, I’m using NewsRob Android for reading Atom and RSS feeds.
Unfortunately, when I capture NewsRob articles using Mobile Org, I end
up with a messed up format in my inbox.org:
* NEXT Bookmark Some text is here http://example.com/path/page.html[2019-02-16 Sat. 16:07]
In contrast, I would prefer:
* NEXT Bookmark [[http://example.com/path/page.html][Some text is here]] [2019-02-16 Sat. 16:07]
Using this preferred format, I may apply my-save-bookmark() as usual.
This is why I had to come up with this helper function:
(defun my-newsrob-capture-fix ()
"Fixes NewsRob OrgMobile capture format error (content starts in 2nd line) and generates proper Org URL link"
;; for details, see id:2019-02-16-my-newsrob-capture-fix
(interactive)
;; ASSUMPTION: cursor is in FIRST line of the captured heading
(beginning-of-line)
(when (re-search-forward "^\\(\\*.*\\)
\\(.*\\)\\s-* \\(http.*\\)\\s-*\\(\\[20.*\\]\\)" nil t)
(replace-match "\\1 [[\\3][\\2]]\n\\4" t nil)))
(bind-key "B" 'my-newsrob-capture-fix my-map)my-filename-to-attr-snippet
A macro that is very handy when inserting images to a lazyblorg entry.
- Process:
- Copy and paste a file base name as a new line
- example:
2019-08-25T18.43 An example image file -- publicvoit.jpg
- example:
- Place the cursor at the begin of its line
- Invoke the macro
- Resulting snippet looks like:
- Copy and paste a file base name as a new line
#+CAPTION: #+ATTR_HTML: :align center :width 560 [[tsfile:2019-08-25T18.43 An example image file -- publicvoit.jpg][2019-08-25T18.43 An example image file -- publicvoit.jpg]]
(fset 'my-filename-to-attr-snippet
(lambda (&optional arg) "Keyboard macro." (interactive "p") (kmacro-exec-ring-item (quote ([return up 35 43 67 65 80 84 73 79 78 58 32 return 35 43 65 84 84 82 95 72 84 77 76 58 32 58 97 108 59 backspace 105 103 110 32 99 101 110 116 101 114 32 58 119 105 100 116 104 32 53 54 48 1 down 91 91 116 115 102 105 108 101 58 67108896 5 escape 119 93 91 25 93 93 15 1 down down] 0 "%d")) arg)))my-mark-as-project
With UOMF: On How to Define Projects in Org Mode I started to use
marking projects with a specific tag and made sure the COOKIE_DATA
property ignores the checkboxes.
Following function makes sure that these things are set properly (and a bit more):
(defun my-mark-as-project ()
"This function makes sure that the current heading has
(1) the tag :project:
(2) has property COOKIE_DATA set to \"todo recursive\"
(3) has any TODO keyword and
(4) a leading progress indicator
(5) expand a yankpad/yasnippet element which is inserted at the top of the body of the heading"
(interactive)
(org-toggle-tag "project" 'on)
(org-set-property "COOKIE_DATA" "todo recursive")
(org-back-to-heading t)
(let* ((title (nth 4 (org-heading-components)))
(keyword (nth 2 (org-heading-components))))
(when (and (bound-and-true-p keyword) (string-prefix-p "[" title))
(message "TODO keyword and progress indicator found")
)
(when (and (not (bound-and-true-p keyword)) (string-prefix-p "[" title))
(message "no TODO keyword but progress indicator found")
(forward-whitespace 1)
(insert "NEXT ")
)
(when (and (not (bound-and-true-p keyword)) (not (string-prefix-p "[" title)))
(message "no TODO keyword and no progress indicator found")
(forward-whitespace 1)
(insert "NEXT [/] ")
)
(when (and (bound-and-true-p keyword) (not (string-prefix-p "[" title)))
(message "TODO keyword but no progress indicator found")
(forward-whitespace 2)
(insert "[/] ")
)
)
(search-forward "
");; goto the first paragraph of the body
(insert "pchecklist
");; insert snippet name for yankpad project management checklist snippet
(search-backward "list")
(org-end-of-line);; goto back to the snippet name
(yankpad-expand);; expand snippet
)Personal notes from the implementation task: id:2019-11-08-my-mark-as-project
I found following interesting elisp sources for implementing this function:
- get heading parsed: http://ergoemacs.org/emacs/elisp_parse_org_mode.html
- insert text: http://ergoemacs.org/emacs/elisp_examples.html
You also might be interested to read A Draft Workflow for Advanced Project Management Using Org Mode and Org Edna where this is a part of the proposed project management workflow.
my-org-auto-tag
I got the code and the idea from this stackoverflow page. Invoking this function tags the current headline with words that can also be found in the combined lists of:
my-org-tag-alist- defined below just for this function
org-tag-persistent-alist- according to standard Org mode usage
org-tag-alist- according to standard Org mode usage
(setq my-org-tag-alist (quote (
("Org" . ?@)
("keywords" . ?@)
)))
(defun my-org-auto-tag ()
(interactive)
(let ((alltags (append my-org-tag-alist org-tag-persistent-alist org-tag-alist))
(headline-words (split-string (org-get-heading t t)))
)
(mapcar (lambda (word) (if (assoc word alltags)
(org-toggle-tag word 'on)))
headline-words))
)my-generate-sanitized-alnum-dash-string
- 2020-06-05: alternative method by https://blog.phundrak.com/better-custom-ids-orgmode/
(defun my-generate-sanitized-alnum-dash-string(str)
"Returns a string which contains only a-zA-Z0-9 with single dashes
replacing all other characters in-between them.
Some parts were copied and adapted from org-hugo-slug
from https://github.com/kaushalmodi/ox-hugo (GPLv3)."
(let* (;; Remove "<FOO>..</FOO>" HTML tags if present.
(str (replace-regexp-in-string "<\\(?1:[a-z]+\\)[^>]*>.*</\\1>" "" str))
;; Remove URLs if present in the string. The ")" in the
;; below regexp is the closing parenthesis of a Markdown
;; link: [Desc](Link).
(str (replace-regexp-in-string (concat "\\](" ffap-url-regexp "[^)]+)") "]" str))
;; Replace "&" with " and ", "." with " dot ", "+" with
;; " plus ".
(str (replace-regexp-in-string
"&" " and "
(replace-regexp-in-string
"\\." " dot "
(replace-regexp-in-string
"\\+" " plus " str))))
;; Replace German Umlauts with 7-bit ASCII.
(str (replace-regexp-in-string "[Ä]" "Ae" str t))
(str (replace-regexp-in-string "[Ü]" "Ue" str t))
(str (replace-regexp-in-string "[Ö]" "Oe" str t))
(str (replace-regexp-in-string "[ä]" "ae" str t))
(str (replace-regexp-in-string "[ü]" "ue" str t))
(str (replace-regexp-in-string "[ö]" "oe" str t))
(str (replace-regexp-in-string "[ß]" "ss" str t))
;; Replace all characters except alphabets, numbers and
;; parentheses with spaces.
(str (replace-regexp-in-string "[^[:alnum:]()]" " " str))
;; On emacs 24.5, multibyte punctuation characters like ":"
;; are considered as alphanumeric characters! Below evals to
;; non-nil on emacs 24.5:
;; (string-match-p "[[:alnum:]]+" ":")
;; So replace them with space manually..
(str (if (version< emacs-version "25.0")
(let ((multibyte-punctuations-str ":")) ;String of multibyte punctuation chars
(replace-regexp-in-string (format "[%s]" multibyte-punctuations-str) " " str))
str))
;; Remove leading and trailing whitespace.
(str (replace-regexp-in-string "\\(^[[:space:]]*\\|[[:space:]]*$\\)" "" str))
;; Replace 2 or more spaces with a single space.
(str (replace-regexp-in-string "[[:space:]]\\{2,\\}" " " str))
;; Replace parentheses with double-hyphens.
(str (replace-regexp-in-string "\\s-*([[:space:]]*\\([^)]+?\\)[[:space:]]*)\\s-*" " -\\1- " str))
;; Remove any remaining parentheses character.
(str (replace-regexp-in-string "[()]" "" str))
;; Replace spaces with hyphens.
(str (replace-regexp-in-string " " "-" str))
;; Remove leading and trailing hyphens.
(str (replace-regexp-in-string "\\(^[-]*\\|[-]*$\\)" "" str)))
str)
)History of this function: id:2019-11-14-Org-Project-Management-Workflow
my-id-get-or-generate
| 2019-11-14 | wrote this function to get nice ID properties |
I don’t like UUIDs as they tell the user nothing. Therefore, I generate ID properties like slugs.
You may want to read this reddit discussion for alternative methods to generate nice IDs.
(defun my-id-get-or-generate()
"Returns the ID property if set or generates and returns a new one if not set.
The generated ID is stripped off potential progress indicator cookies and
sanitized to get a slug. Furthermore, it is prepended with an ISO date-stamp
if none was found before."
(interactive)
(when (not (org-id-get))
(progn
(let* (
(my-heading-text (nth 4 (org-heading-components)));; retrieve heading string
(my-heading-text (replace-regexp-in-string "[[][0-9%/]+[]] " "" my-heading-text));; remove progress indicators like "[2/7]" or "[25%]"
(new-id (my-generate-sanitized-alnum-dash-string my-heading-text));; get slug from heading text
)
;;(message (concat "HEADING: " my-heading-text))
(when (not (string-match "[12][0-9][0-9][0-9]-[01][0-9]-[0123][0-9]-.+" new-id))
;; only if no ISO date-stamp is found at the beginning of the new id:
(setq new-id (concat (format-time-string "%Y-%m-%d-") new-id)))
(org-set-property "ID" new-id)
)
)
)
(kill-new (concat "id:" (org-id-get)));; put ID in kill-ring
(org-id-get);; retrieve the current ID in any case as return value
)
(bind-key (kbd "I") #'my-id-get-or-generate my-map)History of this function: id:2019-11-14-Org-Project-Management-Workflow
my-org-tree-to-indirect-buffer
This beautiful piece of code was done by alphapapa and published on
reddit. Its purpose is to provide more than one indirect buffer when
using org-tree-to-indirect-buffer() (via C-c C-x b). Further more,
it has a different way of naming these buffers.
Using an advice, the original function gets overwritten.
(defun my-org-tree-to-indirect-buffer (&optional arg)
"Create indirect buffer and narrow it to current subtree.
The buffer is named after the subtree heading, with the filename
appended. If a buffer by that name already exists, it is
selected instead of creating a new buffer."
(interactive "P")
(let* ((new-buffer-p)
(pos (point))
(buffer-name (let* ((heading (org-get-heading t t))
(level (org-outline-level))
(face (intern (concat "outline-" (number-to-string level))))
(heading-string (propertize (org-link-display-format heading)
'face face)))
(concat heading-string "::" (buffer-name))))
(new-buffer (or (get-buffer buffer-name)
(prog1 (condition-case nil
(make-indirect-buffer (current-buffer) buffer-name 'clone)
(error (make-indirect-buffer (current-buffer) buffer-name)))
(setq new-buffer-p t)))))
(switch-to-buffer new-buffer)
(when new-buffer-p
;; I don't understand why setting the point again is necessary, but it is.
(goto-char pos)
(rename-buffer buffer-name)
(org-narrow-to-subtree))))
(advice-add 'org-tree-to-indirect-buffer :override 'my-org-tree-to-indirect-buffer)my-refile-recache
| 2020-02-12 | written by myself to clear and re-fill the refile cache |
(defun my-refile-recache ()
"Clears and re-populates the org-refile-cache"
(interactive)
(setq my-refile-recache-start-time (current-time))
(save-some-buffers t) ;; get latest refile targets
(org-refile-cache-clear) ;; Clear the target cache. Caching of refile targets can be turned on by setting org-refile-use-cache. To make the command see new possible targets, you have to clear the cache with this command.
(setq org-refile-target-table (org-refile-get-targets))
(setq current-timestamp
(concat
(format-time-string "%Y-%m-%dT%T")
((lambda (x) (concat (substring x 0 3) ":" (substring x 3 5)))
(format-time-string "%z"))))
(my-log-misc (format-message "my-refile-recache-start-time took %.2fs" (float-time (time-subtract (current-time) my-refile-recache-start-time))))
(when (> (string-to-number (emacs-uptime "%m")) 2) ;; only flash when not part of the boot process (= Emacs runs longer than 2 minutes)
(my-flash (format-message "Refile re-cache took %.2fs" (float-time (time-subtract (current-time) my-refile-recache-start-time)))))
)my-delete-next-collapsed-property-drawer
| 2020-04-23 | Added to clean up misc Org files |
(defun my-delete-next-collapsed-property-drawer()
"isearch-forward → \":PROPERTIES:\" → remove line (with collapsed drawer)"
(search-forward ":PROPERTIES:")
(beginning-of-line)
(org-kill-line)
(org-kill-line)
)my-org-retrieve-url-from-point → C-c o
| 2020-05-18 | added |
I wanted a function that does not open an web URL within Org mode (via
C-c C-o) but rather copies its URL to the system clipboard for
non-Emacs apps to paste.
Lucky me, I found the ready-to-use solution on this page which I bind to previously unused C-c o:
(defun my-org-retrieve-url-from-point ()
(interactive)
(let* ((link-info (assoc :link (org-context)))
(text (when link-info
;; org-context seems to return nil if the current element
;; starts at buffer-start or ends at buffer-end
(buffer-substring-no-properties (or (cadr link-info) (point-min))
(or (caddr link-info) (point-max))))))
(if (not text)
(error "Not in org link")
(add-text-properties 0 (length text) '(yank-handler (my-yank-org-link)) text)
(kill-new text))))(global-set-key (kbd "C-c o") 'my-org-retrieve-url-from-point)my-webarchive-tsfile
| 2020-12-28 | initial version (see this internal id) |
This is basically a file-picker for a specific directory that holds HTML files of all of my visited web pages I archive via SingleFileZ. The function then inserts a “tsfile:” link. Look for other occurances of “tsfile” in this file for further explanation on “tsfile” or read this.
I added a cache for the list of files to minimize unnecessary re-reading of the (long) directory. This cache gets invalidated and updated when one of the following conditions occur:
- there was no previous invocation
- the last function invocation (not cache update!) is older than 90 seconds
- FUTURE IDEA: the universal argument is given
- not implemented yet because I call this function from the org hydra only which would require a second hydra entry for the call with the universal argument.
(defun my-webarchive-tsfile ()
"Asks for a file name within the webarchive dir and returns a tsfile-link of the basename"
(interactive)
;; NOTE: my-webarchive-tsfile-dir-path is defined in the section where system-specific paths are defined in general
;; check if updating the filename cache is necessary:
(when (or
(not (boundp 'my-webarchive-tsfile-file-list))
(not (boundp 'my-webarchive-tsfile-last-invocation-time))
(eq my-webarchive-tsfile-file-list nil)
(< 90.0 (float-time (time-since my-webarchive-tsfile-last-invocation-time)))
)
(progn
(message (concat "Re-reading the list of files from " my-webarchive-tsfile-dir-path))
(setq my-webarchive-tsfile-file-list (f-files my-webarchive-tsfile-dir-path)))
)
;; ask the user for a file:
(setq myfile (helm-basename (helm-comp-read "Which webarchive file:" my-webarchive-tsfile-file-list)))
;; save the current time in order to compare it next invocation:
(setq my-webarchive-tsfile-last-invocation-time (current-time))
;; insert the custom link to the current position:
(insert (concat "[[tsfile:" myfile "][" myfile "]]"))
)
my-mark-block
| 2021-07-06 | Marks the current block at point including BEGIN and END lines. |
Just like org-babel-mark-block but for all block types (between
#+BEGIN_ and #+END_) and it marks including the BEGIN and END
lines. It’s not clever enough to detect quoted block begin/end strings.
(defun my-mark-block()
"marks the block at point including BEGIN and END lines."
(interactive)
;; you don't want to use save-excursion here since it resets your point, not staying at the located begin of block position.
(search-forward (concat "#+" "END_") nil t);; go to end of the block
(end-of-line)
(set-mark-command nil)
(search-backward (concat "#+" "BEGIN_") nil t);; go to start of the block
(setq deactivate-mark nil)
)
(bind-key "b" 'my-mark-block my-map)my-rise-update-project-tables
| 2021-07-10 | established to update two column view dynamic block tables which takes ~20 minutes somehow (performance) |
(defun my-rise-update-project-tables ()
"Updates the two tables that contain focus and non-focus projects"
(interactive)
(save-excursion
(save-some-buffers t) ;; get latest contact changes
(setq my-rise-update-project-tables-start-time (current-time))
(switch-to-buffer "rise.org")
(beginning-of-buffer)
(search-forward (concat "Name: RISE " "focus projects"))
(org-ctrl-c-ctrl-c)
(search-forward (concat "Name: RISE " "non-focus projects"))
(org-ctrl-c-ctrl-c)
;; log info and inform the user:
(let ((my-tmp-log-string (format-message "my-rise-update-project-tables took %.1f minutes"
(/ (float-time (time-subtract (current-time) my-rise-update-project-tables-start-time)) 60.0))))
(my-log-misc my-tmp-log-string)
(my-flash my-tmp-log-string)
))
)my-replace-id-property
| 2021-07-31 | Added to my config |
- Why? https://www.reddit.com/r/orgmode/comments/ouihd3/how_to_modify_searchreplace_an_id_property/
I do think that many Orgers are changing IDs all the time as long as they tend to keep a human readable ID aligned with a changed heading text.
When I do have the urge to change an existing ID property which is just used within the same file, I need to close the Org file in Emacs, re-open the buffer either in Emacs in basic mode or in vim, apply search&replace for the ID and re-open it in Emacs/Org mode again.
The reason is that - by default or at least in my setup - text in link targets is not affected by search&replace.
Is there a more clever way of doing this?
Optimum would be something like “change this ID (either by yanking manually, point on property or point on link to an ID) in all agenda files”. But I’m also interested in an improved workaround in comparison to my method above.
alphapapa helped me with a stub which I expanded to an interactive function:
(defun my-replace-id-property ()
"Replaces the ID of the current heading to a different one and replaces all occurrences in agenda files."
(interactive)
(let* ((my-old-id (org-entry-get nil "ID"))
(my-new-id (read-string "Enter new ID: " nil nil my-old-id))
(my-old-target (concat "id:" my-old-id))
(my-new-target (concat "id:" my-new-id)))
(org-set-property "ID" my-new-id)
(org-ql-select (org-agenda-files)
`(link :target ,my-old-target)
:action `(save-excursion (cl-loop while (re-search-forward ,my-old-target
(org-entry-end-position) t) do
(replace-match ,my-new-target t t))))
))As alphapapa pointed out, there is no error handling yet (undo boundaries in each buffer). If you know how to implement this properly, please do submit a pull request.
org-mode-hook
Set some modes when openening a file in Org-mode:
(add-hook 'org-mode-hook
(lambda ()
;; yasnippet
;;disabled; (make-variable-buffer-local 'yas/trigger-key)
;;disabled; (org-set-local 'yas/trigger-key [tab])
;;disabled; (define-key yas/keymap [tab] 'yas/next-field-group)
;; flyspell mode for spell checking everywhere
;;disabled; (flyspell-mode 1)
;; auto-fill mode on
(auto-fill-mode 1)))Make TAB the yas trigger key in the org-mode-hook and enable flyspell mode and autofill:
(add-hook 'org-mode-hook
(lambda ()
;; flyspell mode for spell checking everywhere
;;disabled; (flyspell-mode 1)
;; Undefine C-c [ and C-c ] since this breaks my org-agenda files when directories are include
;; It expands the files in the directories individually
(org-defkey org-mode-map "\C-c[" 'undefined)
(org-defkey org-mode-map "\C-c]" 'undefined)
;; (local-set-key (kbd "C-c M-o") 'bh/mail-subtree)
)
)Opening image files with external viewer:
(add-hook 'org-mode-hook
'(lambda ()
(setq org-file-apps
(append '(
("\\.png\\'" . default)
("\\.jpg\\'" . default)
("\\.jpeg\\'" . default)
("\\.tiff\\'" . default)
("\\.doc\\'" . default)
("\\.docx\\'" . default)
("\\.xlsx\\'" . default)
("\\.pptx\\'" . default)
) org-file-apps ))))TODO keywords and faces
Define my default keywords:
(setq org-todo-keywords (quote
(
(sequence "TODO(t)" "NEXT(n)" "STARTED(s)" "WAITING(w@/!)" "SOMEDAY(S!)" "|" "DONE(d!/!)" "CANCELLED(c@/!)")
)
)
)Define the style of the keywords:
(setq org-todo-keyword-faces
(quote (("TODO" :foreground "lightblue" :weight bold)
("NEXT" :foreground "red" :weight bold)
("STARTED" :foreground "red" :weight bold)
("DONE" :foreground "forest green" :weight bold)
("WAITING" :foreground "orange" :weight bold)
("TEAM" :foreground "orange" :weight bold)
("SOMEDAY" :foreground "magenta" :weight bold)
("CANCELLED" :foreground "forest green" :weight bold)
("QUOTE" :foreground "red" :weight bold)
("QUOTED" :foreground "magenta" :weight bold)
("APPROVED" :foreground "forest green" :weight bold)
("EXPIRED" :foreground "forest green" :weight bold)
("REJECTED" :foreground "forest green" :weight bold)
("OPEN" :foreground "blue" :weight bold)
("CLOSED" :foreground "forest green" :weight bold)
("PHONE" :foreground "forest green" :weight bold))))«Non-nil means use the fast todo selection scheme with ‘C-c C-t’. This variable describes if and under what circumstances the cycling mechanism for TODO keywords will be replaced by a single-key, direct selection scheme.» https://www.gnu.org/software/emacs/manual/html_node/org/TODO-basics.html
(setq org-use-fast-todo-selection t)«Non-nil means switching TODO states with S-cursor counts as state change. This is the default behavior. However, setting this to nil allows a convenient way to select a TODO state and bypass any logging associated with that.» https://www.gnu.org/software/emacs/manual/html_node/org/TODO-basics.html
(setq org-treat-S-cursor-todo-selection-as-state-change nil)CANCELED -> add ARCHIVE-tag: http://article.gmane.org/gmane.emacs.orgmode/64852
- disabled 2015-12-07
(setq org-todo-state-tags-triggers
(quote (("CANCELLED"
("ARCHIVE" . t))
("WAITING"
("WAITING" . t))
(done
("WAITING"))
("TODO"
("WAITING")
("CANCELLED"))
("NEXT"
("WAITING"))
("STARTED"
("WAITING"))
("DONE"
("WAITING")
("CANCELLED")))))Change font for DONE tasks
(setq org-fontify-done-headline t)
(custom-set-faces
'(org-done ((t (:foreground "PaleGreen"
:weight normal
:strike-through t))))
'(org-headline-done
((((class color) (min-colors 16) (background dark))
(:foreground "LightSalmon" :strike-through t)))))Tagging
Tags with fast selection keys http://orgmode.org/org.html#Setting-tags
(setq org-tag-alist (quote (
;;("Kommunikation" . ?k)
("Besorgung" . ?B)
("issue" . ?i)
;;("nonComputer" . ?n)
;;("fitness" . ?f)
(:startgroup)
("@BWG" . ?b)
;;("@Infonova" . ?i)
;;("@out_of_town" . ?o)
;;("@FHStP" . ?F)
;;("@Ebreichsdorf" . ?e)
;;("@TUG" . ?t)
(:endgroup)
;;(:startgroup)
;;("private" . ?p)
;;("public" . ?P)
;;(:endgroup)
(:startgroup)
;;("bigRock" . ?b)
("MIT" . ?m)
("lp" . ?l)
("reward" . ?r)
("focus" . ?f)
(:endgroup)
)))Allow setting single tags without the menu http://orgmode.org/org.html#Setting-tags
(setq org-fast-tag-selection-single-key (quote expert))my-set-tags-including-inherited
The problem: when I do have the following heading structure and I
export “My Project”, e.g., to HTML, the tags projectX and @Peter
are not associated to “My Task”:
* My Project :projectX:
** My Workpackage :@Peter:
*** My Task :foo:
Within Org-mode, tag inheritance works perfectly. However, the export
modules do not consider tag inheritance at all. This way, “My Task”
does not get the tags projectX and @Peter.
When invoking the following function when the cursor is on a heading, all inherited tags get written to the heading. In the example above, when invoking on the heading “My Task”, the end result would be:
* My Project :projectX:
** My Workpackage :@Peter:
*** My Task :projectX:@Peter:foo:
(defun my-set-tags-including-inherited ()
(interactive)
(let (
(alltags (org-get-tags-at))
;(ignored-tags '(ISAE3402 2del crypt))
)
;; 2018-01-23: any method I tried to remove certain tags did not work due to my inability to filter according to strings:
;; example string: (#("ISAE3402" 0 8 (inherited t)) #("test1" 0 5 (inherited t)) #("foobar" 0 6 (inherited t)) #("test2" 0 5 (inherited t)) #("baz" 0 3 (inherited t)))
;;(delete 'ISAE3402 alltags)
;; remove "a" from al, using equal as the test, applied to the car of each element
; (setq alltags
;(remove* "ISAE3402" alltags :test 'equal :key 'get-text-property)
; 'get-text-property
; 'car
;)
(org-set-tags alltags)
)
)Capture
http://orgmode.org/manual/Capture.html «Capture lets you quickly store notes with little interruption of your work flow.»
One of my most used Org-mode features - a simple must-have.
My general inbox for Org-mode is my inbox.org file. It mostly gets
new headings from MobileOrg but I also fill it from other sources:
emails, manual editing in vim, …
Setting it up: http://orgmode.org/org.html#Setting-up-capture
(setq org-default-notes-file (concat my-org-files-path "inbox.org"))
(define-key global-map "\C-cc" 'org-capture)Capture tricks
http://storax.github.io/blog/2016/05/02/org-capture-tricks/
- See id:2016-05-05-yasnippet-like-capture-templates
* JIRA Ticket %(my-capture-promt "JIRA Project" 'jr-prj)-%(my-capture-promt "JIRA Ticket No." 'jr-no) For project %(my-capture-insert 'jr-prj) I have to do the following stuff: %(my-capture-optional "triage" (format "** Triage %s-%s Do the triage." jr-prj jr-no)) %(my-capture-optional "implementation" (format "** Implement %s-%s Implement stuff - [ ] Tests pass?" jr-prj jr-no))
my-capture-* - Functions for prompting for different things
(defvar my-capture-promt-history nil
"History of prompt answers for org capture.")
(defun my-capture-prompt (prompt variable)
"PROMPT for string, save it to VARIABLE and insert it."
(make-local-variable variable)
(set variable (read-string (concat prompt ": ") nil my-capture-promt-history)))
(defun my-capture-prompt-date (prompt variable)
"PROMPT for a date, save it to VARIABLE and insert it."
(make-local-variable variable)
(set variable
(format-time-string
(org-time-stamp-format nil nil)
(org-read-date nil t nil prompt))
))
(defun my-capture-insert (variable)
"Insert content of VARIABLE."
(symbol-value variable))
(defun my-capture-optional (what text)
"Ask user to include WHAT. If user agrees return TEXT."
(when (y-or-n-p (concat "Include " what "?"))
text))
(defun my-capture-selection (list variable)
"Let the user choose between a pre-defined set of strings"
(make-local-variable variable)
(let ((selected-value (ido-completing-read "Select from list: " list)))
(set variable selected-value)
selected-value)
)org-capture-templates - Prelude
A shortcut for a simple heading with keyword NEXT which will be used
multiple times below:
(setq my-capture-template-next "* NEXT %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n")A test capture template:
(setq my-capture-template-test "** Capture test
- Entering values: %(my-capture-prompt \"Please enter FOO\" 'my-foo) %(my-capture-prompt \"Please enter BAR\" 'my-bar)
- Entering a date: %(my-capture-prompt-date \"Enter a date\" 'my-date)
- Selection: %(my-capture-selection '(\"one\" \"two\" \"three\") 'my-number)
- Optional: %(my-capture-optional \"an optional snippet\" \"The content for the optional thing\")
Re-using:
- Here comes %(my-capture-insert 'my-foo) and %(my-capture-insert 'my-bar)
- The date: %(my-capture-insert 'my-date)
- Your number choice: %(my-capture-insert 'my-number)
\n\n")Using test org-capture-templates:
(setq org-capture-templates
`(
("1" "first version with string" entry (file+headline (concat my-org-files-path "misc.org") "shorts")
"* NEXT %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n" :empty-lines 1)
("2" "second version with variable" entry (file+headline (concat my-org-files-path "misc.org") "shorts")
,my-capture-template-next :empty-lines 1)
))org-capture-templates
- templates: http://orgmode.org/org.html#Capture-templates
- elements: http://orgmode.org/org.html#Template-elements
BEGIN of the templates:
(setq org-capture-templates
`(My general templates:
("s" "shorts-todo" entry (file+headline ,(concat my-org-files-path "misc.org") "shorts")
,my-capture-template-next :empty-lines 2)
("e" "Event" entry (file+headline ,(concat my-org-files-path "misc.org") "Events")
"* %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n" :empty-lines 2)
("b" "Bookmark" entry (file+headline ,(concat my-org-files-path "notes.org") "Bookmarks")
"* %x%?\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n" :empty-lines 2)
("p" "public voit" entry (file+headline ,(concat my-org-files-path "public_voit.org") "Unfinished (non-series, non-persistent)")
"* NEXT %? :blog:%^g\n:PROPERTIES:\n:CREATED: %U\n:ID: %^{prompt}\n:END:\n\n-----------------------\n- [ ] link on older/similar articles?\n- [ ] link on tag pages?\n\n" :empty-lines 2)
("a" "anzuschauen" entry (file+headline ,(concat my-org-files-path "misc.org") "Anzuschauen")
"* NEXT %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n%x\n\n" :empty-lines 2)
("B" "Besorgung" entry (file+headline ,(concat my-org-files-path "hardware.org") "Besorgungen")
,my-capture-template-next :empty-lines 2)Hardware templates:
("h" "hardware")
("hs" "sting" entry (file+olp ,(concat my-org-files-path "hardware.org") "Inventar" "intel NUC (<2015-07-25 Sat>, € 486.84, e-tec)" "shorts")
,my-capture-template-next :empty-lines 2)
("hf" "floyd" entry (file+olp ,(concat my-org-files-path "hardware.org") "Inventar" "lenovo Thinkpad X260 (<2016-03-22 Tue>, 899€, u:book)" "shorts")
,my-capture-template-next :empty-lines 2)
("hp" "RasPlay" entry (file+olp ,(concat my-org-files-path "hardware.org") "Inventar" "Raspberry Pi 2 Model B (<2015-06-29 Mon>, 38€, Pollin.de)")
,my-capture-template-next :empty-lines 2)
;;old;;("hb" "blanche" entry (file+olp "~/org/hardware.org" "Inventar" "Mac Mini mit OS X 10.5 (2009-0?0??)" "shorts")
;;old;; "* NEXT %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n" :empty-lines 2)
("hw" "Winora T3" entry (file+olp ,(concat my-org-files-path "hardware.org") "Inventar" "Fahrrad: Winora T3 ([[contact:Kotnik][Kotnik]], 2464€, <2013-08-02 Fri>)")
,my-capture-template-next :empty-lines 2)Templates for my home:
("w" "Breitenweg")
("ws" "Breitenweg shorts" entry (file+headline ,(concat my-org-files-path "bwg.org") "shorts")
,my-capture-template-next :empty-lines 2)
("we" "Breitenweg event" entry (file+headline ,(concat my-org-files-path "bwg.org") "Events")
"* %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n" :empty-lines 2)
;;old;;("wa" "Breitenweg Ausgaben" table-line (file+headline "~/org/bwg.org" "getätigte Ausgaben") "| %t | %? ||||")Company templates:
("r" "RISE")
("rs" "shorts" entry (file+headline ,(concat my-org-files-path "rise.org") "shorts")
,my-capture-template-next :empty-lines 2)
("re" "event" entry (file+headline ,(concat my-org-files-path "rise.org") "Events")
"* %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n" :empty-lines 2)
("ro" "RB onboarding" entry (file+headline ,(concat my-org-files-path "rise.org") ,my-business-rbos-heading)
,my-business-rbo-template :empty-lines 2)
("rO" "RB offboarding" entry (file+headline ,(concat my-org-files-path "rise.org") ,my-business-rbos-heading)
,my-business-rboff-template :empty-lines 2)Template for my lecture:
("f" "FH St. Pölten shorts" entry (file+headline ,(concat my-org-files-path "fhsp.org") "shorts")
,my-capture-template-next :empty-lines 2)Put it in the inbox, refile it later:
("I" "inbox, refile later" entry (file ,(concat my-org-files-path "inbox.org"))
"\n* %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n" :empty-lines 2)
("W" "WWW: inbox, refile later" entry (file ,(concat my-org-files-path "inbox.org"))
"* %a :website:\n\n%U %?\n\n%:initial\n" :empty-lines 2)Old templates for the records:
("x" "xlog")
("xf" "xlog FNS" table-line (id "xlog-fns-id") "| %T |")
("xz" "xlog ZNS" table-line (id "xlog-zns-id") "| %T |")
("xh" "xlog hometrainer" table-line (id "xlog-hometrainer") "| %T | | | |")
("xb" "xlog Bettwäsche" table-line (id "xlog-bettwaesche-id") "| %T | | | | |")
("xg" "xlog Gewicht" table-line (id "xlog-gewicht") "| %T | |")
("xr" "Reinigung Geschirrspüler" table-line (id "xlog-Geschirrspuelerreinigung") "| %T |")
("xp" "Pollenallergie Symptome" table-line (id "ad5f7363-e280-4566-912d-1fb5699725da") "| %T |")
("xt" "Pollenallergie Tabletteneinnahme" table-line (id "b718be27a93a35207bac9b18ec390cc3") "| %T |")
("xG" "elmex grün" table-line (id "d705cdf9-40e5-4677-9662-e0e17d05798f") "| %T |")
("xR" "elmex rot" table-line (id "fbd9be0e-5077-4ba9-89eb-6041f945991a") "| %T |")
("xD" "dentalux Complex 3" table-line (id "2013-08-06-detalux3") "| %T |")
("xk" "Keyboard Akkus leer" table-line (id "3407c9b7-1b41-443b-9254-32c4af3a54e8") "| %T |")
("xx" "xlogtest" table-line (file+headline ,(concat my-org-files-path "misc.org") "xlogtest2012-06-17") "| %T |")Test template:
("X" "test" entry (file+headline ,(concat my-org-files-path "misc.org") "Tests")
,my-capture-template-test :empty-lines 1)END of the templates:
)
)Moving web bookmarks from inbox.org to notes.org → my-map b
| 2021-07-06 | Not used for quite some time → disabled |
Smart moving bookmark headings from inbox.org to notes.org
- see id:2014-03-09-inbox-to-bookmarks or read http://www.karl-voit.at/2014/08/10/bookmarks-with-orgmode/
(defun my-save-bookmark()
"removes NEXT/Bookmark, (NOT YET: FIXXME: retrieves title),
move time-stamp to CREATED, re-file to bookmarks, invoke Org-mode tagging process"
(interactive)
(save-excursion
;; get myself to the beginning of the current heading:
;;(outline-previous-visible-heading 1) ;; jump to previous heading
;;(outline-next-visible-heading 1) ;; jumps to beginning of the current (interesting) heading
(beginning-of-line) ;; jump to beginning of line
(let ((mybegin (point))) ;; mark beginning of line as start point
(outline-next-visible-heading 1) ;; jumps to EOF if it is the last entry
(save-restriction
(narrow-to-region mybegin (point)) ;; ignore everything outside of region
;; search/replace unwanted keywords at the beginning:
(goto-char (point-min))
(while (search-forward "* NEXT Bookmark " nil t) (replace-match "* " nil t))
(goto-char (point-min))
;; (join-line -1) ;; join line because with capturing via NewsBlur app, the content starts in line 2
;; (goto-char (point-min))
(while (search-forward "* NEXT " nil t) (replace-match "* " nil t))
(goto-char (point-min))
(while (search-forward "* Bookmark " nil t) (replace-match "* " nil t))
(goto-char (point-min))
(while (search-forward "//m.heise.de" nil t) (replace-match "//heise.de" nil t));; remove mobile heise URL
(goto-char (point-min))
(while (search-forward "/from/atom10?wt_mc=rss.ho.beitrag.atom" nil t);; remove heise RSS tags
(replace-match "" nil t)
)
(goto-char (point-min))
(while (search-forward "?wt_mc=rss.ho.beitrag.atom" nil t);; remove heise RSS tags
(replace-match "" nil t)
)
(goto-char (point-min))
;; insert second asterisk (modify to second level heading)
(insert "*")
;; move time-stamp to properties-drawer:
(search-forward-regexp "^\\[20") ;; jump to second line (with time-stamp) via search
(beginning-of-line)
(insert ":PROPERTIES:\n:CREATED: ")
(end-of-line)
(newline)
(insert ":END:\n")
;; move region to end of notes.org
(kill-region mybegin (point)) ;; kill region to kill-ring
(switch-to-buffer "notes.org")
(end-of-buffer)
(newline)
(yank)
;; add tags
(outline-previous-visible-heading 1) ;; jump to heading
(org-set-tags-command)
)
)
)
)
(bind-key "b" 'my-save-bookmark my-map)Mobile capture
- http://orgmode.org/org.html#MobileOrg
- https://github.com/matburt/mobileorg-android
- “Active development of MobileOrg has stopped.”
- → I moved from MobileOrg to Orgzly also for mobile capture, keeping the capture workflow from MobileOrg:
- new headings get captured in
mobileorg.organdmy-mobile-org-import()moves those new items into myinbox.org. - This should prevent overwriting data due to race conditions because of infrequent sync of Orgzly
- new headings get captured in
General OrgMobile setup:
(setq org-directory "~/org")
(setq org-mobile-directory my-org-files-path)
(setq org-mobile-inbox-for-pull (concat my-org-files-path "inbox.org"))Do not generate IDs for all headings: http://orgmode.org/manual/Pushing-to-MobileOrg.html
(setq org-mobile-force-id-on-agenda-items nil)my-mobile-org-import() → my-map i
On my Android phone, I use MobileOrg to capture stuff. Following
binding brings me the most current captured items into my inbox.org:
(defun my-merge-mobileorg-inbox-files-to-mobileorg-file ()
"Merges individual inbox files from different hosts and appends their content to the mobileorg.org file."
(let ((my-mobileorg-files `( ,(concat my-org-files-path "mobileorg-pixel4a.org")
,(concat my-org-files-path "mobileorg-dylan.org")))
(my-mobileorg-result-file (concat my-org-files-path "mobileorg.org")))
(find-file my-mobileorg-result-file) ;; open mobileorg.org
(goto-char (point-max)) ;; go to the end of the buffer (for appending content)
(dolist (file my-mobileorg-files) ;; loop over all input files and copy content to mobileorg.org
(when (file-regular-p file)
(insert-file-contents file)))
(save-buffer) ;; save all new changes to mobileorg.org
(kill-buffer) ;; close mobileorg.org buffer
(dolist (file my-mobileorg-files) ;; loop over all input files for deleting their content which already got moved to mobileorg.org above
(when (file-regular-p file)
(find-file file)
(delete-region (point-min) (point-max))
(save-buffer)
(kill-buffer)))))(defun my-mobile-org-import ()
"Imports mobile-org-data from mobile-org to inbox.org and openes inbox.org"
(interactive "P")
(my-merge-mobileorg-inbox-files-to-mobileorg-file) ;; Merges individual inbox files from different hosts and appends their content to the mobileorg.org file.
(org-mobile-pull)
(find-file (concat my-org-files-path "inbox.org"))
(delete-trailing-whitespace)
)(bind-key "i" (lambda ()
"""foobar"""
(interactive) (my-mobile-org-import)) my-map )Note that even though I use Orgzly to view Org-mode data on my Android phone, I use MobileOrg to capture. This might change in future, when I am able to choose whether or not single SyncThing folders gets synced on WiFi or on 4G networks (instead of all or nothing). Take a look at my feature wish report and the other issue I was referred to.
my-org-mobile-push() - pushing to org-mobile
The function generates misc files for MobileOrg.
(defun my-org-mobile-push (&optional arg)
(interactive)
;; when called with universal argument (C-u), Emacs will be closed
;; after pushing to files
;; save original agenda in temporary variable
(setq ORIGSAVED-org-agenda-custom-commands org-agenda-custom-commands)
;; set agenda for MobileOrg (omit some agenda
;; views I do not need on my phone):
(setq org-agenda-custom-commands
(quote (
("1" "1 month"
((agenda "1 month"
((org-agenda-ndays 31)
(org-agenda-time-grid nil)
(org-agenda-entry-types '(:timestamp :sexp))
)
)))
("B" "borrowed" tags "+borrowed"
(
(org-agenda-overriding-header "borrowed or lend")
(org-agenda-skip-function 'tag-without-done-or-canceled)
))
("$" "Besorgungen" tags "+Besorgung"
(
(org-agenda-overriding-header "Besorgungen")
(org-agenda-skip-function 'tag-without-done-or-canceled)
))
)))
;; generate MobileOrg export:
(org-mobile-push)
;; restore previously saved agenda:
(setq org-agenda-custom-commands
ORIGSAVED-org-agenda-custom-commands)
(if (equal arg '(4))
;; save buffers and exit emacs;; FIXXME: not working yet
(save-buffers-kill-terminal 't)
)
)MobileOrg push → my-map I
As of 2017-04, I moved from MobileOrg to Orgzly for mobile viewing data within my Org-mode data. Therefore, this function is not of any use any more:
(bind-key "I" #'my-org-mobile-push my-map)Refiling
- http://orgmode.org/manual/Capture-_002d-Refile-_002d-Archive.html
- http://orgmode.org/manual/Refile-and-copy.html#Refile-and-copy «When reviewing the captured data, you may want to refile or to copy some of the entries into a different list, for example into a project. Cutting, finding the right location, and then pasting the note is cumbersome.»
Targets include this file and any file contributing to the agenda - up to 5 levels deep
(setq org-refile-targets (quote (
;; ignore my-org-memacs-files here
(my-work-agenda-files :maxlevel . 4)
(my-nonwork-agenda-files :maxlevel . 4)
;;OLD: (nil :maxlevel . 3)
;;OLD: ("contacts.org" :maxlevel . 6)
)))
Targets start with the file name - allows creating level 1 tasks
(setq org-refile-use-outline-path (quote file))Activate caching of targets: (a must-have)
(setq org-refile-use-cache t)Targets complete directly with IDO: so much better!
(setq org-outline-path-complete-in-steps nil)Allow refile to create parent tasks with confirmation:
(setq org-refile-allow-creating-parent-nodes (quote confirm))Refiling to a specific heading stolen from this page:
(defun my-org-refile (file headline &optional arg)
(let ((pos (save-excursion
(find-file file)
(org-find-exact-headline-in-buffer headline))))
(org-refile arg nil (list headline file nil pos)))
(switch-to-buffer (current-buffer)))
;; example:
;; (my-org-refile "misc.org" "Off-site-backup")Attaching
(setq org-attach-use-inheritance t)
(setq org-attach-preferred-new-method 'dir)
(setq org-attach-archive-delete nil)As of 2019-12-08, org-attach-git does have an issue:
cd: No such directory found via CDPATH environment variableInvalid face reference: t
I did not invest much in finding the reason. So it’s disabled for now:
(require 'org-attach-git)org-attach-insert
| 2021-08-09 | Found this nugget on reddit |
(defun my-org-attach-insert (&optional in-emacs)
"Insert attachment from list."
(interactive "P")
(let ((attach-dir (org-attach-dir)))
(if attach-dir
(let* ((file (pcase (org-attach-file-list attach-dir)
(`(,file) file)
(files (completing-read "Insert attachment: "
(mapcar #'list files) nil t))))
(path (expand-file-name file attach-dir))
(desc (file-name-nondirectory path)))
(let ((initial-input
(cond
((not org-link-make-description-function) desc)
(t (condition-case nil
(funcall org-link-make-description-function link desc)
(error
(message "Can't get link description from %S"
(symbol-name org-link-make-description-function))
(sit-for 2)
nil))))))
(setq desc (if (called-interactively-p 'any)
(read-string "Description: " initial-input)
initial-input))
(org-insert-link nil path (concat "attachment:" desc))))
(error "No attachment directory exist"))))
;; (define-key org-mode-map (kbd "C-c o i") #'org-attach-insert)Archiving - preserve top level node and tags when archiving
preserving one level of heading + tags when archiving
| 2020-02-03 | disabled because I switched to org-archive-subtree-hierarchically() |
When I archive a heading (and its sub-headings), it gets moved from
foo.org to foo.org_archive. Following code does preserve at least
the top level node so that the archive file gets the rough structure
of the non-archive file.
http://orgmode.org/worg/org-hacks.html#sec-1-7-1
(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)))(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)))))preserving all heading levels when archiving
| 2020-02-03 | switching from my-org-inherited-no-file-tags() tp this |
Preserve the hierarchy when archiving: blog article, source code (GitHub gist)
(setq org-archive-default-command #'org-archive-subtree-hierarchically)
(defun org-archive-subtree-hierarchically (&optional prefix)
(interactive "P")
(let* ((fix-archive-p (and (not prefix)
(not (use-region-p))))
(afile (car (org-archive--compute-location
(or (org-entry-get nil "ARCHIVE" 'inherit) org-archive-location))))
(buffer (or (find-buffer-visiting afile) (find-file-noselect afile))))
(org-archive-subtree prefix)
(when fix-archive-p
(with-current-buffer buffer
(goto-char (point-max))
(while (org-up-heading-safe))
(let* ((olpath (org-entry-get (point) "ARCHIVE_OLPATH"))
(path (and olpath (split-string olpath "/")))
(level 1)
tree-text)
(when olpath
(org-mark-subtree)
(setq tree-text (buffer-substring (region-beginning) (region-end)))
(let (this-command (inhibit-message t)) (org-cut-subtree)) ; we don’t want to see "Cut subtree" messages
(goto-char (point-min))
(save-restriction
(widen)
(-each path
(lambda (heading)
(if (re-search-forward
(rx-to-string
`(: bol (repeat ,level "*") (1+ " ") ,heading)) nil t)
(org-narrow-to-subtree)
(goto-char (point-max))
(unless (looking-at "^")
(insert "\n"))
(insert (make-string level ?*)
" "
heading
"\n"))
(cl-incf level)))
(widen)
(org-end-of-subtree t t)
(org-paste-subtree level tree-text))))))))Searching, querying
helm-org
| 2019-12-17 | initial setup |
Completion package for Org mode: https://github.com/emacs-helm/helm-org
Used by: org-ql
(use-package helm-org
;;:defer 90
:ensure t
:config
(add-to-list 'helm-completing-read-handlers-alist '(org-capture . helm-org-completing-read-tags))
(add-to-list 'helm-completing-read-handlers-alist '(org-set-tags . helm-org-completing-read-tags))
)helm-org-rifle
| 2020-04-07 | setup for testing |
org-rifle is a swiss army knife for searching within Org mode files.
So far, I was using mostly sparse trees,
my-search-method-according-to-numlines() (isearch-forward and
swiper-isearch) and org-occur.
(use-package helm-org-rifle
:ensure t
:defer 110
:after org
; :bind (:map my-map ("SPC" . yankpad-insert))
)helm-org-agenda-files-headings: grep within headings → my-map H
This is a neat and fast way of looking for string only within heading lines:
(bind-key "H" #'helm-org-agenda-files-headings my-map)peg
| 2020-12-07 | switched to a manually downloaded version |
peg is required by org-ql (and was installed via ELPA as dependency)
but the most recent version I got via list-package was
20150708.641 which caused issues. So I had to set it up via manual
download:
(use-package peg
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/peg/")))
)org-ql
| 2019-12-17 | initial setup |
A powerful query language for Org mode: https://github.com/alphapapa/org-ql
Make sure that you install org-ql after you have installed
helm-org. Otherwise, it may be the case that you don’t get
helm-org-ql as this comment suggests and the README of org-ql
clearly states.
(use-package org-ql
:ensure t
:config
(require 'org-ql-search) ;; workaround for https://github.com/alphapapa/org-ql/issues/53
)FIXXME: Workaround in order to make helm-org-ql available according to https://github.com/alphapapa/org-ql/issues/129#issuecomment-667310696:
(require 'org-ql)
(require 'helm-org-ql)Links
I love customized links. I created a bunch of them in order to link certain kind of data.
Please note that my-business-... variables are not available to you for privacy reasons.
Do not use org-link-abbrev-alist for defining links that are handled via functions. Use org-link-set-parameters instead.
(setq org-link-abbrev-alist
`(
("bib" . "~/archive/library/%s.bib")
("cite" . ,(concat "file:" my-org-files-path "references.org::/%s/"))
; ("mynotes" . "file:~/org/references.org::%s")
; ("papers" . "~/archive/library/%s.pdf")
("photo" . "file:~/people/all_photographs/%s")
("notes" . "~/archive/library/%s-notes.pdf")
("contact" . ,(concat my-org-files-path "contacts.org::/\*.*%s/"))
; ("tsfile" . ,(concat my-org-files-path "memacs/files.org_archive::/\*.*%s/")) replaced by org-link-set-parameters() + my-handle-tsfile-link()
;; 2020-12-10 old: ("ifile" . ,(concat my-org-files-path "memacs/ifiles.org::/\*.*%s/"))
;;("mbox2001" . "file:~/archive/events_memories/backup_2002-06-23/2002-06-23/home/vk/Emails_from_approx_2000-07-01_to_2002-06-24.mbox::/\%s/")
;; 2020-12-10 old: ("postings2002" . "file:~/archive/usenet/memacs-archive/2002-03-13_to_2002-06-23_postings_Karl_Voit_usenet::%s")
;; 2020-12-10 old: ("postings2001" . "file:~/archive/usenet/memacs-archive/2000-07-06_to_2002-01-28_postings_Karl_Voit_usenet::%s")
;;("bank" . "file:~/institutions/easybank/Memacs-easybank-summary.csv::%s")
;;("ipd" . "https://r6portal-defects.infonova.com/browse/IPD-%s")
;;("IPD" . "https://r6portal-defects.infonova.com/browse/IPD-%s")
;;("tfs" . "http://grzd-tfs02:8080/tfs/DefaultCollection/Detego/_workitems?id=%s")
;;("TFS" . "http://grzd-tfs02:8080/tfs/DefaultCollection/Detego/_workitems?id=%s")
("EPA" . ,(concat my-business-jira-server "/EPA-%s"))
("EPAAFO" . ,(concat my-business-jira-server "/EPAAFO-%s"))
("JAFO" . ,(concat my-business-jira-server "/EPAAFO-0?jql=project%20%3D%20EPAAFO%20AND%20Afo-ID%20~%20%22%s%22"))
("EPARISE" . ,(concat my-business-sa-server "%s"))
("DAKEPA" . ,(concat my-business-jira-b-server "DAKEPA-%s"))
("EPABETR" . ,(concat my-business-jira-b-server "EPABETR-%s"))
("BMTSK" . ,(concat "file:" my-business-bmtsk-path "/"))
("IAFO" . ,(concat my-business-jira2-server "/GEMIDPANF-200?jql=project%20%3D%20GEMIDPANF%20AND%20Afo-ID%20~%20%22%s%22"))
("ISO" . ,(concat my-business-jira2-server "/ISO-%s"))
("ISMS" . ,(concat my-business-jira2-server "/ISMS-%s"))
("RB" . ,(concat my-business-jira2-server "/RB-%s"))
("GEMIDP" . ,(concat my-business-jira2-server "/GEMIDP-%s"))
("GEMIDPANF" . ,(concat my-business-jira2-server "/GEMIDPANF-%s"))
("IDP" . ,(concat my-business-sd-server "/IDP-%s"))
))I’ve got the PDF files of my archive only on these hosts:
(when (or (my-system-is-sting) (my-system-is-floyd))
(add-to-list 'org-link-abbrev-alist '("pdf" . "~/archive/library/%s.pdf"))
)Custom Link Completion
- http://draketo.de/light/english/free-software/custom-link-completion-org-mode-25-lines-emacs
- see Org-mode posting/answer 2012-08-20
(defun org-make-link (&rest strings)
"Concatenate STRINGS."
(apply 'concat strings))You might as well be interested in Pragmatic Emacs: Insert internal org-mode links the ivy way
Links to Outlook entities
Please do read my blog article that explains that those links get broken very easily.
- http://superuser.com/questions/71786/can-i-create-a-link-to-a-specific-email-message-in-outlook
- id:2016-05-03-outlook-links
(when (my-eval-if-binary-or-warn "outlook")
(org-add-link-type "outlook" 'org-outlook-open)
(defun org-outlook-open (id)
"Open the Outlook item identified by ID. ID should be an Outlook GUID."
;; 2017-03-02: following line stopped working with "org-outlook-open: ShellExecute failed: Access is denied."
;;(w32-shell-execute "open" (concat "outlook:" id))
;; fix:
(w32-shell-execute "open"
"C:/Program Files/Microsoft Office/Office16/OUTLOOK.EXE"
(concat "/select " "outlook:" id))
)
)gemSpec links
| 2020-12-08 | created |
This is business-related:
(defun my-gemAnbT_IDP-Dienst_ATV (afo)
(start-process "" nil "okular" my-gemAnbT_IDP-Dienst_ATV-pdf "--find" afo)
"")
(defun my-gemSpec_DS_Anbieter (afo)
(start-process "" nil "okular" my-gemSpec_DS_Anbieter-pdf "--find" afo)
"")
(defun my-gemSpec_Net (afo)
(start-process "" nil "okular" my-gemSpec_Net-pdf "--find" afo)
"")
(defun my-gemSpec_PKI (afo)
(start-process "" nil "okular" my-gemSpec_PKI-pdf "--find" afo)
"")
(defun my-gemSpec_IDP_Dienst (afo)
(start-process "" nil "okular" my-gemSpec_IDP_Dienst-pdf "--find" afo)
"")
(defun my-gemLB_FD_IDP (afo)
(start-process "" nil "okular" my-gemLB_FD_IDP-pdf "--find" afo)
"")
(defun my-gemRL_Betr_TI (afo)
(start-process "" nil "okular" my-gemRL_Betr_TI-pdf "--find" afo)
"")
(org-link-set-parameters "gemAnbT_IDP-Dienst_ATV"
:follow #'my-gemAnbT_IDP-Dienst_ATV)
(org-link-set-parameters "gemSpec_DS_Anbieter"
:follow #'my-gemSpec_DS_Anbieter)
(org-link-set-parameters "gemSpec_Net"
:follow #'my-gemSpec_Net)
(org-link-set-parameters "gemSpec_PKI"
:follow #'my-gemSpec_PKI)
(org-link-set-parameters "gemSpec_IDP_Dienst"
:follow #'my-gemSpec_IDP_Dienst)
(org-link-set-parameters "gemLB_FD_IDP"
:follow #'my-gemLB_FD_IDP)
(org-link-set-parameters "gemRL_Betr_TI"
:follow #'my-gemRL_Betr_TI)
;; do NOT use this for links handled by functions! This results in links "opened" on things like line modification, redrawing of screen, ...
;; NOT: (add-to-list 'org-link-abbrev-alist '("gemSpec_DS_Anbieter" . "%(my-gemSpec_DS_Anbieter)"))
;; NOT: (add-to-list 'org-link-abbrev-alist '("gemSpec_Net" . "%(my-gemSpec_Net)"))
;; NOT: (add-to-list 'org-link-abbrev-alist '("gemSpec_PKI" . "%(my-gemSpec_PKI)"))
;; NOT: (add-to-list 'org-link-abbrev-alist '("gemSpec_IDP_Dienst" . "%(my-gemSpec_IDP_Dienst)"))Reference management: link handling functions
Helper function string-replace (this withthat in)
(defun string-replace (this withthat in)
"replace THIS with WITHTHAT' in the string IN"
(with-temp-buffer
(insert in)
(goto-char (point-min))
(replace-string this withthat)
(buffer-substring (point-min) (point-max))))org-pdf-complete-link ()
(defun org-pdf-complete-link (&optional arg)
"Create a papers link using completion."
(let (file link)
(setq file (read-file-name "pdf: " "~/archive/library/"))
(let ((pwd (file-name-as-directory (expand-file-name ".")))
(pwd1 (file-name-as-directory (abbreviate-file-name
(expand-file-name ".")))))
(setq file (string-replace "~/archive/library/" "" file))
(setq file (string-replace pwd "" (string-replace pwd1 "" file)))
(setq file (string-replace ".bib" "" file))
(setq file (string-replace ".pdf" "" file))
(setq link (concat "pdf:" file)))
link))(defun org-ref-complete-link (&optional arg)
"Create a reference link using completion."
(let (file link)
(setq file (read-file-name "ref: " "~/archive/library/"))
(let ((pwd (file-name-as-directory (expand-file-name ".")))
(pwd1 (file-name-as-directory (abbreviate-file-name
(expand-file-name ".")))))
(setq file (string-replace "~/archive/library/" "" file))
(setq file (string-replace pwd "" (string-replace pwd1 "" file)))
(setq file (string-replace ".bib" "" file))
(setq file (string-replace ".pdf" "" file))
(setq link (concat "ref:" file)))
link))(defun org-photo-complete-link (&optional arg)
"Create a reference link using completion."
(let (file link)
(setq file (read-file-name "photo: " "~/people/all_photographs/"))
(let ((pwd (file-name-as-directory (expand-file-name ".")))
(pwd1 (file-name-as-directory (abbreviate-file-name
(expand-file-name ".")))))
(setq file (string-replace "~/people/all_photographs/" "" file))
(setq file (string-replace pwd "" (string-replace pwd1 "" file)))
;(setq file (string-replace ".jpg" "" file))
;(setq file (string-replace ".jpeg" "" file))
;(setq file (string-replace ".tiff" "" file))
(setq link (concat "photo:" file)))
link))- tries to format a new BibTeX entry according to own format
- from: http://www.mfasold.net/blog/2009/02/using-emacs-org-mode-to-draft-papers/
- However, does not work well enough
(my-load-local-el "contrib/format-bib.el")handling tsfile links (Memacs)
Defining memacs variables:
(defvar memacs-root (concat my-org-files-path "memacs/"))
(defvar memacs-file-pattern "files.org_archive") ;; also possible: "*.org"my-handle-tsfile-link (querystring)
- 2016-12-31 by John Kitchin
(defun my-handle-tsfile-link (querystring)
(message (concat "DEBUG1: querystring: " querystring))
(message (concat "DEBUG2: "
"grep \""
querystring
"\" "
(concat memacs-root memacs-file-pattern)))
;; get a list of hits
(let ((queryresults (split-string
(s-trim
(shell-command-to-string
(concat
"grep \""
querystring
"\" "
(concat memacs-root memacs-file-pattern))))
"\n" t)))
(message (concat "DEBUG3: queryresults: " (car queryresults)))
;; check length of list (number of lines)
(cond
((= 0 (length queryresults))
;; edge case: empty query result
(message "Sorry, no results found for query: %s" querystring))
(t
(with-temp-buffer
(insert (if (= 1 (length queryresults))
(car queryresults)
(completing-read "Choose: " queryresults)))
(org-mode)
(goto-char (point-min))
(org-next-link)
(org-open-at-point))))))Setting link parameters:
(org-link-set-parameters
"tsfile"
:follow (lambda (path) (my-handle-tsfile-link path))
:help-echo "Opens the linked file with your default application"
:face '(:foreground "DarkSeaGreen" :underline t)
)OLD code:
(defun my-handle-tsfile-link (querystring)
;; get a list of hits
(let ((queryresults (split-string (replace-regexp-in-string
"\r?\n$" ""
(shell-command-to-string
(concat "grep "
querystring
(concat memacs-root memacs-file-pattern))))
"\n")))
;; doesn't work because queryresults is not a string:
;; (message "%s" (concat "DEBUG: queryresults: " queryresults))
;; check length of list (number of lines)
(cond
((= 0 (length queryresults))
;; edge case: empty query result
(message "Sorry, empty querystring."))
;; I get «split-string: Wrong type argument: stringp, ("")»
((= 1 (length (split-string queryresults "\n")))
;; queryresults is unique
(with-temp-buffer
(insert queryresults)
(org-mode)
(org-element-map (org-element-parse-buffer) 'link
(lambda (ln)
(when (string= (org-element-property :type ln) "file")
(org-element-property :path ln)
(message "%s" (concat "DEBUG: file -> " ln))
)))))
;; I get the «File: » prompt but no completion:
(t
;; querystring results multiple matches
(org-open-file (completing-read
"File: "
(remove-if-not ;remove nils from list
'identity
(loop for queryresult in queryresults
collect
;; get the filename the match is in. assumes no : in the file name
(let* ((f (car (split-string queryresult ":")))
(basedir (file-name-directory f)))
(with-temp-buffer
(insert queryresult)
(org-mode)
(org-element-map (org-element-parse-buffer) 'link
(lambda (ln)
(when (string= (org-element-property :type ln) "file")
(expand-file-name (org-element-property :path ln) basedir))))))))))))))
links color (OLD)
Don’t know why I disabled this:
(require 's)
(defun color-comp (&optional arg)
"Completion function for color links."
(let ((color-data (prog2
(save-selected-window
(list-colors-display))
(with-current-buffer (get-buffer "*Colors*")
(mapcar (lambda (line)
(append (list line)
(s-split " " line t)))
(s-split "\n" (buffer-string))))
(kill-buffer "*Colors*"))))
(format "color:%s"
(s-trim (cadr (assoc (completing-read "Color: " color-data) color-data))))))
(defun color-link-face (path)
"Face function for color links."
(or (cdr (assoc path org-link-colors))
`(:foreground ,path)))
(defun color-link-export (path description backend)
"Export function for color links."
(cond
((eq backend 'html)
(let ((rgb (assoc (downcase path) color-name-rgb-alist))
r g b)
(setq r (* 255 (/ (nth 1 rgb) 65535.0))
g (* 255 (/ (nth 2 rgb) 65535.0))
b (* 255 (/ (nth 3 rgb) 65535.0)))
(format "<span style=\"color: rgb(%s,%s,%s)\">%s</span>"
(truncate r) (truncate g) (truncate b)
(or description path))))))
(org-link-set-parameters "color"
:face 'color-link-face
:complete 'color-comp
:export 'color-link-export)link colors
| 2021-01-11 | moved commands to my-set-linkcolors and defined 3 categories of colors |
- I got the idea from: https://www.reddit.com/r/emacs/comments/hywxef/visually_differentiate_between_links_to_files_and/
- possible values for faces: https://kitchingroup.cheme.cmu.edu/blog/2016/11/04/New-link-features-in-org-9/
- and
add-face-text-property: https://www.gnu.org/software/emacs/manual/html_node/elisp/Faces.html#Faces
- and
- Emacs colors: http://www.raebear.net/computers/emacs-colors/
- If you are interested in taking this any further: https://github.com/stardiviner/org-link-beautify
(setq my-linkcolor-org "wheat3")
(setq my-linkcolor-file "MediumSeaGreen")
(setq my-linkcolor-web "DeepSkyBlue")
(defun my-set-linkcolors ()
"Defines the colors of various link colors"
(interactive)
;; Org links --------------------------------------------------------------------------
(org-link-set-parameters "id" :face `(:foreground ,my-linkcolor-org :underline t))
(org-link-set-parameters "contact" :face `(:foreground ,my-linkcolor-org :underline t))
;; File links --------------------------------------------------------------------------
(org-link-set-parameters "file" :face `(:foreground ,my-linkcolor-file :underline t))
;; defined elsewhere;; (org-link-set-parameters "tsfile" :face '`(:foreground "DarkSeaGreen" :underline t))
(org-link-set-parameters "pdf" :face `(:foreground ,my-linkcolor-file :underline t))
(org-link-set-parameters "EPA" :face `(:foreground ,my-linkcolor-file :underline t))
(org-link-set-parameters "EPAAFO" :face `(:foreground ,my-linkcolor-file :underline t))
(org-link-set-parameters "JAFO" :face `(:foreground ,my-linkcolor-file :underline t))
(org-link-set-parameters "DAKEPA" :face `(:foreground ,my-linkcolor-file :underline t))
(org-link-set-parameters "BMTSK" :face `(:foreground ,my-linkcolor-file :underline t))
(org-link-set-parameters "ISO" :face `(:foreground ,my-linkcolor-file :underline t))
(org-link-set-parameters "gemSpec_DS_Anbieter"
:face `(:foreground ,my-linkcolor-file :underline t))
(org-link-set-parameters "gemSpec_Net"
:face `(:foreground ,my-linkcolor-file :underline t))
(org-link-set-parameters "gemSpec_PKI"
:face `(:foreground ,my-linkcolor-file :underline t))
(org-link-set-parameters "gemSpec_IDP_Dienst"
:face `(:foreground ,my-linkcolor-file :underline t))
(org-link-set-parameters "messageid"
:face `(:foreground ,my-linkcolor-file :underline t))
;; Web links --------------------------------------------------------------------------
(org-link-set-parameters "http" :face `(:foreground ,my-linkcolor-web :underline t))
(org-link-set-parameters "https" :face `(:foreground ,my-linkcolor-web :underline t))
)
(defun my-set-linkcolors ()
"Defines the colors of various link colors"
(interactive)
;; Org links --------------------------------------------------------------------------
(org-link-set-parameters "id" :face '(:foreground "wheat3" :underline t))
(org-link-set-parameters "contact" :face '(:foreground "wheat3" :underline t))
;; File links --------------------------------------------------------------------------
(org-link-set-parameters "file" :face '(:foreground "MediumSeaGreen" :underline t))
;; defined elsewhere;; (org-link-set-parameters "tsfile" :face ''(:foreground "DarkSeaGreen" :underline t))
(org-link-set-parameters "pdf" :face '(:foreground "MediumSeaGreen" :underline t))
(org-link-set-parameters "EPA" :face '(:foreground "MediumSeaGreen" :underline t))
(org-link-set-parameters "EPAAFO" :face '(:foreground "MediumSeaGreen" :underline t))
(org-link-set-parameters "JAFO" :face '(:foreground "MediumSeaGreen" :underline t))
(org-link-set-parameters "DAKEPA" :face '(:foreground "MediumSeaGreen" :underline t))
(org-link-set-parameters "BMTSK" :face '(:foreground "MediumSeaGreen" :underline t))
(org-link-set-parameters "gemSpec_DS_Anbieter"
:face '(:foreground "MediumSeaGreen" :underline t))
(org-link-set-parameters "gemSpec_Net"
:face '(:foreground "MediumSeaGreen" :underline t))
(org-link-set-parameters "gemSpec_PKI"
:face '(:foreground "MediumSeaGreen" :underline t))
(org-link-set-parameters "gemSpec_IDP_Dienst"
:face '(:foreground "MediumSeaGreen" :underline t))
(org-link-set-parameters "messageid"
:face '(:foreground "MediumSeaGreen" :underline t))
;; Web links --------------------------------------------------------------------------
(org-link-set-parameters "http" :face '(:foreground "DeepSkyBlue" :underline t))
(org-link-set-parameters "https" :face '(:foreground "DeepSkyBlue" :underline t))
)
(my-set-linkcolors) ;; set colors when loading- test links
- file: foo/bar.txt description
- tsfile: tsfile:foo/bar.txt description
- pdf: pdf:foo.pdf description
- http: http://Karl-Voit.at description
- https: https://Karl-Voit.at description
- id: id:foo-bar description
- contact: contact:example description
- message-id: Email link
- EPA: EPA:1234 description
- EPAAFO: EPAAFO:1234 description
- JAFO: JAFO:1234 description
- DAKEPA: DAKEPA:1234 description
- BMTSK: BMTSK:1234 description
- as of [2021-01-11 Mon] (before unifying color concept):
- Org links had: snow3
- File links: DarkSeaGreen, wheat2
- Web links: DeepSkyBlue
Open in external app
Found via reddit thread:
Add a type of link so that the emacs will open the linked file with the default external application (useful for media such as movies, pdfs, etc.)
- 2017-09-14: FIXXME: does not work on Windows:
Unable to start '~\path\to\2017-09-12 a file.pdf': The specified file was not found.- I guess that the backslashes have to be replaced by forward slashes for Windows/Cygwin
Alternative approach for Windows:
(w32-shell-execute "open"
"C:/Program Files (x86)/.../cygstart"
(concat " \"" path-to-media "\""))(defun my-open-ext (path-to-media)
(if (my-system-type-is-windows)
(shell-command (concat "cygstart \"" path-to-media "\""))
(shell-command (concat "open " \"" path-to-media \""))
)
)
(org-add-link-type "open" 'my-open-ext)org-super-links
| 2020-06-30 | initial setup for testing |
This reddit comment brought me this nice package: https://github.com/toshism/org-super-links
To my surprise, C-c s, the default prefix of this package, was not
defined in my setup yet. So I re-use it here.
Make sure that org-id-link-to-org-use-id is not nil when you want
to link using existing IDs instead of fragile links.
(use-package org-super-links
:quelpa (org-super-links :repo "toshism/org-super-links" :fetcher github :commit "develop")
:after helm-org
:bind (("C-c s s" . sl-link)
("C-c s l" . sl-store-link)
("C-c s C-l" . sl-insert-link) ;; inserts links to heading title (not property ID)
("C-c s d" . sl-quick-insert-drawer-link)
("C-c s i" . sl-quick-insert-inline-link))
:config
(setq sl-related-into-drawer t
sl-link-prefix 'sl-link-prefix-timestamp)
;; use my custom function to generate ID properties accordin to https://karl-voit.at/2019/11/16/UOMF-Linking-Headings/
(add-hook 'sl-pre-link-hook 'my-id-get-or-generate)
(add-hook 'sl-pre-backlink-hook 'my-id-get-or-generate)
;; Formats link descriptions as suggested on: https://github.com/toshism/org-super-links#limit-length-of-link-description
;; development: id:2020-08-05-implement-filter-function
(defun my-org-super-links-filter-description (link desc)
;; replace double bracket links with their description
(replace-regexp-in-string org-link-bracket-re "\\2"
;; removes: <2020-08-04 Tue>--<2020-08-04 Tue 23:37> (2nd time/date-stamp is optional; including inactive variants)
(replace-regexp-in-string org-element--timestamp-regexp ""
;; removes priority indicators such as [#A]
(replace-regexp-in-string org-priority-regexp ""
;; removes staistic cookies with absolute numbers such as [2/5]
(replace-regexp-in-string " ?\\[[0-9]+/[0-9]\\]" ""
;; removes staistic cookies with percentages such as [33%]
(replace-regexp-in-string " ?\\[[0-9]+%\\]" "" desc)
))))
)
(setq sl-default-description-formatter 'my-org-super-links-filter-description)
(setq sl-backlink-into-drawer "LINKS"
sl-related-into-drawer "LINKS") ;; according to https://github.com/toshism/org-super-links/issues/33#issuecomment-678815869
)Testing my-org-super-links-filter-description:
(mapcar (lambda (s)
(my-org-super-links-filter-description "foo bar" s))
'("<2020-08-04 Tue> [1/2] [66%] [#A] an example heading"
"[2020-08-04 Tue] [1/2] [66%] [#A] an example heading"
"<2020-08-04 Tue 23:07> [1/2] [66%] [#A] an example heading"
"<2020-08-04 Tue 23:07>-<2020-08-04 Tue> [66%] [#A] an example heading"
"<2020-08-04 Tue 23:07>-<2020-08-04 Tue> [2/3] [#A] an example heading"
"<2020-08-04 Tue 23:07>--<2020-08-04 Tue> [2/3] [#A] an example heading"
"[2020-08-04 Tue 23:07]--[2020-08-04 Tue] [2/3] [#A] an example heading"
"[#A] [2020-08-04 Tue 23:07]-<2020-08-04 Tue> [2/3] an example heading"
"<2020-08-05 Wed 19:09>--<2020-08-05 Wed> fixxme: dashes"
"<2020-08-05 Wed 19:09>-<2020-08-05 Wed> fixxme: dash"
)
)org-linker and org-linker-edna
| 2020-09-25 | initial setup for testing |
I asked the author of org-super-links with this feature request to extend org-super-links such that it can be used to define dependencies for org-edna. He denied for org-usper-links but implemented it as extra packages:
- extract heading selection interface stuff: org-linker
- org-edna interface that uses it: org-linker-edna
This is looking great from intial testing. I need to test it even further in my daily life to come to a conclusion.
My optimistic first approach was (again) with QUELPA:
(use-package org-linker
:quelpa (org-linker :repo "toshism/org-linker" :fetcher github)
)However, I still get errors using QUELPA:
Debugger entered--Lisp error: (error "Package ‘helm-org-ql-0’ is unavailable")
signal(error ("Package ‘helm-org-ql-0’ is unavailable"))
error("Package `%s-%s' is unavailable" helm-org-ql "0")
package-compute-transaction(nil ((org (0)) (helm-org-ql (0))))
package-install-from-buffer()
package-install-file("/home/vk/.emacs.d/quelpa/packages/org-linker-20200829.2118.el")
quelpa-package-install-file("/home/vk/.emacs.d/quelpa/packages/org-linker-20200829.2118.el")
quelpa-package-install((org-linker :repo "toshism/org-linker" :fetcher github))
apply(quelpa-package-install (org-linker :repo "toshism/org-linker" :fetcher github) nil)
quelpa((org-linker :repo "toshism/org-linker" :fetcher github))
apply(quelpa (org-linker :repo "toshism/org-linker" :fetcher github))
(if (and quelpa-use-package-inhibit-loading-quelpa (package-installed-p (quote org-linker))) nil (apply (quote quelpa) (quote ((org-linker :repo "toshism/org-linker" :fetcher github)))))
(progn (if (and quelpa-use-package-inhibit-loading-quelpa (package-installed-p (quote org-linker))) nil (apply (quote quelpa) (quote ((org-linker :repo "toshism/org-linker" :fetcher github))))) (defvar use-package--warning297 (function (lambda (keyword err) (let ((msg (format "%s/%s: %s" ... keyword ...))) (display-warning (quote use-package) msg :error))))) (condition-case err (if (not (require (quote org-linker) nil t)) (display-warning (quote use-package) (format "Cannot load %s" (quote org-linker)) :error)) ((debug error) (funcall use-package--warning297 :catch err))))
eval((progn (if (and quelpa-use-package-inhibit-loading-quelpa (package-installed-p (quote org-linker))) nil (apply (quote quelpa) (quote ((org-linker :repo "toshism/org-linker" :fetcher github))))) (defvar use-package--warning297 (function (lambda (keyword err) (let ((msg ...)) (display-warning (quote use-package) msg :error))))) (condition-case err (if (not (require (quote org-linker) nil t)) (display-warning (quote use-package) (format "Cannot load %s" (quote org-linker)) :error)) ((debug error) (funcall use-package--warning297 :catch err)))) nil)
elisp--eval-last-sexp(nil)
eval-last-sexp(nil)
funcall-interactively(eval-last-sexp nil)
call-interactively(eval-last-sexp nil nil)
command-execute(eval-last-sexp)
Maybe I’m to stupid to use QUELPA. :-( I had to manually clone it and install via:
(use-package org-linker
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/org-linker/")))
)(use-package org-linker-edna
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/org-linker-edna/")))
:bind (("C-c s e" . org-linker-edna))
:config
(setq link-id-function 'my-id-get-or-generate) ;; use my ID generation function instead of UUIDs: https://github.com/toshism/org-linker-edna/issues/3#issuecomment-703815638
)Agenda
Org-mode is my digital everything. And therefore, Org is also my calendar which is called “agenda” in Org-mode speak. I see my todos (scheduled), my appointments and all date- & time-stamps on it.
But it gets even more crazy with Memacs: https://github.com/novoid/Memacs/ With Memacs, I get email, text messages, phone calls, downloaded files, visited web pages, Git commits, photos, and so forth on my agenda. This is really cool.
Irreal wrote a blog article about a nice Agenda demo. I’m using almost all features explained (except column mode, effort, clocking).
Agenda files
I maintain two categories of agenda files: work and non-work files which are defined for Windows and non-windows separately (path format differs).
Using my-toggle-agenda-files() I can toggle between host-specific
default agenda and all agenda files.
Definition of work files: (only used in cron-job shell script)
(setq my-work-agenda-files (append `(
;; 2019-06-26: backtick above and ,() below are because of: https://stackoverflow.com/questions/9449364/elisp-alist-and-strings-type-confusion
;; the (quote (("foo/bar.pro")) from before had to be changed when introducing the concat method for the path
,(concat my-org-files-path "rise.org")
;;,(concat my-org-files-path "detego.org")
;;,(concat my-org-files-path "ciso.org")
;;,(concat my-org-files-path "exported-detego-calendar.org")
;;,(concat my-org-files-path "r6-stories.org")
;;,(concat my-org-files-path "infonova.org")
)))The following file is only accessible on my work computer:
(when (my-system-is-rise)
(add-to-list 'my-work-agenda-files my-business-siko-notes))Definitions of non-work files: (only used in cron-job shell script)
(setq my-nonwork-agenda-files (append ` (
,(concat my-org-files-path "misc.org")
,(concat my-org-files-path "issues.org")
,(concat my-org-files-path "projects.org")
,(concat my-org-files-path "finanzen_behoerden_versicherungen.org")
,(concat my-org-files-path "bwg.org")
,(concat my-org-files-path "contacts.org")
;;,(concat my-org-files-path "foodandbeverages.org")
,(concat my-org-files-path "hardware.org")
,(concat my-org-files-path "tugraz.org")
,(concat my-org-files-path "fhsp.org")
,(concat my-org-files-path "notes.org")
,(concat my-org-files-path "public_voit.org")
,(concat my-org-files-path "errors.org")
,(concat my-org-files-path "errors_public_voit.org")
;;,(concat my-org-files-path "movies.org")
;;,(concat my-org-files-path "references.org")
;;"c:/Users/karl.voit/src/lazyblorg/lazyblorg.org")
;;,(concat my-org-files-path "memacs/error.org")
;;,(concat my-org-files-path "memacs/git.org")
;;,(concat my-org-files-path "memacs/ifiles.org")
;;,(concat my-org-files-path "memacs/phonecalls.org")
;;,(concat my-org-files-path "memacs/roylog.org")
;;,(concat my-org-files-path "memacs/SMS.org")
)))2021-01-03: Instead of my previous complex org-agenda setup with work and non-work agenda files and the ability to toggle them, I moved to a simplified setup. Reason: I don’t use the toggle-feature and I want to be able to refresh the super-agenda (which was not possible in my complex setup: refreshed agenda was not org-super-agenda but normal agenda).
(setq org-agenda-files (append my-work-agenda-files my-nonwork-agenda-files))OLD:
my-toggle-agenda-files() toggles between work/everything and nonwork/everything:
Default agenda files: on my business host, start with the work-related files; on my other machines, start with my non-work-related files.
my-toggle-agenda-files() → my-map A
| 2021-01-03 | disabled: I want to test and switch to standard org-super-agenda setup |
(defun my-toggle-agenda-files ()
"Toggle my agenda files between work/everything and nonwork/everything
depending on the current system.
Source for the toggle code: `http://ergoemacs.org/emacs/elisp_toggle_command.html'"
(interactive)
;; use a property “state”. Value is t or nil
(if (get 'my-toggle-agenda-files 'state)
(progn
(message "Agenda files: host-specific")
(if (string-equal system-name "GRZN17009")
(setq org-agenda-files (append my-work-agenda-files ))
(setq org-agenda-files (append my-nonwork-agenda-files ))
)
(put 'my-toggle-agenda-files 'state nil))
(progn
(message "Agenda files: all")
(setq org-agenda-files (append my-work-agenda-files my-nonwork-agenda-files))
(put 'my-toggle-agenda-files 'state t))))
(bind-key "A" 'my-toggle-agenda-files my-map)
(setq org-agenda-files (append my-work-agenda-files my-nonwork-agenda-files))
;; separate agenda files for work/nonwork: ;; (if (my-system-type-is-windows)
;; separate agenda files for work/nonwork: ;; (setq org-agenda-files (append my-work-agenda-files my-nonwork-agenda-files))
;; separate agenda files for work/nonwork: ;; (setq org-agenda-files (append my-nonwork-agenda-files ))
;; separate agenda files for work/nonwork: ;; )Misc agenda helper functions
my-skip-tag(tag)
From: Memnon Anon <gegendosenfleisch@googlemail.com> Newsgroups: gmane.emacs.orgmode Subject: Re: Exclude tag from custom agenda Date: Sun, 9 Dec 2012 15:59:48 +0000 (UTC) Message-ID: <871uezql9d.fsf@mean.albasani.net> Based on http://article.gmane.org/gmane.emacs.orgmode/41427
(defun my-skip-tag(tag)
"Skip entries that are tagged TAG"
(let* ((entry-tags (org-get-tags-at (point))))
(if (member tag entry-tags)
(progn (outline-next-heading) (point))
nil)))tag-without-done-or-canceled()
2012-12-09 From: Memnon Anon <gegendosenfleisch@googlemail.com> To: news1142@Karl-Voit.at Subject: Re: Custom agenda: search by tag and exclude DONE items
(defun tag-without-done-or-canceled ()
"Show items with tag \"borrowed\" that are neither in \"DONE\" or \"CANCELED \" state."
(let ((state (org-entry-get (point) "TODO")))
(if (and (member "borrowed" (org-get-tags-at (point)))
(not (string= state "DONE"))
(not (string= state "CANCELED")))
nil ; do not skip
(line-end-position)))) ; skipMISC functions from Bernt Hansen’s famous http://doc.norang.ca/org-mode.html
(defun bh/is-project-p ()
"Any task with a todo keyword subtask"
(let ((has-subtask)
(subtree-end (save-excursion (org-end-of-subtree t))))
(save-excursion
(forward-line 1)
(while (and (not has-subtask)
(< (point) subtree-end)
(re-search-forward "^\*+ " subtree-end t))
(when (member (org-get-todo-state) org-todo-keywords-1)
(setq has-subtask t))))
has-subtask))
(defun bh/skip-non-stuck-projects ()
"Skip trees that are not stuck projects"
(let* ((subtree-end (save-excursion (org-end-of-subtree t)))
(has-next (save-excursion
(forward-line 1)
(and (< (point) subtree-end)
(re-search-forward "^\\*+ \\(NEXT\\|STARTED\\) " subtree-end t)))))
(if (and (bh/is-project-p) (not has-next))
nil ; a stuck project, has subtasks but no next task
subtree-end)))
(defun bh/skip-non-projects ()
"Skip trees that are not projects"
(let* ((subtree-end (save-excursion (org-end-of-subtree t))))
(if (bh/is-project-p)
nil
subtree-end)))
(defun bh/skip-projects ()
"Skip trees that are projects"
(let* ((subtree-end (save-excursion (org-end-of-subtree t))))
(if (bh/is-project-p)
subtree-end
nil)))
(defun bh/skip-non-archivable-tasks ()
"Skip trees that are not available for archiving"
(let* ((subtree-end (save-excursion (org-end-of-subtree t)))
(daynr (string-to-int (format-time-string "%d" (current-time))))
(a-month-ago (* 60 60 24 (+ daynr 1)))
(last-month (format-time-string "%Y-%m-" (time-subtract (current-time) (seconds-to-time a-month-ago))))
(this-month (format-time-string "%Y-%m-" (current-time)))
(subtree-is-current (save-excursion
(forward-line 1)
(and (< (point) subtree-end)
(re-search-forward (concat last-month "\\|" this-month) subtree-end t)))))
(if subtree-is-current
subtree-end ; Has a date in this month or last month, skip it
;; Make sure the ARCHIVE property is set for this task
;; Create one at the parent task if necessary
(save-excursion
(save-restriction
(widen)
(let ((archive-prop (org-entry-get nil "ARCHIVE" 'inherit))
(parent-task))
(org-up-heading-safe)
(setq parent-task (nth 4 (org-heading-components)))
(unless archive-prop
(setq archive-prop (org-entry-put nil "ARCHIVE" (concat "%s_archive::* " parent-task)))))))
nil)))
(defmacro bh/agenda-sort-test (fn a b)
"Test for agenda sort"
`(cond
;; if both match leave them unsorted
((and (apply ,fn (list ,a))
(apply ,fn (list ,b)))
(setq result nil))
;; if a matches put a first
((apply ,fn (list ,a))
;; if b also matches leave unsorted
(if (apply ,fn (list ,b))
(setq result nil)
(setq result -1)))
;; otherwise if b matches put b first
((apply ,fn (list ,b))
(setq result 1))
;; if none match leave them unsorted
(t nil)))
(defmacro bh/agenda-sort-test-num (fn compfn a b)
`(cond
((apply ,fn (list ,a))
(setq num-a (string-to-number (match-string 1 ,a)))
(if (apply ,fn (list ,b))
(progn
(setq num-b (string-to-number (match-string 1 ,b)))
(setq result (if (apply ,compfn (list num-a num-b))
-1
1)))
(setq result -1)))
((apply ,fn (list ,b))
(setq result 1))
(t nil)))
(defun bh/is-not-scheduled-or-deadline (date-str)
(and (not (bh/is-deadline date-str))
(not (bh/is-scheduled date-str))))
(defun bh/is-due-deadline (date-str)
(string-match "Deadline:" date-str))
(defun bh/is-late-deadline (date-str)
(string-match "In *\\(-.*\\)d\.:" date-str))
(defun bh/is-pending-deadline (date-str)
(string-match "In \\([^-]*\\)d\.:" date-str))
(defun bh/is-deadline (date-str)
(or (bh/is-due-deadline date-str)
(bh/is-late-deadline date-str)
(bh/is-pending-deadline date-str)))
(defun bh/is-scheduled (date-str)
(or (bh/is-scheduled-today date-str)
(bh/is-scheduled-late date-str)))
(defun bh/is-scheduled-today (date-str)
(string-match "Scheduled:" date-str))
(defun bh/is-scheduled-late (date-str)
(string-match "Sched\.\\(.*\\)x:" date-str))
(defun bh/agenda-sort (a b)
"Sorting strategy for agenda items.
Late deadlines first, then scheduled, then non-late deadlines"
(let (result num-a num-b)
(cond
;; time specific items are already sorted first by org-agenda-sorting-strategy
;; non-deadline and non-scheduled items next
((bh/agenda-sort-test 'bh/is-not-scheduled-or-deadline a b))
;; late deadlines next
((bh/agenda-sort-test-num 'bh/is-late-deadline '< a b))
;; late scheduled items next
;; ((bh/agenda-sort-test-num 'bh/is-scheduled-late '> a b))
;; deadlines for today next
((bh/agenda-sort-test 'bh/is-due-deadline a b))
;; scheduled items for today next
((bh/agenda-sort-test 'bh/is-scheduled-today a b))
;; late deadlines next
;; ((bh/agenda-sort-test-num 'bh/is-late-deadline '< a b))
;; late scheduled items next
((bh/agenda-sort-test-num 'bh/is-scheduled-late '> a b))
;; pending deadlines last
((bh/agenda-sort-test-num 'bh/is-pending-deadline '< a b))
;; finally default to unsorted
(t (setq result nil)))
result))
Removes things tagged with “lp” or “reward” when typing “/ RET” in agenda
From: http://doc.norang.ca/org-mode.html#CustomAgendaViewFilteringContext Also: http://orgmode.org/manual/Filtering_002flimiting-agenda-items.html
(defun bh/org-auto-exclude-function-private (tag)
"Automatic task exclusion in the agenda with / RET"
(and (cond
((string= tag "lp") t)
((string= tag "reward") t)
((string= tag "test") t)
((string= tag "2read") t)
)
(concat "-" tag)))For business, I use a different setup:
(defun bh/org-auto-exclude-function-infonova (tag)
"Automatic task exclusion in the agenda with / RET"
(and (cond
((string= tag "lp") t)
((string= tag "reward") t)
((string= tag "test") t)
((string= tag "@BWG") t)
((string= tag "blog") t)
((string= tag "2read") t)
)
(concat "-" tag)))
(if (my-system-type-is-windows)
(setq org-agenda-auto-exclude-function 'bh/org-auto-exclude-function-infonova)
(setq org-agenda-auto-exclude-function 'bh/org-auto-exclude-function-private)
)my-narrow-agenda()
(defun my-narrow-agenda ()
(interactive "P")
; (org-agenda-filter-apply "-\(WAITING\|:reward:\|:lp:\)" 'regexp)
(org-agenda-filter-apply "-NEXT.*:\\(@BWG\\|reward\\):" 'regexp)
;; returns: wrong number of arguments
; (setq current-prefix-arg '(4)) ; C-u
; (org-agenda-filter-by-regexp "\(WAITING\|:reward:\|:lp:\)")
;; (org-agenda-filter-by-regexp '(4) "WAITING")
;; NEXT.*:\(@BWG\|reward\): -> keyword "NEXT" with either tag "@BWG" OR "reward"
)my-super-agenda()
| 2021-01-03 | disabled: I want to test and switch to standard org-super-agenda setup |
Supercharge your Org daily/weekly agenda by grouping items
See also: id:2017-08-12-org-super-agenda
Loading the code:
(use-package org-super-agenda
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/org-super-agenda/")))
)Definition of my-super-agenda-groups, my central configuration of super-agenda:
Original version (before testing the next one):
(setq my-super-agenda-groups
'(;; Each group has an implicit boolean OR operator between its selectors.
(:name "Today" ; Optionally specify section name
:time-grid t ; Items that appear on the time grid
)
(:name "DEADLINES" :deadline t :order 1)
(:name "Focus" :tag "Focus" :order 2 :face (:append t :weight bold))
(:name "Important" :priority "A" :order 4)
(:priority<= "B"
;; Show this section after "Today" and "Important", because
;; their order is unspecified, defaulting to 0. Sections
;; are displayed lowest-number-first.
:order 6)
; (:name "Habits" :habit t :order 3)
(:name "Shopping" :tag "Besorgung" :order 8)
;; Boolean AND group matches items that match all subgroups
;; :and (:tag "shopping" :tag "@town")
;; Multiple args given in list with implicit OR
;; :tag ("food" "dinner"))
;; :habit t
;; :tag "personal")
(:name "Started" :todo "STARTED" :order 10)
;;(:name "Space-related (non-moon-or-planet-related)"
;; ;; Regexps match case-insensitively on the entire entry
;; :and (:regexp ("space" "NASA")
;; ;; Boolean NOT also has implicit OR between selectors
;; :not (:regexp "moon" :tag "planet")))
(:name "BWG" :tag "@BWG" :order 16)
(:todo "WAITING" :order 18) ; Set order of this section
(:name "read" :tag "2read" :order 22)
;; Groups supply their own section names when none are given
(:todo ("SOMEDAY" "WATCHING")
;; Show this group at the end of the agenda (since it has the
;; highest number). If you specified this group last, items
;; with these todo keywords that e.g. have priority A would be
;; displayed in that group instead, because items are grouped
;; out in the order the groups are listed.
:order 25)
(:name "reward"
:tag ("reward" "lp")
:order 100
)
;; After the last group, the agenda will display items that didn't
;; match any of these groups, with the default order position of 99
)
)Test version (not working yet):
(setq my-super-agenda-groups
'(;; Each group has an implicit boolean OR operator between its selectors.
(:name "Today" ; Optionally specify section name
:time-grid t ; Items that appear on the time grid
)
(:name "r DEADLINES" :tag "rise" :deadline t :order 1)
(:name "r Focus" :and (:tag "focus" :tag "rise") :order 2 :face (:append t :weight bold))
(:name "r Important" :and (:tag "rise" :priority "A") :order 4)
(:priority<= "B"
;; Show this section after "Today" and "Important", because
;; their order is unspecified, defaulting to 0. Sections
;; are displayed lowest-number-first.
:tag "rise" :order 6)
;;(:name "r Shopping" :tag ("Besorgung" "rise") :order 8)
;; Boolean AND group matches items that match all subgroups
;; :and (:tag "shopping" :tag "@town")
;; Multiple args given in list with implicit OR
;; :tag ("food" "dinner"))
;; :habit t
;; :tag "personal")
(:name "r Started" :and (:tag "rise" :todo "STARTED") :order 10)
;;(:name "Space-related (non-moon-or-planet-related)"
;; ;; Regexps match case-insensitively on the entire entry
;; :and (:regexp ("space" "NASA")
;; ;; Boolean NOT also has implicit OR between selectors
;; :not (:regexp "moon" :tag "planet")))
;;(:name "BWG" :tag "@BWG" :order 16)
(:todo "r WAITING" :tag "rise" :order 18) ; Set order of this section
;;(:name "read" :tag "2read" :order 22)
;; Groups supply their own section names when none are given
(:todo ("SOMEDAY" "WATCHING")
;; Show this group at the end of the agenda (since it has the
;; highest number). If you specified this group last, items
;; with these todo keywords that e.g. have priority A would be
;; displayed in that group instead, because items are grouped
;; out in the order the groups are listed.
:tag "rise" :order 25)
(:name "r reward"
:and (:tag "rise" :tag ("reward" "lp"))
:order 30
)
(:name "r Habits" :tag "rise" :habit t :order 33)
;; ======= Private: =================================================
(:name "DEADLINES" :and (:not (:tag "rise") :deadline t) :order 50)
(:name "Focus" :and (:not (:tag "rise") :tag "focus") :order 52 :face (:append t :weight bold))
(:name "Important" :and (:not (:tag "rise") :priority "A") :order 54)
(:and (:priority<= "B"
;; Show this section after "Today" and "Important", because
;; their order is unspecified, defaulting to 0. Sections
;; are displayed lowest-number-first.
:not (:tag "rise")) :order 56)
;;(:name "Habits" :habit t :order 53)
(:name "Shopping" :and (:not (:tag "rise") :tag "Besorgung") :order 58)
;; Boolean AND group matches items that match all subgroups
;; :and (:tag "shopping" :tag "@town")
;; Multiple args given in list with implicit OR
;; :tag ("food" "dinner"))
;; :habit t
;; :tag "personal")
(:name "Started" :and (:not (:tag "rise") :todo "STARTED") :order 60)
;;(:name "Space-related (non-moon-or-planet-related)"
;; ;; Regexps match case-insensitively on the entire entry
;; :and (:regexp ("space" "NASA")
;; ;; Boolean NOT also has implicit OR between selectors
;; :not (:regexp "moon" :tag "planet")))
(:name "BWG" :and (:not (:tag "rise") :tag "@BWG") :order 66)
(:and (:todo "WAITING" :not (:tag "rise")) :order 68) ; Set order of this section
(:name "read" :and (:not (:tag "rise") :tag "2read") :order 72)
;; Groups supply their own section names when none are given
(:and (:todo ("SOMEDAY" "WATCHING")
;; Show this group at the end of the agenda (since it has the
;; highest number). If you specified this group last, items
;; with these todo keywords that e.g. have priority A would be
;; displayed in that group instead, because items are grouped
;; out in the order the groups are listed.
:not (:tag "rise")) :order 75)
(:name "reward"
:and (:not (:tag "rise") :tag ("reward" "lp"))
:order 80
)
;; After the last group, the agenda will display items that didn't
;; match any of these groups, with the default order position of 99
)
)my-super-agenda() is a function so that I am able to call the agenda
interactively or within my-org-agenda() which is defined further
down below.
(defun my-super-agenda()
"generates my super-agenda"
(interactive)
(org-super-agenda-mode)
(let
((org-super-agenda-groups my-super-agenda-groups))
(org-agenda nil "a")
)
)super-agenda()
| 2021-01-03 | new, standard org-super-agenda setup instead of old, complex setup |
Supercharge your Org daily/weekly agenda by grouping items
See also: id:2017-08-12-org-super-agenda
(use-package org-super-agenda
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/org-super-agenda/")))
:ensure t
;; :hook (org-agenda-mode . org-super-agenda-mode)
:config
(org-super-agenda-mode)
(setq super-agenda-groups
'(;; Each group has an implicit boolean OR operator between its selectors.
(:name "Today" ; Optionally specify section name
:time-grid t ; Items that appear on the time grid
)
(:name "DEADLINES" :deadline t :order 1)
(:name "Focus" :tag "Focus" :order 2 :face (:append t :weight bold))
(:name "Important" :priority "A" :order 4)
; (:name "Habits" :habit t :order 3)
(:name "Shopping" :tag "Besorgung" :order 8)
;; Boolean AND group matches items that match all subgroups
;; :and (:tag "shopping" :tag "@town")
;; Multiple args given in list with implicit OR
;; :tag ("food" "dinner"))
;; :habit t
;; :tag "personal")
(:name "Started" :todo "STARTED" :order 10)
;;(:name "Space-related (non-moon-or-planet-related)"
;; ;; Regexps match case-insensitively on the entire entry
;; :and (:regexp ("space" "NASA")
;; ;; Boolean NOT also has implicit OR between selectors
;; :not (:regexp "moon" :tag "planet")))
;;(:name "BWG" :tag "@BWG" :order 16)
(:name "read" :tag "2read" :order 22)
;; Groups supply their own section names when none are given
(:todo ("SOMEDAY" "WATCHING")
;; Show this group at the end of the agenda (since it has the
;; highest number). If you specified this group last, items
;; with these todo keywords that e.g. have priority A would be
;; displayed in that group instead, because items are grouped
;; out in the order the groups are listed.
:order 25)
;; "other items": an auto-group with order 99 ----------------------------
(:priority<= "B"
;; Show this section after "Today" and "Important", because
;; their order is unspecified, defaulting to 0. Sections
;; are displayed lowest-number-first.
:order 105)
(:name "reward"
:tag ("reward" "lp")
:order 110
)
(:todo "WAITING" :order 118) ; Set order of this section
;; After the last group, the agenda will display items that didn't
;; match any of these groups, with the default order position of 99
))
);; end of org-super-agendaTest version (not working yet):
(setq my-super-agenda-groups
'(;; Each group has an implicit boolean OR operator between its selectors.
(:name "Today" ; Optionally specify section name
:time-grid t ; Items that appear on the time grid
)
(:name "r DEADLINES" :tag "rise" :deadline t :order 1)
(:name "r Focus" :and (:tag "focus" :tag "rise") :order 2 :face (:append t :weight bold))
(:name "r Important" :and (:tag "rise" :priority "A") :order 4)
(:priority<= "B"
;; Show this section after "Today" and "Important", because
;; their order is unspecified, defaulting to 0. Sections
;; are displayed lowest-number-first.
:tag "rise" :order 6)
;;(:name "r Shopping" :tag ("Besorgung" "rise") :order 8)
;; Boolean AND group matches items that match all subgroups
;; :and (:tag "shopping" :tag "@town")
;; Multiple args given in list with implicit OR
;; :tag ("food" "dinner"))
;; :habit t
;; :tag "personal")
(:name "r Started" :and (:tag "rise" :todo "STARTED") :order 10)
;;(:name "Space-related (non-moon-or-planet-related)"
;; ;; Regexps match case-insensitively on the entire entry
;; :and (:regexp ("space" "NASA")
;; ;; Boolean NOT also has implicit OR between selectors
;; :not (:regexp "moon" :tag "planet")))
;;(:name "BWG" :tag "@BWG" :order 16)
(:todo "r WAITING" :tag "rise" :order 18) ; Set order of this section
;;(:name "read" :tag "2read" :order 22)
;; Groups supply their own section names when none are given
(:todo ("SOMEDAY" "WATCHING")
;; Show this group at the end of the agenda (since it has the
;; highest number). If you specified this group last, items
;; with these todo keywords that e.g. have priority A would be
;; displayed in that group instead, because items are grouped
;; out in the order the groups are listed.
:tag "rise" :order 25)
(:name "r reward"
:and (:tag "rise" :tag ("reward" "lp"))
:order 30
)
(:name "r Habits" :tag "rise" :habit t :order 33)
;; ======= Private: =================================================
(:name "DEADLINES" :and (:not (:tag "rise") :deadline t) :order 50)
(:name "Focus" :and (:not (:tag "rise") :tag "focus") :order 52 :face (:append t :weight bold))
(:name "Important" :and (:not (:tag "rise") :priority "A") :order 54)
(:and (:priority<= "B"
;; Show this section after "Today" and "Important", because
;; their order is unspecified, defaulting to 0. Sections
;; are displayed lowest-number-first.
:not (:tag "rise")) :order 56)
;;(:name "Habits" :habit t :order 53)
(:name "Shopping" :and (:not (:tag "rise") :tag "Besorgung") :order 58)
;; Boolean AND group matches items that match all subgroups
;; :and (:tag "shopping" :tag "@town")
;; Multiple args given in list with implicit OR
;; :tag ("food" "dinner"))
;; :habit t
;; :tag "personal")
(:name "Started" :and (:not (:tag "rise") :todo "STARTED") :order 60)
;;(:name "Space-related (non-moon-or-planet-related)"
;; ;; Regexps match case-insensitively on the entire entry
;; :and (:regexp ("space" "NASA")
;; ;; Boolean NOT also has implicit OR between selectors
;; :not (:regexp "moon" :tag "planet")))
(:name "BWG" :and (:not (:tag "rise") :tag "@BWG") :order 66)
(:and (:todo "WAITING" :not (:tag "rise")) :order 68) ; Set order of this section
(:name "read" :and (:not (:tag "rise") :tag "2read") :order 72)
;; Groups supply their own section names when none are given
(:and (:todo ("SOMEDAY" "WATCHING")
;; Show this group at the end of the agenda (since it has the
;; highest number). If you specified this group last, items
;; with these todo keywords that e.g. have priority A would be
;; displayed in that group instead, because items are grouped
;; out in the order the groups are listed.
:not (:tag "rise")) :order 75)
(:name "reward"
:and (:not (:tag "rise") :tag ("reward" "lp"))
:order 80
)
;; After the last group, the agenda will display items that didn't
;; match any of these groups, with the default order position of 99
)
)my-super-agenda() is a function so that I am able to call the agenda
interactively or within my-org-agenda() which is defined further
down below.
2021-01-03: disabled (not needed when simplified org-super-agenda is applied to any agenda)
(defun my-super-agenda()
"generates my super-agenda"
(interactive)
(org-super-agenda-mode)
(let
((org-super-agenda-groups super-agenda-groups))
(org-agenda nil "a")
)
)my-super-agenda-business()
| 2021-01-03 | disabled: I want to test and switch to standard org-super-agenda setup |
Same as my-super-agenda but with much stricter filters so that I
only see important business stuff.
(setq my-super-agenda-important-business-only-groups
'(;; Each group has an implicit boolean OR operator between its selectors.
(:name "Today" ; Optionally specify section name
:time-grid t ; Items that appear on the time grid
)
(:name "DEADLINES" :order 1
:and (:deadline t :not (:tag ("reward" "@BWG"))))
(:name "Important" :order 2
:and (:priority "A" :not (:tag ("reward" "@BWG"))))
;;(:name "Habits" :habit t :order 3 :and (:not (:tag ("reward" "@BWG"))))
(:name "Shopping" :order 4
:and (:tag "Besorgung" :not (:tag ("reward" "@BWG"))))
;; Boolean AND group matches items that match all subgroups
;; :and (:tag "shopping" :tag "@town")
;; Multiple args given in list with implicit OR
;; :tag ("food" "dinner"))
;; :habit t
;; :tag "personal")
(:name "Started" :order 6
:and (:todo "STARTED" :not (:tag ("reward" "@BWG"))))
;;(:name "Space-related (non-moon-or-planet-related)"
;; ;; Regexps match case-insensitively on the entire entry
;; :and (:regexp ("space" "NASA")
;; ;; Boolean NOT also has implicit OR between selectors
;; :not (:regexp "moon" :tag "planet")))
;;(:name "BWG" :tag "@BWG" :order 7)
(:name "Low Prio"
;; Show this section after "Today" and "Important", because
;; their order is unspecified, defaulting to 0. Sections
;; are displayed lowest-number-first.
:and (:priority<= "B" :not (:tag ("reward" "@BWG")))
:order 7)
(:name "WAITING" :order 9
:and (:todo "WAITING" :not (:tag ("reward" "@BWG")))) ; Set order of this section
(:name "2read" :order 15
:and (:tag "2read" :not (:tag ("reward" "@BWG"))))
(:name "Other (Business)" :order 20
:and (:category ("rise") :not (:tag ("reward" "@BWG"))))
;; Groups supply their own section names when none are given
(:name "SOMEDAY or WATCHING"
;; Show this group at the end of the agenda (since it has the
;; highest number). If you specified this group last, items
;; with these todo keywords that e.g. have priority A would be
;; displayed in that group instead, because items are grouped
;; out in the order the groups are listed.
:and (:todo ("SOMEDAY" "WATCHING") :not (:tag ("reward" "@BWG")))
:order 25)
;;(:name "reward"
;; :tag ("reward" "lp")
;; :order 100
;; )
;; After the last group, the agenda will display items that didn't
;; match any of these groups, with the default order position of 99
)
)(defun my-super-agenda-business()
"generates my super-agenda"
(interactive)
(org-super-agenda-mode)
(let
((org-super-agenda-groups my-super-agenda-important-business-only-groups))
(org-agenda nil "a")
)
)org-agenda-custom-commands → long list of agenda definitions
(if noninteractive
;; if Emacs is started in batch mode: omit org-super-agenda since I don't need it here and there were issues with it:
(setq org-agenda-custom-commands
` (
("n" "no TODO events +180d"
((agenda "no TODO events +180d"
((org-agenda-span 180)
(org-agenda-time-grid nil)
(org-agenda-entry-types '(:timestamp :sexp))
(org-agenda-skip-function
'(or
(org-agenda-skip-entry-if 'todo 'any);; skip if any TODO state is found
(org-agenda-skip-entry-if 'category "errors");; skip if any TODO state is found
(my-skip-tag "lp")
)
)
;;(org-agenda-skip-function '(my-skip-tag "lp"))
)))
nil (,(concat my-org-files-path "agenda_180d_filtered_raw.html")))
("D" "detail agenda"
((agenda "detail agenda"
((org-agenda-span 31)
(org-agenda-time-grid nil)
)))
nil (,(concat my-org-files-path "agenda_details_raw.html")))
))
;; if Emacs is started in interactive mode:
(setq org-agenda-custom-commands
` (
("s" "Super Agenda" agenda "FIXXME: does work but w/o super-agenda"
(org-super-agenda-mode)
((org-super-agenda-groups my-super-agenda-groups))
(org-agenda nil "a"))
("b" "Business Super Agenda" agenda "FIXXME: does work but w/o super-agenda"
(org-super-agenda-mode)
((org-super-agenda-groups my-super-agenda-important-business-only-groups))
(org-agenda nil "a"))
("g" "Agenda" agenda ""
(org-agenda nil "a"))
;; disabled 2014-08-17 ;; ;; https://lists.gnu.org/archive/html/emacs-orgmode/2011-07/msg01374.html
;; disabled 2014-08-17 ;; ("E" "events only" agenda ""
;; disabled 2014-08-17 ;; (
;; disabled 2014-08-17 ;; (org-agenda-skip-function '(org-agenda-skip-entry-if 'todo 'todo))
;; disabled 2014-08-17 ;; ))
("n" "no TODO events +180d"
((org-ql-block '(and (tags "project")
(ts-active :from -1 :to +180)
(not (todo))
;(not (descendants (not (done))))
;(not (descendants (scheduled)))
)
((org-ql-block-header "no TODO events +180d")))))
("7" "no TODO events +180d"
((agenda "no TODO events +180d"
((org-agenda-span 180)
(org-agenda-time-grid nil)
(org-agenda-entry-types '(:timestamp :sexp))
(org-agenda-skip-function
'(or
(org-agenda-skip-entry-if 'todo 'any);; skip if any TODO state is found
(org-agenda-skip-entry-if 'category "infonova");; skip if any TODO state is found
(my-skip-tag "lp")
)
)
;;(org-agenda-skip-function '(my-skip-tag "lp"))
)))
nil (,(concat my-org-files-path "agenda_180d_filtered.html")))
("D" "detail agenda"
((agenda "detail agenda"
((org-agenda-span 31)
(org-agenda-time-grid nil)
)))
nil (,(concat my-org-files-path "agenda_details_raw.html")))
;; disabled 2015-02-15 - replaced by no TODO events ;; ("p" "events Prio [#A]"
;; disabled 2015-02-15 - replaced by no TODO events ;; ((agenda "+PRIORITY=\"A\""
;; disabled 2015-02-15 - replaced by no TODO events ;; ((org-agenda-ndays 31)
;; disabled 2015-02-15 - replaced by no TODO events ;; (org-agenda-time-grid nil)
;; disabled 2015-02-15 - replaced by no TODO events ;; (org-agenda-entry-types '(:timestamp :sexp))
;; disabled 2015-02-15 - replaced by no TODO events ;; (org-agenda-skip-function
;; disabled 2015-02-15 - replaced by no TODO events ;; '(org-agenda-skip-entry-if 'notregexp "\\=.*\\[#A\\]")))
;; disabled 2015-02-15 - replaced by no TODO events ;; ;; (
;; disabled 2015-02-15 - replaced by no TODO events ;; ;; (org-agenda-skip-function 'tag-without-done-or-canceled)
;; disabled 2015-02-15 - replaced by no TODO events ;; ;; )
;; disabled 2015-02-15 - replaced by no TODO events ;; )))
;; disabled 2015-02-15 - replaced by no TODO + normal agenda ;; ("1" "1 month"
;; disabled 2015-02-15 - replaced by no TODO + normal agenda ;; ((agenda "1 month"
;; disabled 2015-02-15 - replaced by no TODO + normal agenda ;; ((org-agenda-ndays 31)
;; disabled 2015-02-15 - replaced by no TODO + normal agenda ;; (org-agenda-time-grid nil)
;; disabled 2015-02-15 - replaced by no TODO + normal agenda ;; (org-agenda-entry-types '(:timestamp :sexp))
;; disabled 2015-02-15 - replaced by no TODO + normal agenda ;; )
;; disabled 2015-02-15 - replaced by no TODO + normal agenda ;; )))
("r" "reward tasks" (
(tags-todo "reward/!STARTED"
(
(org-agenda-overriding-header "rewards: STARTED")
))
(tags-todo "reward/!NEXT"
(
(org-agenda-overriding-header "rewards: NEXT")
))
(tags-todo "reward/!TODO"
(
(org-agenda-overriding-header "rewards: TODO")
))
(tags-todo "reward/!SOMEDAY"
(
(org-agenda-overriding-header "rewards: SOMEDAY")
))
))
("i" "issues" (
(tags-todo "issue/!STARTED"
(
(org-agenda-overriding-header "issues: STARTED")
))
(tags-todo "issue/!NEXT"
(
(org-agenda-overriding-header "issues: NEXT")
))
(tags-todo "issue/!TODO"
(
(org-agenda-overriding-header "issues: TODO")
))
(tags-todo "issue/!SOMEDAY"
(
(org-agenda-overriding-header "issues: SOMEDAY")
))
))
;;disabled; ("R" "grab reward" tags-todo "reward/!TODO|SOMEDAY"
;;disabled; (
;;disabled; (org-agenda-overriding-header "rewards: TODO or SOMEDAY")
;;disabled; ))
("B" "borrowed"
((org-ql-block '(and (tags "borrowed")
(not (done))
)
((org-ql-block-header "borrowed")))))
;;2019-12-17 replaced by org-ql-block ;; ("8" "borrowed" tags "+borrowed"
;;2019-12-17 replaced by org-ql-block ;; (
;;2019-12-17 replaced by org-ql-block ;; (org-agenda-overriding-header "borrowed or lend")
;;2019-12-17 replaced by org-ql-block ;; (org-agenda-skip-function 'tag-without-done-or-canceled)
;;2019-12-17 replaced by org-ql-block ;; ))
("$" "Besorgungen"
((org-ql-block '(and (tags "Besorgungen")
(not (done))
)
((org-ql-block-header "Besorgungen")))))
;;2019-12-17 replaced by org-ql-block ;; ("9" "OLDBesorgungen" tags "+Besorgung"
;;2019-12-17 replaced by org-ql-block ;; (
;;2019-12-17 replaced by org-ql-block ;; (org-agenda-overriding-header "Besorgungen")
;;2019-12-17 replaced by org-ql-block ;; (org-agenda-skip-function 'tag-without-done-or-canceled)
;;2019-12-17 replaced by org-ql-block ;; ))
;; 2020-10-26: open focus projects
("p" "Nonbusiness: Open focus projects: open tasks tagged with \"project\" and \"focus\""
((org-ql-block '(and (tags "project") (tags "focus")
(not (category "rise"))
(not (done))
)
((org-ql-block-header "Open focus projects: open tasks tagged with \"project\" and \"focus\"")))))
;; 2020-10-26: open focus projects business
("P" "Business: Open focus projects: open tasks tagged with \"project\" and \"focus\""
((org-ql-block '(and (tags "project") (tags "focus")
(category "rise")
(not (done))
)
((org-ql-block-header "Open focus projects: open tasks tagged with \"project\" and \"focus\"")))))
;; examples: https://github.com/alphapapa/org-ql/blob/master/examples.org#stuck-projects-block-agenda
;; 2020-01-23: not doing what it is supposed to show: only shows one heading from one org mode file: id:2020-01-23-Security-Policies
("1" "Stuck Projects: tagged with \"project\", open sub-tasks not scheduled"
((org-ql-block '(and (tags "project")
(not (done))
(not (todo "SOMEDAY"))
(not (descendants (todo "NEXT")))
;;(not (descendants (not (done))))
(not (descendants (scheduled))))
((org-ql-block-header "Stuck Projects: tagged with \"project\", open sub-tasks not scheduled")))))
;; 2020-01-23: not doing what it is supposed to show at all
("2" "Stuck: open todos with unscheduled open sub-tasks"
((org-ql-block '(and
(not (done))
(or (todo "NEXT") (todo "STARTED") (todo "WAITING"))
; (todo "NEXT STARTED WAITING");; no result instead of "just get rid of SOMEDAY"
(descendants (not (done)))
(descendants (not (scheduled))))
((org-ql-block-header "Stuck: open todos with unscheduled open sub-tasks")))))
;; 2020-01-23: "with scheduled sub-tasks" does not work -> lists open todos but not all - can't tell what is shown
("3" "Stuck: scheduled todos with scheduled sub-tasks (FIXXME: also DONE subtasks match)"
((org-ql-block '(and
(not (done))
(scheduled)
(not (descendants (not (done))))
(descendants (scheduled))) ;; 2020-08-06: even tasks that are DONE are matching
;;(descendants (and (scheduled) (not (done))))
((org-ql-block-header "Stuck todos: scheduled open todos with scheduled sub-tasks")))))
;; disabled 2015-02-15 - can filter by tag ;; ("O" "SOMEDAY" tags-todo "+TODO=\"SOMEDAY\""
;; disabled 2015-02-15 - can filter by tag ;; (
;; disabled 2015-02-15 - can filter by tag ;; (org-agenda-overriding-header "SOMEDAY is today! :-)")
;; disabled 2015-02-15 - can filter by tag ;; ))
;; disabled 2015-02-15 - can filter by tag ;;
;; disabled 2015-02-15 - can filter by tag ;; ("h" "home @ALW" tags-todo "+@ALW"
;; disabled 2015-02-15 - can filter by tag ;; (
;; disabled 2015-02-15 - can filter by tag ;; (org-agenda-overriding-header "home tasks")
;; disabled 2015-02-15 - can filter by tag ;; ))
;; disabled 2015-02-15 - can filter by tag ;;
;; disabled 2015-02-15 - can filter by tag ;; ("b" "Breitenweg @BWG" tags-todo "+@BWG"
;; disabled 2015-02-15 - can filter by tag ;; (
;; disabled 2015-02-15 - can filter by tag ;; (org-agenda-overriding-header "home tasks")
;; disabled 2015-02-15 - can filter by tag ;; ))
;; disabled 2014-08-17 because of error ;;;; 2014-02-18: from Org-mode ML Subject: Re: Get a list of tasks completed today
;; disabled 2014-08-17 because of error ;;("." "Completed today"
;; disabled 2014-08-17 because of error ;; ((todo "TODO|DONE|CANCELED"
;; disabled 2014-08-17 because of error ;; ((org-agenda-skip-function
;; disabled 2014-08-17 because of error ;; '(org-agenda-skip-entry-if 'notregexp (format-time-string "CLOSED: \\[%Y-%m-%d")))))
;; disabled 2014-08-17 because of error ;; (org-agenda-sorting-strategy '(priority-down)))
;; disabled 2014-08-17 because of error ;; )
;; disabled 2015-02-15 - don't use it any more ;; ;; 2014-02-18: from Org-mode ML Subject: Re: Get a list of tasks completed today
;; disabled 2015-02-15 - don't use it any more ;; ("W" "Closed within a week."
;; disabled 2015-02-15 - don't use it any more ;; tags "CLOSED>\"<-1w>\""
;; disabled 2015-02-15 - don't use it any more ;; ((org-agenda-sorting-strategy '(priority-down))))
;; disabled 2015-02-15 - don't know what's for ;; ("o" "overview Agenda" (
;; disabled 2015-02-15 - don't know what's for ;; (agenda ""
;; disabled 2015-02-15 - don't know what's for ;; nil )
;; disabled 2015-02-15 - don't know what's for ;; ;;diabled by nil above; ((org-agenda-skip-function '(my-skip-tag "reward"))
;; disabled 2015-02-15 - don't know what's for ;; ;;diabled by nil above; (org-agenda-overriding-header "Agenda without rewards: ")))
;; disabled 2015-02-15 - don't know what's for ;; (tags "+TODO=\"DONE\"+CLOSED>=\"<today>\""
;; disabled 2015-02-15 - don't know what's for ;; (
;; disabled 2015-02-15 - don't know what's for ;; (org-agenda-overriding-header "DONE today")
;; disabled 2015-02-15 - don't know what's for ;; ))
;; disabled 2015-02-15 - don't know what's for ;; ;;diabled; (tags "+reward"
;; disabled 2015-02-15 - don't know what's for ;; ;;diabled; (
;; disabled 2015-02-15 - don't know what's for ;; ;;diabled; (org-agenda-overriding-header "Rewards")
;; disabled 2015-02-15 - don't know what's for ;; ;;diabled; ;(org-agenda-skip-function 'bh/skip-non-stuck-projects))
;; disabled 2015-02-15 - don't know what's for ;; ;;diabled; ;(org-agenda-todo-ignore-scheduled 'future)
;; disabled 2015-02-15 - don't know what's for ;; ;;diabled; ;(org-agenda-todo-ignore-deadlines 'future)
;; disabled 2015-02-15 - don't know what's for ;; ;;diabled; )
;; disabled 2015-02-15 - don't know what's for ;; ;;diabled; )
;; disabled 2015-02-15 - don't know what's for ;; ;;too slow - dont need; (tags-todo "-CANCELLED/!"
;; disabled 2015-02-15 - don't know what's for ;; ;;too slow - dont need; ((org-agenda-overriding-header "Stuck Projects")
;; disabled 2015-02-15 - don't know what's for ;; ;;too slow - dont need; (org-agenda-skip-function 'bh/skip-non-stuck-projects)))
;; disabled 2015-02-15 - don't know what's for ;; ;;slow; (tags-todo "-CANCELLED+WAITING/!"
;; disabled 2015-02-15 - don't know what's for ;; ;;slow; ((org-agenda-overriding-header "Waiting and Postponed Tasks")
;; disabled 2015-02-15 - don't know what's for ;; ;;slow; (org-agenda-skip-function 'bh/skip-stuck-projects)
;; disabled 2015-02-15 - don't know what's for ;; ;;slow; (org-tags-match-list-sublevels nil)
;; disabled 2015-02-15 - don't know what's for ;; ;;slow; (org-agenda-todo-ignore-scheduled 'future)
;; disabled 2015-02-15 - don't know what's for ;; ;;slow; (org-agenda-todo-ignore-deadlines 'future)
;; disabled 2015-02-15 - don't know what's for ;; ;;slow; ))
;; disabled 2015-02-15 - don't know what's for ;; ;; (tags "REFILE"
;; disabled 2015-02-15 - don't know what's for ;; ;; ((org-agenda-overriding-header "Tasks to Refile")
;; disabled 2015-02-15 - don't know what's for ;; ;; (org-tags-match-list-sublevels nil)))
;; disabled 2015-02-15 - don't know what's for ;; ;; (tags "-REFILE/"
;; disabled 2015-02-15 - don't know what's for ;; ;; ((org-agenda-overriding-header "Tasks to Archive")
;; disabled 2015-02-15 - don't know what's for ;; ;; (org-agenda-skip-function 'bh/skip-non-archivable-tasks)
;; disabled 2015-02-15 - don't know what's for ;; ;; (org-tags-match-list-sublevels nil)))
;; disabled 2015-02-15 - don't know what's for ;; ;; (tags-todo "-HOLD-CANCELLED/!"
;; disabled 2015-02-15 - don't know what's for ;; ;; ((org-agenda-overriding-header "Projects")
;; disabled 2015-02-15 - don't know what's for ;; ;; (org-agenda-skip-function 'bh/skip-non-projects)
;; disabled 2015-02-15 - don't know what's for ;; ;; (org-agenda-sorting-strategy
;; disabled 2015-02-15 - don't know what's for ;; ;; '(category-keep))))
;; disabled 2015-02-15 - don't know what's for ;; )
;; disabled 2015-02-15 - don't know what's for ;; nil)
;;disabled;; ("x" "Borrowed"
;;disabled;; ((agenda ""
;;disabled;; ((org-agenda-skip-function 'tag-without-done-or-canceled)
;;disabled;; (org-agenda-overriding-header "Fun: ")))))
;;disabled 2014-08-17;; ("X" "calfw" open-calfw-agenda-org)
;;2012-12-10 deactivated; ("c" . "custom searches") ; description for "c" prefix
;;2012-12-10 deactivated; ("cr" "rewards" agenda "+reward"
;;2012-12-10 deactivated; (
;;2012-12-10 deactivated; (org-agenda-overriding-header "rewards")
;;2012-12-10 deactivated; (org-agenda-time-grid nil)
;;2012-12-10 deactivated; (org-agenda-entry-types '(:deadline))
;;2012-12-10 deactivated; ))
;;2012-12-10 deactivated; ("cr" "rewards" agenda "+reward"
;;2012-12-10 deactivated; (
;;2012-12-10 deactivated; (org-agenda-overriding-header "rewards")
;;2012-12-10 deactivated; (org-agenda-time-grid nil)
;;2012-12-10 deactivated; (org-agenda-entry-types '(:deadline))
;;2012-12-10 deactivated; ))
;;2012-12-10 deactivated; ("ct" "@TUG" tags-todo "+@TUG"
;;2012-12-10 deactivated; ((org-agenda-overriding-header "TUG Tasks")))
;;2012-12-10 deactivated; ("ca" "@ALW" tags-todo "+@ALW"
;;2012-12-10 deactivated; ((org-agenda-overriding-header "ALW Tasks")))
;;2012-12-10 deactivated; ("cb" "Besorgungen" tags-todo "+Besorgung"
;;2012-12-10 deactivated; ((org-agenda-overriding-header "Besorgungen")))
;;2012-12-10 deactivated; ("cs" "Started tasks" tags-todo "/!STARTED"
;;2012-12-10 deactivated; ((org-agenda-overriding-header "Started Tasks")))
;;2012-12-10 deactivated; ("n" "Next and Started tasks" tags-todo "-WAITING-CANCELLED/!NEXT|STARTED"
;;2012-12-10 deactivated; ((org-agenda-overriding-header "Next Tasks")))
;;2012-12-10 deactivated; ("p" "Projects" tags-todo "LEVEL=2-REFILE|LEVEL=1+REFILE/!-DONE-CANCELLED-WAITING-SOMEDAY"
;;2012-12-10 deactivated; ((org-agenda-skip-function 'bh/skip-non-projects)
;;2012-12-10 deactivated; (org-agenda-overriding-header "Projects")))
;; ("o" "Other (Non-Project) tasks" tags-todo "LEVEL=2-REFILE|LEVEL=1+REFILE/!-DONE-CANCELLED-WAITING-SOMEDAY"
;; ((org-agenda-skip-function 'bh/skip-projects)
;; (org-agenda-overriding-header "Other Non-Project Tasks")))
;; ("A" "Tasks to be Archived" tags "LEVEL=2-REFILE/DONE|CANCELLED"
;; ((org-agenda-overriding-header "Tasks to Archive")
;; (org-agenda-skip-function 'bh/skip-non-archivable-tasks)))
;2012-12-10 deactivated; ("h" "Habits" tags-todo "STYLE=\"habit\""
;2012-12-10 deactivated; ((org-agenda-todo-ignore-with-date nil)
;2012-12-10 deactivated; (org-agenda-todo-ignore-scheduled nil)
;2012-12-10 deactivated; (org-agenda-todo-ignore-deadlines nil)
;2012-12-10 deactivated; (org-agenda-overriding-header "Habits")))
;; ("#" "Stuck Projects" tags-todo "LEVEL=2-REFILE|LEVEL=1+REFILE/!-DONE-CANCELLED"
;; ((org-agenda-skip-function 'bh/skip-non-stuck-projects)
;; (org-agenda-overriding-header "Stuck Projects")))
;; ("*" "All open TODO tasks" tags-todo "-CANCELLED"
;; ((org-agenda-overriding-header "All Open TODO tasks")
;; (org-agenda-todo-ignore-with-date nil)
;; (org-agenda-todo-ignore-scheduled nil)
;; (org-agenda-todo-ignore-deadlines nil)
;; (org-agenda-todo-ignore-timestamp nil)
;; (org-agenda-todo-list-sublevels t)
;; (org-tags-match-list-sublevels 'indented)))
))
)Agenda settings
start Agenda in follow-mode:
;(setq org-agenda-start-with-follow-mode t)- t = do not initialize agenda Org files when generating (only) agenda
- nil = initialize normal
- performance issue when not “t”: https://punchagan.muse-amuse.in/posts/how-i-learnt-to-use-emacs-profiler.html
;;(setq org-agenda-inhibit-startup nil);; slower but visibility of buffers is correctly shown
(setq org-agenda-inhibit-startup t);; faster with no hidden headings (agenda performance)Compact the block agenda view
(setq org-agenda-compact-blocks t)- Changed in v7.9.3
- http://orgmode.org/worg/doc.html#org-use-tag-inheritance
- performance issue when not nil: https://punchagan.muse-amuse.in/posts/how-i-learnt-to-use-emacs-profiler.html
(setq org-agenda-use-tag-inheritance (quote (agenda)));; agenda performancehttp://orgmode.org/org.html#Weekly_002fdaily-agenda
(setq org-agenda-span 1)For tag searches ignore tasks with scheduled and deadline dates
(setq org-agenda-tags-todo-honor-ignore-options t)Always highlight the current agenda line:
(add-hook 'org-agenda-mode-hook '(lambda () (hl-line-mode 1)))The following custom-set-faces create the highlights
(custom-set-faces
;; custom-set-faces was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
'(highlight ((t (:background "cyan"))))
'(hl-line ((t (:inherit highlight :background "darkseagreen2"))))
'(org-mode-line-clock ((t (:background "grey75" :foreground "red" :box (:line-width -1 :style released-button)))) t))Keep tasks with dates off the global todo lists:
(setq org-agenda-todo-ignore-with-date nil)Allow deadlines which are due soon to appear on the global todo lists:
(setq org-agenda-todo-ignore-deadlines (quote far))Keep tasks scheduled in the future off the global todo lists
(setq org-agenda-todo-ignore-scheduled (quote future))Remove completed deadline tasks from the agenda view
(setq org-agenda-skip-deadline-if-done t)Remove completed scheduled tasks from the agenda view
(setq org-agenda-skip-scheduled-if-done t)Remove completed items from search results
(setq org-agenda-skip-timestamp-if-done t)Include agenda archive files when searching for things
(setq org-agenda-text-search-extra-files (quote (agenda-archives)))show state changes in log-mode of agenda
(setq org-agenda-log-mode-items (quote (state)))http://orgmode.org/worg/org-faq.html
;(setq org-agenda-skip-additional-timestamps-same-entry t)
(setq org-agenda-skip-additional-timestamps-same-entry nil)do not search for time in heading when displaying a date-stamp
(setq org-agenda-search-headline-for-time nil)open agenda in same buffer, full size
(setq org-agenda-window-setup 'current-window)add diary entries in agenda view http://orgmode.org/org.html#Weekly_002fdaily-agenda
(setq org-agenda-include-diary t)Show all future entries for repeating tasks
(setq org-agenda-repeating-timestamp-show-all t)Show all agenda dates - even if they are empty
(setq org-agenda-show-all-dates t)Sorting order for tasks on the agenda
(setq org-agenda-sorting-strategy
(quote ((agenda habit-down time-up user-defined-up priority-down category-keep)
(todo priority-down category-keep)
(tags priority-down category-keep)
(search category-keep))))Start the weekly agenda today
(setq org-agenda-start-on-weekday nil)Non-nil means skip timestamp line if same entry shows because of deadline.
(setq org-agenda-skip-timestamp-if-deadline-is-shown t)Agenda sorting functions
(setq org-agenda-cmp-user-defined 'bh/agenda-sort)Enable display of the time grid so we can see the marker for the current time
(setq org-agenda-time-grid
((daily today remove-match)
#("----------------" 0 16
(org-heading t))
(800 1000 1200 1400 1600 1800 2000)))Display tags farther right
;;(setq org-agenda-tags-column -102)
(setq org-tags-column -101); for powerplantwin 23" TFT turned 90
; degrees; should *not* differ between
; systems! Otherwise Org-files gets
; re-formatted after switching
; system
;;(when (my-system-type-is-windows)
;; ;;(setq org-agenda-tags-column -103);; for 23" TFT turned 90 degrees
;; (setq org-agenda-tags-column -117);; for 24" TFT turned 90 degrees
;; )
;;(when (my-system-is-sting)
;; (setq org-agenda-tags-column -117);; -117 for 23" TFT sting, rotated 90°
;; )
(setq org-agenda-tags-column (- (- (window-total-width) 3))) ;; total width minus 3Sticky agendas remain opened in the background so that you don’t need to regenerate them each time you hit the corresponding keystroke. This is a big time saver.
(setq org-agenda-sticky t)Scrolling through agenda using C-p and C-n instead of PageUp/PageDown also in agenda. Default setting is C-p/C-n for scrolling one line at a time.
(define-key org-agenda-mode-map (kbd "C-p") 'my-scroll-down-half)
(define-key org-agenda-mode-map (kbd "C-n") 'my-scroll-up-half)From reddit I got the settings that deadlines are not shown when SCHEDULED is set:
(setq org-agenda-skip-scheduled-if-deadline-is-shown nil)
;;(setq org-agenda-skip-deadline-prewarning-if-scheduled t)From reddit: Adding a separator line between days. Disabled 2020-01-03 because I usually see one single day only.
(setq org-agenda-format-date (lambda (date) (concat "\n"
(make-string (window-width) 9472)
"\n"
(org-agenda-format-date-aligned date))))Agenda category icons
There is the possibility of adding icons to categories: http://julien.danjou.info/blog/2010/icon-category-support-in-org-mode
This is a neat way of beautifying the agenda.
Unfortunately, the clean way of defining the data directory relatively
to the path stored in my-user-emacs-directory does not work:
(concat my-user-emacs-directory "bin/images/R6-logo_18x12.jpg") nil nil :ascent center)
I don’t know how to fix this and so I stick with the hard coded path and with a bleeding heart.
(setq org-agenda-category-icon-alist nil)
;(when (my-system-type-is-windows)
(add-to-list 'org-agenda-category-icon-alist
'(".*" '(space . (:width (16))))
)
(add-to-list 'org-agenda-category-icon-alist
`("rise" ,(concat my-user-emacs-directory "bin/images/RISE_icon_16x16_dark.png") nil nil :ascent center))
;; (add-to-list 'org-agenda-category-icon-alist
;; '("r6" "~/.emacs.d/bin/images/R6-logo_18x12.jpg" nil nil :ascent center)
;; )
;; (add-to-list 'org-agenda-category-icon-alist
;; '("infonova" "~/.emacs.d/bin/images/R6-logo_18x12.jpg" nil nil :ascent center)
;; )
;; (add-to-list 'org-agenda-category-icon-alist
;; `("detego" ,(concat my-user-emacs-directory "bin/images/detego-inwarehouse-logo-D_only_16x16.png") nil nil :ascent center))
;; (add-to-list 'org-agenda-category-icon-alist
;; `("ciso" ,(concat my-user-emacs-directory "bin/images/detego-inwarehouse-logo-D_only_16x16.png") nil nil :ascent center))
;; (add-to-list 'org-agenda-category-icon-alist
;; `("outlook" ,(concat my-user-emacs-directory "bin/images/detego-inwarehouse-logo-D_only_16x16.png") nil nil :ascent center))
;; (add-to-list 'org-agenda-category-icon-alist
;; `("ISAE3402" ,(concat my-user-emacs-directory "bin/images/detego-inwarehouse-logo-D_only_16x16.png") nil nil :ascent center))
;; OLD version without my-user-emacs-directory; with help of: https://github.com/novoid/dot-emacs/issues/2
;;OLD: (add-to-list 'org-agenda-category-icon-alist
;;OLD: '("ciso" "~/.emacs.d/bin/images/detego-inwarehouse-logo-D_only_16x16.png" nil nil :ascent center)
;;OLD: )
;;(add-to-list 'org-agenda-category-icon-alist
;; '("misc" '(space . (:width (18))))
;; )
; )
(when (and (not (my-system-type-is-windows)) (not (my-system-is-karl-voit-at)))
(add-to-list 'org-agenda-category-icon-alist
'(".*" '(space . (:width (16))))
)
(add-to-list 'org-agenda-category-icon-alist
'("contacts" "~/.emacs.d/bin/images/user-identity.png" nil nil :ascent center)
;; /usr/share/icons/gnome/16x16/emotes/face-smile.png
)
(add-to-list 'org-agenda-category-icon-alist
'("public_voit" "~/.emacs.d/bin/images/application-rss+xml.png" nil nil :ascent center)
;; /usr/share/icons/oxygen/16x16/mimetypes/application-rss+xml.png
)
;; (add-to-list 'org-agenda-category-icon-alist
;; '("misc" "~/.emacs.d/bin/images/emblem-new.png" nil nil :ascent center)
;; ;; /usr/share/icons/oxygen/16x16/emblems/emblem-new.png
;; )
(add-to-list 'org-agenda-category-icon-alist
'("hardware" "~/.emacs.d/bin/images/camera-photo.png" nil nil :ascent center)
;; /usr/share/icons/oxygen/16x16/devices/camera-photo.png
)
(add-to-list 'org-agenda-category-icon-alist
'("bwg" "~/.emacs.d/bin/images/go-home.png" nil nil :ascent center)
;; /usr/share/icons/oxygen/16x16/actions/go-home.png
)
)my-org-agenda() → my-map a
Using the universal argument C-u before my-map a, I can invoke the
“other” agenda (normal agenda vs. business agenda):
switch to open Agenda or open new one:
(defun my-org-agenda (&optional arg)
"Opens the already opened agenda or opens new one instead. With
universal prefix, use business agenda."
(interactive "P")
(setq my-org-agenda-start-time (current-time))
(setq my-org-agenda-tags-column (- (- (window-total-width) 3)))
(setq org-agenda-tags-column my-org-agenda-tags-column) ;; total width minus 3
(if (my-buffer-exists "*Org Agenda*")
(switch-to-buffer "*Org Agenda*")
(progn
(my-super-agenda)
(setq current-timestamp
(concat
(format-time-string "%Y-%m-%dT%T")
((lambda (x) (concat (substring x 0 3) ":" (substring x 3 5)))
(format-time-string "%z"))))
(when (> (string-to-number (emacs-uptime "%m")) 2) ;; only flash when not part of the boot process (= Emacs runs longer than 2 minutes)
(my-flash (format-message "Agenda built.\n(took %.2fs)" (float-time (time-subtract (current-time) my-org-agenda-start-time))))
)
(my-log-misc (format-message "my-org-agenda took %.2fs" (float-time (time-subtract (current-time) my-org-agenda-start-time))))
)
)
)
(bind-key "a" 'my-org-agenda my-map)my-memacs-org-agenda() → my-map m C-cm
Memacs org-agenda shortcut
(defun my-memacs-org-agenda ()
"Opens an org-agenda with activated archive"
(interactive)
;;(setq org-agenda-files (append (quote ("~/org/issues.org"))));; for testing purposes
(org-agenda-list)
;;(call-interactively 'org-agenda-log-mode)
(org-agenda-log-mode '(4))
(call-interactively 'org-agenda-archives-mode)
(org-agenda-archives-mode 'files)
)
;;disabled because I needed "m";; (bind-key "m" 'my-memacs-org-agenda my-map)
(global-set-key "\C-cm" 'my-memacs-org-agenda)Or within a shell as separate Emacs instance:
/usr/bin/emacs --load /home/vk/.emacs.d/init.el --eval '(progn (my-memacs-org-agenda))'
I aliased it within ~/.zshrc.local to memacs
my-export-agenda()
- 2019-05-07: commented out previous postprocessing steps and switched to different output folder “var/export/” that gets synced among my devices. Postprocessing is done via cronjob.
(defun my-export-agenda()
"Exports monthly Org-mode agenda to agenda.ics file"
(interactive)
(save-some-buffers)
;; I don't want the error messages in my exported agenda:
(setq org-agenda-files (remove "~/org/errors.org" org-agenda-files))
(setq max-specpdl-size 10000)
(setq max-lisp-eval-depth 50000)
(org-agenda-list nil nil 60)
;(org-agenda-list nil nil 7)
(message "after org-agenda-list")
;;test; (org-agenda-list nil nil 15)
;; (org-agenda-write "~/org/agenda-export-raw2.ics")
(org-agenda-write (concat my-user-emacs-directory "var/export/agenda-export.ics"))
(message "after org-agenda-write")
;; (setq scriptpath "~/src/postprocess_Org-mode_iCal_export/")
;; (setq icspath (concat my-user-emacs-directory "var/export/"))
;; (setq icspath "~/org/")
;; (shell-command-to-string (concat
;; scriptpath "postprocess_Org-mode_iCal_export.py "
;; "-i " icspath "agenda-export-raw2.ics "
;; "-o " icspath "agenda-export-postprocessed2.ics "
;; "--overwrite "
;; "--remove-summary-timestamp"
;; )
;; )
;; (shell-command-to-string (concat
;; scriptpath "postprocess_Org-mode_iCal_export.py "
;; "-i " icspath "agenda-export-raw2.ics "
;; "-o " icspath "agenda-export-freebusy2.ics "
;; "--overwrite "
;; "--obfuscate"
;; )
;; )
;; (message "after shell-command-to-string")
;; (if (my-system-type-is-gnu)
;; (shell-command-to-string "/home/vk/bin/vk-cronjob-gary-do-unison-sync-unattended-share-all_if_host_is_reachable.sh")
;; (message "Please do sync using unison!")
;; )
)desktop notifications
| 2020-08-20 | initial setup |
This article explains the basic mechanism. Also helpful: this and that.
The creation of the ~/diary file with %%(org-diary) as content:
(write-region "%%(org-diary)" nil (substitute-in-file-name "~/diary") nil)Setup of the notification mechanism such that Org mode appointments
cause desktop notifications via notify-send:
(require 'appt) ;; activate appointment notification
(appt-activate t) ;; activate appointment notification
(setq org-agenda-include-diary t) ;; push Org agenda items to diary
(setq calendar-mark-diary-entries-flag t) ;; mark dates with diary entries, in the calendar window
(setq appt-time-msg-list nil) ;; clear list of appointments for today.
(setq appt-message-warning-time 10 ;; warn 10 min in advance
appt-display-interval 10 ;; repeat notification this amount of minutes; must not be 0 (arith-error)
appt-display-diary nil ;; do not display diary when (appt-activate) is called
appt-display-mode-line t ;; show in the modeline
appt-display-format 'window ;; display notification in window
appt-disp-window-function 'my-appt-disp-window ;; use this function for appointment notifications
calendar-mark-diary-entries-flag t) ;; mark diary entries in calendar
(defun my-appt-disp-window (min-to-app new-time msg)
"My function to display appt notifications: I prefer notify-send as I'm using GNU/Linux on all of my current hosts."
(save-window-excursion
(let ((msg (replace-regexp-in-string ":[a-zA-Z0-9@_:]*:$" "" ;; remove tags
(replace-regexp-in-string "/" "·" ;; get rid of slashes
(replace-regexp-in-string "\\[" "" ;; get rid of opening brackets
(replace-regexp-in-string "\\]" "" ;; get rid of closing brackets
(replace-regexp-in-string "https://" "" ;; get rid of URL protocol
(replace-regexp-in-string "\\(\\[\\[\\)\\(.*?\\)\\]\\]" "\\2" ;; replace links with their description
(replace-regexp-in-string "\\(\\[\\[.*\\]\\[\\)\\(.*?\\)\\]\\]" "\\2" ;; replace links with their description
msg))))))))) ;; elisp org mode heading title sanitization
(progn
(message msg)
(shell-command
(concat my-user-emacs-directory "bin/desktop-notification.sh '" msg "'")
nil nil)))));; date-string must not contain spaces (don't know why)
;; original w/o wrapper (shell-command
;; original w/o wrapper (concat
;; original w/o wrapper "notify-send --urgency=critical \"Org `date +%Y-%m-%dT%H.%M`\" \"" msg "\"") nil nil)));; date-string must not contain spaces (don't know why)
;; add agenda→diary mechanism to the agenda hook
(add-hook 'org-finalize-agenda-hook
(lambda ()
(setq appt-time-msg-list nil) ;; clear list of appointments for today.
(org-agenda-to-appt) ;; copy all agenda schedule to appointments
(appt-activate 1))) ;; active appt (appointment notification)
;; add agenda→diary mechanism to the org-super-agenda hook
(add-hook 'org-super-agenda-mode-hook
(lambda ()
(setq appt-time-msg-list nil) ;; clear list of appointments for today.
(org-agenda-to-appt) ;; copy all agenda schedule to appointments
(appt-activate 1))) ;; active appt (appointment notification)
Unfortunately, I don’t get notifications in locked desktop state with
the default setup: see this reddit thread. Therefore, I had to set up
a wrapper shell script and use this within my-appt-disp-window:
/home/vk/.emacs.d/bin/desktop-notification.sh
#!/bin/bash
message="${1}"
timestamp="$(date +%Y-%m-%dT%H:%M:%S+02:00)"
notify-send --urgency=critical "Org `date +%Y-%m-%dT%H.%M`" "${message}"
#endFollowing thing could also be handy: add the tag rem30 for 30min
pre-warning time instead of the default one. From the manual:
This pre-warning does not work yet according to my tests on id:2020-09-01-setup-desktop-notifications:
;;(setq appt-warning-time-regexp "warntime \\([0-9]+\\)");; original
(setq appt-warning-time-regexp ":rem\\([0-9]+\\):");; to be used, e.g., as tags: =:rem3:= → 3 minutesI haven’t invested this issue such that I know a fix yet.
my-org-agenda-to-appt
For org appointment reminders http://orgmode.org/worg/org-hacks.html#sec-3_1 Get appointments for today
(when (or (my-system-type-is-gnu) (my-system-is-powerplantlinux))
(defun my-org-agenda-to-appt ()
(interactive)
(setq appt-time-msg-list nil)
(let ((org-deadline-warning-days 0)) ;; will be automatic in org 5.23
(org-agenda-to-appt)))
;; Run once, activate and schedule refresh
(my-org-agenda-to-appt)
(appt-activate t)
(run-at-time "24:01" nil 'org-agenda-to-appt)
;; 5 minute warnings
(setq appt-message-warning-time 15)
(setq appt-display-interval 15)
;; Update appt each time agenda opened.
(add-hook 'org-finalize-agenda-hook 'org-agenda-to-appt)
;; Setup zenify, we tell appt to use window, and replace default function
(setq appt-display-format 'window)
(setq appt-disp-window-function (function appt-disp-window))
(defun appt-disp-window (min-to-app new-time msg)
(save-window-excursion
(shell-command
(concat "/usr/bin/zenity --info --title='Appointment' --text='" msg "' &") nil nil)
)
)
)my-export-month-agenda-to-png-via-screenshot()
Generates my agenda and creates a screenshot with it. I used this as a workaround before I customized my agenda export to HTML.
- id:2016-04-12-my-export-month-agenda-to-png-via-screenshot
(defun my-export-month-agenda-to-png-via-screenshot()
(interactive)
(when (my-system-is-sting)
(message "Generating agenda ...")
(org-agenda nil "n") ; generates agenda "n" (one month without todos)
(if (my-buffer-exists "*Org Agenda*")
(switch-to-buffer "*Org Agenda*")
(org-agenda-list)
)
(message "Waiting for Screenshot ...")
(sit-for 1) ; (sleep 1) ... doesn't re-display and thus screenshot
; showed buffer before switching to agenda
(message "Say cheese ...")
(setq myoutput
(shell-command-to-string "/usr/bin/import -window root /home/vk/share/roy/from_sting/agenda.png"))
(message (concat "Screenshot done (" myoutput ")"))
)
)calfw - A calendar framework for Emacs
https://github.com/kiwanami/emacs-calfw
I am not using it because of a missing visualization option I described on https://github.com/kiwanami/emacs-calfw/issues/22
Open calendar using: M-x cfw:open-org-calendar
(use-package calfw-org
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/calfw/")))
)Provide a command to use calfw in org-agenda-custom-commands
- https://github.com/kiwanami/emacs-calfw/issues/18
- 2013-01-16: does not work (yet?)
(defun open-calfw-agenda-org(&rest args)
(let
(
;; do not duplicate deadlines
(org-deadline-warning-days 0)
)
(cfw:open-org-calendar)
)
)habits
«Org has the ability to track the consistency of a special category of TODOs, called “habits”.»
- http://orgmode.org/manual/Tracking-your-habits.html
- http://orgmode.org/worg/org-tutorials/tracking-habits.html
- global STYLE property values for completion
(setq org-global-properties (quote (("STYLE_ALL" . "habit"))))- position the habit graph on the agenda to the right of the default
(setq org-habit-graph-column 100)my-reset-org-with-visibility-and-super-agenda() - reset some Org-mode stuff and reset startup visibility
This function is a combination of my-reset-org() and
my-org-startup-visibility() from above.
(defun my-reset-org-with-visibility-and-super-agenda ()
"Clears all kinds of Org-mode caches and re-builds them if possible and resets the most important buffers to their startup visibility"
(interactive)
(my-reset-org)
(my-org-startup-visibility)
)org-agenda-exporter-settings
I export my agendas defined in org-agenda-custom-commands that have
an export file associated (as of 2017-06-03:
agenda_180d_filtered.html and agenda_details.html) using a daily
cronjob that looks like:
0 4 * * * /usr/bin/emacs --batch --load /home/vk/.emacs.d/init.el --eval '(progn (setq org-agenda-files (append my-work-agenda-files my-nonwork-agenda-files)) (org-store-agenda-views))' >/dev/null 2>&1
As you can see, I override org-agenda-files with both, my work and
my non-work agenda files. Otherwise, I’d get the host-specific
non-work-only agenda which I don’t want to see in my exported agenda
HTML files.
The generated HTML files are placed in a directory that gets automatically synced via Syncthing to my Android phone. The phone has browser bookmarks set for the agenda files and my desktop has icons for those bookmarks. This is how I access my agenda files on my phone.
customizing the agenda export of C-x C-w
(setq org-agenda-exporter-settings
'((ps-number-of-columns 2)
(ps-landscape-mode t)
;;disabled; (org-agenda-add-entry-text-maxlines 5)
(htmlize-output-type 'css)))my-org-obfuscate-agenda-item
This was originally developed by alphapapa as org-agenda-sharpie()
and published on GitHub.
When invoked on an agenda item, you can enter some text and the agenda item gets temporarily overwritten. You can use this to obfuscate or “overwrite” agenda entries before making a screenshot for public use.
(defun org-agenda-sharpie ()
"Censor the text of items in the agenda."
(interactive)
(let (regexp old-heading new-heading properties)
;; Save face properties of line in agenda to reapply to changed text
(setq properties (text-properties-at (point)))
;; Go to source buffer
(org-with-point-at (org-find-text-property-in-string 'org-marker
(buffer-substring (line-beginning-position)
(line-end-position)))
;; Save old heading text and ask for new text
(line-beginning-position)
(unless (org-at-heading-p)
;; Not sure if necessary
(org-back-to-heading))
(setq old-heading (when (looking-at org-complex-heading-regexp)
(match-string 4))))
(unless old-heading
(error "Can't find heading. How can this be?"))
;; Back to agenda buffer
(setq new-heading (read-from-minibuffer "Overwrite visible heading with: "))
(add-text-properties 0 (length new-heading) properties new-heading)
;; Replace agenda text
(save-excursion
(let ((inhibit-read-only t))
(goto-char (line-beginning-position))
(when (search-forward old-heading (line-end-position))
(replace-match new-heading 'fixedcase 'literal))))))iCal
iCal -> Org
Import iCal to Org-mode
- http://ozymandias.dk/emacs/org-import-calendar.el
- https://raw.github.com/vjohansen/emacs-config/master/org-import-calendar.el
(my-load-local-el "contrib/org-import-calendar.el")
;won't work; (use-package org-import-calendar
;won't work; :load-path "~/.emacs.d/contrib/"
;won't work; )
(use-package org-import-icalendar)Austrian Holidays
- from: http://paste.lisp.org/display/96464
- ~/Notes/holidays.el
(require 'holidays)
(setq holiday-austria-holidays '((holiday-fixed 1 1 "Neujahr (frei)")
(holiday-fixed 1 6 "Heilige Drei Könige (frei)")
(holiday-easter-etc 1 "Ostermontag (frei)")
(holiday-easter-etc -46 "Aschermittwoch")
(holiday-easter-etc -2 "Karfreitag")
(holiday-fixed 5 1 "Österreichischer Staatsfeiertag (frei)")
(holiday-easter-etc 39 "Christi Himmelfahrt (frei)")
(holiday-easter-etc 50 "Pfingstmontag (frei)")
(holiday-easter-etc 60 "Fronleichnam (frei)")
(holiday-float 5 0 2 "Muttertag")
(holiday-float 6 0 2 "Vatertag")
(holiday-fixed 8 15 "Mariä Himmelfahrt (frei)")
(holiday-fixed 10 26 "Nationalfeiertag (frei)")
(holiday-fixed 11 1 "Allerheiligen (frei)")
(holiday-fixed 12 8 "Maria Empfängnis (frei)")
(holiday-fixed 12 24 "Heiliger Abend (nicht frei)")
(holiday-fixed 12 25 "Erster Weihnachtstag (frei)")
(holiday-fixed 12 26 "Zweiter Weihnachtstag (frei)")))
;;(setq holiday-other-holidays '((holiday-fixed 10 3 "Tag der Deutschen Einheit")))
(setq holiday-local-holidays holiday-austria-holidays)
(setq calendar-holidays (append holiday-local-holidays holiday-other-holidays))
;; and add (load "~/Notes/holidays" t) to your .emacs and add
;; #+CATEGORY: Feiertag
;; %%(org-calendar-holiday)
;; to an agenda file
;; ######################################################
;; Muttertag... from http://debianforum.de/forum/viewtopic.php?f=29&t=67024time-zone for iCal
- setting timezone in order to get a correct iCal export
- http://lists.gnu.org/archive/html/emacs-orgmode/2009-05/msg00134.html
(setq org-icalendar-timezone "Europe/Vienna")setting destination file for iCal export
- http://lists.gnu.org/archive/html/emacs-orgmode/2009-05/msg00163.html
- http://orgmode.org/worg/org-tutorials/org-google-sync.html
- disabled; does not work
(setq org-combined-agenda-icalendar-file "~/public_html/orgmodevk478.ics")org-mycal-export-limit()
define filter. The filter is called on each entry in the agenda. It defines a regexp to search for two timestamps, gets the start and end point of the entry and does a regexp search. It also checks if the category of the entry is in an exclude list and returns either t or nil to skip or include the entry.
(defun org-mycal-export-limit ()
"Limit the export to items that have a date, time and a range. Also exclude certain categories."
(setq org-tst-regexp "<\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} ... [0-9]\\{2\\}:[0-9]\\{2\\}[^\r\n>]*?\\)>")
(setq org-tstr-regexp (concat org-tst-regexp "--?-?" org-tst-regexp))
(save-excursion
;; get categories
(setq mycategory (org-get-category))
;; get start and end of tree
(org-back-to-heading t)
(setq mystart (point))
(org-end-of-subtree)
(setq myend (point))
(goto-char mystart)
;; search for timerange
(setq myresult (re-search-forward org-tstr-regexp myend t))
;; search for categories to exclude
(setq mycatp (member mycategory org-export-exclude-category))
;; return t if ok, nil when not ok
(if (and myresult (not mycatp)) t nil)))
;; activate filter and call export function
(defun org-mycal-export ()
(let ((org-icalendar-verify-function 'org-mycal-export-limit))
(org-export-icalendar-combine-agenda-files)))org-mode export of calendar events to Google
http://orgmode.org/worg/org-tutorials/org-google-sync.html
Categories that should be excluded
(setq org-export-exclude-category (list "google" "private"))Ignore :noexport: entries in iCal-export
http://comments.gmane.org/gmane.emacs.orgmode/36415
(setq org-icalendar-honor-noexport-tag t)iCal-export
http://comments.gmane.org/gmane.emacs.orgmode/19148
(setq org-icalendar-categories (quote (all-tags category)))'(org-icalendar-include-body 42) ;; 2020-02-24: reduced from 1000 to 42 (recommended by Bastien)
'(org-icalendar-include-sexps nil)
'(org-icalendar-include-todo nil)
'(org-icalendar-store-UID t)
'(org-icalendar-timezone "Europe/Berlin")
'(org-icalendar-use-deadline (quote (event-if-not-todo event-if-todo)))
'(org-icalendar-use-plain-timestamp nil)
'(org-icalendar-use-scheduled (quote (event-if-not-todo event-if-todo)))(setq org-agenda-before-write-hook nil);; 2020-02-24: recommended by BastienTables
(setq org-table-export-default-format "orgtbl-to-csv")orgaggregate - Aggregate Values in a Table
https://github.com/tbanel/orgaggregate «Aggregating a table is creating a new table by computing sums, averages, and so on, out of material from the first table.»
(use-package orgtbl-aggregate
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/orgaggregate/")))
)
;won't work; (use-package org-insert-dblock
;won't work; :load-path "~/.emacs.d/contrib/orgaggregate/"
;won't work; )
(my-load-local-el "contrib/orgaggregate/org-insert-dblock.el")Sticky header lines
| 2020-02-06 | moved from org-table-sticky-header to org-table-header-line-mode |
| 2021-01-01 | moved back to org-table-sticky-header because I can’t make it work |
A minor mode to show the sticky header for org-mode tables.
(use-package org-table-sticky-header
:ensure t
:config
(add-hook 'org-mode-hook 'org-table-sticky-header-mode)
)2020-02-01: According to this toot, this should be replaced by
standard feature M-x org-table-electric-header-mode. Will have to
check after I got this Org version. Already renamed, it’s now
`org-table-header-line-mode`.
2020-02-06: this does not seem to be in my code so far. I keep it until it “appears”. It is reported to be part of Org v9.4.
2020-05-16: It’s now part of Org mode maint git branch. Beginning to test this feature …
2021-01-01: I don’t know why but this did never work.
org-table-header-line-mode was somehow nil all the time. When
enabled manually, sticky headers were not working as well. Maybe it
would have required a restart. Anyhow, since org-table-sticky-header
worked flowelessly for years, I go back for now.
(setq org-table-header-line-mode t)
(setq org-table-sticky-header-mode t)see internal note id:2020-02-09-Upgrade-org-mode-for-org-table-header-line-mode
patching orgtbl-ascii-draw to accept references for min/max values
I created an issue on Github with a feature request which was posted as a patch by the original author.
Here, I apply the patch by overwriting the orgmode function:
(defun orgtbl-ascii-draw (value min max &optional width characters)
"Draw an ascii bar in a table.
VALUE is the value to plot, it determines the width of the bar to draw.
MIN is the value that will be displayed as empty (zero width bar).
MAX is the value that will draw a bar filling all the WIDTH.
WIDTH is the span in characters from MIN to MAX.
CHARACTERS is a string that will compose the bar, with shades of grey
from pure white to pure black. It defaults to a 10 characters string
of regular ascii characters."
(let* ((width (ceiling (or width 12)))
(characters (or characters " .:;c!lhVHW"))
(len (1- (length characters)))
(value (float (if (numberp value)
value (string-to-number value))))
(min (float (if (numberp min) ;; <------ patch
min (string-to-number min))))
(max (float (if (numberp max) ;; <------ patch
max (string-to-number max))))
(relative (/ (- value min) (- max min)))
(steps (round (* relative width len))))
(cond ((< steps 0) "too small")
((> steps (* width len)) "too large")
(t (let* ((int-division (/ steps len))
(remainder (- steps (* int-division len))))
(concat (make-string int-division (elt characters len))
(string (elt characters remainder))))))))This can be removed when the patch hits orgmode/maint in git.
my-thousands-separate()
Formats a long number with thousands separator like 1,234,567.89.
This can not be taken as input for further calculations!
From: https://stackoverflow.com/questions/35661173/how-to-format-table-fields-as-currency-in-org-mode
(defun my-thousands-separate (num)
"Formats the (possibly floating point) number with a thousands
separator."
(let* ((nstr (number-to-string num))
(dot-ind (string-match "\\." nstr))
(nstr-no-decimal (if dot-ind
(substring nstr 0 dot-ind)
nstr))
(nrest (if dot-ind
(substring nstr dot-ind)
nil))
(pretty nil)
(cnt 0))
(dolist (c (reverse (append nstr-no-decimal nil)))
(if (and (zerop (% cnt 3)) (> cnt 0))
(setq pretty (cons ?, pretty)))
(setq pretty (cons c pretty))
(setq cnt (1+ cnt)))
(concat pretty nrest)))| Item | Quantity | Price | Ext |
|---|---|---|---|
| Widget 1 | 10 | 1001001.00 | 10010010.00 |
| Widget 2 | 5 | 501001.00 | 2505005.00 |
| Widget 3 | 1 | 51001.00 | 51001.00 |
| Total | 12,566,016.0 |
Exporting
Not necessary any more:
;;(require 'ox-beamer)
;;(require 'ox-odt)
;;(require 'ox-freemind)
;;(require 'ox-taskjuggler)Add bibtex to pdf export method:
- http://orgmode.org/worg/exporters/anno-bib-template-worg.html#sec-5
- see id:2015-03-21-org-reftex-export
(when (my-eval-if-binary-or-warn "pdflatex")
(setq org-latex-pdf-process
'("pdflatex -interaction nonstopmode -output-directory %o %f"
"bibtex %b"
"pdflatex -interaction nonstopmode -output-directory %o %f"
"pdflatex -interaction nonstopmode -output-directory %o %f"))
)Guess the master file for FILENAME from currently open files according to their extension
- disabled 2015-03-22 because it did not help
(add-hook 'org-mode-hook
(lambda ()
(setq TeX-master (guess-TeX-master (buffer-file-name)))
(message (concat "set master file to: " buffer-file-name))
)
)Export subtree (by default) instead of whole buffer: http://orgmode.org/manual/The-Export-Dispatcher.html
(setq org-export-initial-scope 'subtree)With a densly interconnected Org knowledge-base (e.g., see
org-super-links) and a “few but large Org mode files” in combination
with “I’m using export methods on sub-heading levels mostly”, you end
up with errors that are caused by links that link stuff which is
outside of the sub-heading hierarchy which should be currently
exported.
Therefore, you’ll need this setting for preventing those errors. Please be aware that you won’t get notified when links that should be part of the export result get broken because of a typo or similar.
(setq org-export-with-broken-links t)using alternative LaTeX exporter
For the records:
invoke: M-x org-export-dispatch
(require 'org-export)
(require 'org-e-latex)- http://orgmode.org/worg/exporters/beamer/ox-beamer.html
- new LaTeX exporter: beamer
(require 'ox-latex)
(add-to-list 'org-latex-classes
'("beamer"
"\\documentclass\[presentation\]\{beamer\}"
("\\section\{%s\}" . "\\section*\{%s\}")
("\\subsection\{%s\}" . "\\subsection*\{%s\}")
("\\subsubsection\{%s\}" . "\\subsubsection*\{%s\}")))
- adding ACM export class format
- compare: http://orgmode.org/worg/org-tutorials/org-latex-export.html
(unless (boundp 'org-export-latex-classes)
(setq org-export-latex-classes nil))
(add-to-list 'org-export-latex-classes
'("article"
"\\documentclass{article}"
("\\section{%s}" . "\\section*{%s}")))org-export-latex-classes → koma-article
(add-to-list 'org-export-latex-classes
'("koma-article"
"\\documentclass{scrartcl}
[NO-DEFAULT-PACKAGES]
[EXTRA]"
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
("\\paragraph{%s}" . "\\paragraph*{%s}")
("\\subparagraph{%s}" . "\\subparagraph*{%s}")))org-export-latex-classes → ACM
(add-to-list 'org-export-latex-classes
'("ACM"
"\\documentclass{acm_proc_article-sp}
[NO-DEFAULT-PACKAGES]
[EXTRA]"
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
("\\paragraph{%s}" . "\\paragraph*{%s}")
("\\subparagraph{%s}" . "\\subparagraph*{%s}")))LaTeX classes
http://orgmode.org/org.html#Header-and-sectioning
BEGIN of LaTeX class definitions
(when (my-eval-if-binary-or-warn "pdflatex")
(with-eval-after-load 'ox-latex
;;(message (concat "################################################\norg-latex-classes = [" org-latex-classes "]"))Customized «scrartcl»
(add-to-list 'org-latex-classes
'("scrartcl"
"\\documentclass\[a4paper,parskip=half\]\{scrartcl\}"
("\\section\{%s\}" . "\\section*\{%s\}")
("\\subsection\{%s\}" . "\\subsection*\{%s\}")
("\\subsubsection\{%s\}" . "\\subsubsection*\{%s\}")))«scrartclsmall»
- 2014-10-16: does NOT work yet. Most probably because savetrees does not work well with inputenc
(add-to-list 'org-latex-classes
'("scrartclsmall"
"\\documentclass\[a4paper,parskip=half\]\{scrartcl\}\\usepackage\{savetrees\}"
("\\section\{%s\}" . "\\section*\{%s\}")
("\\subsection\{%s\}" . "\\subsection*\{%s\}")
("\\subsubsection\{%s\}" . "\\subsubsection*\{%s\}")))«detego»
- 2017-09-13:
(add-to-list 'org-latex-classes
'("detego"
"\\documentclass\[a4paper,parskip=half,11pt,headinclude=false,footinclude=false\]\{scrartcl\}
\\usepackage\[ngerman,american\]\{babel\}\\usepackage\{eurosym\}\\usepackage\{xspace\}\\usepackage\[usenames,dvipsnames\]\{xcolor\}
\\usepackage\[protrusion=true,factor=900\]\{microtype\}\\usepackage\{enumitem\}
\\definecolor\{DispositionColor\}\{RGB\}\{0,54,90\}
\\usepackage\{helvet\}
\\renewcommand\{\\familydefault\}\{\\sfdefault\}
\\DeclareRobustCommand\{\\myacro\}\[1\]\{\\textsc\{\\lowercase\{#1\}\}\} %% abbrevations using small caps
\\usepackage{scrlayer-scrpage} \\rehead{\\includegraphics\[height=1cm\]{{c:/Users/karl.voit/.emacs.d/bin/images/Detego-Logo-209x41.png}}} \\pagestyle{scrheadings} %% Logo in header
\\newenvironment{NOTES}{}{} %% declares org-reveal environment in PDF output
\\usepackage[space]{grffile} %% enable spaces in filenames of includegraphics
%% colorful headings:
%\\setheadsepline\{.4pt\}\[\\color\{DispositionColor\}\]
\\renewcommand\{\\headfont\}\{\\normalfont\\sffamily\\color\{DispositionColor\}\}
\\renewcommand\{\\pnumfont\}\{\\normalfont\\sffamily\\color\{DispositionColor\}\}
\\addtokomafont\{disposition\}\{\\color\{DispositionColor\}\}
\\addtokomafont\{caption\}\{\\color\{DispositionColor\}\\footnotesize\}
\\addtokomafont\{captionlabel\}\{\\color\{DispositionColor\}\}
\\usepackage\{enumitem\}
\\setlist\{noitemsep\} %% kills the space between items
"
("\\section\{%s\}" . "\\section*\{%s\}")
("\\subsection\{%s\}" . "\\subsection*\{%s\}")
("\\subsubsection\{%s\}" . "\\subsubsection*\{%s\}")))«rise»
- 2019-12-16
(add-to-list 'org-latex-classes
'("rise"
"\\documentclass\[a4paper,parskip=half,11pt,headinclude=false,footinclude=false\]\{scrartcl\}
\\usepackage\[ngerman,american\]\{babel\}\\usepackage\{eurosym\}\\usepackage\{xspace\}\\usepackage\[usenames,dvipsnames\]\{xcolor\}
\\usepackage\[protrusion=true,factor=900\]\{microtype\}\\usepackage\{enumitem\}
\\definecolor\{DispositionColor\}\{RGB\}\{0,54,90\}
\\usepackage\{helvet\}
\\renewcommand\{\\familydefault\}\{\\sfdefault\}
\\DeclareRobustCommand\{\\myacro\}\[1\]\{\\textsc\{\\lowercase\{#1\}\}\} %% abbrevations using small caps
\\usepackage{scrlayer-scrpage} \\rehead{\\includegraphics\[height=1cm\]{{c:/Users/karl.voit/.emacs.d/bin/images/RISE_logo_202x500.jpeg}}} \\pagestyle{scrheadings} %% Logo in header
\\newenvironment{NOTES}{}{} %% declares org-reveal environment in PDF output
\\usepackage[space]{grffile} %% enable spaces in filenames of includegraphics
%% colorful headings:
%\\setheadsepline\{.4pt\}\[\\color\{DispositionColor\}\]
\\renewcommand\{\\headfont\}\{\\normalfont\\sffamily\\color\{DispositionColor\}\}
\\renewcommand\{\\pnumfont\}\{\\normalfont\\sffamily\\color\{DispositionColor\}\}
\\addtokomafont\{disposition\}\{\\color\{DispositionColor\}\}
\\addtokomafont\{caption\}\{\\color\{DispositionColor\}\\footnotesize\}
\\addtokomafont\{captionlabel\}\{\\color\{DispositionColor\}\}
\\usepackage\{enumitem\}
\\setlist\{noitemsep\} %% kills the space between items
"
("\\section\{%s\}" . "\\section*\{%s\}")
("\\subsection\{%s\}" . "\\subsection*\{%s\}")
("\\subsubsection\{%s\}" . "\\subsubsection*\{%s\}")))«lyrics»
- 2017-03-23: 2-column layout sans-serif for lyrics
(add-to-list 'org-latex-classes
'("lyrics"
"\\documentclass\[a4paper,parskip=half\]\{scrartcl\}\\usepackage\{savetrees\}
\\usepackage\{lmodern\} \\renewcommand*\\sfdefault\{lcmss\} \\renewcommand*\\familydefault\{\\sfdefault\}"
("\\section\{%s\}" . "\\section*\{%s\}")
("\\subsection\{%s\}" . "\\subsection*\{%s\}")
("\\subsubsection\{%s\}" . "\\subsubsection*\{%s\}")))«lyrics2» 2 column version of «lyrics»
(add-to-list 'org-latex-classes
'("lyrics2"
"\\documentclass\[a4paper,parskip=half,twocolumn\]\{scrartcl\}\\usepackage\{savetrees\}
\\usepackage\{lmodern\} \\renewcommand*\\sfdefault\{lcmss\} \\renewcommand*\\familydefault\{\\sfdefault\}"
("\\section\{%s\}" . "\\section*\{%s\}")
("\\subsection\{%s\}" . "\\subsection*\{%s\}")
("\\subsubsection\{%s\}" . "\\subsubsection*\{%s\}")))
Adding TUGRAZ letter export class format
(add-to-list 'org-export-latex-classes
'("TUGRAZletter"
"\\documentclass{scrlttr2}
\\usepackage{tugrazletter}
[NO-DEFAULT-PACKAGES]
[EXTRA]"
("\\section{%s}" . "\\section*{%s}")))END of LaTeX class definitions
);; with-eval-after-load
);; if pdflatex is foundhtmlize
htmlize is an HTML export functionality used by org-reveal or ox-clip (when not in org-mode).
(use-package htmlize
:ensure t
:defer 110
:config
(require 'htmlize)
)ox-slack
From GitHub: derived from MD export but optimized for syntax sub-set of slack.
This package provides the interactive function
org-slack-export-to-clipboard-as-slack, which copies the region to the kill-ring in slack format. From there it should be easy to paste the resultant text into your slack client.
ox-gfm (GitHub flavoured markdown) is needed for ox-slack:
(use-package ox-gfm
:defer 110
:ensure t ;; install package if not found OR: (setq use-package-always-ensure t)
:if (my-system-type-is-windows)
)(use-package ox-slack
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/ox-slack/")))
:defer 110
:if (my-system-type-is-windows)
)ox-pandoc - Export via Pandoc
https://github.com/kawabata/ox-pandoc - «This is another exporter that translates Org-mode file to various other formats via Pandoc.»
(when (my-eval-if-binary-or-warn "pandoc")
(use-package ox-pandoc
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/ox-pandoc/")))
:ensure t ;; install package if not found OR: (setq use-package-always-ensure t)
:defer 110
;; :if (or (my-system-type-is-gnu) (my-system-type-is-windows))
:init
;; define the list of entries manually because the default one is somewhat arbitrary: https://github.com/kawabata/ox-pandoc/issues/9
;; for example, markdown was missing in my list
;; see also id:2018-07-14-markdown-missing-in-ox-pandoc
;; export-to vs. export-as → file vs. buffer
(setq org-pandoc-menu-entry
'(
(?x "to docx and open." org-pandoc-export-to-docx-and-open)
(?X "to docx." org-pandoc-export-to-docx)
(?r "to revealjs and open." org-pandoc-export-to-revealjs-and-open)
(?R "as revealjs." org-pandoc-export-as-revealjs)
(?o "to odt and open." org-pandoc-export-to-odt-and-open)
(?O "to odt." org-pandoc-export-to-odt)
(?8 "to opendocument and open." org-pandoc-export-to-opendocument-and-open)
(?8 "to opendocument." org-pandoc-export-to-opendocument)
;;(?( "as opendocument." org-pandoc-export-as-opendocument)
;;(?0 "to jats." org-pandoc-export-to-jats)
;;(?0 "to jats and open." org-pandoc-export-to-jats-and-open)
;;(? "as jats." org-pandoc-export-as-jats)
;;(?2 "to tei." org-pandoc-export-to-tei)
;;(?2 "to tei and open." org-pandoc-export-to-tei-and-open)
;;(?" "as tei." org-pandoc-export-as-tei)
(?l "to latex-pdf and open." org-pandoc-export-to-latex-pdf-and-open)
(?L "to latex-pdf." org-pandoc-export-to-latex-pdf)
;;(?k "to markdown." org-pandoc-export-to-markdown)
(?k "to markdown and open." org-pandoc-export-to-markdown-and-open)
(?K "as markdown." org-pandoc-export-as-markdown)
;;(?3 "to markdown_mmd." org-pandoc-export-to-markdown_mmd)
(?m "to markdown_mmd and open." org-pandoc-export-to-markdown_mmd-and-open)
(?M "as markdown_mmd. (reddit|Wiki.js)" org-pandoc-export-as-markdown_mmd)
(?s "to markdown_strict & open" org-pandoc-export-to-markdown_strict-and-open)
(?S "as markdown_strict." org-pandoc-export-as-markdown_strict)
;;(?: "to rst." org-pandoc-export-to-rst)
(?1 "to rst and open." org-pandoc-export-to-rst-and-open)
(?2 "as rst." org-pandoc-export-as-rst)
;;(?p "to plain." org-pandoc-export-to-plain)
(?p "to plain and open." org-pandoc-export-to-plain-and-open)
(?P "as plain." org-pandoc-export-as-plain)
;;(?4 "to html5." org-pandoc-export-to-html5)
(?h "to html5 and open." org-pandoc-export-to-html5-and-open)
(?H "as html5." org-pandoc-export-as-html5)
(?3 "to html5-pdf and open." org-pandoc-export-to-html5-pdf-and-open)
(?4 "to html5-pdf." org-pandoc-export-to-html5-pdf)
;;(?6 "to markdown_phpextra." org-pandoc-export-to-markdown_phpextra)
;;(?6 "to markdown_phpextra and open." org-pandoc-export-to-markdown_phpextra-and-open)
;;(?& "as markdown_phpextra." org-pandoc-export-as-markdown_phpextra)
;;(?7 "to markdown_strict." org-pandoc-export-to-markdown_strict)
;;(?9 "to opml." org-pandoc-export-to-opml)
;;(?9 "to opml and open." org-pandoc-export-to-opml-and-open)
;;(?\) "as opml." org-pandoc-export-as-opml)
;;(?< "to slideous." org-pandoc-export-to-slideous)
;;(?< "to slideous and open." org-pandoc-export-to-slideous-and-open)
;;(?, "as slideous." org-pandoc-export-as-slideous)
(?= "to ms-pdf and open." org-pandoc-export-to-ms-pdf-and-open)
(?- "to ms-pdf." org-pandoc-export-to-ms-pdf)
;;(?> "to textile." org-pandoc-export-to-textile)
(?t "to textile and open." org-pandoc-export-to-textile-and-open)
(?T "as textile." org-pandoc-export-as-textile)
;;(?a "to asciidoc." org-pandoc-export-to-asciidoc)
(?a "to asciidoc and open." org-pandoc-export-to-asciidoc-and-open)
(?A "as asciidoc." org-pandoc-export-as-asciidoc)
(?b "to beamer-pdf and open." org-pandoc-export-to-beamer-pdf-and-open)
(?B "to beamer-pdf." org-pandoc-export-to-beamer-pdf)
;;(?c "to context-pdf and open." org-pandoc-export-to-context-pdf-and-open)
;;(?C "to context-pdf." org-pandoc-export-to-context-pdf)
;;(?d "to docbook5." org-pandoc-export-to-docbook5)
(?d "to docbook5 and open." org-pandoc-export-to-docbook5-and-open)
(?D "as docbook5." org-pandoc-export-as-docbook5)
(?e "to epub3 and open." org-pandoc-export-to-epub3-and-open)
(?E "to epub3." org-pandoc-export-to-epub3)
;;(?f "to fb2." org-pandoc-export-to-fb2)
;;(?f "to fb2 and open." org-pandoc-export-to-fb2-and-open)
;;(?F "as fb2." org-pandoc-export-as-fb2)
;;(?g "to gfm." org-pandoc-export-to-gfm)
;;(?g "to gfm and open." org-pandoc-export-to-gfm-and-open)
;;(?G "as gfm." org-pandoc-export-as-gfm)
;;(?h "to html4." org-pandoc-export-to-html4)
(?h "to html4 and open." org-pandoc-export-to-html4-and-open)
(?H "as html4." org-pandoc-export-as-html4)
;;(?i "to icml." org-pandoc-export-to-icml)
;;(?i "to icml and open." org-pandoc-export-to-icml-and-open)
;;(?I "as icml." org-pandoc-export-as-icml)
;;(?j "to json." org-pandoc-export-to-json)
(?j "to json and open." org-pandoc-export-to-json-and-open)
(?J "as json." org-pandoc-export-as-json)
;;(?m "to man." org-pandoc-export-to-man)
;;(?m "to man and open." org-pandoc-export-to-man-and-open)
;;(?M "as man." org-pandoc-export-as-man)
;;(?n "to native." org-pandoc-export-to-native)
;;(?n "to native and open." org-pandoc-export-to-native-and-open)
;;(?N "as native." org-pandoc-export-as-native)
;;(?q "to commonmark." org-pandoc-export-to-commonmark)
;;(?q "to commonmark and open." org-pandoc-export-to-commonmark-and-open)
;;(?Q "as commonmark." org-pandoc-export-as-commonmark)
;;(?r "to rtf." org-pandoc-export-to-rtf)
(?f "to rtf and open." org-pandoc-export-to-rtf-and-open)
(?F "as rtf." org-pandoc-export-as-rtf)
;;(?s "to s5." org-pandoc-export-to-s5)
;;(?s "to s5 and open." org-pandoc-export-to-s5-and-open)
;;(?S "as s5." org-pandoc-export-as-s5)
;;(?t "to texinfo." org-pandoc-export-to-texinfo)
;;(?t "to texinfo and open." org-pandoc-export-to-texinfo-and-open)
;;(?T "as texinfo." org-pandoc-export-as-texinfo)
;;(?u "to dokuwiki." org-pandoc-export-to-dokuwiki)
(?u "to dokuwiki and open." org-pandoc-export-to-dokuwiki-and-open)
(?U "as dokuwiki." org-pandoc-export-as-dokuwiki)
;;(?v "to revealjs." org-pandoc-export-to-revealjs)
;;(?w "to mediawiki." org-pandoc-export-to-mediawiki)
(?5 "to mediawiki and open." org-pandoc-export-to-mediawiki-and-open)
(?6 "as mediawiki." org-pandoc-export-as-mediawiki)
;;(?y "to slidy." org-pandoc-export-to-slidy)
;;(?y "to slidy and open." org-pandoc-export-to-slidy-and-open)
;;(?Y "as slidy." org-pandoc-export-as-slidy)
;;(?z "to dzslides." org-pandoc-export-to-dzslides)
;;(?z "to dzslides and open." org-pandoc-export-to-dzslides-and-open)
;;(?Z "as dzslides." org-pandoc-export-as-dzslides)
;;(?{ "to muse." org-pandoc-export-to-muse)
;;(?{ "to muse and open." org-pandoc-export-to-muse-and-open)
;;(?[ "as muse." org-pandoc-export-as-muse)
;;(?} "to zimwiki." org-pandoc-export-to-zimwiki)
;;(?} "to zimwiki and open." org-pandoc-export-to-zimwiki-and-open)
;;(?] "as zimwiki." org-pandoc-export-as-zimwiki)
;;(?~ "to haddock." org-pandoc-export-to-haddock)
;;(?~ "to haddock and open." org-pandoc-export-to-haddock-and-open)
;;(?^ "as haddock." org-pandoc-export-as-haddock)
(?7 "to epub2 and open." org-pandoc-export-to-epub2-and-open)
(?8 "to epub2." org-pandoc-export-to-epub2)
(?9 "Slack (clipboard)" org-slack-export-to-clipboard-as-slack)
(?0 "as Slack" org-slack-export-as-slack)
)
)
)
)ox-asciidoc - Export to AsciiDoc
https://github.com/yashi/org-asciidoc - «An Org Mode Exporter Backend For AsciiDoc»
(use-package ox-asciidoc
;;:ensure t ;; install package if not found OR: (setq use-package-always-ensure t)
:defer 110
)ox-rst - Export to reStructuredText
2019-09-28: disabled because I don’t need it at the moment
https://github.com/msnoigrs/ox-rst
(my-load-local-el "contrib/ox-rst/ox-rst.el")
(require 'ox-rst)FIXXME: I don’t know why loading via use-package is not working with
this one: package-compute-transaction: Package ‘ox-rst-’ is
unavailable
(use-package ox-rst
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/ox-rst/")))
:ensure t ;; install package if not found OR: (setq use-package-always-ensure t)
:defer 110
:if (my-system-type-is-windows)
)Org-Reveal - generate nice presentations out of Org-mode
https://github.com/yjwen/org-reveal
Reveal.jsis a tool for creating good-looking HTML presentations, authored by Hakim El Hattab.- For an example of a reveal.js presentation, see here.
Org-Revealexports your Org documents to reveal.js presentations.- With Org-reveal, you can create beautiful presentations with 3D effects from simple but powerful Org contents.
(use-package ox-reveal
:ensure t
;;:if (my-system-type-is-windows)
:defer 110
:config
;;(setq org-reveal-root "file:///d:/reveal.js")
(cond ((my-system-type-is-gnu)
(setq org-reveal-root "https://cdn.jsdelivr.net/npm/reveal.js")
(setq org-reveal-extra-css "file:///home/vk/.emacs.d/bin/reveal_theme_night_local.css"))
((string-equal system-name "GRZN17009")
(setq org-reveal-root "file:///C:/Users/karl.voit/.emacs.d/bin/reveal.js/")
(setq org-reveal-extra-css "file:///C:/Users/karl.voit/.emacs.d/bin/reveal_theme_night_local.css"))
((string-equal system-name "cosmo")
(setq org-reveal-root "file:///C:/Users/John/AppData/Roaming/.emacs.d/bin/reveal.js/")
(setq org-reveal-extra-css "file:///C:/Users/John/AppData/Roaming/.emacs.d/bin/reveal_theme_night_local.css"))
(t
(setq org-reveal-root "http://cdn.jsdelivr.net/reveal.js/3.0.0/"))
)
;; my preferred defaults:
(setq org-reveal-hlevel 2)
(setq org-reveal-postamble "<p> Created by Karl. </p>")
(setq org-reveal-center nil)
(setq org-reveal-progress t)
(setq org-reveal-history nil)
(setq org-reveal-control t)
(setq org-reveal-keyboard t)
(setq org-reveal-overview nil)
(setq org-reveal-transition "default")
;; - transitions:
;; - default
;; - cube
;; - page
;; - concave
;; - zoom
;; - linear
;; - fade
;; - none
(setq org-reveal-theme "night")
;; - Styles:
;; - black (default)
;; - white
;; - league
;; - gray one
;; - sky
;; - nice bright one
;; - beige
;; - nice bright one
;; - simple
;; - bright
;; - serif
;; - old school
;; - blood
;; - cool!
;; - *night*
;; - very nice
;; - moon
;; - solarized
)ox-clip - formatted copy from Org-mode to system clipboard
This module copies selected regions in org-mode as formatted text on the clipboard that can be pasted into other applications. When not in org-mode, the htmlize library is used instead.
For Windows the html-clip-w32.py script will be installed. It works pretty well, but I noticed that the hyperlinks in the TOC to headings don’t work, and strike-through doesn’t seem to work. I have no idea how to fix either issue.
Mac OSX needs textutils and pbcopy, which should be part of the base install.
Linux needs a relatively modern xclip. https://github.com/astrand/xclip
There is one command: `ox-clip-formatted-copy’ that should work across Windows, Mac and Linux.
(require ‘htmlize)
- https://libraries.io/emacs/ox-clip
- https://github.com/jkitchin/scimax
- use: M-x ox-clip-formatted-copy
- 2017-11-20: moved from ELPA package to a checkout from https://github.com/jkitchin/ox-clip
- resulted in:
[...] config • ox-clip - formatted copy from Org-mode to system clipboard … Importing package-keyring.gpg...done ad-handle-definition: ‘url-cache-extract’ got redefined Contacting host: jorgenschaefer.github.io:443 gnutls.c: [1] (Emacs) GnuTLS library not found Opening TLS connection to ‘jorgenschaefer.github.io’... Opening TLS connection with ‘gnutls-cli --x509cafile /usr/ssl/certs/ca-bundle.crt -p 443 jorgenschaefer.github.io’...done Opening TLS connection to ‘jorgenschaefer.github.io’...done Contacting host: jorgenschaefer.github.io:443 Contacting host: orgmode.org:80 Contacting host: stable.melpa.org:80 Contacting host: elpa.gnu.org:80 Package refresh done Setting ‘package-selected-packages’ temporarily since "emacs -q" would overwrite customizations For information about GNU Emacs and the GNU system, type C-h C-a. <C-lwindow> is undefined Error running timer ‘require’: (error "Unknown keyword: :export-block") - I’ll have to re-check later-on when I’ve time to fix this.
- resulted in:
(when (or
(and (my-system-type-is-gnu) (my-eval-if-binary-or-warn "xclip") (not (my-system-is-karl-voit-at)))
(and (my-system-type-is-darwin) (my-eval-if-binary-or-warn "textutils") (my-eval-if-binary-or-warn "pbcopy"))
(my-system-type-is-windows);; For Windows the html-clip-w32.py script will be installed.
)
(use-package ox-clip
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/ox-clip/")))
;;:if
:ensure t
:defer 110
)
)lazyblorg
I wrote my own blogging system named lazyblorg and generate my own blog with it.
my-lazyblorg-test() - blog article preview
When writing a blog article, this function generates a local version of the blog article and shows it in the browser.
(if (my-system-type-is-gnu)
(defun my-lazyblorg-test()
"Saves current blog entry to file and invoke lazyblorg process with it"
(interactive)
(save-excursion
(search-backward ":blog:");; search begin of current (previous) blog entry
(beginning-of-line nil)
(set-mark-command nil);; set mark
(org-cycle);; close org-mode heading and sub-headings
(next-line);; goto next org-mode heading (this should be next line after blog entry)
(beginning-of-line nil)
(let ((p (point));; copy region
(m (mark)))
(if (< p m)
(kill-ring-save p m)
(kill-ring-save m p)))
(find-file "/tmp/lazyblorg-preview.org");; fixed temporary file (will be overwritten)
(erase-buffer);; I told you!
(yank);; paste region from above
(save-buffer);; save to disk
(kill-buffer "lazyblorg-preview.org");; destroy last evidence
(previous-line);;
(org-cycle);; close org-mode heading and sub-headings
;; invoke lazyblorg:
(shell-command-to-string "/home/vk/src/lazyblorg/preview_blogentry.sh");; invoke shell script
)
)
)my-jump-to-lazyblorg-heading-according-to-URL-in-clipboard() → my-map l
One of the advantages of lazyblorg is, that a blog entry can be written anywhere in my Org-mode files. This is great for composing blog articles but not so great for locating it in my Org-mode files when I need to access the source of an article.
Therefore, I wrote the following function. The process is now very easy: I locate the article (using my blog search?) in the web browser. Then I copy the URL to the system clipboard. I switch to Emacs and call the function below to jump to the article. Easy as that. :-)
Gets “public voit”-URL from clipboard and jumps to its Org-mode heading:
- 2015-05-23: adapted from: http://www.rexim.me/emacs-as-bookmark-manager-links.html
(defun my-jump-to-lazyblorg-heading-according-to-URL-in-clipboard ()
"Retrieves an URL from the clipboard, gets its Org-mode source,
extracts the ID of the article and jumps to its Org-mode heading"
(interactive)
(let (
;; Getting URL from the clipboard. Since it may contain
;; some text properties we are using substring-no-properties
;; function
(url (substring-no-properties (current-kill 0)))
;; This is a check string: if the URL in the clipboard
;; doesn't start with this, an error message is shown
(domain "karl-voit.at")
)
;; Check if URL string is from my domain (all other strings do
;; not make any sense here)
(if (string-match (upcase domain) (upcase url))
;; Retrieving content by URL into new buffer asynchronously
(url-retrieve url
;; call this lambda function when URL content is retrieved
(lambda (status)
;; Extrating and preparing the ID
(let* (
;; Limit the ID search to the top 1000 characters of the buffer
(pageheader (buffer-substring 1 1000))
;; Start index of the id
(start (string-match "<meta name=\"orgmode-id\" content=\"" pageheader))
;; End index of the id
(end (string-match "\" />" pageheader start))
;; Amount of characters to skip for the openning tag
(chars-to-skip (length "<meta name=\"orgmode-id\" content=\""))
;; Extract ID
(lazyblorg-id (if (and start end (< start end))
;; ... extract it and return.
(substring pageheader (+ start chars-to-skip) end)
nil))
)
(message (concat "Looking for id:" lazyblorg-id " ..."))
(org-open-link-from-string (concat "id:" lazyblorg-id))
)
)
)
(message (concat "Sorry: the URL \"" (substring url 0 (length domain)) "...\" doesn't contain \"" domain "\". Aborting."))
;;(message (concat "domain: " domain))
;;(message (concat "url: " url))
)
)
)binding the function: 2021-07-07 disabled because I’m happy with M-x ... and I don’t use this binding
(bind-key "l" #'my-jump-to-lazyblorg-heading-according-to-URL-in-clipboard my-map)ox-koma-letter
2019-09-28: disabled because I don’t need it at the moment.
I configured the KOMA letter exporter according to this page.
You can get a default drawer template by invoking C-c C-e for export
and then choose # and koma-letter.
FIXXME: there is a big KOMA letter on the result page which I don’t know how to get rid of.
(use-package ox-koma-letter
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/org-contrib/lisp/")))
)
(eval-after-load 'ox '(require 'ox-koma-letter))I prefer the language German in my letters:
(eval-after-load 'ox-koma-letter
'(progn
(add-to-list 'org-latex-classes
'("my-letter"
"\\documentclass\{scrlttr2\}
\\usepackage[german]{babel}
\\setkomavar{frombank}{(1234)\\,567\\,890}
\[DEFAULT-PACKAGES]
\[PACKAGES]
\[EXTRA]"))
(setq org-koma-letter-default-class "my-letter")))Contact management
Yes, of course I do manage contact data about people within Org-mode.
See http://julien.danjou.info/org-contacts.html
These are rather simple settings for it:
Set org-contacts defaults that differ from standard
(setq org-contacts-address-property "CITY")
(setq org-contacts-birthday-property "BORN")
(setq org-contacts-files (list (concat my-org-files-path "contacts.org")))
(setq org-contacts-icon-property "PHOTOGRAPH")
(custom-set-variables
'(org-contacts-address-property "CITY")
'(org-contacts-birthday-property "BORN")
'(org-contacts-icon-property "PHOTOGRAPH")
)Take a look at my-org-region-to-property() as well.
Loading novoid/helm-org-contacts (a fork of tmalsburg/helm-org-contacts) to quickly link contacts.
(use-package helm-org-contacts
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/helm-org-contacts/")))
:after org
)(defun my-helm-org-contacts-refresh-cache ()
"Wrapper for helm-org-contacts-cache that adds time measurement and logging."
(interactive)
(setq my-helm-org-contacts-refresh-cache-start-time (current-time))
(save-some-buffers t) ;; get latest contact changes
(helm-org-contacts-refresh-cache)
(setq current-timestamp
(concat
(format-time-string "%Y-%m-%dT%T")
((lambda (x) (concat (substring x 0 3) ":" (substring x 3 5)))
(format-time-string "%z"))))
(my-log-misc (format-message "helm-org-contacts-refresh-cache took %.2fs" (float-time (time-subtract (current-time) my-helm-org-contacts-refresh-cache-start-time))))
(when (> (string-to-number (emacs-uptime "%m")) 2) ;; only flash when not part of the boot process (= Emacs runs longer than 2 minutes)
(my-flash (format-message "helm-org-contacts-cache took %.2fs" (float-time (time-subtract (current-time) my-helm-org-contacts-refresh-cache-start-time)))))
)babel - working with source code
Activate Babel languages:
(when (my-system-type-is-windows)
(org-babel-do-load-languages
'org-babel-load-languages
'(
(python . t)
(shell . t)
(org . t)
(emacs-lisp . t)
(sql . t)
;;disabled 2019-06-26;; (restclient . t)
(plantuml . t)
))
)
(when (my-system-type-is-gnu)
(org-babel-do-load-languages
'org-babel-load-languages
'(
; (ipython . t)
(python . t)
(ruby . t)
(gnuplot . t)
(shell . t)
(org . t)
(R . t)
(emacs-lisp . t)
(ditaa . t)
(dot . t)
(plantuml . t)
))
)DISABLED 2018-03-16 because of id:2018-03-16-exports-results-parameter-ignored: Inhibit evaluation of code blocks during export http://orgmode.org/manual/Exporting-code-blocks.html
;; (setq org-export-babel-evaluate nil)The issue with org-export-babel-evaluate set to nil disables the
results parameter may be mitigated by #+Property: header-args :cache
yes according to this page.
Do not prompt to confirm evaluation: This may be dangerous - make sure you understand the consequences of setting this – see the docstring for details
(setq org-confirm-babel-evaluate nil)When some code generates an image file, display it in the results:
(add-hook 'org-babel-after-execute-hook 'org-display-inline-images)http://orgmode.org/manual/Sparse-trees.html#index-org_002dshow_002dentry_002dbelow-179
(setq org-show-entry-below (quote ((default))))see id:2014-12-21-org-screen
(require 'org-screen)
(require 'ob-screen)
(defvar org-babel-default-header-args:screen
'(
(:results . "silent")
(:session . "default")
(:cmd . "/bin/zsh")
(:terminal . "/usr/bin/gnome-terminal"))
"Default arguments to use when running screen source blocks.")http://kitchingroup.cheme.cmu.edu/blog/2014/12/21/Capturing-stderr-from-Python-in-org-mode-take-2/
- 2016-04-08: doesn’t work
(if (my-system-type-is-gnu)
;; does not seem to work with Windows:
(setq org-babel-python-command "python -i -c \"import sys; sys.stderr = sys.stdout\"")
(setq org-babel-python-command "python")
)Switch babel to python 3 (see id:2019-01-26-python3-src-blocks)
Following …
(setq org-babel-python-command "ipython3")… causes an issue on Windows:
print('hello')
Use python3 instead of ipython3:
(setq org-babel-python-command "python3")Note: The general Python interpretor is set elsewhere:
python-shell-interpreter
Redirect stderr to stdout in order to see it in the results: id:2015-01-11-redirect-org-babel-sh-stderr-to-stdout
(if (my-system-type-is-gnu)
;outdated: org-babel-sh-command was removed with org-mode v8.3:
;outdated; (setq org-babel-sh-command
;outdated; "~/bin/zsh_stderr_redirected_to_stdout.sh")
;(setq shell-file-name "~/.emacs.d/bin/zsh_stderr_redirected_to_stdout.sh");; id:2015-01-11-redirect-org-babel-sh-stderr-to-stdout
)re-direct stderr to stdout and add an additional line:
From: Ken Mankoff <mankoff@gmail.com> Newsgroups: gmane.emacs.orgmode Subject: Re: No output from babel shell src block Date: Thu, 12 May 2016 15:36:03 -0400 Message-ID: <m237pn83x8.fsf@gmail.com>
(setq org-babel-default-header-args:sh
'((:prologue . "exec 2>&1") (:epilogue . ":"))
'((:epilogue . ":"))
)ob-async: asynchronous babel execution
https://github.com/astahlman/ob-async
- not yet available as a package
- [ ] re-check availability
- 2018-06-27 no package in my sources yet (again)
(use-package ob-async
:ensure t
:config
(add-to-list 'org-ctrl-c-ctrl-c-hook 'ob-async-org-babel-execute-src-block)
)PlantUML
Forget dot. :-)
PlantUML is a handy tool for drawing simple diagrams. It is part of Org-mode since 2010 and is a wrapper to dot, allowing higher-level definitions.
As an example, the following block gets exported as a cool diagram:
Alice -> Bob: synchronous call
Alice ->> Bob: asynchronous call(require 'ob-plantuml)
(setq org-plantuml-jar-path (concat my-user-emacs-directory "bin/plantuml.jar")) ;; I keep the jar file in my ".emacs.d/bin"For a maximum of editing experience and a very cool preview, you also want to install plantuml-mode:
(use-package plantuml-mode
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/plantuml-mode")))
:config
(my-log-hostspecific "plantuml-mode-version" plantuml-mode-version)
(add-to-list 'auto-mode-alist '("\\.plantuml\\'" . plantuml-mode)) ;; Enable plantuml-mode for PlantUML files
(add-to-list
'org-src-lang-modes '("plantuml" . plantuml))
)M-x plantuml-preview | order of preference: SVG, PNG, ASCII |
|---|---|
C-c C-c | preview: renders a PlantUML diagram from the current buffer in the best supported format |
C-u C-c C-c | preview in other window |
C-u C-u C-c C-c | preview in other frame |
org-crypt
Activate org-crypt if gpg is installed:
(when (my-eval-if-binary-or-warn "gpg")
(require 'org-crypt)Encrypt all entries before saving
(org-crypt-use-before-save-magic)
(setq org-tags-exclude-from-inheritance (quote ("crypt" "project")))GPG key to use for encryption:
Note for Windows 10 users: I had to import the private/secret key to
my pgp4win/Kleopatra key management tool. ~/.gnupg/ or
~/.babun/cygwin/.gnupg/ did not result in Emacs being able to find
the key.
(setq org-crypt-key "77B9E3C5")OLD key:
(setq org-crypt-key "8A614641")encrypting whole files: http://orgmode.org/worg/org-tutorials/encrypting-files.html
(require 'epa-file)disabling auto-save for sensitive files http://anirudhs.chaosnet.org/blog/2005.01.21.html
DISABLED 2020-02-04 because of constand data loss when Emacs crashes.
(define-minor-mode my-sensitive-mode
"For sensitive files like password lists.
It disables backup creation and auto saving.
With no argument, this command toggles the mode.
Non-null prefix argument turns on the mode.
Null prefix argument turns off the mode."
;; The initial value.
nil
;; The indicator for the mode line.
" Sensitive"
;; The minor mode bindings.
nil
(if (symbol-value sensitive-mode)
(progn
;; disable backups
(set (make-local-variable 'backup-inhibited) t)
;; disable auto-save
(if auto-save-default
(auto-save-mode -1)))
;;resort to default value of backup-inhibited
(kill-local-variable 'backup-inhibited)
;;resort to default auto save setting
(if auto-save-default
(auto-save-mode 1))))
;; disabling auto-save for gpg file extension
(setq auto-mode-alist
(append '(("\\.gpg$" . sensitive-mode))
auto-mode-alist)
)Do not ask for disabling auto-save
(setq org-crypt-disable-auto-save nil)From this page: Auto-saving does not cooperate with org-crypt.el: so you need to turn it off if you plan to use org-crypt.el quite often. Otherwise, you’ll get an (annoying) message each time you start Org.
To turn it off only locally, you can insert this:
-*- buffer-auto-save-file-name: nil; -*-
DISABLED 2020-02-04 because of constand data loss when Emacs crashes.
(setq auto-save-default nil)END of org-crypt setup
)Reference management → my-map (|)
Do read http://karl-voit.at/2015/12/26/reference-management-with-orgmode/
I do manage references to white papers and books using a self-made concept based on RefTeX and Org-mode.
If I’d start all over again, I’d take a look at org-ref which was not around yet back then.
Set my default bibliography file:
(setq reftex-default-bibliography '("~/archive/library/references.bib"))Set citation format (no clue what I did here)
(defadvice reftex-format-citation (before eval-citation-format)
(setq format (eval format)))Inserting citations when using and when defining them:
(defun org-mode-reftex-setup ()
(load-library "reftex")
(and (buffer-file-name) (file-exists-p (buffer-file-name))
(progn
;;enable auto-revert-mode to update reftex when bibtex file changes on disk
(global-auto-revert-mode t)
(reftex-parse-all)
;;add a custom reftex cite format to insert links
(reftex-set-cite-format
'((?b . "[[bib:%l][%l.bib]]")
(?c . "[[cite:%l][%l]]")
(?p . "[[pdf:%l][%l.pdf]]")
(?a . "[[notes:%l][%l-notes.pdf]]")
(?s . "[[pdf:%l-self][%l-self.pdf]]")
(?t . "%t")
(?h . (concat "** %l - %t\n:PROPERTIES:\n:CREATED: "
"<" (substring (format-time-string (org-time-stamp-format t t)) 1 -1) ">"
"\n:ID: %l\n:END:\n[[bib:%l][%l.bib]]\n[[pdf:%l][%l.pdf]]\n\n*** Abstract\n\n#+BEGIN_QUOTE\n#+END_QUOTE\n\n"))
(?n . (concat "*** PDF Annotations: [[notes:%l][%l-notes.pdf]]\n:PROPERTIES:\n:CREATED: "
"<" (substring (format-time-string (org-time-stamp-format t t)) 1 -1) ">"
"\n:ID: %l-notes\n:END:\n\n"
"\#+begin_src sh :results output :eval no-export\n"
"${HOME}/bin/vkextract_annotations_to_orgmode_snippet.sh %l\n"
"#+end_src"))
))))Binding the keyboard shortcuts:
(define-key org-mode-map (kbd "C-c )") 'reftex-citation)
(define-key org-mode-map (kbd "C-c (") 'org-mode-reftex-search))- disabled 2015-05-14 - double code from above?
;; http://orgmode.org/worg/org-faq.html#using-reftex-in-org-mode
(defun org-mode-reftex-setup ()
(load-library "reftex")
(and (buffer-file-name)
(file-exists-p (buffer-file-name))
(reftex-parse-all))
(define-key org-mode-map (kbd "C-c )") 'reftex-citation))
disabled 2015-05-14: see id:2015-05-14-disable-orgmode-reftex-autoload
(add-hook 'org-mode-hook 'org-mode-reftex-setup)- disabled 2015-05-14 - I don’t use “CHECK_NEEDED” any more
(add-hook 'org-mode-hook
(lambda ()
(if (member "CHECK_NEEDED" org-todo-keywords-1)
(org-mode-reftex-setup))))org-mode-reftex-search ()
(defun org-mode-reftex-search ()
;;jump to the notes for the paper pointed to at from reftex search
(interactive)
(org-open-link-from-string (format "[[cite:%s]]" (reftex-citation t))))Setup my own org-mode-reftex-setup:
- See also: id:2015-05-14-disable-orgmode-reftex-autoload
(defun org-mode-reftex-setup ()
(setq TeX-master t)
(load-library "reftex")
(and (buffer-file-name)
(file-exists-p (buffer-file-name))
(progn
(reftex-parse-all)
(reftex-set-cite-format "[[cite:%l][%l]]")))
(define-key org-mode-map (kbd "C-c )") 'reftex-citation)
(define-key org-mode-map (kbd "C-c (") 'org-mode-reftex-search))
(add-hook 'org-mode-hook 'org-mode-reftex-setup)
(bind-key (kbd "R") #'org-mode-reftex-setup my-map)
;; 2015-05-14: does NOT work (yet). See id:2015-05-14-disable-orgmode-reftex-autoloadorg-ref
On 2019-09-12, I disabled my DIY-reference-management (above) and started to test drive org-ref. This might not be in a stable status.
Setup according to https://github.com/jkitchin/org-ref:
;; setting the path using the my-org-files-path:
;;(setq reftex-default-bibliography '("~/org/org-ref.bib")) ;; Its value is ("~/org/org-ref.bib")
(setq reftex-default-bibliography `( ,(concat my-org-files-path "org-ref.bib"))) ;; Its value is ("~/org/org-ref.bib")
;; see org-ref for use of these variables
(setq org-ref-bibliography-notes (concat my-org-files-path "org-ref.org") ;;"~/org/org-ref.org"
org-ref-default-bibliography `( ,(concat my-org-files-path "org-ref.bib"))
org-ref-pdf-directory "~/archive/library/org-ref/")
(setq bibtex-completion-bibliography (concat my-org-files-path "org-ref.bib")
bibtex-completion-library-path "~/archive/library/org-ref"
bibtex-completion-notes-path "~/archive/library/helm-bibtex-notes")
;; open pdf with system pdf viewer (works on mac)
(setq bibtex-completion-pdf-open-function
(lambda (fpath)
(start-process "open" "*open*" "open" fpath)))
;; alternative
;; (setq bibtex-completion-pdf-open-function 'org-open-file)
;(setq org-latex-pdf-process (list "latexmk -shell-escape -bibtex -f -pdf %f"))
(require 'org-ref)
(require 'doi-utils)Org-mode docu → my-map o
One of the benefits of Emacs is, that it comes with its complete manual. Same holds for the Org-mode. With this shortcut, I am able to navigate through the org manual instantly:
Append the Org-mode documentation from the git repository to the info-paths:
(autoload 'info "info.el")
(eval-after-load 'info
;;(add-to-list 'Info-additional-directory-list (concat my-user-emacs-directory "contrib/org-mode/doc/")) ;; causes "void-variable" error
(setq Info-additional-directory-list (concat my-user-emacs-directory "contrib/org-mode/doc/"))
)Bind a keyboard shortcut to open the Org manual:
(bind-key (kbd "o") (lambda()
(interactive)
(info "(org)")
)
my-map
)Reading RSS feeds
I did test importing some RSS feeds into Orgmode but the decided to stay with my usual Android RSS reader.
org-feed - aggregating RSS feeds in news.org file:
(setq org-feed-alist
'(
("heise"
"http://www.heise.de/newsticker/heise.rdf"
(concat my-org-files-path "news.org") "heise")
("Dilbert"
"http://feeds.feedburner.com/DilbertDailyStrip"
(concat my-org-files-path "news.org") "Dilbert")
)
)org-protocol-capture-html - turn HTML into Org-mode
https://github.com/alphapapa/org-protocol-capture-html
org-protocol is awesome, but browsers do a pretty poor job of turning a page’s HTML content into plain-text. However, Pandoc supports converting from HTML to org-mode, so we can use it to turn HTML into Org-mode content! It can even turn HTML tables into Org tables!
- see: id:2016-07-10-inst-org-protocol-capture
- I disabled the package because I do have to play around with it to make it work on my hosts.
(when (my-eval-if-binary-or-warn "pandoc")
(use-package org-protocol-capture-html
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/org-protocol-capture-html/")))
)
(require 'org-protocol-capture-html)
)org-mind-map
I found org-mind-map via an article on irreal.
At the moment, I am not planning on using it intensively. It is maybe a cool method to visualize the structure of some Org-mode files of mine for demonstration purposes for novice or non-Org-users.
(use-package org-mind-map
;;:ensure t
:defer 120
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/org-mind-map/")))
:config ;; executed after loading package
)2017-10-14: Unfortunately, I do have issues with this tool so that I had to disable it. Maybe I’d give it another try in a couple of months or so.
org-sidebar
| 2019-12-17 | DISABLED: I don’t need it at the moment |
For testing org-sidebar-tree from https://github.com/alphapapa/org-sidebar
disabled setup via quelpa because of quelpa error (see above):
(use-package org-sidebar
:quelpa (org-sidebar :fetcher github :repo "alphapapa/org-sidebar"))Dependency = org-ql
(use-package org-sidebar
:ensure t
;;:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/org-sidebar/")))
)my-recache-all
| 2020-02-12 | written by me |
I tend to manually invoke this for executing all re-caching functions at once before leaving the computer for a longer period of time.
(defun my-recache-all ()
"Calls misc re-cache functions to refresh caches and make new content accessible. This might take long."
(interactive)
(if (> (string-to-number (emacs-uptime "%m")) 2) ;; (= Emacs runs longer than 2 minutes)
(setq my-boot-process nil)
(setq my-boot-process t)
)
(my-helm-org-contacts-refresh-cache)
(when (eq my-boot-process nil)
(my-flash "continuing with \"my-refile-recache\" ..."))
(my-refile-recache)
(when (not my-boot-process)
(my-rise-update-project-tables) ;; omit this on boot process since it takes ~20min
)
)Performance Optimizations
| 2020-05-04 | added to my config |
| 2020-12-06 | disabled to avoid interference with experimental org branch for performance |
In 2020-05-04, that reddit discussion pointed me to this Org ML thread where the following adaptations were published to compensate the performance degradation due to large Org mode files I do have:
;; Unfortunately isearch, sets inhibit-point-motion-hooks and we
;; cannot even use cursor-sensor-functions as a workaround
;; I used a less ideas approach with advice to isearch-search-string as
;; a workaround
(defun org-find-text-property-region (pos prop)
"Find a region containing PROP text property around point POS."
(require 'org-macs) ;; org-with-point-at
(org-with-point-at pos
(let* ((beg (and (get-text-property pos prop) pos))
(end beg))
(when beg
(setq beg (or (previous-single-property-change pos prop)
beg))
(setq end (or (next-single-property-change pos prop)
end))
(unless (equal beg end)
(cons beg end))))))
;; :FIXME: re-hide properties when point moves away
(define-advice isearch-search-string (:after (&rest _) put-overlay)
"Reveal hidden text at point."
(when-let ((region (org-find-text-property-region (point) 'invisible)))
(with-silent-modifications
(put-text-property (car region) (cdr region) 'org-invisible
(get-text-property (point) 'invisible)))
(remove-text-properties (car region) (cdr region) '(invisible nil))))
;; this seems to be unstable, but I cannot figure out why
(defun org-restore-invisibility-specs (&rest _)
""
(let ((pos (point-min)))
(while (< (setq pos (next-single-property-change pos 'org-invisible nil
(point-max))) (point-max))
(when-let ((region (org-find-text-property-region pos 'org-invisible)))
(with-silent-modifications
(put-text-property (car region) (cdr region) 'invisible
(get-text-property pos 'org-invisible))
(remove-text-properties (car region) (cdr region) '(org-invisible
nil)))))))
(add-hook 'post-command-hook #'org-restore-invisibility-specs)
(defun org-flag-region (from to flag spec)
"Hide or show lines from FROM to TO, according to FLAG.
SPEC is the invisibility spec, as a symbol."
(pcase spec
('outline
(remove-overlays from to 'invisible spec)
;; Use `front-advance' since text right before to the beginning of
;; the overlay belongs to the visible line than to the contents.
(when flag
(let ((o (make-overlay from to nil 'front-advance)))
(overlay-put o 'evaporate t)
(overlay-put o 'invisible spec)
(overlay-put o 'isearch-open-invisible #'delete-overlay))))
(_
(with-silent-modifications
(remove-text-properties from to '(invisible nil))
(when flag
(put-text-property from to 'invisible spec)
)))))
;; This normally deletes invisible text property. We do not want this now.
(defun org-unfontify-region (beg end &optional _maybe_loudly)
"Remove fontification and activation overlays from links."
(font-lock-default-unfontify-region beg end)
(let* ((buffer-undo-list t)
(inhibit-read-only t) (inhibit-point-motion-hooks t)
(inhibit-modification-hooks t)
deactivate-mark buffer-file-name buffer-file-truename)
(decompose-region beg end)
(remove-text-properties beg end
'(mouse-face t keymap t org-linked-text t
;; Do not remove invisible during
fontification
;; invisible t
intangible t
org-emphasis t))
(org-remove-font-lock-display-properties beg end)))debug message: config orgmode finished.
(message "→★ orgmode finished in %.2fs" (float-time (time-subtract (current-time) my-org-config-start-time)))For viewing and editing PDF files, Emacs has a lot to offer.
2019-04-08: Had to disable showing PDFs within Windows Emacs because of frequent Emacs crashes(!) after displaying PDF buffers. :-(
org-pdfview
This seems to be a pre-requisite to pdf-tools.
(use-package org-pdfview
;:if (my-system-type-is-gnu)
:ensure t
:defer 110
:config
)pdf-tools
pdf-tools provides really cool functionality to annotate PDF files within Emacs.
History:
- My first steps with many drawbacks: id:2014-12-02-pdf-tools
- This does not work so far. Unmet (and many) dependencies are in my way. This is quite frustrating.
- 2018-08-12: first working installation after doing
sudo apt install elpa-pdf-tools-serverin Debian GNU/Linux stable
The package:
(use-package pdf-tools
;:if (my-system-type-is-gnu)
:ensure t
:defer 120
:pin manual ;; manually update (Source: http://pragmaticemacs.com/emacs/view-and-annotate-pdfs-in-emacs-with-pdf-tools/ )
:config
(pdf-tools-install)
(eval-after-load 'org '(require 'org-pdfview))pdf-tools configuration:
Some default configs (as in id:2019-06-29-fix-pdf-tools-cosmo) do
feature ("\\.pdf\\'" . default) which might then overwriting my
desired setting. Therefore, I just make sure that this setting is not
in the list of org-file-apps any more:
(setq org-file-apps (delete '("\\.pdf\\'" . default) org-file-apps));;(add-to-list 'org-file-apps '("\\.pdf\\'" . org-pdfview-open))
(add-to-list 'org-file-apps '("\\.pdf::\\([[:digit:]]+\\)\\'" . org-pdfview-open))Open pdfs scaled to fit page: (Source)
(setq-default pdf-view-display-size 'fit-page)Use normal isearch: (Source)
(define-key pdf-view-mode-map (kbd "C-s") 'isearch-forward)Workaround for this issue on Org-mode 9 on Windows:
; (when (my-system-type-is-windows)
(add-to-list 'org-file-apps '("\\.pdf\\'" . (lambda (file link) (org-pdfview-open link))))
; )Bindings:
(bind-keys :map pdf-view-mode-map
;; ("f1" . hydra-pdftools/body)
("<s-spc>" . pdf-view-scroll-down-or-next-page)
("g" . pdf-view-first-page)
("G" . pdf-view-last-page)
("l" . image-forward-hscroll)
("h" . image-backward-hscroll)
("j" . pdf-view-next-page)
("k" . pdf-view-previous-page)
("e" . pdf-view-goto-page)
("u" . pdf-view-revert-buffer)
;; ("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)
("i" . pdf-misc-display-metadata)
("s" . pdf-occur)
("b" . pdf-view-set-slice-from-bounding-box)
("r" . pdf-view-reset-slice)
("m" . pdf-annot-add-highlight-markup-annotation)
("<C-n>" . '(lambda nil (interactive) (pdf-view-next-line-or-page 20)))
("<C-p>" . '(lambda nil (interactive) (pdf-view-previous-line-or-page 20)))
)Setting highlighting color:
;:init
(with-eval-after-load 'pdf-view-mode
(when (my-system-type-is-windows)
(push '(color . "yellow") pdf-annot-default-markup-annotation-properties)
)
)
; (setq pdf-annot-default-markup-annotation-properties '(color . "yellow")));; end of pdf-tools- [ ] FIXXME: this is a dirty workaround in order to make pdf-view mode work as expected by me:
- I could not fix following settings:
F1shows the hydra within pdf-view-mode- yellow is the default markup annotation color setting
- I could not fix following settings:
(defun my-pdf-tools ()
(interactive)
(define-key pdf-view-mode-map [f1] 'hydra-pdftools/body)
(push '(color . "yellow") pdf-annot-default-markup-annotation-properties)
)pdf-view-restore
Support for opening last known pdf position in pdf-view-mode provided by pdf-tools.
(use-package pdf-view-restore
;:if (my-system-type-is-gnu)
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/pdf-view-restore/")))
:after pdf-tools
:defer 110
:config
;; temporary workaround for https://github.com/007kevin/pdf-view-restore/issues/1
;; to prevent metadata files stored in each folder of a PDF-file
;; FIXXME: replace with corresponding setting when implemented
(setq pdf-view-restore-filename "~/.emacs.d/var/pdf-view-restore")
(add-hook 'pdf-view-mode-hook 'pdf-view-restore-mode)
)Tramp
| 2020-02-13 | added for testing |
(customize-set-variable 'tramp-default-user "vk")Misc modes/packages (part II)
Misc sources for packages:
Garbage Collection Magic Hack
Recommended by this reddit comment because of performance issues.
(use-package gcmh
:ensure t
:config
(setq garbage-collection-messages t)
(setq gcmh-verbose t)
)tabbar
«Tabbar is an emacs minor mode that displays a tab bar at the top, similar to the idea of web browser’s tabs.»
I just did not think that the screen space was used wisely for the minor advantage.
(when (my-system-type-is-gnu)
(use-package tabbar
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/")))
)
)post-mode
post-mode was used for composing Usenet postings which I do in
slrn since decades and not within Emacs as before.
(setq post-variable-signature-source "~/daten/nobackup/funnies/good_sigs/allsigs.txt")
(setq post-signature-directory "~/daten/nobackup/funnies/good_sigs/")MiniMap
«Minimap is a feature provided by the Sublime editor. It shows a smaller, “minibar”, display of the current buffer alongside the main editing window.»
(use-package minimap
:if (my-system-type-is-gnu)
:ensure t
:diminish minimap-mode
:defer 110
:config ;; executed after loading package
(setq minimap-window-location 'right)
;;deactivated;; (setq minimap-window-location 'right)
(global-set-key (kbd "S-<f10>") 'minimap-mode)
)TWiki
TWiki syntax highlighting
;(use-package erin))
(my-load-local-el "contrib/erin.el")- http://www.emacswiki.org/emacs/TwitteringMode
- http://citizen428.net/blog/2011/01/21/emacs-twittering-mode/
I shortly tested Emacs as a Twitter client but did not find advantages enough to use it instead of the Twitter webpage.
(add-to-list 'load-path (expand-file-name (concat my-user-emacs-directory "contrib/twittering-mode/")))
(use-package twittering-mode)
(setq twittering-timer-interval 300) ; Update your timeline each 300 seconds (5 minutes)
(setq twittering-url-show-status nil) ; Keeps the echo area from showing all the http processes
(setq twittering-icon-mode t) ; Show icons
(setq twittering-use-show-minibuffer-length t) ; Show character count in compose buffer
;; I added is.gd support myself, pull request sent.
;; standard options are tinyurl and toly
;(setq twittering-tinyurl-service 'is.gd)
;; See http://www.reverttoconsole.com/blog/nix/twitter-mode-for-emacs-with-oauth/
(setq twittering-use-master-password t)
;; This tells twittering-mode which time line buffers
;; to open when starting
(setq twittering-initial-timeline-spec-string
'(":friends"
":replies"
":direct_messages"
":search/tugraz/"
":search/tagstore/"
))
;; some key bindings
(add-hook 'twittering-mode-hook
(lambda ()
(mapc (lambda (pair)
(let ((key (car pair))
(func (cdr pair)))
(define-key twittering-mode-map
(read-kbd-macro key) func)))
'(("R" . twittering-native-retweet)
("l" . twittering-goto-next-thing)))))
;; enable spell check
(add-hook 'twittering-edit-mode-hook (lambda () (ispell-minor-mode) (flyspell-mode)))
;; filter by regex http://www.emacswiki.org/emacs/TwitteringMode -> "10 May 2011"
(setq twittering-tweet-filters '("foobar42" "foobar 23"))
(defun twittering-filter-tweets ()
(setq non-matching-statuses '())
(dolist (status twittering-new-tweets-statuses)
(setq matched-tweets 0)
(dolist (pat twittering-tweet-filters)
(if (string-match pat (cdr (assoc 'text status)))
(setq matched-tweets (+ 1 matched-tweets))))
(if (= 0 matched-tweets)
(setq non-matching-statuses (append non-matching-statuses `(,status)))))
(setq new-statuses non-matching-statuses))
(add-hook 'twittering-new-tweets-hook 'twittering-filter-tweets)UndoTree
Some people prefer the undo-tree visualization and method for undoing things in Emacs.
(use-package undo-tree
:ensure t
:diminish undo-tree-mode
:config ;; executed after loading package
(autoload 'undo-tree "undo-tree.el")
)open-resource
http://code.google.com/p/emacs-open-resource/ «It uses recentf’s files buffer to provide a nice interface for selecting found files. Files are searched using the “find” utility in Unix. The results are filtered with grep for unwanted patterns and with awk to return relative paths (relative paths are shorter and thus more readable).»
(add-to-list 'load-path (expand-file-name (concat my-user-emacs-directory "contrib/emacs-open-resource-read-only")))
(use-package open-resource)
(global-set-key "\C-cr" 'open-resource)whitespace-mode + style
https://www.emacswiki.org/emacs/WhiteSpace
«This package is a minor mode to visualize blanks (TAB, (HARD) SPACE and NEWLINE).»
- from Twitter 2012-05-22: @emacs_knight
;;(when (or (my-system-type-is-gnu) (my-system-is-blanche))
(whitespace-mode)
(setq whitespace-style '(trailing space-before-tab indentation empty space-after-tab)) ;; only show bad whitespace
;;(face trailing lines-tail) whitespace-line-column 80) ;; highlight long lines tails (setq whitespace-style
;; )(e)diff
Visualizing differences of files.
ediff from command line usage: emacs -diff file1 file2
(when (my-eval-if-binary-or-warn "diff")
(defun command-line-diff (switch)
(let ((file1 (pop command-line-args-left))
(file2 (pop command-line-args-left)))
;; (ediff file1 file2)))
(ediff-merge-files file1 file2)))
(add-to-list 'command-switch-alist '("diff" . command-line-diff))
)FIXXME: Compare to https://github.com/alphapapa/unpackaged.el#smerge-mode smerge-mode with its hydra from alphapapa.
Here are some settings from this configuration mentioned in that reddit thread: not tested yet
(setq ediff-forward-word-function 'forward-char) ;; from https://emacs.stackexchange.com/a/9411/17066
(setq ediff-highlight-all-diffs t)
(setq ediff-keep-variants nil)
(setq ediff-window-setup-function 'ediff-setup-windows-plain)Counting words → M-=
Counting lines, words, characters.
(use-package wc
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/")))
)Recent files
«Recentf is a minor mode that builds a list of recently opened files. This list is is automatically saved across sessions on exiting Emacs - you can then access this list through a command or the menu.»
(autoload 'recentf "recentf.el")
(recentf-mode 1)
(setq recentf-max-menu-items 50)
(setq recentf-max-saved-items 50)Confluence: vk-open-as-confluence-page() → my-map C
Editing Confluence wiki pages (up to Confluence 3.x)
- https://code.google.com/p/confluence-el/
M-x confluence-get-page
Unfortunately, Altlassian moved away from a Wiki style editing mode to a WYSIWYG editor. This killed my beautiful “edit in Emacs” method:
(when (my-system-type-is-windows)
;(add-to-list 'load-path (expand-file-name "~/.emacs.d/contrib/confluence-el-1.5/"))
(use-package confluence)
(setq confluence-url "http://product.infonova.at/confluence/rpc/xmlrpc")
(add-to-list 'auto-mode-alist '("\\.\\(confluence\\)$" . confluence-mode))
(dolist (hook '(confluence-mode-hook))
(add-hook hook (lambda ()
(flyspell-mode 1)
(ispell-change-dictionary "american")
(flyspell-buffer)
))
)
(defun vk-open-as-confluence-page ()
"Takes current line (delimited by brackets, two spaces or pipe) and opens it as Confluence page in IR6 space"
(interactive)
(save-excursion
(re-search-backward "\\(\\] \\| \\|\* \\|| \\)") ;; search for "] " or " " or "| "
(forward-char)
(forward-char)
(setq start-pos (point))
(re-search-forward "\\( \\[\\| \\| |\\)") ;; search for " [" or " " or " |"
(backward-char)
(backward-char)
(setq end-pos (point))
(setq myname (buffer-substring start-pos end-pos))
;(message "Confluence page name: [%s]" myname)
(confluence-get-page myname "IR6")
;(confluence-get-page myname)
)
)
(bind-key "C" #'vk-open-as-confluence-page my-map)
)message-outlook.el - sending mail with Outlook
With this package, I can C-c C-o on mailto:user@example.com in my
Org mode. A new Emacs message composing buffer appears and with
message-send-and-exit() (C-c C-c) the composed email doesn’t get
sent to the recipient(s) and instead appears as an email in a new
composing window of Outlook where I may continue composing or send it
to the recipient(s).
(when (my-eval-if-binary-or-warn "outlook")
(use-package message-outlook
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/")))
)
)Editing Outlook emails in Emacs
Continue editing an email in Emacs which is being currently composed within Outlook. When finished composing it in Emacs, it can then be sent back to the open Outlook window again.
Disabled, because there are some annoying things related to this workflow.
when (or (my-system-is-powerplantlinux) (my-system-type-is-windows))
(use-package outlookedit
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/")))
)
;;(use-package outlookedit)
(defvar mno-get-outlook-body
"cscript //B //Job:getMessage c:/Users/karl.voit/bin/outlook_emacs.wsf")
(defvar mno-put-outlook-body
"cscript //B //Job:putMessage c:/Users/karl.voit/bin/outlook_emacs.wsf")
;; ######################################################
;; use mail-mode for email or usenet postings:
(add-to-list 'auto-mode-alist '("\\.\\(mail\\|email\\|posting\\)$" . mail-mode))
(dolist (hook '(mail-mode-hook))
(add-hook hook (lambda ()
(mail-mode-auto-fill)
(auto-fill-mode 1)
(flyspell-mode 1)
(ispell-change-dictionary "german8")
(flyspell-buffer)
))
)
;; http://www.emacswiki.org/emacs/MailMode
(add-hook 'mail-mode-hook
(lambda ()
(font-lock-add-keywords nil
'(("^[ \t]*>[ \t]*>[ \t]*>.*$"
(0 'mail-multiply-quoted-text-face))
("^[ \t]*>[ \t]*>.*$"
(0 'mail-double-quoted-text-face))))))
)real-auto-save: Periodically auto-save buffers
| 2020-02-04 | re-activated after data loss when XOrg crashes on t490 |
Automatically save buffers more often within certain modes:
- http://www.emacswiki.org/emacs/AutoSave
http://www.litchie.net/programs/real-auto-save.html[2020-04-15 Wed 16:37] broken link- … installed 2014-03-05 via Marmalade
- https://github.com/ChillarAnand/real-auto-save
(use-package real-auto-save
:ensure t
:after org
:config
(setq real-auto-save-use-idle-timer t);; t → use *idle* timer instead; nil → use fixed timer
;; Auto save interval is 10 seconds by default. You can change it:
(setq real-auto-save-interval 1800) ;; every 30 minutes of idle time
;; 2021-06-19 XOrg on Xubuntu 20.04 is stable ;; (when (my-system-is-rise)
;; 2021-06-19 XOrg on Xubuntu 20.04 is stable ;; (setq real-auto-save-interval 60);; after one minute idle, save on the lenovo t490 + Xubuntu 19.10 due to XOrg instability issues
;; 2021-06-19 XOrg on Xubuntu 20.04 is stable ;; )
;;(setq real-auto-save-use-idle-timer t);; FIXXME: testing https://github.com/ChillarAnand/real-auto-save/issues/43
;;(setq real-auto-save-interval 15) ;; FIXXME: testing https://github.com/ChillarAnand/real-auto-save/issues/43
;;(real-auto-save-activate-advice) ;; suppress confirmation for Makefiles
(add-hook 'org-mode-hook 'real-auto-save-mode)
)spray (speed-reading region) → my-map s
A speed reading mode for Emacs.
- The algorithm is taken from OpenSpritz
- https://github.com/zk-phi/spray
- … installed 2014-06-13 via manual download from github (for testing)
(use-package spray
:ensure t
:defer 110
:config ;; executed after loading package
:bind (:map my-map ("s" . spray-mode))
)yafolding - Folding based on identation → M-RET C-TAB
I do use this folding method for Python source code. It is not perfect but most of the time, it’s a good companion to me.
(use-package yafolding
:ensure t
:defer 110
:mode ("\\.xml\\'" . yafolding-mode)
:config ;; executed after loading package
(add-to-list 'auto-mode-alist '("\\.xml$" . nxml-mode))
;;(add-to-list 'auto-mode-alist '("\\.xml$" . yafolding-mode))
;;(global-set-key (kbd "<C-S-return>") 'yafolding-toggle-all)
;;(global-set-key (kbd "<C-return>") 'yafolding-toggle-element)
:bind (("<M-S-return>" . yafolding-toggle-all)
("<M-return>" . yafolding-toggle-element)
("<C-Tab>" . yafolding-toggle-element))
)Naked full screen Emacs → F12
I love to work in full-screen mode where nothing is distracting me from the information I am working with: the content of Emacs.
There are some packages out there that provide this functionality such as writeroom-mode or darkroom-mode (see discussion of them here).
The code below was written by Bastien Guerry and adopted by me to meet my requirements: https://gist.github.com/bzg/8578998
Conditions when loading:
(when (my-system-type-is-gnu)(defvar my-toggle-naked-emacs-status nil
"state of fullscreen/naked Emacs mode. t means fullscreen, nil means normal")
(make-variable-buffer-local 'my-toggle-naked-emacs-status)
;; See http://bzg.fr/emacs-hide-mode-line.html
(defvar-local hidden-mode-line-mode nil)
(defvar-local hide-mode-line nil)
(define-minor-mode hidden-mode-line-mode
"Minor mode to hide the mode-line in the current buffer."
:init-value nil
:global nil
:variable hidden-mode-line-mode
:group 'editing-basics
(if hidden-mode-line-mode
(setq hide-mode-line mode-line-format
mode-line-format nil)
(setq mode-line-format hide-mode-line
hide-mode-line nil))
(force-mode-line-update)
;; Apparently force-mode-line-update is not always enough to
;; redisplay the mode-line
(redraw-display)
(when (and (called-interactively-p 'interactive)
hidden-mode-line-mode)
(run-with-idle-timer
0 nil 'message
(concat "Hidden Mode Line Mode enabled. "
"Use M-x hidden-mode-line-mode to make the mode-line appear."))))
;; A small minor mode to use a big fringe
(defvar bzg-big-fringe-mode nil)
(define-minor-mode bzg-big-fringe-mode
"Minor mode to hide the mode-line in the current buffer."
:init-value nil
:global t
:variable bzg-big-fringe-mode
:group 'editing-basics
(if (not bzg-big-fringe-mode)
(set-fringe-style nil)
(set-fringe-mode
(/ (- (frame-pixel-width)
(* 100 (frame-char-width)))
3)
)
))
;; Command to toggle the display of the mode-line as a header
(defvar-local header-line-format nil)
(defun mode-line-in-header ()
(interactive)
(if (not header-line-format)
(setq header-line-format mode-line-format
mode-line-format nil)
(setq mode-line-format header-line-format
header-line-format nil))
(set-window-buffer nil (current-buffer)))
(defun my-toggle-naked-emacs ()
"Toggle fullscreen/naked Emacs and normal Emacs"
(interactive)
(cond (my-toggle-naked-emacs-status
;; make it naked!
(setq my-toggle-naked-emacs-status nil)
;; Prevent the cursor from blinking
(blink-cursor-mode 0)
;; Don't let Emacs hurt your ears
(setq visible-bell t)
;; This is bound to f11 in Emacs 24.4
(toggle-frame-fullscreen)
;; ;; Who use the bar to scroll?
;; (scroll-bar-mode 0)
(menu-bar-mode 0)
;; You can also set the initial frame parameters
;; (setq initial-frame-alist
;; '((menu-bar-lines . 0)
;; (tool-bar-lines . 0)))
;; Activate hidden-mode-line-mode
(hidden-mode-line-mode 1)
;; If you want to hide the mode-line in all new buffers
;; (add-hook 'after-change-major-mode-hook 'hidden-mode-line-mode)
;; Alternatively, you can paint your mode-line in White but then
;; you'll have to manually paint it in black again
;; (custom-set-faces
;; '(mode-line-highlight ((t nil)))
;; '(mode-line ((t (:foreground "white" :background "white"))))
;; '(mode-line-inactive ((t (:background "white" :foreground "white")))))
;; reset fringe with:
;; (set-fringe-mode nil)
;; Now activate this global minor mode
(bzg-big-fringe-mode 1)
;; To activate the fringe by default and deactivate it when windows
;; are split vertically, uncomment this:
;; (add-hook 'window-configuration-change-hook
;; (lambda ()
;; (if (delq nil
;; (let ((fw (frame-width)))
;; (mapcar (lambda(w) (< (window-width w) fw))
;; (window-list))))
;; (bzg-big-fringe-mode 0)
;; (bzg-big-fringe-mode 1))))
;; Use a minimal cursor
;; (setq cursor-type 'hbar)
;; ;; Get rid of the indicators in the fringe
;; (mapcar (lambda(fb) (set-fringe-bitmap-face fb 'org-hide))
;; fringe-bitmaps)
;;
;; ;; Set the color of the fringe
;; (custom-set-faces
;; '(fringe ((t (:background "white")))))
;;
;; (custom-set-faces
;; '(default ((t (:background "black" :foreground "grey"))))
;; '(fringe ((t (:background "black")))))
;;(global-set-key (kbd "C-s-SPC") 'mode-line-in-header)
(bind-key "h" 'mode-line-in-header my-map)
(message "Enjoy your concentration!")
)
(t
;; normal mode
(setq my-toggle-naked-emacs-status t)
(blink-cursor-mode t)
(setq visible-bell nil)
(toggle-frame-fullscreen)
;(scroll-bar-mode 1)
;;(menu-bar-mode 1)
(hidden-mode-line-mode nil)
;; If you want to hide the mode-line in all new buffers
;; (add-hook 'after-change-major-mode-hook 'hidden-mode-line-mode)
(bzg-big-fringe-mode nil)
(set-fringe-mode nil)
(message "See everything.")
)
)
)map it to F12 and end condition of loading:
(global-set-key [f12] 'my-toggle-naked-emacs)
)browse-kill-ring → M-y
https://github.com/browse-kill-ring/browse-kill-ring
«Are you tired of using the endless keystrokes of C-y M-y M-y M-y …
to get at that bit of text you killed thirty-seven kills ago? Ever
wish you could just look through everything you’ve killed recently to
find out if you killed that piece of text that you think you killed,
but you’re not quite sure? If so, then browse-kill-ring is the Emacs
extension for you.»
(use-package browse-kill-ring
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/")))
;:load-path (concat my-user-emacs-directory "contrib/")
:config
(browse-kill-ring-default-keybindings); map M-y to browse-kill-ring
)
;; 2017-09-05: to delete when above is working:
;;(require 'browse-kill-ring)
;;(browse-kill-ring-default-keybindings); map M-y to browse-kill-ringpdf-mode - Edit raw PDF files in Emacs
«pdf-mode is a major mode for editing PDF files in Emacs. It’s not perfect, but it should be a good starting point. It might be useful for the poor souls who are working on generating PDF; definitely useful to me.»
2014-11-16 works at a quick test but I disable it for now since I don’t need it for now.
(use-package pdf-mode
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/pdf-mode/")))
)guide-key - displays the available key bindings automatically
«guide-key.el displays the available key bindings automatically and dynamically. guide-key aims to be an alternative of one-key.el.»
This is great: when I do press my prefix for my-map and wait a bit,
I get a popup buffer that tells me what bindings I am able to use.
(use-package guide-key
:ensure t ;; install package if not found OR: (setq use-package-always-ensure t)
:config ;; executed after loading package
(setq guide-key/guide-key-sequence '("C-c C-,"))
(setq guide-key/recursive-key-sequence-flag t)
;; show common Org mode keys
(defun guide-key/my-hook-function-for-org-mode ()
(guide-key/add-local-guide-key-sequence "C-c")
(guide-key/add-local-guide-key-sequence "C-c C-x")
(guide-key/add-local-highlight-command-regexp "org-")
)
(add-hook 'org-mode-hook 'guide-key/my-hook-function-for-org-mode)
(guide-key-mode 1) ; Enable guide-key-mode
)vcard-mode
https://github.com/dochang/vcard-mode
«This package provides a major mode to edit vCard files in Emacs.»
(use-package vcard-mode
:ensure nil ;; install package if not found OR: (setq use-package-always-ensure t)
:load-path "contrib/vcard-mode/" ;; relative to emacs dir
:pin manual
:mode ("\\.vc\\(f\\|ard\\)\\'" . vcard-mode)
)sunrise-mode - file management like midnight commander or FreeCommander
via http://www.emacswiki.org/emacs/Sunrise_Commander and GitHub
disabled 2015-08-31 since I don’t use it for now.
(use-package sunrise-commander
:ensure nil ;; install package if not found OR: (setq use-package-always-ensure t)
:mode ("\\.py\\'" . elpy-mode)
;; 3) Choose some unused extension for files to be opened in Sunrise VIRTUAL
;; mode and add it to `auto-mode-alist', e.g. if you want to name your virtual
;; directories like *.svrm just add to your .emacs file a line like the
;; following:
:mode ("\\.srvm\\'" . sr-virtual-mode)
)RAML-mode
- via http://www2.tcs.ifi.lmu.de/~hoffmann/raml/raml-mode.el
- What is RAML? (RESTful API Modeling Language)
(use-package raml-mode
:if (my-system-type-is-windows)
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/raml-mode/")))
)Synonyms → my-map S
- via http://www.emacswiki.org/emacs/ThesauriAndSynonyms and id:2015-08-28-synonyms.el
- The file names are absolute, not relative, locations
- e.g. /foobar/mthesaur.txt.cache, not mthesaur.txt.cache
(if (file-exists-p (concat my-user-emacs-directory "bin/mthes10/mthesaur.txt"))
(use-package synonyms
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/synonyms/")))
;;:ensure t ;; install package if not found OR: (setq use-package-always-ensure t)
:init ;; executed before loading package
(setq synonyms-file (concat my-user-emacs-directory "bin/mthes10/mthesaur.txt"))
(setq synonyms-cache-file (concat my-user-emacs-directory "bin/vkcachefile"))
:config
(defun my-synonym-current-word ()
"Lookup synonyms for current word."
(interactive)
(synonyms-lookup (thing-at-point 'word) nil nil))
:bind (:map my-map ("S" . my-synonym-current-word))
)
(message (concat "»»» I could not locate \"" my-user-emacs-directory "bin/mthes10/mthesaur.txt\""))
)define-word
- https://github.com/abo-abo/define-word
- via An Emacs Interface to the macOS System Dictionary | Irreal and A Thesaurus for Emacs | Irreal
- uses online service of https://www.wordnik.com/
(use-package define-word
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/define-word/")))
;; :config
)Binding is done via hydra.
nyan-mode - Nyan Cat instead of scroll bar
«Nyan Mode is an analog indicator of your position in the buffer. The Cat should go from left to right in your mode-line, as you move your point from 0% to 100%.»
via https://www.reddit.com/r/emacs/comments/3xoins/totally_useless_and_utterly_awesome_packages/
This seems to be a bit silly but it is actually quite useful for me. I usually do work with a ninety degree tilted monitor where horizontal space is limited but vertical space not. By disabling the scroll bar for Emacs (see further above) and using the Nyan cat as a replacement for it, I can save precious horizontal space.
(use-package nyan-mode
:ensure t ;; install package if not found OR: (setq use-package-always-ensure t)
:init
(when (my-system-type-is-windows)
(setq nyan-bar-length 10);; reduce length on narrow upward/tilted display
)
(when (my-system-type-is-gnu)
(setq nyan-bar-length 20);; reduce length on narrow upward/tilted display
)
:config
(nyan-mode t)
)If you do find Nyan too childish, mlscroll is an interactive neutral alternative.
highlight-tail
https://melpa.org/#/highlight-tail
This minor-mode draws a tail in real time, when you write. It changes the background color of some last typed characters and smoothly fade them out to the background color.
So from now on, your Emacs will be even more sexy! ;o )
If you do not understand what I mean, check the animation: http://nic-nac-project.net/~necui/img/htshow.gif
- via https://www.reddit.com/r/emacs/comments/3xoins/totally_useless_and_utterly_awesome_packages/
- IMHO it is not totally useless: visualizing the current point where I type just like a fading cursor
- update settings via M-x highlight-tail-reload
- disabled 2015-12-26 due issues with jumping cursor
(use-package highlight-tail
:ensure t ;; install package if not found OR: (setq use-package-always-ensure t)
:init
(setq highlight-tail-colors '(("#1c1c1c" . 0)
;;("#bc2525" . 25)
;;("black" . 66)
))
:config
(highlight-tail-mode)
)anzu-mode - showing number of matches when searching
«anzu.el is an Emacs port of anzu.vim. anzu.el provides a minor mode which displays current match and total matches information in the mode-line in various search modes.»
I love this visualization.
(use-package anzu
:ensure t ;; install package if not found OR: (setq use-package-always-ensure t)
:diminish anzu-mode
:config
(global-anzu-mode +1)
)smart-mode-line - abbreviating paths, …
«Smart Mode Line is a sexy mode-line for Emacs. It aims to be easy to read from small to large monitors by using colors, a prefix feature, and smart truncation.»
(use-package smart-mode-line
:ensure t ;; install package if not found OR: (setq use-package-always-ensure t)
:config
(setq sml/no-confirm-load-theme t)
(setq sml/theme 'respectful) ;; select theme: light, dark, respectful
;; hiding minor modes from mode line (don't forget the leading space)
(setq rm-blacklist '(" Fill" " Ind" " MRev" " hl-p" " Guide" " OrgStruct" " ," " PCRE" " counsel" " OTSH" " dired-icon" " GitGutter" " WK" " FlyC-" " Ddl" " Diary"))
;; does not hide in Org-agenda: "Diary " "Ddl " "Grid " "Habit " "FlyC " "WK "
;; replacing path names with abbrevations:
(add-to-list 'sml/replacer-regexp-list '("^~/hosts/all/config/emacs.d" ":EMACS:") t)
(add-to-list 'sml/replacer-regexp-list '("^~/org" ":ORG:") t)
(add-to-list 'sml/replacer-regexp-list '("^~/frankie/src/lazyblorg" ":LB:") t)
(add-to-list 'sml/replacer-regexp-list '("^C:/Users/John/AppData/Roaming/org" ":ORG:") t)
(add-to-list 'sml/replacer-regexp-list '("^~/frankie/" "~/") t)
(smart-mode-line-enable)
)Performance implications! See reddit comment for details.
display-time-mode - Enable the display of time in the modeline
http://www.emacswiki.org/emacs/DisplayTime
- via: http://emacs.stackexchange.com/questions/13227/easy-way-to-give-the-time-its-own-face-in-modeline
(setq display-time-string-forms
'((propertize (format-time-string "%A %F %R" now) 'face 'bold)))
(display-time-mode t)dash
https://github.com/magnars/dash.el «A modern list api for Emacs. No ‘cl required.»
- required by
eno(and most probably others in future) - disabled because I do not use
enofor now
(use-package dash
:ensure t
:defer 110
)edit-at-point
- required by
eno(and most probably others in future) - disabled because I do not use
enofor now
(use-package edit-at-point
:ensure t
:defer 110
)eno-mode: ace-jump/easymotion provides: goto certain char in view
https://github.com/enoson/eno.el
ace-jump/easymotion provides “goto certain char in view”, which let us moving without mouse, but it’s still not efficient or intuitive enough, so I create this package to not just goto but also edit(copy,cut..) any word/symbol/string/paren/line in view by directly selecting hints, similar to ace-jump/easymotion but don’t need to enter the leading char.
(use-package eno
:ensure t
;; :diminish eno
:defer 110
;; :config ;; executed after loading package
:bind (:map my-map ("RET" . eno-word-goto))
)markdown-mode
via: http://ikiwiki.info/tips/Emacs_and_markdown/
(use-package markdown-mode
:ensure t
;:if (my-system-is-rise)
;;:defer 110
:mode ("\\.md\\'" . markdown-mode)
:mode ("\\.mkdn\\'" . markdown-mode)
)swiper - ivy-enhanced alternative to isearch
flexible, simple tools for minibuffer completion in Emacs
This repository contains:
- Ivy, a generic completion mechanism for Emacs.
- Counsel, a collection of Ivy-enhanced versions of common Emacs commands.
- Swiper, an Ivy-enhanced alternative to isearch.
- http://pragmaticemacs.com/emacs/dont-search-swipe/
- http://irreal.org/blog/?p=5340 -> swiper depends on ivy; ivy is much better than ido-mode/smex; example config
- from https://writequit.org/denver-emacs/presentations/2017-04-11-ivy.html
- DISABLED because I faced issues with it:
- tagging in Org-mode lacks tab-completion
- DISABLED because I faced issues with it:
(use-package ivy :demand
:config
(setq ivy-use-virtual-buffers t ;; Add recent files and bookmarks to the ivy-switch-buffer
ivy-count-format "%d/%d ") ;; Displays the current and total number in the collection in the prompt
(ivy-mode 1)
)| Key | Command | Description |
|---|---|---|
| M-n | ivy-next-line | Next line |
| M-p | ivy-previous-line | Previous line |
| M-< | ivy-beginning-of-buffer | Beginning of the Ivy minibuffer |
| M-> | ivy-end-of-buffer | End of the Ivy minibuffer |
| C-v | ivy-scroll-up-command | Page up by one Ivy buffer size |
| M-v | ivy-scroll-down-command | Page down by one Ivy buffer size |
| C-m or RET | ivy-done | Calls the default action |
| C-M-m | ivy-call | Calls the default action, keeps Ivy open |
| M-o | ivy-dispatching-done | Displays the available actions |
| C-M-o | ivy-dispacthing-call | Displays available actions, keeps Ivy open |
| C-’ | ivy-avy | Uses Avy to select candidates |
| TAB | ivy-partial-or-done | Tab completion, repeated presses may call done |
| ivy-resume | Restart Ivy before last action |
(use-package swiper
:ensure t
;;:if (my-system-type-is-windows)
:config
(setq ivy-display-style 'fancy) ;; fancy highlighting
;;advise swiper to recenter on exit
(defun bjm-swiper-recenter (&rest args)
"recenter display after swiper"
(recenter)
)
(when (my-system-type-is-gnu)
(advice-add 'swiper :after #'bjm-swiper-recenter)
)
;(bind-key "C-s" 'swiper)
;;(global-set-key "\C-s" 'swiper)
)counsel - Ivy-enhanced versions of common Emacs commands → M-x → my-map J
flexible, simple tools for minibuffer completion in Emacs
This repository contains:
- Ivy, a generic completion mechanism for Emacs.
- Counsel, a collection of Ivy-enhanced versions of common Emacs commands.
- Swiper, an Ivy-enhanced alternative to isearch.
(use-package counsel
:ensure t
;;:bind (:map my-map ("J" . counsel-imenu)) ;; http://irreal.org/blog/?p=6201 jumping to buffer org-heading
;; 2018-01-23: moved to jump-hydra!
:config
(counsel-mode 1)
)char-menu - insert special characters → F4
«This package allows to insert arbitrary symbols in Emacs in a very efficient and straightforward way. Whether you ever need to insert only a couple of proper punctuation symbols or you’re a Unicode geek who likes all sorts of arrows and fancy math symbols, this package may be of some use.»
- via http://irreal.org/blog/?p=4926
- add characters: “M-x customize-group char-menu RET”
(use-package char-menu
:ensure t
:config
(setq char-menu
'("→" "…" "✓" "×" "·" "•" "№" "★" "°" "–" "—" "§" "«»" "»«" "‘’" "“”" "∅" "©" "†" "␣" "¥"
("Arrows" "←" "→" "↑" "↓" "⇐" "⇒" "⇑" "⇓")
("Math" "Δ" "¬" "≈" "≡" "≠" "∞" "×" "±" "∓" "÷" "√" "∄" "∃")
("Greek" "α" "β" "Y" "δ" "ε" "ζ" "η" "θ" "ι" "κ" "λ" "μ"
"ν" "ξ" "ο" "π" "ρ" "σ" "τ" "υ" "φ" "χ" "ψ" "ω" "Σ" "Δ")
("Hatschek" "Ǎ" "ǎ" "Č" "č" "Ď" "ď" "Ě" "ě" "Ǧ" "ǧ" "Ȟ" "ȟ"
"Ǐ" "ǐ" "ǰ" "Ǩ" "ǩ" "Ľ" "ľ" "Ň" "ň" "Ǒ" "ǒ" "Ř" "ř" "Š" "š" "Ť" "ť"
"Ǔ" "ǔ" "Ǚ" "ǚ" "Ž" "ž" "Ǯ" "ǯ")
("Umlaute" "ä" "ö" "ü" "Ä" "Ö" "Ü" "ß")
))
(global-set-key [f4] 'char-menu)
)helm - completion and selection narrowing
This is something that really pushes Emacs usability.
https://github.com/emacs-helm/helm
«Emacs incremental completion and selection narrowing framework https://emacs-helm.github.io/helm/»
Helm is an Emacs framework for incremental completions and narrowing selections. It helps to rapidly complete file names, buffer names, or any other Emacs interactions requiring selecting an item from a list of possible choices. Helm is a fork of anything.el, which was originally written by Tamas Patrovic and can be considered to be its successor. Helm cleans the legacy code that is leaner, modular, and unchained from constraints of backward compatibility.
(use-package helm
:ensure t
:defer 110
)wttrin - Weather in Emacs → my-map w
(use-package wttrin
:ensure t
:commands (wttrin)
:defer 120
:init
(setq wttrin-default-cities '("graz" "ebreichsdorf" "st.poelten" "schladming" "malia"))
(cond ((my-system-is-sting)
;; 2017-12-23 outdated: (bind-key "w" '(lambda () (interactive) (wttrin-query "graz") (toggle-truncate-lines)) my-map)
(bind-key "w" (lambda () (interactive) (wttrin-query "graz")) my-map)
)
((my-system-type-is-windows)
(bind-key "w" '(lambda () (interactive) (wttrin-query "graz")) my-map)
)
(t
(bind-key "w" '(lambda () (interactive) (wttrin)) my-map)
)
)
)
pandoc-mode - An Emacs minor mode for interacting with Pandoc
(when (my-eval-if-binary-or-warn "pandoc")
(use-package pandoc-mode
:ensure t
:defer 110
)
)bm - visible bookmarks → my-map 8|9|0
https://github.com/joodland/bm
This package provides visible, buffer local, bookmarks and the ability to jump forward and backward to the next bookmark.
It was created because I missed the bookmarks from M$ Visual Studio in GNU Emacs. I think they provide an easy way to navigate in a buffer.
Features:
- Auto remove bookmark after jump to it by bm-next or bm-previous:
- Cycle through bookmarks in all open buffers in LIFO order
- Toggle bookmarks. Jump to next/previous bookmark.
- Setting bookmarks based on a regexp. (Useful when searching logfiles.)
- Mouse navigation.
- Annotate bookmarks.
- Different wrapping modes.
- Different bookmarks styles, line-only, fringe-only or both.
- Persistent bookmarks (buffer local), also in non-file buffers (info) and indirect buffers.
- List bookmarks (in all buffers) in a separate buffer.
- Cycle through bookmarks in all open buffers.
via: http://pragmaticemacs.com/emacs/use-visible-bookmarks-to-quickly-jump-around-a-file/
(use-package bm
:ensure t
:defer 90
:bind (:map my-map ("8" . bm-toggle))
:bind (:map my-map ("9" . bm-previous))
:bind (:map my-map ("0" . bm-next))
)adoc-mode - asciidoc mode
https://github.com/sensorflo/adoc-mode/wiki
AsciiDoc is a text document format for writing short documents, articles, books and UNIX man pages. AsciiDoc files can be translated to HTML and DocBook markups.
adoc-mode is an Emacs major mode for editing AsciiDoc files. It emphasizes on the idea that the document is highlighted so it pretty much looks like the final output. What must be bold is bold, what must be italic is italic etc. Meta characters are naturally still visible, but in a faint way, so they can be easily ignored.
(use-package adoc-mode
:ensure t
:defer 110
:config
(add-to-list
'auto-mode-alist (cons "\\.adoc\\'" 'adoc-mode))
)suggest - suggest Elisp for given input and output
Oh, this is really cool: http://www.wilfred.me.uk/blog/2016/07/30/example-driven-development/
- “Hey $COLLEAGUE, is there any function that takes this list and returns a list like this?”
Just read the web page - it’s hard to explain otherwise.
Disabled for now until I want to impress someone using my Emacs power ;-)
M-x suggest
I ran into “suggest–possibilities: Symbol’s value as variable is
void: it” when C-c C-c: See id:2016-08-04-suggest
(use-package suggest
:ensure t
:defer 110
)move-text - move line up/down → M-, | M-.
«MoveText is extracted from Basic edit toolkit. It allows you to move the current line using M-up / M-down (or any other bindings you choose) if a region is marked, it will move the region instead.»
- tipp from http://irreal.org/blog/?p=5611
I don’t use it for now. Maybe after I got the requirement more often and memorize the commands.
(use-package move-text
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/move-text/")))
:config
(global-set-key (kbd "M-,") 'move-text-up)
(global-set-key (kbd "M-.") 'move-text-down)
)
;; (require 'move-text)
;; (move-text-default-bindings)command-log-mode → my-map k (visualizing keyboard input in buffer)
2017-06-01: package was unavailable → disabled for now since I don’t use it anyway.
https://github.com/lewang/command-log-mode - «Show event history and command history of some or all buffers.»
Used in screencast video: https://www.reddit.com/r/emacs/comments/4yhfn6/emacs_screencast_acelink_swiper_lispy_and_macros/
To see the log buffer, call M-x clm/open-command-log-buffer.
The key strokes in the log are decorated with ISO9601 timestamps on the property `:time’ so if you want to convert the log for screencasting purposes you could use the time stamp as a key into the video beginning.
How to use:
M-x command-log-modemy-map k
(use-package command-log-mode
:ensure t
:defer 110
:diminish command-log-mode
:config ;; executed after loading package
(add-hook 'LaTeX-mode-hook 'command-log-mode)
(bind-key "k" #'clm/open-command-log-buffer my-map)
)A test for starting the mode probably together with the command-log-buffer:
(defun my-start-command-log-mode()
"load the command-log mode and start it."
(interactive "*")
;; M-x clm/open-command-log-buffer
(clm/open-command-log-buffer)
)scss-mode
https://github.com/antonj/scss-mode - «Major mode for editing SCSS files in Emacs.»
Command line utility sass is required, see http://sass-lang.com/
To install sass (haml): gem install haml
Also make sure sass location is in emacs PATH, example:
(setq exec-path (cons (expand-file-name "~/.gem/ruby/1.8/bin") exec-path))
or =customize `scss-sass-command’= to point to your sass executable.
(when (my-eval-if-binary-or-warn "sass")
(use-package scss-mode
;;:if (my-system-is-floyd-or-sting)
:ensure t
:defer 110
:config
(autoload 'scss-mode "scss-mode")
(add-to-list 'auto-mode-alist '("\\.scss\\'" . scss-mode))
)
)json-mode
(use-package json-mode
:if (my-system-type-is-windows)
:ensure t
:defer 110
)mode-icons - Show icons instead of mode names
https://github.com/ryuslash/mode-icons
via: https://www.reddit.com/r/emacs/comments/5fjri7/how_to_use_git_logo_in_modeline_instead_of/
This enhances the style of Emacs IMHO.
(use-package mode-icons
:ensure t
:defer 120
:config
(mode-icons-mode)
(add-hook 'dired-mode-hook #'mode-icons--mode-disable) ;; with mode-icons, visiting a dir with dired takes up *lots* of CPU for =mode-icons-reset= (performance-issue)
)unicode-fonts - Configure Unicode fonts
https://github.com/rolandwalker/unicode-fonts
- solved an issue where a host was using different-height-sized font for few special characters
- see id:2016-08-19-unicode-enlarges-line-height
(use-package unicode-fonts
:ensure t
:if (my-system-is-floyd)
:defer 110
:config
(unicode-fonts-setup)
)goto-chg - visit places of previous changes in current buffer → S-F3|F4
- http://www.emacswiki.org/emacs/download/goto-chg.el
- Goto the point of the most recent edit in the buffer.
- When repeated, goto the second most recent edit, etc.
- Negative argument, C-u -, for reverse direction.
- Works by looking into buffer-undo-list to find points of edit.
- via: http://pragmaticemacs.com/emacs/move-through-edit-points/
(use-package goto-chg
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/")))
:config
(global-set-key [(shift f3)] 'goto-last-change)
(global-set-key [(shift f4)] 'goto-last-change-reverse)
)
;(require 'goto-chg)restclient
GitHub - pashky/restclient.el: HTTP REST client tool for emacs
The restclient here is particular handy when it is combined with the
Org-mode: see use of ob-restclient.el within the Org-mode headings.
This way, I am able to write REST requests right beneath my Org-mode documentation. The REST answers are added there as well. This tool also allows for using variables. More flexibility is almost impossible. ;-)
(use-package restclient
:ensure t ;; install package if not found OR: (setq use-package-always-ensure t)
:defer 110
:if (my-system-type-is-windows)
:init ;; executed before loading package
(use-package json-reformat
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/2del/restclient/")))
)
;; :mode "\\.rb\\'"
)neotree → F1
NeoTree offers a file tree side-panel like NerdTree for Vim.
- installed on 2015-03-22
- disabled 2018-06-19: I don’t use it in real life
(use-package neotree
:ensure t
:defer 120
:config ;; executed after loading package
(global-set-key [f1] 'neotree-toggle)
)csv-mode
Manipulating CSV files.
As with many major modes, I do have a helpful hydra mapped to F1.
(use-package csv-mode
:ensure t
:defer 110
:config
(add-to-list 'auto-mode-alist '("\\.[Cc][Ss][Vv]\\'" . csv-mode))
(autoload 'csv-mode "csv-mode"
"Major mode for editing comma-separated value files." t)
)pcre2el
I got this nice package from a screencast of dired. It offers simplified regular expressions instead of the standard Emacs RegEx.
Example: in dired, you can mark using %m followed by .*(jpg|png)
instead of using the pattern .*\(jpg\|png\).
CAUTION: this changes regex in general from vanilla Emacs regex to PCRE regex!
(use-package pcre2el
:ensure t
:config
(pcre-mode)
)dumb-jump
- an Emacs “jump to definition” package
- From: Irreal: Dumb-jump in Action
- Source: https://github.com/jacktasia/dumb-jump
- Some Oldies but Goodies Updated—Part 1 | Irreal
- Dumb-jump in Action | Irreal
- Using Emacs - 33 - projectile, dumb-jump | C’est la Z → Screecast with projectile and dumb-jump
- Dumb-jump in Action | Irreal
(use-package dumb-jump
:ensure t
)keyfreq
I found it via this blog article: it logs the used commands and their keyboard shortcuts and gives you an overview. Most frequently used commands should be mapped to easy to type shortcuts.
(use-package keyfreq
:ensure t
:config
(keyfreq-mode 1)
(keyfreq-autosave-mode 1)
)You can see the current result by calling keyfreq-show.
Pulse: Highlight lines on misc occasions
This is a tip I got from that blog article:
(defun my-pulse-line (&rest _)
"Pulse the current line."
(pulse-momentary-highlight-one-line (point)))
(dolist (command '(eyebrowse-post-window-switch-hook recenter-top-bottom other-window ace-window my-scroll-down-half my-scroll-up-half))
(advice-add command :after #'my-pulse-line))eyebrowse → my-map ,
When you are working with multiple tasks in parallel, you most likely know the issue of getting lost in your buffers or destroying your window setup for an in-between task.
eyebrowse helps mitigating those issues by providing “saved buffer configurations” and assign it to separate slots that are addressed by their number. If you know GNU screen or tmux in your shell, this is quite familiar to you.
I got the recommendation for it from this reddit thread.
The author is obviously using spacemacs. Unfortunately, the default
prefix C-c C-w is overriding org-refile() which I use frequently.
I chose C-: as alternative prefix in order to un-map the original.
However, I am invoking eyebrowse functionality only via my hydra which
is defined below and inviked via =my-map ,=.
Since my horizontal mode line space is sparse, I wanted a small modification. I need the whole indicator information (with labels) in the hydra (much space) but only the list of the slots in the mode line in order to keep it as small as possible. Therefore I modified the package by duplicating the modeline functions according to this GitHub issue explanation.
Please notice that with only one slot (the default one), the indicator is not shown in the modeline.
| Key bind | Function |
|---|---|
| prefix < | Switch to previous window config |
| prefix > | Switch to next window config |
| prefix ’ | Switch to last window config |
| prefix ” | Close current window config |
| prefix , | Rename current window config |
| prefix c | Create new window config |
| prefix 0 | Switch to window config 0 |
| … | … |
| prefix 9 | Switch to window config 9 |
(use-package eyebrowse
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/eyebrowse/")))
;;:defer 90
:init
(setq eyebrowse-keymap-prefix (kbd "C-:"));; the default overrides org-refile: https://github.com/wasamasa/eyebrowse/issues/86
:config
(eyebrowse-mode t)
;; 2021-07-16: FIXXME: this does not work yet:
;;(add-hook 'eyebrowse-post-window-switch-hook 'my-pulse-line) ;; flash current line after switching
;; (add-hook 'eyebrowse-post-window-switch-hook '(pulse-momentary-highlight-one-line (point)))
)See hydra definition near the end of this file.
ibuffer
Replace list-buffers with ibuffer (ergoemacs: List Buffers; https://www.emacswiki.org/emacs/IbufferMode)
;;(defalias 'list-buffers 'ibuffer)
(global-set-key (kbd "C-x C-b") 'ibuffer)
(autoload 'ibuffer "ibuffer" "List buffers." t)(setq ibuffer-saved-filter-groups
(quote (("default"
("dired" (mode . dired-mode))
("PDF" (mode . pdf-view-mode))
("python" (mode . python-mode))
("org" (or (mode . org-mode)
(mode . org-agenda-mode)
))
;; ("erc" (mode . erc-mode))
("emacs" (or
(name . "^\\*scratch\\*$")
(name . "^\\*Messages\\*$")))
("planner" (or
(name . "^\\*Calendar\\*$")
(name . "^diary$")
(mode . muse-mode)))
;; ("gnus" (or
;; (mode . message-mode)
;; (mode . bbdb-mode)
;; (mode . mail-mode)
;; (mode . gnus-group-mode)
;; (mode . gnus-summary-mode)
;; (mode . gnus-article-mode)
;; (name . "^\\.bbdb$")
;; (name . "^\\.newsrc-dribble")))
))))
(add-hook 'ibuffer-mode-hook
(lambda ()
(ibuffer-switch-to-saved-filter-groups "default")))nxml-mode
Read about the XML mode on http://lgfang.github.io/mynotes/emacs/emacs-xml.html
- [ ] add hide-show config from http://lgfang.github.io/mynotes/emacs/emacs-xml.html in source and hydra
my-xml-pretty-print-region()
Source: http://stackoverflow.com/questions/12492/pretty-printing-xml-files-on-emacs
(defun my-xml-pretty-print-region (begin end)
"Pretty format XML markup in region. You need to have nxml-mode
http://www.emacswiki.org/cgi-bin/wiki/NxmlMode installed to do
this. The function inserts linebreaks to separate tags that have
nothing but whitespace between them. It then indents the markup
by using nxml's indentation rules."
(interactive "r")
(save-excursion
(nxml-mode)
(goto-char begin)
(while (search-forward-regexp "\>[ \\t]*\<" nil t)
(backward-char) (insert "\n"))
(indent-region begin end))
(message "Ah, much better!"))my-xml-pretty-print-buffer()
(defun my-xml-pretty-print-buffer()
"marks whole buffer and calls my-xml-pretty-print-region"
(interactive)
(mark-whole-buffer)
(my-xml-pretty-print-region);; FIXXME: provide (begin end)
)emojify
- 2019-12-31: DISABLED for performance reasons: https://www.reddit.com/r/orgmode/comments/e9p84n/scaling_org_better_to_use_more_medsize_files_or/fcm5bsc/
- Although this might not be that severe: https://www.reddit.com/r/orgmode/comments/e9p84n/scaling_org_better_to_use_more_medsize_files_or/fcnsbe4/
- I leave it disabled because it does not give me that much advantage.
Emoticons for the Emacs: :org: :emacs:
https://github.com/iqbalansari/emacs-emojify
(use-package emojify
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/emacs-emojify/")))
:defer 90
:init
:config
(setq emojify-emoji-styles '(github)) ;; omit "ascii" and "unicode" style
;; display emojis using images since looks nicer
(setq emojify-display-style 'image)
(setq emojify-user-emojis `((":org:" . (("name" . "Org mode")
("image" . ,(concat my-user-emacs-directory "bin/images/org-mode-logo_22x22.png"))
("style" . "github")))
(":emacs:" . (("name" . "Emacs")
("image" . ,(concat my-user-emacs-directory "bin/images/emacs_22x22.png"))
("style" . "github")))))
;; If emojify is already loaded refresh emoji data
(when (featurep 'emojify)
(emojify-set-emoji-data))
(global-emojify-mode 1)
;;(add-hook 'after-init-hook #'global-emojify-mode)
)alert
https://github.com/jwiegley/alert → Desktop notifications
(use-package alert
:ensure t
:config
(setq alert-default-style 'libnotify)
(setq alert-persist-idle-time 60);; After this many idle seconds, alerts will become sticky, and not fade away more. The default is 15 minutes.
;; ;; This is the most basic form usage
;; (alert "This is an alert")
;;
;; ;; You can adjust the severity for more important messages
;; (alert "This is an alert" :severity 'high)
;;
;; ;; Or decrease it for purely informative ones
;; (alert "This is an alert" :severity 'trivial)
;;
;; ;; Alerts can have optional titles. Otherwise, the title is the
;; ;; buffer-name of the (current-buffer) where the alert originated.
;; (alert "This is an alert" :title "My Alert")
;;
;; ;; Further, alerts can have categories. This allows users to
;; ;; selectively filter on them.
;; (alert "This is an alert" :title "My Alert" :category 'debug)
)
; (require 'alert)
My personal alert wrapper functions:
(defun my-alert (mymessage)
"wrapper for high-prio (sticky?) alert"
(interactive)
(when (not noninteractive)
;; only in interactive mode:
(setq mymessage (concat mymessage "\n\n" (concat
(format-time-string "%Y-%m-%dT%T")
((lambda (x) (concat (substring x 0 3) ":" (substring x 3 5)))
(format-time-string "%z")))))
(message mymessage)
(alert mymessage :severity 'high))
)
(defun my-flash (mymessage)
"wrapper for low-prio (non-sticky) alert flash"
(interactive)
(when (not noninteractive)
;; only in interactive mode:
(setq mymessage (concat mymessage "\n\n" (concat
(format-time-string "%Y-%m-%dT%T")
((lambda (x) (concat (substring x 0 3) ":" (substring x 3 5)))
(format-time-string "%z")))))
(message mymessage)
(alert mymessage))
)Test of my alert function:
(my-alert "This is high prio sticky.")
(my-flash "This is low prio flash.")gif-screencast
| 2020-01-23 | added to config after mentioned issue got resolved |
From: https://gitlab.com/ambrevar/emacs-gif-screencast
This package enables you to do screencasts that result in animated GIF images (no sound). However, it takes only one image per screen content change and is therefore much more storage space efficient compared to other animated GIFs.
Requires external command line tools:
- scrot
- for creating the screenshots
- convert
- for post-processing the images
- gifsicle
- for optimizing resulting GIF
On Debian-based systems, they can be installed via:
sudo apt install scrot gifsicle imagemagick
To avoid crashes of the underlying convert job when doing
high-resolution screencasts (as described in this issue), you have to
increase the disk resource value:
In /etc/ImageMagick-6/policy.xml increase the value in the line
<policy domain="resource" name="disk" value="1GiB"/>
from 1GiB to 10GiB.
(use-package gif-screencast
:if (my-system-type-is-gnu)
:ensure t
)- Screencast process:
M-x gif-screencast- <do your stuff>
M-x git-screencast-stop- in your
$HOMEyou will find a file likeoutput-2020-01-23-12:37:14.gifif everything went well.
vimgolf
| 2020-02-11 | found via emacs news and set up to test |
(use-package vimgolf
:ensure t
:defer 110
)Snippets from the README
- Find the challenge you’d like to play on VimGolf.
M-x vimgolf CHALLENGE-ID RETPoint will be in the window containing the starting text and you’ll have the goal text on a second window. Edit the starting text until it matches the ending text and then finish with
C-c C-v C.
| Command | Default Binding | Description |
|---|---|---|
vimgolf | M-x vimgolf | Input a challenge ID and play! |
vimgolf-browse | M-x vimgolf-browse | Open an interactive buffer to browse challenge titles |
vimgolf-submit | C-c C-v C | Finish and score the challenge |
vimgolf-revert | C-c C-v r | Revert to the beginning of the challenge and clear your keystrokes |
vimgolf-diff | C-c C-v d | Open an ediff session for the challenge |
vimgolf-pause | C-c C-v p | Pause keystroke recording |
vimgolf-continue | C-c C-v c | Start keystroke recording where you left off |
vimgolf-quit | C-c C-v q | Stop the challenge |
ace-window
| 2020-12-01 | disabled because of performance issue: with 3 buffers, it can take several seconds! |
After watching Sacha Chua’s video on ace-window, I decided to give it a try.
It’s a better way of jumping and managing multiple windows.
(use-package ace-window
:ensure t
;;:defer 110
:config (setq aw-keys '(?f ?j ?a ?l))
:bind ("C-x o" . ace-window)
)Now, I may switch to a different window py invoking C-x o and the
letter that got shown in the top left edge of the window.
Using the prefix version C-u C-c o I may swap the current window
with another one. A second prefix will delete the target window: C-u
C-u C-x o.
explain-pause-mode
| 2020-05-19 | cloned from GitHub and start testing |
| 2020-05-23 | disabled because it spams my mini-buffer |
Emacs minor mode that watches for long pauses and reports them.
I learned about this mode on on reddit where the developer was asking for testers. Since I do suffer from various performance bottlenecks, I decided to test this package myself.
(use-package explain-pause-mode
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/explain-pause-mode/")))
;;:defer 110
:config
(explain-pause-mode t)
)Emacs Slime Volleyball
| 2020-05-26 | setup this little game after finding it via Emacs News on GitHub |
(use-package slime-volleyball
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/slime-volleyball/")))
:config (require 'slime-volleyball)
)spatial-navigate
| 2020-10-0x | stumbled over it and it seems to be a nice general navigation feature |
| 2020-10-26 | disabled because of “((use-package “Cannot load spatial-navigate” :error nil) (use-package “Failed to install spatial-navigate: Package ‘emacs-26.2’ is unavailable” :error nil))” |
This package enables a nice type of navgating through a document. It’s rather hard to explain - just try it out yourself or read the readme-file.
I love it for navigating Python code, skipping paragraphs, and so forth.
(use-package spatial-navigate
:ensure t
;; :bind (:map my-map ("SPC" . yankpad-insert))
:config
(global-set-key (kbd "<C-up>") 'spatial-navigate-backward-vertical-bar)
(global-set-key (kbd "<C-down>") 'spatial-navigate-forward-vertical-bar)
;; I prefer the usual jump to word navigation for horizontal movements:
;;(global-set-key (kbd "<C-left>") 'spatial-navigate-backward-horizontal-bar)
;;(global-set-key (kbd "<C-right>") 'spatial-navigate-forward-horizontal-bar)
)bug-hunter → bisecting Emacs config issues
| 2020-12-10 | initial setup |
Found via tip from this issue comment.
process for my situation:
- copy config.el to testconfig.el
- insert snippet below at the top of testconfig.el
- this is part of my init.el which is ignored when using other file than init.el
- save all buffers
- start bisecting via
M-x bug-hunter-file, select file and then =i=nteractive
(package-initialize)
(defvar my-init-el-start-time (current-time) "Time when init.el was started")
(setq my-user-emacs-directory "~/.emacs.d/")
(add-to-list 'load-path (concat my-user-emacs-directory "contrib/org-contrib/lisp"))
(add-to-list 'load-path (concat my-user-emacs-directory "contrib/org-mode/lisp"))
(require 'org)(use-package bug-hunter
:ensure t
:defer 110
)keycast - show pressed keys
| 2021-03-14 | installed for screen recording |
- Project URL: https://github.com/tarsius/keycast
(use-package keycast
:ensure t
:defer 110
)copy-as-format
| 2021-07-13 | Got this tip on reddit |
(use-package copy-as-format
:ensure t
:defer 110
:after org
:bind (:map my-map ("f" . (lambda () (interactive)
(setq current-prefix-arg '(4)) ; C-u (universal argument)
(call-interactively 'copy-as-format))))
:config
(defalias 'copy-as-format-reddit 'copy-as-format-markdown) ;; idea from https://www.reddit.com/r/emacs/comments/oil7xw/i_made_a_thing_for_org_bespoke_completion_sparse/h517hps/?context=3
(defvar copy-as-format-format-alist
'(;;("asciidoc" copy-as-format--asciidoc)
;;("bitbucket" copy-as-format--github)
("disqus" copy-as-format--disqus)
("github" copy-as-format--github)
("gitlab" copy-as-format--github)
;;("hipchat" copy-as-format--hipchat)
("html" copy-as-format--html)
("jira" copy-as-format--jira)
("markdown" copy-as-format--markdown)
("reddit" copy-as-format--reddit)
;;("mediawiki" copy-as-format--mediawiki)
;;("org-mode" copy-as-format--org-mode)
;;("pod" copy-as-format--pod)
;;("rst" copy-as-format--rst)
;;("slack" copy-as-format--slack)
)
"Alist of format names and the function to do the formatting.")
)dogears
| 2021-08-13 | found on reddit and set up |
This looks like a cool method to jump back and forth between buffers. I need to test this.
(use-package dogears
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/dogears.el/")))
:defer 90
:config
(dogears-mode 1)
)qrencode
| 2021-09-21 | found via Emacs News and going to test it |
| command | explanation |
|---|---|
| qrencode-region | Shows the current selection as a QR Code. |
| qrencode-url-at-point | Encode URL at point as QR Code. |
(use-package qrencode
:ensure t
:defer 110
)secret-mode
| 2021-10-05 | found via Emacs News |
“secret-mode is an Emacs minor mode to hide your current text.” (Source)
(use-package secret-mode
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/secret-mode.el/")))
:defer 110
:after org
)crdt
| 2021-11-03 | found via Emacs news video of Sacha for EmacsConf21 |
Collaborative editing using Conflict-free Replicated Data Types \o/
- how to collaborate
crdt-protocol-versionneeds to be the same on all peers- make sure to use a computer that has a reachable IP
M-x crdt-share-buffer- enter session name
- enter port (default to 6530), optional password and your display name
- how to join a session
M-x crdt-connect- enter address, port, and your display name.
- interesting:
M-x crdt-list-usersM-x crdt-list-sessionsM-x crdt-stop-sessionstops a session you’ve started and disconnect all other users from it.M-x crdt-disconnectthen choose a session to disconnect from.crdt-visualize-author-mode- Turn on
crdt-org-sync-overlay-mode. All peers that have this enabled have their folding status synchronized.
- [ ] test this with one host with public IPs and peers with private IPs
(use-package crdt
:load-path (lambda () (expand-file-name (concat my-user-emacs-directory "contrib/crdt.el/")))
:defer 110
)My helper functions (part II)
Here I defined some functions I am using interactively and probably map to keys in the next section.
Optimizing search methods
My Org-mode files got big and numerous. I maintain roughly a third million lines of Org-mode within my files. This has an enormous performance impact on certain operations.
For searching within my Emacs files, I do use more sophisticated
methods than isearch if possible. On operating systems that provide
a decent shell environment, I use grep or git grep or ag.
helm-do-grep-ag: grep within files → my-map G
This is for using ag, the silver searcher:
Preconfigured helm for grepping with AG in `default-directory’.
(when (my-eval-if-binary-or-warn "ag")
(bind-key "G" #'helm-do-grep-ag my-map)
)my-search-method-according-to-numlines() → C-s
Choose the best/fastest search method depending on the maximum number of lines of the current buffer.
Read http://karl-voit.at/2016/04/09/chosing-emacs-search-method/ for the whole story.
(defun my-search-method-according-to-numlines (&optional arg)
"Choses search method according to buffer size: small → counsel-grep; huge → swiper-isearch; With C-u it's isearch-forward in any case."
(interactive)
(cond ((or (equal current-prefix-arg '(4)) (my-system-type-is-windows));; Windows OR universal argument → isearch-forward
(isearch-forward))
(t
(if (and (buffer-file-name)
(not (ignore-errors (file-remote-p (buffer-file-name))))
(if (eq major-mode 'org-mode)
(> (buffer-size) 60000);; for Org mode buffers, the max size for counsel-grep is 60,000 characters
(> (buffer-size) 300000)));; for non-Org mode buffers, the max size for counsel-grep is 60,000 characters
(progn
(save-buffer)
(counsel-grep))
(swiper-isearch) ;; 2019-12-07: old command before upgrading everything and replacing with swiper-isearch;; (swiper--ivy (swiper--candidates))
))
))
(global-set-key "\C-s" 'my-search-method-according-to-numlines)
(global-set-key "\C-S" 'isearch-forward)PREVIOUS (simple) approach:
(defun my-search-method-according-to-numlines ()
"Determines the number of lines of current buffer and chooses a search method accordingly"
(interactive)
(if (< (count-lines (point-min) (point-max)) 20000)
(swiper)
(isearch-forward)
)
)
;;fancy search: (global-set-key "\C-s" 'swiper)
;;normal search:
(global-set-key "\C-S" 'isearch-forward)On 2017-06-17, I stubled over an even more sophisticated setup for deciding on a search tool: https://github.com/redguardtoo/emacs.d/blob/master/lisp/init-ivy.el
my-toggle-beginner-setup() → S-F11
When I am working with Emacs, I do not use the menu bar nor the icon bar, for example. Those things got hidden in my configuration.
However, when I teach Emacs to people not familiar with the vast amount of customizations, I use the following functions to toggle my setup to look like a default Emacs.
(defvar my-toggle-beginner-setup-status nil
"state of Emacs setup which is least confusing for beginners. t means beginner, nil means normal")
;;(make-variable-buffer-local 'my-toggle-beginner-setup-status)
(defun my-emacs-normal-setup ()
"Hide things for my normal usage"
(interactive)
(if (functionp 'tool-bar-mode) (tool-bar-mode -1)) ;; hide icons
(menu-bar-mode 0) ;; hide menu-bar
(when (not (my-system-is-karl-voit-at))
(scroll-bar-mode 0) ;; hide scroll-bar, I do have Nyan-mode instead!
)
;; 2020-06-21 disabled because it causes more effort when errors are sparse:
;;(setq debug-on-quit t);; show debug information on canceling endless loops and so forth
(org-expiry-insinuate)
(setq org-log-into-drawer t)
(org-bullets-mode 1)
;; http://www.emacswiki.org/emacs/sylecn
;;show nothing in *scratch* when started
(setq initial-scratch-message nil)
;; ######################################################
;; handle CamelCaseParts as distinct words
;; http://ergoemacs.org/emacs/emacs_adv_tips.html
;; disabled 2017-10-10: not that useful ;; (global-subword-mode 1) ; 1 for on, 0 for off
;; https://www.gnu.org/software/emacs/manual/html_node/ccmode/Subword-Movement.html
;; FIXXME: this is a test for getting it work independent of
;; CamelCase words
;;(setq org-hide-leading-stars t)
;; disabled 2021-02-15 since I switched to bright mode: (load-theme 'wombat t) ;; dark theme
)
(defun my-emacs-beginner-setup ()
"Make things nice for beginners"
(interactive)
(tool-bar-mode) ;; show icons
(menu-bar-mode) ;; show menu-bar
(scroll-bar-mode 1) ;; show scroll-bar
(setq debug-on-quit nil);; no debug information on canceling endless loops and so forth
;; http://www.emacswiki.org/emacs/sylecn
;;show nothing in *scratch* when started
(setq initial-scratch-message ";; This buffer is for notes you don't want to save\n;; If you want to create a file, visit that file with C-x C-f,\n;; then enter the text in that file's own buffer.\n\n")
;; http://ergoemacs.org/emacs/emacs_adv_tips.html
;; disabled 2017-10-10: not that useful ;; (global-subword-mode 0) ; 1 for on, 0 for off
;; https://www.gnu.org/software/emacs/manual/html_node/ccmode/Subword-Movement.html
;; FIXXME: this is a test for getting it work independent of CamelCase words
;;(setq org-hide-leading-stars nil)
(org-bullets-mode 0)
(org-expiry-deinsinuate);; omit automatically created drawers
(setq org-log-into-drawer nil)
;; disabled 2021-02-15 since I switched to bright mode: (disable-theme 'wombat)
;; http://stackoverflow.com/questions/24684979/how-to-add-a-tool-bar-button-in-emacs
;;(add-hook 'after-init-hook
;; (lambda ()
;; (define-key global-map [tool-bar pdf-button]
;; '(menu-item "Export to PDF" org-latex-export-to-pdf
;; :image (image :type png :file "~/.emacs.d/bin/images/icon_PDF_16x16.png")
;; ))))
(define-key global-map [tool-bar pdf-button]
'(menu-item "Export to PDF" org-latex-export-to-pdf
:image (image :type png :file (concat my-user-emacs-directory "bin/images/icon_PDF_16x16.png"))
))
)
(my-emacs-normal-setup)
(defun my-toggle-beginner-setup ()
"Toggle Emacs beginner setup and normal Emacs"
(interactive)
(cond (my-toggle-beginner-setup-status
;; normal mode
(my-emacs-normal-setup)
(message "As you please")
(setq my-toggle-beginner-setup-status nil)
)
(t
;; make it easy for beginners
(my-emacs-beginner-setup)
(message "Welcome to Emacs!")
(setq my-toggle-beginner-setup-status t)
)
)
)
(global-set-key [(shift f11)] 'my-toggle-beginner-setup)my-toggle-dark-bright-theme() → S-F12
Some times, I do have to switch from my default dark theme to a bright one in order to get a decent result for a projector or similar.
(defvar my-toggle-dark-bright-theme-status nil
"Toggle between dark emacs theme and bright emacs theme; nil means initial switch to dark theme, t means initial switch to bright theme")
(defun my-toggle-dark-bright-theme ()
"Toggle between dark emacs theme and bright emacs theme"
(interactive)
(cond (my-toggle-dark-bright-theme-status
(message "Loading bright theme")
(disable-theme 'wombat)
;;(load-theme 'leuven t)
(setq my-toggle-dark-bright-theme-status nil)
)
(t
(message "Loading dark theme")
;;(disable-theme 'leuven)
(load-theme 'wombat t) ;; dark theme
(setq my-toggle-dark-bright-theme-status t)
)
)
)
(global-set-key [(shift f12)] 'my-toggle-dark-bright-theme)my-toggle-split-and-single-window() - Toggle between split windows and a single window
http://thornydev.blogspot.co.at/2012/08/happiness-is-emacs-trifecta.html
(defun my-toggle-split-and-single-window()
"Switch back and forth between one window and whatever split of
windows we might have in the frame. The idea is to maximize the
current buffer, while being able to go back to the previous split
of windows in the frame simply by calling this command again."
(interactive)
(if (not (window-minibuffer-p (selected-window)))
(progn
(if (< 1 (count-windows))
(progn
(window-configuration-to-register ?u)
(delete-other-windows))
(jump-to-register ?u))))
;(my-iswitchb-close)
)Inserting time-stamps → my-map [dDtT]
Org-mode has some built-in methods to create active and inactive time-stamps. The following functions offer a shortcut to insert the current day as an Org-mode time-stamp when I am within an Org-mode buffer and in ISO 8601 format when I am in another major mode.
- 2011-04-20: C-j t … timestamp
- http://www.sabren.net/articles/emacs.php3
- http://www.gnu.org/software/emacs/manual/html_node/emacs/Date-Display-Format.html
- COMBINED WITH:
- 2012-12-09:
From: Russell Adams <RLAdams@AdamsInfoServ.Com> Newsgroups: gmane.emacs.orgmode Subject: Re: Using org-mode for laboratory notes. Date: Wed, 19 Sep 2012 12:08:21 -0500 Message-ID: <20120919170820.GC31853@cardamom.adamsinfoserv.com>
- 2012-12-09:
;; Insert immediate timestamp
(defun my-insert-timestamp()
"Insert the current time in yyyy-mm-dd format."
(interactive "*")
(if (eq major-mode 'org-mode)
(progn
(org-insert-time-stamp nil t nil)
(insert " ")
)
(insert (format-time-string "%Y-%m-%d" (current-time)))
)
)
(bind-key "t" #'my-insert-timestamp my-map)(defun my-insert-timestamp-inactive()
"Insert the current time in yyyy-mm-dd format."
(interactive "*")
(if (eq major-mode 'org-mode)
(progn
(org-insert-time-stamp nil t t)
(insert " ")
)
(insert (format-time-string "%Y-%m-%d" (current-time)))
)
)
(bind-key "T" #'my-insert-timestamp-inactive my-map)(defun my-insert-datestamp()
"Insert the current date in yyyy-mm-dd format."
(interactive "*")
(if (eq major-mode 'org-mode)
(progn
(org-insert-time-stamp nil nil nil)
(insert " ")
)
(insert (format-time-string "%Y-%m-%d" (current-time)))
)
)
(bind-key "d" #'my-insert-datestamp my-map)(defun my-insert-datestamp-inactive()
"Insert the current date in yyyy-mm-dd format."
(interactive "*")
(if (eq major-mode 'org-mode)
(progn
(org-insert-time-stamp nil nil t)
(insert " ")
)
(insert (format-time-string "%Y-%m-%d" (current-time)))
)
)
(bind-key "D" #'my-insert-datestamp-inactive my-map)OS X: mdfind (find via spotlight)
Code of this heading does provide access to the macOS spotlight search engine for Emacs. I did not use it quite often, as long as I was using macOS on my computers.
http://blog.zenspider.com/2007/03/locate-and-spotlight.html
(when (my-system-type-is-darwin)
(defun locate-make-mdfind-command-line (search-string)
(list "mdfind" (concat "kMDItemDisplayName=*" search-string "*")))
(defun spotlight ()
"Search for files by name using spotlight"
(interactive)
(let ((locate-command "mdfind")
(locate-make-command-line 'locate-make-mdfind-command-line))
(call-interactively 'locate nil)))
(defun spotlight-full ()
"Search using spotlight"
(interactive)
(let ((locate-command "mdfind"))
(call-interactively 'locate nil)))
)my-codenav-*: Code navigation → M-i | M-k
I found very handy navigation commands on Code Navigation in Emacs which I included here:
(defun my-codenav-imenu-candidates ()
"Get the candidates list from imenu."
(let* ((items (imenu--make-index-alist))
(items (delete (assoc "*Rescan*" items) items)))
items))
(defun my-codenav-flatten-candidates (candidates)
"Flatten CANDIDATES of imenu list."
(let (result)
(dolist (candidate candidates result)
(if (imenu--subalist-p candidate)
(setq result (append result (my-codenav-flatten-candidates (cdr candidate))))
(add-to-list 'result candidate)))
result))
(defun my-codenav-sort-candidates (candidates)
(sort candidates (lambda (a b) (< (cdr a) (cdr b)))))
(defun my-codenav-current-symbol (names-and-pos)
"Figure out current definition by checking positions of NAMES-AND-POS against current position."
(let ((list-length (length names-and-pos))
(current-pos (point))
(current-index 0)
(next-index 0))
(dolist (symbol names-and-pos)
;; If we reaches the end, just return the last element
;; instead of returning index+1
(setq next-index (if (< next-index (1- list-length))
(1+ current-index)
current-index))
(let* ((current-symbol-pos (marker-position (cdr symbol)))
(next-symbol-pos (marker-position (cdr (nth next-index names-and-pos)))))
(if (and (= current-index 0) (< current-pos current-symbol-pos))
(return 0))
(if (and (>= current-pos current-symbol-pos) (< current-pos next-symbol-pos))
(return current-index)))
(setq current-index (1+ current-index)))
;; If last item, decrement index
(if (eq current-index (length names-and-pos))
(1- current-index)
current-index)))
(defun my-codenav-next-definition ()
"Navigate to next function/class definition."
(interactive)
(let* ((imenu-candidates (my-codenav-imenu-candidates))
(names-and-pos (my-codenav-sort-candidates (my-codenav-flatten-candidates imenu-candidates)))
(current-symbol (my-codenav-current-symbol names-and-pos))
(next-symbol-index (if (>= (1+ current-symbol) (length names-and-pos)) 0
(1+ current-symbol)))
(next-symbol (nth next-symbol-index names-and-pos)))
(imenu next-symbol)))
(defun my-codenav-prev-definition ()
"Navigate to previous function/class definition."
(interactive)
(let* ((imenu-candidates (my-codenav-imenu-candidates))
(names-and-pos (my-codenav-sort-candidates (my-codenav-flatten-candidates imenu-candidates)))
(current-symbol (my-codenav-current-symbol names-and-pos))
(prev-symbol-index (if (< (1- current-symbol) 0) (1- (length names-and-pos))
(1- current-symbol)))
(prev-symbol (nth prev-symbol-index names-and-pos)))
(imenu prev-symbol)))
(global-set-key (kbd "M-i") (lambda () (interactive) (my-codenav-prev-definition)))
(global-set-key (kbd "M-k") (lambda () (interactive) (my-codenav-next-definition)))my-lorem-ipsum-overlay
| 2020-02-09 | found on GitHub via Mastodon toot and added |
First, I’m going to install lorem-ipsum which provides basic
functionality to generate latin bullshit:
(use-package lorem-ipsum
:ensure t
:defer 110
)I found this beauty within alphapapa’s diamonds on GitHub:
(defcustom unpackaged/lorem-ipsum-overlay-exclude nil
"List of regexps to exclude from `my-lorem-ipsum-overlay'."
:type '(repeat regexp))
(setq unpackaged/lorem-ipsum-overlay-exclude
`(
"NEXT" "TODO" "STARTED" "WAITING" "DONE" "SOMEDAY" "CANCELED"
"Today"
"Important" "Started" "reward" "Scheduled:"
"Other"
;;,(rx "Other" space "items") ;; "Other items" NOT working yet
;;,(rx "Sched\\." (one-or-more digit) "x:") ;; "Sched.10x:" NOT working yet
;;"Sched\\.[0-9]+:" ;; NOT working
"WAITING" "items" ;; "WAITING items" NOT working yet
"Priority" ;; "Priority <= B items" NOT working yet
"misc" "projects" "issues" "hardware"
"Monday" "Tuesday" "Wednesday" "Thursday" "Friday" "Saturday" "Sunday"
"January" "February" "March" "April" "May" "June" "July" "August" "September" "October" "November" "November" "December"
)
)
;;;###autoload
(defun my-lorem-ipsum-overlay ()
"Overlay all text in current buffer with \"lorem ipsum\" text.
When called again, remove overlays. Useful for taking
screenshots without revealing buffer contents.
Each piece of non-whitespace text in the buffer is compared with
regexps in `unpackaged/lorem-ipsum-overlay-exclude', and ones
that match are not overlaid. Note that the regexps are compared
against the entire non-whitespace token, up-to and including the
preceding whitespace, but only the alphabetic part of the token
is overlaid. For example, in an Org buffer, a line that starts
with:
#+TITLE: unpackaged.el
could be matched against the exclude regexp (in `rx' syntax):
(rx (or bol bos blank) \"#+\" (1+ alnum) \":\" (or eol eos blank))
And the line would be overlaid like:
#+TITLE: parturient.et"
(interactive)
(require 'lorem-ipsum)
(let ((ovs (overlays-in (point-min) (point-max))))
(if (cl-loop for ov in ovs
thereis (overlay-get ov :lorem-ipsum-overlay))
;; Remove overlays.
(dolist (ov ovs)
(when (overlay-get ov :lorem-ipsum-overlay)
(delete-overlay ov)))
;; Add overlays.
(let ((lorem-ipsum-words (--> lorem-ipsum-text
(-flatten it) (apply #'concat it)
(split-string it (rx (or space punct)) 'omit-nulls)))
(case-fold-search nil))
(cl-labels ((overlay-match (group)
(let* ((beg (match-beginning group))
(end (match-end group))
(replacement-word (lorem-word (match-string group)))
(ov (make-overlay beg end)))
(when replacement-word
(overlay-put ov :lorem-ipsum-overlay t)
(overlay-put ov 'display replacement-word))))
(lorem-word (word)
(if-let* ((matches (lorem-matches (length word))))
(apply-case word (downcase (seq-random-elt matches)))
;; Word too long: compose one.
(apply-case word (downcase (compose-word (length word))))))
(lorem-matches (length &optional (comparator #'=))
(cl-loop for liw in lorem-ipsum-words
when (funcall comparator (length liw) length)
collect liw))
(apply-case (source target)
(cl-loop for sc across-ref source
for tc across-ref target
when (not (string-match-p (rx lower) (char-to-string sc)))
do (setf tc (string-to-char (upcase (char-to-string tc)))))
target)
(compose-word (length)
(cl-loop while (> length 0)
for word = (seq-random-elt (lorem-matches length #'<=))
concat word
do (cl-decf length (length word)))))
(save-excursion
(goto-char (point-min))
(while (re-search-forward (rx (group (1+ (or bol bos blank (not alpha)))
(0+ (not (any alpha blank)))
(group (1+ alpha))
(0+ (not (any alpha blank)))))
nil t)
(unless (cl-member (match-string 0) unpackaged/lorem-ipsum-overlay-exclude
:test (lambda (string regexp)
(string-match-p regexp string)))
(overlay-match 2))
(goto-char (match-end 2)))))))))Note: I filed a feature request on ignoring some keywords from replacement.
my-insert-char
| 2020-02-12 | found and setup this nugget via this toot and that toot |
This toot shows a nice method to enter Unicode characters system-wide:
- define
my-insert-charbelow - manually test in the command line using:
emacsclient -c -e '(my-insert-char)' - map to a system-wise keyboard shortcut and use it to put arbitrary Unicode characters in the system clipboard
Helper function to modify the behavior of counsel-unicode-char to
match the one of insert-char taken from this reddit thread:
(defun counsel-unicode-char-to-kill (&optional count)
"Insert COUNT copies of a Unicode character to kill ring.
COUNT defaults to 1."
(interactive "p")
(setq ivy-completion-beg (point))
(setq ivy-completion-end (point))
(ivy-read "Unicode name: " counsel--unicode-table
:history 'counsel-unicode-char-history
:action (lambda (name)
(with-ivy-window
(kill-new (make-string count (get-text-property 0 'code name)))
))
:caller 'counsel-unicode-char-to-kill))(defun my-insert-char ()
(interactive)
(with-temp-buffer
(call-interactively 'insert-char) ;; classic method
;; (call-interactively 'counsel-unicode-char) ;; improved usability but inserts characters differently
;; (call-interactively 'counsel-unicode-char-to-kill)
(kill-ring-save (point-min) (point-max))))
(defun my-insert-char-counsel ()
(interactive)
(with-temp-buffer
(call-interactively 'counsel-unicode-char) ;; improved usability but inserts characters differently
(kill-ring-save (point-min) (point-max))))
(defun my-insert-char-counsel-to-kill ()
(interactive)
(with-temp-buffer
(call-interactively 'counsel-unicode-char-to-kill)
(kill-ring-save (point-min) (point-max))))hydra
Hydra is a method to customize personal and visual menus to summarize various functionality.
Please note: :color red is for repeating actions, :color blue for
one-time actions. From the web site:
The
:colorkey is a shortcut. It aggregates:exitand:foreign-keyskey in the following way:
color toggle red stay blue :exit t amaranth :foreign-keys warn teal :foreign-keys warn :exit t pink :foreign-keys run
START of hydra
(use-package hydra
:ensure t
:defer 90
:config ;; executed after loading packagetoggle things with Ruby-style docstring → my-map M
Example 7 from hydra-examples.el
(defvar whitespace-mode nil)
(defhydra hydra-toggle (:color teal)
"
_f_ auto-fill-mode: %`auto-fill-function
_t_ truncate-lines: %`truncate-lines
_w_ whitespace-mode: %`whitespace-mode
_l_ org link display: %`org-descriptive-links
_a_ abbrev-mode: %`abbrev-mode
_d_ debug-on-error: %`debug-on-error
"
;; ("q" nil "quit")
("a" abbrev-mode nil)
("d" toggle-debug-on-error nil)
("f" auto-fill-mode nil)
("t" toggle-truncate-lines nil)
("w" whitespace-mode nil)
("l" org-toggle-link-display nil)
)
;; Recommended binding:
;;(global-set-key (kbd "C-c C-v") 'hydra-toggle/body)
(bind-key "M" #'hydra-toggle/body my-map)s-expressions in the docstring
Example 9 from hydra-examples.el
;; You can inline s-expresssions into the docstring like this:
(defvar dired-mode-map)
(declare-function dired-mark "dired")
(when (bound-and-true-p hydra-examples-verbatim)
(require 'dired)
(defhydra hydra-marked-items (dired-mode-map "")
"
Number of marked items: %(length (dired-get-marked-files))
"
("m" dired-mark "mark")))apropos → C-c h
Example 10 from hydra-examples.el
(defhydra hydra-apropos (:color blue
:hint nil)
"
_a_propos _c_ommand
_d_ocumentation _l_ibrary
_v_ariable _u_ser-option
^ ^ valu_e_"
("a" apropos)
("d" apropos-documentation)
("v" apropos-variable)
("c" apropos-command)
("l" apropos-library)
("u" apropos-user-option)
("e" apropos-value))
;; Recommended binding:
(global-set-key (kbd "C-c h") 'hydra-apropos/body)rectangle-mark-mode → C-x r h
Example 11 from hydra-examples.el
(require 'rect)
(defhydra hydra-rectangle (:body-pre (rectangle-mark-mode 1)
:color pink
:post (deactivate-mark))
"
^_k_^ _d_elete _s_tring
_h_ _l_ _o_k _y_ank
^_j_^ _n_ew-copy _r_eset
^^^^ _e_xchange _u_ndo
^^^^ ^ ^ _p_aste
"
("h" rectangle-backward-char nil)
("l" rectangle-forward-char nil)
("k" rectangle-previous-line nil)
("j" rectangle-next-line nil)
("e" hydra-ex-point-mark nil)
("n" copy-rectangle-as-kill nil)
("d" delete-rectangle nil)
("r" (if (region-active-p)
(deactivate-mark)
(rectangle-mark-mode 1)) nil)
("y" yank-rectangle nil)
("u" undo nil)
("s" string-rectangle nil)
("p" kill-rectangle nil)
("o" nil nil))
(global-set-key (kbd "C-x r h") 'hydra-rectangle/body)reStructuredText → F1
(defhydra hydra-rst (:color blue)
(concat my-f-key-settings
"
_a_ insert • complete • promote adornment ( C-c C-a C-a )
_c_ycle adornment ( C-- C-= ) Let's love
_r_e-adjust adornments of buffer ( C-c C-a C-s ) reStructured Text
_v_isualize adornment formats used ( C-c C-a C-d )
_,_ ↑ ( C-M-e )
section
_._ ↓ ( C-M-a )
_m_ark section ( C-M-h )
_n_ew line with indent ( C-j )
────^^────────────────────────────────────────────────────────────
_s_hift region → ( C-c C-r TAB )
← _S_hift region ( M-- C-c C-r TAB )
────^^───────────────────────────────────────────^^───────────────────────────────────────────────────────────
_C_omment region ( M-; ) _t_oc temp view (close with c; zip with z) ( C-c C-t C-t )
_b_ullet list region ( C-c C-l C-b ) _T_oc insert TOC (did not work) ( C-c C-t C-i )
_e_numerated list region ( C-c C-l C-e ) _u_pdate TOC ( C-c C-t C-u )
_i_nsert item ( C-c C-l C-i )
^^
")
("a" rst-adjust nil)
("c" (rst-adjust -1) nil :color red)
("r" rst-straighten-adornments nil)
("v" rst-display-adornments-hierarchy nil)
("," rst-forward-section nil :color red)
("." rst-backward-section nil :color red)
("m" rst-mark-section nil :color red)
("s" rst-shift-region nil :color red)
("S" rst-shift-region nil :color red)
("n" newline-and-indent nil)
("C" comment-dwim nil)
("b" rst-bullet-list-region nil)
("e" rst-enumerate-region nil)
("i" rst-insert-list nil)
("t" rst-toc nil)
("T" rst-toc-insert nil)
("u" rst-toc-update nil)
("q" nil "quit")
)
(require 'rst)
(define-key rst-mode-map [f1] 'hydra-rst/body)hydra-search → F9
As soon as I was able to test org-rifle, it has replaced many search workflows I was using before. Its speed combined with the result visualization is brilliant.
helm-org-rifle- Show results from all open Org buffers
helm-org-rifle-agenda-files- Show results from Org agenda files
helm-org-rifle-current-buffer- Show results from current buffer
helm-org-rifle-directories- Show results from selected directories; with prefix, recursively
helm-org-rifle-files- Show results from selected files
helm-org-rifle-org-directory- Show results from Org files in org-directory
(defhydra hydra-search (:color blue)
(concat my-f-key-settings
"
^^Rifle ^^Profiler ^^Bookmarks ^^MISC Ex.: #A NEXT :foo:bar: !unwanted
^^────────────────────────^^──────────────────^^─────────────────────────────^^────────────────
rifle _c_urrent buffer _p_rofile CPU _m_ark new bookmark C-x r m _d_ired-jump
rifle _o_pen buffers _R_eport jump _b_ookmark C-x r b
rifle _a_genda files profiler sto_P_ _l_ist bookmarks C-x r l
rifle whole _O_rg dir ^^ ^^
^^ ^^ dogears-_g_o
^^ ^^ dogears-_r_emember
^^Filter ^^ ^^ ^^
^^────────────────────────────────────────^^─────────────────────────────^^────────────────
tree: _w_aiting tasks
tree: OPEN TASKS by tags, no completion: my-sparse-tree-with-_t_ag-filter
tree: all tasks by tags: org-tags-sparse-_T_ree
list: all tasks by tags: org-tags-_v_iew (C-c a m)
")
("q" nil "quit")
("c" helm-org-rifle-current-buffer nil)
("o" helm-org-rifle nil)
("O" helm-org-rifle-org-directory nil)
("a" helm-org-rifle-agenda-files nil)
("p" (lambda () (interactive) (profiler-start 'cpu)) nil)
("R" profiler-report nil)
("P" profiler-stop nil)
("m" bookmark-set nil)
("b" bookmark-jump nil)
("l" bookmark-bmenu-list nil)
("g" dogears-go nil)
("r" dogears-remember nil)
("d" dired-jump nil)
("w" my-sparse-tree-WAITING nil)
("t" my-sparse-tree-with-tag-filter nil)
("T" org-tags-sparse-tree nil)
("v" org-tags-view nil)
)
(global-set-key [f9] 'hydra-search/body)hydra-projectile → S-F9
| 2020-12-10 | initial setup; stolen from here |
(defhydra hydra-projectile-other-window (:color teal)
"projectile-other-window"
("f" projectile-find-file-other-window "file")
("g" projectile-find-file-dwim-other-window "file dwim")
("d" projectile-find-dir-other-window "dir")
("b" projectile-switch-to-buffer-other-window "buffer")
("q" nil "cancel" :color blue))
(defhydra hydra-projectile (:color teal
:hint nil)
(concat my-f-key-settings
"
PROJECTILE: %(projectile-project-root)
Find File Search/Tags Buffers Cache
------------------------------------------------------------------------------------------
_s-f_: file _a_: ag _i_: Ibuffer _c_: cache clear
_ff_: file dwim _g_: update gtags _b_: switch to buffer _x_: remove known project
_fd_: file curr dir _o_: multi-occur _s-k_: Kill all buffers _X_: cleanup non-existing
_r_: recent file ^^^^_z_: cache current
_d_: dir
")
("a" projectile-ag)
("b" projectile-switch-to-buffer)
("c" projectile-invalidate-cache)
("d" projectile-find-dir)
("s-f" projectile-find-file)
("ff" projectile-find-file-dwim)
("fd" projectile-find-file-in-directory)
("g" ggtags-update-tags)
("s-g" ggtags-update-tags)
("i" projectile-ibuffer)
("K" projectile-kill-buffers)
("s-k" projectile-kill-buffers)
("m" projectile-multi-occur)
("o" projectile-multi-occur)
("s-p" projectile-switch-project "switch project")
("p" projectile-switch-project)
("s" projectile-switch-project)
("r" projectile-recentf)
("x" projectile-remove-known-project)
("X" projectile-cleanup-known-projects)
("z" projectile-cache-current-file)
("`" hydra-projectile-other-window/body "other window")
("q" nil "cancel" :color blue))
(global-set-key [(shift f9)] 'hydra-projectile/body)
hydra-nxml → F1
(defhydra hydra-nxml (:color blue)
(concat my-f-key-settings
"
^^ ^^ ^^ ←→ element C-M n|p
^^View ^^ ^^ ↑↓ element C-M u|d
^────────^───────────────────────^──────^─────────────────────^─────────^─────
_r_egion prettyfy ^^ ^^ C-M-i auto-complete
_b_uffer prettify ^^ ^^ C-/ finish element
^^ ^^ ^^
^^ ^^ ^^
")
("r" my-xml-pretty-print-region nil)
("b" my-xml-pretty-print-buffer nil)
("q" nil "quit")
)
(require 'nxml-mode)
(define-key nxml-mode-map [f1] 'hydra-nxml/body)hydra-csv → F1
(defhydra hydra-csv (:color blue)
(concat my-f-key-settings
"
^^
_a_lign Fields into Columns C-c C-a _B_ Set Buffer's Comment Start C-c C-c
_u_nalign Columns into Fields C-c C-u _L_ Sort By Field Lexicographically C-c C-s
^^ _N_ Sort By Field Numerically C-c C-n
_,_ ← Field → _._ C-M-b/f _D_ Use Descending Sort Order C-c C-d
^^ _r_everse Order of Lines C-c C-r
_S_ Make Separators Invisible C-c C-v _t_ranspose Rows and Columns C-c C-t
_i_ Toggle Field Index Mode ^^
^^ _k_ Kill Fields C-c C-k
^^ _y_ank Fields (Columns) C-c C-y
^^ _Y_ank As New Table C-c C-z
^^
")
("a" csv-align-fields nil :color red)
("u" csv-unalign-fields nil :color red)
("B" csv-set-comment-start nil)
("D" csv-toggle-descending nil)
("k" csv-kill-fields nil)
("N" csv-sort-numeric-fields nil)
("r" csv-reverse-region nil)
("L" csv-sort-fields nil)
("t" csv-transpose nil)
("S" csv-toggle-invisibility nil :color red)
("y" csv-yank-fields nil)
("Y" csv-yank-as-new-table nil)
("." csv-forward-field nil :color red)
("," (csv-forward-field -1) nil :color red)
("i" csv-field-index-mode nil :color red)
("q" nil "quit")
)
(require 'csv-mode)
(define-key csv-mode-map [f1] 'hydra-csv/body)hydra-org → F1
In 2018-07 I started to create hydras for major modes that contain shortcuts to many functions I am using as well as cheatsheets that work as a reminder. I started with dired and Elpy mode.
For Org mode, I could not come up with a list of shortcuts and cheatsheets I want to see within the hydra. Most probably because all Org mode commands are already within my finger-brains ;-)
This is to collect ideas of commands that might be candidates for hydra-org:
- [X] my-jump-to-lazyblorg-heading-according-to-URL-in-clipboard()
- [X] jump to [123] and do org-decrypt-entry where
- 1: notes > browser
- 2: ciso > personal
- 3: ciso > shared
- [X] my-insert-orgmode-url-from-clipboard()
- [X] my-set-tags-including-inherited () → I forgot meanwhile!
- [X] my-sparse-tree-with-tag-filter() - ask for a tag and filter open Org-tasks → my-map F
- [ ] toggle commands for private/business agenda
- [ ] start memacs (agenda) views
- [ ] my-url-linkify()
- [ ] my-lazyblorg-test()
Org agenda hydra:
- [ ] my-agenda-cancel-event-and-set-to-inactive() → I forgot meanwhile!
- [ ] my-0d() → I forgot meanwhile!
Not org related but might be candidates as well:
- [X] my-toggle-beginner-setup() → F1
- [X] my-toggle-dark-bright-theme() → S-F1
- [ ] https://github.com/abo-abo/hydra/wiki/Org-agenda
(defhydra hydra-org (:color blue)
(concat my-f-key-settings
"
^^Go to ^^Inserting ^^Org-timer ^^Properties ^^Tables
^────────^───────────────────────^──────^───────────────────────────^^───────────────────────^─────────^───────────────────────────^^────────────────────────────────────
_L_azyblorg ID via clipboard ID _u_rl clipboard → Org link Start C-c C-x _0_ _o_rdered dependency S-RET fill from cell above
_p_ersonal credentials _T_ags include inherited Insert C-c C-x _._ _N_oblocking (this is never blocked) C-u C-u C-c = edit cell formular
_b_usiness credentials _1_ split block (M-RET) Pause C-c C-x _,_ org-linker-_e_dna C-c ? info on cell + reference
org-_a_ttach-reveal add _n_ote to logbook Stop C-c C-x ___ ^^ C-c { debug formula mode
^^ _c_ontact link ^^ ^^ C-c } toggle row/column overlay
^^ mark as _P_roject ^^ ^^ C-c ' edit formulas (S-<arrows> for changing references)
^^ generate & copy _i_d ^^ ^^
^^ _w_ebarchive tsfile ^^ ^^
^^C-c C-a attachment menu indent-_r_igidly C-x TAB ^^ ^^
^^ org-_A_ttach-set-directory ^^ ^^
^^ my-org-attach-_I_nsert ^^ ^^
^^ ^^ ^^ ^^ ^^M-0 C-x e kmacro-end-and-call-macro → do macro until end of buffer
^^Filter ^^Export ^^MISC my-map C-c C-,
^────────^───────────────────────^──────^─────────────────────────^─────────^───────────────────────────────────────────────────
_f_ocus agenda (prio A; sched .) _R_eddit/Wiki.js (region) _x_ secret-mode y yankpad-expand
_F_ocus disabled for agenda _d_efine word b my-mark-block
^^ ^^ _W_eather Graz S my-synonym-current-word
^^ ^^ _!_ save-buffers-kill-terminal s spray-mode (speed-reading)
")
("f" (lambda ()
(interactive)
(org-agenda-filter-apply '("+.*\\[#A\\].*") 'regexp)
) nil)
("F" (lambda ()
(interactive)
(org-agenda-filter-show-all-re)
) nil)
("p" (lambda ()
(interactive)
(switch-to-buffer "notes.org")
(org-id-goto "browser-restart")
(org-decrypt-entry)
) nil)
("P" my-mark-as-project nil)
("w" my-webarchive-tsfile nil)
;; 2020-05-20: we do not share credentials in this company *g*
;; ("B" (lambda ()
;; (interactive)
;; (switch-to-buffer "rise.org")
;; (org-id-goto "rise-shared-credentials")
;; (org-decrypt-entry)
;; ) nil)
("b" (lambda ()
(interactive)
(switch-to-buffer "rise.org")
(org-id-goto "rise-personal-credentials")
(org-decrypt-entry)
) nil)
("L" my-jump-to-lazyblorg-heading-according-to-URL-in-clipboard nil)
("u" my-insert-orgmode-url-from-clipboard nil)
("T" my-set-tags-including-inherited nil)
("1" my-org-split-block nil)
("R" my-reddit-export-via-pandoc nil)
("d" define-word-at-point nil)
("W" (lambda () (interactive) (wttrin-query "graz")) nil)
("n" org-add-note nil)
("c" helm-org-contacts nil)
("i" my-id-get-or-generate nil)
("e" org-linker-edna nil)
("0" org-timer-start nil)
("." org-timer nil)
("," org-timer-pause-or-continue nil)
("_" org-timer-stop nil)
("!" save-buffers-kill-terminal nil)
;; ("t" my-dired-tagtrees nil)
;; ("T" my-dired-tagtrees-recursive nil)
("N" (lambda () (interactive) (org-set-property "NOBLOCKING" "t")) nil)
("o" (lambda () (interactive) (org-set-property "ORDERED" "t")) nil)
("r" indent-rigidly nil)
("A" org-attach-set-directory nil)
("a" org-attach-reveal nil)
("I" my-org-attach-insert nil)
("x" secret-mode nil)
("q" nil "quit")
)
(define-key org-mode-map [f1] 'hydra-org/body)
(define-key org-agenda-mode-map [f1] 'hydra-org/body)hydra-python → F1
(defhydra hydra-python (:color blue)
(concat my-f-key-settings
"
^View^ ^Navigation^ ^^ C-↑↓ goto line of same level
^^─────────────────────^^──────────────────^^──────────────── M-RET yafolding-toggle-element
_h_ide/show fun M-h _p_ ← error F5 ^^
_c_ycle all M-H _n_ error → F6 ^^
^^ _<_ ← symbol ^^
^^ _>_ symbol → ^^
^^ _d_ definition ^^
^^ _r_ references ^^
^^ ^^ ^^
^Edit^ ^Help^ ^^
^^─────────────────────^^──────────────────^^────────────────
_i_mplement C-c i _H_elp (pylookup) ^^
^^ ^^ ^^
^^ ^^ ^^
")
("q" nil "quit")
("h" hs-cycle nil :color red)
("c" hs-cycle-all nil)
("p" flymake-goto-prev-error nil :color red)
("n" flymake-goto-next-error nil :color red)
("<" highlight-symbol-prev nil)
(">" highlight-symbol-next nil)
("d" lsp-find-definition nil)
("r" lsp-find-references nil)
;;old;; ("i" elpygen-implement nil)
;;old;; ("r" elpy-refactor nil)
;;old;; ("d" sphinx-doc nil)
;;old;; ("." elpy-goto-definition nil)
("H" pylookup-lookup nil)
; ("" nil)
)
(with-eval-after-load 'python
(define-key python-mode-map [f1] 'hydra-python/body)
)hydra-notmuch → F1
| 2021-02-13 | disabled since I can’t use business email with Emacs |
(defhydra hydra-notmuch (:color blue)
(concat my-f-key-settings
"
^^─────────────────────^^──────────────────^^────────────────
_g_ fetch mails ^^ ^^
_m_ new email ^^ ^^
^^ ^^ ^^
^^ ^^ ^^
")
("q" nil "quit")
("g" my-notmuch-sync-and-update-index-and-buffer nil)
("m" notmuch-mua-new-mail nil)
; ("p" flymake-goto-prev-error nil :color red)
; ("<" highlight-symbol-prev nil)
)
(when (my-system-type-is-gnu)
(define-key notmuch-hello-mode-map [f1] 'hydra-notmuch/body)
)hydra-notmuch-message-mode → F1
| 2021-02-13 | disabled since I can’t use business email with Emacs |
(when (my-system-type-is-gnu)
(defhydra hydra-notmuch-message-mode (:color blue)
(concat my-f-key-settings
"
^^Header ^^Footnotes ^^Format
^^────────────────────────────^^────────────────────────^^────────────────
change _s_ubject (C-c C-s f) _a_dd (C-c ! a) _i_nsert quote (M-RET)
^^ _b_ack to text (C-c ! b) _S_ign
^^ _g_oto FN (C-c ! g) _E_ncrypt and sign
^^ _d_elete (C-c ! d) ^^
^^ _r_enumber (C-c ! r) ^^
^^ ^^ ^^
^^ ^^ ^^
")
("q" nil "quit")
("s" message-change-subject nil)
("i" message-newline-and-reformat nil)
("a" footnote-add-footnote nil)
("b" footnote-back-to-message nil)
("g" footnote-goto-footnote nil)
("d" footnote-delete-footnote nil)
("r" footnote-renumber-footnotes nil)
("S" mml-secure-sign-pgpmime nil)
("E" mml-secure-encrypt-pgpmime nil)
; ("p" flymake-goto-prev-error nil :color red)
; ("<" highlight-symbol-prev nil)
)
(define-key notmuch-message-mode-map [f1] 'hydra-notmuch-message-mode/body)
)hydra-notmuch-show-mode → F1
| 2021-02-13 | disabled since I can’t use business email with Emacs |
(when (my-system-type-is-gnu)
(defhydra hydra-notmuch-show-mode (:color blue)
(concat my-f-key-settings
"
^^Email ^^Thread
^^────────────────────────────────────^^────────────────────────
raw message _V_ _P_revious _N_ext message
add/remove tag: _+_ _-_ fi_l_ter thread
toggle _h_eaders ^^
_h_tml part → browser ^^
save attachments _w_ ^^
^^ ^^
_r_eply _R_eply all ^^
_o_rg link (C-c l paste: C-c C-l) ^^
^^ ^^
")
("q" nil "quit")
("" nil)
("V" notmuch-show-view-raw-message nil)
("w" notmuch-show-save-attachments nil)
("+" notmuch-show-add-tag nil)
("-" notmuch-show-remove-tag nil)
("h" notmuch-show-toggle-visibility-headers nil)
("P" notmuch-show-previous-message nil)
("N" notmuch-show-next-message nil)
("R" notmuch-show-reply nil)
("r" notmuch-show-reply-sender nil)
("l" notmuch-show-filter-thread nil)
("w" notmuch-show-save-attachments nil)
("h" notmuch-show-view-part nil)
("o" org-notmuch-store-link nil)
)
(define-key notmuch-show-mode-map [f1] 'hydra-notmuch-show-mode/body)
)hydra-git → Shift F2
(defhydra hydra-git (:color blue)
(concat my-f-key-settings
"
^^View ^^ ^^
^^─────────────────────^^──────────────────^^────────────────
_s_tatus my-map g ^^ ^^
_t_ime-machine ^^ ^^
magit-_l_og-buffer-file^^ ^^
^^ ^^ ^^
^^Smeargle ^^ ^^
^^─────────────────────^^──────────────────^^────────────────
_h_ighlight on ^^ ^^
smeargle _c_ommits ^^ ^^
smeargle _C_lear ^^ ^^
^^ ^^ ^^
")
("q" nil "quit")
("s" magit-status nil)
("t" git-timemachine-toggle nil)
("l" magit-log-buffer-file nil)
("h" smeargle nil :color red)
("c" smeargle-commits nil :color red)
("C" smeargle-clear nil)
)
(with-eval-after-load 'magit
(define-key global-map [(shift f2)] 'hydra-git/body)
;;(global-set-key [f9] 'hydra-git/body)
)hydra-dired → F1
(defhydra hydra-dired (:color blue)
(concat my-f-key-settings
"
_t_agtrees _f_ilter _d_ate2name g refresh M-c dired-ranger-copy M-t filetags
_T_agtrees recursive _F_ilter recursive time_2_name + mkdir M-v dired-ranger-paste M-a appendfilename
^────────^────────────^──────^──────────────^─────────^───── *. mark extensions M-m dired-ranger-move
_a_bsolute link _m_emacs tsfile link _D_ate2name.el D delete marked
_A_bsolute basename ^^ ^^ tk hide marked C-c C-o open externally
^^ ^^ ^^ U unmark all C-o open in new frame
^View ^ ^Edit^ ^Order^
^────────^────────────^──────^──────────────^─────────^───── w copy filename → M-0 w copy absolute filename T touch/set date
_c_ollapse mode _v_idir (C-x C-q) _s_ize ordered C copy/clone C-t d image-dired+ of marked files M chmod
_o_pen in file manager ^^ _h_uman size r rename/move <percent> l lowercase O chown
_O_pen in tmux _SPC_ filetags.el _1_ time ordered ! pipe to shell <percent> u uppercase S ln -s
_i_mage thumbnails ^^ _n_ormal ordered x delete flagged <percent> & flag temp files C-x C-f create file
_(_ toggle details ^^ ^^ c compress
^^ ^^ ^^ Z dired-do-compress (=unp)
^^ ^^ ^^
^^ ^^ ^^ attach to org: _3_ symlink _4_ ln _5_ cp _6_ mv
")
("t" my-dired-tagtrees nil)
("T" my-dired-tagtrees-recursive nil)
("f" my-dired-filetags-filter nil)
("F" my-dired-filetags-filter-recursive nil)
("d" my-dired-date2name nil)
("2" my-dired-time2name nil)
; ("D" filetags-dired-update-tags nil)
("D" date2name-dired-add-date-to-name nil)
("a" my-dired-copy-filename-as-absolute-link nil)
("m" my-dired-copy-filename-as-tsfile-link nil)
("A" (let ((current-prefix-arg '(4))) ;; emulate C-u
(call-interactively 'my-dired-copy-filename-as-absolute-link)
)
nil)
("c" dired-collapse-mode nil)
("o" my-dired-open-in-file-manager nil)
("O" my-dired-open-here-in-tmux-shell nil)
("i" my-dired-mark-images-and-thumbnail nil)
("(" dired-hide-details-mode nil)
("v" dired-toggle-read-only nil)
("SPC" filetags-dired-update-tags nil)
("s" (dired-sort-other "-alS --group-directories-first") nil)
("h" (dired-sort-other "-alSh --group-directories-first") nil)
("1" (dired-sort-other "-alt --group-directories-first") nil)
("n" (dired-sort-other "-al --group-directories-first") nil)
("3" (lambda ()
(interactive)
(let ((org-attach-method 'lns))
(call-interactively #'org-attach-dired-to-subtree)))
nil)
("4" (lambda ()
(interactive)
(let ((org-attach-method 'ln))
(call-interactively #'org-attach-dired-to-subtree)))
nil)
("5" (lambda ()
(interactive)
(let ((org-attach-method 'cp))
(call-interactively #'org-attach-dired-to-subtree)))
nil)
("6" (lambda ()
(interactive)
(let ((org-attach-method 'mv))
(call-interactively #'org-attach-dired-to-subtree)))
nil)
("q" nil "quit")
; ("s" (setq dired-listing-switches "-alS --block-size=\'1") nil)
; ("n" (setq dired-listing-switches "-al --block-size=\'1") nil)
)
(define-key dired-mode-map [f1] 'hydra-dired/body)hydra-pdftools → F1
- Example hydra: https://github.com/abo-abo/hydra/wiki/PDF-Tools
(defhydra hydra-pdftools (:color blue :hint nil)
(concat my-f-key-settings
"
╭───────────┐
Move History Scale/Fit │ PDF Tools │
╭──────────────────────────────────────────────────────────────────┴───────────╯
^^_g_^^ _B_ ^↧^ _+_ ^ ^ [_s_] search [_u_] revert buffer
^^^↑^^^ ^↑^ _H_ ^↑^ ↦ _W_ ↤ [_o_] outline [_i_] info
^^_p_^^ ^ ^ ^↥^ _0_ ^ ^ [_F_] link [_d_] dark mode
^^^↑^^^ ^↓^ ╭─^─^─┐ ^↓^ ╭─^ ^─┐ [_f_] search link
_h_ ←pag_e_→ _l_ _N_ │ _P_ │ _-_ _b_
^^^↓^^^ ^ ^ ╰─^─^─╯ ^ ^ ╰─^ ^─╯
^^_n_^^ ^ ^ _r_eset slice box
^^^↓^^^
^^_G_^^
Navigation Search Annotations
───────────────────────────────────────────────────────────────────────────^─────────^───────────────
↑ C-p BSPC p < M-< C-s search forward C-c C-a l list annotations (jump: SPC)
line view page page border document C-r search backward q close annotations list
↓ C-n SPC n > M-> f search in links C-c C-a h highlight (m)
F pick link and jump d mark for delete
M-g g goto page M-s o occur (jump via RET) x delete marked
u unmark
Display Margins AuxTeX
───────────────────────────────────────────────────────────────────────────────────────────────────
+/- Zoom s b trim margins C-c C-g jump to PDF spot
0 reset zoom s r reset margins C-mouse-1 jump to source in PDF
W/H/P fit width/height/page
o outline (jump via RET) g → reload file C-c C-p → print file
")
("\\" hydra-master/body "back")
("q" 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)
("m" pdf-annot-add-highlight-markup-annotation))
hydra-buffers → F2 + my-map ,
This hydra offers buffer management functionalty.
FIXXME: add more features:
- [ ] resize functions:
- [ ] go through cheatsheet
- https://github.com/abo-abo/hydra/wiki/Window-Management
- [ ] I’ve defined a swap function or so
(global-set-key (kbd “S-C-<left>”) ‘shrink-window-horizontally) weniger hoch - (global-set-key (kbd “S-C-<right>”) ‘enlarge-window-horizontally) höher = (global-set-key (kbd “S-C-<down>”) ‘shrink-window) (global-set-key (kbd “S-C-<up>”) ‘enlarge-window)
(“h” windmove-left) (“j” windmove-down) (“k” windmove-up) (“l” windmove-right)
(defhydra hydra-buffers (:color blue)
(concat my-f-key-settings
"
%s(eyebrowse-mode-line-indicator)
^^ _0_ switch to window config 0 C-S-; prefix
_,_ ← window _1_ switch to window config 1 prefix c create
_._ window → ... ^^ prefix , rename
^↦^ previous window config _9_ switch to window config 9 prefix l last window
_r_ename current window config
_c_reate new window config ^^ _b_ ibuffer-list-buffers
_C_lose current window config ^^
new _f_rame ^^
_!_ save-buffers-kill-terminal ^^ ▄
^^ ▄ C-x 2 split _v_ertical ▄ ^^ C-x 0 _d_elete this
_t_oggle ▄ ←→▐▐ ^^ ^^ C-x 1 _k_eep this, delete others
^^ ▄ C-x 3 split _h_orizontal ▐▐ ^^ _o_ther window
_s_plit/single ▄ ←→ ▇ s_w_ap ▇ ←→ ▇ ^^ _=_ enlarge window
^^ ^^ _-_ shrink window
────^^────────────────────────────────────────────────────────────
")
;; red = stay; blue = close
("," eyebrowse-prev-window-config nil :color red)
("." eyebrowse-next-window-config nil :color red)
("<tab>" eyebrowse-last-window-config nil :color red)
("r" eyebrowse-rename-window-config nil :color red)
("c" eyebrowse-create-window-config nil :color red)
("C" eyebrowse-close-window-config nil :color red)
("0" eyebrowse-switch-to-window-config-0 nil :color blue)
("1" eyebrowse-switch-to-window-config-1 nil :color blue)
("2" eyebrowse-switch-to-window-config-2 nil :color blue)
("3" eyebrowse-switch-to-window-config-3 nil :color blue)
("4" eyebrowse-switch-to-window-config-4 nil :color blue)
("5" eyebrowse-switch-to-window-config-5 nil :color blue)
("6" eyebrowse-switch-to-window-config-6 nil :color blue)
("7" eyebrowse-switch-to-window-config-7 nil :color blue)
("8" eyebrowse-switch-to-window-config-8 nil :color blue)
("9" eyebrowse-switch-to-window-config-9 nil :color blue)
("d" delete-window nil :color blue)
("k" delete-other-windows nil :color blue)
("v" my-vsplit-last-buffer nil :color blue)
("h" my-hsplit-last-buffer nil :color blue)
("o" other-window nil :color red)
("f" new-frame nil :color red)
("t" my-toggle-vertical-horizontal-split nil :color blue)
("s" my-toggle-split-and-single-window nil :color blue)
("w" window-swap-states nil)
("b" ibuffer-list-buffers nil)
;; ("-" shrink-window-horizontally nil :color red)
;; ("=" enlarge-window-horizontally nil :color red)
("-" shrink-window nil :color red)
("=" enlarge-window nil :color red)
("!" save-buffers-kill-terminal nil)
("q" nil "quit")
)
(define-key global-map [f2] 'hydra-buffers/body)
(define-key my-map (kbd "C-c C-,") 'hydra-buffers/body) ;; to get it on a more prominent binding (as well) because I use it quite often!hydra-emojis → Shift F4
2019-12-31: DISABLED for performance reasons: https://www.reddit.com/r/orgmode/comments/e9p84n/scaling_org_better_to_use_more_medsize_files_or/fcm5bsc/
(defhydra hydra-emojis (:color blue)
(concat my-f-key-settings
"
_i_nteractively inserting emojis
_a_propos emojis
────^^────────────────────────────────────────────────────────────
")
;; red = stay; blue = close
("i" emojify-insert-emoji nil :color blue)
("a" emojify-apropos-emoji nil :color blue)
("q" nil "quit")
)
(define-key global-map [(shift f4)] 'hydra-emojis/body)hydra-spelling → F5
Idea stolen from this reddit thread.
(defhydra hydra-spelling (:color red)
(concat my-f-key-settings
"
^
^Spelling^ ^Errors^ ^Checker^
^────────^──────────^──────^────────────^───────^───────
check _r_egion _n_ext error _m_ode
check _b_uffer _c_orrect toggle _l_anguage
_s_ynonym
_d_efine word
^^
")
("q" nil "quit")
("r" flyspell-region nil)
("l" my-toggle-ispell-language nil)
("n" flyspell-goto-next-error nil)
("s" my-synonym-current-word nil :color blue)
("d" define-word-at-point nil :color blue) ;; define-word
;; ("<" flyspell-correct-previous :color pink nil)
;; (">" flyspell-correct-next :color pink nil)
("c" flyspell-correct-word-before-point nil)
;; ("d" ispell-change-dictionary)
("b" flyspell-buffer nil)
("m" flyspell-mode nil))
(global-set-key [f5] 'hydra-spelling/body)hydra-markdown → F1
| 2020-04-19 | Disabled because I got (void-variable markdown-mode-map) and could not fix it now |
(defhydra hydra-markdown (:color blue)
(concat my-f-key-settings
"
^^─────────────────────^^──────────────────^^────────────────
_b_old _c_omment ^^
_i_talics ^^ ^^
^^ ^^ ^^
^^ ^^ ^^
")
("q" nil "quit")
("b" markdown-insert-bold nil)
("i" markdown-insert-italics nil)
("c" (lambda ()
(interactive)
(insert "[//]: # ()")) nil)
)
(define-key markdown-mode-map [f1] 'hydra-markdown/body)END of hydra
);; end of hydra
(with-eval-after-load 'pdf-view-mode
(define-key pdf-view-mode-map [f1] 'hydra-pdftools/body)
)
;; (define-key pdf-view-mode-map [f1] 'hydra-pdftools/body)
Key bindings
In this heading, I do define many key bindings.
Unset binding for C-x C-c (save-buffers-kill-terminal)
| 2020-12-18 | initial setup |
I sometimes confise the order of C-c C-x (prefix for various
commands) with C-x C-c which closes my Emacs session and all of its
buffers. So I decided to remove this mapping and quit emacs via M-x
save-buffers-kill-terminal or a hydra.
(global-set-key (kbd "C-x C-c") nil)my-map, the ressurection → C-c C-,
=C-c ,= is defined by Org-mode and must be re-defined here, after Org-mode has messed it up:
(There might be a better way but this is my current workaround.)
(global-set-key (kbd "C-c C-,") 'my-map)
(global-set-key (kbd "C-c ,") 'my-map)
;; so that following is possible again:
(bind-key "," #'hydra-buffers/body my-map)general navigation keys: Home, End, forward/backward word, scrolling
Home/End should behave like everywhere else:
(global-set-key [home] 'beginning-of-buffer)
(global-set-key [end] 'end-of-buffer)Move back/forward word is essential to me:
(global-set-key [C-left] 'backward-word)
(global-set-key [C-right] 'forward-word)2016-03-23: PageUp/Down (instead of line up/down) for keyboards without PgUp/Dn-keys:
(global-set-key (kbd "C-p") 'my-scroll-down-half)
(global-set-key (kbd "C-n") 'my-scroll-up-half)I tried some of those but they did not stick:
;; https://www.reddit.com/r/emacs/comments/445w6s/whats_some_small_thing_in_your_dotemacs_that_you/czntjs2
;;(global-set-key (kbd "C-, l") 'avy-goto-line)
;;(global-set-key (kbd "C-, w") 'avy-goto-word-0)
;;(global-set-key (kbd "C-, .") 'winner-redo)
;;(global-set-key (kbd "C-, m") 'winner-undo)
;;(global-set-key (kbd "C-, w") 'ace-window)
;;(global-set-key (kbd "C-, s") 'workspace-goto)
;;(global-set-key (kbd "C-, ]") 'evil-jump-to-tag)
;;(global-set-key (kbd "C-, n") 'neotree-toggle)C-f jumps 5 lines:
(global-set-key (kbd "C-f") '(lambda () (interactive) (forward-line 5)))boxquote → my-map [qQ]
| 2021-07-07 | Disabled because I wasn’t using it for over a decade |
Box quote does something like this:
,---- | This is an example. `----
(bind-key "q" #'boxquote-region my-map)
(bind-key "Q" #'boxquote-title my-map)switching lines → my-map <up/down>
http://whattheemacsd.com//editing-defuns.el-02.html
Swapping two lines:
(defun my-move-line-down ()
(interactive)
(let ((col (current-column)))
(save-excursion
(forward-line)
(transpose-lines 1))
(forward-line)
(move-to-column col)))
(defun my-move-line-up ()
(interactive)
(let ((col (current-column)))
(save-excursion
(forward-line)
(transpose-lines -1))
(move-to-column col)))
(bind-key (kbd "<up>") #'my-move-line-up my-map)
(bind-key (kbd "<down>") #'my-move-line-down my-map)joining lines → my-map j
Joining the current line with the next one: http://whattheemacsd.com//key-bindings.el-03.html
(bind-key "j"
(lambda ()
(interactive)
(join-line -1))
my-map
)web-jump → my-map w
«WebJump is a programmable Web hotlist (or bookmark) facility that uses Emacs completion to select a hotlist item and can prompt for query and option parameters.»
- http://www.neilvandyke.org/webjump/
- https://github.com/thefury/site-lisp/blob/master/dotemacs.el
- http://whattheemacsd.com//my-misc.el-01.html (Urban Dictionary)
(require 'webjump)
(bind-key "w" #'webjump my-map)
(setq webjump-sites ;(append ;; append instead of overwrite
'(
;; ------------------------------------------------------------------
("Emacs Lisp List" . "anc.ed.ac.uk/~stephen/emacs/ell.html")
("Ohio State Emacs Lisp Archive" .
[simple-query "www.cis.ohio-state.edu/emacs-lisp/"
"neutral.verbum.org/search?q=" "&archive=archive"])
("PGP Key Server" .
[simple-query "pgp.mit.edu"
"pgp.mit.edu:11371/pks/lookup?op=index&search=" ""])
;; my own jumps
("Org-mode docu" . "http://orgmode.org/org.html")
("Org-mode mailinglist" .
[simple-query "orgmode.org"
"http://search.gmane.org/?group=gmane.emacs.orgmode&query=" ""])
("Debian Bug Number" .
[simple-query "www.debian.org/Bugs/"
"bugs.debian.org/cgi-bin/bugreport.cgi?bug="
""])
("EmacsWiki" .
[simple-query "www.emacswiki.org/cgi-bin/wiki.pl"
"www.emacswiki.org/cgi-bin/wiki.pl?search="
"&dosearch=1"])
("Google" .
[simple-query "www.google.at" "www.google.at/search?q=" ""])
("IMDB" .
[simple-query "www.imdb.com" "www.imdb.com/Find?select=All&for=" ""])
;; ------------------------------------------------------------------
) webjump-sample-sites ;) ;; append instead of overwrite
)
Show recently files → my-map r
Show a dialog to open a recent file.
;;(bind-key "r" #'recentf-open-files my-map) ;; old mapping
(bind-key "r" #'helm-recentf my-map)Outlook: edit/save message → my-map oe|os
Some interaction with Outlook:
(when (my-eval-if-binary-or-warn "outlook")
(bind-key "oe" #'mno-edit-outlook-message my-map)
(bind-key "os" #'mno-save-outlook-message my-map)
)org-mark-ring-goto() → my-map <left>
Jump to the previous position in the mark ring.
(bind-key (kbd "<left>") #'org-mark-ring-goto my-map)open this config.org file → my-map .
Very handy to modify my config file: open it ;-)
(bind-key (kbd ".") (lambda() ;; open main.el
(interactive)
(find-file (concat my-user-emacs-directory "config.org"))
)
my-map
)open my org-mode teaser → my-map O
I’ve written an org-mode teaser file which can be found on https://github.com/novoid/org-mode-workshop
With this keyboard shortcut, I am able to quickly open the teaser file.
(bind-key (kbd "O") (lambda()
(interactive)
(when (my-system-type-is-gnu)
(find-file
"~/src/org-mode-workshop/featureshow/org-mode-teaser.org")
)
(when (string-equal system-name "GRZN17009")
(find-file
"c:/Users/karl.voit/src/org-mode-workshop/featureshow/org-mode-teaser.org")
)
(when (string-equal system-name "cosmo")
(find-file
"c:/Users/John/src/org-mode-workshop/featureshow/org-mode-teaser.org")
)
)
my-map
)
OrgStruct folding
Until 2017-05, I was using the Orgstruct minor mode for navigating
through my Emacs config file. With migrating my old main.el to this
config.org, the Orgstruct mode got obsolete for me.
Following commands offer a better usability for folding and unfolding in OrgStruct mode:
2015-11-10 deactivated:
(bind-key "[" (lambda () (interactive) (org-cycle t)) my-map)
(bind-key "]" (lambda () (interactive) (org-cycle)) my-map)my-fix-drawer-order() → my-map C
I once noticed broken PROPERTIES drawers because of a bug in the
Org-mode version I was using back then. Unfortunately, it messed up my
drawers unnoticed for some time. For fixing the most common stuff, I
created a macro and stored it here.
It searches for :END: followed by :PROPERTIES: (assuming first drawer
is :LOGBOOK: and toggles order of them:
(fset 'my-fix-drawer-order
(lambda (&optional arg) "Keyboard macro." (interactive "p") (kmacro-exec-ring-item (quote ([19 58 69 78 68 58 17 10 58 80 82 79 80 69 82 84 73 69 83 58 return 1 67108896 19 58 69 78 68 58 5 23 18 58 76 79 71 66 79 79 75 58 return 25 return down] 0 "%d")) arg)))
(bind-key "C" #'my-fix-drawer-order my-map)hippie-expand → M-/
«HippieExpand looks at the word before point and tries to expand it in various ways including expanding from a fixed list (like `‘expand-abbrev’’), expanding from matching text found in a buffer (like `‘dabbrev-expand’’) or expanding in ways defined by your own functions. Which of these it tries and in what order is controlled by a configurable list of functions.»
- issues when overriding undo-tree-undo (C-/): http://emacs.stackexchange.com/questions/2530/global-key-binding-overriden-by-undo-tree
- http://stackoverflow.com/questions/5332221/globally-overriding-emacs-keybindings
;(add-hook 'undo-tree-mode (lambda () (local-unset-key "C-/")))
;;failed;(global-set-key (kbd "C-c /") 'hippie-expand)
;; I could not make it work with C-/ - so I stick to M-/
(global-set-key (kbd "M-/") 'hippie-expand)my-fill-or-unfill → M-q
Function defined above.
(global-set-key (kbd "M-q") 'my-fill-or-unfill)mark word|line|sentence|sexp|defun → my-map mw|ml|ms|mx|md
With these commands, I get great shortcuts to put the current word, line, sentence, sexp or defun into the marked region:
(bind-key (kbd "mw") #'mark-word my-map)
(defun mark-line (&optional arg)
(interactive "p")
(beginning-of-line)
(let ((here (point)))
(dotimes (i arg)
(end-of-line))
(set-mark (point))
(goto-char here)))
(bind-key "m l" 'mark-line my-map)
(defun mark-sentence (&optional arg)
(interactive "P")
(backward-sentence)
(mark-end-of-sentence arg))
(bind-key "m s" #'mark-sentence my-map)
(bind-key "m x" #'mark-sexp my-map)
(bind-key "m d" #'mark-defun my-map)my-notmuch → my-map n
| 2021-02-13 | disabled since I can’t use business email with Emacs |
(when (my-system-type-is-gnu)
(bind-key "n" 'my-notmuch my-map)
)hydra-search
| 2020-04-13 | created to test if this binding position works |
Somehow, the binding from the definition of the hydra does not work.
(global-set-key [f9] 'hydra-search/body)literate test 2
;; nowebtest2
(setq nowebtest2 t)autostart
At the end of loading most of my configuration, I want to execute some things, some of them only in interactive mode.
Fast start of my Emacs: my GNU/Emacs starts within approximately 70
seconds as of 2019-04-17 on Windows. Large parts of the startup time
is spent doing the tasks defined in this section. If I don’t need
stuff like agenda or my startup visibility, I create an empty file
~/.emacs.d/var/faststart and the following code omits some
time-intensive parts of the autostart activity. This brings me down to
approximately 25 seconds as of 2019-04-17.
(message "→★ finished loading config.org (w/o autostart) in %.2fs" (float-time (time-subtract (current-time) my-config-el-start-time)))
(setq faststart-indicator-file (concat no-littering-var-directory "faststart"))
(setq recache-indicator-file (concat no-littering-var-directory "recache"))
;; omit some things when running in batch-mode:
(when (not noninteractive)
;; when interactive:
(global-set-key (kbd "M-x") 'counsel-M-x) ;; id:2017-03-02-cool-command-completion
(my-log-misc "interactive Emacs is started")
(when (or (my-system-is-rise) (my-system-is-sting))
(my-hsplit-last-buffer)
)
;(sleep-for 2)
(setq my-org-agenda-tags-column (- (- (window-total-width) 3)))
(message (concat "Setting agenda tags column to " (number-to-string my-org-agenda-tags-column)))
(setq org-agenda-tags-column my-org-agenda-tags-column) ;; total width minus 3
(if (file-exists-p faststart-indicator-file)
(progn
(my-log-misc "Faststart activated → omitting some autostart things")
(message "Faststart activated → omitting some autostart things") ;; see explanation above
)
(progn
(message "Creating agenda …")
;;(my-log-misc "Creating agenda …")
(my-org-agenda)
(message "my-org-startup-visibility …")
(my-org-startup-visibility)
;; setup my buffers the way I like it:
(my-hsplit-last-buffer) ;; split horizontal: left is agenda
(my-mobile-org-import) ;; switch to inbox.org (right side) and move latest input from mobileorg.org into inbox.org
(eyebrowse-create-window-config) ;; create 2nd config for misc personal stuff
(switch-to-buffer "notes.org") ;; open notes buffer
;; MAYBE: open misc.org on the other side
(eyebrowse-rename-window-config 2 "misc") ;; name 2nd config
(eyebrowse-create-window-config) ;; create 3rd config for rise
(switch-to-buffer "rise.org") ;; open rise buffer
(org-shifttab) ;; toggle visibility
(eyebrowse-rename-window-config 3 "rise") ;; set name for rise config
(other-window 1) ;; switch from rise.org to agenda on the left side → DOESN'T work yet because there is no agenda on the left for some reason
(when (my-system-is-rise)
(eyebrowse-create-window-config) ;; create 4th config for rise/dired
(eyebrowse-rename-window-config 4 "rise-dired") ;; set name for config
(other-window 1) ;; switch from on the left side → may not work yet (test!)
(dired my-business-dired-folder);; open dired buffer with business config
(eyebrowse-switch-to-window-config-3);; switch back to "rise"
)
)
)
(my-log-misc "end of autostart")
)Note: Removing faststart-indicator-file or running my-recache-all
is done later-on. This is to make sure that Emacs bootup statistics stay
comparable.
custom variables
This somehow got written by Emacs. Honestly, I am not sure whether or not I should keep this here. Well, it does not hurt either.
(custom-set-variables
;; custom-set-variables was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
'(org-contacts-address-property "CITY")
'(org-contacts-birthday-property "BORN")
'(org-contacts-icon-property "PHOTOGRAPH")
'(safe-local-variable-values
(quote
((eval ispell-change-dictionary "german8")
(eval ispell-change-dictionary "american")
(eval ispell-change-dictionary "en_US")
(flyspell-default-dictionary . "german8")))))
;; Somehow, this variable got overwritten by something from the
;; email config section to here to 'message-send-mail-with-outlook
;; and therefore it's been set here as well:
(setq message-send-mail-function 'message-smtpmail-send-it)Closing and end for profiling
This is the end of the Elisp blocks to be tangled. Finishing up loading my configuration (famous last words):
;; ignoring recache process below in emacs startup time:
(setq my-config-el-loading-time (float-time (time-subtract (current-time) my-config-el-start-time)))
(when (not noninteractive)
;; when interactive:
(my-log-misc
(format-message "interactive Emacs boot finished (took %.2fs)" (float-time (time-subtract (current-time) my-config-el-start-time)))
)
;;(my-log-misc
;; (format-message "batch Emacs boot finished (took %.2fs)" (float-time (time-subtract (current-time) my-config-el-start-time)))
;;)
)
(if (file-exists-p faststart-indicator-file)
(progn
(delete-file faststart-indicator-file)
)
(progn
(when (and (file-exists-p recache-indicator-file) (not noninteractive))
(my-recache-all)
;;(delete-file recache-indicator-file) ;; don't delete, since some computers may use this for every startup
)
)
)
(my-flash (format-message "Not found here:\n%s" my-binary-not-found-list))
(my-flash (format-message "Emacs boot finished\n(took %.2fs)" my-config-el-loading-time))
(message "»»» Binaries not found in checks above: %s" my-binary-not-found-list)
;;(my-log-hostspecific (format "Binaries not found at startup checks: %s" my-binary-not-found-list))
(message "→★ finished loading config.org in %.2fs" my-config-el-loading-time)Current key mappings (sorted)
Here are some blocks that try to extract keyboard bindings from the configuration file here.
Mappings not using my-map (non-sorted output)
| key | function |
|---|---|
| [M-l] | downcase-word |
| [M-u] | upcase-word |
| [M-c] | capitalize-word |
| [remap fill-paragraph] | |
| emacs-lisp-mode C-c e | macrostep-expand |
| M-h | hs-cycle |
| M-H | hs-cycle-all |
| M-h | hs-cycle |
| M-H | hs-cycle-all |
| python-mode C-c i | elpygen-implement |
| dired-mode ~,~ | dired |
\C-cl | org-store-link |
\C-ca | org-agenda |
| C-c % | org-mark-ring-push |
| C-c <left> | org-mark-ring-goto |
| C-c <down> | org-mark-ring-push |
global \C-cc | org-capture |
\C-cm | my-memacs-org-agenda |
| org-mode C-c ) | reftex-citation |
| org-mode C-c ( | org-mode-reftex-search |
| [f8] | minimap-mode |
| C-s-SPC | mode-line-in-header |
| [f12] | my-toggle-naked-emacs |
| [f4] | char-menu |
| [f2] | goto-last-change |
| [f3] | goto-last-change-reverse |
| C-c h | hydra-apropos/body |
| C-x r h | hydra-rectangle/body |
| [f5] | hydra-spelling/body |
\C-s | my-search-method-according-to-numlines |
| global [tool-bar pdf-button] | |
| [f1] | my-toggle-beginner-setup |
| [(shift f1)] | my-toggle-dark-bright-theme |
| M-i (lambda () (interactive) (my-codenav-prev-definition | |
| M-k (lambda () (interactive) (my-codenav-next-definition | |
| [home] | beginning-of-buffer |
| [end] | end-of-buffer |
| [C-left] | backward-word |
| [C-right] | forward-word |
| C-p | scroll-down-command |
| C-n | scroll-up-command |
| C-f | (lambda () (interactive) (forward-line 5 |
| M-/ | hippie-expand |
| M-q | my-fill-or-unfill |
| M-x | counsel-M-x) ;; id:2017-03-02-cool-command-completion |
| [M-l] | ~downcase-word) ~ |
| [M-u] | ~upcase-word) ~ |
| [M-c] | ~capitalize-word) ~ |
| [remap fill-paragraph] | |
| global [(f5)] | ~flyspell-mode) ~ |
| global [(shift f5)] | ~my-toggle-ispell-language) ~ |
| global [(f6)] | ~flyspell-goto-next-error) ~ |
| global [(f7)] | ~flyspell-correct-word-before-point) ~ |
| org-mode RET | |
\C-cl | ~org-store-link) ~ |
\C-ca | ~org-agenda) ~ |
| C-c % | ~org-mark-ring-push) ~ |
| C-c <left> | ~org-mark-ring-goto) ~ |
| C-c <down> | ~org-mark-ring-push) ~ |
global \C-cc | ~org-capture) ~ |
\C-cm | ~my-memacs-org-agenda) ~ |
| org-mode C-c ) | ~reftex-citation) ~ |
| org-mode C-c ( | ~org-mode-reftex-search)) ~ |
| [f8] | ~minimap-mode) ~ |
| C-s-SPC | ~mode-line-in-header) ~ |
| [f12] | ~my-toggle-naked-emacs) ~ |
| M-x | ~counsel-M-x) ;; id:2017-03-02-cool-command-completion ~ |
| [f4] | ~char-menu) ~ |
| [f2] | ~goto-last-change) ~ |
| [f3] | ~goto-last-change-reverse) ~ |
| [f1] | ~neotree-toggle) ~ |
\C-s | ~my-search-method-according-to-numlines) ~ |
| global [tool-bar pdf-button] | |
| [f1] | ~my-toggle-beginner-setup) ~ |
| [(shift f1)] | ~my-toggle-dark-bright-theme) ~ |
| [home] | ~beginning-of-buffer) ~ |
| [end] | ~end-of-buffer) ~ |
| [C-left] | ~backward-word) ~ |
| [C-right] | ~forward-word) ~ |
| C-p | ~scroll-down-command) ~ |
| C-n | ~scroll-up-command) ~ |
| C-f | ~(lambda () (interactive) (forward-line 5))) ~ |
| M-/ | ~hippie-expand) ~ |
Mappings not using my-map (sorted output)
| key | function |
|---|---|
\C-ca | org-agenda |
\C-ca | ~org-agenda) ~ |
| C-c <down> | org-mark-ring-push |
| C-c <down> | ~org-mark-ring-push) ~ |
| C-c h | hydra-apropos/body |
| C-c <left> | org-mark-ring-goto |
| C-c <left> | ~org-mark-ring-goto) ~ |
\C-cl | org-store-link |
\C-cl | ~org-store-link) ~ |
\C-cm | my-memacs-org-agenda |
\C-cm | ~my-memacs-org-agenda) ~ |
| C-c % | org-mark-ring-push |
| C-c % | ~org-mark-ring-push) ~ |
| C-f | (lambda () (interactive) (forward-line 5 |
| C-f | ~(lambda () (interactive) (forward-line 5))) ~ |
| [C-left] | backward-word |
| [C-left] | ~backward-word) ~ |
| C-n | scroll-up-command |
| C-n | ~scroll-up-command) ~ |
| C-p | scroll-down-command |
| C-p | ~scroll-down-command) ~ |
| [C-right] | forward-word |
| [C-right] | ~forward-word) ~ |
\C-s | my-search-method-according-to-numlines |
\C-s | ~my-search-method-according-to-numlines) ~ |
| C-s-SPC | mode-line-in-header |
| C-s-SPC | ~mode-line-in-header) ~ |
| C-x C-b | ibuffer |
| C-x r h | hydra-rectangle/body |
| C-z | my-dired-recent-dirs |
| dired-mode <backspace> | diredp-up-directory-reuse-dir-buffer |
| dired-mode C-c C-o | my-dired-open-in-external-app |
| dired-mode C-s | dired-isearch-filenames |
| dired-mode ~,~ | dired |
| dired-mode [f1] | hydra-dired/body |
| dired-mode M-a | my-dired-appendfilename |
| dired-mode M-c | dired-ranger-copy) ;; overwrites: diredp-capitalize-this-file |
| dired-mode M-m | dired-ranger-move) ;; overwrites: back-to-indentation |
| dired-mode M-t | my-dired-filetags |
| dired-mode M-v | dired-ranger-paste) ;; overwrites: scroll-down-command |
| emacs-lisp-mode C-c e | macrostep-expand |
| [end] | end-of-buffer |
| [end] | ~end-of-buffer) ~ |
| [f12] | my-toggle-naked-emacs |
| [f12] | ~my-toggle-naked-emacs) ~ |
| [f1] | my-toggle-beginner-setup |
| [f1] | ~my-toggle-beginner-setup) ~ |
| [f2] | goto-last-change |
| [f2] | ~goto-last-change) ~ |
| [f3] | goto-last-change-reverse |
| [f3] | ~goto-last-change-reverse) ~ |
| [f4] | char-menu |
| [f4] | ~char-menu) ~ |
| [f5] | hydra-spelling/body |
| [f8] | minimap-mode |
| [f8] | ~minimap-mode) ~ |
| [f1] | ~neotree-toggle) ~ |
global \C-cc | org-capture |
global \C-cc | ~org-capture) ~ |
| global [(f5)] | ~flyspell-mode) ~ |
| global [(f6)] | ~flyspell-goto-next-error) ~ |
| global [(f7)] | ~flyspell-correct-word-before-point) ~ |
| global [(shift f5)] | ~my-toggle-ispell-language) ~ |
| global [tool-bar pdf-button] | |
| global [tool-bar pdf-button] | |
| [home] | beginning-of-buffer |
| [home] | ~beginning-of-buffer) ~ |
image-dired-thumbnail-mode \C-n | image-diredx-next-line |
image-dired-thumbnail-mode \C-p | image-diredx-previous-line |
image-dired-thumbnail-mode g | revert-buffer);; revert all thumbnails if `image-diredx-async-mode' is on |
image-dired-thumbnail-mode x | image-diredx-flagged-delete);; Delete confirmation prompt with thumbnails |
| [M-c] | capitalize-word |
| [M-c] | ~capitalize-word) ~ |
| M-h | hs-cycle |
| M-H | hs-cycle-all |
| M-/ | hippie-expand |
| M-/ | ~hippie-expand) ~ |
| M-i (lambda () (interactive) (my-codenav-prev-definition | |
| M-k (lambda () (interactive) (my-codenav-next-definition | |
| [M-l] | downcase-word |
| [M-l] | ~downcase-word) ~ |
| M-q | my-fill-or-unfill |
| [M-u] | upcase-word |
| [M-u] | ~upcase-word) ~ |
| M-x | counsel-M-x) ;; id:2017-03-02-cool-command-completion |
| M-x | ~counsel-M-x) ;; id:2017-03-02-cool-command-completion ~ |
| org-mode C-c ( | org-mode-reftex-search |
| org-mode C-c ( | ~org-mode-reftex-search)) ~ |
| org-mode C-c ) | reftex-citation |
| org-mode C-c ) | ~reftex-citation) ~ |
| org-mode RET | |
| python-mode C-c i | elpygen-implement |
| python-mode [f1] | hydra-python/body |
| [remap fill-paragraph] | |
| [remap fill-paragraph] | |
| [(shift f1)] | my-toggle-dark-bright-theme |
| [(shift f1)] | ~my-toggle-dark-bright-theme) ~ |
Mapping from my-map outside of use-package
- [ ] fix script
| \texttt{C-c ,} | function | comment |
|---|
config.el: (define-key my-map P | pylookup-lookup | |
main_before_moving_to_config.org.el: (define-key my-map P | pylookup-lookup | |
main_sting_before_configorg.el: (define-key my-map P | pylookup-lookup | |
main_sting_before_configorg_ORIG.el: (define-key my-map P | pylookup-lookup |
Mapping from my-map within use-package
| \texttt{C-c ,} | function | comment |
|---|---|---|
| 0 | bm-next | |
| 8 | bm-toggle | |
| 9 | bm-previous | |
| RET | eno-word-goto | |
| S | my-synonym-current-word | |
| SPC | yankpad-insert | |
| c | smeargle | |
| h | highlight-symbol | |
| s | spray-mode |
Mapping of F-keys
id:2017-05-22-f-key-mapping
New mapping for F-keys: id:2017-05-26-new-F-key-bindings
| Key | New binding |
|---|---|
| <f1> | my-toggle-beginner-setup |
| Shift-<f1> | my-toggle-dark-bright-theme |
| <f2> | goto-last-change |
| <f3> | goto-last-change-reverse |
| <f4> | char-menu |
| <f5> | flyspell hydra |
| <f6> | flyspell-goto-next-error |
| <f7> | flyspell-correct-word-before-point |
| <f8> | |
| <f9> | python hydra |
| <f10> | menu-bar-open |
| <f11> | toggle-frame-fullscreen |
| <f12> | my-toggle-naked-emacs |
Local Variables
;; Local Variables: ;; eval: (make-local-variable ‘org-insert-heading-hook) ;; eval: (remove-hook ‘org-insert-heading-hook ‘org-expiry-insert-created t) ;; eval: (make-local-variable ‘org-after-todo-state-change-hook) ;; eval: (remove-hook ‘org-after-todo-state-change-hook ‘org-expiry-insert-created t) ;; eval: (make-local-variable ‘org-after-tags-change-hook) ;; eval: (remove-hook ‘org-after-tags-change-hook ‘org-expiry-insert-created t) ;; End: