-*- mode: org; eval: (org-show-todo-tree ‘()) -*-
This is my Emacs configuration file and is an example of literate programming. This file is loaded on several computers and also configures the window manager on one of them.
This file is loaded by org-dotemacs in .emacs.d/init.el.
Deleting a section should only effect things that are clear from the section title. While this feel obviouse once stated, it’s not followed without active vigilance.
Thus spake the Master Programmer:
“A well-written program is its own Heaven; a poorly-written program is its own Hell.”
– The Tao of Programming : Book 4
(setq user-full-name "Murray Fordyce")
(setq user-mail-address "unDeadHerbs@gmail.com")
(setq copyright-names-regexp
(format "%s <%s>" user-full-name user-mail-address))The following line allows blocks to be marked as broken or unused.
If so move DISABLED to green and remove the WORKING tag.
These are settings that are relating to the core of Emacs rather than any the things I do with it.
Since I want all settings to be in this file, I’m disabling `Customizing`’s ability to save settings, so that this is testable.
(setq custom-file
(if (boundp 'server-socket-dir)
(expand-file-name "custom.el" server-socket-dir)
(expand-file-name (format "emacs-custom-%s.el" (user-uid)) temporary-file-directory)))(custom-set-variables
'(safe-local-variable-values
'((eval org-update-statistics-cookies 't)
(eval local-set-key
(kbd "]")
#'udh/close-braket-and-update-link)
(indent-tabs-mode quote nil)
(eval org-show-todo-tree 'nil))))(require 'package)
(require 'use-package)(setq package-archives '(("gnu" . "https://elpa.gnu.org/packages/")
("melpa" . "https://melpa.org/packages/"))) ; milkyPostman's repo
; ("org" . "https://orgmode.org/elpa/"))) ; Org-mode's repository
;(package-initialize) ; allready called in my init.el
(when (not package-archive-contents)
(package-refresh-contents))(defun udh/install-and-load (package)
(ignore-errors
(unless (package-installed-p package)
(package-install package))
(require package)))
(setq load-prefer-newer t)
(udh/install-and-load 'auto-compile)
(auto-compile-on-load-mode)
(udh/install-and-load 'package-utils);;(package-utils-upgrade-all)This should probably be done with emacs-dashboard.
When Emacs gains support for threadding package installation and configuration should be made asynchronous.
This will be a major rewrite since many packages are set in multiple
locations. The system will need to receive settings for a package and
then put them in some queue for when the package is loaded. The
priority of a package can be set to realtime if it’s mode is asked
for.
Disabled since not needed currently.
;(udh/install-and-load 'quelpa)This probably belongs in Computer Specific before GTD. Have a pair of functions to query what is installed and install things. This should probably be only one function. The Guix one will just install it, but for other OSs it will check if it’s installed and add a warning to [*scratch*] if it’s not.
Update Emacs’s GPG keyring for GNU ELPA. https://elpa.gnu.org/packages/gnu-elpa-keyring-update.html
;; (setq package-check-signature '())
(udh/install-and-load 'gnu-elpa-keyring-update)
;; (setq package-check-signature t)(setq inhibit-startup-message t)
(setq sentence-end-double-space t)
(menu-bar-mode -1)
(tool-bar-mode -1)
(scroll-bar-mode -1)
;; TODO: Disable suspention on gui clients and in
;; tmux.
(global-unset-key (kbd "C-z"));; TODO unset (kbd "C-[") from ESC
;(define-key key-translation-map
; [?\C-\[] nil);[(control left_bracket)])
;(define-key key-translation-map
; (kbd "C-[") nil);[(control left_bracket)])
;(define-key key-translation-map
; [escape] [?\e])
;(define-key key-translation-map
; [escape] nil)
;(define-key key-translation-map
; [?\e] nil)
;(when (boundp 'local-function-key-map)
; ;;(define-key local-function-key-map)
; (defun remove-escape-from-local-function-key-map ()
; (define-key local-function-key-map [?\e] nil)
; (define-key local-function-key-map [escape] nil)
; (define-key local-function-key-map [?\C-\[] nil)
; (define-key local-function-key-map (kbd "C-[") nil))
;(add-hook 'term-setup-hook
; #'remove-escape-from-local-function-key-map))(defun close-frame-if-no-server ()
(if (server-running-p)
(condition-case err
(delete-frame)
(error (if (< emacs-major-version 22)
(save-buffers-kill-terminal)
(save-buffers-kill-emacs))))
(if (< emacs-major-version 22)
(save-buffers-kill-terminal)
(save-buffers-kill-emacs))))
(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? "))
(close-frame-if-no-server)
(message "Canceled exit")))
(global-set-key (kbd "C-x C-c") 'ask-before-closing)(udh/install-and-load 'persistent-scratch)
(persistent-scratch-setup-default)(setq ido-show-dot-for-dired t)ReEnable the up arrow for looking though history.
(setq-default history-length 1000)
;(add-hook 'ido-setup-hook
; (lambda () (define-key ido-compleation-map [up] 'previous-history-element)))
;(setq(defun void (&rest ignored)
"Do nothing, quietly."
(interactive "p"))(defun udh/shell (cmd)
"Run a command in the shell and then strip extra whitespace."
(replace-regexp-in-string
"^[\n ]*" ""
(replace-regexp-in-string
"[ \n]*$" ""
(shell-command-to-string cmd))))(defun udh/sdate ()
"Today's date as an sdate"
(udh/shell "sdate -f 5 -d"))
(defun udh/date-to-sdate (date)
"Convert a regular date to an sdate"
(udh/shell (concat "sdate -f 5 -d -D " date)))“Getting Things Done” is an old book with lots of ideas, some of which are good. I’ve borrowed some of the core workflow and the naming.
| Action | Key-bind | Location |
|---|---|---|
| Agenda | C-c a g | Global |
| Capture | C-c c | Global |
| Effort | C-c C-x e | Org Header |
| Refile | C-c C-w | Org Header |
| Task List | C-c a t | Global |
| Timestamp | C-c . | Org |
| T-stamp Deadline | C-c d | Org |
| T-stamp Inactive | C-c ! | Org |
| T-stamp Schedule | C-c s | Org |
;;(setq org-directory "~/")
;;(setq org-directory "~/org")
;;(setq org-agenda-files (list "todo.org" "inbox.org"))
;;the files seem to default to ~/org/* and customizing it breaks something
(setq org-agenda-files '("~/org" "~/org/roam"))Rather than delegating on capture (like in GTD), I categorise tasks and notes on their review.
(setq org-capture-templates
`(("i" "Inbox" entry (file "inbox.org")
,(concat "* TODO %?\n:PROPERTIES:\n:CREATION_DATE: %(udh/sdate)\n:END:"))))
(defun org-capture-inbox ()
(interactive)
(call-interactively 'org-store-link)
(org-capture nil "i"))
(global-set-key (kbd "C-c a") 'org-agenda)
(global-set-key (kbd "C-c c") 'org-capture-inbox)When I press `C-c c` in some buffers (like scratch) I get the error
This is for once I’m using mu4e.user-error: No method for storing a link from this buffer
;("@" "Inbox [mu4e]" entry (file "inbox.org")
; ,(concat "* TODO Process \"%a\" %?\n"
; "/Entered on/ %U"))
;
;(defun org-capture-mail ()
; (interactive)
; (call-interactively 'org-store-link)
; (org-capture nil "@"))
;(define-key mu4e-headers-mode-map (kbd "C-c c") 'mu4e-org-store-and-capture)
;(define-key mu4e-view-mode-map (kbd "C-c c") 'mu4e-org-store-and-capture)info:Org#Priorities
| Action | Key-bind |
|---|---|
| Mark Done | t |
(setq org-agenda-custom-commands
'(("g" "Get Things Done (GTD)"
((agenda ""
((org-agenda-skip-function
'(org-agenda-skip-entry-if 'deadline))
(org-deadline-warning-days 0)))
(todo "TODO"
((org-agenda-skip-function
'(org-agenda-skip-entry-if 'deadline))
(org-agenda-prefix-format " %i %-12:c [%e] ")
(org-agenda-overriding-header "\nTasks\n")))
(agenda nil
((org-agenda-entry-types '(:deadline))
(org-agenda-format-date "")
(org-deadline-warning-days 7)
(org-agenda-skip-function
'(org-agenda-skip-entry-if 'notregexp "\\* NEXT"))
(org-agenda-overriding-header "\nDeadlines")))
(tags "CLOSED>=\"<today>\""
((org-agenda-overriding-header "\nCompleted today\n")))))))(setq org-agenda-include-diary t)(setq org-agenda-start-day "-1d")
(setq org-agenda-span 9)
(setq org-agenda-start-on-weekday nil)This is showing 9 days in the agenda view.
There’s no need to show the daily repeating unscheduled tasks on everyday after the first.
When planning it’s important that all blocked time is displayed as blocked. It’s just not helpful when looking at the agenda view of the calendar.
| Action | Key-bind | Location |
|---|---|---|
| Clock in | C-c C-x i | Org Header |
| Clock Out | C-c C-x o | Org Header |
| Set Time Estimate | C-c C-x e | Org Header |
(setq org-log-done 'time)The idea version of this would be the project listing the folder it owns and all time spent with that folder as directory of the active frame is tracked.
Find a way to insert this into task creation or sorting.
(defun log-todo-next-creation-date (&rest ignore)
"Log NEXT creation time in the property drawer under the key 'ACTIVATED'"
(when (and (string= (org-get-todo-state) "NEXT")
(not (org-entry-get nil "ACTIVATED")))
(org-entry-put nil "ACTIVATED" (format-time-string "[%Y-%m-%d]"))))
(add-hook 'org-after-todo-state-change-hook
#'log-todo-next-creation-date)I plan to have `README.org` files in all projects. They should work together with my GTD setup to track actions and time. Look into `eproject` package for possible features.
While I feel that making an external database is a silly move and that a better hashmap should have been added to emacs to solve this problem for everybody, this is still a better solution than fully reimpliemnting the features myself.Org-roam needs starting before org-mode. So some of these lines are commented out and moved to ~/.emacs.d/init.el. https://org-roam.discourse.group/t/org-roam-buffer-do-not-refresh-automaticly/2873
;(udh/install-and-load 'org-roam)
;(setq org-roam-directory "~/org/roam");org-directory)Move to init.el.
;(org-roam-db-sync t)
;(org-roam-db-autosync-mode)(global-set-key (kbd "C-c n f") #'org-roam-node-find)
(global-set-key (kbd "C-c n i") #'org-roam-node-insert)
(global-set-key (kbd "C-c n l") #'org-roam-buffer-toggle)
;(global-set-key (kbd "C-c n d") #'org-roam-dailies-capture-today)
(global-set-key (kbd "C-c n d") #'org-roam-dailies-goto-today)(org-roam-db-autosync-enable);(setq org-roam-capture-templates
;'(("d" "default" plain "%?" :target
; (file+head "%<%Y%m%d%H%M%S>-${slug}.org" ":PROPERTIES:\n:CREATION_DATE: %(udh/sdate)\n:END:\n#+FILETAGS: :UPDATE:\n#+title: ${title}
;")
; :unnarrowed t)))
(setq org-roam-capture-templates
'(("d" "default" plain "%?" :target
(file+head "%<%Y%m%d%H%M%S>-${slug}.org" "* ${title} :UPDATE:\n:PROPERTIES:\n:CREATION_DATE: %(udh/sdate)\n:END:\n")
:unnarrowed t)));;(defun my-read-org-template (file)
;; "Read the contents of FILE and expand Org capture template expressions."
;; (let ((template (with-temp-buffer
;; (insert-file-contents file)
;; (buffer-string))))
;; (org-roam-capture--fill-template template)))
;;(setq org-roam-dailies-capture-templates
;; '(("d" "default from template" plain "%?"
;; :target (file+head "%<%Y%m%d>-Daily.org"
;; "%(with-temp-buffer
;; (insert-file-contents \"~/org/roam/daily/daily-template.org\")
;; (buffer-string))")
;; :unnarrowed t)))
;;(setq org-roam-dailies-capture-templates
;; '(("d" "default from template" plain "%?"
;; :target (file+head "%<%Y%m%d>-Daily.org"
;; "%(my-read-org-template \"~/org/roam/daily/daily-template.org\")")
;; :unnarrowed t)))
(setq org-roam-dailies-capture-templates
`(("d" "default from template" plain "%?"
:target (file+head "%<%Y>-Week_%<%V>-Daily.org"
,(with-temp-buffer
(insert-file-contents "~/org/roam/daily/daily-template.org")
(buffer-string)))
:unnarrowed t)))(defun udh/org-roam-preview ()
"Return the preview content at point.
This function returns the all contents under the current
headline, up to the next headline."
(let ((beg (save-excursion
(beginning-of-line)
(point)))
(end (save-excursion
(org-end-of-line)
(point))))
(string-trim (buffer-substring-no-properties beg end))))
(setq org-roam-preview-function #'udh/org-roam-preview)- for list entries, the item in the list and maybe the parent chain
- for a paragraph, take a few lines above and below, capturing at least the whole sentince.
- This currently doesn’t find the end of the link before calculating the end of the line, so it might not even capture the whole link.
It’s useful to be able to export an existing header as a new card.
(defun udh/org-roam-heading-to-node ()
"Convert current subtree at point to a node file. Tag with UPDATE."
;; This is a minor rewrite of org-roam-extract-subtree for my preferences
;; Namely, have a top level heading rather than a file name and give it a tag.
(interactive)
(save-excursion
(org-back-to-heading-or-point-min t)
(when (bobp) (user-error "Already a top-level node"))
(org-id-get-create)
(save-buffer)
(org-roam-db-update-file)
(let* ((template-info nil)
(node (org-roam-node-at-point))
(template (org-roam-format-template
(string-trim (org-capture-fill-template org-roam-extract-new-file-path))
(lambda (key default-val)
(let ((fn (intern key))
(node-fn (intern (concat "org-roam-node-" key)))
(ksym (intern (concat ":" key))))
(cond
((fboundp fn)
(funcall fn node))
((fboundp node-fn)
(funcall node-fn node))
(t (let ((r (read-from-minibuffer (format "%s: " key) default-val)))
(plist-put template-info ksym r)
r)))))))
(file-path
(expand-file-name
(read-file-name "Extract node to: "
(file-name-as-directory org-roam-directory) template nil template)
org-roam-directory)))
(when (file-exists-p file-path)
(user-error "%s exists. Aborting" file-path))
(org-cut-subtree)
(save-buffer)
(with-current-buffer (find-file-noselect file-path)
(org-paste-subtree)
(while (> (org-current-level) 1) (org-promote-subtree))
(beginning-of-buffer)
(org-toggle-tag "UPDATE" 'on)
(save-buffer)))))org-roam is now mature enough for usage.
I’m just going to build the tools my self for now.
(require 'org-id)
(setq org-id-link-to-org-use-id 'create-if-interactive-and-no-custom-id)
;; https://stackoverflow.com/a/13142796/4499969
(defun pop-kill-ring ()
(pop kill-ring)
(when kill-ring-yank-pointer
(setq kill-ring-yank-pointer kill-ring)));; https://writequit.org/articles/emacs-org-mode-generate-ids.html
(defun udh/org-custom-id-get (&optional pom create prefix)
"Get the CUSTOM_ID property of the entry at point-or-marker POM.
If POM is nil, refer to the entry at point. If the entry does
not have an CUSTOM_ID, the function returns nil. However, when
CREATE is non nil, create a CUSTOM_ID if none is present
already. PREFIX will be passed through to `org-id-new'. In any
case, the CUSTOM_ID of the entry is returned."
(interactive)
(org-with-point-at pom
(let ((id (org-entry-get nil "CUSTOM_ID")))
(cond
((and id (stringp id) (string-match "\\S-" id))
id)
(create
(setq id (org-id-new (concat prefix "h")))
(org-entry-put pom "CUSTOM_ID" id)
(org-id-add-location id (buffer-file-name (buffer-base-buffer)))
id)))))(defun udh/org-add-ids-to-headlines-in-file ()
"Add CUSTOM_ID properties to all headlines in the
current file which do not already have one."
(interactive)
(org-map-entries (lambda () (udh/org-custom-id-get (point) 'create))))
(defun udh/org-id-new (&optional prefix)
"Create a new globally unique ID.
An ID consists of two parts separated by a colon:
- a prefix
- a unique part that will be created according to `org-id-method'.
PREFIX can specify the prefix, the default is given by the variable
`org-id-prefix'. However, if PREFIX is the symbol `none', don't use any
prefix even if `org-id-prefix' specifies one.
So a typical ID could look like \"Org-4nd91V40HI\"."
(let* ((prefix (if (eq prefix 'none)
""
(concat (or prefix org-id-prefix) "-")))
unique)
(if (equal prefix "-") (setq prefix ""))
(cond
((memq org-id-method '(uuidgen uuid))
(setq unique (org-trim (shell-command-to-string org-id-uuid-program)))
(unless (org-uuidgen-p unique)
(setq unique (org-id-uuid))))
((eq org-id-method 'org)
(let* ((etime (org-reverse-string (org-id-time-to-b36)))
(postfix (if org-id-include-domain
(progn
(require 'message)
(concat "@" (message-make-fqdn))))))
(setq unique (concat etime postfix))))
(t (error "Invalid `org-id-method'")))
(concat prefix unique)))
(defun udh/org-add-ids-to-headlines-in-file ()
"Add CUSTOM_ID properties to all headlines in the current
file which do not already have one. Only adds ids if the
`auto-id' option is set to `t' in the file somewhere. ie,
#+OPTIONS: auto-id:t"
(interactive)
(save-excursion
(widen)
(goto-char (point-min))
(when (re-search-forward "^#\\+OPTIONS:.*auto-id:t" (point-max) t)
(org-map-entries (lambda () (udh/org-custom-id-get (point) 'create))))))
;; automatically add ids to saved org-mode headlines
(add-hook 'org-mode-hook
(lambda ()
(add-hook 'before-save-hook
(lambda ()
(when (and (eq major-mode 'org-mode)
(eq buffer-read-only nil))
(udh/org-add-ids-to-headlines-in-file)))))) ;; https://emacs.stackexchange.com/a/47752/27015
(defun udh/org-link-update-custom-id ()
(interactive)
(save-excursion
(while (not (org-element-link-parser))
(backward-char))
(let ((list-of-links-p (org-element-property
:contents-begin (org-element-link-parser))))
(org-open-at-point)
(cond ((org-at-heading-p)
(kill-new (udh/org-custom-id-get (point) 'create))
(org-mark-ring-goto)
(insert "[[#")
(yank)
(pop-kill-ring)
(insert "]")
(delete-forward-char 1)
(when list-of-links-p
(zap-to-char 1 ?\])))
(t
(org-mark-ring-goto))))))
(defun udh/org-link-update-id ()
(interactive)
(save-excursion
(while (not (org-element-link-parser))
(backward-char))
(let ((context (org-element-context))
(list-of-links-p (org-element-property
:contents-begin (org-element-link-parser))))
(cond ((and (eq (car context) 'link)
(eq (caadr context) :type)
(string= (cadadr context) "id"))
't
;; if its already an id link, skip this
;; There is probably (patterned) a better way to check the link type.
)
((and (eq (car context) 'link)
(eq (caadr context) :type)
(or
(string= (cadadr context) "http")
(string= (cadadr context) "https")
(string= (cadadr context) "doi")
(string= (cadadr context) "file")))
't
;; Web links can't be updated this way
)
(t
(org-open-at-point)
(cond ((org-at-heading-p)
(kill-new (org-id-get (point) t))
(org-mark-ring-goto)
(insert "[[id:")
(yank)
(pop-kill-ring)
(insert "]")
(delete-forward-char 1)
(when list-of-links-p
(zap-to-char 1 ?\])))
(t
(org-mark-ring-goto))))))))org-open-at-point opens the browser if the link is external.
(defun udh/org-link-update-buffer ()
(interactive)
(beginning-of-buffer)
(while (org-next-link)
;;(when (string= "fuzzy"
;; (org-element-property
;; :type (org-element-link-parser)))
(udh/org-link-update-id))))(defun udh/close-braket-and-update-link ()
(interactive)
(insert "]")
;; Borrowed from the code for #'org-open-at-point .
(let* ((context
(org-element-lineage
(org-element-context)
'(clock comment comment-block footnote-definition
footnote-reference headline inline-src-block inlinetask
keyword link node-property planning src-block timestamp)
t))
(type (org-element-type context)))
(cond
((eq type 'link) (udh/org-link-update-id)))))
(add-hook 'org-mode-hook
(lambda () (local-set-key (kbd "]") #'udh/close-braket-and-update-link)))Now that the links are hygienic, exporting a dot diagram should be easy. Just walk all of the headings and links, print out the arrows and shapes, and then make each the size of the number of times it’s referenced by the first two passes.
Have TODO tags changed to NEXT or BLOCKED when they are created/saved. This gives the rest of the system something easier to trigger off of and something easier to colour the other nodes based off of.
(show-paren-mode 1)In many modes < and > are not bracketing symbols and shouldn’t
be counted as mismatched brackets.
(udh/install-and-load 'pretty-mode)(add-hook 'tty-setup-hook
(lambda () (set-face-foreground 'minibuffer-prompt "cyan")))(defun turn-on-flyspell-prog ()
"Unconditionally turn on Flyspell-prog mode."
(flyspell-prog-mode))
(add-hook 'text-mode-hook
#'turn-on-flyspell)
(add-hook 'prog-mode-hook
#'turn-on-flyspell-prog)Looking into the run hooks, it claims that text-mode-hook should be run, org might just be clearing the minor mode away.
While I don’t use this often, it’s really annoying when it’s not on and I do want it.(udh/install-and-load 'undo-tree)
(defun turn-on-undo-tree ()
"Unconditionally turn on undo-tree-mode."
(undo-tree-mode 1))
(add-hook 'text-mode-hook
#'turn-on-undo-tree)
(add-hook 'prog-mode-hook
#'turn-on-undo-tree)I don’t expect that the efficiency implications of this will matter, but it’s good to care.
These are some pretty universal changes to how white-space is handled and represented. I turn them on in each mode that needs them.(udh/install-and-load 'dynamic-spaces)
(udh/install-and-load 'whitespace)These set the basics of how I want tabs but also insulate buffers.
(setq-default tab-width 2)
(setq tab-width 2)
(make-variable-buffer-local 'tab-width)
(setq-default indent-tabs-mode t)
(setq indent-tabs-mode t)
(make-variable-buffer-local 'indent-tabs-mode)(udh/install-and-load 'linum-relative)
(setq relative-line-numbers-motion-function 'forward-visible-line)Have line numbers that are multiples of five show though the relative numbers. Align them differently so they are easy to distinguish.
(udh/install-and-load 'hideshow)
(udh/install-and-load 'hideshowvis)(udh/install-and-load 'centered-cursor-mode)(udh/install-and-load 'bind-key)The latest version, called ivy has been subsumed into a package
called counsel.
(udh/install-and-load 'counsel)
(ivy-mode)https://emacs.stackexchange.com/questions/58631/how-to-open-a-file-without-using-ivy
Disabled: The tab compleation in regular find file doesn’t allow for
fuzzy matching or cycling. Trying ivy for a while and seeing if
it’s anoying.
;(defun gjg/find-file-no-ivy ()
; (interactive)
; (let ((ivy-state ivy-mode))
; (ivy-mode -1)
; (call-interactively 'find-file)
; (ivy-mode ivy-state)))
;
;(global-set-key (kbd "C-x C-f") 'gjg/find-file-no-ivy)(defun udh/execute-command-no-ivy ()
(interactive)
(let ((ivy-state ivy-mode))
(ivy-mode -1)
(call-interactively 'execute-extended-command)
(ivy-mode ivy-state)))
(global-set-key (kbd "M-x") 'udh/execute-command-no-ivy)Currently C-M-j calls ivy-immediate-done, map that to
C-<return>.
C-c C-c follow links into either org
or eww (or wherever the link goes since this will be in the
[[dest][name]] format).
While in org-mode if nothing to do at point follow link.
; (org-open-at-point)There’s a thing called FFAP in the Emacs info manual. give it a read.
(defun other-window-reverse (count &optional all-frames)
"Call `other-window' with a negitive argument."
(interactive "p")
(other-window (* -1 count) all-frames))
(global-set-key (kbd "C-x O") 'other-window-reverse)C-a going to the logical begging of line rather than the
technical beginning of line.
(global-set-key (kbd "C-a") 'back-to-indentation)
(global-unset-key (kbd "M-m"))(udh/install-and-load 'multiple-cursors)
;;(global-set-key (kbd "C-S-l") 'mc/edit-lines)
(bind-key* "C-d" 'mc/mark-next-like-this)
;;(global-set-key (kbd "C-S-d") 'mc/mark-previous-like-this)
;;(global-set-key (kbd "C-M-d") 'mc/mark-all-like-this)(setq mouse-yank-at-point 't)This should be made into a minor mode once it’s larger.
(require ‘multiple-cursors-mode)
When searching, highlight all lines that are matching, make sure they are visible. Reduce context around lines until all are visable on screen (or a limit is hit).
Really, just make a regex search that filters the visible lines. And a second function to revert the view, all else is of much less importance.
the package `all` seems similar, give it a look.
Mix together centered-cursor-mode and hideshowvis-minor-mode to
have folded all regions that aren’t within a small range of the point.
Call this fisheye-mode.
(setq is-termux
(string-suffix-p "Android"
(udh/shell "uname -a")))(setq is-guix
(not (string-suffix-p "not found"
(udh/shell "which guix"))))(when is-guix
;(udh/system "guix install emacs-guix")
;(udh/install-and-load 'guix)
(udh/install-and-load 'pretty-sha-path)) ;(when is-guix
;(defn udh/install (guix(setq is-kitchensink (string= "kitchensink" (system-name)))There are open questions on the Emacs mailing list as to what’s wrong with this.
;(setq socks-override-functions 1)
;(setq socks-noproxy '("localhost"))
;(require 'socks)
;(setq url-gateway-method 'socks)
;(setq socks-server '("Default server" "127.0.0.1" 9250 5))(when is-kitchensink
(load-theme 'wheatgrass)
(add-to-list 'default-frame-alist '(alpha . (85 . 85))))This difference only matters with viewing pictures in telega.
(when is-kitchensink
(custom-set-faces '(default ((t (:height 93))))))(when is-kitchensink
(setq visible-bell 1))(when is-kitchensink
;(defun udh/start-exwm ()
(progn
(udh/install-and-load 'exwm)
(require 'exwm)
(require 'exwm-config)
(exwm-config-default)))
;(add-hook 'emacs-startup-hook
; #'udh/start-exwm))Check that mouse-autoselect-window don’t stop the mouse following the window, it justs add synchrony.
I know that some exwm settings don’t work if configured after exwm is loaded, verify that things are setup correctly, particularly the EXWM major mode being below here.
Use `emacs-startup-hook` to fix this.
(when is-kitchensink
(global-set-key (kbd "<XF86AudioRaiseVolume>") #'alsamixer-up-volume)
(global-set-key (kbd "<XF86AudioLowerVolume>") #'alsamixer-down-volume)
(global-set-key (kbd "<XF86AudioMute>") #'alsamixer-toggle-mute))(when is-kitchensink
(global-set-key (kbd "<XF86MonBrightnessUp>") #'void)
(global-set-key (kbd "<XF86MonBrightnessDown>") #'void))(when is-kitchensink
(global-set-key (kbd "<XF86Sleep>") #'void));(when is-kitchensink
; (desktop-save-mode 1))(setq is-windmills (string= "windmills" (system-name)))(when is-windmills
(custom-set-faces '(default ((t (:height 98))))))(setq is-work (string= "PC0229718" (system-name)))(when is-work
(custom-set-faces '(default ((t (:height 80))))))(udh/install-and-load 'calendar)(require 'exwm-systemtray)
(exwm-systemtray-enable)(setq exwm-manage-force-tiling t)(setq exwm-workspace-number 10)Bind keys 0-9 to workspaces.
(setq exwm-input-global-keys
`(;([?\s-r] . exwm-reset)
;([?\s-w] . exwm-workspace-switch)
,@(mapcar (lambda (i)
`(,(kbd (format "s-%d" i)) .
(lambda ()
(interactive)
(exwm-workspace-switch-create ,i))))
(number-sequence 0 9))))
(define-key exwm-mode-map [?\C-q] 'exwm-input-send-next-key)Bind S-<XF86Back> and S-<XF86Forward> to move between frames or workspaces.
I don’t like bindings to C-c, not really sure why. There are several bindings to C-c in EXWM, move them over to s- bindings.Some of the default bindings are:
| C-c C-f | exwm-layout-set-fullscreen | Enter fullscreen mode |
| C-c C-h | exwm-floating-hide | Hide a floating X window |
| C-c C-k | exwm-input-release-keyboard | Switch to char-mode |
| C-c C-m | exwm-workspace-move-window | Move X window to another workspace |
| C-c C-q | exwm-input-send-next-key | Send a single key to the X window; can be prefixed with C-u to send multiple keys |
| C-c C-t C-f | exwm-floating-toggle-floating | Toggle between tiling and floating mode |
| C-c C-t C-m | exwm-layout-toggle-mode-line | Toggle mode-line |
|---|
Probably map though them and bind them to S-c by default.
Unbind all C-c Commands. (Not sure if this sends C-c to underlying frame or just blocks it entirely.
(define-key exwm-mode-map (kbd "C-c") nil)(add-hook 'exwm-manage-finish-hook
(lambda ()
(when (and exwm-class-name
(string= exwm-class-name "XTerm"))
(exwm-input-set-local-simulation-keys '(([?\C-c ?\C-c] . ?\C-c))))))Unbind M-! or have some timeout command on it. Since Emacs is single threaded starting a non-forked task though M-! will block Emacs and therefore EXWM.
This is for when I use EXWM on a multi screen computer.(require 'exwm-randr)
(setq exwm-randr-workspace-output-plist '(0 "VGA1"))
(add-hook 'exwm-randr-screen-change-hook
(lambda ()
(start-process-shell-command
"xrandr" nil "xrandr --output VGA1 --left-of LVDS1 --auto")))
(exwm-randr-enable)(defun exwm-change-screen-hook ()
(let ((xrandr-output-regexp "\n\\([^ ]+\\) connected ")
default-output)
(with-temp-buffer
(call-process "xrandr" nil t nil)
(goto-char (point-min))
(re-search-forward xrandr-output-regexp nil 'noerror)
(setq default-output (match-string 1))
(forward-line)
(if (not (re-search-forward xrandr-output-regexp nil 'noerror))
(call-process "xrandr" nil nil nil "--output" default-output "--auto")
(call-process
"xrandr" nil nil nil
"--output" (match-string 1) "--primary" "--auto"
"--output" default-output "--off")
(setq exwm-randr-workspace-output-plist (list 0 (match-string 1)))))))Find a nest-able tabbed interface to use. Some options are: Nerdtab, frame-tabs, rings, tab-group, tabbar, or there might be a EXWM builtin.
Currently M-& starts an async program, replicate this behaviour except:- automaticly rename the created x buffer
- create a new async buffer.
;(setq exwm-input-global-keys (append exwm-input-global-keys
; `(,(kbd "s-x") .
; #'async-shell-command)))(when is-kitchensink
(udh/install-and-load 'exwm-mff)
(customize-set-variable 'exwm-mff-mode 't))
(setq mouse-autoselect-window t) ;; outside because I also use with i3
; (setq focus-follows-mouse t)I think it just needs to be run after X has started
Nope, it’s defiantly disabling sometimes.
Seemed fine for a few weeks, perhaps this is gone.
This would remove the case where the window sudenly switches from the track point being tapped.
;(udh/install-and-load 'org)
(use-package org
:pin gnu)
(require 'org)(setf (cdr (assoc 'file org-link-frame-setup)) 'find-file)(add-hook 'org-mode-hook #'flyspell-mode)(add-hook 'org-mode-hook #'auto-fill-mode)(add-hook 'org-mode-hook #'centered-cursor-mode)(defun udh/org-disable-tabs ()
"Made sure tabs settings are local and then turn them off."
(make-variable-buffer-local 'indent-tabs-mode)
(setq indent-tabs-mode nil))
(add-hook 'org-mode-hook
#'udh/org-disable-tabs)(defun org-collapse-element ()
"Moves to parent element and then collapses it."
(interactive)
(org-up-element)
(org-cycle))
(defun udh/org-mode-keys ()
(local-set-key (kbd "RET") 'org-return-indent)
;;(local-set-key (kbd "M-C-RET") 'org-return)
(local-set-key (kbd "M-[") 'org-backward-element)
(local-set-key (kbd "M-]") 'org-forward-element)
(local-set-key (kbd "M-{") 'org-collapse-element)
(local-set-key (kbd "M-}") 'org-down-element))
;;(add-hook 'org-mode-hook
;; #'udh/org-mode-keys)I’d like to have `showstars`, `indent`, and `inlineimages` enabled by default; however, I’m not sure if that’s a safe idea, since it’s better to have each file be self contained.
This is currently disabled becauseorg-trello erroneously marks
ido as required.
(add-to-list 'auto-mode-alist '("\\.trello$" . org-mode))
;; TODO: Find a better way to detect this.
;;(defun udh/org-trello-detect ()
;; (let ((filename (buffer-file-name (current-buffer))))
;; (when (and filename (string= "trello" (file-name-extension filename)))
;; (org-trello-mode))))
;;(add-hook 'org-mode-hook #'udh/org-trello-detect)Call org-trello/sync-buffer when the buffer is saved.
(org-babel-do-load-languages
'org-babel-load-languages
'((emacs-lisp . t)
(dot . t)
(octave . t)
(lisp . t)
(scheme . t)
(python . t)
(plantuml . t)
(R . t)))(udh/install-and-load 'ob-spice)
(udh/install-and-load 'ob-async)
(udh/install-and-load 'ob-diagrams)
(udh/install-and-load 'ob-octave)(setq org-confirm-babel-evaluate nil)(udh/install-and-load 'slime)
(setq inferior-lisp-program "clisp")(udh/install-and-load 'geiser)
(setq scheme-program-name "guile")
(setq geiser-default-implementation 'guile)(udh/install-and-load 'plantuml-mode)
(setq org-plantuml-jar-path (expand-file-name "~/build/planttext/plantuml.jar"))
(add-to-list 'org-src-lang-modes '("plantuml" . plantuml))(udh/install-and-load 'pyvevn)Maybe check for a folder with the same name as the current file. Might use the pyenv.make I wrote earlier.
I used to have `ob-tmux` installed, see why. Add a latex uspackage forlistings in the offending document.
(customize-set-variable 'org-src-preserve-indentation 't)
(add-to-list 'org-latex-packages-alist '("" "listingsutf8"))This is part of a more general philosophy I’m trying to enforce; that org-mode and it’s agenda is part of the interface of Emacs rather than a separate thing inside of it. That all things being done are being done in a project and so that perspective should be wrapping it.
(udh/install-and-load 'org-fragtog)
(add-hook 'org-mode-hook #'org-fragtog-mode)
(add-to-list 'org-latex-packages-alist '("" "amsmath" t))
; needed? (add-to-list 'org-latex-packages-alist '("" "amssymb" t))
(add-to-list 'org-latex-packages-alist '("" "braket" t))
(add-to-list 'org-latex-packages-alist '("" "tikz" t))
(add-to-list 'org-latex-packages-alist '("" "arrows.meta" t))
(add-to-list 'org-latex-packages-alist '("" "positioning" t))
(add-to-list 'org-latex-packages-alist '("" "mathtools" t))
(add-to-list 'org-latex-packages-alist '("" "physics" t))
(add-to-list 'org-latex-packages-alist '("" "xfrac" t))Org-mode offers a BEGIN_CENTER header; but, it forgets how to highlight org-mode within that region. It’s probably defaulting to text-mode.
I use a lot of latex in some of my documents, it would be nice if auto-fill didn’t wrap at what seems like random locations. It’s wrapping based on the underlying latex text rather than the image size.
If I have an inlined latex preview image, when I type, if the cursor is on the image, it will place the first leter before the image (as it should) and then move the cursor off of the image to after it. This is not how it works on chars, where the cursor just stays on top of the char while typeing.
This used to be installed, what is it for? ;; org-preview-html
I often switch to the overview and then need to scroll up to see everything, even though it all fits.
I like follow mode some times. Enable this (or the like) in org buffers that are split and in the same frame and workspace.
Pressing M-q on a long funciton call will split strings over
multiple lines, breaking the python string syntax.
I think it happens when I switch on follow mode.
Look into the secretaria package
They stopped being auto folded, I think this is a bug in org-roam.
This also hides code blocks; but, that’s probably ok.
(setq org-hide-block-startup t
org-startup-folded "fold")I don’t like the pile of old dired buffers that builds up.
This might be better served by a specific mode for previewing folders. `envrc`?
pandoc can’t do .doc files
see info:emacs#Document View footnote 1
Indentation and alignment are a contentious topic in C family languages. I think the most reasonable solution is to have user’s editors display it however they like. The indentation paradigm that most respects users in this is tabs for indentation and spaces for alignment.(udh/install-and-load 'smart-tabs-mode)
(smart-tabs-insinuate 'c 'c++)(udh/install-and-load 'flycheck)
(udh/install-and-load 'flymake)
(udh/install-and-load 'flymake-cursor)
(udh/install-and-load 'flymake-easy)(udh/install-and-load 'arduino-mode)(defun udh/c-mode-layout ()
;;(glasses-mode 1)
(require 'flymake-cursor)
(setq-default c-basic-offset 2
;;tab-width 2
;;indent-tabs-mode t
)
(hs-minor-mode 1)
;;(hideshowvis-minor-mode 1)
;;(hideshowvis-symbols)
(linum-relative-mode 1)
(centered-cursor-mode 1)
;;(hl-line-mode 1)
;;(highlight-blocks-mode 1)
;;(highlight-current-line-minor-mode 1)
;;(highline-mode 1)
(flycheck-mode 1)
(flyspell-prog-mode))
(add-hook 'c-mode-common-hook
#'udh/c-mode-layout)
(defun udh/c-mode-keys ()
(local-set-key (kbd "C-,") 'flycheck-next-error)
(local-set-key (kbd "C-t") 'hs-toggle-hiding)
(local-set-key (kbd "C-M-t") 'hs-hide-level)
(local-set-key (kbd "M-{") 'hs-hide-block)
(local-set-key (kbd "M-}") 'hs-show-block)
(local-set-key (kbd "C-S-b")
(lambda ()
"Enable flymake keys."
(interactive)
;;(flycheck-select-checker 'c/c++-cppcheck)
(flymake-mode -1)
(flymake-mode 1)
(local-set-key (kbd "C-M-S-e") 'flymake-goto-next-error)
(local-set-key (kbd "C-M-S-r") 'flymake-goto-prev-error)))
(local-set-key (kbd "C-M-S-b")
(lambda ()
"Disable flymake keys."
(interactive)
(flycheck-mode -1)
(flymake-mode -1)
(local-unset-key (kbd "C-M-S-e"))
(local-unset-key (kbd "C-M-S-r")))))
(setq tags-revert-without-query 1)
(add-hook 'c-mode-common-hook
#'udh/c-mode-keys)(setq path-to-ctags (executable-find "etags"))Shouldn’t emacs know where etags is?
(add-to-list 'auto-mode-alist '("\\.tpp\\'" . c++-mode))
(add-to-list 'auto-mode-alist '("\\.ino\\'" . c++-mode))(defun udh/C-Family-prettify ()
"Enable pretty symbols - Targeted at C family languages."
(pretty-mode 1)
(pretty-regexp ">=" "≥")
(pretty-regexp "<=" "≤")
(pretty-regexp "!=" "≠")
(pretty-regexp "==" "≡")
(pretty-regexp "!" "¬")
(pretty-regexp "||" "∥")
(pretty-regexp "false" "⊭")
(pretty-regexp "true" "⊨")
(pretty-regexp "//" "⑊")
(pretty-regexp "()" "≬")
(pretty-regexp "[*]" "∗"))(udh/install-and-load 'ctags)
(udh/install-and-load 'ctags-update)(defun udh/c-common-prettify ()
"Enable pretty symbols in C."
(udh/C-Family-prettify)
(pretty-regexp "--" "↧");"↓"
(pretty-regexp "[+][+]" "↥");"↑"
(pretty-regexp "float" "ℝ")
(pretty-regexp "\bint\b" "ℤ")
(pretty-regexp "char" "¶")
(pretty-regexp "void" "Ø")
(pretty-regexp "//" "⑊")
;;(pretty-regexp "const" "𝌸")
;;(pretty-regexp "[/][/][*]" "∫∮" )
;;(pretty-regexp "[*][/][/]" "∮∫" )
;;(pretty-regexp "[*][/]" "∮" )
;;(pretty-regexp "[/][*]" "∮" )
)
(add-hook 'c-mode-common-hook
#'udh/c-common-prettify);;(defun udh/set-flycheck-cpp-language-standard
;; (setq flycheck-clang-language-standard "c++1z"))
;;(add-hook 'c++-mode-hook
;; #'udh/set-flycheck-cpp-language-standard)(udh/install-and-load 'cppcheck)
(udh/install-and-load 'flymake-cppcheck)(defun udh/cpp-prettify ()
"Enable pretty symbols in Cpp."
(udh/c-common-prettify)
(pretty-regexp " *> > >" "⋙")
(pretty-regexp "< < < *" "⋘")
(pretty-regexp " *> >" "≫")
(pretty-regexp "< < *" "≪")
(pretty-regexp "<<" "《");"⩽"
;;(pretty-regexp "< < <" "⫹")
(pretty-regexp ">>" "》");"⩾"
;;(pretty-regexp "> > >" "⫺")
;;(pretty-regexp "[.]unlock()" "")
;;(pretty-regexp "[.]lock()" "")
(pretty-regexp "std::deque" "ℚ");ɋʠ
(pretty-regexp "std::function" "ℱ");∳ƒⁿ
(pretty-regexp "std::ostream" "水");⇴⌫⼮
(pretty-regexp "std::atomic" "⚛");⌬
(pretty-regexp "std::thread" "⎇");↛ ⇶
(pretty-regexp "std::mutex" "↹");Θ ҉ ҈ ⊙ ↺
(pretty-regexp "std::map" "↦");"≔"
(pretty-regexp "std::pair" "⑵");"②";"ʭ"
(pretty-regexp "std::make_pair" "mk⑵")
(pretty-regexp "std::vector" "→")
(pretty-regexp "std::cin" "⌨")
;;(pretty-regexp "std::buffer" "𝌖")
(pretty-regexp "[.]second" "₂")
(pretty-regexp "[.]first" "₁")
(pretty-regexp "template" "◳")
(pretty-regexp "()" "≬")
(pretty-regexp "std" "§");"準"
(pretty-regexp "::" "∷");"⁞"
(pretty-regexp "symbol" "※")
(pretty-regexp "Symbol" "⁜")
(pretty-regexp "Stream" "川")
(pretty-regexp "Thread" "⇶")
(pretty-regexp "Array" "⇻")
(pretty-regexp "Tree" "ᛘ");𝌎
;;(pretty-regexp "Key" "🔑")
(pretty-regexp "[*]" "∗"))
;;(add-hook 'c-mode-common-hook #'udh/c-mode-prettify)
(add-hook 'cpp-edit-mode-hook
#'udh/cpp-prettify)(udh/install-and-load 'openscad-mode)(defun udh/scad-prettify ()
"Enable pretty symbols in SCAD."
(pretty-mode 1)
(udh/C-Family-prettify)
(pretty-regexp "module" "◳"))
(add-hook 'scad-mode-hook 'udh/scad-prettify)(udh/install-and-load 'proof-general)(udh/install-and-load 'markdown-mode)
(add-to-list 'auto-mode-alist '("\\.md\\'" . markdown-mode));;(require 'rainbow-blocks)
;;(add-hook 'tty-setup-hook
;; (add-hook 'lisp-mode-hook
;; 'rainbow-blocks-mode)
(add-hook 'scheme-mode-hook
(lambda () (setq indent-tabs-mode nil)))(defun udh/lisp-prettify ()
(pretty-mode 1)
(pretty-regexp "lambda" "λ")
(pretty-regexp "#f" "⊭")
(pretty-regexp "#t" "⊨")
(pretty-regexp "()" "≬"))
(defun udh/lisp-prettify-maths ()
(pretty-regexp "member?" "∈")
(pretty-regexp "union" "∪")
(pretty-regexp "intersection" "∩"))
(add-hook 'scheme-mode-hook 'udh/lisp-prettify)
(add-hook 'clojure-mode-hook 'udh/lisp-prettify)(udh/install-and-load 'cider)(setq org-babel-python-command "python3")(udh/install-and-load 'erc) ; builtin
(add-hook 'erc-mode-hook
#'turn-on-flyspell)
(add-hook 'erc-disconnected-hook
(lambda (nick host-name reason)
;; Re-establish the connection even if the server closed it.
(setq erc-server-error-occurred nil)))
(setq erc-lurker-hide-list '("JOIN" "PART" "QUIT","MODE"))
(setq erc-lurker-threshold-time 3600)
;;(setq erc-hide-list '("JOIN" "PART" "QUIT" "MODE"))
;;(setq erc-hide-list '())
(setq erc-log-channels-directory "~/.erc/logs/")
(add-hook 'erc-insert-post-hook 'erc-save-buffer-in-logs)
;;that might make erc slow
;;the forums are unsure
;;https://www.emacswiki.org/emacs/ErcLogging#toc6erc-imageerc-status-sidebarerc-youtubeorerc-yt
;(setq telega-proxies
; (list
; '(:server "127.0.0.1" :port 9250 :enable t
; :type (:@type "proxyTypeSocks5"))))(add-hook 'telega-chat-mode-hook
#'turn-on-flyspell)Have the time next to the day for older messages.
Use day name for past few days. I think it currently is just doing it for this week.
The old s command from ed is commonly used in IRC to correct typos.
Seeing as message editing is allowed in telegram, this could actuly
edit the messages. Add an advice around sending messages to do this.
(add-hook 'telega-chat-mode-hook
#'centered-cursor-mode)(udh/install-and-load 'emojify)
(add-hook 'telega-root-mode-hook 'emojify-mode)
(add-hook 'telega-chat-mode-hook 'emojify-mode)For example the emoji for a person shrugging can be modified by a skin colour and a gender. Display each of those three icons in a row instead of combining them..
Currently text emoticons like “:)” are changed into icons as well.
Either don’t change 👍 into a thumbs up for me or have
telega-chatbuf-input-send convert it to one before sending.
;TODO: guix install mu isync
(require 'mu4e)
;mkdir the mail directory
;mu init --my-address='Address' ; this should be automagicable;(quelpa '(matrix-client
; :fetcher github :repo "alphapapa/matrix-client.el"
; :files (:defaults "logo.png" "matrix-client-standalone.el.sh")
; :upgrade nil))
;(unload-feature 'matrix-client)Currently when I load matrix-client-frame a new workspace is
created. This is strange and undesirable. Find a way to close the
workspace as a temporary fix; but, find out why this is happening.
(udh/install-and-load 'elpher)
(defun elpher/eww-browse-url (original url &optional new-window)
"Handle gemini and gopher links."
(cond ((string-match-p "\\`\\(gemini\\|gopher\\)://" url)
(require 'elpher)
(elpher-go url))
(t (funcall original url new-window))))
(advice-add 'eww-browse-url :around 'elpher/eww-browse-url)Also update the wiki when you fix this.
(udh/install-and-load 'dyalog-mode)(udh/install-and-load 'gnu-apl-mode)(udh/install-and-load 'j-mode)(udh/install-and-load 'octave-mode)(udh/install-and-load 'matlab-mode)
(add-to-list
'auto-mode-alist
'("\\.m$" . matlab-mode))
(setq matlab-indent-function t)
(setq matlab-shell-command "matlab.exe")Forgive the exe tag, this is for my work computer’s WSL environment.
Use matlab.exe -batch "1+1" to run scripts on the shell.
(add-hook 'matlab-mode-hook 'whitespace-mode)
;(add-hook 'matlab-mode-hook 'whitespace-cleanup)
;(add-hook 'matlab-mode-hook 'indent-buffer)(udh/install-and-load 'ess);; udh/install-and-load pascal-mode ; I presume
(add-to-list 'auto-mode-alist '("\\.simba\\'" . pascal-mode))(udh/install-and-load 'magit)
(udh/install-and-load 'magit-filenotify)
(udh/install-and-load 'magit-popup)
(udh/install-and-load 'magit-tramp)Have magit print the hash of a commit after making it.
Magit clean deletes temporary files, I’m using that state please don’t.(put 'magit-clean 'disabled nil)Magit dosen’t seem to find this reposistory when I open this file from its linked location.
This seems to break magit.;(udh/install-and-load 'magit-gh-pulls)
;(add-hook 'magit-mode-hook 'turn-on-magit-gh-pulls)(udh/install-and-load 'tramp)
(udh/install-and-load 'tramp-term)
(setq tramp-default-method "ssh")(set-default 'tramp-default-proxies-alist (quote ((".*" "\\`root\\'" "/ssh:%h:"))))if I click an [[org link]] in a buffer that is ssh’ed with tramp, I
Disabled since not needed currentlyexpect it to open a file in the
Disabled since not needed currentlysame tramp.
I would like /ssh:host:~user/ to work, or something like it.
Hmm, now that I’m watching, it’s not.
This is a particular problem when the same term is open on two desktops. The mouse flickers between them so you can’t type without selectin
Anki is a spaced repetition system. The module Anki-Editor and the Anki addon AnkiConnect are used to generate the cards in orgmode. I use AnkiDroid as my client which supports native mathjax, due to a bug this must be done before the plug ins loaded.;;(setq-default anki-editor-use-math-jax t)
(setq-default anki-editor-latex-style 'mathjax)
(udh/install-and-load 'anki-editor)anki-editor-push-notes to open an
async Anki and then close the async once it’s done with it.
;(async-shell-command "anki")
;(exwm-input--fake-key ?\k)I often want more than one info book open at a time. This might be better done with org links and a folder.
(when is-windmills
(add-to-list 'load-path "/usr/lib64/erlang/lib/tools-3.6/emacs/")
(setq erlang-root-dir "/usr/lib64/erlang")
(add-to-list 'exec-path "/usr/lib64/erlang/bin")
(require 'erlang-start))The Tao gave birth to machine language. Machine language gave birth to the assembler.
The assembler gave birth to the compiler. Now there are ten thousand languages.
Each language has its purpose, however humble. Each language expresses the Yin and Yang of software. Each language has its place within the Tao.
But do not program in COBOL if you can avoid it.
– The Tao of programming : Book 1 Canto 2
I feel that Java fills the same position as COBOL did. It’s an excessively verbose language that use “best practices” as a substitute for good design. In both cases this is because the language is relegated to those who haven’t groked program/computer architecture at the basic levels[fn::Many because they haven’t cared to; but, a few because they are only programmers for economic reasons.]; but, at least COBOL recognised and embraced that.
(defun udh/whitespace-settings ()
(whitespace-mode 1)
(if (display-graphic-p)
(setq whitespace-style
'(face tabs spaces trailing space-before-tab
newline indentation empty space-after-tab
space-mark tab-mark newline-mark))
(setq whitespace-style
'(face tabs trailing space-before-tab
newline indentation empty
space-mark tab-mark newline-mark))))
(add-hook 'whitespace-load-hook 'udh/whitespace-settings)
(setq whitespace-empty-at-eob-regexp "^
\\([
]+\\)");set it not to care about the first empty line (org files tend to have one)Move flymake errors to mini-buffer.
Installed from https://github.com/bkaestner/secret-mode.el
I often want to speak/type in my accent. Now that I’m chatting over Emacs, I can.(defun udh/to-ipa ($string &optional $from $to)
"Convert a string or the selected region to IPA using espeak."
(interactive
(if (use-region-p)
(list nil (region-beginning) (region-end))
(let ((bds (bounds-of-thing-at-point 'paragraph)) )
(list nil (car bds) (cdr bds)) ) ) )
(let (workOnStringP inputStr outputStr)
(setq workOnStringP (if $string t nil))
(setq inputStr (if workOnStringP $string (buffer-substring-no-properties $from $to)))
(setq outputStr
(udh/shell
(concat "espeak -q --ipa" " " "\"" inputStr "\"")))
(if workOnStringP
outputStr
(save-excursion
(delete-region $from $to)
(goto-char $from)
(insert outputStr) )) ) )The function indent-region is useful, but not great in scripts.
(defun indent-buffer ()
"Indent the currently visited buffer."
(interactive)
(indent-region (point-min) (point-max)))`hilight` `highlight-blocks` `highlight-current-line` `highlight-indentation` `highlight-parentheses`
;; (udh/install-and-load ‘tmux-pane)
;; (udh/install-and-load ‘visible-mark)
;;(yas-reload-all)
;;(setq yas-snippet-dirs '("~/emacs.d/snippets"))
;;(setq yas/root-directory '"~/.emacs.d/snippets")
;;(yas/reload-all)(udh/install-and-load ‘helm-config) (helm-mode 1)
Packages `vagrant` and `vagrant-tramp`
(defun org-transpose-paragraphs (arg) (interactive) (when (and (not (or (org-at-table-p) (org-on-heading-p) (org-at-item-p))) (thing-at-point ‘sentence)) (transpose-paragraphs arg) (backward-paragraph) (re-search-forward ”:graph:”) (goto-char (match-beginning 0)) t)) (add-to-list ‘org-metaup-hook (lambda () (interactive) (org-transpose-paragraphs -1))) (add-to-list ‘org-metadown-hook (lambda () (interactive) (org-transpose-paragraphs 1)))
(defun org-log-current-defun () (save-excursion (org-back-to-heading) (if (looking-at org-complex-heading-regexp) (match-string 4)))) (add-hook ‘org-mode-hook (lambda () (make-variable-buffer-local ‘add-log-current-defun-function) (setq add-log-current-defun-function ‘org-log-current-defun)))
(add-to-list ‘org-latex-classes ‘(“udh-books” “\documentclass{book} \usepackage{braket}” (“\part{%s}” . “\part*{%s}”) (“\chapter{%s}” . “\chapter*{%s}”) (“\section{%s}” . “\section*{%s}”) (“\subsection{%s}” . “\subsection*{%s}”) (“\subsubsection{%s}” . “\subsubsection*{%s}”)))
(add-to-list ‘org-latex-classes ‘(“udh-article” “\documentclass{scrartcl} \usepackage{braket}” (“\section{%s}” . “\section*{%s}”) (“\subsection{%s}” . “\subsection*{%s}”) (“\subsubsection{%s}” . “\subsubsection*{%s}”) (“\paragraph{%s}” . “\paragraph*{%s}”) (“\subparagraph{%s}” . “\subparagraph*{%s}”)))
(add-to-list ‘org-latex-classes ‘(“udh-pub” “\documentclass{book} \usepackage{braket}” (“\chapter{%s}” . “\chapter*{%s}”) (“\section{%s}” . “\section*{%s}”) (“\subsection{%s}” . “\subsection*{%s}”) ;(“\subsubsection{%s}” . “\subsubsection*{%s}”) ;(“\paragraph{%s}” . “\paragraph*{%s}”) ;(“\subparagraph{%s}” . “\subparagraph*{%s}”) ))
; Forward/Preface ; Table of Contents ; Introduction ; Chapter 1 ; …
Org-drill? outline-toc?
If a file moves, the link cache will forget where it is. This also opens all of the org files, so it needs to be after all other configuration.Disabled because this opens every org file I have at startup, which is pretty annoying.
;(org-id-update-id-locations)(defun udh/org-sdate-name-to-property ()
"I've named a lot of org headings in the format \"date - name\" and I'd
like to move that date into the properties drawer."
(interactive)
(let ((current_name (nth 4 (org-heading-components)))
(date_pattern "[0-9][0-9][0-9][0-9][0-9]?")
(separator_pattern " - ")
(title_pattern ".+"))
(if (string-match (concat "^"
date_pattern
separator_pattern
title_pattern
"$")
current_name)
(let ((new_name (replace-regexp-in-string
(concat date_pattern
separator_pattern)
""
current_name))
(date (replace-regexp-in-string
(concat separator_pattern
title_pattern)
""
current_name)))
(org-set-property "CREATION_DATE" date)
(org-edit-headline new_name)))))
;; (org-map-entries 'udh/org-sdate-name-to-property)(defun udh/org-date-name-to-property ()
"I've named a lot of org headings in the format \"date - name\" and I'd
like to move that date into the properties drawer."
(interactive)
(let ((current_name (nth 4 (org-heading-components)))
(date_pattern "20[0-9][0-9]-[0-1][0-9]-[0-3][0-9]")
(separator_pattern " - ")
(title_pattern ".+"))
(if (string-match (concat "^"
date_pattern
separator_pattern
title_pattern
"$")
current_name)
(let ((new_name (replace-regexp-in-string
(concat date_pattern
separator_pattern)
""
current_name))
(date (replace-regexp-in-string
(concat separator_pattern
title_pattern)
""
current_name)))
(org-set-property "CREATION_DATE" (udh/date-to-sdate date))
(org-edit-headline new_name)))))
;; (org-map-entries 'udh/org-sdate-name-to-property)If the title is exactly “Daily Note”, get the “CREATION_DATE” and add that to the title as “Daily Note (10056)”
(defun udh/add-date-to-daily ()
"I've named a lot of org headings in the format \"date - name\" and I'd
like to move that date into the properties drawer."
(interactive)
(let ((current_name (nth 4 (org-heading-components)))
(date_pattern "20[0-9][0-9]-[0-1][0-9]-[0-3][0-9]")
(separator_pattern " - ")
(title_pattern ".+"))
(if (string-match (concat "^"
date_pattern
separator_pattern
title_pattern
"$")
current_name)
(let ((new_name (replace-regexp-in-string
(concat date_pattern
separator_pattern)
""
current_name))
(date (replace-regexp-in-string
(concat separator_pattern
title_pattern)
""
current_name)))
(org-set-property "CREATION_DATE" (udh/date-to-sdate date))
(org-edit-headline new_name)))))
;; (org-map-entries 'udh/org-sdate-name-to-property)