My main .emacs
file.
NOTE: For built-in packages, check out the emacs manual via: C-h r
!
Install via ansible with the following command, which will prompt for sudo
password (pacman package installation) due to the -K
or --ask-become-pass
flag:
cd ansible/
ansible-playbook main.yml -K
You can add -i hosts
if you want to run against remote hosts instead of
locally.
NOTE: Hard-coded to ArchLinux and my own needs.
To unset a key binding: ~M-x global-unset-key~y
To remove all hooks from a mode during testing, evaulate: (setq <mode-hook>
nil)
. As per:
https://www.gnu.org/software/emacs/manual/html_node/emacs/Hooks.html
(use-package compile
:ensure t
:custom
(compilation-ask-about-save nil "Auto save before compiling.")
(compilation-scroll-output t "Scroll output and don't stop on errors.")
)
(setq debug-on-error t)
(use-package bug-hunter
:ensure t
:defer t)
To start Esup, run M-x esup
, and watch the magic happen.
By default, Esup will profile user-init-file
. To profile a custom file, call
esup
with a prefix argument. That is, C-u M-x esup
.
(use-package esup
:ensure t
:defer t
:defer
:config
;; Work around a bug where esup tries to step into the byte-compiled
;; version of `cl-lib', and fails horribly.
;; See; https://github.com/jschaf/esup/issues/85
(setq esup-depth 0)
)
(use-package dired
:custom
(dired-async-mode t)
(dired-listing-switches "-alFh")
(dired-dwim-target t) ;; Guess target for operations.
)
- Decompress archive(s):
Z
decompress to a folder named after archive.! <RETURN>
to decompress to current folder.
- Rename files/folders:
C-xC-q
(M-x dired-toggle-read-only
) buffer editing.C-cC-c
commit changes to disk.
(use-package doc-view
:ensure-system-package ((gs . ghostscript))
)
Eglot (Github: joaotavora/eglot) is the built-in, streamlined LSP (Language Server Protocol) client for emacs, to talk to LSP Servers with. it is the alternative to the external,feature-rich package: lsp-mode.
NOTE: Currently transitioning over to eglot
from: lsp-mode
, as part of
trying to slim down config and use more built-ins.
(use-package eglot
;; TODO: Raise bug about how this `:after` call breaks `eglot` automatically
;; running.
;; :after (company-mode)
:hook (
(eglot-mode . global-company-mode)
;; NOTE: `prog-mode` covers too many non-lsp modes. Tired of constant
;; errors, so going back to explicitly enabling eglot on each mode!
;; (prog-mode . eglot-ensure)
)
:ensure t)
Breadcrumb is a mode that fell out of the wish for eglot Users to have the same
breadcrumb as seen in lsp-ui
. See: Github: joaotavora/eglot - Breadcrumb
feature (can eglot support headerline like lsp-mode does?) #988.
This is external to eglot, but placing here just because of the link.
(use-package breadcrumb
:vc (:url "https://github.com/joaotavora/breadcrumb"
:rev :newest)
:ensure t
:config
(breadcrumb-mode)
)
(use-package eww
:bind (("<f4>" . eww))
;; FIXME: eww is okay, but for things like google account redirects, we need
;; a real browser.
:config
(setq eww-bookmarks-directory "~/org/personal/")
;; (progn
;; (setq
;; browse-url-browser-function (quote eww-browse-url)
;; )
;; )
)
'(browse-url-browser-function (quote browse-url-default-browser)) ; Use system default browser instead of eww.
;; bound this to Darwin only.
;; (cond
;; ((string-equal system-type "darwin")
;; (setq browse-url-browser-function (quote browse-url-default-browser))));;'browse-url-generic
;; browse-url-generic-program "/Applications/Opera.app/Contents/MacOS/Opera")))
(use-package language-detection
; https://github.com/andreasjansson/language-detection.el
:ensure t
:defer t
)
(require 'cl-lib)
(defun eww-tag-pre (dom)
"See: https://github.com/andreasjansson/language-detection.el.
DOM - web dom."
(let ((shr-folding-mode 'none)
(shr-current-font 'default))
(shr-ensure-newline)
(insert (eww-fontify-pre dom))
(shr-ensure-newline)))
(defun eww-fontify-pre (dom)
"See: https://github.com/andreasjansson/language-detection.el.
DOM - web dom."
(with-temp-buffer
(shr-generic dom)
(let ((mode (eww-buffer-auto-detect-mode)))
(when mode
(eww-fontify-buffer mode)))
(buffer-string)))
(defun eww-fontify-buffer (mode)
"See: https://github.com/andreasjansson/language-detection.el.
MODE - ??"
(delay-mode-hooks (funcall mode))
(font-lock-default-function mode)
(font-lock-default-fontify-region (point-min)
(point-max)
nil))
(defun eww-buffer-auto-detect-mode ()
"See: https://github.com/andreasjansson/language-detection.el."
(let* ((map '((ada ada-mode)
(awk awk-mode)
(c c-mode)
(cpp c++-mode)
(clojure clojure-mode lisp-mode)
; (csharp csharp-mode java-mode)
(css css-mode)
(dart dart-mode)
(delphi delphi-mode)
(emacslisp emacs-lisp-mode)
(erlang erlang-mode)
(fortran fortran-mode)
(fsharp fsharp-mode)
(go go-mode)
(groovy groovy-mode)
(haskell haskell-mode)
(html html-mode)
(java java-mode)
(javascript javascript-mode)
(json json-mode javascript-mode)
(latex latex-mode)
(lisp lisp-mode)
(lua lua-mode)
(matlab matlab-mode octave-mode)
(objc objc-mode c-mode)
(perl perl-mode)
(php php-mode)
(prolog prolog-mode)
(python python-mode)
(r r-mode)
(ruby ruby-mode)
(rust rust-mode)
(scala scala-mode)
(shell shell-script-mode)
(smalltalk smalltalk-mode)
(sql sql-mode)
(swift swift-mode)
(visualbasic visual-basic-mode)
(xml sgml-mode)))
(language (language-detection-string
(buffer-substring-no-properties (point-min) (point-max))))
(modes (cdr (assoc language map)))
(mode (cl-loop for mode in modes
when (fboundp mode)
return mode)))
(message (format "%s" language))
(when (fboundp mode)
mode)))
(setq shr-external-rendering-functions
'((pre . eww-tag-pre)))
FIXME: flymake: temp disable due to noise from legacy init mode:
(error "Can’t find a suitable init function")
.
Doesn’t appear when flymake is started by eglot
in a mode that has an lsp.
(use-package flymake
:bind (:map flymake-mode-map
("C-c e" . flymake-show-buffer-diagnostics)
("C-c p" . flymake-show-project-diagnostics)
("C-c j" . flymake-goto-next-error)
)
;; :hook (
;; (prog-mode . flymake-mode)
;; (text-mode . flymake-mode)
;; )
:config
(progn
(set-face-attribute 'flymake-error nil :background "DarkRed")
(set-face-attribute 'flymake-warning nil :background "DarkBlue")
(set-face-attribute 'flymake-note nil :background "DarkGreen")
)
)
- Don’t prompt to kill processes on exit.
(setq confirm-kill-processes nil) (setq-default tab-width 4)
- Global defaults:
(setq-default tab-width 4)
- Fuzzy completions (just like
ido
with fuzzy matching set +smex
) and Save history in minibuffers.(fido-mode t) (savehist-mode t) (setq savehist-additional-variables '(search-ring regexp-search-ring))
- Bookmarks:
(setq bookmark-default-file "~/org/personal/bookmarks")
- Highlights:
(global-hl-line-mode 1) ;; horizontal highlighted line on cursor. ;; http://www.emacswiki.org/emacs/EmacsNiftyTricks ;; http://emacs-fu.blogspot.com/2008/12/highlighting-todo-fixme-and-friends.html (defun my_highlighted_words () "Highlight specific words in the buffer." (interactive) (font-lock-add-keywords nil '(("\\<\\(Note\\|NOTE\\|FIXME\\|Todo\\|TODO\\|BUG\\|Bug\\):" 1 '(:foreground "red" :weight bold) t))))
;; backup files - https://www.emacswiki.org/emacs/BackupDirectory
(setq
backup-by-copying t ; don't clobber symlinks
backup-directory-alist
'(("." . "~/.emacs.d/.backups/")) ; don't litter my fs tree
delete-old-versions t
kept-new-versions 6
kept-old-versions 2
version-control t) ; use versioned backups
(make-directory "~/.emacs.d/.backups/" t)
;; https://emacs.stackexchange.com/questions/17210/how-to-place-all-auto-save-files-in-a-directory
(setq auto-save-file-name-transforms
`(
("\\`/[^/]*:\\([^/]*/\\)*\\([^/]*\\)\\'" "/tmp/\\2" t)
(".*" "~/.emacs.d/.auto-saves/" t)
)
)
(make-directory "~/.emacs.d/.auto-saves/" t)
;; Don't save lock files by files - https://www.emacswiki.org/emacs/LockFiles.
(setq create-lockfiles nil)
Auto save all open files in current session and reload on startup.
(use-package desktop
:ensure t
:defer t
:init (desktop-save-mode)
:config
(progn
;; Don't autosave desktops, it's too expensive. Desktops aren't
;; that precious, and Emacs will save the desktop on exit anyway.
(setq
desktop-restore-eager 0
desktop-load-locked-desktop t
desktop-auto-save-timeout nil
desktop-path '("~/")
desktop-dirname "~/")
(dolist (mode '(magit-mode git-commit-mode))
(add-to-list 'desktop-modes-not-to-save mode))))
Use the C-based line numbers instead of the slower lisp (`linum`). https://www.emacswiki.org/emacs/LineNumbers#h5o-1
(use-package display-line-numbers
:hook (
(conf-mode . 'display-line-numbers)
(prog-mode . 'display-line-numbers)
(text-mode . 'display-line-numbers)
(org-mode . (lambda () (display-line-numbers-mode -1)))
)
:custom-face
(line-number ((t (:inherit (shadow default) :background "grey10"))))
)
Allow `Alt+3` on a Mac to be `#`:
- https://stackoverflow.com/questions/1704119/carbon-emacs-re-enable-hash-key
- https://stackoverflow.com/questions/3977069/emacs-question-hash-key
(global-set-key (kbd "M-3") '(lambda () (interactive) (insert "#")))
(define-key isearch-mode-map (kbd "M-3") '(lambda () (interactive) (isearch-process-search-char ?\#)))
which-key
integration, to show keyboard shortcuts.
(use-package which-key
:ensure t
:config
(which-key-mode))
Highlight white-space (eg. tabs) in the buffer.
(use-package whitespace
:ensure t
:config
(global-whitespace-mode)
(setq whitespace-style (quote (face trailing tabs)))
)
Load extra dot files (if they exist).
(make-directory "~/org/emacs" t)
(use-package cus-edit
:custom (custom-file "~/org/emacs/custom_set_variables.el" "Moved custom-set-variables to it's own file")
)
(let () (dolist (dot_emacs '("~/org/emacs/custom_set_variables.el"
"~/org/emacs/private_dot_emacs.el"
"~/org/emacs/unstable_config_dot_emacs.el"
"~/org/emacs/work_specific_dot_emacs.el"))
"Loading my extra emacs dot files if they exist."
(when (file-exists-p dot_emacs)
(message (concat "Loading external dot file: " dot_emacs))
(load-file dot_emacs))))
The gutter bar at the bottom of the emacs window/frame.
(setq column-number-mode t)
See:
(set-face-attribute 'mode-line-active nil
:foreground "black" :background "goldenrod" :box '(:line-width 1 :color "black"))
smart mode line wraps up a lot of nice tweaks in one package.
NOTE: Trialling the stock mode-line for a bit to see if I can live without smart-mode-line.
(use-package smart-mode-line
;; :ensure t
:disabled t
:defer t
:init
(setq
sml/no-confirm-load-theme t
sml/theme 'dark
sml/mode-width `full
)
(sml/setup)
(column-number-mode t)
)
Don’t load outdated byte code.
(setq load-prefer-newer t)
SO: How do I byte compile everything?
;; (byte-recompile-directory (expand-file-name "~/.emacs.d") 0)
Log but don’t pop up Warnings buffer for all native compilation warnings.
(setq native-comp-async-report-warnings-errors 'silent)
I’ve used projectile
for years, but giving project
a go. Only ever used:
Commands | Projectile | Project |
---|---|---|
Fuzzy search for files | C-c p f | C-x p f |
Grep project | C-c g | C-x p g |
Switch buffers in project | C-x p b | |
Switch Project | C-c p p | C-c p p |
Going to try project
for a bit and see how it goes.
(use-package project
:ensure t)
Historical notes:
Been getting more annoyed at not using daemon mode on my main box and
connecting with emacsclients. Due to work, I use quite a few git-worktree’s
of the same repo. The problem would be accidentally cross editing files
across the different worktree’s (Hence not using daemon mode, and instead
just running up multiple emacs --debug-init
sessions for each worktree.
Let’s have a go at banishing this behaviour:
- Projectile: Allows for project focus (git repo), whilst also doing fuzzy file searching across the entire project (Nice!)
- Perspective: Allows for workspaces that when switched to, return the
buffers to their original state. Also focuses down the
ido
buffer to the open buffers in that workspace (Nice!) - persp-projectile: Combines Projectile and Perspective so that switching projects gives you the Perspective buffer change behaviour (Much nicer than Projectile’s insistence that you want to always open a new file but also keep old buffers hanging around).
NOTE: Projectile state is not saved in desktop-save
.
NOTE: Perspective mode with IDO only show’s files in project, so have to use
ibuffer to get full list.
- https://github.com/bbatsov/projectile
- https://github.com/nex3/perspective-el
- https://github.com/bbatsov/persp-projectile
(use-package projectile
:disabled
;; :ensure t
;; :defer t
:bind ("C-c p" . 'projectile-command-map)
:init
(progn
(projectile-mode)
(recentf-mode) ; enables projectile-recentf mode for recent files.
; https://github.com/bbatsov/projectile/issues/1183
; Projectile now scrapes all files to discover project type for modeline.
; This is calculated on every cursor movement, so lags emacs like crazy.
; Below is the workaround to disable this until it is fixed.
(setq projectile-mode-line
'(:eval (format " Projectile[%s]"
(projectile-project-name))))
)
)
(use-package server
:ensure t
:after (exec-path-from-shell)
:config
;; https://wiki.archlinux.org/title/Emacs#Multiplexing_emacs_and_emacsclient
(unless (server-running-p)
(server-start))
)
See: Github: purcell/exec-path-from-shell & Yi Tang: Managing Emacs Server as Systemd Service for notes on using the environment variables:
Environment Variables
The customised shell configuration in .bashrc are loaded when opening an interactive shell session. So the Emacs server managed by systemd would not have the environment variables, alias, functions or whatever defined in .bashrc.
This stackoverflow post provides the rationale and how to tweak the unit file so systemd would load .bashrc.
This problem can solved a lot easier on the Emacs side, by using exec-path-from-shell package. It will ensure the environment variables inside Emacs are the same as in the user’s interactive shell.
Simply put the following in your .emacs would do the trick.
(exec-path-from-shell-initialize)
(use-package exec-path-from-shell
:ensure t
:config
(exec-path-from-shell-initialize)
)
Lookup dictionary definitions.
See: https://emacsredux.com/blog/2023/04/11/looking-up-words-in-a-dictionary/,
for details as well as installing the dictionary service as an alternative
to: dict.org
.
M-x dictionary-search
look up word definition.M-x dictionary-lookup-definition
to do a lookup at point.
(use-package dictionary
:ensure t
:defer t
:config (setq dictionary-server "dict.org")
)
See: EmacsWiki: FlySpell Performance about disabling
flyspell-issue-message-flag
to greatly speed up flyspell-buffer
.
(use-package flyspell
:ensure t
:hook (
(prog-mode . flyspell-prog-mode)
(text-mode . flyspell-mode)
)
:config (setq flyspell-issue-message-flag nil)
)
M-x flyspell-buffer
ispell
is the built in spell checker, but aspell
is better (multiple
dictionaries). See: http://www.emacswiki.org/emacs/InteractiveSpell#toc6
(use-package ispell
:ensure-system-package (aspell)
:custom
(ispell-list-command "list")
(ispell-personal-dictionary "~/org/ispell_personal_dict")
(ispell-program-name "aspell")
(ispell-silently-savep t) ;; No confirmation on saving to personal dictionary.
)
Either:
M-$ i
.C-c $
and then clickSave word
in GUI drop-down.
Steps:
- Pull welsh dictionary from; https://ftp.gnu.org/gnu/aspell/dict/cy/.
- Un-tar, build and install dictionary:
./configure && make && sudo make install
. - Set file local variable to set the Welsh dictionary:
M-x add-file-local-variable <ret>ispell-local-dictionary<ret>"cy"<ret>
. - Revert buffer and verify spellings:
M-x flyspell-buffer
.
The tab-bar
package creates tabs like a browser. Each tab can maintain it’s
layout. Seems to hook into desktop-save
to restore on restarts.
(use-package tab-bar
:ensure t
:defer t
:after (hydra)
:bind ("C-x t" . 'hydra-tab-bar/body)
:config
;; https://github.com/abo-abo/hydra/wiki/Emacs-27-tab-bar-mode
;; https://github.com/abo-abo/hydra/wiki/Binding-Styles
(defhydra hydra-tab-bar (:color amaranth)
"Tab Bar Operations"
("t" tab-new "Create a new tab" :column "Creation")
("c" tab-new "Create a new tab")
("d" dired-other-tab "Open Dired in another tab")
("f" find-file-other-tab "Find file in another tab")
("0" tab-close "Close current tab")
("k" tab-close "Close current tab")
("m" tab-move "Move current tab" :column "Management")
("r" tab-rename "Rename Tab")
("n" tab-bar-select-tab-by-name "Select tab by name" :column "Navigation")
("s" tab-bar-select-tab-by-name "Select tab by name")
("j" tab-previous "Previous Tab")
("l" tab-next "Next Tab")
(";" tab-next "Next Tab")
("q" nil "Exit" :exit t)
)
)
Treesit uses the tree-sitter grammars to provide faces/fontifying/structures to text by an AST instead of a regex (ie. fast, accurate, works during editing).
Automatically install tree-sitter grammars.
(use-package treesit-auto
:ensure t
:demand t
:config
(setq
treesit-auto-install t
)
(global-treesit-auto-mode)
)
(global-auto-revert-mode t)
(put 'downcase-region 'disabled nil) ; allow downcase-region without the disabled feature warning.
(put 'upcase-region 'disabled nil) ; allow upcase-region without the disabled feature warning.
(setq calendar-week-start-day 1)
(menu-bar-mode -1) ;; Disable Menu Bar
(tool-bar-mode -1) ;; Disable tool Bar
(fset 'yes-or-no-p 'y-or-n-p) ;; yes/no -> y/n
(load-theme 'wombat t)
; (display-time) ;; Time in modeline. Un-comment to enable.
(display-battery-mode t) ;; Battery in modeline. Un-comment to enable.
(setq large-file-warning-threshold (* 40 1024 1024)) ;; large files shouting from 40MB's
;; http://pragmaticemacs.com/emacs/dired-human-readable-sizes-and-sort-by-size/
(setq dired-listing-switches "-alh")
Builtin method of moving between windows with (default) Shift+<arrow>
. See:
PragmaticEmacs: Whizz between windows with windmove.
(use-package windmove
:ensure t
:config (windmove-default-keybindings)
)
(defun go-to-column (column)
"GoTo column.
Was getting annoyed seeing errors that point to a COLUMN number;
so grabbed this code:
- http://emacsredux.com/blog/2013/07/09/go-to-column/"
(interactive "nColumn: ")
(move-to-column column t))
(global-set-key (kbd "M-g M-c") 'go-to-column)
(defun my-programming-defaults-config ()
"All of my programming defaults in one place."
(interactive)
(whitespace-mode) ;; highlights whitespace.
(my_highlighted_words) ;; highlights specific words in red & bold.
(display-fill-column-indicator-mode) ;; adds fill column indicator.
;; (auto-fill-mode nil) ;; disables auto fill at column.
(setq indent-tabs-mode nil) ;; spaces instead of tabs
(setq tab-width 4) ;; 4 spaces per tab key press.
;; TODO: raise a bug on which-function-mode breaking in python when opening a
;; triple double-qoute (`"""`) docstring in a function and then emacs
;; freezes. Replicated on work files with: `emacs -q`, but failed to
;; replicate so far on a quickly mocked up file in /tmp/.
;;
;; (which-function-mode) ;; Display current function in mode line. (http://emacsredux.com/blog/2014/04/05/which-function-mode/)
(my_highlighted_words) ;; highlight specific words
(show-paren-mode 1) ;; highlight matching brackets
(setq tags-revert-without-query t)
)
(add-hook 'prog-mode-hook 'my-programming-defaults-config)
;; Don't line-wrap in html files.
;; https://stackoverflow.com/questions/9294437/emacs-disable-wordwrapping-in-html-mode
(add-hook 'html-mode-hook (lambda () (auto-fill-mode -1)))
(defun revert-all-buffers ()
"Refreshes all open buffers from their respective files."
(interactive)
(dolist (buf (buffer-list))
(with-current-buffer buf
(when (and (buffer-file-name) (file-exists-p (buffer-file-name)) (not (buffer-modified-p)))
(revert-buffer t t t) )))
(message "Refreshed open files.") )
(defun my-scratch-mode-config ()
"Disabling config for *scratch* buffer."
(interactive)
(display-fill-column-indicator-mode -1)
(auto-fill-mode -1)
)
(add-hook 'lisp-interaction-mode-hook 'my-scratch-mode-config)
Here’s a simple defun to show non-ascii characters of current buffer in an Occur buffer http://www.emacswiki.org/emacs/FindingNonAsciiCharacters
(defun occur-non-ascii ()
"Find any non-ascii characters in the current buffer."
(interactive)
(occur "[^[:ascii:]]"))
(defun my-text-mode-config ()
"All of my `text-mode` config in one place."
(interactive)
(whitespace-mode) ;; highlights whitespace.
(my_highlighted_words) ;; highlights specific words in red & bold.
(display-fill-column-indicator-mode) ;; adds fill column indicator.
(auto-fill-mode) ;; wraps at auto fill column.
(my_highlighted_words) ;; highlight specific words
(setq indent-tabs-mode nil) ;; spaces instead of tabs
)
(add-hook 'text-mode-hook 'my-text-mode-config) ;; singular text-mode-hook
(add-hook 'conf-mode-hook 'my-text-mode-config) ;; *.conf
(defun comment-or-uncomment-region-or-line ()
"Un/Comments the region or the current line if there's no active region."
(interactive)
(let (beg end)
(if (region-active-p)
(setq beg (region-beginning) end (region-end))
(setq beg (line-beginning-position) end (line-end-position)))
(comment-or-uncomment-region beg end)))
(global-set-key (kbd "C-c '") 'comment-or-uncomment-region-or-line)
Fill Column is used to reflow text automatically & highlight margins, as well as show a hard column line. See: Emacs Wiki: FillColumnIndicator. I changed the column fill to be a double pipe. See unicode table.
(use-package fill-column-indicator
:ensure t
:defer t
:config
(progn
(setq-default fci-rule-column 79)
(setq fci-rule-character ?\u2016)
;; automatically wrap to 79 characters.
(setq-default fill-column 79)
(setq-default git-commit-fill-column 79))
)
Useful package when paired with a presentation mode like: [[*\[\[https://github.com/takaxp/org-tree-slide\]\[org-tree-slide\]\]:][org-tree-slide]], give a fullscreen (distraction-free) presentation. See: YouTube: Emacs Tips - How to Give Presentations with Org Mode (Questions).
(use-package hide-mode-line :ensure t)
NOTE: Seeing LSP and other packages blowing up on this missing requirement.
(use-package treemacs
:ensure t
:defer t
:custom
(treemacs-project-follow-mode t)
)
Centre buffers, example for presentations
(use-package visual-fill-column
:ensure t
:custom
(visual-fill-column-width 110)
(visual-fill-column-center-text t)
)
(use-package alert
;; TODO: Check if Mac can work with libnotify. It works on Linux.
;; Still not working + libnotify keeps being reinstalled by brew due to
;; different name.
;; :ensure-system-package (libnotify)
:ensure t
:commands (alert)
:init
(if (eq system-type 'darwin)
(setq alert-default-style 'terminal-notifier)
(setq alerqt-default-style 'libnotify)
)
(setq
alert-fade-time 15
)
)
Notifications from scheduled items in the Org Agenda. Builds off: [[*\[\[https://github.com/jwiegley/alert\]\[alert\]\]:][alert]].
NOTE: On Mac’s I am using an Alert notification for terminal-notifier
, so
that notifications have to be explicitly closed.
(use-package org-alert
;; https://github.com/julienXX/terminal-notifier/issues/292 - No Notification in macOS12.1 #292
;; https://github.com/julienXX/terminal-notifier
;; TODO: Check if Mac can work with libnotify. It works on Linux.
;; :ensure-system-package terminal-notifier
:ensure t
;; :disabled t ;; Why is this blowing up??
:after (org)
:config
(setq
alert-default-style 'libnotify
org-alert-notify-cutoff 5
org-alert-notify-after-event-cutoff 1
)
(org-alert-enable)
)
Very old way of doing custom notification pop-ups:
- http://emacs-fu.blogspot.com/2009/11/showing-pop-ups.html
- https://www.gnu.org/software/emacs/manual/html_node/elisp/Desktop-Notifications.html, since this would be nicer to move to a standardised package.
;; TODO: figure out why the built in `notifications` package doesn't play
;; sounds:
(defun djcb-popup (title msg &optional timeout icon sound)
"Show a popup if we're on X, or echo it otherwise;
TITLE is the title of the message, MSG is the context.
Optionally, you can provide a TIMEOUT (milliseconds, default=5000) an ICON and
a SOUND to be played (default=/../alert.wav)"
(interactive)
(shell-command
(concat "mplayer -really-quiet "
(if sound sound "/usr/share/sounds/purple/alert.wav")
" 2> /dev/null"))
;; Removed `(if (eq window-system 'x))` check since it wasn't doing the
;; notify-send on my terminal emacs session nested in tmux in a terminal
;; under cinnamon.
(shell-command (concat "notify-send"
(if icon (concat " -i " icon) "")
(if timeout (concat " -t " timeout) " -t 5000")
" '" title "' '" msg "'"))
;; text only version
(message (concat title ": " msg)))
Run example:
(djcb-popup "Warning" "The end is near" nil "/usr/share/icons/gnome/128x128/apps/libreoffice-base.png" "/usr/share/sounds/purple/alert.wav")
VC config (VC is built in version control package. Magit is an enhanced git VC package).
(setq vc-follow-symlinks t)
magit - a pretty good git package with more features than the built in emacs “vc” package.
(use-package magit
:ensure t
:bind (
("<f3>" . magit-status)
("\C-ct" . magit-status) ;; Alternative when on a touchbar Mac.
("\C-c\C-s" . magit-status) ;; Overridden by =org-schedule=.
("\C-cg" . vc-git-grep)
("\C-cb" . magit-blame))
:config
(setq magit-auto-revert-mode t)
;; `M-x magit-describe-section-briefly`, then check the square brackets in:
;; `<magit-section ... [<section_name> status] ...>`.
(setq
magit-section-initial-visibility-alist
'(
(stashes . hide)
(unpulled . show)
(unpushed . show)
(pullreqs . show)
))
)
magit-svn (legacy):
Used this years ago when SVN and git-svn where part of my daily work routine. Haven’t needed to touch SVN in years, but keeping here for legacy reasons.
(use-package magit-svn
:ensure t
:defer t
:after (magit)
)
magit-popup (legacy):
magit/magit#3749 magit
moved to using transient
but some packages (magithub
-
vermiculus/magithub#402) haven’t updated, hence
explicit definition of magit-popup
(use-package magit-popup
:ensure t
:after (magit)
)
Builds on top of Magit to interact with VCS’s so that you can create/edit Issues/PR’s.
Replacement for magithub, which works with Gitlab/Github. See old commits for
my old magithub
config.
(use-package forge
;; https://www.reddit.com/r/emacs/comments/fe165f/pinentry_problems_in_osx/
;; to fix GPG timeouts due to no password provided/asked.
;; NOTE: for emacsclients, it asks in the main instance window.
:if (not (eq system-type 'windows-nt)) ;; FIXME: Needs `cc` compiler defined.
:ensure t
:after (magit)
:config
(add-to-list 'forge-alist '("git-scm.clinithink.com:2009" "git-scm.clinithink.com/api/v4" "git-scm.clinithink.com" forge-gitlab-repository))
(add-to-list 'forge-alist '("bitbucket.eigen.live" "bitbucket.eigen.live/rest/api/1.0" "bitbucket.eigen.live" forge-bitbucket-repository))
(add-to-list 'forge-alist '("gitlab.eigen.live" "gitlab.eigen.live/api/v4" "gitlab.eigen.live" forge-gitlab-repository))
)
Code Review is a package that builds on top of Magit, but supports interacting with PR’s to do code reviews (comments, diff view, approvals, etc).
M-x code-review-forge-pr-at-point
on forge PR line.r
for transient menu in acode-review
buffer.
(use-package code-review
:ensure t
:defer t
:after (magit)
:config
(setq
code-review-bitbucket-host "bitbucket.eigen.live/rest/api/1.0"
code-review-gitlab-host "gitlab.eigen.live/api"
code-review-gitlab-graphql-host "gitlab.eigen.live/api"
;; Dump requests into the logs for debugging. eg.
;; https://github.com/wandersoncferreira/code-review/issues/195.
;;
;; code-review-log-raw-request-responses t
)
)
A GNU Emacs major mode for keeping notes, authoring documents, computational notebooks, literate programming, maintaining to-do lists, planning projects, and more — in a fast and effective plain text system.
NOTE: Broken apart org mode config via: Github: jwiegley/use-package/issues/662 - Calling use-package multiple times on the same package #662.
See: http://cestlaz.github.io/posts/using-emacs-26-gcal/
(use-package calfw
:ensure t
:defer t
:after (org)
:bind
(
("<f8>" . cfw:open-org-calendar)
)
:config
(progn
(use-package calfw-gcal
;; FIXME: 10year old package with deprecated `cl` requirement.
;; TODO: replace for: https://github.com/myuhe/org-gcal.el.
:ensure t
:defer t)
(use-package calfw-ical
:ensure t
:defer t)
(use-package calfw-org
:ensure t
:defer t)
)
;; FIXME: what does this do??
(setq cfw:org-overwrite-default-keybinding t)
)
(use-package org
;; NOTE: ~ox-confluence~ from ~org-contrib~ never worked well, compared to
;; the exports listed in: ~config.org~. Disabling for now.
;; https://emacs.stackexchange.com/questions/7890/org-plus-contrib-and-org-with-require-or-use-package
;; https://emacs.stackexchange.com/questions/70081/how-to-deal-with-this-message-important-please-install-org-from-gnu-elpa-as-o
;; :ensure org-contrib
:ensure t
:bind (
("C-c l" . org-store-link)
("C-c a" . org-agenda)
("C-c c" . org-capture))
:init
(progn
(setq
org-directory "~/org/"
;; org-agenda-files (list "~/org/" "~/org/personal/" "~/org/programming_notes/")
org-agenda-files (apply 'append
(mapcar
(lambda (directory)
(directory-files-recursively
directory org-agenda-file-regexp))
'("~/org/")))
org-default-notes-file "~/org/notes.org"
;; refile level.
;; http://www.millingtons.eclipse.co.uk/glyn/dotemacs.html
org-refile-targets (quote
((org-agenda-files :maxlevel . 5)
("~/org/personal/projects.org" :maxlevel . 2)
("~/org/programming_notes/notes.org" :maxlevel . 5)))
;; Allow refiling to a file to support moving up to heading level 1
org-refile-use-outline-path 'file
;; FIXME: Something has changed to the point where I can no longer refile
;; to headings in a file after the file selection part. Changing the
;; outline path option below allows me to do it, but it is super laggy
;; from all of the headings it is fuzzy searching through.
;;
;; I may have to give up on refiling to the top heading in a file with the
;; ~org-refile-use-outline-path 'file~ change above.
org-outline-path-complete-in-steps nil
org-log-done t
;; https://kundeveloper.com/blog/org-capture-3/ for `org-capture-templates` ideas.
org-capture-templates '(
("t" "Todo" entry (file+headline "~/org/todo.org" "UNSORTED")
"* TODO %? %^G\n %U - %i\n %a")
("p" "Projects" entry (file+headline "~/org/personal/projects.org" "UNSORTED")
"* TODO %?\n %U - %i\n %a")
("b" "Buy" entry (file+headline "~/org/personal/buy.org" "UNSORTED")
"* TODO %?\n %U - %i\n %a")
("i" "Inbox - Dumping ground" entry (file "~/org/inbox.org") "* %?\n")
("n" "Notes" entry (file+headline "~/org/programming_notes/notes.org" "UNSORTED")
"* TODO %?\n %U - %i\n %a")
("y" "YouTube: Watch List.\n\t\t*Link is pulled from X Clipboard!!*\n\t\t*NOTE:* if this is a Playlist;\n\t\t- manually delete ~v=<id>&~.\n\t\t- keep: ~list=<id>~!" entry (file+headline "~/org/personal/personal_todos.org" "YouTube Watch list:")
"* [[shell:mpv %x &][YouTube: %?]] :WATCH:")
)
)
(global-set-key "\C-cr" (lambda () (interactive) (org-capture nil "t")))
(global-set-key "\C-cn" (lambda () (interactive) (org-capture nil "n")))
)
:config
;; ;; Explicit requires from the `org-contrib` package.
;; (require 'ox-confluence) ;; FIXME: wrong type arguments error!
(setq
org-link-file-path-type 'relative
org-use-tag-inheritance nil ;; Don't show un-tagged sub-headings when there is a tag on a high-level.
)
)
- http://orgmode.org/worg/code/elisp/dto-org-gtd.el
- http://www.gnu.org/software/emacs/manual/html_node/org/Remember-templates.html
- Convert markdown links (
[display_message](link)
) to org links ([[link][display_message]]
):(fset 'convert-markdown-link-to-org-link "\C-[xreplace-regexp\C-m\\[\\(.*\\)\\](\\(.*\\))\C-m[[\\2][\\1]]\C-m")
Suggested Export Options at top of file: #+OPTIONS: \n:nil toc:nil
num:nil
. Or: #+OPTIONS: \n:nil toc:nil num:nil html-postamble:nil
to remove
the footer as well.
- No line wrapping.
- No TOC.
- Don’t number headings.
Been trying different ways to export org files to then dump into Confluence. Current rating of exporters:
- Export to HTML.
- Highlight region.
M-x org-html-export-as-html
, cursor jumps to export buffer.M-x browse-url-of-buffer
, to open in your browser.- Select all in Browser tab and paste into Confluence edit mode.
- Export to ASCII.
M-x org-ascii-export-as-ascii
.- Requires below config changes.
- Issues around Headings being picked up by Confluence (eg. h3 == h2, no h3+).
- Issues around Formatting being picked up by Confluence (eg. No Bold markup).
- Export to Markdown.
M-x org-md-export-as-markdown
.- Great rendering in a
/markdown
macro, but other macros cannot be nested inside or work with the/markdown
macro. eg. No/toc
macro. - Pretty good rendering pasting into Confluence edit area, but no auto wrapping. ie. 80 characters.
- BROKEN:
M-x ox-confluence
fromorg-contrib
throws errors on emacs29.
Better ASCII export output from org files when the target is an Atlassian
Confluence Wiki. Export via: M-x org-ascii-export-as-ascii
(C-cC-etA
).
TODO: figure out what Heading underlining style Confluence uses for H3-H5!!
(setq org-ascii-text-width 10000) ;; Large text width to avoid line wrapping.
(setq org-ascii-inner-margin 0) ;; Don't indent lines between headings.
;; Confluence expects H2 to be ~-~.
(setq org-ascii-underline '((ascii 61 45 45)
(latin1 61 126 45)
(utf-8 9552 9472 9548 9476 9480)))
(defun org-custom-link-img-follow (path)
"PATH to find custom linked images."
(org-open-file-with-emacs
(format "~/org/github_blog/images/%s" path)))
(defun org-custom-link-img-export (path desc format)
"Rewrite custom linked images for export.
PATH - path to images.
DESC - Description to add as alt text..
FORMAT - .format to use."
(cond
((eq format 'html)
(format "<img src=\"http://jackson15j.github.io/%s\" alt=\"%s\"/>" path desc))))
(require 'org)
;; FIXME: `org-add-link-type` is deprecated. Replace with:
;; `org-link-set-parameters`.
(org-add-link-type "img" 'org-custom-link-img-follow 'org-custom-link-img-export)
(let () (dolist (dot_emacs '("~/org/config.org"
))
"Loading my extra emacs dot files if they exist."
(when (file-exists-p dot_emacs)
(message (concat "Loading external literate config: " dot_emacs))
(org-babel-load-file dot_emacs))))
Add: :async
to an org-babel code block to run async when called with:
C-cC-c
.
FIXME: Comment out `ob-async`. It’s throwing errors on post-install restart!
- https://www.orgmode.org/manual/Custom-Agenda-Views.html
- https://redgreenrepeat.com/2021/04/09/org-mode-agenda-getting-started-scheduled-items-and-todos/
- http://www.cachestocaches.com/2016/9/my-workflow-org-agenda/#the-agenda
- https://github.com/gjstein/emacs.d/blob/master/config/gs-org-agenda.el
(use-package org
:config
(setq
org-agenda-custom-commands '(
;; Keep tags but hide `DONE` tasks: https://orgmode.org/manual/Matching-tags-and-properties.html
("r" "Agenda Review"
(
(agenda "")
(tags "ACTION" ((org-agenda-overriding-header "\nItems I need to action!! ~:ACTION:~")))
(tags "CHASE" ((org-agenda-overriding-header "\nChase down these people!! ~:CHASE:~")))
(tags "INVESTIGATE|INVESTIGATION" ((org-agenda-overriding-header "\nInvestigation tasks!! ~:INVESTIGATE:INVESTIGATION:~")))
(tags "REVIEW|WIKI" ((org-agenda-overriding-header "\nDump this into Confluence!! ~:REVIEW:WIKI:~")))
(tags "READ|WATCH" ((org-agenda-overriding-header "Books/Links I need to read/WATCH!! ~:READ:WATCH:~")))
(tags "TRAINING" ((org-agenda-overriding-header "Current/Future training tasks ~:TRAINING:~")))
(tags "ADMIN" ((org-agenda-overriding-header "Admin tasks ~:ADMIN:~")))
(tags-todo "-ACTION-ADMIN-CHASE-READ-REVIEW-TRAINING-WATCH-WIKI" ((org-agenda-overriding-header "\nGeneral TODO's")))
)
nil ;; settings
("/tmp/org_agenda_review.html" "/tmp/org_agenda_review.ics" "/tmp/org_agenda_review.txt") ;; ~org-store-agenda-views~ output file
)
;; https://fortelabs.com/blog/para/
("p" "PARA Personal (Project Area Resources Archive) Agenda Review"
(
(agenda "" ((org-agenda-files (list "~/org/" "~/org/personal/" "~/org/programming_notes/"))))
(tags "ACTION|CHASE|INVESTIGATE|INVESTIGATION|TRAVEL" ((org-agenda-overriding-header "\nProject: \"a series of tasks linked to a goal, with a deadline.\" ~:ACTION:CHASE:INVESTIGATE:INVESTIGATION:~") (org-agenda-files (list "~/org/" "~/org/personal/" "~/org/programming_notes/"))))
(tags-todo "-ACTION-ADMIN-CHASE-EMACS-PERSONAL-READ-REVIEW-TRAINING-TRAVEL-WATCH-WIKI-WORKFLOW-STYLE=\"habit\"-SCHEDULED>=\"<now>\"-DEADLINE>=\"<now>\"" ((org-agenda-overriding-header "Project: (Tag to remove non-urgent TODO's out of this list!!)") (org-agenda-files (list "~/org/" "~/org/personal/" "~/org/programming_notes/"))))
(tags "ADMIN|REVIEW|WIKI|WORKFLOW-STYLE=\"habit\"" ((org-agenda-overriding-header "\nAreas: \"a sphere of activity with a standard to be maintained over time.\" ~:ADMIN:REVIEW:WIKI:WORKFLOW:~") (org-agenda-files (list "~/org/" "~/org/personal/" "~/org/programming_notes/"))))
(tags "EMACS|PERSONAL-STYLE=\"habit\"|READ|TRAINING-STYLE=\"habit\"|WATCH|UNSORTED" ((org-agenda-overriding-header "\nResource: \"a topic or theme of ongoing interest.\" ~:EMACS:PERSONAL:READ:TRAINING:WATCH:UNSORTED:~") (org-agenda-files (list "~/org/" "~/org/personal/" "~/org/programming_notes/"))))
)
nil ;; settings
;; See: https://orgmode.org/manual/Exporting-Agenda-Views.html
;; ~M-x org-store-agenda-views~ outputs all files for all views.
;; Script export: ~emacs --batch -l ~/.emacs --eval '(org-store-agenda-views)'~
("/tmp/org_agenda_para.html" "/tmp/org_agenda_para.ics" "/tmp/org_agenda_para.txt")
)
("w" "PARA Work (Project Area Resources Archive) Agenda Review"
(
(agenda "" ((org-agenda-files (directory-files-recursively "~/org/work/" org-agenda-file-regexp))))
(tags "ACTION|CHASE|INVESTIGATE|INVESTIGATION|TRAVEL" ((org-agenda-overriding-header "\nProject: \"a series of tasks linked to a goal, with a deadline.\" ~:ACTION:CHASE:INVESTIGATE:INVESTIGATION:~") (org-agenda-files (directory-files-recursively "~/org/work/" org-agenda-file-regexp))))
(tags-todo "-ACTION-ADMIN-CHASE-EMACS-PERSONAL-READ-REVIEW-TRAINING-TRAVEL-WATCH-WIKI-WORKFLOW" ((org-agenda-overriding-header "Project: (Tag to remove non-urgent TODO's out of this list!!)") (org-agenda-files (directory-files-recursively "~/org/work/" org-agenda-file-regexp))))
(tags "ADMIN|REVIEW|WIKI|WORKFLOW" ((org-agenda-overriding-header "\nAreas: \"a sphere of activity with a standard to be maintained over time.\" ~:ADMIN:REVIEW:WIKI:WORKFLOW:~") (org-agenda-files (directory-files-recursively "~/org/work/" org-agenda-file-regexp))))
(tags "READ|TRAINING|WATCH|UNSORTED" ((org-agenda-overriding-header "\nResource: \"a topic or theme of ongoing interest.\" ~:READ:TRAINING:WATCH:UNSORTED:~") (org-agenda-files (directory-files-recursively "~/org/work/" org-agenda-file-regexp))))
)
nil ;; settings
;; See: https://orgmode.org/manual/Exporting-Agenda-Views.html
;; ~M-x org-store-agenda-views~ outputs all files for all views.
;; Script export: ~emacs --batch -l ~/.emacs --eval '(org-store-agenda-views)'~
("/tmp/org_agenda_para.html" "/tmp/org_agenda_para.ics" "/tmp/org_agenda_para.txt")
)
("d" "Agenda for Today (Compact view for Exporting to displays)"
(
(agenda)
(tags "ACTION|CHASE|INVESTIGATE|INVESTIGATION|TRAVEL" ((org-agenda-overriding-header "Project: \"a series of tasks linked to a goal, with a deadline.\" ~:ACTION:CHASE:INVESTIGATE:INVESTIGATION:~")))
)
(
(org-agenda-span 1)
(org-agenda-use-time-grid nil)
)
("/tmp/org_agenda_today.html" "/tmp/org_agenda_today.ics" "/tmp/org_agenda_today.txt")
)
("i" "Personal agenda for last 2 weeks"
(
(agenda "")
)
(
(org-agenda-span 15)
(org-agenda-start-day "-14d")
(org-agenda-skip-function-global nil)
)
)
("y" "Personal agenda for month"
(
(agenda "")
)
(
(org-agenda-span 'month)
(org-agenda-skip-function-global nil)
)
)
("o" "Work agenda for last 2 weeks (1-2-1 Reviews)"
(
(agenda "" ((org-agenda-files (directory-files-recursively "~/org/work/" org-agenda-file-regexp))))
)
(
(org-agenda-span 15)
(org-agenda-start-day "-14d")
(org-agenda-skip-function-global nil)
)
)
("u" "Work Month view"
(
(agenda "" ((org-agenda-files (directory-files-recursively "~/org/work/" org-agenda-file-regexp))))
)
(
(org-agenda-span 'month)
(org-agenda-skip-function-global nil)
)
)
)
org-src-fontify-natively t
org-overriding-columns-format "%CATEGORY %80ITEM %TODO %TAGS %5Effort(Est){:} %CLOCKSUM{:}" ;; C-cC-xC-c in an Agenda view.
org-agenda-compact-blocks t ;; Compact agenda. Same as setting: `org-agenda-block-separator nil`.
org-agenda-tags-column 100 ;; Stop tags rendering off the right of the buffer.
org-agenda-skip-function-global '(org-agenda-skip-entry-if 'todo 'done) ;; Hide `DONE` lines from Agenda view.
)
)
Repeated tasks / org#Tracking your habits:
- Enable
org-habit
in agenda view: org#Tracking your habits. - Tag repeated tasks with a deadline (
C-cC-d
). - Add the repeat [and reminder] value.
- Mark as done with
C-cC-t
, which will log thatDOEN
and update the deadline to the next future point.
Repeat:
- every fortnight: put
+2w
into deadline/schedule datetime. - daily, but next iteration is after today, if marking as
"DONE"
after missing several days: put.+1d
into deadline/schedule datetime.
See: Sachachua: Org-mode and habits.
(use-package org
:custom
(org-habit-graph-column 60) ;; 40
(org-habit-preceding-days 30) ;; 21
(org-habit-show-all-today t)
:config
(add-to-list 'org-modules 'org-habit)
)
Eval Org-modules. See: Sachachua: dotemacs#modules:
(eval-after-load 'org
'(org-load-modules-maybe t))
(use-package ob-core
:custom
(
(org-confirm-babel-evaluate . nil)
)
)
Initial babel core languages list:
Items like shell language supports multiple shells, but using those
shells does not work since the core is ob-shell
not
ob-<sh|bash|dash|fish|zsh>
.
;; active Babel languages
(org-babel-do-load-languages
'org-babel-load-languages
'(
(awk . t)
(C . t)
(css . t)
(dot . t)
(emacs-lisp . t)
(gnuplot . t)
(makefile . t)
(plantuml . t)
(python . t)
(shell . t)
(sql . t)
(sqlite . t)
)
)
Also see:
See: StackOverflow: Org Bable Redirect stderr (-c option requires an argument).
Either:
- Redirect all output at the file level:
#+PROPERTY: header-args:shell :prologue "exec 2>&1" :epilogue ":" :results drawer
- Redirect all output at the Heading level:
:PROPERTIES: :header-args:shell: :prologue "exec 2>&1" :epilogue ":" :results drawer :END:
NOTE: C-cC-c
on the Property block to refresh for the file.
;; (make-directory "~/org/jira/" t)
;; (use-package org-jira
;; :ensure t
;; :defer t
;; :config
;; (setq
;; jiralib-url "https://eigentech.atlassian.net/"
;; org-jira-working-dir "~/org/jira/"
;; )
;; )
;; This is an Emacs package that creates graphviz directed graphs from
;; the headings of an org file
;; https://github.com/theodorewiles/org-mind-map
(use-package org-mind-map
;; Switch to a fork due to org-mind-map waiting to be moved to new maintainers.
:vc (:url "https://github.com/lockywolf/org-mind-map.git"
:rev :newest)
:init
(require 'ox-org)
:ensure t
:ensure-system-package (gvgen . graphviz)
:config
(setq org-mind-map-default-graph-attribs
'(("autosize" . "false")
("size" . "9,12")
("resolution" . "200")
("nodesep" . "0.75")
("overlap" . "false")
("spline" . "true")
("rankdir" . "LR")))
;; (setq org-mind-map-engine "dot") ; Default. Directed Graph
;; (setq org-mind-map-engine "neato") ; Undirected Spring Graph
;; (setq org-mind-map-engine "twopi") ; Radial Layout
;; (setq org-mind-map-engine "fdp") ; Undirected Spring Force-Directed
(setq org-mind-map-engine "sfdp") ; Multiscale version of fdp for the layout of large graphs
;; (setq org-mind-map-engine "circo") ; Circular Layout
)
Modern Org Presentation solution.
Base config stolen from: Github: jypma/emacsconf2021/blob/master/presentation.org.
(defun my/presentation-setup ()
(shell-command "dunstctl set-paused true")
(turn-off-display-fill-column-indicator-mode)
(flyspell-mode 0)
(setq text-scale-mode-amount 3)
(org-display-inline-images)
(text-scale-mode 1)
(hide-mode-line-mode 1)
(display-line-numbers-mode 0)
;; (visual-fill-column-mode 1) ;; doesn't work in org-tree-slide
(visual-line-mode 1)
(font-lock-flush)
(font-lock-ensure))
(defun my/presentation-end ()
(shell-command "dunstctl set-paused false")
(turn-on-display-fill-column-indicator-mode)
(flyspell-mode 1)
(text-scale-mode 0)
(hide-mode-line-mode 0)
(display-line-numbers-mode 1)
(org-remove-inline-images)
;; (visual-fill-column-mode 0)
(visual-line-mode 0)
(font-lock-flush)
(font-lock-ensure))
(use-package org-tree-slide
:ensure t
;; Load immediately, since it messes with org-mode faces
:demand
:hook
((org-tree-slide-play . my/presentation-setup)
(org-tree-slide-stop . my/presentation-end))
:bind
(:map org-mode-map
("<f6>" . org-tree-slide-mode))
(:map org-tree-slide-mode-map
("p" . 'org-tree-slide-move-previous-tree)
("n" . 'org-tree-slide-move-next-tree)
)
:custom
(org-tree-slide-slide-in-effect nil)
(org-tree-slide-activate-message "Presentation started.")
(org-tree-slide-deactivate-message "Presentation ended.")
(org-tree-slide-header t)
(org-image-actual-width nil)
)
Applying styles to TODO keywords in org files + allow multiple sequences.
See:
- org#Faces for TODO keywords.
- org#Multiple sets in one file.
C-S-<left>/<right>
to jump sub-sequences (Ctrl-Shift-<left>/<right>
).
(setq org-todo-keyword-faces
'(
("TODO" . org-warning)
("FUTURE" . (:foreground "black" :weight bold :background "DarkOrange1"))
("STARTED" . (:foreground "black" :background "gold1"))
("INPROGRESS" . (:foreground "white" :background "green4"))
("BLOCKED" . (:foreground "white" :weight bold :background "red4"))
("CANCELED" . (:foreground "blue" :weight bold :strike-through t))
("PARKED" . (:foreground "DarkGrey"))
)
)
(setq org-todo-keywords
'(
(sequence "TODO" "INPROGRESS" "BLOCKED" "|" "DONE" "CANCELED" "PARKED")
)
)
Modes for drawing diagrams like: Ladder/Sequence, MindMaps, Class/Block/Object, UML diagrams.
.mscgen
files are used to create diagrams from plaintext. These days I am
using UML/mermaid.
- http://www.mcternan.me.uk/mscgen/
- https://emacs-fu.blogspot.com/2010/04/creating-custom-modes-easy-way-with.html
(define-generic-mode
'mscgen-mode ;; name of the mode to create
'("#") ;; comments start with '#'
'("label" "note" "width"
"textcolour" "linecolour" "textbgcolour") ;; some keywords
'(("=" . 'font-lock-operator) ;; '=' is an operator
("=>" . 'font-lock-operator)
("->" . 'font-lock-operator)
(";" . 'font-lock-builtin) ;; ';' is a a built-in
("[" . 'font-lock-builtin)
("]" . 'font-lock-builtin)
("|" . 'font-lock-builtin)
)
'("\\.msc$") ;; files for which to activate this mode
nil ;; other functions to call
"A mode for mscgen files" ;; doc string for this mode
)
(defun mscgen-compile-buffer-hook()
"Compile command to generate a PNG from the current mscgen buffer.
See: https://stackoverflow.com/questions/6138029/how-to-add-a-hook-to-only-run-in-a-particular-mode
for the use of the hook."
(compile (concat "mscgen -T png " buffer-file-name " && mscgen -T svg " buffer-file-name))
(message (concat "Generated PNG/SVG for: " buffer-file-name))
)
(add-hook 'mscgen-mode-hook 'my-programming-defaults-config)
(add-hook 'mscgen-mode-hook
(lambda ()
(add-hook 'after-save-hook 'mscgen-compile-buffer-hook nil 'make-it-local)))
Mermaid is a new plaintext diagram markup that has native rendering support in Github (See: Github Docs: Creating Diagrams). To render locally, you need to install: =mermaid-cli=. Example that should render natively in Github:
sequenceDiagram
A-->B: Works!
- Add to top of file and then
C-cC-c
to both store errors in the RESULT block and to also ignore the puppeteer headless deprecation warning. NOTE: Minor spelling mistake in puppeteer for config #21:#+PROPERTY: header-args:mermaid :prologue "exec 2>&1" :epilogue ":" :pupeteer-config-file ~/.puppeteerrc
- Add:
{"headless": "new"}
to:~/.puppeteerrc
.
brew install mermaid-cli` falls over with: ~Error: mermaid-cli has been
disabled because it installs a pre-built copy of Chromium!
.
Which is mentioned in the Closed:WontFix issue: update brew formula to work
with 9.0.3 #288. Installing via npm
globally instead.
(use-package mermaid-mode
:ensure-system-package (mmdc . "npm install -g @mermaid-js/mermaid-cli")
:ensure t
)
(use-package ob-mermaid
:ensure-system-package (mmdc . "npm install -g @mermaid-js/mermaid-cli")
:ensure t
:config
(add-to-list 'org-babel-load-languages '(mermaid . t))
(org-babel-do-load-languages 'org-babel-load-languages org-babel-load-languages)
)
Create architecture/design images with UML.
Here are some good org-babel plantuml examples: Github: dfeich/org-babel-examples/blob/master/plantuml/plantuml-babel.org.
NOTE: On Mac’s brew
does not symlink OpenJDK
by default, to not break
system packages. Run:
sudo ln -sfn /usr/local/opt/openjdk/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk.jdk
(defun plantuml-compile-buffer-hook()
"Compile command to generate a PNG from the current plantuml buffer."
(compile (concat "java -jar ~/org/plantuml.jar " buffer-file-name ";\njava -jar ~/org/plantuml.jar -tsvg " buffer-file-name))
(message (concat "Generated PNG for: " buffer-file-name))
)
(use-package plantuml-mode
;; https://plantuml.com/emacs
:ensure-system-package ((dot . graphviz) (java))
:ensure t
:after (org org-src)
;; FIXME: since my tree-sit change in python to use `python-mode`
;; everywhere, it seems to have broken the `.plantuml` look-up in
;; `auto-mode-alist`. ie. plantuml files open up with `python-mode` ??
:mode "\\.plantuml\\'"
:hook
(
(plantuml-mode . my-programming-defaults-config)
(plantuml-mode . (lambda () (add-hook 'after-save-hook 'plantuml-compile-buffer-hook nil 'make-it-local)))
)
:init
;; Enable plantuml-mode for PlantUML org code block
(add-to-list 'org-src-lang-modes '("plantuml" . plantuml))
:config
(setq
;; Use plantuml server, once: ~(setq plantuml-default-exec-mode 'server)~.
;; https://hub.docker.com/r/plantuml/plantuml-server
;; docker run -d -p 8099:8080 plantuml/plantuml-server:jetty
;; plantuml-server-url "http://localhost:8099"
;; See: following issue for inability to use PlantUML server in org-babel:
;; https://github.com/skuro/plantuml-mode/issues/165
org-plantuml-jar-path "~/org/plantuml.jar"
plantuml-jar-path "~/org/plantuml.jar"
plantuml-default-exec-mode 'jar
)
)
(use-package docker
:ensure t
:defer t
:bind ("C-c d" . docker)
:custom
(
;; https://github.com/Silex/docker.el/issues/188
;; Don't use vterm everywhere.
(docker-run-async-with-buffer-function 'docker-run-async-with-buffer-shell)
(docker-container-columns '(
(:name "Names" :width 40 :template "{{ json .Names }}" :sort nil :format nil)
(:name "Status" :width 30 :template "{{ json .Status }}" :sort nil :format nil)
(:name "Image" :width 40 :template "{{ json .Image }}" :sort nil :format nil)
(:name "Id" :width 12 :template "{{ json .ID }}" :sort nil :format nil)
(:name "Ports" :width 20 :template "{{ json .Ports }}" :sort nil :format nil)
(:name "Command" :width 23 :template "{{ json .Command }}" :sort nil :format nil)
(:name "Created" :width 23 :template "{{ json .CreatedAt }}" :sort nil :format (lambda (x) (format-time-string "%F %T" (date-to-time x))))
)
)
)
)
eglot
uses: https://github.com/rcjsuen/dockerfile-language-server-nodejs.
(use-package dockerfile-mode
:ensure-system-package (docker-langserver . "npm install -g dockerfile-language-server-nodejs")
:ensure t
;; TODO: Raise bug about how this `:after` call breaks `eglot` automatically
;; running.
;; :after (eglot)
:hook
(
((dockerfile-mode dockerfile-ts-mode) . eglot-ensure)
((dockerfile-mode dockerfile-ts-mode) . (lambda () (set (make-local-variable 'compile-command) "docker build .")))
)
)
;; (use-package kubernetes
;; ;; https://kubernetes-el.github.io/kubernetes-el/
;; :ensure t
;; :defer t
;; :commands (kubernetes-overview)
;; :init
;; ;; https://github.com/kubernetes-el/kubernetes-el/issues/265
;; ;; Work around: cyclic dependency.
;; ;; `Debugger entered--Lisp error: (invalid-function kubernetes-utils--save-window-state)`
;; (defmacro kubernetes-utils--save-window-state (&rest body)
;; `(let ((pos (point)) (col (current-column)) (window-start-line (window-start)) (inhibit-redisplay t))
;; (save-excursion ,@body)
;; (goto-char pos)
;; (move-to-column col)
;; (set-window-start (selected-window) window-start-line)))
;; )
Tramp into a docker container with: C-x C-f /docker:[user@]container:/path/to/file
Originally used: docker-tramp, but updated to latest Emacs29 (on 2022-10-25)
and now have this warning: ~ ■ Warning (emacs): Package ‘docker-tramp’ has been
obsoleted, please use integrated package ‘tramp-container’ [2 times]~, so
removing for: tramp-container
.
NOTE: TRAMP natively supports Docker, Podman and Kubernetes. Need to look into how this will work in latest Emacs29 branch builds!!
(use-package ansible
; https://github.com/k1LoW/emacs-ansible
:ensure t
:defer t
:config
(progn
(add-hook 'yaml-mode-hook '(lambda () (ansible 1)))
)
(use-package ansible-doc
; https://github.com/lunaryorn/ansible-doc.el
:ensure t
:defer t
:hook (yaml-mode . ansible-doc-mode)
)
(use-package company-ansible
; https://github.com/krzysztof-magosa/company-ansible
:ensure t
:defer t
:after (company)
:config
(add-to-list 'company-backends 'company-ansible)
)
)
Code completions. This can be done with the built-in completion-at-point
(C-M-i
), but using company-mode
for a drop down at point.
(use-package company
:ensure t
:defer t
:bind (:map company-active-map
("C-n" . company-select-next)
([(tab)] . company-complete)
)
:hook ((prog-mode . global-company-mode))
:config
(setq
company-tooltip-limit 20 ; bigger popup window.
company-idle-delay .3 ; decrease delay before autocompletion popup shows.
;; (setq company-backends (delete 'company-semantic company-backends))
)
)
Rate completions by use.
(use-package company-statistics
:ensure t
:after (company-mode)
:hook ((after-init . company-statistics-mode))
)
++ C/CPP:
- https://emacs-lsp.github.io/lsp-mode/page/lsp-cmake/
pipenv install --dev cmake-language-server
.- Bit weird, but need to activate pipenv on a python file in the repo, then reload the CMakeList.txt`.
(use-package cmake-mode
:ensure-system-package (cmake)
:ensure t
:hook ((cmake-mode . eglot-ensure))
)
TODO:
- Move to
eglot
.- Treesit mode is being picked up now but eglot is not enabled in the mode.
- Build
compile_commands.json
.
See: Clangd Docs: Editor Plugins.
(use-package cc-mode
;; https://emacs-lsp.github.io/lsp-mode/page/lsp-clangd/
:ensure-system-package (clangd)
:ensure t
:after (eglot)
:hook (((c++-mode c++-ts-mode c-mode c-ts-mode) . eglot-ensure))
:config
(add-to-list 'major-mode-remap-alist '(c-mode . c-ts-mode))
(add-to-list 'major-mode-remap-alist '(c++-mode . c++-ts-mode))
(add-to-list 'major-mode-remap-alist '(c-or-c++-mode . c-or-c++-ts-mode))
(with-eval-after-load 'eglot
(add-to-list 'eglot-server-programs '((c++-mode c++-ts-mode c-mode c-ts-mode) "clangd"))
)
)
My very very old setup, long before LSP was a thing. Haven’t used it in about a decade.
;; (use-package cc-mode
;; ;; gdb on mac:
;; ;; brew tap homebrew/dupes && brew install gdb
;; ;; Note: gdb keybinding is: C-x C-a C-l, which I did have my rename term windows as.
;; :ensure t
;; :defer t
;; :bind (
;; ;; ("<f9>" . compile)
;; ([remap comment-region] . 'recompile) ; "C-c C-c"
;; ("M-." . 'xref-find-definitions) ; https://www.emacswiki.org/emacs/EmacsTags
;; )
;; :config
;; (progn
;; (use-package smart-compile
;; :ensure t
;; :defer t)
;; (use-package xcscope
;; ;; Use cscope files within emacs, to jump around C/C++ code.
;; ;; https://github.com/dkogan/xcscope.el
;; :ensure t
;; :defer t
;; :config
;; (progn
;; ;; Setup auto-magically hooks into c/c++ modes.
;; (cscope-setup)
;; )
;; (define-key c++-mode-map [remap c-set-style] 'cscope-find-this-symbol) ;; C-c .
;; ;; Note etags search defaults to: M-.
;; )
;; (use-package company-c-headers
;; ;; Complete c-headers
;; :ensure t
;; :defer t
;; :config
;; (push 'company-c-headers company-backends)
;; )
;; ;; cc-mode general settings.
;; ;; g++-4.9 -g3 -Wall -std=c++11 -stdlib=libc++ -lc++ *.cpp
;; ;; clang++ -g3 -Wall -std=c++11 -stdlib=libc++ -lc++ *.cpp
;; (add-to-list 'smart-compile-alist '("\\.[Cc]+[Pp]*\\'" . "clang++ -g3 -Wall -std=c++11 -stdlib=libc++ -lc++ -o %n.out *.cpp"))
;; (add-hook 'c-mode-common-hook 'my-programming-defaults-config)
;; (setq c-basic-offset 4) ;; http://emacswiki.org/emacs/IndentingC
;; (setq c-default-style "linux") ;; http://cc-mode.sourceforge.net/html-manual/Built_002din-Styles.html#Built_002din-Styles
;; ;; FIXME: Either bound this to `*compilation*` window only, so it stops
;; ;; jumping when I grep, or find the old stop-on-first-error behaviour I
;; ;; used to use.
;; (setq compilation-auto-jump-to-first-error nil)
;; )
;; (define-key c++-mode-map [remap comment-region] 'compile) ;; C-c C-c
;; )
(use-package clang-format
;; Applies clang-format to C++ files based on a .clang-format file in the
;; project.
;; requires `clang-format` to be installed from system package manger.
:ensure-system-package (clang)
:ensure t
:after (cc-mode)
:config
(progn
(define-key c++-mode-map (kbd "C-c #") 'clang-format-region)
)
)
Used to use this a decade ago. Not sure if it’s worth keeping now that LSP is the common way to offload completions and look-ups.
(defun create-tags (dir-name)
"Create tags file in directory: DIR-NAME."
(interactive "Directory: ")
(eshell-command
; (format "find %s -type f -name \"*.[ch]\" | etags -" dir-name))) ;; `.c`/`.h` in a non-git repo.
(format "cd $(git rev-parse --show-toplevel) && git ls-files | etags -" dir-name))) ;; tag all files.
FIXME: keep getting: `Unable to activate package ‘csharp-mode’.` messages, so disabling until I have time to re-implement with `lsp-mode`.
;; (defun my-csharp-mode-syntax ()
;; "Hook for my tweaks to 'csharp-mode'."
;; (interactive)
;; ;; https://www.gnu.org/software/emacs/manual/html_node/efaq/Indenting-switch-statements.html
;; ;; https://stackoverflow.com/questions/3954607/c-sharp-emacs-mode-questions-indentation-and-build#3956173
;; ;; http://kirste.userpage.fu-berlin.de/chemnet/use/info/cc-mode/cc-mode_6.html
;; ;; `C-cC-s` to see indent at point.
;; (c-set-offset `inline-open 0) ; Stop brackets being indented further on a method.
;; )
;; (use-package csharp-mode
;; ;; https://jamiecollinson.com/blog/my-emacs-config/#c-1
;; :ensure t
;; :defer t
;; :init
;; (add-hook 'csharp-mode-hook 'my-programming-defaults-config)
;; (add-hook 'csharp-mode-hook 'my-csharp-mode-syntax)
;; ;; https://stackoverflow.com/questions/4608679/can-i-change-emacs-default-compile-command
;; (add-hook 'csharp-mode-hook (lambda () (set (make-local-variable 'compile-command) "cd $(git rev-parse --show-toplevel) && dotnet run")))
;; (use-package omnisharp
;; ;; https://github.com/OmniSharp/omnisharp-emacs
;; ;; https://jamiecollinson.com/blog/my-emacs-config/#c-1
;; ;; https://www.tuicool.com/articles/22a2Ejb
;; ;; NOTE: Needs a project with a `.csproj` file to do completions. Done with:
;; ;; `dotnet new <project_type>`
;; ;; FIXME: Deferring since I don't have omnisharp installed. Currently not
;; ;; doing csharp. Should do a check of packages installed.
;; :defer t
;; :after (company)
;; :bind (:map omnisharp-command-map
;; ;; FIXME: Make these not global to C++ !!
;; ("C-c f" . 'omnisharp-run-code-action-refactoring) ; Refactor/missing_imports/etc...
;; ("M-." . 'omnisharp-go-to-definition)
;; )
;; :config
;; (add-hook 'csharp-mode-hook 'omnisharp-mode)
;; (add-to-list 'company-backends 'company-omnisharp))
;; (use-package coverlay
;; ;; https://github.com/twada/coverlay.el
;; ;; Coverage from an LCOV file.
;; ;; Watch a file via: `M-x coverlay-watch-file /path/to/lcov-file`. or:
;; ;; `C-c C-l w`.
;; :ensure t
;; :defer t
;; :init
;; (setq coverlay:mark-tested-lines nil)
;; )
;; )
TODO: switch over to eglot!
(use-package css-mode
; https://emacs-lsp.github.io/lsp-mode/page/lsp-css/
:ensure t
:ensure-system-package (vscode-langservers-extracted)
:defer t
:hook ((css-mode css-ts-mode) . eglot-ensure)
)
(use-package csv-mode
:ensure t
:defer t)
(use-package dap-mode
:if (not (eq system-type 'windows-nt)) ;; FIXME: (void-function dap-ui-mode)
:ensure t
:defer t
:after (lsp hydra)
:bind (
([f6] . dap-hydra)
([f7] . 'dap-ui-repl)
)
:commands
(
dap-mode
dap-ui-mode
dap-tooltip-mode
dap-ui-controls-mode
)
:config
(setq
;; NOTE: For Python. install: `debugpy` python package in the project!
dap-python-debugger 'debugpy ;; The default: `ptvsd` is deprecated!
dap-ui-variable-length 1000 ;; https://github.com/emacs-lsp/dap-mode/issues/416 - don't truncate `locals` variables.
dap-internal-terminal 'dap-internal-terminal-shell ;; Forgotten how to scroll `vterm` so using shell.
)
;; https://www.reddit.com/r/emacs/comments/tckmb2/dapmode_breakpoints_not_showing_when_in_terminal/
(add-hook 'dap-stopped-hook
(lambda (arg) (call-interactively #'dap-hydra)))
)
;; (use-package dap-LANGUAGE) to load the dap adapter for your language
(with-eval-after-load 'dap-faces
(unless (display-graphic-p)
(set-face-background 'dap-ui-marker-face "color-166") ; An orange background for the line to execute
(set-face-attribute 'dap-ui-marker-face nil :inherit nil) ; Do not inherit other styles
(set-face-background 'dap-ui-pending-breakpoint-face "blue") ; Blue background for breakpoints line
(set-face-attribute 'dap-ui-verified-breakpoint-face nil :inherit 'dap-ui-pending-breakpoint-face)
)
)
(use-package realgud
:ensure t
:defer t)
Major mode for .env
files.
(use-package dotenv-mode
:ensure t)
(add-hook 'emacs-lisp-mode-hook 'my-programming-defaults-config)
;; code from: http://www.emacswiki.org/emacs/EmacsLispMode
(add-hook 'emacs-lisp-mode-hook
(lambda ()
;; Pretty-print eval'd expressions.
(define-key emacs-lisp-mode-map
"\C-x\C-e" 'pp-eval-last-sexp)
;; ;; Recompile if .elc exists. ;; recompiles everything on every save -cas
;; (add-hook (make-local-variable 'after-save-hook)
;; (lambda ()
;; (byte-force-recompile default-directory)))
(define-key emacs-lisp-mode-map
"\r" 'reindent-then-newline-and-indent)))
(add-hook 'emacs-lisp-mode-hook 'eldoc-mode)
FIXME: erlang mode is throwing errors on start in latest emacs28!!
;; (use-package erlang
;; ;; (require 'erlang-start)
;; :ensure t
;; :defer t
;; )
(use-package feature-mode
:ensure t
:defer t
:mode "\\.spec\\'"
)
Required by M-x org-plot/gnuplot
.
(use-package gnuplot
:ensure-system-package (gnuplot)
:ensure t
:defer t
)
Mode for editing gnuplot
files.
(use-package gnuplot-mode
:ensure t
:defer t
)
Go config links:
- https://andrewjamesjohnson.com/configuring-emacs-for-go-development/.
- https://legends2k.github.io/note/go_setup/.
- Github Gist: GnaneshKunai/go-ts-fmt.el.
- https://arenzana.org/2019/01/emacs-go-mode/.
- https://honnef.co/articles/writing-go-in-emacs/ & https://honnef.co/articles/writing-go-in-emacs-cont./.
- https://github.com/golang/go/wiki/IDEsAndTextEditorPlugins.
Requires go
& gopls
to be installed. See:
- https://github.com/golang/tools/tree/master/gopls
- https://emacs-lsp.github.io/lsp-mode/page/lsp-gopls/
Also see: Add optional support for tree-sitter #396, which is tracking issues
with supporting the new go-ts-mode
.
(use-package go-mode
:ensure-system-package (go gopls)
:ensure t
:after eglot
:functions flycheck-mode
:preface
(defun cas/go-config ()
"Tame tab indenting for go mode."
(setq tab-width 4)
(setq go-ts-mode-indent-offset 4)
(setq indent-tabs-mode t)
(add-hook 'before-save-hook #'eglot-format-buffer -10 t)
(add-hook 'before-save-hook #'gofmt-before-save)
;; Need the above line to load the: ~gofmt~ package in emacs. Why!?
;; (add-hook 'before-save-hook 'gofmt nil t)
(if (not (string-match "go" compile-command))
(set (make-local-variable 'compile-command)
"go build -v && go test -v && go vet"))
)
:hook (
((go-mode go-ts-mode) . cas/go-config)
((go-mode go-ts-mode) . eglot-ensure)
)
)
Debug Go programs with: Delve, via: go-dlv on top of realgud.
For help either look at: Github:
go-delve/delve/blob/master/Documentation/cli/README.md, or: help
in a
running delve process.
Typical workflow might be:
- Debug Tests:
M-x dlv <return> dlv test <return>
, Debug App:dlv debug
. - Set Breakpoint:
b <file>:<line>
, List:bp
, toggle:toggle <int>
- Start/Continue:
c
. - Step:
s
, Step Over:n
, Step Out:n
. - Print variable:
p <variable>
. - Call function:
call <func>
. - Restart:
r
. **NOTE:** need to restart debug session to pick up file changes!! - Exit:
exit
(use-package go-dlv
:ensure-system-package (delve)
:ensure t
:after (realgud)
)
Go support in org-code blocks.
(use-package ob-go
:ensure t
:config
(add-to-list 'org-babel-load-languages '(go . t))
(org-babel-do-load-languages 'org-babel-load-languages org-babel-load-languages)
)
This will allow the following code block to run:
fmt.Println("Current Time:", time.Now())
(use-package graphql-mode
:ensure t
:defer t
)
Dependency on GraphQL-mode to do requests.
(use-package request
:ensure t
:defer t
)
(use-package groovy-mode
; https://github.com/Groovy-Emacs-Modes/groovy-emacs-modes
:ensure t
:defer t
:mode (
("\\.groovy\\'" . groovy-mode)
("\\Jenkinsfile*\\'" . groovy-mode)
)
:config
(progn
(add-hook 'groovy-mode-hook 'my-programming-defaults-config)
)
)
; https://emacs-lsp.github.io/lsp-mode/page/lsp-html/
;; (add-hook 'html-mode-hook 'lsp)
(use-package i3wm-config-mode
:ensure t
:defer t)
See: InnoSetup mode: https://jrsoftware.org/isinfo.php
(use-package iss-mode
:mode "\\.iss\\'"
:ensure t
:defer t
:init
(setq iss-compiler-path "C:/Program Files (x86)/Inno Setup 6")
)
(defun my-java-mode-syntax ()
"Hook for my tweaks to `java-mode`."
(interactive)
;; https://www.gnu.org/software/emacs/manual/html_node/efaq/Indenting-switch-statements.html
(c-set-offset 'case-label '+) ; A "case" or "default" label.
(c-set-offset 'brace-list-entry '++) ; Subsequent lines in an enum or static array list.
(c-set-offset `arglist-intro `+) ; function fields on a new line.
)
;; https://writequit.org/eos/eos-java.html
;; https://github.com/dakrone/emacs-java-imports
;; https://github.com/mopemope/meghanada-emacs
(use-package meghanada
:ensure t
:defer t
:init
(add-hook 'java-mode-hook #'meghanada-mode)
(add-hook 'java-mode-hook 'flycheck-mode)
(add-hook 'java-mode-hook 'my-programming-defaults-config)
;; Java warnings stop compilation scrolling, so let's always scroll.
(add-hook 'java-mode-hook (lambda() compilation-scroll-output t))
(add-hook 'java-mode-hook (lambda () compile-command "cd $(git rev-parse --show-toplevel) && mvn clean verify"))
(add-hook 'java-mode-hook 'my-java-mode-syntax)
)
(use-package mvn
:ensure t
:defer t
:init
;; Correctly colourise the compilation buffer for maven calls.
;; https://github.com/apg/mvn-el
(ignore-errors
(require 'ansi-color)
(defun colorize-compilation-buffer ()
(when (eq major-mode 'compilation-mode)
(let ((inhibit-read-only t))
(if (boundp 'compilation-filter-start)
(ansi-color-apply-on-region compilation-filter-start (point))))))
(add-hook 'compilation-filter-hook 'colorize-compilation-buffer))
)
;; https://github.com/codesuki/add-node-modules-path
;; (use-package add-node-modules-path
;; :ensure t
;; :defer t
;; )
;; https://github.com/jscheid/prettier.el
;; (use-package prettier
;; :ensure t
;; :defer t
;; )
; https://github.com/prettier/prettier-emacs
; Requires global prettier install: `npm install -g prettier`.
;; (use-package prettier-js
;; :ensure t
;; :defer t
;; )
; https://emacs.cafe/emacs/javascript/setup/2017/05/09/emacs-setup-javascript-2.html
; https://emacs-lsp.github.io/lsp-mode/tutorials/reactjs-tutorial/ = ts-ls.
; https://emacs-lsp.github.io/lsp-mode/page/lsp-eslint/
; https://classic.yarnpkg.com/en/docs/cli/global
; - move yarn global install path to home dir and then install eslint globally.
; `yarn config set prefix ~/.yarn`
; `npx -p node@14 yarn global add eslint`
; `M-x lsp-install-server <ret> eslint <ret>`
(use-package js2-mode
:ensure t
:defer t
:mode ("\\.js\\'" "\\.jsx\\'" "\\.mjs\\'")
:hook (
;; (js2-mode . add-node-modules-path)
;; (js2-mode . prettier-js-mode) ; runs prettier on save.
;; (js2-mode . prettier-mode) ; runs prettier on save.
(js2-mode . eglot-ensure)
)
;; :config
)
;; FIXME: need to update the path to my local node-modules for my project that
;; is in a sub-directory of the repo.
;; (use-package eslint-fix
;; ; https://github.com/codesuki/eslint-fix
;; :ensure t
;; :defer t
;; :hook (
;; (js-mode . selint-fix)
;; (js2-mode . selint-fix)
;; )
;; :init
;; (setq eslint-fix-executable "npx eslint")
;; )
(use-package json-mode
:ensure t
:defer t
:mode ("\\.json\\'" . json-mode)
:hook (
(json-mode . my-programming-defaults-config)
(json-mode . (lambda () (auto-fill-mode -1))) ;; disables auto fill at column.
(json-mode . (lambda () (setq js-indent-level 2)))
)
)
;; *****************************************************
;; *****************************************************
;; Json programming
;; *****************************************************
;; *****************************************************
; TODO: Figure out which package is requiring `json-reformat` ??
;; Debugger entered--Lisp error: (file-missing "Cannot open load file" "No such file or directory" "json-reformat")
;; require(json-reformat)
;; byte-code("\300\301!\210\300\302!\210\300\303!\210\300\304!\210\305\306\307\310\311\301%\207" [require js rx json-snatcher json-reformat custom-declare-group json-mode nil "Major mode for editing JSON files." :group] 6)
;; json-mode()
;; set-auto-mode-0(json-mode nil)
;; set-auto-mode--apply-alist((("\\.iss\\'" . iss-mode) ("\\.msc$" . mscgen-mode) ("\\.rcp\\'" . emacs-lisp-mode) (".*mutt.*" . mail-mode) ("\\.plantuml\\'" . plantuml-mode) ("\\.odc\\'" . archive-mode) ("\\.odf\\'" . archive-mode) ("\\.odi\\'" . archive-mode) ("\\.otp\\'" . archive-mode) ("\\.odp\\'" . archive-mode) ("\\.otg\\'" . archive-mode) ("\\.odg\\'" . archive-mode) ("\\.ots\\'" . archive-mode) ("\\.ods\\'" . archive-mode) ("\\.odm\\'" . archive-mode) ("\\.ott\\'" . archive-mode) ("\\.odt\\'" . archive-mode) ("\\.mjs\\'" . js2-mode) ("\\.jsx\\'" . js2-mode) ("\\.js\\'" . js2-mode) ("\\.py\\'" . python-mode) ("\\.restclient\\'" . restclient-mode) ("\\.json\\'" . json-mode) ("\\.yaml\\'" . yaml-mode) ("\\.yml\\'" . yaml-mode) ("\\.\\(e?ya?\\|ra\\)ml\\'" . yaml-mode) ("\\.md\\'" . markdown-mode) ("\\Jenkinsfile*\\'" . groovy-mode) ("\\.groovy\\'" . groovy-mode) ("\\.php\\'" . php-mode) ("\\.\\(?:php[s345]?\\|phtml\\)\\'" . php-mode-maybe) ("\\.\\(?:php\\.inc\\|stub\\)\\'" . php-mode) ("/\\.php_cs\\(?:\\.dist\\)?\\'" . php-mode) ("web.config$" . xml-mode) ("\\.cmake\\'" . cmake-mode) ("CMakeLists\\.txt\\'" . cmake-mode) ("\\.tsv\\'" . tsv-mode) ("\\.[Cc][Ss][Vv]\\'" . csv-mode) ("\\.dockerfile\\'" . dockerfile-mode) ("/Dockerfile\\(?:\\.[^/\\]*\\)?\\'" . dockerfile-mode) ("\\.hrl\\'" . erlang-mode) ("\\.erl\\'" . erlang-mode) ("/ebin/.+\\.app" . erlang-mode) ("\\.yrl" . erlang-mode) ("\\.xrl$" . erlang-mode) ("\\.hrl$" . erlang-mode) ("\\.escript" . erlang-mode) ("\\.app\\.src$" . erlang-mode) ("\\.erl$" . erlang-mode) ("go\\.mod\\'" . go-dot-mod-mode) ...) nil nil)
;; set-auto-mode()
;; normal-mode(t)
;; after-find-file(nil nil)
;; find-file-noselect-1(#<buffer package.json> "~/work/Apollo/Unlock/unlock_webui/package.json" :nowarn nil "~/work/Apollo/Unlock/unlock_webui/package.json" (27399170 66307))
;; find-file-noselect("/home/craig/work/Apollo/Unlock/unlock_webui/packag..." :nowarn)
;; desktop-restore-file-buffer("/home/craig/work/Apollo/Unlock/unlock_webui/packag..." "package.json" nil)
;; desktop-create-buffer(208 "/home/craig/work/Apollo/Unlock/unlock_webui/packag..." "package.json" fundamental-mode (override-global-mode global-whitespace-mode company-mode projectile-mode which-key-mode dap-mode global-auto-revert-mode) 2720 (nil nil) nil nil ((buffer-display-time 24951 42966 348475 416000) (buffer-file-coding-system . utf-8-unix)) ((mark-ring nil)))
;; eval-buffer(#<buffer *load*> nil "/home/craig/.emacs.desktop" nil t) ; Reading at buffer position 15343
;; load-with-code-conversion("/home/craig/.emacs.desktop" "/home/craig/.emacs.desktop" t t)
;; load("/home/craig/.emacs.desktop" t t t)
;; desktop-read()
;; #f(compiled-function () #<bytecode -0x19a5bc467a428ba3>)()
;; run-hooks(after-init-hook delayed-warnings-hook)
;; command-line()
;; normal-top-level()
(use-package json-reformat
:ensure t
:defer t)
Setup Flycheck (Code checking on the fly (replaces flymake)). Used to run this for years, but moving back to using emacs built-ins.
(use-package flycheck ; On-the-fly syntax checking
:ensure t
:defer t
:bind (:map flycheck-mode-map
("C-c e" . list-flycheck-errors)
("C-c T f" . flycheck-mode)
("C-c j" . flycheck-next-error)
)
;; :init (global-flycheck-mode)
:config
(progn
(setq
flycheck-completion-system 'ido
flycheck-highlighting-mode 'lines
flycheck-display-errors-delay 0.0
flycheck-flake8-maximum-complexity 10
flycheck-flake8rc "setup.cfg"
flycheck-highlighting-mode (quote lines)
;; Set the standard library to libc++ so that C++11 headers will work
flycheck-clang-standard-library "libc++"
)
(set-face-attribute 'flycheck-error nil :background "DarkRed") ; dark red
(set-face-attribute 'flycheck-warning nil :background "DarkBlue") ; dark blue
(set-face-attribute 'flycheck-info nil :background "DarkGreen") ; dark green
;; Use italic face for checker name
(set-face-attribute 'flycheck-error-list-checker-name nil :inherit 'italic)
)
:diminish flycheck-mode)
(flycheck-mode flycheck-mode-line) ; Flycheck status
'(flycheck-error-list-column-number ((t (:inherit font-lock-constant-face :background "blue"))))
'(flycheck-warning ((t (:background "DarkBlue" :underline (:color "DarkOrange" :style wave)))))
;; ;; Chain modes after `lsp`.
;; ;; https://rat.dev/flycheck/flycheck/issues/1762
;; (defvar-local my/flycheck-local-cache nil)
;; (defun my/flycheck-checker-get (fn checker property)
;; (or (alist-get property (alist-get checker my/flycheck-local-cache))
;; (funcall fn checker property)))
;; (advice-add 'flycheck-checker-get :around 'my/flycheck-checker-get)
;; (add-hook 'lsp-managed-mode-hook
;; (lambda ()
;; (when (derived-mode-p 'python-mode)
;; (setq my/flycheck-local-cache '((lsp . ((next-checkers . (python-pylint)))))))))
Log file highlighting
(use-package log4j-mode
:ensure t
:defer t
:mode "\\.log\\'"
)
'(log4j-font-lock-fatal-face ((t (:foreground "darkred" :weight bold))))
'(log4j-font-lock-info-face ((t (:foreground "ForestGreen"))))
'(log4j-font-lock-warn-face ((t (:foreground "orange"))))
lsp-mode
is the external, feature-rich version of: [[*\[\[https://joaotavora.github.io/eglot/\]\[eglot\]\]:][eglot]] (built-in), for
interacting with LSP Servers in emacs.
Seeing LSP and other packages blowing up on this missing requirement.
(use-package posframe
:ensure t
:defer t
)
;; set prefix for lsp-command-keymap (few alternatives - "C-l", "C-c l")
(setq lsp-keymap-prefix "s-l")
(use-package lsp-mode
:ensure t
:defer t
:hook (;; replace XXX-mode with concrete major-mode(e. g. python-mode)
;; Python workflow:
;; * `pipenv install --dev python-language-server[all]`.
;; * Start pipenv: `C-cC-pa`.
;; * Start lsp: `M-x lsp`.
(rust-mode . lsp)
;; if you want which-key integration
(lsp-mode . lsp-enable-which-key-integration)
(lsp-mode . my-programming-defaults-config)
)
:commands lsp
:config
(setq
lsp-file-watch-threshold 20000
gc-cons-threshold 100000000
read-process-output-max (* 1024 1024 4) ;; 4MB
)
)
(use-package lsp-ui
;; https://github.com/emacs-lsp/lsp-ui
:ensure t
:defer t
:after (lsp)
:commands (
lsp-ui-mode
lsp-ui-peek-mode
lsp-ui-sideline-mode
)
:bind (:map lsp-command-map
([remap xref-find-definitions] . #'lsp-ui-peek-find-definitions) ;; M-.
([remap xref-find-references] . #'lsp-ui-peek-find-references) ;; M-?
)
:config
(setq
lsp-ui-doc-show-with-cursor t
)
)
(use-package lsp-treemacs
:after (lsp))
I preferred jedi over rope for ease of setup and usage, but have moved away from Jedi for pyright ([[*\[\[https://emacs-lsp.github.io/lsp-pyright/\]\[lsp-pyright\]\]:][lsp-pyright]]) since it is installed outside of dependencies (so more consistent usage with emacs across repos + no longer have to fight to install dev dependencies for local editor completions). See: https://github.com/pappasam/jedi-language-server.
;; (use-package lsp-jedi
;; :ensure t
;; :defer t
;; :after (python-mode lsp)
;; )
My Current choice of sourcing completions for python: Github: emacs-lsp/lsp-pyright.
(use-package lsp-pyright
:disabled
;; :ensure t
:defer t
:after (python-mode lsp)
:hook (python-mode . (lambda ()
(require 'lsp-pyright)
(lsp)))) ; or lsp-deferred
NOTE: Working on some code that prevents me installing Jedi due to dependency conflicts. Trying out MS Python, but eventually moved over to: [[*\[\[https://emacs-lsp.github.io/lsp-pyright/\]\[lsp-pyright\]\]:][lsp-pyright]]. Error:
(ignore-error module-not-gpl-compatible ;; Added ingore-error due to noise from tree-sitter-langs `python.dylib`. ;; See: https://github.com/emacs-tree-sitter/elisp-tree-sitter/issues/100 for a similar problem on NixOS. )
(use-package lsp-python-ms
:disabled
;; :ensure t
:defer t
:after (python-mode lsp)
:init (setq lsp-python-ms-auto-install-server t)
:hook (python-mode . (lambda ()
(require 'lsp-python-ms)
;; Using `lsp-deferred` since it handles showing
;; errors in the buffer after the MS LSP agent has
;; finished analysis (instead of `lsp`).
(lsp-deferred))))
make-mode (built-in):
FIXME: remove the eglot-ensure
hook on prog-mode
, since there is no
lsp-server for Makefile’s.
(use-package make-mode
:ensure t
:preface
(defun cas/make-mode-config ()
"Set config just for Makefile buffers."
(setq indent-tabs-mode t)
;; (remove-hook 'prog-mode-hook 'eglot-ensure)
)
:hook ((makefile-mode . cas/make-mode-config))
)
NOTE:
flymd
looks to be broken and unmaintained. Useimpatient-mode
for live previews.M-x markdown-preview
, requires:markdown
, to be installed with system package manager.
Look at:
;; https://www.emacswiki.org/emacs/KeyboardMacros
;; https://www.emacswiki.org/emacs/KeyboardMacrosTricks
(fset 'convert-markdown-ref-to-list
"\C-[xreplace-regexp\C-m\\[\\(.*\\)\\].*\C-m* [\\1].\C-m")
(fset 'convert-markdown-github-url-to-ref
"\C-[xreplace-regexp\C-m.*github.com/\\(.*\\)/\\(.*\\)\C-m[Github: \\1/\\2]: https://github.com/\\1/\\2\C-m")
;; FIXME: figure out how to feed the `LFD` or `C-qC-j` without it
;; counting as a real `RET` and breaking the `replace-regexp` with:
;; `\\(` !!
(defalias 'strip-a-ids-from-org-markdown-export
(kmacro "M-< M-x r e p l a c e - r e g e x p RET \\ ( < a SPC i d = .* > < / a > \\ ) RET RET"))
(use-package markdown-mode
;; ~markdown~ in arch package manager.
;; :ensure-system-package (markdown) ;; Required by ~M-x markdown-preview~.
:ensure t
:ensure-system-package (marksman)
:mode ("README\\.md\\'" . gfm-mode)
;; multimarkdown is in brew/yay, but not pulling down on arch??
;; :init (setq markdown-command "multimarkdown")
:bind (
("C-c C-a b" . convert-markdown-ref-to-list)
("C-c C-a g" . convert-markdown-github-url-to-ref)
("C-c C-a s" . strip-a-ids-from-org-markdown-export)
)
:hook (
(markdown-mode . my-text-mode-config)
(markdown-mode . eglot-ensure)
)
)
impatient-mode
is a way of doing live previews of the current buffer in a web
browser.
(use-package impatient-mode
; start webserver with: `M-x httpd-start`.
; Then set the mode on the buffer: `M-x impatient-mode`.
:ensure t
:defer t
)
http-start
doesn’t blow up when port is in use, so this ends up
sending the impatient-mode generated URL to whatever service is already
running on the default port of 8080.
See: https://blog.bitsandbobs.net/blog/emacs-markdown-live-preview/
(defun my-markdown-filter (buffer)
"Function to allow `impatient-mode` to preview markdown. Usage:
* `M-x httpd-start`
* Go to required BUFFER.
* `M-x impatient-mode`
* `M-x imp-set-user-filter RET markdown-html RET`"
(princ
(with-temp-buffer
(let ((tmp (buffer-name)))
(set-buffer buffer)
(set-buffer (markdown tmp))
(format "<!DOCTYPE html><html><title>Markdown preview</title><link rel=\"stylesheet\" href = \"https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/3.0.1/github-markdown.min.css\"/>
<body><article class=\"markdown-body\" style=\"box-sizing: border-box;min-width: 200px;max-width: 980px;margin: 0 auto;padding: 45px;\">%s</article></body></html>" (buffer-string))))
(current-buffer)))
(defun my-markdown-preview ()
"Preview markdown."
(interactive)
(unless (process-status "httpd")
(setq httpd-port 8088)
(httpd-start))
(impatient-mode)
(imp-set-user-filter 'my-markdown-filter)
(imp-visit-buffer))
(use-package html-to-markdown
;; Convert html code to markdown.
:ensure t
:defer t)
(use-package markdown-toc
;; https://github.com/ardumont/markdown-toc
;; Used to generate a table of contents in a markdown file.
:ensure t
:defer t)
pcap:
pcap (wireshark) file support.
(use-package pcap-mode
:ensure t
:defer t)
Need to run the php-language-server for eglot to connect to:
docker kill php-language-server
docker rm php-language-server
docker pull felixfbecker/php-language-server
docker run --detach -p2088:2088 --restart=always --name php-language-server felixfbecker/php-language-server
What’s Next?
- Sign in to your Docker account → docker login
- View a summary of image vulnerabilities and recommendations → docker scout quickview felixfbecker/php-language-server
WARNING: The requested image’s platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested b9a761ffbf9a77c0fa4fbdbc390e7f43977f75338963d7285232766297d903c2
NOTE: On Mac’s; eglot will not connect if it is set to localhost
!
(use-package php-mode
:ensure t
:defer t
:mode ("\\.php\\'" . php-mode)
:hook (
(php-mode-hook . my-programming-defaults-config)
(php-mode . eglot-ensure)
)
;; :custom
;; ;; See: https://2metz.fr/blog/configuring-emacs-eglot-lsp-with-docker-containers/
;; ;; for an example of eglot starting docker containers.
;; (eglot-withhold-process-id "1")
:config
(with-eval-after-load 'eglot
(add-to-list 'eglot-server-programs
'(php-mode . ("127.0.0.1" 2088))))
)
;; '(php-mode . ("docker" "run" "--rm" "--detach" "--name=php-language-server" "felixfbecker/php-language-server"))))
(use-package powershell
:ensure t
:defer t
:hook (
(powershell-mode . my-programming-defaults-config)
; (powershell-mode . lsp) ;; No `Expand-Archive` on Arch pwsh, so cannot install `pwsh-ls` automatically.
)
)
Historical Links:
- http://www.emacswiki.org/emacs/ProgrammingWithPythonDotEl.
- https://github.com/fgallina/python.el.
- http://www.saltycrane.com/blog/2010/05/my-emacs-python-environment/.
NOTE: This still requires running: M-x eglot
and then picking the python LSP
server (suggest: pyright-langserver
).
(use-package python
:ensure-system-package ((python3 . python) (pyright))
:after eglot
:ensure t
:functions flycheck-mode
:preface
(defun cas/python-config ()
"Python additional config."
(if (not (string-match "python" compile-command))
(set (make-local-variable 'compile-command)
"pytest"))
)
:hook (
(python-ts-mode . cas/python-config)
((python-mode python-ts-mode) . eglot-ensure)
)
:config
(setq
;; See: https://github.com/renzmann/treesit-auto#keep-track-of-your-hooks
python-ts-mode-hook python-mode-hook
)
)
Uses Github: psf/black to reformat python buffer on save.
(use-package blacken
:ensure t
:hook (python-mode . blacken-mode)
;; :init
;; NOTE: Commented out below line due to currently working on projects that
;; require `black` but have no: `[tool.black]` in the `pyproject.toml` file.
;; (setq blacken-only-if-project-is-blackened t)
)
Calls isort to sort imports.
TODO: figure out why this is cause code to be eaten from the top of the file on save.
;; (use-package isortify
;; :ensure t
;; :defer t
;; :after (python-mode)
;; :hook (python-mode . isortify-mode)
;; )
Mentioned as the Emacs Ruff integration.
FIXME: bound to only python buffers (with ruff
installed??).
(use-package flymake-ruff
:ensure-system-package ((ruff))
:ensure t
:hook (eglot-managed-mode . flymake-ruff-load)
:custom
;; https://github.com/renzmann/.emacs.d/blob/emacs-29/README.org#python
(python-check-command "ruff")
)
(with-eval-after-load 'compile
(add-to-list 'compilation-error-regexp-alist-alist
'(pyright "^[[:blank:]]+\\(.+\\):\\([0-9]+\\):\\([0-9]+\\).*$" 1 2 3))
(add-to-list 'compilation-error-regexp-alist 'pyright))
;; FIXME: auto activation blows up when a file has no conda env associated to it.
;;
(when (eq system-type 'darwin)
;; FIXME: Bound this to my Work laptop only and not break my personal linux
;; laptop when I don't touch conda.
(use-package conda
:after (python-mode)
:ensure t
:defer t
:config
;; https://github.com/necaris/conda.el/issues/107 - stopped working with
;;conda 4.13.0
;;
;; Brew location for `miniforge`.
;; TODO: bound to `darwin`.
;; TODO: check all available paths to see which exists or look into ENV variables ??
(setq conda-anaconda-home (expand-file-name "/opt/homebrew/Caskroom/miniforge/base/"))
(setq conda-env-home-directory (expand-file-name "/opt/homebrew/Caskroom/miniforge/base/"))
;; ;; Web install location for `miniconda`.
;; (setq conda-anaconda-home (expand-file-name "~/opt/miniconda3/"))
;; (setq conda-env-home-directory (expand-file-name "~/opt/miniconda3/"))
;; if you want interactive shell support, include:
(conda-env-initialize-interactive-shells)
;; if you want eshell support, include:
;; (conda-env-initialize-eshell)
;; (defun conda-autoload ()
;; (interactive)
;; "auto activate conda if environment.yml exists."
;; (f-traverse-upwards (lambda (path)
;; (let ((venv-path (f-expand "environment.yml" path)))
;; (when (f-exists? venv-path)
;; (conda-env-activate-for-buffer)
;; )))))
;; NOTE: Using above function to load env for each buffer, instead of the
;; global mode, since the global setting below doesn't gracefully handle
;; buffers that don't have a conda env.
;;
;; ;; if you want auto-activation (see below for details), include:
;; (conda-env-autoactivate-mode t)
;; ;; if you want to automatically activate a conda environment on the opening of a file:
;; (add-to-hook 'find-file-hook (lambda () (when (bound-and-true-p conda-project-env-path)
;; (conda-env-activate-for-buffer))))
;; modeline
;; (setq-default mode-line-format (cons '(:exec conda-env-current-name) mode-line-format))
;; :hook (
;; (python-mode . conda-autoload)
;; )
)
)
FIXME: removing since current work is poetry in a conda env. Advice is to just use conda to manage the venv loading, since poetry is looking in the wrong location.
(use-package poetry
:ensure t
:defer t
:after (python-mode)
;; :config
;; (poetry-tracking-mode) ;; activate poetry virtualenv's on buffer change.
)
Configure global pyright to pick up project local venv. Starting
eglot, will then call the correctly configured pyright (Still need to
pyvenv-activate
then restart eglot
, for the rest of emacs to be
happy).
- See:
M-x pyrightconfig-write </path/to/venv/>
.M-x eglot
.
(defun pyrightconfig-write (virtualenv)
"Write a `pyrightconfig.json' file at the Git root of a project
with `venvPath' and `venv' set to the absolute path of
`virtualenv'. When run interactively, prompts for a directory to
select."
(interactive "DEnv: ")
;; Naming convention for venvPath matches the field for pyrightconfig.json
(let* ((venv-dir (tramp-file-local-name (file-truename virtualenv)))
(venv-file-name (directory-file-name venv-dir))
(venvPath (file-name-directory venv-file-name))
(venv (file-name-base venv-file-name))
(base-dir (vc-git-root default-directory))
(out-file (expand-file-name "pyrightconfig.json" base-dir))
(out-contents (json-encode (list :venvPath venvPath :venv venv))))
(with-temp-file out-file (insert out-contents))
(message (concat "Configured `" out-file "` to use environment `" venv-dir))))
The replacement to virtualenv
. Do C-cC-pa
or M-x pipenv-activate
to start
a projects pipenv.
;; (use-package pipenv
;; :ensure t
;; :defer t
;; :after (python-mode)
;; :hook (python-mode . pipenv-mode)
;; :init
;; (setq
;; pipenv-projectile-after-switch-function
;; #'pipenv-projectile-after-switch-default))
(use-package pyvenv
:ensure t
:defer t
:after (python-mode)
:functions pyvenv-autoload
:config
(defun pyvenv-autoload ()
"auto activate venv directory if exists. See: https://github.com/jorgenschaefer/pyvenv/issues/51"
(interactive)
(f-traverse-upwards (lambda (path)
(let ((venv-path (f-expand ".venv" path)))
(when (f-exists? venv-path)
(pyvenv-activate venv-path)
)))))
:hook (
(python-mode . pyvenv-autoload)
;; Modified from: https://github.com/jorgenschaefer/pyvenv/issues/95
;; FIXME: correct this so it runs LSP after above call, so I don't
;; need to do: C-xC-v.
;; (pyvenv-post-activate-hooks . lsp)
)
)
rust:
(use-package rust-mode
:ensure t
:defer t
:hook (rust-mode . eglot-ensure)
)
(use-package sh-script
:ensure-system-package ((shellcheck) (bash-language-server))
:ensure t
:defer t
:hook (((shell-script-mode sh-mode bash-ts-mode) . eglot-ensure))
)
- Linter: Github: sqlfluff/sqlfluff
(use-package sql
:ensure-system-package (sqlfluff)
:ensure t
:config
(setq
sql-dialect 'postgres
sql-linter-program 'sqlfluff
indent-tabs-mode nil ;; spaces instead of tabs
)
)
Testing out SQLFluff for linting.
(use-package flymake-sqlfluff
:ensure-system-package (sqlfluff)
:ensure t)
(use-package sql-indent
:ensure t)
Terraform is infrastructure as code to abstract across the big Cloud providers.
(use-package terraform-mode
:ensure-system-package
(
(terraform)
(terraform-ls)
)
:ensure t
:hook (((terraform-mode terraform-ts-mode) . eglot-ensure))
:config (setq terraform-format-on-save t)
;; https://github.com/hashicorp/terraform-ls/blob/main/docs/USAGE.md
(with-eval-after-load 'eglot
(add-to-list 'eglot-server-programs
`(terraform-mode . ,(eglot-alternatives
'(("terraform-ls" "serve")
("terraform-lsp" "serve"))))))
)
(use-package typescript-mode
:ensure t
:ensure-system-package (typescript-language-server)
)
(use-package nxml-mode
:mode ("web.config$" . xml-mode)
:init
(progn
(add-hook 'nxml-mode-hook 'my-programming-defaults-config)
(add-hook 'nxml-mode-hook (lambda () (auto-fill-mode -1))) ;; disables auto fill at column.
;; http://www.nuxeo.com/blog/nxml-mode-tabs/
(add-hook 'nxml-mode-hook (lambda () (setq indent-tabs-mode nil)))
(setq
nxml-child-indent 4
)
)
)
- SO: Pretty Printing XML files on Emacs. Picked the solution below so that I did not have to pull in an OS package.
(defun bf-pretty-print-xml-region (begin end)
"Pretty format XML markup in region. You need to have nxml-mode
http://www.emacswiki.org/cgi-bin/wiki/NxmlMode installed to do
this. The function inserts linebreaks to separate tags that have
nothing but whitespace between them. It then indents the markup
by using nxml's indentation rules."
(interactive "r")
(save-excursion
(nxml-mode)
(goto-char begin)
(while (search-forward-regexp "\>[ \\t]*\<" nil t)
(backward-char) (insert "\n") (setq end (1+ end)))
(indent-region begin end))
(message "Ah, much better!"))
Usage:
- Past XML into an
nxml-mode
buffer. - To expand single-line XML: Select region or jump to start and call:
bf-pretty-print-xml-region
. - To indent multi-line XML: Select region and call:
indent-region
.
Use :ensure-system-package
to install the: Github:
redhat-developer/yaml-language-server for eglot to use. NOTE: Look at the
github page to configure schemas for the YAML file (eg. Kubernetes schema) to
do completions!
(use-package yaml-mode
:ensure-system-package (yaml-language-server)
:ensure t
:hook (((yaml-mode yaml-ts-mode) . eglot-ensure))
)
RedHat maintains a whole library of JSON schemas for it’s Github: redhat-developer/yaml-language-server to use. These need to be pulled in dynamically, so that emacs can appropriately warn/highlight/complete/document the YAML in the current buffer.
Links:
- https://developers.redhat.com/blog/2020/11/25/how-to-configure-yaml-schema-to-make-editing-files-easier#yaml_schema.
- https://emacs-lsp.github.io/lsp-mode/page/lsp-yaml/.
- https://www.schemastore.org/json/.
- https://github.com/SchemaStore/schemastore/commit/12841f7f81401f2c48c3c1c647c9e0739a34a89b for DBT project files.
- Github: joaotavora/eglot/discussions/918 - Eglot + yaml-language-server #918.
Hopefully, Github: yveszoundi/eglot-yaml solves this problem for eglot.
M-x eglot-yaml-schema-for-buffer
to select a JSON schema for the current YAML
buffer.
NOTE: Not in emacs package managers! Commented out for now.
;; (use-package eglot-yaml
;; :ensure t
;; :after (eglot)
;; :hook ((yaml-ts-mode . eglot-yaml-init))
;; )
RSS feeds in emacs.
An Emacs web feeds client.
(use-package elfeed
:ensure t
:defer t
:bind
(:map elfeed-search-mode-map
("l" . elfeed-search-tag--star))
(:map elfeed-show-mode-map
("l" . elfeed-show-tag--star))
:hook (
(elfeed-show-mode . (lambda () (setq-local shr-width 80)))
)
:custom
(elfeed-use-curl t)
(elfeed-log-level 'debug)
:config (setq-default word-wrap t)
;; (setq elfeed-log-level 'debug)
(defun elfeed-show-tag--star ()
(interactive)
(elfeed-show-tag 'star))
(defun elfeed-search-tag--star ()
(interactive)
(elfeed-search-toggle-all 'star))
)
Configure the Elfeed RSS reader with an Orgmode file.
(use-package elfeed-org
:ensure t
:defer t
:config
(setq
rmh-elfeed-org-files (list "~/org/personal/elfeed.org")
)
:init (elfeed-org)
)
(use-package elfeed-protocol
:after (elfeed elfeed-org)
:init
(setq
;; curl recommend
elfeed-use-curl t
elfeed-set-timeout 36000
elfeed-curl-extra-arguments '("--insecure") ;necessary for https without a trust certificate
;; Setup Fever
elfeed-protocol-update-unread-only t
elfeed-protocol-fever-fetch-category-as-tag t
;; ~.authinfo.gpg~ contents: ~machine <ip/hostname> port <port> login <user> password <password>~.
elfeed-protocol-feeds '(("fever+http://[email protected]:8095"
:api-url "http://[email protected]:8095/api/fever.php"
:use-authinfo t))
)
;; enable elfeed-protocol
(elfeed-protocol-enable)
:ensure t
:defer t
:custom
(
(elfeed-protocol-log-trace t)
(elfeed-protocol-fever-maxsize 10)
)
)
(setq my-elfeed-update-timer
(run-at-time 15 15
(lambda () (when (= elfeed-curl-queue-active 0)
(elfeed-protocol-fever-update-older "fever+http://[email protected]:8095")))))
(cancel-timer my-elfeed-update-timer)
(defun elfeed-nuclear-update ()
(interactive)
(cl-loop for entry in (elfeed-search-selected)
do (elfeed-untag-1 entry 'unread))
(elfeed-protocol-fever-reinit "http://[email protected]:8095")
)
(defun elfeed-protocol-advice-rmh-elfeed-org-export-feed (headline)
"Advice for `rmh-elfeed-org-export-feed', add elfeed-protocol ID as suffix for each feed."
(let* ((url (car headline))
(proto-id (car (elfeed-protocol-feed-list))))
(when proto-id
(setcar headline (elfeed-protocol-format-subfeed-id proto-id url)))))
(advice-add 'rmh-elfeed-org-export-feed :before #'elfeed-protocol-advice-rmh-elfeed-org-export-feed)
Update old tags on config change with: M-x elfeed-apply-hooks-now
.
(use-package elfeed-autotag
:after (elfeed elfeed-org elfeed-protocol)
:init
(setq elfeed-autotag-files '("~/org/personal/elfeed.org"))
(elfeed-autotag)
:ensure t
:defer t
)
Youtube integration for Elfeed, the feed reader for Emacs.
(use-package elfeed-tube
:ensure-system-package ((mpv) (yt-dlp))
:ensure t
:defer t
:after (elfeed)
:demand t
:config
;; (setq elfeed-tube-auto-save-p nil) ; default value
;; (setq elfeed-tube-auto-fetch-p t) ; default value
(elfeed-tube-setup)
:bind (:map elfeed-show-mode-map
("F" . elfeed-tube-fetch)
([remap save-buffer] . elfeed-tube-save)))
If you want “live” captions and better MPV support:
(use-package elfeed-tube-mpv
:ensure-system-package (mpv)
:ensure t
:bind (
(:map elfeed-show-mode-map
("C-c C-f" . elfeed-tube-mpv-follow-mode)
("C-c C-w" . elfeed-tube-mpv-where)
("v" . elfeed-tube-mpv)
)
(:map elfeed-search-mode-map
("v" . elfeed-tube-mpv)
)
)
)
A frontend for elfeed (like Mu4e Dashboard).
(use-package elfeed-dashboard
:ensure t
:defer t
:config
(setq elfeed-dashboard-file "~/org/personal/elfeed-dashboard.org")
;; update feed counts on elfeed-quit
(advice-add 'elfeed-search-quit-window :after #'elfeed-dashboard-update-links))
Alternative to [[*\[\[https://github.com/manojm321/elfeed-dashboard\]\[elfeed-dashboard\]\]:][elfeed-dashboard]].
(use-package elfeed-summary
:ensure t
:defer t
:custom
(
(elfeed-summary-default-filter "")
(elfeed-summary-settings
'(
;; (group (:title . "All feeds") (:elements (query . :all)))
(group (:title . "Searches")
(:elements
(search (:filter . "+in-progress")
(:title . "InProgress videos"))
(search (:filter . "+star")
(:title . "Starred"))
(search (:filter . "+favourite")
(:title . "Favourites"))
(search (:filter . "@1-days-ago +unread")
(:title . "Unread today"))
(search (:filter . "@7-days-ago +unread")
(:title . "Unread entries this week"))
(search (:filter . "@6-months-ago emacs")
(:title . "Something about Emacs"))))
(group (:title . "Videos")
(:elements
(group
(:title . "RPGs")
(:elements
(query . (and youtube solorpg))))
(group
(:title . "Coffee")
(:elements
(query . (and youtube coffee))))
(group
(:title . "Documentaries")
(:elements
(query . (and youtube documentary))))
(group
(:title . "Development")
(:elements
(query . (and youtube (design dev programming work)))))
))
(group (:title . "Blogs")
(:elements
(group
(:title . "RPGs")
(:elements
(query . (and solorpg (not youtube)))))
(group
(:title . "Documentaries")
(:elements
(query . (and documentary (not youtube)))))
(group
(:title . "Development")
(:elements
(query . (and (design dev programming work ci tech security) (not youtube)))))
))
(group (:title . "All other feeds") (:elements :misc))
;; (group (:title . "Tags Tree")
;; (:elements
;; (auto-tags (:source . (query . :all)))))
)
)
)
)
FIXME: Raise bug around missing Powerline version in melpa.
- https://sr.ht/~johnhamelink/elfeed-paywall/, https://www.reddit.com/r/emacs/comments/6r07ea/is_elfeed_able_to_extract_full_text_from_articles/ - Avoid paywalls and retrieve content from a feed entry’s link.
- https://github.com/zabe40/elfeed-time - elfeed-time displays the approximate time it will take to read, watch, or listen to an elfeed entry. It can display this information in both elfeed-search-mode, and elfeed-show-mode.
- https://github.com/yt-dlp/yt-dlp,
cvzi/mpv-youtube-upnext#8 - log into YouTube via
either:
.netrc
, or:--cookies
pulled from the browser and stored in a file set in theyt-dlp
config file. - https://cundy.me/post/elfeed/ - Customized
elfeed-search-print-entry-function
to put more useful information on theelfeed-search
buffer. eg. likeelfeed-time
(youtube duration, date). - Fix
elfeed-org
tags on FreshRSS sourced feeds. - https://gist.github.com/alphapapa/80d2dba33fafcb50f558464a3a73af9a - anything worth stealing from Alphapapa’s config?
- https://noonker.github.io/posts/2020-04-22-elfeed/ - any inspiration?
- https://punchagan.muse-amuse.in/blog/elfeed-hook-to-fetch-full-content/ - Fetch full content of a page.
- https://bitbucket.org/shackra/4hoa/src/master/ - A Go application that will burn your feeds and retrieve articles of the Internet for you to read in eww (or any other non-graphical web browser).
Mingus (MPD client)
MPD references:
- https://github.com/dakrone/eos/blob/master/eos-music.org
- https://wiki.archlinux.org/index.php/Music_Player_Daemon
- https://wiki.archlinux.org/index.php/Ncmpcpp
(use-package mingus
:ensure t
:defer t
:bind
(
("C-c m" . mingus)
("<f9>" . mingus-toggle)
("C-<f12>" . mingus-prev)
("<f12>" . mingus-next)
)
:custom
(
(mingus-mpd-host "raudio-office.local")
)
)
Looking to see if there are any good alternative MPD clients to mingus for controlling my remote MPD servers.
C-x Z
Prefixl
Playlist.N
Artists.:
Browser.C
Connect to Profile. Profiles defined via: libmpdel.SPC
Play/Pause toggle.
(use-package mpdel
:ensure t
:custom
(
(libmpdel-hostname "raudio-office.local")
)
:config
(setq libmpdel-profiles
'(
("Local server" "localhost" 6600 ipv4)
("RAudio-Office server" "raudio-office.local" 6600 ipv4)
("RAudio-Office2 server" "raudio-office2.local" 6600 ipv4)
("Volumio-Office server" "volumio-office.local" 6600 ipv4)
("Volumio-Kitchen server" "volumio-kitchen.local" 6600 ipv4)
)
)
(mpdel-mode)
)
Packages around reading (eg. novels/epubs, Speed Reading, etc).
Speed reading by line or word.
(use-package amread-mode
:ensure t
:commands (amread-mode)
:custom
(
(amread-scroll-style 'word)
(amread-voice-reader-language 'english)
(amread-word-speed 10.0) ;; WPS eg. 300WPM = 5WPS.
)
:custom-face
(amread-highlight-face ((t (:background "red4" :foreground "white"))))
)
(use-package devdocs
:ensure t
:defer t
:hook (
(c-mode . (lambda () (setq-local devdocs-current-docs '("c"))))
(c++-mode . (lambda () (setq-local devdocs-current-docs '("cpp" "cmake~3.20"))))
(python-mode . (lambda () (setq-local devdocs-current-docs '("python~3.9" "django~3.2" "django_rest_framework"))))
)
)
Emacs-based screen reader to read words when passing over them, or the whole
buffer with M-<
(beginning-of-buffer
). Toggle with: M-x eloud-mode
.
NOTE:
- This slows down buffer movement greatly.
- Throws traceback when trying to close with a FIDO fuzzy completion. Have to
type out:
eloud-mode<return>
, in:M-x
, to disable. - Espeak Docs: Commnands.
(use-package eloud
:ensure t
:ensure-system-package (espeak)
:config
(if (eq system-type 'darwin)
(setq eloud-espeak-path "/usr/local/bin/espeak"))
(setq eloud-speech-rate 350)
)
iRFC (Download & View RFC’s). FIXME: appears to not exist anymore.
;; (use-package irfc
;; :ensure t
;; :defer t
;; :config
;; (progn
;; (setq
;; irfc-directory "~/Downloads/rfcs/"
;; irfc-assoc-mode t)
;; )
;; )
Reddit client. Guessing this is dead after the public API shutdown, but here is
my original note: FIXME: uncomment once Debugger entered--Lisp error:
(void-variable hierarchy--make)
is fixed.
;; (use-package md4rd
;; :ensure t
;; :defer t
;; )
nov (ereader mode - epub):
Open .epub
archive and then M-x nov-mode
.
(use-package nov
:ensure t
:mode ("\\.epub\\'" . nov-mode)
:custom
(nov-save-place-file "~/org/personal/nov_history")
)
Replacement for built-in doc-view
+ ghostscript
dependency to view
PDF’s. Renders in memory, instead of storing images in an on-disk
cache.
(use-package pdf-tools
:ensure t
:config
(pdf-tools-install)
)
Speed reading in a buffer by flashing each word in turn. Spritz clone for speed reading.
(use-package spray
:ensure t
:defer t)
In spray-mode
buffers, following commands are available:
spray-start/stop
(SPC
) pause or resume spraying.spray-backward-word
(h, <left>
) pause and back to the last word.spray-forward-word
(l, <right>
) inverse of spray-backward-word.spray-faster
(f
) increases speed.spray-slower
(s
) decreases speed.spray-quit
(q, <return>
) quitspray-mode
.
Stackoverflow search. FIXME: package doesn’t exist any more?
;; (use-package sos
;; :ensure t
;; :defer t
;; :bind (("<f5>" . sos))
;; )
Highlight word stems in text buffers, thereby providing artificial fixation points to improve speed reading.
(use-package stem-reading-mode
:ensure t
:defer t)
ansi-term
is terminal emulator. I originally preferred it to
multi-term/eshell/shell, but find shell
works better with paths and running
of applications (eg. `aws` CLI client correctly logging in).
Code from: https://github.com/jwalgran/dotfiles/blob/master/.emacs.d/config.el
(use-package term
:demand t
:bind (("<f2>" . visit-ansi-term)
;; Note: gdb keybinding is: C-x C-a C-l, which I did have my rename term windows as.
;; ("C-x C-a" . open-term)
)
:init
(progn
;; https://github.com/ahinz/emacs-config/blob/7e025076097f045aea2a0aedd0523ee996753346/.emacs.d/ah-modes.el#L268
(defun open-named-term (new-buffer-name cmd &rest switches)
(setq term-ansi-buffer-name (generate-new-buffer-name new-buffer-name))
(setq term-ansi-buffer-name (apply 'make-term term-ansi-buffer-name cmd nil switches))
(set-buffer term-ansi-buffer-name)
(term-mode)
(term-char-mode)
(term-set-escape-char ?\C-x)
(switch-to-buffer term-ansi-buffer-name))
;; https://github.com/ahinz/emacs-config/blob/7e025076097f045aea2a0aedd0523ee996753346/.emacs.d/ah-modes.el#L268
(defun open-term (name)
(interactive "sName: ")
(open-named-term name "/bin/bash"))
(defun visit-ansi-term ()
"If the current buffer is:
1) a running ansi-term named *ansi-term*, rename it.
2) a stopped ansi-term, kill it and create a new one.
3) a non ansi-term, go to an already running ansi-term
or start a new one while killing a defunt one"
(interactive)
(let ((is-term (string= "term-mode" major-mode))
(is-running (term-check-proc (buffer-name)))
(term-cmd "/bin/bash")
(anon-term (get-buffer "*ansi-term*")))
(if is-term
(if is-running
(if (string= "*ansi-term*" (buffer-name))
(call-interactively 'rename-buffer)
(if anon-term
(switch-to-buffer "*ansi-term*")
(ansi-term term-cmd)))
(kill-buffer (buffer-name))
(ansi-term term-cmd))
(if anon-term
(if (term-check-proc "*ansi-term*")
(switch-to-buffer "*ansi-term*")
(kill-buffer "*ansi-term*")
(ansi-term term-cmd))
(ansi-term term-cmd)))))
;; Make ansi-term buffers close when you kill the shell process
(defun term-sentinel--my-advice-term-sentinel (proc msg)
(if (memq (process-status proc) '(signal exit))
(let ((buffer (process-buffer proc)))
ad-do-it
(kill-buffer buffer))
ad-do-it))
(advice-add 'term-sentinel :around #'my-advice-term-sentinel)
)
(add-hook 'ansi-term-hook (lambda () (global-hl-line-mode 0))) ; http://stackoverflow.com/questions/9990370/how-to-disable-hl-line-feature-in-specified-mode
)
Add the following programs to the list of programs that eshell
won’t complain
about not being a proper terminal. This will move out of line-mode and into
paging mode (eg. like scrolling through a man page on a real terminal). See:
- Emacs StackExchange: fix or workaround: “Terminal is not fully functional”.
- Emacs Wiki: Eshell Visual Commands.
NOTE: This will use ansi-term
for those command calls, so can use:
C-xC-j
, and: C-cC-k
, to jump in and out of editing mode.
Bindings:
C-p
/C-n
to move up/down by line.C-cC-p
/C-cC-n
to move up/down to each input/prompt.
(use-package eshell
:ensure t
:config
(setq eshell-history-size 1000000)
(with-eval-after-load 'em-term
(add-to-list 'eshell-visual-commands "aws"))
)
Vterm is a terminal with pretty good ncurses support and compliance.
NOTES: Requires cmake
installed on the system to compile!!
C-cC-t
to enter/exit copy-mode.
(use-package vterm
:if (not (eq system-type 'windows-nt)) ;; FIXME: compiling on Windows.
:ensure-system-package (cmake)
:ensure t
:after (cmake-mode)
:init (setq vterm-always-compile-module t)
:config (setq vterm-max-scrollback 100000)
)
Touch typing practice. Call: M-x speed-type-text
.
(use-package speed-type
:ensure t
:defer t)
Emacs Monkeytype is a typing game/tutor inspired by monkeytype.com but for Emacs.
M-x monkeytype-<buffer|region>
.M-x monkeytype-stop
orC-cC-cs
.
(use-package monkeytype
:ensure t
:defer t
:config
(setq
;; How often to update mode-line
monkeytype-mode-line-interval-update 10
;; Use space instead or newline
monkeytype-treat-newline-as-space t
;; Minimum amount of transitions for test
;; If not enough repeat them
monkeytype-minimum-transitions 50
;; Inserts debugging log, this can take a while
;; if typing text is too long.
monkeytype-insert-log nil
;; Default directory for saving Monkeytype data
monkeytype-directory "~/.monkeytype"
;; Format for time-stamped files for saving.
monkeytype-file-name "%a-%d-%b-%Y-%H-%M-%S"
;; Toggle randomise text
monkeytype-randomize t
;; Toggle downcase text
monkeytype-dowcase t
;; Amount of words for most mistyped words test
monkeytype-most-mistyped-amount 100
;; Toggle auto-fill on typing text
monkeytype-auto-fill nil
;; Toggle auto-fill on words related typing text
monkeytype-words-auto-fill t
;; Toggle auto deletion of trailing white space
monkeytype-delete-trailing-whitespace t
;; Regexp used to divide and extracts words
monkeytype-excluded-chars-regexp "[^[:alnum:]']"
;; Toggle converting downloaded text to ASCII
monkeytype-asciify t
)
)
Create visual menu’s like what `magit` provides, but easily customised.
(use-package hydra :ensure t)
Search YouTube from emacs, play via mpv, download via yt-dlp.
(use-package yeetube
:ensure
:ensure-system-package ((wget))
:custom
(yeetube-display-thumbnails nil)
(yeetube-results-limit 50)
)
Run up a rest client in emacs to quickly test APIs. See:
- http://emacsrocks.com/e15.html
- EmacsConf 2021: Creating technical API documentation and presentations using org-babel, restclient, and org-treeslide.
- Github: jypma/emacsconf2021/blob/master/presentation.org.
Eg. Run (C-cC-c
) the following in an empty buffer with restclient-mode on:
GET https://api.github.com User-Agent: Emacs Restclient
(use-package restclient
:ensure t
:defer t
:mode ("\\.restclient\\'" . restclient-mode)
)
Add restclient
support to org-babel code blocks.
Eg. Run (C-cC-c
) the following code block.
GET https://api.github.com
User-Agent: Emacs Restclient
(use-package ob-restclient
:ensure t
:after (restclient)
:config
(add-to-list 'org-babel-load-languages '(restclient . t))
(org-babel-do-load-languages 'org-babel-load-languages org-babel-load-languages)
)
Configs that look good enough to go back and maybe learn/steal from: