Skip to content

My emacs configuration files

Notifications You must be signed in to change notification settings

henryleach/emacs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

52 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Henry’s Emacs Config File

Setting configuration in an complied org file for better organisation.

Basic Customisation

(setq
     inhibit-startup-screen t
     ;; Get rid of all noises
     ring-bell-function 'ignore
     ;; I might be a beginner, but I know what the scratch buffer is.
     initial-scratch-message nil
     ;; One space should be enough for anyone 
     sentence-end-double-space nil
     ;; Delete the whole line and following newline
     kill-whole-line t
)

;; Accept 'y' in lieu of 'yes'.
(defalias 'yes-or-no-p 'y-or-n-p)
;; Overwrite selected text
(delete-selection-mode t)
;; Line numbers everywhere
(global-display-line-numbers-mode t)
;; Soft line wrapping - only in text modes?
(global-visual-line-mode 1)
;; Show the matching brackets
(show-paren-mode)
;; Also show the column/character position in the modeline
(column-number-mode)
;; No need for tool or menu bar
(menu-bar-mode -1)
(tool-bar-mode -1)

;; Prefer a cursor bar to block, guess it's what I'm used to.
(setq-default cursor-type 'bar)

It can get confusing if emacs saves some custom variable without you expecting it, then changes in your config file don’t seem to work. So send these changes to nowhere

(setq custom-file null-device)

Some performance tweaks: add more memory, the default limits are very low and stop very long lines from hanging emacs.

(setq gc-cons-threshold 100000000)
(setq read-process-output-max (* 1024 1024)) ;; 1mb
;; Avoid performance issues in files with very long lines.
;;(global-so-long-mode 1) only native from V27 onwards
(if (<= emacs-major-version 27)
    (use-package so-long
      :config (global-so-long-mode 1))
    (setq global-so-long-mode 1))

Keybindings

General keybindings that aren’t linked to any specific packages.

  ;; When moving forward I want to be at the start of a word, not the end.
  (global-set-key (kbd "M-f") 'forward-to-word)
;; Backspace and Del are a long reach
(global-set-key (kbd "C-z") 'backward-kill-word)

Various characters that aren’t reliably on all keyboards I use.

(global-set-key (kbd "C-c e") "")
(global-set-key (kbd "C-c u") "ü")
(global-set-key (kbd "C-c o") "ö")
(global-set-key (kbd "C-c s") "ß")

Remap Caps Lock

If you don’t spend much time shouting when you type, it’s worth remapping the Caps Lock key to being Control, as it’s in a much nicer position than the normal control key.

MacOS System Preferences > Keyboard > Modifier Keys

Windows 10 You have to edit the register, because…Windows? Copy the following into a text file, save with a .reg extension, then double click. This requires admin privileges. (From StackExchange).

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout]
"Scancode Map"=hex:00,00,00,00,00,00,00,00,02,00,00,00,1d,00,3a,00,00,00,00,00

Linux None persistently with:

setxkbmap -option ctrl:nocaps

but that won’t survive a reboot. To make the change more permanent we need to add the option “ctrl:nocaps” to /etc/default/keyboard in the XKBOPTIONS=”” part.

Steps from here.

MacOS Options

If you have a UK Keyboard on a Mac, and want to type a hash symbol you need this.

;; Allow hash to be entered
(cond ((eq system-type 'darwin)
	    (global-set-key (kbd "M-3") #'(lambda () (interactive) (insert "#")))
       ))

Windows 10 Options

To get emacs working ‘normally’ there are a couple of steps you should do, Xah tips

  1. Set a ‘HOME’ variable. WinKey + search for ‘Environment Variables’, then create a new one called ‘HOME’ and set it to your home directory, probably c:\Users\username.

UTF-8 Everywhere

(set-charset-priority 'unicode)
(setq locale-coding-system 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(set-selection-coding-system 'utf-8)
(prefer-coding-system 'utf-8)
(setq default-process-coding-system '(utf-8-unix . utf-8-unix))

Backup File Location

It’s crazy to have them scattered everywhere, instead put them in one place:

(setq backup-directory-alist '(("." . "~/.emacs.d/backups")))

Set Frame Title

 (setq frame-title-format
	'((:eval (if (buffer-file-name)
		(abbreviate-file-name (buffer-file-name))
		  "%b"))
   (:eval (if (buffer-modified-p) 
	       ""))
   " - Emacs")
 )

Tabs

Tabs are a bit of a mess and it should probably be fixed once I’ve understood it.

Bookmarks and Recent Files

Seeing recent files is helpful, and especially when you open Emacs, and then can carry on from where you left off.

(recentf-mode 1)
(setq recentf-max-saved-items 25)	;Otherwise it gets very slow
(global-set-key "\C-x\ \C-r" 'recentf-open-files)
(add-hook 'after-init-hook 'recentf-open-files)

Appearance

Theme

Solarized is relatively sedate. ‘material-theme’ is also nice, but has ugly looking blocks around headings in org-mode. The cool kids these days are mostly using Doom Themes.

(use-package solarized-theme
:ensure t
:config
(load-theme 'solarized-dark t))

Fonts and Text Appearance

We want proprtional fonts in a number of places, but not others.

Could probably pick a specific font too if I wanted, something more serify. To see which fonts are available, run (font-family-list) in scratch, and see the result. Can also use (x-list-fonts "Font Name") but that might be for X-based systems only, e.g. not Windows.

To list monospaced fonts, filter with the below, as found on SO.

(seq-filter (lambda (font)
              (when-let ((info (font-info font)))
                (string-match-p "spacing=100" (aref info 1))))
            (font-family-list))

Fonts are very dependant on what’s installed on each system, so there’s a list of preferences and we work through those, picking the first installed one. Sizes can render a bit differently between OSs, with MacOS appearing slightly smaller, so we make that system dependent.

(defun font-candidate (&rest fonts)
   "Return existing font which first match."
   (cl-find-if (lambda (f) (find-font (font-spec :name f))) fonts))

;; Only run when in a windowing system
(when (display-graphic-p)
  ;; Choose fonts in order of preference here
  ;; Must have at least one font that works on each system; 'nix, MacOS and Windows
  (setq var-pitch-fonts '("DejaVu Serif" "Georgia"))
  (setq fix-pitch-fonts '("Calling Code" "DejaVu Sans Mono" "Menlo" "Courier New"))

  ;; Adjust sizes depending on the OS
  (setq var-pitch-font
   (concat
    (apply 'font-candidate var-pitch-fonts) "-"
    (cond ((eq system-type 'darwin) "13")
      ((eq system-type 'berkeley-unix) "9")
      (t "12")) ;; Fallback
     ))

  (setq fix-pitch-font
   (concat
    (apply 'font-candidate fix-pitch-fonts) "-"
    (cond ((eq system-type 'darwin) "12")
      ((eq system-type 'berkeley-unix) "8")
      (t "11")) ;; Fallback
     ))

  (set-face-attribute 'variable-pitch nil :font var-pitch-font)
  (set-face-attribute 'fixed-pitch nil :font fix-pitch-font)

  ;; Default font for most things
  (set-frame-font fix-pitch-font nil t)
)

(defun set-buffer-variable-pitch ()
  (interactive)
  (variable-pitch-mode t)
  (setq line-spacing 3)
   (set-face-attribute 'org-table nil :inherit 'fixed-pitch)
   (set-face-attribute 'org-code nil :inherit 'fixed-pitch)
   (set-face-attribute 'org-block nil :inherit 'fixed-pitch)
  )
;; Specify where the proportional fonts should be used.
(add-hook 'org-mode-hook 'set-buffer-variable-pitch)
(add-hook 'eww-mode-hook 'set-buffer-variable-pitch)
(add-hook 'Info-mode-hook 'set-buffer-variable-pitch)

Mode Line

A fancier modeline. Also run M-x nerd-icons-install-fonts to make sure all the relevant fonts are installed.

;; Needed for multiple mode-line
;; themes
(use-package all-the-icons
  :ensure t
)
;; Don't forget to run M-x all-the-icons-install-fonts

;; now uses 
(use-package doom-modeline
  :ensure t
  :config (doom-modeline-mode 1))

Dimmer

Dims the modeline of the inactive buffers.

(use-package dimmer
  :ensure t
  :custom (dimmer-fraction 0.1)
  :config (dimmer-mode))

Rainbow Delimiters

Pretty and helpful for any bracket heavy languages.

(use-package rainbow-delimiters
 :ensure t
 :config
 (add-hook 'prog-mode-hook #'rainbow-delimiters-mode)
)

Emoji

Guide on setting up emacs-emojify by Ian YE Pan. For Windows there’s the Segoe UI Emoji, for other systems you can download the Noto Colour Emoji and install them. For Linux that’s adding to a ~~/.fonts~ dir and running fc-cache -v ~/.fonts to add them.

 (setq emoji-font (cond
		    ((member "Segoe UI Emoji" (font-family-list)) "Segoe UI Emoji")
		    ((member "Noto Color Emoji" (font-family-list)) "Noto Color Emoji")))

 (use-package emojify
     :ensure t
     :config
     (when emoji-font (set-fontset-font
			t 'symbol (font-spec :family emoji-font) nil 'prepend))
     (setq emojify-display-style 'unicode)
     (setq emojify-emoji-styles '(unicode))
     :hook
	(after-init . global-emojify-mode))

(Yes, there’s a better way of doing the above, code, I just don’t have the brainpower right now 😕.)

Then the easiest way to find and insert an emoji is to call emojify-apropos-emoji.

Xah Colour Colour Codes

Highlights RGB values in their colours, using the following function from Xah Lee.

(defun xah-syntax-color-hex ()
  "Syntax color text of the form 「#ff1100」 and 「#abc」 in current buffer.
URL `http://xahlee.info/emacs/emacs/emacs_CSS_colors.html'
Version 2017-03-12"
  (interactive)
  (font-lock-add-keywords
   nil
   '(("#[[:xdigit:]]\\{3\\}"
      (0 (put-text-property
	  (match-beginning 0)
	  (match-end 0)
	  'face (list :background
		      (let* (
			     (ms (match-string-no-properties 0))
			     (r (substring ms 1 2))
			     (g (substring ms 2 3))
			     (b (substring ms 3 4)))
			(concat "#" r r g g b b))))))
     ("#[[:xdigit:]]\\{6\\}"
      (0 (put-text-property
	  (match-beginning 0)
	  (match-end 0)
	  'face (list :background (match-string-no-properties 0)))))))
  (font-lock-flush))

(add-hook 'css-mode-hook 'xah-syntax-color-hex)
(add-hook 'php-mode-hook 'xah-syntax-color-hex)
(add-hook 'html-mode-hook 'xah-syntax-color-hex)
  

Packages

Own Functions

Load any personal functions.

(add-to-list 'load-path "~/.emacs.d/private_functions/")
(load-library "hl_functions")

Dired

Want to reduce the clutter mostly by hiding hidden files and extended information, which can be done via dired-omit-mode that hides certain files, a function that comes from the additional, built in, dired-x package, and dired-hide-details-mode that list only file and directory names, and nothing else. Toggle it on and off with ~”(“~.

Perhaps package dired+ or dired-subtree is interesting? also other dired hacks. There’s also something in this about dired opening multiple windows, which mine does and is very annoying. Looks like I should be using a instead of RET. Also i opens a directory in the same buffer below.

Also hiding details by default needs to be enabled somehow.

(add-hook 'dired-mode-hook (lambda () (dired-hide-details-mode)))
(with-eval-after-load 'dired
  (require 'dired-x)
  ;; Set dired-x global variables here.  For example:
   (setq-default dired-omit-mode t)
   (setq-default dired-omit-files "^\\.?#\\|^\\.$\\|^\\.\\.$\\|^\\.")
   (define-key dired-mode-map (kbd "C-o") 'dired-omit-mode)
    )
(add-hook 'dired-mode-hook
    (lambda ()
     ;; Set dired-x buffer-local variables here.  For example:
     ;; (dired-omit-mode 1)
      ))

dired-narrow allows you to quickly filter the files in a dired buffer, hit the keybinding and start typing

(use-package dired-narrow
:ensure t
:bind (:map dired-mode-map
            ("/" . dired-narrow)))

Which Key

Shows possible completitions. Also use which-key-postframe?

(use-package which-key 
 :ensure t
 :init 
 (which-key-mode t)
)

Undo-Tree

Naturally bound to C-/, n and p navigate up and down, f and b switch branches. q (or C-q) will quit with changes matching the point you selected.

Also make C-z simple undo, I can’t get that muscle memory out of my fingers.

http://pragmaticemacs.com/emacs/advanced-undoredo-with-undo-tree

(use-package undo-tree
  :ensure t
  :diminish undo-tree-mode
  :config
  (progn
    (global-undo-tree-mode)
    (setq undo-tree-visualizer-timestamps t)
    (setq undo-tree-visualizer-diff t)
    ;;(global-unset-key "\C-z") ;; remove other bindings
    ;;(global-set-key "\C-\/" 'undo-tree-undo)
    (setq undo-tree-history-directory-alist '(("." . "~/.emacs.d/undo")))
    ))

Ido

Better suggestion customisation. Is the list better vertical, or horizontal?

(use-package ido
  :ensure t
  :config
  (progn
    (setq ido-enable-flex-matching t)
    (setq ido-everywhere t)
    (ido-mode 1)
    ;; Display ido results vertically, rather than horizontally
   ;; (setq ido-decorations (quote ("\n-> " "" "\n   " "\n   ..." "[" "]" " [No match]" " [Matched]" " [Not readable]" " [Too big]" " [Confirm]")))
))

Regex

Default Commands Reminder

  • C-s isearch-forward
  • C-r iseach-backward
  • C-M-s isearch-forward-regexp
  • C-M-r isearch-backward-regexp
  • M-% query-replace
  • C-M-% query-replace-regexp - remapped to visual-regexp
(use-package visual-regexp
  :ensure t
  :config
  (progn
    (define-key global-map (kbd "C-M-%") 'vr/query-replace)
    ))

Avy

Avy is a fast way of jumping around the visible screen, and it can do lots of other useful things too.

(use-package avy
  :ensure t
  :bind ("C-c C-SPC" . avy-goto-char-timer)
  )

If you define avy-actions (see them with ? once you’ve narrowed your selection) you can type the character for that action (which won’t be used as an option in the narrowing process) before typing the characters that select your candidate. Then, once you’ve selected your candidate that action will be applied.

Must also remember to use global-pop-mark (C-x C-SPC) to jump back to where you were previously after a little excursion.

Spell Checking

Enable flyspell in all text modes and in those places in source where you write comments. This uses either ispell or aspell on Linux. For Windows and MacOS it seems to be easiest to use Hunspell (MacOS: brew install hunspell). Then you need to download the dictionaries you want, useful note from brew:

Dictionary files (*.aff and *.dic) should be placed in ~/Library/Spelling/ or Library/Spelling. Homebrew itself provides no dictionaries for Hunspell, but you can download compatible dictionaries from other sources, such as https://wiki.openoffice.org/wiki/Dictionaries .

Also emacs on MacOS can’t find hunspell dictionaries unless you start it in the home folder, or use this tip to fix that.

Working on mutli-language support: https://200ok.ch/posts/2020-08-22_setting_up_spell_checking_with_multiple_dictionaries.html https://www.monotux.tech/posts/2021/02/hunspell-multi-lang/ https://stackoverflow.com/questions/42159012/emacs-spell-check-on-fly-for-2-languages

For OpenBSD install hunspell and dicts with:

pkg_add hunspell mozilla-dicts-ca
;; set up hunspell dictionary for windows and macos
(cond ((eq system-type 'windows-nt)
	 (add-to-list 'exec-path "~/.emacs.d/Hunspell/bin/")
	 (setenv "DICTDIR" (expand-file-name "~/.emacs.d/Hunspell/")) 

	 (setq ispell-program-name (locate-file "hunspell"
		      exec-path exec-suffixes 'file-executable-p))
	 (setq ispell-list-command "--list")
	 (setq ispell-local-dictionary "en_GB")
	 ;; Added below to try and get multilanguage to work.
	 ;; (setq ispell-dictionary "en_GB,de_DE_frami")
	 ;; (ispell-set-spellchecker-params)
	 ;; (ispell-hunspell-add-multi-dic "en_GB,de_DE_frami")
	 )
	 ((eq system-type 'darwin)
	 ;; Set $DICPATH to "$HOME/Library/Spelling" for hunspell.
	 (setenv
	  "DICPATH"
	  (concat (getenv "HOME") "/Library/Spelling"))
	 (setenv "DICTIONARY" "en_GB")
	   ;; Assuming this is where "brew install hunspell" puts it.
	 (setq ispell-program-name "/usr/local/bin/hunspell")
	 (setq ispell-list-command "--list")
	 (setq ispell-local-dictionary "en_GB")
	 )
	 ((eq system-type 'berkeley-unix) ;; for OpenBSD, same for other BSDs?
	 (setenv "DICTDIR" "/usr/local/share/mozilla-dicts")
	 (setenv "DICTIONARY" "en-GB")
	 (setq ispell-progam-name "hunspell")
	 (setq ispell-list-command "--list")
	 (setq ispell-local-dictionary "en-GB")
	 )
)
(add-hook 'text-mode-hook 'flyspell-mode)
(add-hook 'prog-mode-hook 'flyspell-prog-mode)

;; On big org files this can get very slow, so use it only when not typing
(use-package flyspell-lazy
  :ensure t
  :config
  (flyspell-lazy-mode 1)
)

Move Buffer

Allows for quick switching of buffers between windows within a frame, bound to C-S-<arrow>.

(use-package buffer-move
  :ensure t
  :config
  (progn
    (global-set-key (kbd "<C-S-up>")     'buf-move-up)
    (global-set-key (kbd "<C-S-down>")   'buf-move-down)
    (global-set-key (kbd "<C-S-left>")   'buf-move-left)
    (global-set-key (kbd "<C-S-right>")  'buf-move-right))
)

Expand Region

(use-package expand-region
  :ensure t
  :bind ("C-=" . er/expand-region))

Org-Mode

Basic changes.

;; show inline images as a default.
(setq org-startup-with-inline-images t)

;; Store links from anywhere
(global-set-key (kbd "C-c l") 'org-store-link)
(global-set-key (kbd "C-c a") 'org-agenda)

More to do states, and their colours (not always theme compatible, should probably update that later).

;; TODO list sequence, add 'IN PROGRESS' and  'WAITING' to default options
(setq org-todo-keywords
      '((sequence "TODO" "IN PROGRESS" "WAITING" "|" "DONE")))

;; Colour the todo keywords
(setq org-todo-keyword-faces
  '(("TODO" . (:foreground "white" :background "OrangeRed3"))
    ("IN PROGRESS" . (:foreground "white" :background "firebrick"))
    ("WAITING" . (:background "pink"))
    ("DONE" . (:background "OliveDrab3"))))

With long ToDo items names, the list can get messy and wrap in unpleasant ways, then a column view is nicer. Can access this from the agenda ToDo view C-c a t using C-c C-x C-c. Note that you have to use this to sequence to refresh the column view as well, pressing g as usual refreshes, but jumps out of the column view. There’s probably a way to fix that.

;; Set the column view for the todo list
;; see in agenda view with C-c C-x C-c
(setq org-columns-default-format
      "%35ITEM %TODO %15DEADLINE %ALLTAGS")

Appearance, based a lot on this. Some useful info here too.

;; Means * / = ~ etc. will be hidden.
(setq org-hide-emphasis-markers t)
(setq org-startup-folded t)
;; Pretty bullets instead of lots of stars
(use-package org-bullets
  :ensure t
  :config
  (add-hook 'org-mode-hook (lambda () (org-bullets-mode 1))))

Keep the agenda files in a separate file. Partly because we disabled writing customisation info into the init.el file, but also it means you can have a text file per installation with the org files for that installation in it. Either add a whole file path, or a folder (ending in ’ / ‘) to add all .org files in it.

If you give the following only a relative path or a file name, it looks in the directory of the currently open buffer. If emacs can’t find it, then any function relating the agenda don’t work (e.g. can’t clock in). If you add files to your agenda list with C-[, or remove them, with C-]) they will be added and removed in this file.

The agenda view will also mess around with your windows/buffer views. With the last option set it will return you to your previous layout when hitting q.

(setq org-agenda-files "~/.emacs.d/agenda_files.txt")

;; The agenda view can mess with your layout
(setq org-agenda-restore-windows-after-quit t)

For the clock table I don’t want it to jump to days, but keep hours as the biggest unit, otherwise it’s harder to compare tasks quickly.

;;Keep the clock table in hours, and not count days
(setq org-duration-format (quote h:mm))

Templates and Skeletons

Use a basic org-mode template for new files. More details at AutoType.

(auto-insert-mode)
(setq auto-insert-query nil)
(define-auto-insert '("\.org" . "Org Skeleton")
'("Short description: "
  "#+TITLE: " (my/create-org-title (buffer-name)) \n
  "#+DATE: "(format-time-string "<%Y-%m-%d %a>") \n
  "#+FILETAGS: " \n \n _))
(define-skeleton html-det-sum
    "Insert the escaped HTML code to create a detail/summary field"
    nil
    >"@@html:<details>@@\n"
    >"@@html:<summary>@@"_"@@html:</summary>@@\n
@@html:</details>@@\n")

Exporting

Normally I just want to export a small section as HTML to copy into an e-mail, never the whole file. This setting doesn’t seem to stick though.

(setq org-export-initial-scope 'subtree)

HTMLIZE

This helps to syntax colour exported code blocks, needed by org-mode’s html export module.

(use-package htmlize
   :ensure t
)

Archiving

Make the archive match the hierarchy in the main org document. Using the org-archive-subtree function. Replaces the usual function, under the same command C-c C-x C-a. This does keep the hierarchy, but not the sequence.

(require 'org-archive-subtree-hierarchical)
(setq org-archive-default-command 'org-archive-subtree-hierarchical)

Programming

Smart Parentheses

A better way of dealing with brackets. github page, and a user guide.

(use-package smartparens-config
  :ensure smartparens
  :config (progn (show-smartparens-global-mode t)) ;; High list current pair
  )
;;(add-hook 'prog-mode-hook 'turn-on-smartparens-strict-mode)

Projectile

Documents for project interaction library. To mark a folder as a project, add a empty ‘.projectile’ file to it.

(use-package projectile
  :ensure t
  :init
  (projectile-mode +1)
  :bind (:map projectile-mode-map
              ("C-c p" . projectile-command-map)))

Treemacs

For better overviews in projects. Documentation

(use-package treemacs
  :ensure t
  :defer t
)

(use-package treemacs-projectile
  :after (treemacs projectile)
  :ensure t)

Company Mode

Company completion can be used in anything, but I only want to use it for coding. Still seems active in comments, which I don’t really want.

(use-package company
  :ensure t
  :defer t
  :diminish
  :config
  (setq company-dabbrev-other-buffers t
        company-dabbrev-code-other-buffers t)
  :hook (;;(text-mode . company-mode)
         (prog-mode . company-mode)))

Python

I want a consistent configuration between Windows, MacOS and Linux; so I suspect this is going to be limited by what I can get work on Windows.

For working with different python environments. This is also loaded/integrated with Elpy, but here we set the WORKON_HOME directory so it’s easier to find them in M-x pyvenv-workon.

(use-package pyvenv
  :ensure t
  :init
  (cond ((eq system-type 'windows-nt)
	  (setenv "WORKON_HOME" "c:/ProgramData/Anaconda3/envs")))
)

Slightly nicer than Flymake. For Python, make sure it’s calling whatever the current envs python is.

(use-package flycheck
  :ensure t
  :config
  :hook (sh-mode . flycheck-mode)
)

LSP Mode is all fancy and modern, but Elpy gets the job done.

For Windows where python is installed via Anaconda, I can only get it to work reliably if I activate the environment I want to work in first in the Anaconda prompt, then launch Emacs. This means installing all the dependencies in each environment first (e.g. jedi, flake8 etc.), but anything else eventually causes a failure as some different version of Python is launched in parallel which is missing the right packages.

(use-package elpy
  :ensure t
  :defer t
  :init
  (advice-add 'python-mode :before 'elpy-enable)
  :config
  (setq elpy-rpc-python-command "python")
  (setq elpy-rpc-virtualenv-path 'current)
  (setq elpy-get-info-from-shell t)
  (when (load "flycheck" t t) ;; is the 3rd value nil or t? depends who you ask. 
     (setq elpy-modules (delq 'elpy-module-flymake elpy-modules))
     (add-hook 'elpy-mode-hook 'flycheck-mode))
  (setq python-shell-interpreter "ipython"
	  python-shell-interpreter-args "-i --simple-prompt")
)

;; This ensures that the python shell buffer scrolls
;; down to show the output of the last run code.
(advice-add 'elpy-shell-send-region-or-buffer
	      :before (lambda (&optional rest)
			(let ((curbuf (current-buffer)))
			  (elpy-shell-switch-to-shell)
			  (goto-char (point-max))
			  (recenter -10)
			  (elpy-shell-switch-to-buffer)))
	      '((name . "elpy-shell-scroll-to-bottom")))

Markdown

(use-package markdown-mode
  :ensure t
  :commands (markdown-mode gfm-mode)
  :mode (("README\\.md\\'" . gfm-mode)
         ("\\.md\\'" . markdown-mode)
         ("\\.markdown\\'" . markdown-mode))
  :init (setq markdown-command "multimarkdown"))

YAML

(use-package yaml-mode
  :mode "\\.yaml\\'"
  :ensure t)

Web

If Web-Mode doesn’t automatically detect the correct engine for templates, you can force the correct one with M-x web-mode-set-engine RET ENGINE_NAME RET, e.g. “go”.

If that gets tiresome it is also possible to add:

-*- engine:ENGINE_NAME -*-

into a comment on the page.

(use-package web-mode
  :ensure t
  :mode ("\\.html\\'"
	   "\\.php\\'")
  :config
  (progn
    (setq web-mode-code-indent-offset 2)
    (setq web-mode-enable-engine-detection t)
    (setq web-mode-enable-auto-quoting nil)))

CSV

CSV-mode docs, default separators are tabs and commas, add semi-colon for all languages that use a comma as a decimal place separator.

The docs say that editing csv-separators should be enough to set the possible separators, but this doesn’t seem to be working correctly, when opening a semi-colon separated file it doesn’t split on the semi-colons.

csv-separator-chars should not be set directly, but trying to set that with =’(44 59 9)= didn’t make any difference. How does csv-mode know which separator it should use in a file? Even reducing the separators to only being “;” didn’t make it work.

(use-package csv-mode
  :ensure t
  :config
  (progn
    ;; Below seems to set the separators correctly, but
    ;; then CSV mode ignores semi-colons when opening files.
    (setq csv-separators '("," ";" "	"))
    )
)

Tex/Latex

For editing LaTex documents AucTeX appears the most integrated option, defaults below from the AucTex manual.

(use-package tex
   :ensure auctex)
(setq TeX-auto-save t)
(setq TeX-parse-self t)
(setq-default TeX-master nil)

Lilypond

Lilypond is a LaTeX like way of marking up musical notation, and then generating the engraving, normally as a PDF file. There is official documentation for it, but that didn’t quite work, this had more details to get Emacs to actually find the lilypond-mode.el file which is automatically installed with lilypond, but not automatically found.. This depends on where it’s been installed, and there must be a good way of doing that. Here I’m just limiting to where it’s installed on a Mac with brew.sh, and only checking it then. There is also an integration with flycheck that might be worth checking out.

(cond ((eq system-type 'darwin)
      (setq load-path (append (list
			       (expand-file-name "/usr/local/Cellar/lilypond/2.22.2/share/emacs/site-lisp/lilypond"))
			       load-path))))

(autoload 'LilyPond-mode "lilypond-mode")
(setq auto-mode-alist
      (cons '("\\.ly$" . LilyPond-mode) auto-mode-alist))

(add-hook 'LilyPond-mode-hook (lambda () (turn-on-font-lock)))

Magit

For working with Git, and related EDiff settings. Could probably customise the faces of the diffs a bit more.

(use-package magit
  :ensure t)

;; Somewhat related EDiff settings
;; Don't use the little pop-up window, and split horizontally by default.
(setq ediff-window-setup-function 'ediff-setup-windows-plain)
(setq ediff-split-window-function 'split-window-horizontally)

Interesting Packages to be investigated

LSP mode for Python development environment instead of Elpy?

References/other config files of interest

https://zzamboni.org/post/my-emacs-configuration-with-commentary/ https://github.com/zzamboni/dot-emacs/blob/master/init.org

https://pages.sachachua.com/.emacs.d/Sacha.html#org955a0ab

https://github.com/patrickt/emacs/blob/master/readme.org (and the init.el file)

http://www.howardism.org/Technical/Emacs/emacs-init.html

https://github.com/cocreature/dotfiles/blob/master/emacs/.emacs.d/emacs.org

https://blog.sumtypeofway.com/posts/emacs-config.html

https://github.com/PythonNut/quark-emacs

Use Package Docs

Ideas? https://zzamboni.org/post/my-blogging-setup-with-emacs-org-mode-ox-hugo-hugo-gitlab-and-netlify/

Useful Commands I always forget

C-h k Describes keybindings M-; Comment region <s TAB Insert Code Block. This is actually part of a whole templating system.