Skip to content

Latest commit

 

History

History
2738 lines (2658 loc) · 87.7 KB

File metadata and controls

2738 lines (2658 loc) · 87.7 KB

-*- mode: org; eval: (org-show-todo-tree ‘()) -*-

README

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.

General Philosophy

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

Personage Attributes

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

Buffer-wide TODO states

The following line allows blocks to be marked as broken or unused.

Does the WORKING tag still disable the code?

If so move DISABLED to green and remove the WORKING tag.

Emacs Core Settings

These are settings that are relating to the core of Emacs rather than any the things I do with it.

Disable Custom

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

Allow Local Values

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

Setup Packages

Install and manage all of the packages I use.
(require 'package)
(require 'use-package)

Package Repositories

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

Package Installation and Loading Settings

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

Add a notification when there are updates

;;(package-utils-upgrade-all)

This should probably be done with emacs-dashboard.

Convert to macro so that package name doesn’t need quoting

Take the package configuration as a second argument

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.

Non-elpa Packages

Quelpa is a package for installing packages from git repositories rather than package archives.

Disabled since not needed currently.

;(udh/install-and-load 'quelpa)

Some packages need to be installed on the OS level

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.

GNU Keyring

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)

Interface Defaults

(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"))

Disable C-[ override

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

Ask-Before-Closing

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

Persistent-Scratch

(udh/install-and-load 'persistent-scratch)
(persistent-scratch-setup-default)

Fix IDO

Allow opening folders
(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

ELisp features

Void

Sometimes it’s important to assign a function to something, but the function doesn’t matter. For example, Kitchensink’s Screen Brightness keys.
(defun void (&rest ignored)
  "Do nothing, quietly."
  (interactive "p"))

setq-append

I often want to append to a configuration value in this config, particularly for exwm and customize. Build a macro `(setq-append var val)` that becomes `(setq var (append var val))`. If i understand correctly, this needs to be a macro because the first param to `setq` need to be referencable by name. This might be false if the refrence is back treaceable in elisp.

Shell Command

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

sdate

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

rewrite this in elisp

GTD

“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.

ActionKey-bindLocation
AgendaC-c a gGlobal
CaptureC-c cGlobal
EffortC-c C-x eOrg Header
RefileC-c C-wOrg Header
Task ListC-c a tGlobal
TimestampC-c .Org
T-stamp DeadlineC-c dOrg
T-stamp InactiveC-c !Org
T-stamp ScheduleC-c sOrg

Add attribution to Cortex and Cyborganise

Relevant Files

I’ve made a ~~/.agenda_files~ that is auto loaded. Either move its content here or move the file into version control. I made the file because I couldn’t get lists to work in the below code.
;;(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"))

Capture to Inbox

Review this now that we have 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)

Capture from anywhere

When I press `C-c c` in some buffers (like scratch) I get the error

user-error: No method for storing a link from this buffer

Capture from mu4e

This is for once I’m using mu4e.
;("@" "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)

Add numeric priorities.

info:Org#Priorities

Track event creation and sorting in properties

Agenda

ActionKey-bind
Mark Donet
(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")))))))

Don’t list events with deadlines in second, regular, TODO section.

Have Org-Agenda not close all other windows

Include Diary Events in Calendar

Find diary style events in the agenda files and include them in the calendar view.
(setq org-agenda-include-diary t)

Calendar Windowing

Show 9 days starting with yesterday; that is, yesterday, today, and the coming week.
(setq org-agenda-start-day "-1d")
(setq org-agenda-span 9)
(setq org-agenda-start-on-weekday nil)

This only seems to show 7 days

This is showing 9 days in the agenda view.

Don’t clutter with obvious tasks.

There’s no need to show the daily repeating unscheduled tasks on everyday after the first.

Yes there is

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.

Google Calendar Things

Sort events by both importance cookies and time estimate

Time Tracking

ActionKey-bindLocation
Clock inC-c C-x iOrg Header
Clock OutC-c C-x oOrg Header
Set Time EstimateC-c C-x eOrg Header

Track When Tasks are Completed

(setq org-log-done 'time)

Star a timer when opening a file via a org link

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 save and open project setups, track time with them.

Time Estimation

Find a way to insert this into task creation or sorting.

Track when activity becomes doable

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

Have that track the NEXT to TODO change instead?

Project Management

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.

Roam

Major Package

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)

Startup

Move to init.el.

;(org-roam-db-sync t)
;(org-roam-db-autosync-mode)

Keybindings

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

Automatically add added notes to added notes

By default newly added notes aren’t added to the note cache, so the database is permanently out of sync.
(org-roam-db-autosync-enable)

Capture Template

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

Daily Capture Template

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

Single Line Backlinks

I only want to show the line that references the link, not the whole section.
(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)

I’d prefer the current “thing”

  • 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.

org roam refile as file

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

My Rebuild

This is largely outdated as org-roam is now mature enough for usage.

I’m just going to build the tools my self for now.

Generic Utilities

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

Custom IDs

Create

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

Update File

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

Update link

  ;; 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))))))))
