Skip to content

Latest commit

 

History

History
2449 lines (2012 loc) · 80.9 KB

config.org

File metadata and controls

2449 lines (2012 loc) · 80.9 KB

Emacs Configuration

Personal Information

(setq user-full-name "Dimitar Petrov"
      user-mail-address "[email protected]")

Initialize MELPA

(when (>= emacs-major-version 24)
  (setq-default
   load-prefer-newer t
   package-enable-at-startup nil)
  (package-initialize)
  (add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/") t)
  (add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/") t)
  (add-to-list 'package-archives '("elpy" . "https://jorgenschaefer.github.io/packages/") t)
  (unless (package-installed-p 'delight)
    (package-refresh-contents)
    (package-install 'delight))
  (unless (package-installed-p 'use-package)
    (package-refresh-contents)
    (package-install 'use-package)))

;; Add plugins directory to load-path
(add-to-list 'load-path "~/.emacs.d/plugins/")

Define Personal Functions

Tone Down Fringes

;; Function
(defun my-tone-down-fringes ()
  "Changes the leader background to be the same as THEME background color."
  (set-face-attribute 'fringe nil
                      :foreground (face-foreground 'default)
                      :background (face-background 'default)))

Themes

Use fancy lambdas

(global-prettify-symbols-mode t)

Cyberpunk theme

The cyberpunk theme is dark and colorful. The code bellow removes the boxes around the mode line

(use-package cyberpunk-theme
  :if (window-system)
  :ensure t
  :init
  (progn
    (set-face-attribute `mode-line nil
                        :box nil)
    (set-face-attribute `mode-line-inactive nil
                        :box nil)))

Solarized theme

Here’s some configuration for bbatsov’s solarized themes.

(use-package solarized-theme
  :defer 10
  :init
  (setq solarized-use-variable-pith nil)
  :ensure t)

Monokai theme

(use-package monokai-theme
  :ensure t
  :init
  (setq monokai-use-variable-pitch nil))

Waher theme

(use-package waher-theme
  :if (window-system)
  :ensure t
  :init)

Zenburn theme

(use-package zenburn-theme
  :ensure t
  :init)

Spacemacs theme

(use-package spacemacs-theme
     :ensure t
     :defer t
     )

Convenient theme functions

    (defun switch-theme (theme)
      "Disables any currently active themes and loads THEME."
      ;; This interactive call is taken from `load-theme'
      (interactive
       (list
        (intern (completing-read "Load custom theme: "
                                 (mapc 'symbol-name
                                       (custom-available-themes))))))
      (let ((enabled-themes custom-enabled-themes))
        (mapc #'disable-theme custom-enabled-themes)
        (load-theme theme t))
      (my-tone-down-fringes)
)

    (defun disable-active-themes ()
      "Disables any currently active themes listed in `custom-enabled-themes'."
      (interactive)
      (mapc #'disable-theme custom-enabled-themes))

    (bind-key "S-<f12>" 'switch-theme)
    (bind-key "S-<f11>" 'disable-active-themes)

Load theme - wheatgrass

(load-theme 'zenburn t)
(switch-theme 'wheatgrass)

Font

Source Code Pro is a nice mono-spaced font. Here is how we tell Emacs to use the font we want to use.

(add-to-list 'default-frame-alist
             '(font . "Source Code Pro-10"))

Evil Mode

Load evil package and enable evil-mode

In order to define and use a <leader> prefix for your personal shortcuts you have to install the package evil-leader. In order to work on all buffers (messages*/*scratch), evil-leader has to be loaded before evil. Evil-leader issue in generic buffers

 ;; fix TAB issue in text-mode
   (setq evil-want-C-i-jump nil)

;; initialize evil
   (use-package evil
     :ensure t
     :config
     (use-package evil-leader
       :ensure t
       :config
       (global-evil-leader-mode 1)
       (evil-leader/set-leader ",")
       (setq evil-leader/in-all-states 1)
       (evil-leader/set-key "b" 'helm-mini
         "e" 'helm-find-files
         "K" 'kill-buffer
         "y" 'helm-show-kill-ring
         "j" 'avy-goto-word-1
         "l" 'avy-goto-line
         "u" 'undo-tree-visualize
         "s" 'helm-swoop
         "n" 'company-yasnippet
         "k" 'evil-window-next
         "j" 'evil-window-prev
         "f" 'evil-prev-buffer
         "d" 'evil-next-buffer
         "g" 'org-agenda-filter-by-tag
         "r" 'org-refile
         "B" 'org-agenda-bulk-action))
     (evil-mode))

;;   (use-package evil-args
;;     :ensure t
;;     :config
;;     ;; bind evil-args text objects
;;     (define-key evil-inner-text-objects-map "a" 'evil-inner-arg)
;;     (define-key evil-outer-text-objects-map "a" 'evil-outer-arg)
;;
;;     ;; bind evil-forward/backward-args
;;     (define-key evil-normal-state-map "L" 'evil-forward-arg)
;;     (define-key evil-normal-state-map "H" 'evil-backward-arg)
;;     (define-key evil-motion-state-map "L" 'evil-forward-arg)
;;     (define-key evil-motion-state-map "H" 'evil-backward-arg)
;;
;;     ;; bind evil-jump-out-args
;;     (define-key evil-normal-state-map "K" 'evil-jump-out-args))

   (use-package evil-matchit
     :ensure t
     :config
     (global-evil-matchit-mode 1))

Load evil-org

(use-package evil-org
  :diminish evil-org-mode
  :load-path "~/.emacs.d/plugins/evil-org-mode")
(evil-org-mode t)

Load evil-surround

(use-package evil-surround
  :ensure t)
(global-evil-surround-mode 1)

Use escape to get out of as much stuff as possible

  (bind-key "<escape>" 'isearch-cancel isearch-mode-map)
  (define-key minibuffer-local-map (kbd "ESC") 'abort-recursive-edit)
  (define-key minibuffer-local-ns-map (kbd "ESC") 'abort-recursive-edit)
  (define-key minibuffer-local-completion-map (kbd "ESC") 'abort-recursive-edit)
  (define-key minibuffer-local-must-match-map (kbd "ESC") 'abort-recursive-edit)
  (define-key minibuffer-local-isearch-map (kbd "ESC") 'abort-recursive-edit)
;  (bind-key "<escape>" 'helm-keyboard-quit helm-map)
;  (bind-key "<escape>" 'helm-keyboard-quit helm-comp-read-map)

;; Make movement keys work like they should
(define-key evil-normal-state-map (kbd "<remap> <evil-next-line>") 'evil-next-visual-line)
(define-key evil-normal-state-map (kbd "<remap> <evil-previous-line>") 'evil-previous-visual-line)
(define-key evil-motion-state-map (kbd "<remap> <evil-next-line>") 'evil-next-visual-line)
(define-key evil-motion-state-map (kbd "<remap> <evil-previous-line>") 'evil-previous-visual-line)
(define-key evil-normal-state-map (kbd "C-k") 'evil-scroll-up)
(define-key evil-normal-state-map (kbd "C-j") 'evil-scroll-down)

; Make horizontal movement cross lines                                    
(setq-default evil-cross-lines t)

Make escape work the way it does in vim

;; esc quits
(defun minibuffer-keyboard-quit ()
  "Abort recursive edit.
In Delete Selection mode, if the mark is active, just deactivate it;
then it takes a second \\[keyboard-quit] to abort the minibuffer."
  (interactive)
  (if (and delete-selection-mode transient-mark-mode mark-active)
      (setq deactivate-mark  t)
    (when (get-buffer "*Completions*") (delete-windows-on "*Completions*"))
    (abort-recursive-edit)))
(define-key evil-normal-state-map [escape] 'keyboard-quit)
(define-key evil-visual-state-map [escape] 'keyboard-quit)
(define-key minibuffer-local-map [escape] 'minibuffer-keyboard-quit)
(define-key minibuffer-local-ns-map [escape] 'minibuffer-keyboard-quit)
(define-key minibuffer-local-completion-map [escape] 'minibuffer-keyboard-quit)
(define-key minibuffer-local-must-match-map [escape] 'minibuffer-keyboard-quit)
(define-key minibuffer-local-isearch-map [escape] 'minibuffer-keyboard-quit)
(global-set-key [escape] 'evil-exit-emacs-state)

Toggle Windows Split

(defun dp/window-toggle-split-direction ()
  "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))))))))

#Commented

#** FIX: Org mode with Evil fails cycle with TAB in terminal emacs # ##+BEGIN_SRC emacs-lisp

##+END_SRC

Bindings for Evil and Org-mode

  (dolist (state '(normal visual))
;    (evil-define-key state org-mode-map (kbd "C-j") 'org-metadown)
;    (evil-define-key state org-mode-map (kbd "C-k") 'org-metaup)
    (evil-define-key state org-mode-map (kbd "<") 'org-metaleft)
    (evil-define-key state org-mode-map (kbd ">") 'org-metaright)
;    (evil-define-key state org-mode-map (kbd "M-h") 'org-metaleft)
;    (evil-define-key state org-mode-map (kbd "M-l") 'org-metaright)
    (evil-define-key state org-mode-map (kbd "M-J") 'org-shiftmetadown)
    (evil-define-key state org-mode-map (kbd "M-K") 'org-shiftmetaup)
    (evil-define-key state org-mode-map (kbd "M-H") 'org-shiftmetaleft)
    (evil-define-key state org-mode-map (kbd "M-L") 'org-shiftmetaright)
    (evil-define-key state org-mode-map (kbd "^") 'org-beginning-of-line)
    (evil-define-key state org-mode-map (kbd "$") 'org-end-of-line))

(evil-define-key 'normal org-mode-map (kbd "<tab>") 'org-cycle)

;  (bind-key "J" 'org-agenda-goto-date org-agenda-mode-map)
;  (bind-key "j" 'evil-next-line org-agenda-mode-map)
;  (bind-key "k" 'evil-previous-line org-agenda-mode-map)

  ;;; evil surround pairs

  (defun evil-surround-org-pairs ()
    (push '(?= . ("=" . "=")) evil-surround-pairs-alist)
    (push '(?~ . ("~" . "~")) evil-surround-pairs-alist))

  (add-hook 'org-mode-hook 'evil-surround-org-pairs)

  ;;; get out of editing a source block

  (add-hook 'org-src-mode-map (lambda () (evil-local-set-key 'normal (kbd "Z Z") 'org-edit-src-exit)))

Display relative numbers for the current buffer

(use-package relative-line-numbers
  :ensure t
  :init)
(global-relative-line-numbers-mode)

(defun relative-abs-line-numbers-format (offset)
  "The default formatting function.
Return the absolute value of OFFSET, converted to string."
  (if (= 0 offset)
      (number-to-string (line-number-at-pos))
    (number-to-string (abs offset))))

(setq relative-line-numbers-format 'relative-abs-line-numbers-format)

Disable line numbers in org-mode

(add-hook 'org-mode-hook (lambda () (relative-line-numbers-mode 0)))

Org-agenda Vim Keybindings

   (add-to-list 'evil-motion-state-modes 'org-agenda-mode)

   (eval-after-load 'org-agenda
    '(progn
       (evil-set-initial-state 'org-agenda-mode 'normal)
       (evil-define-key 'normal org-agenda-mode-map
         (kbd "<RET>") 'org-agenda-switch-to
         (kbd "\t") 'org-agenda-goto

         "q" 'org-agenda-quit
         "r" 'org-agenda-redo
         "S" 'org-save-all-org-buffers
         "gj" 'org-agenda-goto-date
         "gJ" 'org-agenda-clock-goto
         "gm" 'org-agenda-bulk-mark
         "go" 'org-agenda-open-link
         "s" 'org-agenda-schedule
         "+" 'org-agenda-priority-up
         "," 'org-agenda-priority
         "-" 'org-agenda-priority-down
         "y" 'org-agenda-todo-yesterday
         "n" 'org-agenda-add-note
         "t" 'org-agenda-todo
         ":" 'org-agenda-set-tags
         ";" 'org-timer-set-timer
         "i" 'org-agenda-clock-in
         "O" 'org-agenda-clock-out
;;         "I" 'helm-org-task-file-headings
;;         "i" 'org-agenda-clock-in-avy
;;         "O" 'org-agenda-clock-out-avy
         "u" 'org-agenda-bulk-unmark
         "x" 'org-agenda-exit
         "j"  'org-agenda-next-line
         "k"  'org-agenda-previous-line
         "vt" 'org-agenda-toggle-time-grid
         "va" 'org-agenda-archives-mode
         "vw" 'org-agenda-week-view
         "vl" 'org-agenda-log-mode
         "vd" 'org-agenda-day-view
         "vc" 'org-agenda-show-clocking-issues
         "g/" 'org-agenda-filter-by-tag
         "o" 'delete-other-windows
         "gh" 'org-agenda-holiday
         "gv" 'org-agenda-view-mode-dispatch
         "f" 'org-agenda-later
         "b" 'org-agenda-earlier
         "c" 'helm-org-capture-templates
         "e" 'org-agenda-set-effort
         "n" nil  ; evil-search-next
         "{" 'org-agenda-manipulate-query-add-re
         "}" 'org-agenda-manipulate-query-subtract-re
         "A" 'org-agenda-toggle-archive-tag
         "." 'org-agenda-goto-today
         "0" 'evil-digit-argument-or-evil-beginning-of-line
         "<" 'org-agenda-filter-by-category
         ">" 'org-agenda-date-prompt
         "F" 'org-agenda-follow-mode
         "D" 'org-agenda-deadline
         "H" 'org-agenda-holidays
         "J" 'org-agenda-next-date-line
         "K" 'org-agenda-previous-date-line
         "L" 'org-agenda-recenter
;;         "P" 'org-agenda-show-priority
         "R" 'org-agenda-clockreport-mode
         "Z" 'org-agenda-sunrise-sunset
         "T" 'org-agenda-show-tags
         "X" 'org-agenda-clock-cancel
         "[" 'org-agenda-manipulate-query-add
         "g\\" 'org-agenda-filter-by-tag-refine
         "]" 'org-agenda-manipulate-query-subtract)))

Disable evil-mode when in term-mode

AlwaysEnterEmacsModewithAnsiTerm

 (eval-after-load 'evil-vars '(evil-set-initial-state 'term-mode 'emacs))
;; (eval-after-load 'evil-vars '(evil-set-initial-state 'inferior-python-mode 'emacs))

Org Mode

Install latest org-mode

(use-package org
  :mode (("\\.org$" . org-mode))
  :ensure org-plus-contrib
  )

;; org-mode is the default mode for .org, .org_archive, and .txt files.
(add-to-list 'auto-mode-alist '("\\.\\(org.gpg\\|org_archive.gpg\\|txt\\)$" . org-mode))

Display Preferences

Display an outline of pretty bullets instead of list of asterisks

(use-package org-bullets
  :ensure t)
(require 'org-bullets)
(add-hook 'org-mode-hook
          (lambda ()
            (org-bullets-mode t)))
(setq org-hide-leading-stars t)

(require 'ox-latex)

Also change the usual ellipsis(…) with a little downward-pointing that org displays when there is stuff under a header

(setq org-ellipsis "")

Use syntax highlighting in source blocks while editing.

(setq org-src-fontify-natively t) 

Automatically change list bullets. Org-mode has a way to automatically change the list bullets when you change list levels

(setq org-list-demote-modify-bullet (quote (("+" . "-")
                                            ("*" . "-")
                                            ("1." . "-")
                                            ("1)" . "-")
                                            ("A)" . "-")
                                            ("B)" . "-")
                                            ("a)" . "-")
                                            ("b)" . "-")
                                            ("A." . "-")
                                            ("B." . "-")
                                            ("a." . "-")
                                            ("b." . "-"))))

Org Modules

; Enable habit tracking (and a bunch of other modules)
(setq org-modules '(
                    org-habit
                    org-bbdb
                    org-bibtex
                    org-crypt
                    org-gnus
                    org-mu4e
                    org-id
                    org-info
                    org-inlinetask
                    org-irc
                    org-mew
                    org-mhe
                    org-protocol
                    org-rmail
                    org-w3m
                    ))

(eval-after-load 'org
  '(org-load-modules-maybe t))

(setq org-expiry-inactive-timestamps t)

; position the habit graph on the agenda to the right of the default
(setq org-habit-graph-column 50)

Keybindings

(global-set-key "\C-cl" 'org-store-link)
(global-set-key "\C-cc" 'org-capture)
(global-set-key "\C-cb" 'org-iswitchb)
(global-set-key (kbd "<f12>") 'org-agenda)
(global-set-key (kbd "<f11>") 'org-clock-goto)
(global-set-key (kbd "<f9>") 'org-search-view)
(global-set-key (kbd "<f8>") 'dp/switch-dictionary)
(global-set-key (kbd "C-x |") 'dp/window-toggle-split-direction)
(global-set-key (kbd "<f6>") 'winner-undo)
(global-set-key (kbd "<f7>") 'winner-redo)
(global-set-key (kbd "<f5>") 'spray-mode)
(global-set-key (kbd "<f3>") 'window-configuration-to-register)
(global-set-key (kbd "<f4>") 'jump-to-register)

Checklist handling (norang)

There’s a contributed org-checklist that can uncheck the boxes automatically when task is marked done

(require 'org-checklist)

Clocking (norang)

;;
;; Resume clocking task when emacs is restarted
(org-clock-persistence-insinuate)
;;
;; Show lot of clocking history so it's easy to pick items off the C-F11 list
(setq org-clock-history-length 23)
;; Resume clocking task on clock-in if the clock is open
(setq org-clock-in-resume t)
;; Change tasks to NEXT when clocking in
(setq org-clock-in-switch-to-state 'dp/clock-in-to-next)
;; Separate drawers for clocking and logs
(setq org-drawers (quote ("PROPERTIES" "LOGBOOK")))
;; Save clock data and state changes and notes in the LOGBOOK drawer
(setq org-clock-into-drawer t)
;; Sometimes I change tasks I'm clocking quickly - this removes clocked tasks with 0:00 duration
(setq org-clock-out-remove-zero-time-clocks t)
;; Clock out when moving task to a done state
(setq org-clock-out-when-done t)
;; Save the running clock and all clock history when exiting Emacs, load it on startup
(setq org-clock-persist t)
;; Do not prompt to resume an active clock
(setq org-clock-persist-query-resume nil)
;; Enable auto clock resolution for finding open clocks
(setq org-clock-auto-clock-resolution (quote when-no-clock-is-running))
;; Include current clocking task in clock reports
(setq org-clock-report-include-clocking-task t)

(setq dp/keep-clock-running nil)

(defun dp/clock-in-to-next (kw)
  "Switch a task from TODO to NEXT when clocking in.
Skips capture tasks, projects, and subprojects.
Switch projects and subprojects from NEXT back to TODO"
  (when (not (and (boundp 'org-capture-mode) org-capture-mode))
    (cond
     ((and (member (org-get-todo-state) (list "TODO"))
           (dp/is-task-p))
      "NEXT")
     ((and (member (org-get-todo-state) (list "NEXT"))
           (dp/is-project-p))
      "TODO"))))

(defun dp/find-project-task ()
  "Move point to the parent (project) task if any"
  (save-restriction
    (widen)
    (let ((parent-task (save-excursion (org-back-to-heading 'invisible-ok) (point))))
      (while (org-up-heading-safe)
        (when (member (nth 2 (org-heading-components)) org-todo-keywords-1)
          (setq parent-task (point))))
      (goto-char parent-task)
      parent-task)))

(defun dp/punch-in (arg)
  "Start continuous clocking and set the default task to the
selected task.  If no task is selected set the Organization task
as the default task."
  (interactive "p")
  (setq dp/keep-clock-running t)
  (if (equal major-mode 'org-agenda-mode)
      ;;
      ;; We're in the agenda
      ;;
      (let* ((marker (org-get-at-bol 'org-hd-marker))
             (tags (org-with-point-at marker (org-get-tags-at))))
        (if (and (eq arg 4) tags)
            (org-agenda-clock-in '(16))
          (dp/clock-in-organization-task-as-default)))
    ;;
    ;; We are not in the agenda
    ;;
    (save-restriction
      (widen)
      ; Find the tags on the current task
      (if (and (equal major-mode 'org-mode) (not (org-before-first-heading-p)) (eq arg 4))
          (org-clock-in '(16))
        (dp/clock-in-organization-task-as-default)))))

(defun dp/punch-out ()
  (interactive)
  (setq dp/keep-clock-running nil)
  (when (org-clock-is-active)
    (org-clock-out))
  (org-agenda-remove-restriction-lock))

(defun dp/clock-in-default-task ()
  (save-excursion
    (org-with-point-at org-clock-default-task
      (org-clock-in))))

(defun dp/clock-in-parent-task ()
  "Move point to the parent (project) task if any and clock in"
  (let ((parent-task))
    (save-excursion
      (save-restriction
        (widen)
        (while (and (not parent-task) (org-up-heading-safe))
          (when (member (nth 2 (org-heading-components)) org-todo-keywords-1)
            (setq parent-task (point))))
        (if parent-task
            (org-with-point-at parent-task
              (org-clock-in))
          (when dp/keep-clock-running
            (dp/clock-in-default-task)))))))

(defvar dp/organization-task-id "efe0217b-425f-4de2-a1a7-293d3dd68cd7")

(defun dp/clock-in-organization-task-as-default ()
  (interactive)
  (org-with-point-at (org-id-find dp/organization-task-id 'marker)
    (org-clock-in '(16))))

(defun dp/clock-out-maybe ()
  (when (and dp/keep-clock-running
             (not org-clock-clocking-in)
             (marker-buffer org-clock-default-task)
             (not org-clock-resolving-clocks-due-to-idleness))
    (dp/clock-in-parent-task)))

(add-hook 'org-clock-out-hook 'dp/clock-out-maybe 'append)
(require 'org-id)
(defun dp/clock-in-task-by-id (id)
  "Clock in a task by id"
  (org-with-point-at (org-id-find id 'marker)
    (org-clock-in nil)))

(defun dp/clock-in-last-task (arg)
  "Clock in the interrupted task if there is one
Skip the default task and get the next one.
A prefix arg forces clock in of the default task."
  (interactive "p")
  (let ((clock-in-to-task
         (cond
          ((eq arg 4) org-clock-default-task)
          ((and (org-clock-is-active)
                (equal org-clock-default-task (cadr org-clock-history)))
           (caddr org-clock-history))
          ((org-clock-is-active) (cadr org-clock-history))
          ((equal org-clock-default-task (car org-clock-history)) (cadr org-clock-history))
          (t (car org-clock-history)))))
    (widen)
    (org-with-point-at clock-in-to-task
      (org-clock-in nil))))
;; Agenda clock report parameters
(setq org-agenda-clockreport-parameter-plist
       (quote (:link t :maxlevel 5 :fileskip0 t :compact t :narrow 80)))

The following setup is removing the empty LOGBOOK drawers if they occur

;; Remove empty LOGBOOK drawers on clock out
(defun dp/remove-empty-drawer-on-clock-out ()
  (interactive)
  (save-excursion
    (beginning-of-line 0)
    (org-remove-empty-drawer-at (point))))

(add-hook 'org-clock-out-hook 'dp/remove-empty-drawer-on-clock-out 'append)

Next is for tasks

(defun dp/mark-next-parent-tasks-todo ()
  "Visit each parent task and change NEXT states to TODO"
  (let ((mystate (or (and (fboundp 'org-state)
                          state)
                     (nth 2 (org-heading-components)))))
    (when mystate
      (save-excursion
        (while (org-up-heading-safe)
          (when (member (nth 2 (org-heading-components)) (list "NEXT"))
            (org-todo "TODO")))))))

(add-hook 'org-after-todo-state-change-hook 'dp/mark-next-parent-tasks-todo 'append)
(add-hook 'org-clock-in-hook 'dp/mark-next-parent-tasks-todo 'append)

Editing source code

I do not want to get distracted by the same code in the other window, so i want org src to use the current window.

(setq org-src-window-setup 'current-window)

Setting up default files

The following sets a default target file for notes, and defines a global key for capturing new material.

;; Set to the location of my Org files on the NFS Share
(setq org-directory "/media/rdisk/new_tree/SelfImprover/OrgModeRepo")

(setq org-default-notes-file (concat org-directory "/notes.org"))

;; Capture templates for: TODO tasks, Notes, appointments, phone calls, meetings, and org-protocol
(setq org-capture-templates
      (quote (("l" "Ledger entries")
               ("lm" "MBNA" plain (file
                                   (concat org-directory "/NixOrg/ledger.dat.gpg"))
                "%(org-read-date) %^{Payee} 
     Liabilities:MBNA 
     Expenses:%^{Account}  %^{Amount} 
  ")
                  ("lc" "Cash" plain
                   (file
                    (concat org-directory "/NixOrg/ledger.dat.gpg"))
                   "%(org-read-date) * %^{Payee} 
     Expenses:Cash 
     Expenses:%^{Account}  %^{Amount} 
  ")
              ("t" "Todo" entry (file
                                 (concat org-directory "/NixOrg/refile.org.gpg"))
               "* TODO %?\n%U\n%a\n" :clock-in t :clock-resume t)
              ("r" "Respond" entry (file
                                    (concat org-directory "/NixOrg/refile.org.gpg"))
               "* NEXT Respond to %:from on %:subject\nSCHEDULED: %t\n%U\n%a\n" :clock-in t :clock-resume t :immediate-finish t)
              ("n" "Note" entry (file
                                 (concat org-directory "/NixOrg/refile.org.gpg"))
               "* %? :NOTE:\n%U\n%a\n" :clock-in t :clock-resume t)
              ("j" "Journal" entry (file+datetree 
                                    (concat org-directory "/NixOrg/journal.org.gpg"))
               "* %?\n%[jnl.txt]\n%U\n" :clock-in t :clock-resume t)
              ("c" "Conditionning" entry (file+datetree 
                                    (concat org-directory "/NixOrg/journal.org.gpg"))
               "* %?\n%[powerEval.txt]\n%U\n" :clock-in t :clock-resume t)
              ("w" "org-protocol" entry (file
                                         (concat org-directory "/NixOrg/refile.org.gpg"))
               "* TODO Review %c\n%U\n" :immediate-finish t)
              ("m" "Meeting" entry (file
                                    (concat org-directory "/NixOrg/refile.org.gpg"))
               "* MEETING with %? :MEETING:\n%U" :clock-in t :clock-resume t)
              ("p" "Phone call" entry (file
                                       (concat org-directory "/NixOrg/refile.org.gpg"))
               "* PHONE %? :PHONE:\n%U" :clock-in t :clock-resume t)
              ("h" "Habit" entry (file
                                  (concat org-directory "/NixOrg/refile.org.gpg"))
               "* NEXT %?\nSCHEDULED: %(format-time-string \"%<<%Y-%m-%d %a .+1d/3d>>\")\n:PROPERTIES:\n:STYLE: habit\n:REPEAT_TO_STATE: NEXT\n:END:\n%U\n%a\n"))))

Org Agenda Configuration

(setq org-agenda-files
      (append (file-expand-wildcards
             (concat org-directory "/NixOrg/*.org.gpg"))
             (file-expand-wildcards
              (concat org-directory "/NixOrg/roles/*.org.gpg"))
              (file-expand-wildcards
               (concat org-directory "/NixOrg/luxoft/*.org.gpg"))
             (file-expand-wildcards
              (concat org-directory "/NixOrg/amdocs/*.org.gpg"))))

(setq org-agenda-span 'day)

Install and configure org-agenda-property

(use-package org-agenda-property
  :ensure t)

(setq org-agenda-property-list (quote ("DELEGATEE")))
;;(setq org-agenda-property-column (quote 60))
(setq org-agenda-property-position (quote same-line))

;; Enable org-mode inheritance 
(setq org-use-property-inheritance t)

Archiving

(setq org-archive-mark-done nil)
(setq org-archive-location "%s_archive.gpg::* Archived Tasks")

(defun dp/skip-non-archivable-tasks ()
  "Skip trees that are not available for archiving"
  (save-restriction
    (widen)
    ;; Consider only tasks with done todo headings as archivable candidates
    (let ((next-headline (save-excursion (or (outline-next-heading) (point-max))))
          (subtree-end (save-excursion (org-end-of-subtree t))))
      (if (member (org-get-todo-state) org-todo-keywords-1)
          (if (member (org-get-todo-state) org-done-keywords)
              (let* ((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
                  nil))  ; available to archive
            (or subtree-end (point-max)))
        next-headline))))

Searches include archive files

;; Include agenda archive files when searching for things
(setq org-agenda-text-search-extra-files (quote (agenda-archives)))

Project Helper Functions (norang)

(defun dp/is-project-p ()
  "Any task with a todo keyword subtask"
  (save-restriction
    (widen)
    (let ((has-subtask)
          (subtree-end (save-excursion (org-end-of-subtree t)))
          (is-a-task (member (nth 2 (org-heading-components)) org-todo-keywords-1)))
      (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))))
      (and is-a-task has-subtask))))

(defun dp/is-project-subtree-p ()
  "Any task with a todo keyword that is in a project subtree.
Callers of this function already widen the buffer view."
  (let ((task (save-excursion (org-back-to-heading 'invisible-ok)
                              (point))))
    (save-excursion
      (dp/find-project-task)
      (if (equal (point) task)
          nil
        t))))

(defun dp/is-task-p ()
  "Any task with a todo keyword and no subtask"
  (save-restriction
    (widen)
    (let ((has-subtask)
          (subtree-end (save-excursion (org-end-of-subtree t)))
          (is-a-task (member (nth 2 (org-heading-components)) org-todo-keywords-1)))
      (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))))
      (and is-a-task (not has-subtask)))))

(defun dp/is-subproject-p ()
  "Any task which is a subtask of another project"
  (let ((is-subproject)
        (is-a-task (member (nth 2 (org-heading-components)) org-todo-keywords-1)))
    (save-excursion
      (while (and (not is-subproject) (org-up-heading-safe))
        (when (member (nth 2 (org-heading-components)) org-todo-keywords-1)
          (setq is-subproject t))))
    (and is-a-task is-subproject)))

(defun dp/list-sublevels-for-projects-indented ()
  "Set org-tags-match-list-sublevels so when restricted to a subtree we list all subtasks.
  This is normally used by skipping functions where this variable is already local to the agenda."
  (if (marker-buffer org-agenda-restrict-begin)
      (setq org-tags-match-list-sublevels 'indented)
    (setq org-tags-match-list-sublevels nil))
  nil)

(defun dp/list-sublevels-for-projects ()
  "Set org-tags-match-list-sublevels so when restricted to a subtree we list all subtasks.
  This is normally used by skipping functions where this variable is already local to the agenda."
  (if (marker-buffer org-agenda-restrict-begin)
      (setq org-tags-match-list-sublevels t)
    (setq org-tags-match-list-sublevels nil))
  nil)

(defvar dp/hide-scheduled-and-waiting-next-tasks t)

(defun dp/toggle-next-task-display ()
  (interactive)
  (setq dp/hide-scheduled-and-waiting-next-tasks (not dp/hide-scheduled-and-waiting-next-tasks))
  (when  (equal major-mode 'org-agenda-mode)
    (org-agenda-redo))
  (message "%s WAITING and SCHEDULED NEXT Tasks" (if dp/hide-scheduled-and-waiting-next-tasks "Hide" "Show")))

(defun dp/skip-stuck-projects ()
  "Skip trees that are not stuck projects"
  (save-restriction
    (widen)
    (let ((next-headline (save-excursion (or (outline-next-heading) (point-max)))))
      (if (dp/is-project-p)
          (let* ((subtree-end (save-excursion (org-end-of-subtree t)))
                 (has-next ))
            (save-excursion
              (forward-line 1)
              (while (and (not has-next) (< (point) subtree-end) (re-search-forward "^\\*+ NEXT " subtree-end t))
                (unless (member "WAITING" (org-get-tags-at))
                  (setq has-next t))))
            (if has-next
                nil
              next-headline)) ; a stuck project, has subtasks but no next task
        nil))))

(defun dp/skip-non-stuck-projects ()
  "Skip trees that are not stuck projects"
  ;; (dp/list-sublevels-for-projects-indented)
  (save-restriction
    (widen)
    (let ((next-headline (save-excursion (or (outline-next-heading) (point-max)))))
      (if (dp/is-project-p)
          (let* ((subtree-end (save-excursion (org-end-of-subtree t)))
                 (has-next ))
            (save-excursion
              (forward-line 1)
              (while (and (not has-next) (< (point) subtree-end) (re-search-forward "^\\*+ NEXT " subtree-end t))
                (unless (member "WAITING" (org-get-tags-at))
                  (setq has-next t))))
            (if has-next
                next-headline
              nil)) ; a stuck project, has subtasks but no next task
        next-headline))))

(defun dp/skip-non-projects ()
  "Skip trees that are not projects"
  ;; (dp/list-sublevels-for-projects-indented)
  (if (save-excursion (dp/skip-non-stuck-projects))
      (save-restriction
        (widen)
        (let ((subtree-end (save-excursion (org-end-of-subtree t))))
          (cond
           ((dp/is-project-p)
            nil)
           ((and (dp/is-project-subtree-p) (not (dp/is-task-p)))
            nil)
           (t
            subtree-end))))
    (save-excursion (org-end-of-subtree t))))

(defun dp/skip-non-tasks ()
  "Show non-project tasks.
Skip project and sub-project tasks, habits, and project related tasks."
  (save-restriction
    (widen)
    (let ((next-headline (save-excursion (or (outline-next-heading) (point-max)))))
      (cond
       ((dp/is-task-p)
        nil)
       (t
        next-headline)))))

(defun dp/skip-project-trees-and-habits ()
  "Skip trees that are projects"
  (save-restriction
    (widen)
    (let ((subtree-end (save-excursion (org-end-of-subtree t))))
      (cond
       ((dp/is-project-p)
        subtree-end)
       ((org-is-habit-p)
        subtree-end)
       (t
        nil)))))

(defun dp/skip-projects-and-habits-and-single-tasks ()
  "Skip trees that are projects, tasks that are habits, single non-project tasks"
  (save-restriction
    (widen)
    (let ((next-headline (save-excursion (or (outline-next-heading) (point-max)))))
      (cond
       ((org-is-habit-p)
        next-headline)
       ((and dp/hide-scheduled-and-waiting-next-tasks
             (member "WAITING" (org-get-tags-at)))
        next-headline)
       ((dp/is-project-p)
        next-headline)
       ((and (dp/is-task-p) (not (dp/is-project-subtree-p)))
        next-headline)
       (t
        nil)))))

(defun dp/skip-project-tasks-maybe ()
  "Show tasks related to the current restriction.
When restricted to a project, skip project and sub project tasks, habits, NEXT tasks, and loose tasks.
When not restricted, skip project and sub-project tasks, habits, and project related tasks."
  (save-restriction
    (widen)
    (let* ((subtree-end (save-excursion (org-end-of-subtree t)))
           (next-headline (save-excursion (or (outline-next-heading) (point-max))))
           (limit-to-project (marker-buffer org-agenda-restrict-begin)))
      (cond
       ((dp/is-project-p)
        next-headline)
       ((org-is-habit-p)
        subtree-end)
       ((and (not limit-to-project)
             (dp/is-project-subtree-p))
        subtree-end)
       ((and limit-to-project
             (dp/is-project-subtree-p)
             (member (org-get-todo-state) (list "NEXT")))
        subtree-end)
       (t
        nil)))))

(defun dp/skip-project-tasks ()
  "Show non-project tasks.
Skip project and sub-project tasks, habits, and project related tasks."
  (save-restriction
    (widen)
    (let* ((subtree-end (save-excursion (org-end-of-subtree t))))
      (cond
       ((dp/is-project-p)
        subtree-end)
       ((org-is-habit-p)
        subtree-end)
       ((dp/is-project-subtree-p)
        subtree-end)
       (t
        nil)))))

(defun dp/skip-non-project-tasks ()
  "Show project tasks.
Skip project and sub-project tasks, habits, and loose non-project tasks."
  (save-restriction
    (widen)
    (let* ((subtree-end (save-excursion (org-end-of-subtree t)))
           (next-headline (save-excursion (or (outline-next-heading) (point-max)))))
      (cond
       ((dp/is-project-p)
        next-headline)
       ((org-is-habit-p)
        subtree-end)
       ((and (dp/is-project-subtree-p)
             (member (org-get-todo-state) (list "NEXT")))
        subtree-end)
       ((not (dp/is-project-subtree-p))
        subtree-end)
       (t
        nil)))))

(defun dp/skip-projects-and-habits ()
  "Skip trees that are projects and tasks that are habits"
  (save-restriction
    (widen)
    (let ((subtree-end (save-excursion (org-end-of-subtree t))))
      (cond
       ((dp/is-project-p)
        subtree-end)
       ((org-is-habit-p)
        subtree-end)
       (t
        nil)))))

(defun dp/skip-non-subprojects ()
  "Skip trees that are not projects"
  (let ((next-headline (save-excursion (outline-next-heading))))
    (if (dp/is-subproject-p)
        nil
      next-headline)))

Custom agenda views (norang)

;; Do not dim blocked tasks
(setq org-agenda-dim-blocked-tasks nil)

;; Compact the block agenda view
(setq org-agenda-compact-blocks t)

;; Custom agenda command definitions
(setq org-agenda-custom-commands
      (quote (("N" "Notes" tags "NOTE"
               ((org-agenda-overriding-header "Notes")
                (org-tags-match-list-sublevels t)))
              ("h" "Habits" tags-todo "STYLE=\"habit\""
               ((org-agenda-overriding-header "Habits")
                (org-agenda-sorting-strategy
                 '(todo-state-down effort-up category-keep))))
              (" " "Agenda"
               ((agenda "" nil)
                (tags "REFILE"
                      ((org-agenda-overriding-header "Tasks to Refile")
                       (org-tags-match-list-sublevels nil)))
                (tags-todo "-CANCELLED/!NEXT"
                           ((org-agenda-overriding-header (concat "Project Next Tasks"
                                                                  (if dp/hide-scheduled-and-waiting-next-tasks
                                                                      ""
                                                                    " (including WAITING and SCHEDULED tasks)")))
                            (org-agenda-skip-function 'dp/skip-projects-and-habits-and-single-tasks)
                            (org-tags-match-list-sublevels t)
                            (org-agenda-todo-ignore-scheduled dp/hide-scheduled-and-waiting-next-tasks)
                            (org-agenda-todo-ignore-deadlines dp/hide-scheduled-and-waiting-next-tasks)
                            (org-agenda-todo-ignore-with-date dp/hide-scheduled-and-waiting-next-tasks)
                            (org-agenda-sorting-strategy
                             '(todo-state-down effort-up category-keep))))
                (tags-todo "-CANCELLED/!"
                           ((org-agenda-overriding-header "Stuck Projects")
                            (org-agenda-skip-function 'dp/skip-non-stuck-projects)
                            (org-agenda-sorting-strategy
                             '(category-keep))))
                (tags-todo "-HOLD-CANCELLED/!"
                           ((org-agenda-overriding-header "Projects")
                            (org-agenda-skip-function 'dp/skip-non-projects)
                            (org-tags-match-list-sublevels 'indented)
                            (org-agenda-sorting-strategy
                             '(category-keep))))
                (tags-todo "-REFILE-CANCELLED-WAITING-HOLD/!"
                           ((org-agenda-overriding-header (concat "Project Subtasks"
                                                                  (if dp/hide-scheduled-and-waiting-next-tasks
                                                                      ""
                                                                    " (including WAITING and SCHEDULED tasks)")))
                            (org-agenda-skip-function 'dp/skip-non-project-tasks)
                            (org-agenda-todo-ignore-scheduled dp/hide-scheduled-and-waiting-next-tasks)
                            (org-agenda-todo-ignore-deadlines dp/hide-scheduled-and-waiting-next-tasks)
                            (org-agenda-todo-ignore-with-date dp/hide-scheduled-and-waiting-next-tasks)
                            (org-agenda-sorting-strategy
                             '(category-keep))))
                (tags-todo "-REFILE-CANCELLED-WAITING-HOLD/!"
                           ((org-agenda-overriding-header (concat "Standalone Tasks"
                                                                  (if dp/hide-scheduled-and-waiting-next-tasks
                                                                      ""
                                                                    " (including WAITING and SCHEDULED tasks)")))
                            (org-agenda-skip-function 'dp/skip-project-tasks)
                            (org-agenda-todo-ignore-scheduled dp/hide-scheduled-and-waiting-next-tasks)
                            (org-agenda-todo-ignore-deadlines dp/hide-scheduled-and-waiting-next-tasks)
                            (org-agenda-todo-ignore-with-date dp/hide-scheduled-and-waiting-next-tasks)
                            (org-agenda-sorting-strategy
                             '(category-keep))))
                (tags-todo "-CANCELLED+WAITING|HOLD/!"
                           ((org-agenda-overriding-header (concat "Waiting and Postponed Tasks"
                                                                  (if dp/hide-scheduled-and-waiting-next-tasks
                                                                      ""
                                                                    " (including WAITING and SCHEDULED tasks)")))
                            (org-agenda-skip-function 'dp/skip-non-tasks)
                            (org-tags-match-list-sublevels nil)
                            (org-agenda-todo-ignore-scheduled dp/hide-scheduled-and-waiting-next-tasks)
                            (org-agenda-todo-ignore-deadlines dp/hide-scheduled-and-waiting-next-tasks)))
                (tags "-REFILE/"
                      ((org-agenda-overriding-header "Tasks to Archive")
                       (org-agenda-skip-function 'dp/skip-non-archivable-tasks)
                       (org-tags-match-list-sublevels nil))))
               nil))))
; Overwrite the current window with the agenda
(setq org-agenda-window-setup 'current-window)

Agenda view tweaks

;; 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 effort-up category-keep)
              (todo category-up effort-up)
              (tags category-up effort-up)
              (search category-up))))

;; Start the weekly agenda on Monday
(setq org-agenda-start-on-weekday 1)

;; Enable display of the time grid so we can see the marker for the current time
(setq org-agenda-time-grid (quote ((daily today remove-match)
                                   #("----------------" 0 16 (org-heading t))
                                   (0900 1100 1300 1500 1700))))

;; Display tags farther right
;; (setq org-agenda-tags-column -102)

;; Place tags close to the right-hand side of the window
(add-hook 'org-finalize-agenda-hook 'place-agenda-tags)
(defun place-agenda-tags ()
  "Put the agenda tags by the right border of the agenda window."
  (setq org-agenda-tags-column (- 10 (window-width)))
    (org-agenda-align-tags))

;; Vertical align the agenda views
(setq org-agenda-prefix-format
   (quote
    ((agenda . " %i %-18:c%?-12t% s")
     (timeline . "  % s")
     (todo . " %i %-18:c")
     (tags . " %i %-18:c")
     (search . " %i %-18:c"))))

;;
;; Agenda sorting functions
;;
(setq org-agenda-cmp-user-defined 'dp/agenda-sort)

(defun dp/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
     ((dp/agenda-sort-test 'dp/is-not-scheduled-or-deadline a b))

     ; deadlines for today next
     ((dp/agenda-sort-test 'dp/is-due-deadline a b))

     ; late deadlines next
     ((dp/agenda-sort-test-num 'dp/is-late-deadline '> a b))

     ; scheduled items for today next
     ((dp/agenda-sort-test 'dp/is-scheduled-today a b))

     ; late scheduled items next
     ((dp/agenda-sort-test-num 'dp/is-scheduled-late '> a b))

     ; pending deadlines last
     ((dp/agenda-sort-test-num 'dp/is-pending-deadline '< a b))

     ; finally default to unsorted
     (t (setq result nil)))
    result))

(defmacro dp/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))
     (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 dp/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 dp/is-not-scheduled-or-deadline (date-str)
  (and (not (dp/is-deadline date-str))
       (not (dp/is-scheduled date-str))))

(defun dp/is-due-deadline (date-str)
  (string-match "Deadline:" date-str))

(defun dp/is-late-deadline (date-str)
  (string-match "\\([0-9]*\\) d\. ago:" date-str))

(defun dp/is-pending-deadline (date-str)
  (string-match "In \\([^-]*\\)d\.:" date-str))

(defun dp/is-deadline (date-str)
  (or (dp/is-due-deadline date-str)
      (dp/is-late-deadline date-str)
      (dp/is-pending-deadline date-str)))

(defun dp/is-scheduled (date-str)
  (or (dp/is-scheduled-today date-str)
      (dp/is-scheduled-late date-str)))

(defun dp/is-scheduled-today (date-str)
  (string-match "Scheduled:" date-str))

(defun dp/is-scheduled-late (date-str)
  (string-match "Sched\.\\(.*\\)x:" date-str))

Sticky Agendas

Sticky agendas allow you to have more than one agenda view created simultaneously. You can quickly switch to the view without incurring an agenda rebuild by invoking the agenda custom command key that normally generates the agenda. If it already exists it will display the existing view. g forces regeneration of the agenda view.

I normally have two views displayed (F12 a for the daily/weekly agenda and F12 SPC for my project management view)

;; Use sticky agenda's so they persist
(setq org-agenda-sticky t)

Agenda persistent filters

This is a great feature! Persistent agenda filters means if you limit a search with / TAB SomeTag the agenda remembers this filter until you change it.

Enable persistent filters with the following variable

(setq org-agenda-persistent-filter t)

Keep tasks with timestamps visible on the global todo lists (norang)

;; Keep tasks with dates on the global todo lists
(setq org-agenda-todo-ignore-with-date nil)

;; Keep tasks with deadlines on the global todo lists
(setq org-agenda-todo-ignore-deadlines nil)

;; Keep tasks with scheduled dates on the global todo lists
(setq org-agenda-todo-ignore-scheduled nil)

;; Keep tasks with timestamps on the global todo lists
(setq org-agenda-todo-ignore-timestamp nil)

;; 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) 

Editing clock and consistency checks

(setq org-time-stamp-rounding-minutes (quote (1 1)))

(setq org-agenda-clock-consistency-checks
      (quote (:max-duration "4:00"
              :min-duration 0
              :max-gap 0
              :gap-ok-around ("4:00"))))

Meeting Notes

(defun dp/prepare-meeting-notes ()
  "Prepare meeting notes for email
   Take selected region and convert tabs to spaces, mark TODOs with leading >>>, and copy to kill ring for pasting"
  (interactive)
  (let (prefix)
    (save-excursion
      (save-restriction
        (narrow-to-region (region-beginning) (region-end))
        (untabify (point-min) (point-max))
        (goto-char (point-min))
        (while (re-search-forward "^\\( *-\\\) \\(TODO\\|DONE\\): " (point-max) t)
          (replace-match (concat (make-string (length (match-string 1)) ?>) " " (match-string 2) ": ")))
        (goto-char (point-min))
        (kill-ring-save (point-min) (point-max))))))

Review agenda views

;; define "R" as the prefix key for reviewing what happened in various
;; time periods
(add-to-list 'org-agenda-custom-commands
             '("R" . "Review" )
             )

;; Common settings for all reviews
(setq dp/org-agenda-review-settings
      '(
;;        (org-agenda-files '("~/org/notes.org"
;;                            "~/org/projects.org"
;;                            ))
        (org-agenda-show-all-dates t)
        (org-agenda-start-with-log-mode t)
        (org-agenda-start-with-clockreport-mode t)
        (org-agenda-archives-mode t)
        ;; I don't care if an entry was archived
        (org-agenda-hide-tags-regexp
         (concat org-agenda-hide-tags-regexp
                 "\\|ARCHIVE"))
      ))
;; Show the agenda with the log turn on, the clock table show and
;; archived entries shown.  These commands are all the same exept for
;; the time period.
(add-to-list 'org-agenda-custom-commands
             `("Rw" "Week in review"
                agenda ""
                ;; agenda settings
                ,(append
                  dp/org-agenda-review-settings
                  '((org-agenda-span 'week)
                    (org-agenda-start-on-weekday 0)
                    (org-agenda-overriding-header "Week in Review"))
                  )
                (concat org-directory "/review/week.html")
                ))


(add-to-list 'org-agenda-custom-commands
             `("Rd" "Day in review"
                agenda ""
                ;; agenda settings
                ,(append
                  dp/org-agenda-review-settings
                  '((org-agenda-span 'day)
                    (org-agenda-overriding-header "Week in Review"))
                  )
                (concat org-directory "/review/day.html")
                ))

(add-to-list 'org-agenda-custom-commands
             `("Rm" "Month in review"
                agenda ""
                ;; agenda settings
                ,(append
                  dp/org-agenda-review-settings
                  '((org-agenda-span 'month)
                    (org-agenda-start-day "01")
                    (org-read-date-prefer-future nil)
                    (org-agenda-overriding-header "Month in Review"))
                  )
                (concat org-directory "/review/month.html")
                ))

Configure org-refile

(setq org-refile-targets '((org-agenda-files . (:maxlevel . 6))))

Logging stuff

(setq org-log-done (quote time))
(setq org-log-into-drawer t)
(setq org-log-state-notes-insert-after-drawers nil)

(setq org-todo-keywords
      (quote ((sequence "TODO(t)" "NEXT(n)" "|" "DONE(d)")
              (sequence "WAITING(w@/!)" "HOLD(h@/!)" "|" "CANCELLED(c@/!)" "PHONE" "MEETING"))))

(setq org-todo-keyword-faces
      (quote (("TODO" :foreground "red" :weight bold)
              ("NEXT" :foreground "blue" :weight bold)
              ("DONE" :foreground "forest green" :weight bold)
              ("WAITING" :foreground "orange" :weight bold)
              ("HOLD" :foreground "magenta" :weight bold)
              ("CANCELLED" :foreground "forest green" :weight bold)
              ("MEETING" :foreground "yellow" :weight bold)
              ("PHONE" :foreground "yellow" :weight bold))))

(setq org-todo-state-tags-triggers
      (quote (("CANCELLED" ("CANCELLED" . t))
              ("WAITING" ("WAITING" . t))
              ("HOLD" ("WAITING") ("HOLD" . t))
              (done ("WAITING") ("HOLD"))
              ("TODO" ("WAITING") ("CANCELLED") ("HOLD"))
              ("NEXT" ("WAITING") ("CANCELLED") ("HOLD"))
              ("DONE" ("WAITING") ("CANCELLED") ("HOLD")))))

Tags (norang)

; Tags with fast selection keys
(setq org-tag-alist (quote ((:startgroup)
                            ("@errand" . ?e)
                            ("@office" . ?o)
                            ("@home" . ?H)
                            ("@field" . ?f)
                            ("@reading" . ?r)
                            (:endgroup)
                            ("WAITING" . ?w)
                            ("HOLD" . ?h)
                            ("PERSONAL" . ?P)
                            ("WORK" . ?W)
                            ("crypt" . ?E)
                            ("NOTE" . ?n)
                            ("CANCELLED" . ?c)
                            ("BELIEF" . ?b)
                            ("FLAGGED" . ??))))

; Allow setting single tags without the menu
;(setq org-fast-tag-selection-single-key (quote expert))

; For tag searches ignore tasks with scheduled and deadline dates
(setq org-agenda-tags-todo-honor-ignore-options t)

; For fast selection of tags
(setq org-use-fast-tag-selection t)

; Allow changing todo states with S-left and S-right skipping all of the normal processing when entering or leaving a todo state.

(setq org-treat-S-cursor-todo-selection-as-state-change nil)

org-indent-mode

(setq org-startup-indented t)

google-translate

This package allows to translate the strings using Google Translate service directly from GNU Emacs

(use-package google-translate
  :ensure t)
(require 'google-translate)
(require 'google-translate-smooth-ui)
(global-set-key "\C-ct" 'google-translate-smooth-translate)

(setq google-translate-translation-directions-alist
      '(("en" . "bg") ("bg" . "en")))

Task estimate with column mode

; Set default column view headings: Task Effort Clock_Summary
(setq org-columns-default-format "%60ITEM(Task) %20TAGS(Context) %10Effort(Effort){:} %10CLOCKSUM")

; global Effort estimate values
; global STYLE property values for completion
(setq org-global-properties (quote (("Effort_ALL" . "0:15 0:30 0:45 1:00 2:00 3:00 4:00 5:00 6:00 0:00")
                                    ("STYLE_ALL" . "habit"))))

Handling blocked tasks

Blocked tasks are tasks that have subtasks which are not in a done todo state. Blocked tasks show up in a grayed font by default in the agenda.

To enable task blocking set the following variable:

(setq org-enforce-todo-dependencies t)

This setting prevents tasks from changing to DONE if any subtasks are still open. This works pretty well except for repeating tasks. I find I’m regularly adding TODO tasks under repeating tasks and not all of the subtasks need to be complete before the next repeat cycle.

You can override the setting temporarily by changing the task with C-u C-u C-u C-c C-t but I never remember that. I set a permanent property on the repeated tasks as follows:

NOBLOCKING t

Encrypting org files

(require 'epa-file)

(setq org-crypt-disable-auto-save nil) 
(setq epa-file-inhibit-auto-save nil)

Install pinentry

(use-package pinentry
  :ensure t)

(setenv "INSIDE_EMACS" (format "%s,comint" emacs-version))
(pinentry-start)

Spritz reading mode for emacs

(use-package spray
  :ensure t)

Ledger Mode

(use-package ledger-mode
  :ensure t
  :init
  (setq ledger-clear-whole-transactions 1)

  :config
  (add-to-list 'evil-emacs-state-modes 'ledger-report-mode)
  :mode "\\.dat\\.gpg\\'")

Yasnippet

(use-package yasnippet
  :ensure t)

(yas-global-mode 1)

Yaml Mode

Install and enable yaml mode

(use-package yaml-mode
  :ensure t)

(add-hook 'yaml-mode-hook
          (lambda ()
            (define-key yaml-mode-map "\C-m" 'newline-and-indent)))

Install and enable ansible mode emacs-ansible

(use-package ansible
  :ensure t)

(add-hook 'yaml-mode-hook '(lambda() (ansible 1)))

Latex Mode

Export with xelatex

;; Use xelatex for PDF export
;;(setq texcmd "latexmk -pdflatex=xelatex -pdf -quiet %f")

;; LaTeX compilation command
;;(setq org-latex-pdf-process (list texcmd))

;; Another solution
(setq org-export-dispatch-use-expert-ui t ; non-intrusive export dispatch
        org-latex-pdf-process               ; for regular export
        '("xelatex -shell-escape -interaction nonstopmode -output-directory %o %f"
          "xelatex -shell-escape -interaction nonstopmode -output-directory %o %f"
          "xelatex -shell-escape -interaction nonstopmode -output-directory %o %f"))
;; For export to latex I use the following setting to get fontified listings from source blocks:
(setq org-latex-listings t)

Report Export Class

(setq org-export-with-sub-superscripts nil)
(add-to-list 'org-latex-classes
          '("dp-report"
             "\\documentclass{report}
\\usepackage{fontspec}
\\usepackage[bulgarian,english]{babel}
\\usepackage{hyperref}
\\usepackage{fancyhdr}
\\usepackage{listings}
\\usepackage{titlesec}
\\usepackage{graphics}
\\usepackage{fancyhdr}
\\usepackage{lmodern}
\\usepackage{geometry}
\\usepackage{longtable}
\\usepackage{underscore}
\\setmainfont{CMU Serif}
\\geometry{
  a4paper,
  total={210mm,297mm},
  left=20mm,
  right=20mm,
  top=20mm,
  bottom=15mm,
  }
\\pagestyle{fancy}
\\fancyhf{}
\\renewcommand{\\sectionmark}[1]{\\markright{#1}}
\\fancyhead[R]{Page \\thepage}
\\fancyhead[L]{\\rightmark}
\\fancyfoot[C]{\\emph{Proprietary and Confidential}} 
[NO-DEFAULT-PACKAGES]
[NO-PACKAGES]
[EXTRA]"
             ("\\section{%s}" . "\\section*{%s}")
             ("\\subsection{%s}" . "\\subsection*{%s}")
             ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
             ("\\paragraph{%s}" . "\\paragraph*{%s}")
             ("\\subparagraph{%s}" . "\\subparagraph*{%s}")))
(setq org-latex-hyperref-template "\\hypersetup{
pdfauthor={%a},
pdftitle={%t},
pdfkeywords={%k},
pdfsubject={%d},
pdfcreator={%c},
pdflang={%L},
colorlinks=true,
linktoc=all,
linkcolor=blue,
}\n"
      )

Evince for PDF Files

;; PDFs visited in Org-mode are opened in Evince (and not in the default choice) http://stackoverflow.com/a/8836108/789593
(add-hook 'org-mode-hook
      '(lambda ()
         (delete '("\\.pdf\\'" . default) org-file-apps)
         (add-to-list 'org-file-apps '("\\.pdf\\'" . "evince %s"))))

Python Mode

; Install python-environment

;(use-package python-environment
;  :ensure t)

; Use jedi for auto-completion
;(use-package elpy
;  :ensure t)

;(add-hook 'python-mode-hook 'jedi:setup)
;(setq jedi:complete-on-dot t)                 ; optional
(use-package elpy
  :ensure t)

(elpy-enable)
(elpy-use-ipython)
(setq elpy-rpc-backend "jedi")
(setq python-shell-interpreter "/usr/bin/ipython"
  python-shell-interpreter-args "--TerminalInteractiveShell.editing_mode=vi --simple-prompt -i")
(defalias 'workon 'pyvenv-workon)
; Install ein
(use-package ein
  :ensure t)

; Install flycheck
(use-package flycheck
  :ensure t)

; Install py-autopep8
(use-package py-autopep8
  :ensure t)

Configure pyvenv

(use-package pyvenv
  :ensure t
  :init
  (setenv "WORKON_HOME" "~/.emacs.d/.python-environments/default/")
  (pyvenv-mode 1)
  (pyvenv-tracking-mode 1))

Octave Mode

(setq auto-mode-alist
(cons '("\\.m$" . octave-mode) auto-mode-alist))

(add-hook 'octave-mode-hook
(lambda ()
(abbrev-mode 1)
(auto-fill-mode 1)
(if (eq window-system 'x)
(font-lock-mode 1))))

OmniSharp Mode

(use-package omnisharp
  :ensure t
  :config
  (progn
    (add-hook 'csharp-mode-hook 'omnisharp-mode)))

    (setq omnisharp-server-executable-path "/home/dpetrov/src/omnisharp-server/omnisharp-server/OmniSharp/bin/Debug/OmniSharp.exe")

Company Mode

(use-package company
  :ensure t)

(eval-after-load 'company
  '(add-to-list 'company-backends 'company-omnisharp))

Use smex to handle M-x with ido

(use-package smex
  :ensure t)

(smex-initialize)
(global-set-key (kbd "M-x") 'smex)
(global-set-key (kbd "M-X") 'smex-major-mode-commands)

General configuration

Turn off bars

(menu-bar-mode -1)
(scroll-bar-mode -1)
(tool-bar-mode -1)

Disable emacs welcome screen

(setq inhibit-startup-message t)

Adjust windows margins

(setq-default left-margin-width 0 right-margin-width 0) ; Define new widths.
 (set-window-buffer nil (current-buffer)) ; Use them now.

Sane defaults

Some default configurations

;; Answering just 'y' or 'n' will do
(defalias 'yes-or-no-p 'y-or-n-p)

;; Turn off the blinking cursor
(blink-cursor-mode -1)

Enable line highlight

(global-hl-line-mode t)

Disable Indent-Tabs-mode

(setq-default indent-tabs-mode nil)
(setq-default tab-width 2)

Set default input method to Bulgarian-phonetic

(setq default-input-method "bulgarian-phonetic")

Backups and autosave

This is one of the things people usually want to change right away. Emacs saves backup files in the current directory.

(defvar autosave-dir
 (concat "/home/" (user-login-name) "/.emacs.d/backups/"))

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

HTTP

(use-package ob-http
  :ensure t)

Diagrams and graphics

Graphviz and Ditaa make it easier to create diagrams from Emacs. See http://sachachua.com/evil-plans for examples and source.

(setq org-ditaa-jar-path "/usr/share/java/ditaa/ditaa-0_9.jar")
(setq org-plantuml-jar-path "/home/dpetrov/src/plantuml.jar")

(setq org-startup-with-inline-images t)
(use-package org
  :config
  (progn
    (add-hook 'org-babel-after-execute-hook 'org-display-inline-images)
    (org-babel-do-load-languages
     'org-babel-load-languages
     '((dot . t)
       (ditaa . t)
       (plantuml . t)
       (sh . t)
       (http . t)
       (perl . t)
       (python . t)
       (R . t)))
    (add-to-list 'org-src-lang-modes '("dot" . graphviz-dot))))

Powerline

(use-package powerline
  :ensure t)
(require 'powerline)
(powerline-vim-theme)
(display-time-mode t)

Helm-interactive completion

Help makes it easy to complete various things. I find it to be easier to configure that ido in order to get completion in as many places as possible, although I prefer ido’s way of switching buffers.

(use-package helm
  :ensure t
  :diminish helm-mode
  :init
  (progn
    (require 'helm-config)
    (setq helm-candidate-number-limit 100)
    (setq helm-split-window-default-side 'same)
    (setq helm-full-frame nil)
    ;; From https://gist.github.com/antifuchs/9238468
    (setq helm-idle-delay 0.0 ; update fast sources immediately (doesn't).
          helm-input-idle-delay 0.01  ; this actually updates things
                                        ; reeeelatively quickly.
          helm-yas-display-key-on-candidate t
          helm-quick-update t
          helm-M-x-requires-pattern nil
          helm-ff-skip-boring-files t)
    (helm-mode))
  :bind (("C-c h" . helm-mini)
         ("C-h a" . helm-apropos)
         ("C-x C-b" . helm-buffers-list)
         ("C-x b" . helm-buffers-list)
         ("M-y" . helm-show-kill-ring)
         ("M-x" . helm-M-x)
         ("C-x c o" . helm-occur)
         ("C-x c s" . helm-swoop)
         ("C-x c y" . helm-yas-complete)
         ("C-x c Y" . helm-yas-create-snippet-on-region)
         ("C-x c SPC" . helm-all-mark-rings)))

Also, visual-line-mode is so much better than auto-fill-mode. It does not actually break the text into multiple lines - it only looks that way

(remove-hook 'text-mode-hook #'turn-on-auto-fill)
(add-hook 'text-mode-hook 'turn-on-visual-line-mode)

Use Swoop

(use-package helm-swoop
  :ensure t
  :bind (("C-s" . helm-swoop)
         ("C-S-s" . helm-multi-swoop-all))
  :config
  ;; Hopefully temporary, because my version of helm-swoop requires it
  ; (setq helm-match-plugin-mode helm-mode)
  )

;; disable pre-input
(setq helm-swoop-pre-input-function
      (lambda () ""))

Projectile

Install projectile and helm-projectile

(use-package projectile
  :ensure t
  :diminish projectile-mode
  :config
  (progn
    (setq projectile-require-project-root nil)
    (setq projectile-keymap-prefix (kbd "C-c p"))
    (setq projectile-completion-system 'default)
    (setq projectile-enable-caching nil)
    (setq projectile-indexing-method 'alien)
    (add-to-list 'projectile-globally-ignored-files "node-modules"))
  :config
  (projectile-global-mode))
(use-package helm-projectile
  :ensure t)

Smooth scrolling

In order to disable the jumpy scrolling

(use-package smooth-scrolling
  :ensure t
  :init)
(setq scroll-margin 5 scroll-conservatively 9999 scroll-step 1)

Set default browser to firefox

(setq browse-url-browser-function 'browse-url-generic
      browse-url-generic-program "firefox")

Using flyspell mode to reduce spelling errors

flyspell-mode is enabled for almost everything to help prevent creating documents with spelling errors.

;; flyspell mode for spell checking everywhere
(add-hook 'org-mode-hook 'turn-on-flyspell 'append)

;; Disable keys in org-mode
;;    C-c [ 
;;    C-c ]
;;    C-c ;
;;    C-c C-x C-q  cancelling the clock (we never want this)
(add-hook 'org-mode-hook
          '(lambda ()
             ;; 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)
             (org-defkey org-mode-map "\C-c;" 'undefined)
             (org-defkey org-mode-map "\C-c\C-x\C-q" 'undefined))
          'append)

(add-hook 'org-mode-hook
          (lambda ()
            (local-set-key (kbd "C-c M-o") 'dp/mail-subtree))
          'append)

(defun dp/mail-subtree ()
  (interactive)
  (org-mark-subtree)
  (org-mime-subtree))

(let ((langs '("american" "bulgarian")))
  (setq lang-ring (make-ring (length langs)))
  (dolist (elem langs) (ring-insert lang-ring elem)))

(defun dp/switch-dictionary ()
  (interactive)
  (let ((lang (ring-ref lang-ring -1)))
    (ring-insert lang-ring lang)
    (ispell-change-dictionary lang)
    (flyspell-buffer)
    (message "Dictionary switched to %s" lang)))

Install Jammer

  (use-package jammer
    :ensure t
    :init)
  
    (setq jammer-repeat-delay '1)
    (setq jammer-repeat-type 'linear)
    (setq jammer-repeat-window '0.75)
;;  (setq jammer-block-type 'blacklist)
    (setq jammer-block-list '("h"))

;;  (jammer-mode 1)

Enable winner-mode

(winner-mode 1)

Install Multi Term

(use-package multi-term
  :ensure t)

(setq multi-term-program "/bin/zsh")

Enable primary selection and disable clipboard to support clipit

(setq x-select-enable-primary t)

;; Not sure if that is also needed
;; (setq x-select-enable-clipboard nil)

Dired Configuration

;; Auto-refresh dired on file change
(add-hook 'dired-mode-hook 'auto-revert-mode)

Desktop Configuration

(use-package revive
  :ensure t)

(require 'windows)
(require 'recentf)

;; -- Load the saved windows automatically on boot
(add-hook 'window-setup-hook 'resume-windows)

;; -- Save place in file
(setq-default save-place t)

;; --  Use this command to quit and save your setup
(define-key ctl-x-map "C" 'see-you-again)

Email Configuration

Configure mu4e

(require 'mu4e-contrib)

(setq mu4e-maildir (expand-file-name "~/Maildir"))

(setq mu4e-drafts-folder "/gmail/[Gmail].Drafts")
(setq mu4e-sent-folder   "/gmail/[Gmail].Sent Mail")
(setq mu4e-trash-folder  "/gmail/[Gmail].Trash")

;; don't save message to Sent Messages, GMail/IMAP will take care of this
(setq mu4e-sent-messages-behavior 'delete)

;; setup some handy shortcuts
(setq mu4e-maildir-shortcuts
      '(("/amdocs/INBOX"             . ?a)
        ("/gmail/INBOX" . ?g)
        ("/gmail/Trash"     . ?t)))

;; allow for updating mail using 'U' in the main view:
(setq mu4e-get-mail-command "offlineimap")
(setq mu4e-update-interval 300)


;; something about ourselves
(setq
 user-mail-address "[email protected]"
 user-full-name  "Dimitar Petrov"
 mu4e-compose-signature (concat
                         "Dimitar Petrov\n"
                         "[email protected]"))

(add-to-list 'mu4e-view-actions
             '("ViewInBrowser" . mu4e-action-view-in-browser) t)

;; sending mail -- replace USERNAME with your gmail username
;; also, make sure the gnutls command line utils are installed
;; package 'gnutls-bin' in Debian/Ubuntu, 'gnutls' in Archlinux.

(use-package smtpmail
  :ensure t)

(setq message-send-mail-function 'smtpmail-send-it
      starttls-use-gnutls t
      smtpmail-starttls-credentials
      '(("smtp.gmail.com" 587 nil nil))
      smtpmail-auth-credentials
      (expand-file-name "~/.authinfo.gpg")
      smtpmail-default-smtp-server "smtp.gmail.com"
      smtpmail-smtp-server "smtp.gmail.com"
      smtpmail-smtp-service 587
      smtpmail-debug-info t)

(use-package evil-mu4e
  :ensure t)

(setq org-mu4e-link-query-in-headers-mode nil)
(setq shr-color-visible-luminance-min 80)
(defun dp/render-html-message ()
  (let ((dom (libxml-parse-html-region (point-min) (point-max))))
    (erase-buffer)
    (shr-insert-document dom)
    (goto-char (point-min))))

(setq mu4e-html2text-command 'dp/render-html-message)

Configure GNUS

(setq gnus-select-method
      '(nnmaildir "gmail"
                  (directory "~/Maildir/gmail/")
                  (directory-files nnheader-directory-files-safe)
                  (get-new-mail nil)))

Links

Configure ido (disabled)

;  (setq ido-enable-flex-matching t)
;  (setq ido-everywhere t)
;  (ido-mode 1)
;  (ido-ubiquitous)
;  (flx-ido-mode 1) ; better/faster matching
;  (setq ido-create-new-buffer 'always) ; don't confirm to create new buffers
;  (ido-vertical-mode 1)
;  (setq ido-vertical-define-keys 'C-n-and-C-p-only)

Final Configuration

;; -- Set up window saving!! Place at end of .emacs file
(win:startup-with-window)

Post-steps after cloning the GitHub Repository

Clone the evil-org-mode to plugins since it is not added to Melpa yet

mkdir -p ~/.emacs.d/plugins; git clone git://github.com/edwtjo/evil-org-mode.git ~/.emacs.d/plugins/evil-org-mode

Get windows.el

mkdir -p ~/.emacs.d/plugins; wget 'http://www.gentei.org/~yuuji/software/windows.el' -O ~/.emacs.d/plugins/windows.el