(setq use-package-verbose t)dotfiles-dir is now set in init.el.
(add-to-list 'load-path (concat dotfiles-dir "lisp/"))
(add-to-list 'load-path (concat dotfiles-dir "elpa/"))(use-package exec-path-from-shell
:ensure t
:if (memq window-system '(mac ns x))
:config
(exec-path-from-shell-initialize))(require 'package)
(add-to-list 'package-archives
'("melpa" . "https://melpa.org/packages/")
'("marmalade" .
"http://marmalade-repo.org/packages/"))
(with-eval-after-load 'package (add-to-list 'package-archives '("nongnu" . "https://elpa.nongnu.org/nongnu/")))
; (add-to-list 'package-archives '("org" . "https://orgmode.org/elpa/") t)
; (package-refresh-contents)
; (package-initialize); custom files for M-x customize
(setq custom-file (concat dotfiles-dir "custom.el"))
(load custom-file)(when (not (require 'use-package nil t))
(package-refresh-contents)
(package-install 'use-package))
(require 'use-package)
(require 'use-package-ensure) ;install packages by default
(setq use-package-always-ensure t)Diminish will hide stuff from the mode line. Use-package supports :diminsh if diminish is supported.
(use-package diminish)
(diminish 'eldoc-mode)
(diminish 'visual-line-mode)
(diminish 'flyspell-mode) ; server
(server-start)
(use-package edit-server
:config (edit-server-start))(global-set-key "\M-/" 'hippie-expand) (use-package helm
:diminish
:bind (("C-x C-f" . helm-find-files)
("M-x" . helm-M-x)
("C-x r b" . helm-filtered-bookmarks)
("C-x b" . 'helm-mini))
:config (progn
(helm-mode 1)))(use-package helm-descbinds
:config (helm-descbinds-mode))(setq inhibit-startup-message t
inhibit-startup-echo-area-message t)(setq backup-directory-alist
`((".*" . ,temporary-file-directory)))
(setq auto-save-file-name-transforms
`((".*" ,temporary-file-directory t))) ; http://nileshk.com/2009/06/13/prompt-before-closing-emacs.html
(defun ask-before-closing ()
"Ask whether or not to close, and then close if y was pressed"
(interactive)
(if (y-or-n-p (format "Are you sure you want to exit Emacs? "))
(if (< emacs-major-version 22)
(save-buffers-kill-terminal)
(save-buffers-kill-emacs))
(message "Canceled exit")))
(when window-system
(global-set-key (kbd "C-x C-c") 'ask-before-closing))
From http://pragmaticemacs.com/emacs/dont-kill-buffer-kill-this-buffer-instead/:
(defun bjm/kill-this-buffer ()
"Kill the current buffer."
(interactive)
(kill-buffer (current-buffer)))
(global-set-key (kbd "C-x k") 'bjm/kill-this-buffer) ; http://www-cdf.fnal.gov/~sthrlnd/emacs_help.html:
;; Kills all them buffers except scratch
;; obtained from http://www.chrislott.org/geek/emacs/dotemacs.xhtml
(defun nuke-all-buffers ()
"kill all buffers, leaving *scratch* only"
(interactive)
(delete-other-frames)
(delete-other-windows)
(mapcar (lambda (x) (kill-buffer x))
(buffer-list))
) ; removing because I lost files due to this I think
(global-auto-revert-mode t)
From https://www.masteringemacs.org/article/working-coding-systems-unicode-emacs:
(prefer-coding-system 'utf-8)
(set-default-coding-systems 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
;; backwards compatibility as default-buffer-file-coding-system
;; is deprecated in 23.2.
(if (boundp 'buffer-file-coding-system)
(setq-default buffer-file-coding-system 'utf-8)
(setq default-buffer-file-coding-system 'utf-8))
;; Treat clipboard input as UTF-8 string first; compound text next, etc.
(setq x-select-request-type '(UTF8_STRING COMPOUND_TEXT TEXT STRING))From http://pragmaticemacs.com/emacs/add-the-system-clipboard-to-the-emacs-kill-ring/:
(setq save-interprogram-paste-before-kill t)Removed <2020-08-09 Sun> because I need M-up and M-down for org-mode reorganization
(subword-mode 1) ; FAQ 5.50--only one space after period
(setq sentence-end-double-space nil)
; http://pragmaticemacs.com/emacs/cycle-spacing/
(global-set-key (kbd "M-SPC") 'cycle-spacing)sort directories at the top:
(defun mydired-sort ()
"Sort dired listings with directories first."
(save-excursion
(let (buffer-read-only)
(forward-line 2) ;; beyond dir. header
(sort-regexp-fields t "^.*$" "[ ]*." (point) (point-max)))
(set-buffer-modified-p nil)))
(defadvice dired-readin
(after dired-after-updating-hook first () activate)
"Sort dired listings with directories first before adding marks."
(mydired-sort))DWIM:
(setq dired-dwim-target t)Guess shell commands using dired-x:
(require 'dired-x);; Behave like vi's O command
(defun open-previous-line (arg)
"Open a new line before the current one.
See also `newline-and-indent'."
(interactive "p")
(beginning-of-line)
(open-line arg)
(when newline-and-indent
(indent-according-to-mode)))
(defvar newline-and-indent t
"Modify the behavior of the open-*-line functions to cause them to autoindent.")
(global-set-key (kbd "M-o") 'open-previous-line)(save-place-mode 1);; (use-package multiple-cursors
;; :bind (("C-c m c" . 'mc/edit-lines))
;; )(defun unfill-paragraph ()
"Takes a multi-line paragraph and makes it into a single line of text."
(interactive)
(let ((fill-column (point-max)))
(fill-paragraph nil)))
(define-key global-map "\C-\M-q" 'unfill-paragraph)From pragmatic emacs:
(setq scroll-preserve-screen-position 1)
;;scroll window up/down by one line
(global-set-key (kbd "M-n") (kbd "C-u 1 C-v"))
(global-set-key (kbd "M-p") (kbd "C-u 1 M-v"))Make tabs look bigger:
(setq x-stretch-cursor t)(use-package persistent-scratch
:config
(persistent-scratch-setup-default))Per http://pragmaticemacs.com/emacs/expand-region/:
(use-package expand-region
:bind (("C-=" . er/expand-region)))From http://pragmaticemacs.com/emacs/uniquify-your-buffer-names/:
(require 'uniquify)
(setq uniquify-buffer-name-style 'forward)
(setq uniquify-separator "/")
(setq uniquify-after-kill-buffer-p t) ; rename after killing uniquified
(setq uniquify-ignore-buffers-re "^\\*")
; don't muck with special buffers(global-set-key (kbd "M-u") 'upcase-dwim)
(global-set-key (kbd "M-l") 'downcase-dwim)
(global-set-key (kbd "M-c") 'capitalize-dwim)
Disable dinging on C-g
(setq visible-bell 1)
(tool-bar-mode -1)(add-hook 'artist-mode-hook (lambda () (setq indent-tabs-mode nil)))(setq require-final-newline t)(use-package yasnippet
:diminish yas-minor-mode
:config (yas-global-mode t)
)(use-package flymake)Magit TODOs:
(use-package magit-todos
:commands (magit-todos-mode)
:hook (magit-mode . magit-todos-mode)
:custom
(magit-todos-keywords (list "TODO" "FIXME"))
(magit-todos-keyword-suffix "")
(magit-todos-exclude-globs '("*_archive"))
:after magit)(use-package magit
:bind (("C-x g" . magit-status))
:config
(require 'vc)
(magit-todos-mode)
(remove-hook 'find-file-hooks 'vc-find-file-hook)
)
; require is only so we can remove the vc hook:
;; (use-package magit-workflow
;; :ensure nil
;; :hook (magit-mode . turn-on-magit-workflow))Link to Github etc via browse-at-remote! This is really neat!
(use-package browse-at-remote
:bind (("C-c g" . 'browse-at-remote))
); thanks https://emacs.stackexchange.com/a/55628/39670
(defface hl-todo-TODO
'((t :background "#666600" :foreground "#ffffff" :inherit (hl-todo)))
"Face for highlighting TODO")
(use-package hl-todo
:custom
(hl-todo-keyword-faces
'(("TODO" . hl-todo-TODO)
("FIXME" . hl-todo-TODO)
))
:hook ((prog-mode . hl-todo-mode)))(use-package pony-mode)
(use-package virtualenvwrapper
:config
(venv-initialize-interactive-shells) ;; if you want interactive shell support
(venv-initialize-eshell) ;; if you want eshell support
(setq venv-location (expand-file-name "~/.virtualenvs/"))
(add-hook 'python-mode-hook (lambda ()
(hack-local-variables)
(venv-workon project-venv-name))))
(use-package jedi
:config (add-hook 'python-mode-hook 'jedi:setup)
(setq jedi:setup-keys t) ; optional
; (setq jedi:complete-on-dot t) ; optional
(jedi:setup))
(use-package python)(set-variable 'python-fill-docstring-style 'django); https://github.com/akaihola/flymake-python
(when (load "flymake" t)
(defun flymake-pylint-init ()
(let* ((temp-file (flymake-init-create-temp-buffer-copy
'flymake-create-temp-inplace))
(local-file (file-relative-name
temp-file
(file-name-directory buffer-file-name))))
(list (expand-file-name "~/.emacs.d/bin/pyflymake.py") (list local-file))))
;; check path
(add-to-list 'flymake-allowed-file-name-masks
'("\\.py\\'" flymake-pylint-init)))
(add-hook 'find-file-hook 'flymake-find-file-hook)
(defun flymake-html-init ())
(defun flymake-simple-tex-init ())(use-package markdown-mode
:config (add-hook 'markdown-mode-hook 'turn-on-visual-line-mode))
(use-package graphviz-dot-mode)
(use-package puppet-mode)
(use-package yaml-mode)
(use-package json-mode)
(use-package puppet-mode
:mode (("\\.pp'" . puppet-mode)))
(use-package dockerfile-mode
:mode (("Dockerfile\\'" . dockerfile-mode)))
(use-package markdown-mode
:mode (("\\.md\\'" . markdown-mode)
("\\.markdown\\'" . markdown-mode))
:config (setq markdown-command "multimarkdown")
(add-hook 'markdown-mode-hook
(lambda ()
;; disable electric indent
(setq-local electric-indent-mode nil)
)))
(use-package php-mode
:mode (("\\.php\\'" . php-mode)
("\\.inc\\'" . php-mode)))N.B. to make Apple’s afplay quieter for org-mode, you’ll need to set the bell value to ~/.emacs.d/quietbell.wav. Keywords: bell, loud, ear hurt, don’t use -v 100. You need to set both the finished bell and the overtime bell!
The quiet bell was generated by
ffmpeg -i loudbell.wav -filter:a "volume=-20dB" quietbell.wav
(First I tried to use afplay arguments to do this but I decided making a separate file was easier to understand.)
; https://blog.aaronbieber.com/2016/09/24/an-agenda-for-life-with-org-mode.html:
(defun air-org-skip-subtree-if-habit ()
"Skip an agenda entry if it has a STYLE property equal to \"habit\"."
(let ((subtree-end (save-excursion (org-end-of-subtree t))))
(if (string= (org-entry-get nil "STYLE") "habit")
subtree-end
nil)))
(use-package org
:ensure org-contrib
:config (add-hook 'org-mode-hook 'turn-on-flyspell)
(add-hook 'org-mode-hook 'visual-line-mode)
(setq org-src-fontify-natively t)
(setq org-todo-keyword-faces
'(("WORKING" . "orange")
("CANCELLED" . "grey")))
(setq org-agenda-files (list "~/Dropbox/org/inbox.org"
"~/Dropbox/org/plan.org"
"~/Dropbox/org/main-todo.org"
"~/Dropbox/org/now.org"
"~/Dropbox/org/repeating.org"
"~/Dropbox/org/projects.org"))
(setq org-directory "~/Dropbox/org/")
(setq org-capture-templates
'(("t" "Todo [inbox]" entry
(file+headline "~/Dropbox/org/inbox.org" "Tasks")
"* TODO %i%?\n%a")
("T" "Todo [inbox, no link]" entry
(file+headline "~/Dropbox/org/inbox.org" "Tasks")
"* TODO %i%?\n")
("b" "Backlog" entry
(file+headline "~/Dropbox/org/backlog.org" "Org-capture backlog")
"* %i%?\n%a")
("B" "Backlog [no link]" entry
(file+headline "~/Dropbox/org/backlog.org" "Org-capture backlog")
"* %i%?\n")
("p" "Project" entry
(file "~/Dropbox/org/projects.org")
"* %i%?\n%a")
("P" "Project [no link]" entry
(file "~/Dropbox/org/projects.org")
"* %i%?\n")
))
(setq org-default-notes-file "~/Dropbox/org/inbox.org")
(setq org-refile-targets '((("~/Dropbox/org/main-todo.org") :maxlevel . 1)
(("~/Dropbox/org/repeating.org") :maxlevel . 1)
(("~/Dropbox/org/projects.org") :maxlevel . 1)
(("~/Dropbox/org/backlog.org") :maxlevel . 1)
(("~/Dropbox/org/now.org") :maxlevel . 1)
(("~/Dropbox/org/mom.org") :maxlevel . 1)
))
(setq org-export-with-section-numbers nil)
(setq org-export-with-sub-superscripts nil)
(setq org-todo-keywords
'((sequence "TODO(t)" "WORKING(n)" "WAITING(w@/!)" "POSTPONED(p)" "|" "DONE(d)" "CANCELLED(c)")))
(setq org-tag-alist '(("crypt" . ?x)
(:startgroup . nil)
("home" . ?h)
("work" . ?w)
("roamtodos" . ?r)
("defer" . ?d)
(:endgroup . nil)
))
(setq org-agenda-custom-commands
'(("w" "Work agenda"
; Priority A
((tags-todo "PRIORITY=\"A\"&-home&-roamtodos"
((org-agenda-overriding-header "Priority A")))
; Due soon
(tags-todo "-PRIORITY=\"A\"&DEADLINE<=\"<+7d>\"&-home&-roamtodos&-TODO=\"WAITING\""
((org-agenda-overriding-header "Due soon")))
; Project list
(tags "LEVEL=1&-home&-defer&SCHEDULED<=\"<+1d>\"|LEVEL=1&-home&-roamtodos&-defer-SCHEDULED={.}"
((org-agenda-files '("~/Dropbox/org/projects.org"))
(org-agenda-overriding-header "Projects")))
; Tasks w/o deadline
(tags-todo (concat "-PRIORITY=\"A\"&-home&-roamtodos&-defer&-TODO=\"WAITING\""
; "&-FILE=\"" (expand-file-name "~/Dropbox/org/projects.org") "\""
"&-DEADLINE={.+}")
((org-agenda-skip-function '(air-org-skip-subtree-if-habit))
(org-agenda-overriding-header "Tasks w/o deadlines")))
; Due later
(tags-todo (concat "-home&-roamtodos&-TODO=\"WAITING\"&DEADLINE>\"<+7d>\"")
((org-agenda-skip-function '(air-org-skip-subtree-if-habit))
(org-agenda-overriding-header "Due later")))
; Habits
(tags-todo "-home&-roamtodos&STYLE=\"habit\""
((org-agenda-overriding-header "Habits")))
; Waiting tasks
(tags-todo "-home&-roamtodos&TODO=\"WAITING\""
((org-agenda-overriding-header "Waiting tasks"))))
((org-overriding-columns-format "%60ITEM %DEADLINE %TAGS")
(org-agenda-view-columns-initially t)
(org-agenda-compact-blocks t)
(org-agenda-sorting-strategy '(deadline-up))))
("h" "Home agenda"
; Priority A
((tags-todo "PRIORITY=\"A\"&-work&-roamtodos"
((org-agenda-overriding-header "Priority A")))
; Due soon
(tags-todo "-PRIORITY=\"A\"&DEADLINE<=\"<+7d>\"&-work&-roamtodos&-TODO=\"WAITING\""
((org-agenda-overriding-header "Due soon")))
; Project list
(tags "LEVEL=1&-work&-roamtodos&-defer&SCHEDULED<=\"<+1d>\"|LEVEL=1&-work&-defer-SCHEDULED={.}"
((org-agenda-files '("~/Dropbox/org/projects.org"))
(org-agenda-overriding-header "Projects")))
; Tasks w/o deadline
(tags-todo (concat "-PRIORITY=\"A\"-work&-roamtodos&-defer&-TODO=\"WAITING\""
; "&-FILE=\"" (expand-file-name "~/Dropbox/org/projects.org") "\""
"&-DEADLINE={.+}")
((org-agenda-skip-function '(air-org-skip-subtree-if-habit))
(org-agenda-overriding-header "Tasks w/o deadlines")))
; Due later
(tags-todo (concat "-work&-roamtodos&-TODO=\"WAITING\"&DEADLINE>\"<+7d>\"")
((org-agenda-skip-function '(air-org-skip-subtree-if-habit))
(org-agenda-overriding-header "Due later")))
; Habits
(tags-todo "-work&-roamtodos&STYLE=\"habit\""
((org-agenda-overriding-header "Habits")))
; Waiting tasks
(tags-todo "-work&-roamtodos&TODO=\"WAITING\""
((org-agenda-overriding-header "Waiting tasks"))))
((org-overriding-columns-format "%60ITEM %DEADLINE %TAGS")
(org-agenda-view-columns-initially t)
(org-agenda-compact-blocks t)
(org-agenda-sorting-strategy '(deadline-up))))
("W" "Waiting"
((todo "WAITING"))
((org-overriding-columns-format "%50ITEM %DEADLINE %TAGS")
(org-agenda-view-columns-initially t)
(org-agenda-compact-blocks t)
(org-agenda-sorting-strategy '(deadline-up))))
("r" "ROAM"
((tags-todo "roamtodos"))
((org-overriding-columns-format "%50ITEM %SCHEDULED %DEADLINE %CATEGORY")
(org-agenda-view-columns-initially t)
(org-agenda-compact-blocks t)
(org-agenda-sorting-strategy '(scheduled-up)))) ;; options set here apply to the entire block
))
;; ...other commands here
(setq org-startup-folded nil)
(setq org-log-into-drawer t)
(setq org-enforce-todo-dependencies t)
(add-to-list 'org-modules 'org-habit)
(add-to-list 'org-modules 'org-checklist)
(setq org-agenda-todo-ignore-scheduled 'future)
(setq org-agenda-tags-todo-honor-ignore-options t)
(setq org-agenda-skip-deadline-prewarning-if-scheduled t)
(require 'org-checklist)
(require 'org-crypt)
(setq org-crypt-key "08A19D14958B2044")
(org-crypt-use-before-save-magic)
(setq org-agenda-window-setup 'only-window)
(setq org-clock-persist t)
(setq org-highlight-latex-and-related '(latex))
(require 'ox-beamer)
(setq org-export-with-toc nil)
; (setq org-tags-exclude-from-inheritance (quote ("crypt")))
(setq org-src-tab-acts-natively t)
(setq org-src-preserve-indentation t)
(setq org-clock-out-remove-zero-time-clocks t)
(setq org-id-method (quote uuidgen))
(setq org-use-speed-commands t)
(setq org-catch-invisible-edits 'error)
:bind (("C-c l" . org-store-link)
("C-c a" . org-agenda)
("C-c c" . org-capture)
:map org-mode-map
("C-c P" . org-panes-check-olivetti)
("C-'" . nil) ; don't bind C-' to org-cycle-agenda-files
))
(add-hook 'org-mode-hook 'helm-mode)
(use-package org-bullets
:config
(add-hook 'org-mode-hook (lambda () (org-bullets-mode 1))))
(use-package org-journal
:custom (org-journal-encrypt-journal t)
(org-journal-file-type 'daily)
(org-journal-file-format "%Y-%m-%d.org")
:bind (("C-c j" . org-journal-new-entry))
)
(use-package org-mime
:config (setq org-mime-export-options '(:preserve-breaks t))
(add-hook 'message-mode-hook
(lambda ()
(local-set-key "\C-c\M-o" 'org-mime-htmlize))))
(use-package org-panes
:ensure nil
:config (setq org-panes-split-overview-horizontally t)
(setq org-panes-main-size 70))
; 2022-06-02 - alert was not installed so org-pomodoro was failing
(use-package alert)
(use-package org-pomodoro
:ensure nil
:custom
(org-pomodoro-manual-break t)
:bind (("C-c t" . org-pomodoro))
)Adding org-mime HTML; thanks https://emacs.stackexchange.com/a/18331!
(add-hook 'org-mime-html-hook
(lambda ()
(goto-char (point-min))
(insert "<div style=\"font-family:Georgia,serif\">")
(goto-char (point-max))
(insert "</div>")))Olivetti and org-panes don’t play together well. This function will disable olivetti-mode and then re-enable it after calling org-panes, if olivetti-mode was on.
(defun org-panes-check-olivetti ()
(interactive)
(if (bound-and-true-p olivetti-mode)
(progn (olivetti-mode -1)
(org-panes)
(olivetti-mode))
(org-panes))); thanks to https://cute-jumper.github.io/emacs/2013/10/06/orgmode-to-github-pages-with-jekyll
(defun org-jekyll-post-link-follow (path)
(org-open-file-with-emacs path))
(defun org-jekyll-post-link-export (path desc format)
(cond
((eq format 'html)
(format "<a href=\"{%% post_url %s %%}\">%s</a>" (file-name-sans-extension path) desc))))
(org-add-link-type "jekyll-post" 'org-jekyll-post-link-follow 'org-jekyll-post-link-export)From https://endlessparentheses.com/embedding-youtube-videos-with-org-mode-links.html:
(defvar yt-iframe-format
;; You may want to change your width and height.
(concat "<iframe width=\"440\""
" height=\"335\""
" src=\"https://www.youtube.com/embed/%s\""
" frameborder=\"0\""
" allowfullscreen>%s</iframe>"))
(org-add-link-type
"yt"
(lambda (handle)
(browse-url
(concat "https://www.youtube.com/embed/"
handle)))
(lambda (path desc backend)
(cl-case backend
(html (format yt-iframe-format
path (or desc "")))
(latex (format "\href{%s}{%s}"
path (or desc "video"))))))I want to auto-commit org files, which I do via this module + a .dir-locals.el file in the org directory.
(use-package git-auto-commit-mode)
(Removed as of 2022-07-11 because I haven’t been using the wiki.)
Install wiki:
;; (when (not (require 'org-wiki nil t))
;; (let ((url "https://raw.githubusercontent.com/caiorss/org-wiki/master/org-wiki.el"))
;; (with-current-buffer (url-retrieve-synchronously url)
;; (goto-char (point-min))
;; (re-search-forward "^$")
;; (delete-region (point) (point-min))
;; (kill-whole-line)
;; (package-install-from-buffer))
;; (require 'org-wiki)))
;; (setq org-wiki-location "~/Dropbox/jb.com/org/wiki")
;; (org-wiki-make-menu)Wiki template:
Removed <2020-12-15 Tue> because the template doesn’t seem to work plus it makes the org-mode view of this file weird.
; This is outside use-package so this path can be overridden
(setq org-roam-directory (expand-file-name "~/Dropbox/org-roam/"))
(use-package org-roam
:after org
:custom
(org-roam-mode-sections
(list #'org-roam-backlinks-section
#'org-roam-reflinks-section
;; #'org-roam-unlinked-references-section
))
(org-roam-capture-templates
'(("d" "default" plain "%?" :target
(file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}
- tags :: ")
:unnarrowed t)))
; thanks https://systemcrafters.net/build-a-second-brain-in-emacs/5-org-roam-hacks/
(defun org-roam-node-insert-immediate (arg &rest args)
(interactive "P")
(let ((args (cons arg args))
(org-roam-capture-templates (list (append (car org-roam-capture-templates)
'(:immediate-finish t)))))
(apply #'org-roam-node-insert args)))
:config
(org-roam-setup)
(defun org-roam-node-insert-immediate (arg &rest args)
(interactive "P")
(let ((args (cons arg args))
(org-roam-capture-templates (list (append (car org-roam-capture-templates)
'(:immediate-finish t)))))
(apply #'org-roam-node-insert args)))
; https://github.com/org-roam/org-roam/issues/991#issuecomment-882010053
(add-to-list 'magit-section-initial-visibility-alist (cons 'org-roam-node-section 'hide))
:bind (("C-c n f" . org-roam-node-find)
("C-c n r" . org-roam-node-random)
("C-c n c" . org-roam-capture)
("C-c n g" . org-roam-graph)
(:map org-mode-map
(
("C-c n i" . org-roam-node-insert)
("C-c n I" . org-roam-node-insert-immediate)
("C-c n o" . org-id-get-create)
("C-c n t" . org-roam-tag-add)
("C-c n a" . org-roam-alias-add)
("C-c n l" . org-roam-buffer-toggle)
))))
This allows you to show the org-roam buffer by default, if tim/org-roam-buffer-auto-mode is set.
Thanks to org-roam/org-roam#507 (comment).
(defun tim/org-roam-buffer-auto-toggle (frame) “Ensure that org-roam buffer is visible iff frame contains an org-roam file.” (with-selected-frame frame (when (xor (eq ‘visible (org-roam-buffer–visibility)) (seq-find (lambda (window) (org-roam-buffer-p (window-buffer window))) (window-list))) (org-roam-buffer-toggle))))
(define-minor-mode tim/org-roam-buffer-auto-mode “Global minor mode for toggling the org-roam buffer automatically.
When this global minor mode is enabled, then the org-roam backlink buffer is shown if and only if the current frame has a window with an org-roam file.” :global t :lighter ” OrgRoamBuf” (if tim/org-roam-buffer-auto-mode (add-hook ‘window-buffer-change-functions ‘tim/org-roam-buffer-auto-toggle) (remove-hook ‘window-buffer-change-functions ‘tim/org-roam-buffer-auto-toggle)))
- thanks also to jrblevin/deft#75 (comment)
(use-package deft
; :after org-roam
:init
(require 'org-roam)
:bind
(("C-c n d" . deft)
:map deft-mode-map
("C-g" . quit-window))
:custom
(deft-recursive t)
(deft-use-filter-string-for-filename t)
(deft-default-extension "org")
(deft-directory org-roam-directory)
:config
(defun cm/deft-parse-title (file contents)
"Parse the given FILE and CONTENTS and determine the title.
If `deft-use-filename-as-title' is nil, the title is taken to
be the first non-empty line of the FILE. Else the base name of the FILE is
used as title."
(let ((begin (string-match "^#\\+[tT][iI][tT][lL][eE]: .*$" contents)))
(if begin
(string-trim (substring contents begin (match-end 0)) "#\\+[tT][iI][tT][lL][eE]: *" "[\n\t ]+")
(deft-base-filename file))))
(advice-add 'deft-parse-title :override #'cm/deft-parse-title)
(setq deft-strip-summary-regexp
(concat "\\("
"[\n\t]" ;; blank
"\\|^#\\+[[:alpha:]_]+:.*$" ;; org-mode metadata
"\\|^:PROPERTIES:\n\\(.+\n\\)+:END:\n"
"\\)")))
Thanks very much to https://speechcode.com/blog/org-to-clipboard
(defun org-to-clipboard ()
"Convert the contents of the current buffer or region from Org
mode to HTML. Store the result in the clipboard."
(interactive)
(if (use-region-p)
(shell-command-on-region (region-beginning)
(region-end)
"org2clip")
(shell-command-on-region (point-min)
(point-max)
"org2clip")))archive-finished-tasks macro:
(fset 'archive-finished-tasks
(kmacro-lambda-form [?\C-c ?\C-x ?\C-a ?\C-\M-s ?* ? ?\( ?D ?O ?N ?E ?| ?C ?A ?N ?C ?E ?L ?L ?E ?D ?\) return] 0 "%d"))find-next-subtask macro:
(fset 'find-next-open-task
(kmacro-lambda-form [?\C-s ?\[ ? ?\] return ?\C-u ?3 ?\C-l] 0 "%d"))
(with-eval-after-load 'org
(bind-key "C-c C-x n" #'find-next-open-task org-mode-map))FIXME broken
(fset 'schedule-now-plus-28-days
(kmacro-lambda-form [?\C-c ?\C-s ?. S-down S-down S-down S-down return] 0 "%d"))
(add-hook 'org-agenda-mode-hook (lambda ()
(define-key org-agenda-mode-map (kbd "C-c >") 'schedule-now-plus-28-days)))
;(require 'org-protocol); (use-package bbdb)
(use-package notmuch
:bind (("C-x E" . notmuch))
)
(eval-after-load 'notmuch-show
'(define-key notmuch-show-mode-map "`" 'notmuch-show-apply-tag-macro))
(eval-after-load 'notmuch-search
'(define-key notmuch-search-mode-map "`" 'notmuch-search-apply-tag-macro))
(use-package ol-notmuch)
(setq message-fill-column nil)
(add-hook 'message-mode-hook #'visual-line-mode)
(setq message-elide-ellipsis "[... %l line(s) removed ...]\n")
(setq message-wash-forwarded-subjects t)
(setq message-forward-before-signature nil)
; TODO figure out how to turn off auto-fill-mode for message-mode/mml-mode
; add date to reply
(setq message-citation-line-function 'message-insert-formatted-citation-line)
(setq message-citation-line-format "On %A, %b %d %Y, %f wrote:\n")
; the "jb-" is to make sure there's no conflict if I ever use poly-org
(use-package polymode
:config
(define-hostmode poly-mml-hostmode :mode 'notmuch-message-mode)
(define-innermode jb-poly-org-innermode
:mode 'org-mode
:head-matcher "--text follows this line--"
:tail-matcher "^THISNEVEREXISTS$"
:head-mode 'host
:tail-mode 'org-mode)
(define-polymode poly-org-mode
:hostmode 'poly-mml-hostmode
:innermodes '(jb-poly-org-innermode))
(add-hook 'mml-mode-hook
(lambda () (local-set-key (kbd "C-c o") #'poly-org-mode)))
)(defun org-mime-search-for-multipart ()
"Searches for multipart code and prompts whether to send email"
(let ((found-multipart (save-excursion
(save-restriction
(widen)
(goto-char (point-min))
(search-forward "<#multipart type=alternative>" nil t)))))
(when (and (not found-multipart)
(not (y-or-n-p "org-mime-htmlize not called; send anyway?")))
(setq quit-flag t))))
(add-hook 'message-send-hook 'org-mime-search-for-multipart)
;; (defun mua-send-mime
;; (y-or-n-p "Send without org-mime?")
;; )(use-package wc-goal-mode)
(use-package olivetti
:bind ("C-c f" . olivetti-mode))(use-package google-this
:diminish
:config (google-this-mode 1)
)(use-package restclient) (use-package projectile
:diminish
:init
(projectile-mode +1)
(setq projectile-switch-project-action 'projectile-commander)
(setq projectile-current-project-on-switch 'keep)
:bind (:map projectile-mode-map
("s-p" . projectile-command-map)
("C-c p" . projectile-command-map)))
(use-package helm-projectile
:init
(helm-projectile-on)
)
(use-package imenu-list
:init
(setq imenu-list-auto-resize t)
:bind (("C-'" . imenu-list-smart-toggle))
)(use-package crontab-mode)(use-package pcre2el
:diminish 'pcre-mode
:config
(pcre-mode))(setq delete-by-moving-to-trash t)(use-package flymake-shellcheck
:commands flymake-shellcheck-load
:init
(add-hook 'sh-mode-hook 'flymake-shellcheck-load))
FYI this needs the h register populated with the header to insert, which is:
<head> <style type=”text/css”> </style> <script src=”https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js”></script>
<script language=”javascript”> // thanks to https://stackoverflow.com/posts/18052837/revisions and // https://stackoverflow.com/posts/30156191/revisions
$(function () { $ (“textarea”).each(function () { this.cols = “100”; this.style.height = (this.scrollHeight+10)+’px’; });$(“input[type=’text’]” ).each(function( index ) { $ (this).attr(“size”, $(this).val().length + 5 ); }); }); </script> </head>
(use-package vcard-mode
:ensure nil
:mode "\\.vc\\(f\\|ard\\)\\'"); see https://stackoverflow.com/questions/37038441/generate-a-random-5-letternumber-string-at-cursor-point-all-lower-case
(defun random-alnum ()
(let* ((alnum "abcdefghijklmnopqrstuvwxyz0123456789")
(i (% (abs (random)) (length alnum))))
(substring alnum i (1+ i))))
(defun random-string (number)
"Generate a random string"
(interactive "p")
(dotimes (i number)
(insert (random-alnum))))Adapted from https://www.emacswiki.org/emacs/InsertDate:
C-c dinserts the date like2021-05-03C-u C-c dinserts the date likeMon May 3 12:16:50 2021(defun insert-date (prefix) "Insert the current date. With prefix-argument, use ISO format. With two prefix arguments, write out the day and month name." (interactive "P") (let ((format (cond ((not prefix) "%Y-%m-%d") ((equal prefix '(4)) "%c"))) (system-time-locale "en_US")) (insert (format-time-string format)))) (global-set-key (kbd "C-c d") 'insert-date)
(defun replace-body-with-reply-parser (&rest _) (interactive) (if (boundp 'reply-parser-program) (progn (message-goto-body) (call-process-region (point); START (point-max); END "python" t t t (expand-file-name reply-parser-program)) (message-goto-body)))) (advice-add 'notmuch-mua-new-reply :after #'replace-body-with-reply-parser)
This section goes from least- to most-specific, allowing other files to override the above and/or add other Emacs configuration.
; SYSTEM-TYPE config
; (may change system-name)
(setq system-type-as-string
(replace-regexp-in-string "/" "-" (prin1-to-string system-type)))
(setq system-type-specific-config
(concat dotfiles-dir "system-type-specific/" system-type-as-string ".el"))
(if (file-exists-p system-type-specific-config)
(load system-type-specific-config)); SYSTEM-NAME config
(setq system-name-specific-config
(concat dotfiles-dir "system-name-specific/" (system-name) ".el"))
(if (file-exists-p system-name-specific-config)
(load system-name-specific-config)); USER config
(setq user-specific-config
(concat dotfiles-dir "user-specific/" user-login-name ".el"))
(if (file-exists-p user-specific-config)
(load user-specific-config)); LOCAL config
(setq local-specific-config (concat dotfiles-dir "local.el"))
(if (file-exists-p local-specific-config)
(load local-specific-config))