Don’t open external links
The org-open-at-point opens the browser if the link is external.

Update All Links

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

Update Links Live

When the user types a link, update it. Checking for the close bracket is easy enough. This is much faster than walking the tree on save.
(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)))

Diagrams

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.

todo management

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.

Global Text Presentation Settings

Highlight Parentheses

(show-paren-mode 1)

Check if things are parenthesises

In many modes < and > are not bracketing symbols and shouldn’t be counted as mismatched brackets.

Set Theme

Pretty Mode

Having a good notation improves both reading speed and comprehension. Using `pretty-mode` I can reduce the amount of visual and mental space taken up by language boilerplate without reducing clarity.
(udh/install-and-load 'pretty-mode)

Cyan Mini-Buffer

I like cyan, make that the mini buffer text colour. This is set to terminal only because cyan isn’t readable on white.
(add-hook 'tty-setup-hook
          (lambda () (set-face-foreground 'minibuffer-prompt "cyan")))

Spell Check Everywhere

Spelling is hard, enable spell checking everywhere I can.
(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)

org-mode and magit-commit aren’t working

Looking into the run hooks, it claims that text-mode-hook should be run, org might just be clearing the minor mode away.

Undo Tree Everywhere

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)

Can I have that enable when called rather than always on?

I don’t expect that the efficiency implications of this will matter, but it’s good to care.

Whitespace

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)

Line Numbers should be Relative

(udh/install-and-load 'linum-relative)
(setq relative-line-numbers-motion-function 'forward-visible-line)

Absolute reference

Have line numbers that are multiples of five show though the relative numbers. Align them differently so they are easy to distinguish.

Code Folding

(udh/install-and-load 'hideshow)
(udh/install-and-load 'hideshowvis)

Keep Cursor Centred

Being able to manage one’s perspective into code independently to the location being edited is a pretty reasonable request and has been very advantageous for many years. However, given the increase in screen sizes, better Code Folding, and Pretty Mode, this independence is often unhelpful and extra work to maintain.
(udh/install-and-load 'centered-cursor-mode)

Global Keyboard Interface

(udh/install-and-load 'bind-key)

Interactive Compleation Buffers

I’m happy to say that the mess that was IDO has been largely replaced, several times. The feature is now stable enough that it’s useable.

The latest version, called ivy has been subsumed into a package called counsel.

(udh/install-and-load 'counsel)
(ivy-mode)

Disable in find file

The file finder is much easier when it is consistent with a terminal, so this is better disabled.

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)

Disable in M-x

I almost never want to search for a command; but, I regularly use the history. Disabling ivy for purpose. This may be better acomplished if I can have access to history with the up arrow but also allow search when typing. The two interaction modes are pretty exclusive, so this should be achievable.
(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)

Allow for non-Compleation

Currently C-M-j calls ivy-immediate-done, map that to C-<return>.

Navigation With C-c C-c

While not in org-mode, have 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)

This will need to link with GTD and maybe start a timer.

Find Fule At Point

There’s a thing called FFAP in the Emacs info manual. give it a read.

Frame Movement

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

Cursor Movement

I prefer 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"))

The best option would be for C-a to toggle.

Multiple Cursors

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

ret terminates multiple_cursors for some reason

Have middle click paste not move the cursor

I use the text cursor for text, not the graphic cursor. If I paste with the middle mouse button, I want it past where the text cursor is, not move it to the graphic cursor first.
(setq mouse-yank-at-point 't)

ED

Replicate the features of ED that I really like.

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.

Fold around point

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.

Computer or OS Specific

Termux

(setq is-termux
      (string-suffix-p "Android"
                       (udh/shell "uname -a")))

GUIX

(setq is-guix
      (not (string-suffix-p "not found"
                            (udh/shell "which guix"))))

Install guix.el

Install the packages for dealing with Guix.
(when is-guix
	  ;(udh/system "guix install emacs-guix")
  ;(udh/install-and-load 'guix)
  (udh/install-and-load 'pretty-sha-path))

install

 ;(when is-guix
	;(defn udh/install (guix

Kitchensink (x201)

Kitchen Sink is the name of my laptop. Check if that is this system so things can depend on that. This computer is trying to run Emacs as the operating system, LISP all the way down. The underlying system is Guix and I’ll be pulling as much of the configuration of that as I can into Emacs so that I can manage the system as a singular whole.
(setq is-kitchensink (string= "kitchensink" (system-name)))

Emacs

Use Tor

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

Theme

Transparency
Set frames to have an alpha content of 85%. And 85% when inactive.
(when is-kitchensink
	    (load-theme 'wheatgrass)
    (add-to-list 'default-frame-alist '(alpha . (85 . 85))))
This makes everything transparent, not just the background.

This difference only matters with viewing pictures in telega.

Font
(when is-kitchensink
    (custom-set-faces '(default ((t (:height 93))))))

Visual Bell

This disables the audio bell.
(when is-kitchensink
    (setq visible-bell 1))

Start EXWM

The majority of EXWM’s settings are in it’s mode configuration below, this is just to start it and specify any system specific settings.
(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.

Verify EXWM load order

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.

Hardware Controls

Volume Keys

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

Screen Brightness

These keys are already work correctly, but Emacs also receives them and complains.
(when is-kitchensink
  (global-set-key (kbd "<XF86MonBrightnessUp>") #'void)
  (global-set-key (kbd "<XF86MonBrightnessDown>") #'void))

Sleep

This key is already work correctly, but Emacs also receives it and complains.
(when is-kitchensink
  (global-set-key (kbd "<XF86Sleep>") #'void))
Start a VTerm Lock on sleep

ThinkLight

Waiting on kernel changes in kitchensink.scm.

Interface Recovery

This needs testing/trying. I’m puting this here more as a note than a setting.
;(when is-kitchensink
;  (desktop-save-mode 1))

Windmills (Tower)

(setq is-windmills (string= "windmills" (system-name)))

Decrease emacs default font size two points

(when is-windmills
    (custom-set-faces '(default ((t (:height 98))))))

PC0229718

(setq is-work (string= "PC0229718" (system-name)))

Decrease emacs default font size

(when is-work
    (custom-set-faces '(default ((t (:height 80))))))

Major Mode Settings

Calendar

Not sure what installing this adds, but it needed reorganising.
(udh/install-and-load 'calendar)

EXWM

EXWM isn’t loaded here since it’s only wanted on some systems.

Only run this section if exwm is loaded

System Tray

(require 'exwm-systemtray)
(exwm-systemtray-enable)

No Floating Windows

(setq exwm-manage-force-tiling t)

Key-binds

Workspaces

Initialize all 0-9 workspaces.
(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)
Also bind shift 0-9 to 10-19 to match i3

Map S-x to start programs

Back and Fourth Hardware Keys

Bind S-<XF86Back> and S-<XF86Forward> to move between frames or workspaces.

Rescue C-c keys

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-fexwm-layout-set-fullscreenEnter fullscreen mode
C-c C-hexwm-floating-hideHide a floating X window
C-c C-kexwm-input-release-keyboardSwitch to char-mode
C-c C-mexwm-workspace-move-windowMove X window to another workspace
C-c C-qexwm-input-send-next-keySend a single key to the X window; can be prefixed with C-u to send multiple keys
C-c C-t C-fexwm-floating-toggle-floatingToggle between tiling and floating mode
C-c C-t C-mexwm-layout-toggle-mode-lineToggle 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)

Program Specific Bindings

I don’t have any yet, but they’ll follow this form if I do
(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))))))
IceCat
C-s for find C-< and C-> for home and end

Task Safety

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.

Multi Screen

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)

Dynamic Multiple Monitors

For when the docking station gets a second monitor and regular use again.
(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)))))))

Tabs

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.

start programs with s-x

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

Centre X cursor on frame movement

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

Only run this is exwm is installed; or, add it to an exwm startup hook

This needs to center the mouse on workspace switch

Sometimes this seems to stop and need re-enabling

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.

Run after starting X, rather than at startup

Perhaps also center on typing?

This would remove the case where the window sudenly switches from the track point being tapped.

Have all desktops generated and set to scratch on startup

<s-XF86Back> and <s-XF86Forward> to “incremnet” and “decrement” workspace

Org Mode

;(udh/install-and-load 'org)
(use-package org
		:pin gnu)
(require 'org)

Open Links in Same Window

(setf (cdr (assoc 'file org-link-frame-setup)) 'find-file)

Spell Check by Default

(add-hook 'org-mode-hook #'flyspell-mode)

Autofill by Default

(add-hook 'org-mode-hook #'auto-fill-mode)

Center The Cursor

(add-hook 'org-mode-hook #'centered-cursor-mode)

Disable Tabs

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

Folding

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

Set only last star to show and fake white-space before lines

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.

Org Trello

This is currently disabled because org-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)

Sync on save

Call org-trello/sync-buffer when the buffer is saved.

Org Babel

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

Sort - other languages

(udh/install-and-load 'ob-spice)
(udh/install-and-load 'ob-async)
(udh/install-and-load 'ob-diagrams)
(udh/install-and-load 'ob-octave)

Org Babel Confirmation

Have this ask once per language per file, as it’s currently written it’s a security hole.
(setq org-confirm-babel-evaluate nil)

SLIME

(udh/install-and-load 'slime)
(setq inferior-lisp-program "clisp")

Scheme

(udh/install-and-load 'geiser)
(setq scheme-program-name "guile")
(setq geiser-default-implementation 'guile)

Plantuml

Here is plantuml.jar link in case an update is needed.
(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))
Download this if it’s not there

Python

Python Environment
(udh/install-and-load 'pyvevn)
Try to detect environments folders and use them

Maybe check for a folder with the same name as the current file. Might use the pyenv.make I wrote earlier.

tmux

I used to have `ob-tmux` installed, see why.

PDF Formatting

Add a latex uspackage for listings in the offending document.
(customize-set-variable 'org-src-preserve-indentation 't)
(add-to-list 'org-latex-packages-alist '("" "listingsutf8"))

Move C-c C-t to C-c t to match Org-Agenda

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.

Preview Latex Fragment

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

LaTeX is not syntax hilighted in centerd region

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.

have org-fill-paragraph respect latexpreview

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.

have inline images act more like chars

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.

Unknown

This used to be installed, what is it for? ;; org-preview-html

When I global cycle the visibility to none, center the cursor

I often switch to the overview and then need to scroll up to see everything, even though it all fits.

follow-mode

I like follow mode some times. Enable this (or the like) in org buffers that are split and in the same frame and workspace.

Backspace doesn’t work on regions

Shift-Tab should de-indent

Tab doesn’t work on regions

re-wrapping long lines dosen’t understand strings

Pressing M-q on a long funciton call will split strings over multiple lines, breaking the python string syntax.

Move this to org-bable?

Something is disableing C-c . from being org-time-stamp

I think it happens when I switch on follow mode.

secretaria seems intresting

Look into the secretaria package

Fold PROPERTIES Draws

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

Dired

Replace buffers on open

I don’t like the pile of old dired buffers that builds up.

preview GIFs/mp4s

This might be better served by a specific mode for previewing folders. `envrc`?

use pandoc to open docx and some others

pandoc can’t do .doc files

see what unoconv can do

see info:emacs#Document View footnote 1

C Family Setting

Common Settings

Indent and Align

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

Interactive Compiling

Having compiler annotations and warning inline is very helpful to some forms of debugging and prototyping.
(udh/install-and-load 'flycheck)
(udh/install-and-load 'flymake)
(udh/install-and-load 'flymake-cursor)
(udh/install-and-load 'flymake-easy)

Arduino Language

Arduino doesn’t have much configuration yet, so it’s just hidden in here.
(udh/install-and-load 'arduino-mode)

Sort

(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)
I don’t use most of those, prune them and make a help table

Etags

(setq path-to-ctags (executable-find "etags"))
Why do I need to search for part of the emacs package?

Shouldn’t emacs know where etags is?

Non-Standard C Languages

(add-to-list 'auto-mode-alist '("\\.tpp\\'" . c++-mode))
(add-to-list 'auto-mode-alist '("\\.ino\\'" . c++-mode))

Pretty

(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 "[*]" ""))

C and CPP Settings

(udh/install-and-load 'ctags)
(udh/install-and-load 'ctags-update)

C Common Pretty

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

C Settings

CPP Settings

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

This compalines about something macro related, also we’re on 2a now

CPP Check

(udh/install-and-load 'cppcheck)
(udh/install-and-load 'flymake-cppcheck)

CPP Pretty

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

SCAD

(udh/install-and-load 'openscad-mode)

SCAD Pretty

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

Coq

(udh/install-and-load 'proof-general)

Markdown

(udh/install-and-load 'markdown-mode)
(add-to-list 'auto-mode-alist '("\\.md\\'" . markdown-mode))

Lisps

;;(require 'rainbow-blocks)
;;(add-hook 'tty-setup-hook
;;    (add-hook 'lisp-mode-hook
;;              'rainbow-blocks-mode)

Scheme

No Tabs

(add-hook 'scheme-mode-hook
          (lambda () (setq indent-tabs-mode nil)))

Pretty

(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)
disable builtin pretties

Clojure

I don’t remember needing this.
(udh/install-and-load 'cider)

Python

;;;for python ;;enable elpy ;(elpy-enable) ;; set compleat to C-c k ;(define-key yas-minor-mode-map (kbd “C-c k”) ‘yas-expand) ;; set iedit mode ;(define-key global-map (kbd “C-c o”) ‘iedit-mode)
(setq org-babel-python-command "python3")

Chats

IRC

The mode ERC is used for IRC in emacs.
(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#toc6

To Maybe install

  • erc-image
  • erc-status-sidebar
  • erc-youtube or erc-yt

Telegram

The package `telega` is for connecting to the telegram chat service. Install via `guix install emacs-telega -c 1` if guix is installed, otherwise use the melpa package and hope the compile stage succeeds (happens on first run).

Use Tor for Telega

This will need to be smarter about which system it is on later. Once tor is working as a global proxy this can grab settings from there.
;(setq telega-proxies
;      (list
;       '(:server "127.0.0.1" :port 9250 :enable t
;                 :type (:@type "proxyTypeSocks5"))))

Spell Check

(add-hook 'telega-chat-mode-hook
          #'turn-on-flyspell)

Timestamps

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.

Make ed style s editing

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.

Prevent the dowloads from auto deleting

Fill page with chat history

(add-hook 'telega-chat-mode-hook
          #'centered-cursor-mode)

Emojify

Emoji are nice to have in some chat programs in order to keep parity with the standard interface.
(udh/install-and-load 'emojify)
(add-hook 'telega-root-mode-hook 'emojify-mode)
(add-hook 'telega-chat-mode-hook 'emojify-mode)

There are probbably settings to look though.

Have combined emoji display as each part rather than one.

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..

Don’t change text emoticons

Currently text emoticons like “:)” are changed into icons as well.

Don’t change :: emotocons by default in telegram

Either don’t change 👍 into a thumbs up for me or have telega-chatbuf-input-send convert it to one before sending.

mu4e

;TODO: guix install mu isync
(require 'mu4e)
;mkdir the mail directory
;mu init --my-address='Address' ; this should be automagicable

isync

Matrix

This is currently disabled because the TODOs are too serious.
;(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)

Makes a new exwm workspace on load

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.

The matrix-client-room-list is empty

The error’s on refresh are periodic and really annoying

EWW

Have each tab rename to the active site Have calling M-x eww make a new tab from any buffer Make a bookmark org file Have a “bookmark and close” function Have a “Dump all tabs to bookmarks” function

Gopher

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

This doesn’t work

Also update the wiki when you fix this.

APL

(udh/install-and-load 'dyalog-mode)

keyboard

(udh/install-and-load 'gnu-apl-mode)

J

(udh/install-and-load 'j-mode)

Octave

(udh/install-and-load 'octave-mode)

Matlab

(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.

Auto fix whitespace

(add-hook 'matlab-mode-hook 'whitespace-mode)
;(add-hook 'matlab-mode-hook 'whitespace-cleanup)
;(add-hook 'matlab-mode-hook 'indent-buffer)

R

(udh/install-and-load 'ess)

Pascal

;; udh/install-and-load pascal-mode ; I presume
(add-to-list 'auto-mode-alist '("\\.simba\\'" . pascal-mode))

Python

‘guix install python python-ipython`

Magit

(udh/install-and-load 'magit)
(udh/install-and-load 'magit-filenotify)
(udh/install-and-load 'magit-popup)
(udh/install-and-load 'magit-tramp)

Emit Hashes into Messages

Have magit print the hash of a commit after making it.

Disable Magit Clean

Magit clean deletes temporary files, I’m using that state please don’t.
(put 'magit-clean 'disabled nil)

follow sym links

Magit dosen’t seem to find this reposistory when I open this file from its linked location.

github

This seems to break magit.
;(udh/install-and-load 'magit-gh-pulls)
;(add-hook 'magit-mode-hook 'turn-on-magit-gh-pulls)

Tramp

Tramp is an thing about remote computers. Fill this in later with more details.
(udh/install-and-load 'tramp)
(udh/install-and-load 'tramp-term)
(setq tramp-default-method "ssh")

Remote sudo

(set-default 'tramp-default-proxies-alist (quote ((".*" "\\`root\\'" "/ssh:%h:"))))

org links

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.

Remote Tilda Compleation

I would like /ssh:host:~user/ to work, or something like it.

Term

Term keeps stealing focus when the screen updates.

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

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)

On push open anki and then close it again

Since Anki syncs on open and close, there’s no real reason to have it running all the time. Advise 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)

Info

Have the name of the buffer change with the book

I often want more than one info book open at a time. This might be better done with org links and a folder.

Erlang

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

COBOL and Java

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.

Minor Mode Settings

Whitespace-Mode

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

Organize that code better and give the function a name

Flymake

Move flymake errors to mini-buffer.

secret-mode

Installed from https://github.com/bkaestner/secret-mode.el

Misc Utility Functions

IPA region

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

guix install espeak

Indent Buffer

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

Unsorted TODOs

Highlight Mode

`hilight` `highlight-blocks` `highlight-current-line` `highlight-indentation` `highlight-parentheses`

tmux pane

;; (udh/install-and-load ‘tmux-pane)

visible-mark

;; (udh/install-and-load ‘visible-mark)

YASnippet

;;(yas-reload-all)
;;(setq yas-snippet-dirs '("~/emacs.d/snippets"))
;;(setq yas/root-directory '"~/.emacs.d/snippets")
;;(yas/reload-all)

Helm

(udh/install-and-load ‘helm-config) (helm-mode 1)

Vagrant

Packages `vagrant` and `vagrant-tramp`

correct M-arrow to move paragraphs rather than single lines

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

magit change logs use current org heading as function for description

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

org-export latex settings

(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 ; …

Packages to look at

Org-drill? outline-toc?

Post Config Startup

Sync Org IDs

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)

Rather than at startup, run this when a link fails to be found?

If the file wasn’t already open, close it when scanned?

One Off Tools

Move sdate from org heading name to properties

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

Move regular date from org heading name to sdate in properties

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

Add Dates to “Dayly Note”s

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)