My Emacs Config

This is my Emacs config for home and work. Feel free to borrow, copy and hack … I did it myself from different sources!


To get this initialization to work place this snippet in init.el.

(require 'org)
  (expand-file-name ""

Add this to your init.el to get some nice colors and fonts.

  '(default ((t (:inherit nil :stipple nil :background "seashell" :foreground "SystemWindowText" :inverse-video nil :box nil :strike-through nil :overline nil :underline nil :slant normal :weight normal :height 120 :width normal :foundry "outline" :family "Consolas"))))
  '(org-level-1 ((t (:inherit outline-1 :height 1.1))))
  '(region ((t (:background "#ddffdd")))))


What system are we running on?

At work I use Windows and at home GNU/Linux.

(defvar my/work (eq system-type 'windows-nt))
(defvar my/home (eq system-type 'gnu/linux))


(setq inhibit-startup-screen t)
(setq inhibit-startup-echo-area-message t)
(setq inhibit-startup-message t)   
(tool-bar-mode 0)
(tooltip-mode  0)
(scroll-bar-mode 0)
(defalias 'yes-or-no-p 'y-or-n-p)
(global-visual-line-mode 1)

Get backups out of the way and remove littering in auto-save-list

(setq auto-save-list-file-prefix nil)

(if my/work
    (setq temporary-file-directory "C:/Users/khajvaz/AppData/Local/Temp"))

(setq backup-directory-alist
      `((".*" . ,temporary-file-directory)))
(setq auto-save-file-name-transforms
      `((".*" ,temporary-file-directory t)))


Open important files

(global-set-key (kbd "<f1>") (lambda() (interactive)(find-file "~/org/")))
(global-set-key (kbd "<f2>") (lambda() (interactive)(find-file "~/org/")))
(global-set-key (kbd "<f3>") (lambda() (interactive)(find-file "~/org/")))

Bind functions

Text Zoom

(global-set-key (kbd "C-c C-+") 'text-scale-increase)
(global-set-key (kbd "C-c C--") 'text-scale-decrease)
(global-set-key (kbd "C-c C-0") (lambda () (interactive)(text-scale-adjust 0)))

Revert Buffer, if not changed.

Interactive call to revert-buffer. Ignoring the auto-save file and not requesting for confirmation. When the current buffer is modified, the command refuses to revert it, unless you specify the optional argument: force-reverting to true.

 (kbd "<f5>")
 (lambda (&optional force-reverting)
   (interactive "P")
   ;;(message "force-reverting value is %s" force-reverting)
   (if (or force-reverting (not (buffer-modified-p)))
       (revert-buffer :ignore-auto :noconfirm)
     (error "The buffer has been modified."))))


Setup repos

Debian Buster needs this variable to work.

(if my/home
    (setq gnutls-algorithm-priority "NORMAL:-VERS-TLS1.3"))

Now let's setup repos.

(require 'package)
(add-to-list 'package-archives
	     '("melpa" . ""))


Install Use-Package, then use it for other packages.

(unless (package-installed-p 'use-package)
  (package-install 'use-package))
      (require 'use-package))


Install Quelpa and Quelpa-Use-Package.

(use-package quelpa
  :ensure t
  (setq quelpa-checkout-melpa-p nil))
   :fetcher git
   :url ""))
(require 'quelpa-use-package)


(global-set-key (kbd "<f12>") 'flyspell-buffer)
(global-set-key (kbd "<f11>") 'fd-switch-dictionary)

(setq ispell-curent-dictionary "deutsch")
(setq ispell-local-dictionary "deutsch")

(if my/work
    (setq ispell-program-name "~/tools/hunspell/bin/hunspell.exe"))

(defun fd-switch-dictionary()
      (let* ((dic ispell-current-dictionary)
	 (change (if (string= dic "deutsch") "english" "deutsch")))
	(ispell-change-dictionary change)
	(message "Dictionary switched from %s to %s" dic change)))

Org Mode


(setq org-startup-indented t)
(setq org-hide-emphasis-markers t)
(setq org-startup-folded t)
(setq org-log-into-drawer t)
(setq org-todo-keywords
      '((sequence "TODO(t)" "INPROGRESS(i@/!)" "WAIT(w@/!)" "|" "DONE(d@)" "CANCELED(c@)")))


Classic linking

(require 'org-id)
(setq org-id-link-to-org-use-id 'create-if-interactive-and-no-custom-id)
(define-key global-map "\C-cl" 'org-store-link)


(use-package org-super-links
  :quelpa (org-super-links :repo "toshism/org-super-links" :fetcher github :commit "develop")
  (("C-c s s" . org-super-links-link)
   ("C-c s l" . org-super-links-store-link)
   ("C-c s C-l" . org-super-links-insert-link))
  (setq org-super-links-related-into-drawer t))


Basic templates.

(define-key global-map (kbd "C-c c") 'org-capture)
(setq org-capture-templates
      '(("t" "Todo" entry (file "~/org/")
	 "* TODO %?\nSCHEDULED: %t\n")
	("n" "Note" entry (file "~/org/")
	 "* %U %?\n\n")

At work I also need a meeting template.

(if my/work
    (add-to-list 'org-capture-templates '("m" "Meeting" entry (file "~/org/")
				      "* %U %?\n\n** Teilnehmer: \n- ?\n\n** Agenda Punkt 1\n- ?\n\n** Aufgaben:\n*** TODO ")))


Basic stuff

(define-key global-map "\C-ca" 'org-agenda)
(setq org-agenda-window-setup (quote current-window))
(setq org-agenda-files (list "~/org/" "~/org/"))
(setq org-agenda-start-day nil)
(setq org-agenda-span 7)
(setq org-agenda-start-on-weekday nil)
(setq org-agenda-skip-deadline-prewarning-if-scheduled t)
(setq org-agenda-todo-ignore-deadlines (quote all))
(setq org-agenda-todo-ignore-scheduled (quote all))
(setq org-agenda-skip-scheduled-if-done t)
(setq org-agenda-skip-deadline-if-done t)

Custom agenda views

Priority-based agenda taken from Use Eisenhower for priority:

  • A = Urgent AND Important (DO NOW)
  • B = NOT Urgent and Important (DO)
  • C = Urgent and NOT Important (DELEGATE)
  • D = NOT Urgent AND NOT Important (DON'T DO)

At work I also need some custom tagging and views.

(setq org-highest-priority ?A)
(setq org-lowerst-priority ?C) 
(setq org-default-priority ?C)
(defun air-org-skip-subtree-if-priority (priority)
  (let ((subtree-end (save-excursion (org-end-of-subtree t)))
	(pri-value (* 1000 (- org-lowest-priority priority)))
	(pri-current (org-get-priority (thing-at-point 'line t))))
    (if (<= pri-value pri-current)
(setq org-agenda-custom-commands
	("k" "Agenda for KEMAL"
	 ((tags "PRIORITY<=\"B\"" 
		((org-agenda-skip-function '(org-agenda-skip-entry-if 'todo 'done))
		 (org-agenda-overriding-header "High Priority Tasks:")))
	  (agenda "")
	  (alltodo ""
		     '(or (air-org-skip-subtree-if-priority ?B)
			  (org-agenda-skip-if nil '(scheduled deadline))))))))
	("t" "Speak with the TEAM"
	 ((tags "team"
		((org-agenda-skip-function '(org-agenda-skip-entry-if 'todo 'done))
		 (org-agenda-overriding-header "Let's talk about:")))))
	("b" "Speak with the BOSS"
	 ((tags "boss"
		((org-agenda-skip-function '(org-agenda-skip-entry-if 'todo 'done))
		 (org-agenda-overriding-header "Let's talk about:")))))))


(setq org-refile-targets
      '((org-agenda-files :maxlevel . 1)))
(setq org-refile-use-outline-path 'file)
(setq org-outline-path-complete-in-steps nil)


To use this make a screenshot with a tool that saves the picture to the clipboard. We then grab this photo, save it and insert a link to this file. For GNU/Linux I use org-download package to get this done. For Windows 10 I use a custom function from, because org-download doesn't work.

(if my/home
    (define-key global-map "\C-ci" 'org-download-clipboard)
  (define-key global-map "\C-ci" 'my-org-insert-screenshot))

(when my/home
  (use-package org-download
  :ensure t
  (setq org-download-method 'attach)))

(defun my-org-insert-screenshot ()
  (setq filename
	  (concat "data/imgs/" (format-time-string "%Y%m%d_%H%M%S_")) ) ".png"))
  (unless (file-exists-p (file-name-directory filename))
    (make-directory (file-name-directory filename)))
  (shell-command (concat "powershell -command \"Add-Type -AssemblyName System.Windows.Forms;if ($([System.Windows.Forms.Clipboard]::ContainsImage())) {$image = [System.Windows.Forms.Clipboard]::GetImage();[System.Drawing.Bitmap]$image.Save('" filename "',[System.Drawing.Imaging.ImageFormat]::Png); Write-Output 'clipboard content saved as file'} else {Write-Output 'clipboard does not contain image data'}\""))
  (if (file-exists-p filename)
      (insert (concat "[[file:" filename "]]"))))


(use-package helm
  :ensure t
  (("M-x" . 'helm-M-x)
   ("C-x C-f" . 'helm-find-files)
   ("C-s" . 'helm-occur)
   ("C-x C-b" . 'helm-buffers-list)
   ("M-y" . 'helm-show-kill-ring)
   ("C-x C-p" . 'helm-list-elisp-packages)
   ([tab] . 'helm-execute-persistent-action))
  (setq helm-mode 1)
  (setq helm-autoresize-mode 0)
  (setq helm-split-window-in-side-p 1)
  (setq helm-move-to-line-cycle-in-source 1))

Which Key

(use-package which-key
  :ensure t


Get needed packages.

(require 'ox-html)
(require 'ox-publish)
(use-package webfeeder
  :ensure t)

Helper stuff

Some stuff from to clear up HTML.

(setq org-html-home/up-format "")
(setq org-html-link-up "")
(setq org-html-link-home "")
(setq org-html-scripts "")

Add a post template to Org Capture.

(add-to-list 'org-capture-templates
	     '("p" "Post" plain (file create-blog-post)
	       (file "~/Nextcloud/Documents/blog/src/posts/")))
(defun create-blog-post ()
	"Create an org file in ~/source/myblog/posts."
	(let ((name (read-string "Filename: ")))
	  (expand-file-name (format "" name) "~/Nextcloud/Documents/blog/src/posts/")))

Get stuff for the sitemap, generate RSS, publish.

(defun my-sitemap-format-entry (entry style project)
  (format "%s - [[file:%s][%s]] (%s)"
	  (format-time-string "%Y-%m-%d" (org-publish-find-date entry project))
	  (org-publish-find-title entry project)
	   (expand-file-name entry (plist-get (cdr project) :base-directory)))))

(defun org-find-category (file)
    (message file)
    (insert-file-contents file)
    (goto-char (point-min))
    (let ((beg (+ 1 (re-search-forward "^#\\+CATEGORY\:")))
	  (end (progn (forward-word) (point))))
      (buffer-substring beg end))))

(defun rss-gen()
   (delete '"index.html" (directory-files "~/Nextcloud/Documents/blog/pages/" nil
   :title "anonimno's blog"
   :description "My blog in RSS"
   :builder 'webfeeder-make-rss))

(defun my-blog-publish()
    ;;(let ((msg (read-string "Commit msg: "))))
    (let ((msg (read-string "Commit msg: ")))
      (shell-command (format "%s %s" "~/Nextcloud/Documents/blog/pages/" msg)))

Project setup.

(setq org-publish-project-alist
	 :base-directory "~/Nextcloud/Documents/blog/src/posts/"
	 :base-extension "org"
	 :publishing-directory "~/Nextcloud/Documents/blog/pages/"
	 :publishing-function org-html-publish-to-html
	 :recursive t
	 :exclude "level-.*\\|.*\.draft\.org"
	 :section-numbers nil
	 :with-toc nil
	 :with-sub-superscript nil
	 :with-author nil
	 :with-date t
	 :with-drawers t
	 :auto-sitemap t
	 :sitemap-filename ""
	 :sitemap-title "anonimno's blog"
	 :sitemap-sort-files anti-chronologically
	 :sitemap-style list
	 :sitemap-format-entry my-sitemap-format-entry
	 :html-head-include-default-style nil
	 :html-head "<link rel=\"stylesheet\" type=\"text/css\" href=\"/assets/site.css\" />"
	 :html-preamble "<a href=\"/about.html\"> <img alt=\"anonimno\" class=\"avatar--circle\" src=\"/assets/avatar.png\" width=\"100\" height=\"100\"></a> <p class=\"pubdate\" style=\"visibility:hidden;\"> %d </p>"
	 :html-postamble "<p><span style=\"float: left;\"><a href= \"/rss.xml\">RSS</a></span> <span style=\"float: right;\"><a href= \"/index.html\">Home</a></span></p> <br> <p><span class=\"date\" style=\"float: left;\">Updated: %C</span> <span class=\"licence\" style=\"float: right;\">License: <a href= \"\">CC BY-SA 4.0</a></span></p>")

	 :base-directory "~/Nextcloud/Documents/blog/src/assets/"
	 :base-extension "css\\|js\\|png\\|jpg\\|gif\\|pdf\\|mp3\\|ogg\\|swf"
	 :publishing-directory "~/Nextcloud/Documents/blog/pages/assets/"
	 :recursive t
	 :publishing-function org-publish-attachment)

	("all" :components ("blog" "assets"))))

RSS Home

Updated: 2021-07-28 Wed 18:56 License: CC BY-SA 4.0