diff options
| author | Raúl Benencia <rul@kalgan.cc> | 2019-06-23 11:43:30 -0700 | 
|---|---|---|
| committer | Raúl Benencia <rul@kalgan.cc> | 2019-06-23 13:32:01 -0700 | 
| commit | 284c8327c95bb0c71b111ebf95723a35a478295c (patch) | |
| tree | faea9db4b1bba00d73d33b2065ed102f88b76b2c /.emacs.local.d/modes | |
Add emacs config
Diffstat (limited to '.emacs.local.d/modes')
32 files changed, 1274 insertions, 0 deletions
| diff --git a/.emacs.local.d/modes/anzu.el b/.emacs.local.d/modes/anzu.el new file mode 100644 index 0000000..5b1cc64 --- /dev/null +++ b/.emacs.local.d/modes/anzu.el @@ -0,0 +1,8 @@ +;; Debian packages: elpa-anzu + +(use-package anzu +  :ensure t +  :bind (("M-%" . anzu-query-replace) +         ("C-M-%" . anzu-query-replace-regexp)) +  :config +  (global-anzu-mode)) diff --git a/.emacs.local.d/modes/auto-complete.el b/.emacs.local.d/modes/auto-complete.el new file mode 100644 index 0000000..c536b37 --- /dev/null +++ b/.emacs.local.d/modes/auto-complete.el @@ -0,0 +1,13 @@ +;; auto-complete +(require 'auto-complete) +(require 'auto-complete-config) + +;; Debian packages: auto-complete-el + +(add-to-list 'ac-dictionary-directories "/usr/share/auto-complete/dict/") + +(ac-config-default) +(defun auto-complete-mode-maybe () +  "No maybe for you. Only AC!" +  (unless (minibufferp (current-buffer)) +    (auto-complete-mode 1))) diff --git a/.emacs.local.d/modes/auto-fill.el b/.emacs.local.d/modes/auto-fill.el new file mode 100644 index 0000000..dad2831 --- /dev/null +++ b/.emacs.local.d/modes/auto-fill.el @@ -0,0 +1,4 @@ +;; auto-fill mode +(add-hook 'text-mode-hook 'turn-on-auto-fill) +(global-set-key (kbd "C-c q") 'auto-fill-mode) + diff --git a/.emacs.local.d/modes/beancount.el b/.emacs.local.d/modes/beancount.el new file mode 100644 index 0000000..ca5c7c6 --- /dev/null +++ b/.emacs.local.d/modes/beancount.el @@ -0,0 +1,5 @@ +(require 'beancount) + +;; Automatically open .beancount files in beancount-mode. +(add-to-list 'auto-mode-alist '("\\.beancount$" . beancount-mode)) + diff --git a/.emacs.local.d/modes/company.el b/.emacs.local.d/modes/company.el new file mode 100644 index 0000000..dc80b33 --- /dev/null +++ b/.emacs.local.d/modes/company.el @@ -0,0 +1,29 @@ +;; Debian packages: elpa-company +;; Elpa packages: company-quickhelp + +(use-package company +  :ensure t +  :defer t +  :init (global-company-mode) +  :config +  (progn +    ;; Use Company for completion +    (bind-key [remap completion-at-point] #'company-complete company-mode-map) + +    (setq company-tooltip-align-annotations t +          ;; Easy navigation to candidates with M-<n> +          company-show-numbers t) +    (setq company-dabbrev-downcase nil)) +  :diminish company-mode) + +(use-package company-quickhelp          ; Documentation popups for Company +  :ensure t +  :defer t +  :init (add-hook 'global-company-mode-hook #'company-quickhelp-mode)) + +(use-package company-go +  :ensure t +  :defer t +  :init +  (with-eval-after-load 'company +    (add-to-list 'company-backends 'company-go))) diff --git a/.emacs.local.d/modes/dashboard.el b/.emacs.local.d/modes/dashboard.el new file mode 100644 index 0000000..1dc81d3 --- /dev/null +++ b/.emacs.local.d/modes/dashboard.el @@ -0,0 +1,11 @@ +;; Elpa packages: dashboard + +(use-package dashboard +    :ensure t +    :diminish dashboard-mode +    :config +    (setq dashboard-banner-logo-title "Only the educated are free.") +    (setq dashboard-items '((recents  . 10) +                            (projects . 5) +                            (bookmarks . 10))) +    (dashboard-setup-startup-hook)) diff --git a/.emacs.local.d/modes/doom-modeline.el b/.emacs.local.d/modes/doom-modeline.el new file mode 100644 index 0000000..c3b6cc2 --- /dev/null +++ b/.emacs.local.d/modes/doom-modeline.el @@ -0,0 +1,5 @@ +;; Elpa packages: doom-modeline + +(use-package doom-modeline +  :ensure t +  :hook (after-init . doom-modeline-mode)) diff --git a/.emacs.local.d/modes/ecb.el b/.emacs.local.d/modes/ecb.el new file mode 100644 index 0000000..146a75f --- /dev/null +++ b/.emacs.local.d/modes/ecb.el @@ -0,0 +1,21 @@ +;;; activate ecb +(require 'ecb) +(require 'ecb-autoloads) + +(setq ecb-layout-name "left13") +(setq ecb-show-sources-in-directories-buffer 'always) + +;;; activate and deactivate ecb +(global-set-key (kbd "C-x C-;") 'ecb-activate) +(global-set-key (kbd "C-x C-'") 'ecb-deactivate) +;;; show/hide ecb window +(global-set-key (kbd "C-;") 'ecb-show-ecb-windows) +(global-set-key (kbd "C-'") 'ecb-hide-ecb-windows) +;;; quick navigation between ecb windows +(global-set-key (kbd "C-)") 'ecb-goto-window-edit1) +(global-set-key (kbd "C-!") 'ecb-goto-window-directories) +(global-set-key (kbd "C-@") 'ecb-goto-window-sources) +(global-set-key (kbd "C-#") 'ecb-goto-window-methods) +(global-set-key (kbd "C-$") 'ecb-goto-window-compilation) + + diff --git a/.emacs.local.d/modes/eshell.el b/.emacs.local.d/modes/eshell.el new file mode 100644 index 0000000..c9be093 --- /dev/null +++ b/.emacs.local.d/modes/eshell.el @@ -0,0 +1,85 @@ +(setq eshell-history-size 512) +(setq eshell-prompt-regexp "^.*> ") + +(require 'em-hist)			; So the history vars are defined +(if (boundp 'eshell-save-history-on-exit) +    (setq eshell-save-history-on-exit t)) ; Don't ask, just save +(if (boundp 'eshell-ask-to-save-history) +    (setq eshell-ask-to-save-history 'always)) ; For older(?) version + +(defun eshell/ef (fname-regexp &optional dir) +  (ef fname-regexp (or dir default-directory))) + + +;;; ---- path manipulation + +(defun pwd-repl-home (pwd) +  (interactive) +  (let* ((home (expand-file-name (getenv "HOME"))) +	 (home-len (length home))) +    (if (and +	 (>= (length pwd) home-len) +	 (equal home (substring pwd 0 home-len))) +	(concat "~" (substring pwd home-len)) +      pwd))) + +(defun curr-dir-git-branch-string (pwd) +  "Returns current git branch as a string, or the empty string if +PWD is not in a git repo (or the git command is not found)." +  (interactive) +  (when (and (eshell-search-path "git") +             (locate-dominating-file pwd ".git")) +    (let ((git-output (shell-command-to-string (concat "git branch | grep '\\*' | sed -e 's/^\\* //'")))) +      (concat "[g:" +              (if (> (length git-output) 0) +                  (substring git-output 0 -1) +                "(no branch)") +              "] ")))) + +(defun curr-dir-svn-string (pwd) +  (interactive) +  (when (and (eshell-search-path "svn") +             (locate-dominating-file pwd ".svn")) +    (concat "[s:" +            (cond ((string-match-p "/trunk\\(/.*\\)?" pwd) +                   "trunk") +                  ((string-match "/branches/\\([^/]+\\)\\(/.*\\)?" pwd) +                   (match-string 1 pwd)) +                  (t +                   "(no branch)")) +            "] "))) + +(setq eshell-prompt-function +      (lambda () +        (concat +         (or (curr-dir-git-branch-string (eshell/pwd)) +             (curr-dir-svn-string (eshell/pwd))) +         ((lambda (p-lst) +            (if (> (length p-lst) 3) +                (concat +                 (mapconcat (lambda (elm) (if (zerop (length elm)) "" +                                            (substring elm 0 1))) +                            (butlast p-lst 3) +                            "/") +                 "/" +                 (mapconcat (lambda (elm) elm) +                            (last p-lst 3) +                            "/")) +              (mapconcat (lambda (elm) elm) +                         p-lst +                         "/"))) +          (split-string (pwd-repl-home (eshell/pwd)) "/")) +         "> "))) + +;; ; From http://www.emacswiki.org/cgi-bin/wiki.pl/EshellWThirtyTwo +;; ; Return nil, otherwise you'll see the return from w32-shell-execute +;; (defun eshell/open (file) +;;   "Invoke (w32-shell-execute \"Open\" FILE) and substitute slashes for +;; backslashes" +;;   (w32-shell-execute "Open" (substitute ?\\ ?/ (expand-file-name file))) +;;   nil) + +(add-hook 'eshell-mode-hook +	  (lambda () +            (local-set-key "\C-c\C-q" 'eshell-kill-process) +            (local-set-key "\C-c\C-k" 'compile))) diff --git a/.emacs.local.d/modes/flycheck.el b/.emacs.local.d/modes/flycheck.el new file mode 100644 index 0000000..45571e2 --- /dev/null +++ b/.emacs.local.d/modes/flycheck.el @@ -0,0 +1,12 @@ +;; Debian-packages: elpa-flycheck python3-proselint + +(flycheck-define-checker proselint +  "A linter for prose." +  :command ("proselint" source-inplace) +  :error-patterns +  ((warning line-start (file-name) ":" line ":" column ": " +	    (id (one-or-more (not (any " ")))) +	    (message) line-end)) +  :modes (text-mode markdown-mode gfm-mode org-mode)) + +(add-to-list 'flycheck-checkers 'proselint) diff --git a/.emacs.local.d/modes/flyspell.el b/.emacs.local.d/modes/flyspell.el new file mode 100644 index 0000000..8cf27b8 --- /dev/null +++ b/.emacs.local.d/modes/flyspell.el @@ -0,0 +1,12 @@ +(defcustom flyspell-delayed-commands nil +  "List of commands that are \"delayed\" for Flyspell mode. +After these commands, Flyspell checking is delayed for a short time, +whose length is specified by `flyspell-delay'." +  :group 'flyspell +  :type '(repeat (symbol))) + +(setq ispell-dictionary "en") +(setq flyspell-default-dictionary "en") + +(setq flyspell-issue-welcome-flag nil) +(setq-default ispell-list-command "list") diff --git a/.emacs.local.d/modes/go-lang.el b/.emacs.local.d/modes/go-lang.el new file mode 100644 index 0000000..5d43e16 --- /dev/null +++ b/.emacs.local.d/modes/go-lang.el @@ -0,0 +1,23 @@ +;; Debian packages: elpa-go-mode +;; Elpa packages: go-eldoc + +(use-package go-mode +  :ensure t +  :init +  (progn +    (setq gofmt-command "goimports") +    (add-hook 'before-save-hook 'gofmt-before-save) +    (bind-key [remap find-tag] #'godef-jump)) +  :config +  (add-hook 'go-mode-hook 'electric-pair-mode) +  (add-hook 'go-mode-hook 'my-go-mode-hook)) + +(use-package go-eldoc +  :ensure t +  :defer +  :init +  (add-hook 'go-mode-hook 'go-eldoc-setup)) + +;; Define function to call when go-mode loads +(defun my-go-mode-hook () +  (set 'compile-command "go build -v && go test -v && go vet")) diff --git a/.emacs.local.d/modes/helm.el b/.emacs.local.d/modes/helm.el new file mode 100644 index 0000000..55a4c19 --- /dev/null +++ b/.emacs.local.d/modes/helm.el @@ -0,0 +1,22 @@ +(use-package helm +  :bind (("M-x" . helm-M-x) +         ("M-<f5>" . helm-find-files) +         ([f10] . helm-buffers-list) +         ([S-f10] . helm-recentf)) +  :config +  (setq helm-mode-fuzzy-match t) +  (setq helm-completion-in-region-fuzzy-match t) +  ) + + +(setq helm-M-x-fuzzy-match                  t +      helm-bookmark-show-location           t +      helm-buffers-fuzzy-matching           t +      helm-completion-in-region-fuzzy-match t +      helm-file-cache-fuzzy-match           t +      helm-imenu-fuzzy-match                t +      helm-mode-fuzzy-match                 t +      helm-locate-fuzzy-match               t +      helm-quick-update                     t +      helm-recentf-fuzzy-match              t +      helm-semantic-fuzzy-match             t) diff --git a/.emacs.local.d/modes/ibuffer.el b/.emacs.local.d/modes/ibuffer.el new file mode 100644 index 0000000..d5198d8 --- /dev/null +++ b/.emacs.local.d/modes/ibuffer.el @@ -0,0 +1,35 @@ +;; Debian packages: elpa-ibuffer-vc + +(use-package ibuffer                    ; Better buffer list +  :bind (([remap list-buffers] . ibuffer)) +  ;; Show VC Status in ibuffer +  :config (setq ibuffer-formats +                '((mark modified read-only vc-status-mini " " +                        (name 18 18 :left :elide) +                        " " +                        (size 9 -1 :right) +                        " " +                        (mode 16 16 :left :elide) +                        " " +                        (vc-status 16 16 :left) +                        " " +                        filename-and-process) +                  (mark modified read-only " " +                        (name 18 18 :left :elide) +                        " " +                        (size 9 -1 :right) +                        " " +                        (mode 16 16 :left :elide) +                        " " filename-and-process) +                  (mark " " +                        (name 16 -1) +                        " " filename)))) + +(use-package ibuffer-vc                 ; Group buffers by VC project and status +  :ensure t +  :defer t +  :init (add-hook 'ibuffer-hook +                  (lambda () +                    (ibuffer-vc-set-filter-groups-by-vc-root) +                    (unless (eq ibuffer-sorting-mode 'alphabetic) +                      (ibuffer-do-sort-by-alphabetic))))) diff --git a/.emacs.local.d/modes/ido.el b/.emacs.local.d/modes/ido.el new file mode 100644 index 0000000..8b475f9 --- /dev/null +++ b/.emacs.local.d/modes/ido.el @@ -0,0 +1,19 @@ +;; Debian packages: elpa-flx-ido elpa-ido-vertical-mode elpa-ido-completing-read+ + +(require 'ido) +(ido-mode t) + +(require 'flx-ido) +(ido-mode 1) +(ido-everywhere 1) +(flx-ido-mode 1) +;; disable ido faces to see flx highlights. +(setq ido-enable-flex-matching t) +(setq ido-use-faces nil) + +(require 'ido-vertical-mode) +(ido-vertical-mode 1) +(setq ido-vertical-define-keys 'C-n-and-C-p-only) + +(require 'ido-completing-read+) + diff --git a/.emacs.local.d/modes/imenu.el b/.emacs.local.d/modes/imenu.el new file mode 100644 index 0000000..1a2b29b --- /dev/null +++ b/.emacs.local.d/modes/imenu.el @@ -0,0 +1,12 @@ +;; Debian packages: elpa-imenu-list +(use-package imenu-list +  :ensure t +  :bind ("C-." . imenu-list-minor-mode) +  :config +  (setq imenu-list-focus-after-activation t) +  (setq imenu-list-size 0.2) +  (setq imenu-list-position 'left) +  (add-hook 'go-mode-hook #'imenu-list-minor-mode)) + + + diff --git a/.emacs.local.d/modes/latex.el b/.emacs.local.d/modes/latex.el new file mode 100644 index 0000000..de4de1f --- /dev/null +++ b/.emacs.local.d/modes/latex.el @@ -0,0 +1,9 @@ +(add-hook 'latex-mode-hook 'flyspell-mode) +(setq TeX-PDF-mode t) + +(defun pdfevince () +  (add-to-list 'TeX-output-view-style +		'("^pdf$" "." "evince %o %(outpage)"))) + +(add-hook  'LaTeX-mode-hook  'pdfevince  t) ; AUCTeX LaTeX mode + diff --git a/.emacs.local.d/modes/linum.el b/.emacs.local.d/modes/linum.el new file mode 100644 index 0000000..8df9986 --- /dev/null +++ b/.emacs.local.d/modes/linum.el @@ -0,0 +1,3 @@ +;(require 'linum-relative) + +(add-hook 'go-mode-hook #'linum-mode) diff --git a/.emacs.local.d/modes/magit.el b/.emacs.local.d/modes/magit.el new file mode 100644 index 0000000..e1ca63f --- /dev/null +++ b/.emacs.local.d/modes/magit.el @@ -0,0 +1,15 @@ +;; Debian packages: elpa-magit elpa-magithub + +(use-package magit +  :ensure t +  :defer t +  :bind (("C-x g" . magit-status)) +  :config +  (progn +    (defun inkel/magit-log-edit-mode-hook () +      (flyspell-mode t) +      (turn-on-auto-fill)) +    (defadvice magit-status (around magit-fullscreen activate) +      (window-configuration-to-register :magit-fullscreen) +      ad-do-it +      (delete-other-windows)))) diff --git a/.emacs.local.d/modes/mail-mode.el b/.emacs.local.d/modes/mail-mode.el new file mode 100644 index 0000000..c10cd81 --- /dev/null +++ b/.emacs.local.d/modes/mail-mode.el @@ -0,0 +1,10 @@ +(add-to-list 'auto-mode-alist '("/mutt" . mail-mode)) +(add-hook 'mail-mode-hook +          (lambda () +            (font-lock-add-keywords nil +                                    '(("^[ \t]*>[ \t]*>[ \t]*>.*$" +                                       (0 'compilation-error)) +                                      ("^[ \t]*>[ \t]*>.*$" +                                       (0 'compilation-column-number)) +                                      ("^[ \t]*>.*$" +                                       (0 'comint-highlight-prompt)))))) diff --git a/.emacs.local.d/modes/markdown.el b/.emacs.local.d/modes/markdown.el new file mode 100644 index 0000000..f035509 --- /dev/null +++ b/.emacs.local.d/modes/markdown.el @@ -0,0 +1,5 @@ +(autoload 'markdown-mode "markdown-mode.el" +  "Major mode for editing Markdown files" t) + +(setq auto-mode-alist +      (cons '("\\.mdwn" . markdown-mode) auto-mode-alist)) diff --git a/.emacs.local.d/modes/mu4e.el b/.emacs.local.d/modes/mu4e.el new file mode 100644 index 0000000..da8b7c8 --- /dev/null +++ b/.emacs.local.d/modes/mu4e.el @@ -0,0 +1,61 @@ +(require 'mu4e) + +;; sending mail +(setq message-send-mail-function 'message-send-mail-with-sendmail +      sendmail-program "/home/lur/bin/te-msmtp" +      user-mail-address "raul@thousandeyes.com" +      user-full-name "Raúl Benencia") + +(setq mu4e-user-mail-address-list (list "raul@thousandeyes.com")) + +(setq message-kill-buffer-on-exit t) +;; Use fancy chars +(setq mu4e-use-fancy-chars t) +;; don't save message to Sent Messages, Gmail/IMAP takes care of this +(setq mu4e-sent-messages-behavior 'delete) +(setq mu4e-update-interval 60)               ;; update every 5 minutes + +;; use 'fancy' non-ascii characters in various places in mu4e +;;(setq mu4e-use-fancy-chars t) + +(setq relevant-maildirs " (maildir:/INBOX OR maildir:/jira OR maildir:/news OR maildir:/git)") +(mu4e-alert-enable-notifications) +(mu4e-alert-set-default-style 'libnotify) +(setq mu4e-alert-interesting-mail-query +      (concat "flag:unread" +              " AND NOT flag:trashed" +              " AND" relevant-maildirs)) + +(mu4e-alert-set-default-style 'libnotify) +;;(add-hook 'after-init-hook #'mu4e-alert-enable-notifications) +(add-hook 'after-init-hook #'mu4e-alert-enable-mode-line-display) + +(setq mu4e-bookmarks +  `(,(make-mu4e-bookmark +       :name  "INBOX" +       :query "maildir:/INBOX" +       :key ?i) +    ,(make-mu4e-bookmark +       :name  "Unread messages" +       :query (concat "flag:unread AND NOT flag:trashed AND" relevant-maildirs) +       :key ?u) +     ,(make-mu4e-bookmark +       :name "Today's messages" +       :query (concat "date:today..now AND" relevant-maildirs) +       :key ?t) +     ,(make-mu4e-bookmark +       :name "Last 7 days" +       :query (concat "date:7d..now AND" relevant-maildirs) +       :key ?w) +     ,(make-mu4e-bookmark +       :name "Today's unread logs " +       :query (concat "date:today..now flag:unread AND NOT" relevant-maildirs) +       :key ?l) +     ,(make-mu4e-bookmark +       :name "Today's logs " +       :query (concat "date:today..now AND NOT maildir:/fim AND NOT" relevant-maildirs) +       :key ?l)) +) + +;; (require 'mu4e-maildirs-extension) +;; (mu4e-maildirs-extension) diff --git a/.emacs.local.d/modes/notmuch.el b/.emacs.local.d/modes/notmuch.el new file mode 100644 index 0000000..f5096c8 --- /dev/null +++ b/.emacs.local.d/modes/notmuch.el @@ -0,0 +1,105 @@ +;; -------- +;; notmuch mode +;; -------- +(require 'notmuch) + +;; This should be upstream +(require 'notmuch-show) +(require 'notmuch-tag) +(defun notmuch-tree-show-message-in () +  "Show the current message (in split-pane)." +  (interactive) +  (let ((id (notmuch-tree-get-message-id)) +        (inhibit-read-only t) +        buffer) +    (when id +      ;; We close and reopen the window to kill off un-needed buffers +      ;; this might cause flickering but seems ok. +      (notmuch-tree-close-message-window) +      (setq notmuch-tree-message-window +            (split-window-vertically (/ (window-height) 4))) +      (with-selected-window notmuch-tree-message-window +        ;; Since we are only displaying one message do not indent. +        (let ((notmuch-show-indent-messages-width 0) +              (notmuch-show-only-matching-messages t)) +          (setq buffer (notmuch-show id)))) +      ;; We need the `let' as notmuch-tree-message-window is buffer local. +      (let ((window notmuch-tree-message-window)) +        (with-current-buffer buffer +          (setq notmuch-tree-message-window window) +          (add-hook 'kill-buffer-hook 'notmuch-tree-message-window-kill-hook))) +      (when notmuch-show-mark-read-tags +        (notmuch-tree-tag-update-display notmuch-show-mark-read-tags) +        (notmuch-tree-tag notmuch-show-mark-read-tags)) +      (setq notmuch-tree-message-buffer buffer)))) +;; End upstream + +(define-key notmuch-show-mode-map "S" +  (lambda () +    "mark message as spam" +    (interactive) +    (notmuch-show-tag (list "+spam" "-inbox" "-unread")))) + +(define-key notmuch-search-mode-map "S" +  (lambda (&optional beg end) +    "mark thread as spam" +    (interactive (notmuch-search-interactive-region)) +    (notmuch-search-tag (list "+spam" "-inbox" "-unread") beg end))) + +(define-key notmuch-search-mode-map "R" +  (lambda (&optional beg end) +    "mark thread as read" +    (interactive (notmuch-search-interactive-region)) +    (notmuch-search-tag (list "-unread") beg end) +    (notmuch-search-next-thread))) + +(define-key notmuch-search-mode-map (kbd "RET") +  (lambda () +    "Show the selected thread with notmuch-tree if it has more +than one email. Use notmuch-show otherwise." +    (interactive) +    (if (= (plist-get (notmuch-search-get-result) :total) 1) +        (notmuch-search-show-thread) +      (notmuch-tree (notmuch-search-find-thread-id) +                    notmuch-search-query-string +                    nil +                    (notmuch-prettify-subject (notmuch-search-find-subject)))))) + +(setq notmuch-folders '(("inbox" . "tag:inbox") +                        ("debian-announce" . "tag:inbox AND tag:debian-announce") +                        ("debian-devel" . "tag:inbox AND tag:debian-devel") +                        ("debian-haskell" . "tag:inbox AND tag:debian-haskell") +                        )) + +(defun color-inbox-if-unread () (interactive) +       (save-excursion +         (goto-char (point-min)) +         (let ((cnt (car (process-lines "notmuch" "count" "tag:inbox and tag:unread")))) +           (when (> (string-to-number cnt) 0) +             (save-excursion +               (when (search-forward "inbox" (point-max) t) +                 (let* ((overlays (overlays-in (match-beginning 0) (match-end 0))) +                        (overlay (car overlays))) +                   (when overlay +                     (overlay-put overlay 'face '((:inherit bold) (:foreground "green"))))))))))) +(add-hook 'notmuch-hello-refresh-hook 'color-inbox-if-unread) + +(defun my-notmuch-show-view-as-patch () +  "View the the current message as a patch." +  (interactive) +  (let* ((id (notmuch-show-get-message-id)) +         (subject (concat "Subject: " (notmuch-show-get-subject) "\n")) +         (diff-default-read-only t) +         (buf (get-buffer-create (concat "*notmuch-patch-" id "*"))) +         (map (make-sparse-keymap))) +    (define-key map "q" 'notmuch-kill-this-buffer) +    (switch-to-buffer buf) +    (let ((inhibit-read-only t)) +      (erase-buffer) +      (insert subject) +      (insert (notmuch-get-bodypart-internal id 1 nil))) +    (set-buffer-modified-p nil) +    (diff-mode) +    (lexical-let ((new-ro-bind (cons 'buffer-read-only map))) +      (add-to-list 'minor-mode-overriding-map-alist new-ro-bind)) +    (goto-char (point-min)))) diff --git a/.emacs.local.d/modes/org.el b/.emacs.local.d/modes/org.el new file mode 100644 index 0000000..f01718d --- /dev/null +++ b/.emacs.local.d/modes/org.el @@ -0,0 +1,676 @@ +;; Debian packages: elpa-org elpa-org-bullets + +(require 'org-capture) +(require 'org-protocol) +(require 'org-habit) +(require 'org-bullets) + +;; -------- +;; Org mode +;; -------- + +(require 'org) + +(setq org-agenda-files '("~/src/git/org/")) +(setq org-cycle-separator-lines 0) +(setq org-startup-indented t) +(setq org-hide-leading-stars nil) + +(setq org-startup-indented t +      org-bullets-bullet-list '(" ") ;; no bullets, needs org-bullets package +      org-ellipsis "  " ;; folding symbol +      org-pretty-entities t +      org-hide-emphasis-markers t +      ;; show actually italicized text instead of /italicized text/ +      org-agenda-block-separator "" +      org-fontify-whole-heading-line t +      org-fontify-done-headline t +      org-fontify-quote-and-verse-blocks t) + + +;; ORG BINDINGS ;; +(global-set-key (kbd "<f12>") 'org-agenda) +(global-set-key (kbd "<f5>") 'bh/org-todo) +(global-set-key (kbd "<f8>") 'org-clock-goto) + +(global-set-key (kbd "<f9> I") 'bh/punch-in) +(global-set-key (kbd "<f9> O") 'bh/punch-out) + + +;; ORG STATES ;; +(setq org-todo-keywords +      (quote ((sequence "TODO(t)" "NEXT(n)" "|" "DONE(d)") +              (sequence "WAITING(w@/!)" "HOLD(h@/!)" "|" "CANCELLED(c@/!)" "PHONE" "MEETING")))) + + +(setq org-use-fast-todo-selection t) + +(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"))))) + +(setq org-enforce-todo-dependencies t) +(setq org-log-done (quote time)) +(setq org-log-redeadline (quote time)) +(setq org-log-reschedule (quote time)) + +;; CAPTURE ;; +(setq org-default-notes-file "~/src/git/org/refile.org") + +;; I use C-c c to start capture mode +(global-set-key (kbd "C-c c") 'org-capture) + +;; Capture templates for: TODO tasks, Notes, appointments, phone calls, meetings, and org-protocol +(setq org-capture-templates +      (quote (("t" "todo" entry (file "~/src/git/org/refile.org") +               "* TODO %?\n%U\n%a\n" :clock-in t :clock-resume t) +              ("r" "respond" entry (file "~/src/git/org/refile.org") +               "* 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 "~/src/git/org/refile.org") +               "* %? :NOTE:\n%U\n%a\n" :clock-in t :clock-resume t) +              ("j" "Journal" entry (file+datetree "~/src/git/org/diary.org") +               "* %?\n%U\n" :clock-in t :clock-resume t) +              ("w" "org-protocol" entry (file "~/src/git/org/refile.org") +               "* TODO Review %c\n%U\n" :immediate-finish t) +              ("m" "Meeting" entry (file "~/src/git/org/refile.org") +               "* MEETING with %? :MEETING:\n%U" :clock-in t :clock-resume t) +              ("p" "Phone call" entry (file "~/src/git/org/refile.org") +               "* PHONE %? :PHONE:\n%U" :clock-in t :clock-resume t) +              ("h" "Habit" entry (file "~/src/git/org/refile.org") +               "* NEXT %?\n%U\n%a\nSCHEDULED: %(format-time-string \"%<<%Y-%m-%d %a .+1d/3d>>\")\n:PROPERTIES:\n:STYLE: habit\n:REPEAT_TO_STATE: NEXT\n:END:\n")))) + +;; Remove empty LOGBOOK drawers on clock out +(defun bh/remove-empty-drawer-on-clock-out () +  (interactive) +  (save-excursion +    (beginning-of-line 0) +    (org-remove-empty-drawer-at "LOGBOOK" (point)))) + +(add-hook 'org-clock-out-hook 'bh/remove-empty-drawer-on-clock-out 'append) + +(add-hook 'org-capture-mode-hook 'delete-other-windows) +(setq my-org-protocol-flag nil) +(defadvice org-capture-finalize (after delete-frame-at-end activate) +  "Delete frame at remember finalization" +  (progn (if my-org-protocol-flag (delete-frame)) +         (setq my-org-protocol-flag nil))) + +(defadvice org-capture-kill (after delete-frame-at-end activate) +  "Delete frame at remember abort" +  (progn (if my-org-protocol-flag (delete-frame)) +         (setq my-org-protocol-flag nil))) + +(defadvice org-protocol-capture (before set-org-protocol-flag activate) +  (setq my-org-protocol-flag t)) + + +;; REFILE ;; + +; Targets include this file and any file contributing to the agenda - up to 9 levels deep +(setq org-refile-targets (quote ((nil :maxlevel . 9) +                                 (org-agenda-files :maxlevel . 9)))) + +; Exclude DONE state tasks from refile targets +(defun bh/verify-refile-target () +  "Exclude todo keywords with a done state from refile targets" +  (not (member (nth 2 (org-heading-components)) org-done-keywords))) + +(setq org-refile-target-verify-function 'bh/verify-refile-target) + +; Targets complete directly with IDO +(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)) + +;; AGENDA VIEW ;; + + +;; 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/!" +                           ((org-agenda-overriding-header "Stuck Projects") +                            (org-agenda-skip-function 'bh/skip-non-stuck-projects) +                            (org-agenda-sorting-strategy +                             '(category-keep)))) +                (tags-todo "-HOLD-CANCELLED/!" +                           ((org-agenda-overriding-header "Projects") +                            (org-agenda-skip-function 'bh/skip-non-projects) +                            (org-tags-match-list-sublevels 'indented) +                            (org-agenda-sorting-strategy +                             '(category-keep)))) +                (tags-todo "-CANCELLED/!NEXT" +                           ((org-agenda-overriding-header (concat "Project Next Tasks" +                                                                  (if bh/hide-scheduled-and-waiting-next-tasks +                                                                      "" +                                                                    " (including WAITING and SCHEDULED tasks)"))) +                            (org-agenda-skip-function 'bh/skip-projects-and-habits-and-single-tasks) +                            (org-tags-match-list-sublevels t) +                            (org-agenda-todo-ignore-scheduled bh/hide-scheduled-and-waiting-next-tasks) +                            (org-agenda-todo-ignore-deadlines bh/hide-scheduled-and-waiting-next-tasks) +                            (org-agenda-todo-ignore-with-date bh/hide-scheduled-and-waiting-next-tasks) +                            (org-agenda-sorting-strategy +                             '(todo-state-down effort-up category-keep)))) +                (tags-todo "-REFILE-CANCELLED-WAITING-HOLD/!" +                           ((org-agenda-overriding-header (concat "Project Subtasks" +                                                                  (if bh/hide-scheduled-and-waiting-next-tasks +                                                                      "" +                                                                    " (including WAITING and SCHEDULED tasks)"))) +                            (org-agenda-skip-function 'bh/skip-non-project-tasks) +                            (org-agenda-todo-ignore-scheduled bh/hide-scheduled-and-waiting-next-tasks) +                            (org-agenda-todo-ignore-deadlines bh/hide-scheduled-and-waiting-next-tasks) +                            (org-agenda-todo-ignore-with-date bh/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 bh/hide-scheduled-and-waiting-next-tasks +                                                                      "" +                                                                    " (including WAITING and SCHEDULED tasks)"))) +                            (org-agenda-skip-function 'bh/skip-project-tasks) +                            (org-agenda-todo-ignore-scheduled bh/hide-scheduled-and-waiting-next-tasks) +                            (org-agenda-todo-ignore-deadlines bh/hide-scheduled-and-waiting-next-tasks) +                            (org-agenda-todo-ignore-with-date bh/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 bh/hide-scheduled-and-waiting-next-tasks +                                                                      "" +                                                                    " (including WAITING and SCHEDULED tasks)"))) +                            (org-agenda-skip-function 'bh/skip-non-tasks) +                            (org-tags-match-list-sublevels nil) +                            (org-agenda-todo-ignore-scheduled bh/hide-scheduled-and-waiting-next-tasks) +                            (org-agenda-todo-ignore-deadlines bh/hide-scheduled-and-waiting-next-tasks))) +                (tags "-REFILE/" +                      ((org-agenda-overriding-header "Tasks to Archive") +                       (org-agenda-skip-function 'bh/skip-non-archivable-tasks) +                       (org-tags-match-list-sublevels nil)))) +               nil)))) + +(defun bh/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) +              nil +            (or subtree-end (point-max))) +        next-headline)))) + +(defun bh/org-auto-exclude-function (tag) +  "Automatic task exclusion in the agenda with / RET" +  (and (cond +        ((string= tag "hold") +         t)) +       (concat "-" tag))) + +(setq org-agenda-auto-exclude-function 'bh/org-auto-exclude-function) +(setq org-agenda-span 'day) +(setq org-deadline-warning-days 30) + + +(defun bh/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 bh/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 +      (bh/find-project-task) +      (if (equal (point) task) +          nil +        t)))) + +(defun bh/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 bh/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 bh/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 bh/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 bh/hide-scheduled-and-waiting-next-tasks t) + +(defun bh/toggle-next-task-display () +  (interactive) +  (setq bh/hide-scheduled-and-waiting-next-tasks (not bh/hide-scheduled-and-waiting-next-tasks)) +  (when  (equal major-mode 'org-agenda-mode) +    (org-agenda-redo)) +  (message "%s WAITING and SCHEDULED NEXT Tasks" (if bh/hide-scheduled-and-waiting-next-tasks "Hide" "Show"))) + +(defun bh/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 (bh/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 bh/skip-non-stuck-projects () +  "Skip trees that are not stuck projects" +  ;; (bh/list-sublevels-for-projects-indented) +  (save-restriction +    (widen) +    (let ((next-headline (save-excursion (or (outline-next-heading) (point-max))))) +      (if (bh/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 bh/skip-non-projects () +  "Skip trees that are not projects" +  ;; (bh/list-sublevels-for-projects-indented) +  (if (save-excursion (bh/skip-non-stuck-projects)) +      (save-restriction +        (widen) +        (let ((subtree-end (save-excursion (org-end-of-subtree t)))) +          (cond +           ((bh/is-project-p) +            nil) +           ((and (bh/is-project-subtree-p) (not (bh/is-task-p))) +            nil) +           (t +            subtree-end)))) +    (save-excursion (org-end-of-subtree t)))) + +(defun bh/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 +       ((bh/is-task-p) +        nil) +       (t +        next-headline))))) + +(defun bh/skip-project-trees-and-habits () +  "Skip trees that are projects" +  (save-restriction +    (widen) +    (let ((subtree-end (save-excursion (org-end-of-subtree t)))) +      (cond +       ((bh/is-project-p) +        subtree-end) +       ((org-is-habit-p) +        subtree-end) +       (t +        nil))))) + +(defun bh/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 bh/hide-scheduled-and-waiting-next-tasks +             (member "WAITING" (org-get-tags-at))) +        next-headline) +       ((bh/is-project-p) +        next-headline) +       ((and (bh/is-task-p) (not (bh/is-project-subtree-p))) +        next-headline) +       (t +        nil))))) + +(defun bh/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 +       ((bh/is-project-p) +        next-headline) +       ((org-is-habit-p) +        subtree-end) +       ((and (not limit-to-project) +             (bh/is-project-subtree-p)) +        subtree-end) +       ((and limit-to-project +             (bh/is-project-subtree-p) +             (member (org-get-todo-state) (list "NEXT"))) +        subtree-end) +       (t +        nil))))) + +(defun bh/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 +       ((bh/is-project-p) +        subtree-end) +       ((org-is-habit-p) +        subtree-end) +       ((bh/is-project-subtree-p) +        subtree-end) +       (t +        nil))))) + +(defun bh/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 +       ((bh/is-project-p) +        next-headline) +       ((org-is-habit-p) +        subtree-end) +       ((and (bh/is-project-subtree-p) +             (member (org-get-todo-state) (list "NEXT"))) +        subtree-end) +       ((not (bh/is-project-subtree-p)) +        subtree-end) +       (t +        nil))))) + +(defun bh/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 +       ((bh/is-project-p) +        subtree-end) +       ((org-is-habit-p) +        subtree-end) +       (t +        nil))))) + +(defun bh/skip-non-subprojects () +  "Skip trees that are not projects" +  (let ((next-headline (save-excursion (outline-next-heading)))) +    (if (bh/is-subproject-p) +        nil +      next-headline))) + +;; CLOCKING ;; +;; 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 'bh/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 bh/keep-clock-running nil) + +(defun bh/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")) +           (bh/is-task-p)) +      "NEXT") +     ((and (member (org-get-todo-state) (list "NEXT")) +           (bh/is-project-p)) +      "TODO")))) + +(defun bh/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 bh/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 bh/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)) +          (bh/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)) +        (bh/clock-in-organization-task-as-default))))) + +(defun bh/punch-out () +  (interactive) +  (setq bh/keep-clock-running nil) +  (when (org-clock-is-active) +    (org-clock-out)) +  (org-agenda-remove-restriction-lock)) + +(defun bh/clock-in-default-task () +  (save-excursion +    (org-with-point-at org-clock-default-task +      (org-clock-in)))) + +(defun bh/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 bh/keep-clock-running +            (bh/clock-in-default-task))))))) + +(defvar bh/organization-task-id "eb155a82-92b2-4f25-a3c6-0304591af2f9") + +(defun bh/clock-in-organization-task-as-default () +  (interactive) +  (org-with-point-at (org-id-find bh/organization-task-id 'marker) +    (org-clock-in '(16)))) + +(defun bh/clock-out-maybe () +  (when (and bh/keep-clock-running +             (not org-clock-clocking-in) +             (marker-buffer org-clock-default-task) +             (not org-clock-resolving-clocks-due-to-idleness)) +    (bh/clock-in-parent-task))) + +(add-hook 'org-clock-out-hook 'bh/clock-out-maybe 'append) + + +;; ORG REPORTS ;; +; Set default column view headings: Task Effort Clock_Summary +(setq org-columns-default-format "%80ITEM(Task) %10Effort(Effort){:} %10CLOCKSUM") + +(defun my-org-clocktable-indent-string (level) +  (if (= level 1) +      "" +    (let ((str "^")) +      (while (> level 2) +        (setq level (1- level) +              str (concat str "--"))) +      (concat str "-> ")))) + +(advice-add 'org-clocktable-indent-string :override #'my-org-clocktable-indent-string) + +(setq org-clock-clocktable-default-properties '(:maxlevel 4 :scope file :formula %)) + +; 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")))) + +;; Agenda log mode items to display (closed and state changes by default) +(setq org-agenda-log-mode-items (quote (closed state))) + +;; TAGS ;; +; Tags with fast selection keys +(setq org-tag-alist (quote ((:startgroup) +                            ("@errand" . ?e) +                            ("@office" . ?o) +                            ("@home" . ?H) +                            (:endgroup) +                            ("WAITING" . ?w) +                            ("HOLD" . ?h) +                            ("PERSONAL" . ?P) +                            ("WORK" . ?W) +                            ("ORG" . ?O) +                            ("NOTE" . ?n) +                            ("CANCELLED" . ?c) +                            ("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) + +(require 'ox-extra) +(ox-extras-activate '(ignore-headlines)) + +(add-to-list 'org-latex-classes +             '("memoir-article" +               "\\documentclass[11pt,oneside,article]{memoir} +                [PACKAGES] +                \\usepackage{memoir-article-style} +                [NO-DEFAULT-PACKAGES]" +               ("\\section{%s}" . "\\section*{%s}") +               ("\\subsection{%s}" . "\\subsection*{%s}") +               ("\\subsubsection{%s}" . "\\subsubsection*{%s}") +               ("\\paragraph{%s}" . "\\paragraph*{%s}") +               ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))) diff --git a/.emacs.local.d/modes/package.el b/.emacs.local.d/modes/package.el new file mode 100644 index 0000000..acbfc21 --- /dev/null +++ b/.emacs.local.d/modes/package.el @@ -0,0 +1,7 @@ +(require 'package) ;; You might already have this line + +(add-to-list 'package-archives +             '("melpa-stable" . "https://stable.melpa.org/packages/") t) + +(package-initialize) ;; You might already have this line + diff --git a/.emacs.local.d/modes/projectile.el b/.emacs.local.d/modes/projectile.el new file mode 100644 index 0000000..f5f8097 --- /dev/null +++ b/.emacs.local.d/modes/projectile.el @@ -0,0 +1,3 @@ +;; Debian packages: elpa-projectile + +(projectile-global-mode) diff --git a/.emacs.local.d/modes/smex.el b/.emacs.local.d/modes/smex.el new file mode 100644 index 0000000..d724452 --- /dev/null +++ b/.emacs.local.d/modes/smex.el @@ -0,0 +1,15 @@ +;; Debian packages: elpa-smex +;; Elpa packages: helm-smex + +(require 'smex) ; Not needed if you use package.el +(smex-initialize) ; Can be omitted. This might cause a (minimal) delay +                                        ; when Smex is auto-initialized on its first run. + +(require 'helm-smex) +(global-set-key [remap execute-extended-command] #'helm-smex) +(global-set-key (kbd "M-X") #'helm-smex-major-mode-commands) + +;; (global-set-key (kbd "M-x") 'smex) +;; (global-set-key (kbd "M-X") 'smex-major-mode-commands) +;; This is your old M-x. +(global-set-key (kbd "C-c C-c M-x") 'execute-extended-command) diff --git a/.emacs.local.d/modes/sml.el b/.emacs.local.d/modes/sml.el new file mode 100644 index 0000000..247d9b2 --- /dev/null +++ b/.emacs.local.d/modes/sml.el @@ -0,0 +1,7 @@ +;; Debian packages: elpa-smart-mode-line elpa-smart-mode-line-powerline-theme + +(use-package smart-mode-line +  :ensure t +  :config +  (setq sml/theme 'respectful) +  (sml/setup)) diff --git a/.emacs.local.d/modes/sublimity.el b/.emacs.local.d/modes/sublimity.el new file mode 100644 index 0000000..a702a22 --- /dev/null +++ b/.emacs.local.d/modes/sublimity.el @@ -0,0 +1,8 @@ +;; Elpa packages: sublimity + +(require 'sublimity) +(require 'sublimity-scroll) +;(require 'sublimity-map) +;(require 'sublimity-attractive) + +(sublimity-mode 1) diff --git a/.emacs.local.d/modes/themes.el b/.emacs.local.d/modes/themes.el new file mode 100644 index 0000000..c6e9bc2 --- /dev/null +++ b/.emacs.local.d/modes/themes.el @@ -0,0 +1,6 @@ +;; Debian packages: elpa-clues-theme elpa-monokai-theme elpa-smart-mode-line-powerline-theme elpa-solarized-theme elpa-zenburn-theme +;; Elpa packages: atom-one-dark + +(load-theme 'clues t) + + diff --git a/.emacs.local.d/modes/whitespace.el b/.emacs.local.d/modes/whitespace.el new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/.emacs.local.d/modes/whitespace.el @@ -0,0 +1 @@ + diff --git a/.emacs.local.d/modes/writeroom.el b/.emacs.local.d/modes/writeroom.el new file mode 100644 index 0000000..ba700a1 --- /dev/null +++ b/.emacs.local.d/modes/writeroom.el @@ -0,0 +1,27 @@ +(use-package writeroom-mode +  :defer t +  :config +  (setq writeroom-width 140 +        writeroom-mode-line nil +        writeroom-global-effects '(writeroom-set-bottom-divider-width +                                   writeroom-set-internal-border-width +                                   (lambda (arg) +                                     (let ((langs '("python" +                                                    "emacs-lisp" +                                                    "common-lisp" +                                                    "js" +                                                    "ruby"))) +                                       (cond +                                        ((= arg 1) +                                         (progn +                                           (setq org-src-block-faces +                                                 (mapcar (lambda (lang) (list lang '(:family "Source Code Pro" :height 0.8))) langs)) +                                           (normal-mode) +                                           (variable-pitch-mode))) +                                        ((= arg -1) +                                         (progn +                                           (setq org-src-block-faces +                                                 (mapcar (lambda (lang) (list lang '(:family "Source Code Pro" :height 1.0))) langs)) +                                           (normal-mode) +                                           (variable-pitch-mode) +(variable-pitch-mode))))))))) | 
