See my config here: https://github.com/durantschoon/.spacemacs.d
This file was created with boilerplate files described in the video here. If you’re just getting started with emacs, you might want to start with some videos I made with my friend Daniel Mai. Unfortunately we lost our original playlists, but we’ve uploaded what we’d saved as these three playlists (we plan to add video descriptions again soon):
This is how I installed emacs on my mac with homebrew:
I use a different (arbitrary) icon for each version, so I can tell at a glance at startup which version I’m using:
Version | Icon |
---|---|
emacs-plus@27 | –with-EmacsIcon4-icon |
emacs-plus@28 | –with-emacs-card-blue-deep-icon |
# uninstall old
brew uninstall emacs-plus
# install new
brew install emacs-plus@28 --with-xwidgets --with-emacs-card-blue-deep-icon
# update link in /Applications in a zsh shell
[[ -L /Applications/Emacs.app ]] && =rm /Applications/Emacs.app
ln -si /usr/local/opt/emacs-plus@28/Emacs.app /Applications/
# delete all byte compiled files in elpa to force the new version to recompile everything
=rm -rf ~/.emacs.d/elpa
I’m using `concat` so the bots don’t find my entire email address and spam me.
(setq user-full-name "Durant Schoon"
user-mail-address (concat "durant.schoon" "@" "gmail.com"))
Set up the customize file to its own separate file, instead of saving customize settings in init.el.
(setq custom-file (expand-file-name "custom.el" user-emacs-directory))
(load custom-file)
You don’t need to read this section. It’s mostly me thinking outloud about how to solve certain problems with my emacs configuration.
I define a list of elisp files I keep on dropbox which I do not want in my git repository, e.g. private.el. Remember to git ignore them! (with ‘i’ in magit with the cursor on the file name under Unstaged changes).
I used to load directly from dropbox, but this will copy over the file the first time I run emacs on a new machine assuming dropbox is set up first.
(progn
(let ((private-emacs-files '("private.el"))
(private-emacs-from-dir "~/Dropbox/emacs/")
(private-emacs-to-dir user-emacs-directory))
(dolist (filename private-emacs-files)
(let ((copy-from (concat private-emacs-from-dir filename))
(copy-to (concat private-emacs-to-dir filename)))
(if (and (file-exists-p copy-from)
(not (file-exists-p copy-to)))
(progn
(message (concat "copying " copy-from " to " copy-to))
(copy-file copy-from copy-to)))))))
Let’s start with some sane defaults, shall we?
Sources for this section include Magnars Sveen and Sacha Chua.
;; These functions are useful. Activate them.
(put 'downcase-region 'disabled nil)
(put 'upcase-region 'disabled nil)
(put 'narrow-to-region 'disabled nil)
;; Remember
;; C-x n n
;; Narrow down to between point and mark (narrow-to-region).
;; This can really freak you out, don't enable it unless you
;; practice getting out of it.
;; C-x n w
;; Widen to make the entire buffer accessible again (widen).
(put 'dired-find-alternate-file 'disabled nil)
;; Answering just 'y' or 'n' will do
(defalias 'yes-or-no-p 'y-or-n-p) ;; "No me rompas las pelotas" cr
;; Keep all backup and auto-save files in one directory
(setq backup-directory-alist '(("." . "~/.emacs.d/backups")))
(setq auto-save-file-name-transforms '((".*" "~/.emacs.d/auto-save-list/" t)))
;; UTF-8 please
(setq locale-coding-system 'utf-8) ; pretty
(set-terminal-coding-system 'utf-8) ; pretty
(set-keyboard-coding-system 'utf-8) ; pretty
(set-selection-coding-system 'utf-8) ; please
(prefer-coding-system 'utf-8) ; with sugar on top
(setq-default indent-tabs-mode nil)
(setq-default indicate-empty-lines t)
;; Turn off the blinking cursor
(blink-cursor-mode -1)
;; Don't count two spaces after a period as the end of a sentence.
;; Just one space is needed.
(setq sentence-end-double-space nil)
;; delete the region when typing, just like as we expect nowadays.
(delete-selection-mode t)
(show-paren-mode t)
(column-number-mode t)
(global-visual-line-mode)
(setq uniquify-buffer-name-style 'forward)
;; -i gets alias definitions from .bash_profile
(setq shell-command-switch "-ic")
;; Don't beep at me
;; (setq visible-bell t)
;; because of a bug in El Capitan, setting this to nil
(setq visible-bell nil)
(require 'package)
;; (package-initialize) ; no longer needed
(add-to-list 'package-archives
'("marmalade" . "http://marmalade-repo.org/packages/") t)
I don’t think I need this
(let ((default-directory "~/.emacs.d/elpa/"))
(normal-top-level-add-subdirs-to-load-path))
I’ll call them “quords” because q followed by any other letter than u should be a good candidate (unlikely to be found in English).
(use-package use-package-chords
:ensure t
:config
(key-chord-mode 1)
(key-chord-define-global "hh" 'win-swap-horizontal)
(key-chord-define-global "vv" 'win-swap-vertical)
(key-chord-define-global "ww" 'toggle-window-split)
(key-chord-define-global "qf" 'ffap-no-confirmation))
(global-set-key (kbd "C-M-/") 'comint-dynamic-complete-filename)
(global-set-key (kbd "s-<tab>") 'completion-at-point)
(define-key global-map (kbd "RET") 'newline-and-indent)
;; key bindings ;; http://ergoemacs.org/emacs/emacs_hyper_super_keys.html
(when (eq system-type 'darwin) ; mac specific settings
;; ---------- REMAP KEYS ----------
;; (setq mac-option-modifier 'alt) ; not needed, I think
(setq mac-command-modifier 'meta)
(setq mac-option-modifier 'super) ; make opt key do Super
(setq mac-control-modifier 'control) ; make Control key do Control
(setq ns-function-modifier 'hyper) ; make Fn key do Hyper
;; ---------- SCROLLING ---------- ; for trackpads
(global-set-key [wheel-right] 'scroll-left)
(global-set-key [wheel-left] 'scroll-right))
(global-set-key [kp-delete] 'delete-char) ;; sets fn-delete to be right-delete
(when (eq system-type 'darwin) ; mac specific settings
(global-set-key "\M-`" 'other-frame) ; act like other mac programs
; was just f11, bad on Darwin
; similar to M-<f10> which is toggle-frame-maximized
(global-set-key (kbd "M-<f11>") 'toggle-frame-fullscreen))
(global-set-key [(meta down)] 'scroll-other-window) ; C-M-v
(global-set-key [(meta up)] 'scroll-other-window-down) ; C-M-S-v
(global-set-key (kbd "C-x 4 o") 'switch-to-buffer-other-window-return)
(global-set-key (kbd "C-x 4 k") 'kill-buffer-other-window)
(require 'windmove)
(defun win-swap-horizontal ()
"Swap windows left/right using buffer-move.el"
(interactive)
(if (null (windmove-find-other-window 'right))
(buf-move-left) (buf-move-right)))
(global-set-key (kbd "C-c h") 'win-swap-horizontal)
(defun win-swap-vertical ()
"Swap windows up/down using buffer-move.el"
(interactive)
(if (null (windmove-find-other-window 'above))
(buf-move-down) (buf-move-up)))
(global-set-key (kbd "C-c v") 'win-swap-vertical)
(defun switch-to-buffer-other-window-return ()
"Like `switch-to-buffer-other-window`, but return to original buffer."
(interactive)
(switch-to-buffer-other-window (other-buffer))
(other-window 1))
(defun kill-buffer-other-window ()
"Kill the buffer in the other window.
I usually work with 2 windows side by side so when I do anything
that opens a buffer in the other window (eg. looking at a function
definition), I'll want to kill it after when I'm done. That's when
I use kill-buffer-other-window."
(interactive)
(other-window 1)
(kill-buffer (current-buffer))
(other-window 1))
;; toggle-window-split
;; See https://www.emacswiki.org/emacs/ToggleWindowSplit
(defun toggle-window-split ()
(interactive)
(if (= (count-windows) 2)
(let* ((this-win-buffer (window-buffer))
(next-win-buffer (window-buffer (next-window)))
(this-win-edges (window-edges (selected-window)))
(next-win-edges (window-edges (next-window)))
(this-win-2nd (not (and (<= (car this-win-edges)
(car next-win-edges))
(<= (cadr this-win-edges)
(cadr next-win-edges)))))
(splitter
(if (= (car this-win-edges)
(car (window-edges (next-window))))
'split-window-horizontally
'split-window-vertically)))
(delete-other-windows)
(let ((first-win (selected-window)))
(funcall splitter)
(if this-win-2nd (other-window 1))
(set-window-buffer (selected-window) this-win-buffer)
(set-window-buffer (next-window) next-win-buffer)
(select-window first-win)
(if this-win-2nd (other-window 1))))))
(global-set-key (kbd "C-x |") 'toggle-window-split)
(global-set-key [f5] 'global-whitespace-mode)
(global-set-key [f6] 'toggle-truncate-lines)
Now that I’m switching to spacemacs my muscle memory wants to do this:
Actually this requires setting up a prefix-key properly which I’ll have to learn about later.
(global-set-key (kbd "M-m g s") 'magit-status)
Testing this. I’m not convinced I like everything about it. phi-search works with multiple cursors.
(global-set-key (kbd "C-s") 'phi-search)
(global-set-key (kbd "C-r") 'phi-search-backward)
(global-set-key (kbd "C-c o") 'browse-url-at-point) ; like "o"pen
(global-set-key (kbd "H-o") 'browse-url-of-buffer) ; like "o"pen
From ZapUpToChar (replaces zap-to-char so it doesn’t zap the char itself)
(defadvice zap-to-char (after my-zap-to-char-advice (arg char) activate)
"Kill up to the ARG'th occurence of CHAR, and leave CHAR. If
you are deleting forward, the CHAR is replaced and the point is
put before CHAR"
(insert char)
(if (< 0 arg) (forward-char -1)))
(toggle-scroll-bar -1)
(defun maximize-frame (frame)
"Maximize frame"
(interactive)
(with-selected-frame frame
(let ((fullscreen (frame-parameter nil 'fullscreen)))
(cond
((memq fullscreen '(fullscreen fullboth))
(set-frame-parameter nil 'fullscreen-restore 'maximized))
(t
(set-frame-parameter nil 'fullscreen 'maximized))))))
(add-hook 'after-make-frame-functions #'maximize-frame)
;; from the iterm2 FAQ, how to use the mouse in emacs in iterm
;; should I make this darwin specific?
(require 'mouse)
(xterm-mouse-mode t)
(defun track-mouse (e) "Make an empty 'track-mouse' function for event E.")
(defun my-prog-mode-hook ()
(linum-mode 1)
(message "Truncating long lines in programming mode...")
(toggle-truncate-lines t)
(setq-local dabbrev-case-fold-search nil) ;; eg. "myVar" expands case-sensitively
(add-to-list 'write-file-functions 'delete-trailing-whitespace))
(add-hook 'prog-mode-hook 'my-prog-mode-hook)
Display information about the current function
(which-function-mode t)
ctags creates a tags file (TAGS) from your source code so you can jump to a program definition.
Remember these (from EmacsWiki):
M-. (‘find-tag’) – find a tag, that is, use the Tags file to look up a definition. If there are multiple tags in the project with the same name, use `C-u M-.’ to go to the next match. M-* ‘M-*’ (‘pop-tag-mark’) – jump back
I started using Universal ctags. Universal ctags replaces exuberent ctags I believe. So you can just run
tags -eR
in directory with your files
If you’re using projectile for managing project directories, see Regenerate tags. I see there is a command `projectile-regenerate-tags`. And it looks like I need to find out more about ggtags.
(when (eq system-type 'darwin)
;;; Useful for https://github.com/dunn/company-emoji
;; https://www.reddit.com/r/emacs/comments/8ph0hq/i_have_converted_from_the_mac_port_to_the_ns_port/
;; not tested with emacs26 (requires a patched Emacs version for multi-color font support)
(if (version< "27.0" emacs-version)
(set-fontset-font
"fontset-default" 'unicode "Apple Color Emoji" nil 'prepend)
(set-fontset-font
t 'symbol (font-spec :family "Apple Color Emoji") nil 'prepend)))
(when (eq system-type 'darwin)
(set-frame-font "Hasklig"))
The Fira Code font has ==> cool ligatures <== ! I followed these instructions including the imporant recommendation to comment out the ‘(46 .’ line below.
DEBUG: The following code works setting the default font to fira code, however when I type C-’ in a source block emacs hangs :(
(when (window-system)
(set-default-font "Fira Code"))
(let ((alist '((33 . ".\\(?:\\(?:==\\|!!\\)\\|[!=]\\)")
(35 . ".\\(?:###\\|##\\|_(\\|[#(?[_{]\\)")
(36 . ".\\(?:>\\)")
(37 . ".\\(?:\\(?:%%\\)\\|%\\)")
(38 . ".\\(?:\\(?:&&\\)\\|&\\)")
(42 . ".\\(?:\\(?:\\*\\*/\\)\\|\\(?:\\*[*/]\\)\\|[*/>]\\)")
(43 . ".\\(?:\\(?:\\+\\+\\)\\|[+>]\\)")
(45 . ".\\(?:\\(?:-[>-]\\|<<\\|>>\\)\\|[<>}~-]\\)")
;; (46 . ".\\(?:\\(?:\\.[.<]\\)\\|[.=-]\\)")
(47 . ".\\(?:\\(?:\\*\\*\\|//\\|==\\)\\|[*/=>]\\)")
(48 . ".\\(?:x[a-zA-Z]\\)")
(58 . ".\\(?:::\\|[:=]\\)")
(59 . ".\\(?:;;\\|;\\)")
(60 . ".\\(?:\\(?:!--\\)\\|\\(?:~~\\|->\\|\\$>\\|\\*>\\|\\+>\\|--\\|<[<=-]\\|=[<=>]\\||>\\)\\|[*$+~/<=>|-]\\)")
(61 . ".\\(?:\\(?:/=\\|:=\\|<<\\|=[=>]\\|>>\\)\\|[<=>~]\\)")
(62 . ".\\(?:\\(?:=>\\|>[=>-]\\)\\|[=>-]\\)")
(63 . ".\\(?:\\(\\?\\?\\)\\|[:=?]\\)")
(91 . ".\\(?:]\\)")
(92 . ".\\(?:\\(?:\\\\\\\\\\)\\|\\\\\\)")
(94 . ".\\(?:=\\)")
(119 . ".\\(?:ww\\)")
(123 . ".\\(?:-\\)")
(124 . ".\\(?:\\(?:|[=|]\\)\\|[=>|]\\)")
(126 . ".\\(?:~>\\|~~\\|[>=@~-]\\)")
)
))
(dolist (char-regexp alist)
(set-char-table-range composition-function-table (car char-regexp)
`([,(cdr char-regexp) 0 font-shape-gstring]))))
(add-hook 'helm-major-mode-hook
(lambda ()
(setq auto-composition-mode nil)))
From updated [page](https://github.com/tonsky/FiraCode/wiki/Emacs-instructions)
;;; Fira code
;; This works when using emacs --daemon + emacsclient
(add-hook 'after-make-frame-functions (lambda (frame) (set-fontset-font t '(#Xe100 . #Xe16f) "Fira Code Symbol")))
;; This works when using emacs without server/client
(set-fontset-font t '(#Xe100 . #Xe16f) "Fira Code Symbol")
;; I haven't found one statement that makes both of the above situations work, so I use both for now
(defconst fira-code-font-lock-keywords-alist
(mapcar (lambda (regex-char-pair)
`(,(car regex-char-pair)
(0 (prog1 ()
(compose-region (match-beginning 1)
(match-end 1)
;; The first argument to concat is a string containing a literal tab
,(concat " " (list (decode-char 'ucs (cadr regex-char-pair)))))))))
'(("\\(www\\)" #Xe100)
("[^/]\\(\\*\\*\\)[^/]" #Xe101)
("\\(\\*\\*\\*\\)" #Xe102)
("\\(\\*\\*/\\)" #Xe103)
("\\(\\*>\\)" #Xe104)
("[^*]\\(\\*/\\)" #Xe105)
("\\(\\\\\\\\\\)" #Xe106)
("\\(\\\\\\\\\\\\\\)" #Xe107)
("\\({-\\)" #Xe108)
("\\(\\[\\]\\)" #Xe109)
("\\(::\\)" #Xe10a)
("\\(:::\\)" #Xe10b)
("[^=]\\(:=\\)" #Xe10c)
("\\(!!\\)" #Xe10d)
("\\(!=\\)" #Xe10e)
("\\(!==\\)" #Xe10f)
("\\(-}\\)" #Xe110)
("\\(--\\)" #Xe111)
("\\(---\\)" #Xe112)
("\\(-->\\)" #Xe113)
("[^-]\\(->\\)" #Xe114)
("\\(->>\\)" #Xe115)
("\\(-<\\)" #Xe116)
("\\(-<<\\)" #Xe117)
("\\(-~\\)" #Xe118)
("\\(#{\\)" #Xe119)
("\\(#\\[\\)" #Xe11a)
("\\(##\\)" #Xe11b)
("\\(###\\)" #Xe11c)
("\\(####\\)" #Xe11d)
("\\(#(\\)" #Xe11e)
("\\(#\\?\\)" #Xe11f)
("\\(#_\\)" #Xe120)
("\\(#_(\\)" #Xe121)
("\\(\\.-\\)" #Xe122)
("\\(\\.=\\)" #Xe123)
("\\(\\.\\.\\)" #Xe124)
("\\(\\.\\.<\\)" #Xe125)
("\\(\\.\\.\\.\\)" #Xe126)
("\\(\\?=\\)" #Xe127)
("\\(\\?\\?\\)" #Xe128)
("\\(;;\\)" #Xe129)
("\\(/\\*\\)" #Xe12a)
("\\(/\\*\\*\\)" #Xe12b)
("\\(/=\\)" #Xe12c)
("\\(/==\\)" #Xe12d)
("\\(/>\\)" #Xe12e)
("\\(//\\)" #Xe12f)
("\\(///\\)" #Xe130)
("\\(&&\\)" #Xe131)
("\\(||\\)" #Xe132)
("\\(||=\\)" #Xe133)
("[^|]\\(|=\\)" #Xe134)
("\\(|>\\)" #Xe135)
("\\(\\^=\\)" #Xe136)
("\\(\\$>\\)" #Xe137)
("\\(\\+\\+\\)" #Xe138)
("\\(\\+\\+\\+\\)" #Xe139)
("\\(\\+>\\)" #Xe13a)
("\\(=:=\\)" #Xe13b)
("[^!/]\\(==\\)[^>]" #Xe13c)
("\\(===\\)" #Xe13d)
("\\(==>\\)" #Xe13e)
("[^=]\\(=>\\)" #Xe13f)
("\\(=>>\\)" #Xe140)
("\\(<=\\)" #Xe141)
("\\(=<<\\)" #Xe142)
("\\(=/=\\)" #Xe143)
("\\(>-\\)" #Xe144)
("\\(>=\\)" #Xe145)
("\\(>=>\\)" #Xe146)
("[^-=]\\(>>\\)" #Xe147)
("\\(>>-\\)" #Xe148)
("\\(>>=\\)" #Xe149)
("\\(>>>\\)" #Xe14a)
("\\(<\\*\\)" #Xe14b)
("\\(<\\*>\\)" #Xe14c)
("\\(<|\\)" #Xe14d)
("\\(<|>\\)" #Xe14e)
("\\(<\\$\\)" #Xe14f)
("\\(<\\$>\\)" #Xe150)
("\\(<!--\\)" #Xe151)
("\\(<-\\)" #Xe152)
("\\(<--\\)" #Xe153)
("\\(<->\\)" #Xe154)
("\\(<\\+\\)" #Xe155)
("\\(<\\+>\\)" #Xe156)
("\\(<=\\)" #Xe157)
("\\(<==\\)" #Xe158)
("\\(<=>\\)" #Xe159)
("\\(<=<\\)" #Xe15a)
("\\(<>\\)" #Xe15b)
("[^-=]\\(<<\\)" #Xe15c)
("\\(<<-\\)" #Xe15d)
("\\(<<=\\)" #Xe15e)
("\\(<<<\\)" #Xe15f)
("\\(<~\\)" #Xe160)
("\\(<~~\\)" #Xe161)
("\\(</\\)" #Xe162)
("\\(</>\\)" #Xe163)
("\\(~@\\)" #Xe164)
("\\(~-\\)" #Xe165)
("\\(~=\\)" #Xe166)
("\\(~>\\)" #Xe167)
("[^<]\\(~~\\)" #Xe168)
("\\(~~>\\)" #Xe169)
("\\(%%\\)" #Xe16a)
;; ("\\(x\\)" #Xe16b) This ended up being hard to do properly so i'm leaving it out.
("[^:=]\\(:\\)[^:=]" #Xe16c)
("[^\\+<>]\\(\\+\\)[^\\+<>]" #Xe16d)
("[^\\*/<>]\\(\\*\\)[^\\*/<>]" #Xe16f))))
(defun add-fira-code-symbol-keywords ()
(font-lock-add-keywords nil fira-code-font-lock-keywords-alist))
(add-hook 'prog-mode-hook
#'add-fira-code-symbol-keywords)
brew tap caskroom/fonts
# Both of these work
brew cask install font-hasklig
# brew cask install font-hasklig-nerd-font
My notes about loading the fonts used by Howard Abrams:
- Darwin: “Source Code Pro” from link
Use homebrew
brew tap homebrew/cask-fonts && brew cask install font-source-code-pro
If this returns a value, you’re good:
(x-list-fonts "Source Code Pro")
- Darwin: “Source Sans Pro” from link
Download from google fonts. Shift select all the .ttf files. Cmd-o to open (and install each
Test with:
(x-list-fonts "Source Sans Pro")
see: https://github.com/i-tu/Hasklig
build.cmd
(defvar ha/fixed-font-family
(cond ((x-list-fonts "Source Code Pro") "Source Code Pro")
((x-list-fonts "Anonymous Pro") "Anonymous Pro")
((x-list-fonts "M+ 1mn") "M+ 1mn"))
"My fixed width font based on what is installed, `nil' if not defined.")
(defvar ha/variable-font-family
(cond ((x-list-fonts "Source Sans Pro") "Source Sans Pro")
((x-list-fonts "Lucida Grande") "Lucida Grande")
((x-list-fonts "Verdana") "Verdana")
((x-family-fonts "Sans Serif") "Sans Serif")
(nil (warn "Cannot find a Sans Serif Font. Install Source Sans Pro.")))
"My variable width font available to org-mode files and whatnot.")
Need this to suppress an error on darwin?
(customize-set-variable 'solarized-termcolors 256)
I nabbed these from Daniel Mai. They’re great!
(defun switch-theme (theme)
"Disables any currently active themes and loads THEME."
;; This interactive call is taken from `load-theme'
(interactive
(list
(intern (completing-read "Load custom theme: "
(mapc 'symbol-name
(custom-available-themes))))))
(let ((enabled-themes custom-enabled-themes))
(mapc #'disable-theme custom-enabled-themes)
(load-theme theme t)))
(defun disable-active-themes ()
"Disables any currently active themes listed in `custom-enabled-themes'."
(interactive)
(mapc #'disable-theme custom-enabled-themes))
(bind-key "s-<f12>" 'switch-theme)
(bind-key "s-<f11>" 'disable-active-themes)
After watching Howard Abrams video Introduction to EShell, I was really impressed with his color scheme. So I checked out his emacs config for his Color Theme.
His note:
The color themes work quite well, except they don’t know about the org-mode source code blocks, so we need to set up a couple functions that we can use to set them.
My note: I needed to manually create this directory to avoid an error on startup: ~/.emacs.d/elpa/color-theme-20070910.1007/themes
(use-package color-theme-modern
:ensure t
:config (use-package color-theme-sanityinc-tomorrow :ensure t))
(defun org-src-color-blocks-light ()
"Colors the block headers and footers to make them stand out more for lighter themes"
(interactive)
(custom-set-faces
'(org-block-begin-line
((t (:underline "#A7A6AA" :foreground "#008ED1" :background "#EAEAFF"))))
'(org-block-background
((t (:background "#FFFFEA"))))
'(org-block
((t (:background "#FFFFEA"))))
'(org-block-end-line
((t (:overline "#A7A6AA" :foreground "#008ED1" :background "#EAEAFF"))))))
(defun org-src-color-blocks-dark ()
"Colors the block headers and footers to make them stand out more for dark themes"
(interactive)
(custom-set-faces
'(org-block-begin-line
((t (:foreground "#008ED1" :background "#002E41"))))
'(org-block-background
((t (:background "#000000"))))
'(org-block
((t (:background "#000000"))))
'(org-block-end-line
((t (:foreground "#008ED1" :background "#002E41"))))))
(deftheme ha/org-theme "Sub-theme to beautify org mode")
(defun ha/change-theme (theme org-block-style)
"Changes the color scheme and reset the mode line."
(funcall theme)
(funcall org-block-style)
(let* ((ha/fixed-font-tuple (list :font ha/fixed-font-family))
(ha/variable-font-tuple (list :font ha/variable-font-family))
(base-font-color (face-foreground 'default nil 'default))
(background-color (face-background 'default nil 'default))
(primary-color (face-foreground 'mode-line nil))
(secondary-color (face-background 'secondary-selection nil 'region))
(base-height (face-attribute 'default :height))
(headline `(:inherit default :weight bold :foreground ,base-font-color)))
(when ha/fixed-font-family
(set-frame-font ha/fixed-font-family)
(set-face-attribute 'default nil :font ha/fixed-font-family :height 140)
(set-face-font 'default ha/fixed-font-family))
;; Noticeable?
;; (set-face-attribute 'region nil :background "#ffff50" :foreground "black")
;; Subtle?
(set-face-attribute 'region nil :background "#0000bb" :foreground 'unspecified)
(custom-theme-set-faces 'ha/org-theme
`(org-agenda-structure ((t (:inherit default :height 2.0 :underline nil))))
`(org-verbatim ((t (:inherit 'fixed-pitched :foreground "#aef"))))
`(org-table ((t (:inherit 'fixed-pitched))))
`(org-block ((t (:inherit 'fixed-pitched))))
`(org-block-background ((t (:inherit 'fixed-pitched))))
`(org-block-begin-line ((t (:inherit 'fixed-pitched))))
`(org-block-end-line ((t (:inherit 'fixed-pitched))))
`(org-level-8 ((t (,@headline ,@ha/variable-font-tuple))))
`(org-level-7 ((t (,@headline ,@ha/variable-font-tuple))))
`(org-level-6 ((t (,@headline ,@ha/variable-font-tuple))))
`(org-level-5 ((t (,@headline ,@ha/variable-font-tuple))))
`(org-level-4 ((t (,@headline ,@ha/variable-font-tuple
:height 1.1))))
`(org-level-3 ((t (,@headline ,@ha/variable-font-tuple
:height 1.1))))
`(org-level-2 ((t (,@headline ,@ha/variable-font-tuple
:height 1.1))))
`(org-level-1 ((t (,@headline ,@ha/variable-font-tuple
:height 2.1))))
`(org-document-title ((t (,@headline ,@ha/variable-font-tuple :height 1.5 :underline nil)))))))
(ha/change-theme 'color-theme-sanityinc-tomorrow-night 'org-src-color-blocks-dark)
(custom-set-faces
'(mode-line ((t (:background "blue4" :foreground "gray90"))))
'(mode-line-inactive ((t (:background "#404045" :foreground "gray60"))))
'(mode-line-buffer-id ((t ( :foreground "gold1" :weight ultra-bold))))
'(which-func ((t ( :foreground "orange"))))
'(show-paren-match ((t (:background "default" :foreground "#afa" :weight ultra-bold))))
'(show-paren-mismatch ((t (:background "default" :foreground "#cc6666" :weight ultra-bold)))))
(set-face-attribute 'region nil :background "#00a")
The cyberpunk theme is dark and colorful. However, I don’t like the boxes around the mode line.
(use-package cyberpunk-theme
:if (window-system)
:ensure t
:init
(progn
(load-theme 'cyberpunk t)
(set-face-attribute `mode-line nil
:box nil)
(set-face-attribute `mode-line-inactive nil
:box nil)))
(use-package monokai-theme
:if (window-system)
:ensure t
:init
(setq monokai-use-variable-pitch nil))
When adding a new mode which has its own name for a tab variable, add it to the list below. Then changing `tab-width` will change all the other values.
Note: exclude py-indent-offset and keep default of 4
(setq-default tab-width 2) ; or any other preferred value
(let ((tab-variables `(c-basic-offset
sgml-basic-offset
css-indent-offset
web-mode-code-indent-offset
web-mode-markup-indent-offset
web-mode-code-indent-offset
js-indent-level
js2-indent-level
js2-basic-offset
coffee-tab-width
json-reformat:indent-width
)))
(dolist (tab-var tab-variables)
(defvaralias tab-var 'tab-width)))
To use this: (self-note: recall I have super “s” bound to Alt on Darwin)
(global-set-key (kbd "s-i") 'indent-relative)
Suppose I have code like below and I want to indent the first t with the nil above.
(setq helm-locate-command "mdfind -interpret -name %s %s"
helm-ff-newfile-prompt-p nil
helm-M-x-fuzzy-match t
helm-ff-file-name-history-use-recentf t)
I would place my cursor on that first t and type s-i to do it.
(tool-bar-mode -1)
Following instructions here you’ll need to execute this:
M-x all-the-icons-install-fonts
After running this:
(use-package all-the-icons :ensure t)
(use-package doom-modeline
:ensure t
:hook (after-init . doom-modeline-mode)
:config
(use-package all-the-icons :ensure t)
(setq doom-modeline-height 25)
)
Most modes seem to recoginze the right file names when loading, but these need to be set here.
(add-to-list 'auto-mode-alist '("\\.aliases$" . sh-mode))
(add-to-list 'auto-mode-alist '("\..*rc\\'" . sh-mode))
(add-to-list 'auto-mode-alist '("\..*zsh.*\\'" . shell-script-mode))
;; for freemind mindmaps, yes conflicts with .mm files in Objective C
(add-to-list 'auto-mode-alist '("\\.mm$" . xml-mode))
from: http://stackoverflow.com/questions/730751/hiding-m-in-emacs
(defun remove-dos-eol ()
"Do not show ^M in files containing mixed UNIX and DOS line endings."
(interactive)
(setq buffer-display-table (make-display-table))
(aset buffer-display-table ?\^M []))
;; automatically clean up bad whitespace
(setq whitespace-action '(auto-cleanup))
from UnfillRegion
(defun unfill-region (beg end)
"Unfill the region, joining text paragraphs into a single
logical line. This is useful, e.g., for use with
`visual-line-mode'."
(interactive "*r")
(let ((fill-column (point-max)))
(fill-region beg end)))
;; Handy key definition
(define-key global-map "\C-\M-Q" 'unfill-region)
lifted from Stack Overflow
;; (defun my-put-file-name-on-clipboard ()
(defun copy-filename-to-clipboard ()
"Put the current file name on the clipboard"
(interactive)
(let ((filename (if (equal major-mode 'dired-mode)
default-directory
(buffer-file-name))))
(when filename
(with-temp-buffer
(insert filename)
(clipboard-kill-region (point-min) (point-max)))
(message filename))))
;; since C-w and M-w copy and cut, this is similar
(global-set-key (kbd "H-w") 'copy-filename-to-clipboard)
lifted from reddit but now modified
(setq-default ffap-no-confirmation-extensions-order (list ".jsx" ".js" ".css"))
(defun ffap-no-confirmation (&optional filename)
"Find file at point or FILENAME without asking for confirmation first if file
exists. If ffap-no-confirmation-extensions-order is defined, the extensions will
be appended in order to see if a file name exists and then it will be opened."
(interactive)
(let* ((name (or filename (ffap-string-at-point 'file)))
(fname (expand-file-name name))
(foundp nil))
(progn
(if (and name fname (file-exists-p fname))
(progn
(find-file fname)
(setq foundp t)))
(if (and (not foundp) (boundp 'ffap-no-confirmation-extensions-order))
(let ((exts ffap-no-confirmation-extensions-order)
(i 0))
(while (and (not foundp) (<= i (length exts)))
(let* ((ext (elt exts i))
(fname-w-ext (concat fname ext)))
(if (file-exists-p fname-w-ext)
(progn
(find-file fname-w-ext)
(message (concat "ffap-no-confirmation found " fname-w-ext " by extension."))
(setq foundp t))))
(setq i (1+ i)))))
(if (not foundp)
(find-file-at-point filename)))))
I was testing VS Code (which I occasionally consider switching to from emacs, but I keep coming back) and I found this blog post when trying to fix the terminal font. I was excited to see it also fixed my shell prompt (M-x shell) in emacs too!
Rough instructions from blog:
In OS X terminal preferences
- cmd-,
- Profiles
- <YOURNAME>(Default)
- Font: “Meslo LG M DZ Regular for Powerline 14 pt.”
Your font name may vary…
(add-hook 'shell-mode-hook
(lambda ()
(face-remap-set-base 'comint-highlight-prompt :inherit nil)))
Babel is Org-mode’s ability to execute source code within Org-mode documents.
(org-babel-do-load-languages
'org-babel-load-languages
'((C . t)
(css . t)
(emacs-lisp . t)
(haskell . t)
(python . t)
(ruby . t)
(shell . t)
))
;; (coq . t)
;; (cpp . t) ; C++
;; (prolog . t)
(defun my-org-confirm-babel-evaluate (lang body)
(not (or (string= lang "C")
(string= lang "emacs-lisp")
(string= lang "haskell")
(string= lang "python")
(string= lang "ruby")
;; (string= lang "shell") ;; commented = do confirm
)))
(setq org-confirm-babel-evaluate 'my-org-confirm-babel-evaluate)
“Edit With Emacs” Chrome plugin
Following Daniel Mai again here to use Emacs to edit posts on
Discourse, which has a post editor that overrides normal Emacs key
bindings with other functions. As such, markdown-mode
is used.
(use-package edit-server
:ensure t
:config
(progn
(edit-server-start)
(setq edit-server-default-major-mode 'markdown-mode)
(setq edit-server-new-frame nil)))
Load private data, for example, I have a google api key set as goo-api-key for url shortening.
TODO: Maybe I should set a list of files above under “Use dropbox” and load each one of them. Dangerous if anyone ever has access to that directory but that should not.
(let ((private-data-file (concat user-emacs-directory "private.el")))
(if (file-exists-p private-data-file)
(progn
(message (concat "loading " private-data-file))
(load private-data-file))))
(use-package server
:config
(server-start))
Note I use helm-ag (see helm section below).
(use-package ag
:commands ag
:ensure t
:config
(add-hook 'ag-mode-hook
(lambda () (progn
(message "Truncating long lines in ag mode...")
(toggle-truncate-lines t)))))
(use-package anaconda-mode
:ensure t
:after (exec-path-from-shell)
:hook ((python-mode . anaconda-mode)
(python-mode . anaconda-eldoc-mode))
:config
(setq anaconda-mode-localhost-address "localhost") ; for Darwin (Mac OS)
)
Match parentheses, braces etc. automatically (apparently popularized by Textmate).
(use-package autopair
:ensure t
:config
(autopair-global-mode) ;; to enable in all buffers
)
Try chords with avy.
(use-package avy
:ensure t
:chords (("jj" . avy-goto-char) ; type the character rapidly
("jk" . avy-goto-char-2) ; type the first 2 characters rapidly
("jl" . avy-goto-line)
("jw" . avy-goto-word-1) ; type 1st char for beginnings of words
))
Just for my notes, if I don’t like this, I can try the suggested bindings with this:
(use-package avy
:bind (("C-:" . avy-goto-char) ; conflicts with helm-company
("C-'" . avy-goto-char-2)
("M-g f" . avy-goto-line)
))
(use-package buffer-move
:ensure t
:bind (("<C-s-up>" . buf-move-up) ; Control-super-up
("<C-s-down>" . buf-move-down)
("<C-s-left>" . buf-move-left)
("<C-s-right>" . buf-move-right)))
(use-package csharp-mode
:defer t
:ensure t)
(use-package coffee-mode
:defer t
:ensure t
:config
(progn
(add-hook 'coffee-after-compile-hook 'sourcemap-goto-corresponding-point)
;; (define-key coffee-mode-map [(meta r)] 'coffee-compile-buffer)
;; (define-key coffee-mode-map (kbd "C-j") 'coffee-newline-and-indent))
))
(add-hook 'css-mode-hook (lambda () (rainbow-mode t)))
Auto completion, perhaps a better or more currently maintained package compared to AutoComplete, but research the blogosphere to make your own decisions. I had never used either and I’m starting with company mode.
(use-package company-anaconda
:ensure t)
;;; https://github.com/dunn/company-emoji
(use-package company-emoji
:ensure t)
(use-package company
:ensure t
:requires company-anaconda
:config
(add-hook 'after-init-hook 'global-company-mode)
(setq company-tooltip-limit 20) ; bigger popup window
(setq company-idle-delay .3) ; decrease delay before autocompletion popup shows
(setq company-echo-delay 0) ; remove annoying blinking
(setq company-begin-commands '(self-insert-command)) ; start autocompletion only after typing
(setq company-minimum-prefix-length 3)
(define-key company-active-map (kbd "C-n") #'company-select-next)
(define-key company-active-map (kbd "C-p") #'company-select-previous)
;; (eval-after-load "company"
;; '(add-to-list 'company-backends 'company-emoji))
(eval-after-load "company"
'(add-to-list 'company-backends 'company-anaconda)))
For file completion with golang you will need gocode
. See mdempysky’s
repo for instructions. Under emacs, it lists usage with autocomplete,
but once you install it on your system correctly, company mode should
be able to find it.
(use-package company-go
:ensure t
:config
(add-hook 'go-mode-hook (lambda ()
(set (make-local-variable 'company-backends) '(company-go))
(company-mode))))
Debugging this. Running clojure-mode still causes this error for me:
load-with-code-conversion: Symbol’s value as variable is void: <!DOCTYPE
(use-package clojure-mode
:ensure t
:mode (("\\.clj$" . clojure-mode))
)
(use-package clojure-mode
:ensure t
:mode (("\\.clj$" . clojure-mode))
:config
(progn
;; require or autoload paredit-mode
(add-hook 'clojure-mode-hook #'paredit-mode)
;; require or autoload smartparens
;; (add-hook 'clojure-mode-hook #'smartparens-strict-mode)
))
(defun durant/dired-truncate-lines ()
(toggle-truncate-lines t))
(add-hook 'dired-mode-hook #'durant/dired-truncate-lines)
(use-package dockerfile-mode
:ensure t)
According to their website, “Emmet — the essential toolkit for web-developers.”
(use-package emmet-mode
:ensure t
:commands emmet-mode
:config
(progn
(add-hook 'html-mode-hook 'emmet-mode)
(add-hook 'css-mode-hook 'emmet-mode)
(add-hook 'sass-mode-hook 'emmet-mode)
(add-hook 'sgml-mode-hook 'emmet-mode))
)
(setq ediff-split-window-function 'split-window-horizontally)
(setq ediff-highlight-all-diffs 'nil)
;; rod bogart kicks ass!
;; these probably went with an alias
;; alias ediff='emacs --eval cmd-ediff'
;; usage: ediff FILE1 FILE2
(defun cmd-ediff ()
"A command line access to ediff."
(interactive)
(let ((buf1 (current-buffer)))
(other-window 1)
(ediff-buffers (current-buffer) buf1)))
(use-package emacsql-psql
:ensure t
)
(use-package emojify-mode
:ensure t
:config
(add-hook 'after-init-hook #'global-emojify-mode)
)
(use-package esup
:ensure t)
So emacs can also find executables (like “coffee” for coffee-repl). See repo documentation.
I should go over all of Daniel’s Mac customizations and put this in Settings.
(use-package exec-path-from-shell
:if (memq window-system '(mac ns))
:ensure t
:init
(exec-path-from-shell-initialize))
(use-package expand-region
:ensure t
:bind ("C-=" . er/expand-region))
Download shellcheck for sh-mode checking.
(use-package flycheck
:ensure t
:after (sh)
:config
(setq-default flycheck-html-tidy-executable
"/usr/local/Cellar/tidy-html5/5.2.0/bin/tidy")
(setq-default flycheck-temp-prefix ".flycheck")
;; Prevent flycheck from treating files like init.el as package files
(setq-default flycheck-disabled-checkers
(append flycheck-disabled-checkers
'(json-jsonlist emacs-lisp-checkdoc)))
(add-to-list 'flycheck-checkers 'python-flake8)
(add-to-list 'flycheck-checkers 'javascript-eslint)
(flycheck-add-mode 'javascript-eslint 'web-mode)
(flycheck-add-mode 'javascript-eslint 'js2-mode)
(flycheck-add-mode 'javascript-eslint 'rjsx-mode) ; replaces 'js2-jsx-mode
(add-hook 'sh-mode-hook 'flycheck-mode)
;; Since we're using eslint
;; Turn off js2 mode errors & warnings (we lean on eslint/standard)
(setq-default js2-mode-show-parse-errors nil)
(setq-default js2-mode-show-strict-warnings nil)
(global-flycheck-mode))
Instead of attempting something like this:
:config
;; (add-hook 'python-mode-hook
;; (lambda ()
;; (setq flycheck-python-pylint-executable
;; (concat
;; (locate-file "pylint" exec-path exec-suffixes 1)
;; " --load-plugins=pylint_flask"))))
I just added this line:
ignored-modules=flask_sqlalchemy
to my ~/.pylintrc
Install the HTML5/CSS/JavaScript linters.
pip3 install pylint
pip3 install pylint-flask
brew install tidy-html5
npm install -g csslint
eslint setup from this blogpost including this emacs-lisp code
;; use local eslint from node_modules before global
;; http://emacs.stackexchange.com/questions/21205/flycheck-with-file-relative-eslint-executable
(defun my/use-eslint-from-node-modules ()
(let* ((root (locate-dominating-file
(or (buffer-file-name) default-directory)
"node_modules"))
(eslint (and root
(expand-file-name "node_modules/eslint/bin/eslint.js"
root))))
(when (and eslint (file-executable-p eslint))
(setq-local flycheck-javascript-eslint-executable eslint))))
(add-hook 'flycheck-mode-hook #'my/use-eslint-from-node-modules)
;; for better jsx syntax-highlighting in web-mode
;; - courtesy of Patrick @halbtuerke
;; UPDATE: this might be superceded with rjsx
(defadvice web-mode-highlight-part (around tweak-jsx activate)
(if (equal web-mode-content-type "jsx")
(let ((web-mode-enable-part-face nil))
ad-do-it)
ad-do-it))
(use-package git-link
:ensure t
)
(use-package go-mode
:ensure t
:config
(add-hook 'before-save-hook #'gofmt-before-save))
TODO: I should figure out how to convert these to add them directly to use-package above
;; Define function to call when go-mode loads
(defun my-go-mode-hook ()
(setq gofmt-command "goimports") ; gofmt uses invokes goimports
(if (not (string-match "go" compile-command)) ; set compile command default
(set (make-local-variable 'compile-command)
"go build -v && go test -v && go vet"))
;; Key bindings specific to go-mode
(local-set-key (kbd "M-.") 'godef-jump) ; Go to definition
(local-set-key (kbd "M-*") 'pop-tag-mark) ; Return from whence you came
(local-set-key (kbd "M-p") 'compile) ; Invoke compiler
(local-set-key (kbd "M-P") 'recompile) ; Redo most recent compile cmd
(local-set-key (kbd "M-]") 'next-error) ; Go to next error (or msg)
(local-set-key (kbd "M-[") 'previous-error) ; Go to previous error or msg
;; Misc go stuff
(auto-complete-mode 1)) ; Enable auto-complete mode
(use-package go-guru
:ensure t
:config
(customize-set-variable 'go-guru-scope "...")
(add-hook 'go-mode-hook #'go-guru-hl-identifier-mode))
A simple comint-based mode for gore (command-line evaluator for golang code). See the repo
Interesting, but not quite usable. This is quite slow on my system and din’t use company-go out of the box. I’m going to disable this.
(use-package gore-mode
:defer t
:ensure t
(setq gore-bin-path "~/Programming/go/bin/gore")
)
To try it, use C-return send each line in a buffer running gore-mode.
println(200*300, math.Log10(1000))
p 200*300, math.Log10(1000)
(add-hook 'grep-mode-hook
'(lambda ()
(progn
(message "Truncating long lines in grep mode...")
(toggle-truncate-lines t))))
More code from Daniel Mai (which I’ve now customized). Helm looks to me like one of the biggest boosts in emacs productivity since I took a break from using it. I would think every emacs user would eventually want to use it. Though it does have a learning curve. You should consider the tutorial. I’ve mostly started with videos on youtube to get started.
From my limited investigations, I believe that Helm (with Helm-swoop) does everything you’d want from Ivy, Swiper, and Counsel.
(use-package helm
:ensure t
:init (progn
(require 'helm-config)
(use-package helm-projectile
:ensure t
:commands helm-projectile
:bind ("C-c p h" . helm-projectile)
:config (helm-projectile-on))
(use-package helm-ag :defer 10 :ensure t)
(setq helm-locate-command "mdfind -interpret -name %s %s"
helm-ff-newfile-prompt-p nil
helm-M-x-fuzzy-match t
helm-ff-file-name-history-use-recentf t)
(helm-mode)
;; use <tab> to select files instead of <return>
;; If you need it, C-i will do what <return> used to do
(define-key helm-map (kbd "<tab>") 'helm-execute-persistent-action)
(use-package helm-swoop
:ensure t
:bind ("M-s s" . helm-swoop)))
:bind (("C-c h" . helm-command-prefix)
("C-x b" . helm-mini)
("C-x r b" . helm-bookmarks)
("C-`" . helm-resume)
("M-x" . helm-M-x)
("M-y" . helm-show-kill-ring)
("C-x C-f" . helm-find-files)))
(use-package helm-company
:ensure t
:init
(eval-after-load 'company
'(progn
(define-key company-mode-map (kbd "C-:") 'helm-company)
(define-key company-active-map (kbd "C-:") 'helm-company))))
(use-package helm-etags-plus
:ensure t
:init
(eval-after-load 'anaconda ;; note this is not 'anaconda-mode
(global-set-key "\M-." 'helm-etags-plus-select)) ;; specifically fix anaconda mode
:config
(global-set-key "\M-." 'helm-etags-plus-select)
(global-set-key "\M-*" 'helm-etags-plus-history) ;;list all visited tags
(global-set-key "\M-," 'helm-etags-plus-history-go-back) ;;go back directly
;; I prefer keeping M-/ for dabbrev-expand
;; (global-set-key "\M-/" 'helm-etags-plus-history-go-forward) ;;go forward directly
)
for hs-minor-mode
Globally hyper h/t will hide/toggle, enabling hs-minor-mode if necessary.
So you can just move to a code block and H-h to hide it or H-t to toggle.
(global-set-key (kbd "H-h") 'enable-hs-and-hide-block)
(global-set-key (kbd "H-s") (kbd "C-c @ C-s")) ; show block
(global-set-key (kbd "H-t") 'enable-hs-and-toggle-hiding)
;; "C-c C-f" to mimic code folding in web-mode
(eval-after-load "python"
(eval-after-load "hs-minor"
(define-key python-mode-map (kbd "C-c C-f") 'enable-hs-and-toggle-hiding)))
(defun enable-hs-and-hide-block ()
"Enable hs-minor-mode if it isn't on and hide the source block"
(interactive)
(unless (bound-and-true-p hs-minor-mode)
(hs-minor-mode 1)
(message "hs-minor-mode enabled"))
(hs-hide-block))
(defun enable-hs-and-toggle-hiding ()
"Enable hs-minor-mode if it isn't on and toggle-hiding"
(interactive)
(unless (bound-and-true-p hs-minor-mode)
(hs-minor-mode 1)
(message "hs-minor-mode enabled"))
(hs-toggle-hiding))
(autoload 'hl7-mode "~/.emacs.d/site-lisp/hl7-mode.el" "Major mode for editing HL7v2 messages." t nil)
(push '("^MSH|\\^~\\\\\\&" . hl7-mode) magic-mode-alist)
See also useful commands html-mode
(defun my-html-mode-hook ()
(linum-mode 1)
(column-number-mode 1)
(message "Truncating long lines in html mode...")
(toggle-truncate-lines t)
)
(add-hook 'html-mode-hook 'my-html-mode-hook)
(use-package idris-mode
:bind (("C-c x" . idris-compile-and-execute))
:ensure t)
(use-package helm-idris
:ensure t
:after (idris-mode helm))
Additional setup from the documentation:
npm install -g indium
Note that when this launches I have to run C-c C-z immediately to get the \*JS REPL\* buffer. I added a hook to try to do this automatically (with indium-switch-to-repl-buffer), but it doesn’t seem to work.
(use-package indium
:ensure t
:config
(add-hook 'js-mode-hook #'indium-interaction-mode)
(add-hook 'indium-repl-mode-hook #'indium-switch-to-repl-buffer)
)
See the official installation instructions.
Example file: .indium.json
which goes in the root of your JS project
(currently only “chrome” or “node” are supported).
{
"configurations": [
{
"name": "Web project",
"type": "chrome"
}
]
}
When I want to run on a particular file MY_FILE.js I can use this setup:
The inspect-brk will break on the first line to allow you to debug. The “h”elp key is useful. Jump to a line in your code and type “h” and the program will until you get “h”ere. For example, if you’re in a loop, “h” will cycle once more through the loop until you’re “h”ere again.
{
"configurations": [
{
"name": "Debug a single file",
"type": "node",
"command": "node MY_FILE.js",
"inspect-brk": true
}
]
}
(add-hook 'js-mode-hook 'js2-minor-mode)
Note: rjsx mode should pick up .jsx files automatically
(use-package rjsx-mode
:ensure t
:config
(add-to-list 'interpreter-mode-alist '("node" . rjsx-mode))
(add-to-list 'auto-mode-alist '("components\\/.*\\.js\\'" . rjsx-mode)))
See: https://emacs.cafe/emacs/javascript/setup/2017/04/23/emacs-setup-javascript.html
Note: rjsx mode will pick up .jsx
files
(use-package js2-mode
:ensure t
:config
(add-to-list 'auto-mode-alist '("\\.js\\'" . js2-mode))
(add-hook 'js2-mode-hook #'js2-imenu-extras-mode))
(use-package js2-refactor
:ensure t
:after (js2-mode)
:config
(add-hook 'js2-mode-hook #'js2-refactor-mode)
(js2r-add-keybindings-with-prefix "C-c C-m") ;; note this is C-c RET
(define-key js2-mode-map (kbd "C-k") #'js2r-kill))
(use-package xref-js2
:ensure t
:after (js2-mode xref)
:config
;; js-mode (which js2 is based on) binds "M-." which conflicts with xref, so
;; unbind it.
(define-key js-mode-map (kbd "M-.") nil)
;; Explicitly define these to override my previous global-set-key definitions
(define-key js-mode-map "\M-." 'xref-find-definitions)
(define-key js-mode-map "\M-," 'xref-pop-marker-stack)
(define-key js-mode-map "\M-?" 'xref-find-references)
(add-hook 'js2-mode-hook
(lambda ()
(add-hook 'xref-backend-functions #'xref-js2-xref-backend nil t))))
Read: https://medium.com/@jrwillette88/tern-why-it-breaks-and-how-to-fix-it-8d1677df05f9
Emacs Reference setup: http://ternjs.net/doc/manual.html#emacs
Setup: https://emacs.cafe/emacs/javascript/setup/2017/05/09/emacs-setup-javascript-2.html
tern
requires installation (it also looks like when I upgrade versions of
node I need to also reinstall tern).
cd ~/Documents/GitHub
git clone https://github.com/ternjs/tern.git
cd tern
npm install -g
From the above instructions, regarding set up of .tern-project:
Now, depending on your JavaScript project, you might want to setup tern to work with your project structure. If completion doesn’t work out of the box using tern defaults you will have to set it up using a .tern-project placed in the root folder containing your JavaScript files.
Note: jsx needs to be installed
npm i -g tern-jsx
Find the webpack.config.dev.js file and set it:
{
"ecmaVersion": 6,
"libs": [
"browser",
"react"
],
"plugins": {
"node": {},
"jsx": {},
"webpack": {
"configPath": "./node_modules/bs-recipes/recipes/webpack.preact-hot-loader/webpack.config.dev.js"
}
}
}
In the webpack file I needed to make some updates to deprecated function names:
module.exports = {
// ...
plugins: [
new webpack.optimize.OccurrenceOrderPlugin(), // new name
new webpack.NoEmitOnErrorsPlugin() // new name
// ...
],
// ...
};
Run the server to test it. (But there is code in tern.el to find and run the server on its own).
tern # maybe with --verbose
If it seems to be working (see above Medium Article for more), let’s configure it for emacs auto-complete with company:
(use-package tern-auto-complete
:ensure t)
(use-package tern
:ensure t
:config
(add-hook 'js-mode-hook (lambda () (tern-mode t)))
;; Disable completion keybindings, as we use xref-js2 instead
(define-key tern-mode-keymap (kbd "M-.") nil)
(define-key tern-mode-keymap (kbd "M-,") nil)
(eval-after-load 'tern
'(progn
(require 'tern-auto-complete)
(tern-ac-setup))))
(use-package company-tern
:ensure t
:after (tern company)
:config
(add-to-list 'company-backends 'company-tern)
(add-hook 'js2-mode-hook (lambda () (tern-mode) (company-mode))))
(use-package prettier-js
:ensure t
:after (js2 web)
:config
(add-hook 'js2-mode-hook 'prettier-js-mode)
(add-hook 'web-mode-hook 'prettier-js-mode))
(use-package js-doc
:ensure t
:after (js2 rjsx)
:config
(dolist (hook-and-map '((js2-mode-hook . js2-mode-map)
(rjsx-mode-hook . rjsx-mode-map)))
(let* ((hook (car hook-and-map))
(mode-map (cdr hook-and-map)))
(add-hook hook
#'(lambda ()
(define-key mode-map "\C-ci" 'js-doc-insert-function-doc)
(define-key mode-map "@" 'js-doc-insert-tag))))))
(use-package json-mode
:ensure t
:config
(add-to-list 'auto-mode-alist '("\\.json$" . json-mode))
)
This is not needed because I already have json-reformat-region
.
(defun json-format-region ()
(interactive)
(save-excursion
(shell-command-on-region (region-beginning)
(region-end)
"python -m json.tool"
(buffer-name)
t)))
(use-package livescript-mode
:defer t
:ensure t
:config
(add-hook 'livescript-after-compile-hook 'sourcemap-goto-corresponding-point)
)
A great interface for git projects. It’s much more pleasant to use than the git interface on the command line. Use an easy keybinding to access magit.
(use-package magit
:ensure t
:bind ("C-c g" . magit-status)
:config
(define-key magit-status-mode-map (kbd "q") 'magit-quit-session))
(use-package markdown-mode
:defer t
:ensure t)
For some reason I need to require ‘cl. Some of the mc libraries require ‘cl-lib, but that doesn’t seem to be enough.
Refer to the source for examples.
(use-package multiple-cursors
:ensure t
:init
(require 'cl)
:bind (("C-S-c C-S-c" . mc/edit-lines)
("C->" . mc/mark-next-like-this)
("C-<" . mc/mark-previous-like-this)
("C-c C-<" . mc/mark-all-like-this)
("C-!" . mc/mark-next-symbol-like-this)
("s-r" . mc/mark-all-in-region)
("s-d" . mc/mark-all-dwim)))
”s-d” is super-d (I’ve bound super to option)
Special:
mc/mark-sgml-tag-pair: Mark the current opening and closing tag. Also try mc/mark-all-like-this-dwim in a tag
Mark the region, then mc/edit-beginnings-of-lines
mc/insert-numbers: Insert increasing numbers for each cursor, top to bottom. mv/i-n mc/insert-letters: Insert increasing letters for each cursor, top to bottom. mv/i-l
If you have
print “foo”, foo, a third time foo here is foo on the next line and on line 3, here is foo too
You can change foo in the first line and the next foo to bar:
- Select the first foo in a region (move to 1st f, C-space, M-f)
- C-> (to start multiple-cursors)
- type “bar”
- C-g or <return> to end
You can change foo in the first two lines only:
- select the firs two lines only
- s-r (for mc/mark-all-in-region)
- type bar
- return
If you have
foo: one barr: two bazzz: three quux: four
You can select “: ” and mc/mark-all-like-this or s-d for mc/mark-all-dwim, then start typing (you’ll need to retype “: ” or you can kill and yank it back, first thing if you want to keep it).
While editing, you can use C-’ to hide all non-edited text
test: this is extra text, not to be modified
Decide if I still need this (from Using Octave Mode):
Note there is no final “e” in “octave-mod”
Also the autoload is disabled because it actually interferes with octave mode which should be set up by default according to this.
; (autoload 'octave-mode "octave-mod" nil t)
; Do this otherwise objective-c mode is set
(setq auto-mode-alist
(cons '("\\.m$" . octave-mode) auto-mode-alist))
(add-hook 'octave-mode-hook
(lambda ()
(abbrev-mode 1)
(auto-fill-mode 1)
(if (eq window-system 'x)
(font-lock-mode 1))))
See also useful commands org-mode
(bind-key "C-c l" 'org-store-link)
(bind-key "C-c c" 'org-capture)
(bind-key "C-c a" 'org-agenda)
(bind-key "<M-C-return>" 'org-insert-subheading)
(global-set-key "\C-cb" 'org-iswitchb)
org-directory is set to ~/org by default, so I might do something like:
ln -si ~/Dropbox/home/org ~/
or
ln -si ~/Dropbox/work/org ~/
(setq org-default-notes-file (concat org-directory "/captured_notes.org"))
(use-package org-bullets
:ensure t)
(setq org-hide-emphasis-markers t)
https://mobileorg.github.io/documentation/#using-dropbox
Run (org-mobile-push)
;; Set to the location of your Org files on your local system
(setq org-directory "~/org")
;; Set to the name of the file where new notes will be stored
(setq org-mobile-inbox-for-pull "~/org/flagged.org")
;; Set to <your Dropbox root directory>/MobileOrg.
(setq org-mobile-directory "~/Dropbox/Apps/MobileOrg")
Try animated gifs with code from here.
(setq org-file-apps
'(;; Web Pages
("\\.gif\\'" . (lambda (file link)
(let ((my-image (create-image file))
(tmpbuf (get-buffer-create "*gif")))
(switch-to-buffer tmpbuf)
(erase-buffer)
(insert-image my-image)
(image-animate my-image nil t))))
(auto-mode . emacs)
))
The clocking expressions are for clocking work time.
(add-hook 'org-mode-hook (lambda ()
(setq org-clock-persist 'history)
(org-clock-persistence-insinuate)
(org-bullets-mode 1)
(auto-fill-mode 1)
; (indent-tabs-mode t)
))
(setq org-todo-keywords
'((sequence "TODO" "IN_PROGRESS" "|" "DONE")))
This doesn’t work as intended with variable width fonts, but does add more space.
from: https://orgmode.org/worg/org-hacks.html#orgheadline64
(setq ba/org-adjust-tags-column t)
(defun ba/org-adjust-tags-column-reset-tags ()
"In org-mode buffers it will reset tag position according to
`org-tags-column'."
(when (and
(not (string= (buffer-name) "*Remember*"))
(eql major-mode 'org-mode))
(let ((b-m-p (buffer-modified-p)))
(condition-case nil
(save-excursion
(goto-char (point-min))
(command-execute 'outline-next-visible-heading)
;; disable (message) that org-set-tags generates
(flet ((message (&rest ignored) nil))
(org-set-tags 1 t))
(set-buffer-modified-p b-m-p))
(error nil)))))
(defun ba/org-adjust-tags-column-now ()
"Right-adjust `org-tags-column' value, then reset tag position."
(set (make-local-variable 'org-tags-column)
(- (- (window-width) (length org-ellipsis))))
;; (- (- (window-width) 3)))
(ba/org-adjust-tags-column-reset-tags))
(defun ba/org-adjust-tags-column-maybe ()
"If `ba/org-adjust-tags-column' is set to non-nil, adjust tags."
(when ba/org-adjust-tags-column
(ba/org-adjust-tags-column-now)))
(defun ba/org-adjust-tags-column-before-save ()
"Tags need to be left-adjusted when saving."
(when ba/org-adjust-tags-column
(setq org-tags-column 1)
(ba/org-adjust-tags-column-reset-tags)))
(defun ba/org-adjust-tags-column-after-save ()
"Revert left-adjusted tag position done by before-save hook."
(ba/org-adjust-tags-column-maybe)
(set-buffer-modified-p nil))
; automatically align tags on right-hand side
(add-hook 'window-configuration-change-hook
'ba/org-adjust-tags-column-maybe)
(add-hook 'before-save-hook 'ba/org-adjust-tags-column-before-save)
(add-hook 'after-save-hook 'ba/org-adjust-tags-column-after-save)
(add-hook 'org-agenda-mode-hook (lambda ()
(setq org-agenda-tags-column (- (window-width)))))
; between invoking org-refile and displaying the prompt (which
; triggers window-configuration-change-hook) tags might adjust,
; which invalidates the org-refile cache
(defadvice org-refile (around org-refile-disable-adjust-tags)
"Disable dynamically adjusting tags"
(let ((ba/org-adjust-tags-column nil))
ad-do-it))
(ad-activate 'org-refile)
(use-package org-jira
:defer t
:ensure t
:config
(setq jiralib-url "https://udacity.atlassian.net")
)
For use with textexpander-sync-el
(use-package osx-plist
:no-require)
(add-hook 'package-menu-mode-hook
(lambda ()
(progn
(message "Truncating long lines in package menu mode...")
(toggle-truncate-lines t))))
works with multiple cursors
(use-package phi-search
:defer t
:ensure t
:config
(require 'phi-replace)
(global-set-key (kbd "M-%") 'phi-replace-query))
Not sure how this works yet:
(use-package phi-search-mc
:defer t
:ensure t)
Display Control-l characters in a pretty way
(use-package pp-c-l
:ensure t
:config
(pretty-control-l-mode 1)
)
See also useful commands python-mode and more notes about ipython and my startup file at the end of this section. Specify a separate history file because I like to have a separate ipython running in an terminal and this way the sqlite dbs won’t get clobbered.
(use-package python-mode
:ensure t
:config
(setq-default python-shell-interpreter "ipython"
python-shell-interpreter-args
(concat "--HistoryManager.hist_file=/tmp/emacs_ipython_hist.sqlite "
"--simple-prompt -i")))
(use-package auto-virtualenv
:ensure t
:config
(add-hook 'python-mode-hook 'auto-virtualenv-set-virtualenv))
(use-package blacken
:ensure t
:config
(add-hook 'python-mode-hook 'blacken-mode))
from stackoverflow
(defface font-lock-ucs-string-face
'((((class grayscale) (background light)) :foreground "DarkGray" :slant italic)
(((class grayscale) (background dark)) :foreground "DarkGray" :slant italic)
(((class color) (min-colors 88) (background light)) :foreground "red")
(((class color) (min-colors 88) (background dark)) :foreground "red")
(((class color) (min-colors 16) (background light)) :foreground "red")
(((class color) (min-colors 16) (background dark)) :foreground "red")
(((class color) (min-colors 8)) :foreground "red")
(t :slant italic))
"Font Lock mode face used to highlight strings."
:group 'font-lock-faces)
(defun py-font-lock-syntactic-face-function (state)
"See variable `font-lock-syntactic-face-function'"
(message "Running py-font-lock-syntactic-face-function at %d." (point))
(if (nth 3 state)
(if (looking-back "u\"")
'font-lock-ucs-string-face
'font-lock-string-face)
'font-lock-comment-face))
(add-hook 'python-mode-hook (lambda ()
(setq-default font-lock-syntactic-face-function
'py-font-lock-syntactic-face-function)))
Initially, I could not get ipython to load my python startup file that I was setting in PYTHONSTARTUP
Now, it works. I run my startup file with this configuration: Generate ipython profile at command line with:
ipython profile create
# find again with
# ipython profile locate
Then edit the config file (using ~ for my home dir is most generic).
c.InteractiveShellApp.exec_lines = ['%run ~/.python_startup.py']
Note that setting this:
c.InteractiveShellApp.exec_PYTHONSTARTUP = True
did NOT work in ipython in emacs for me
Project navigation and management library for Emacs.
http://batsov.com/projectile/ https://docs.projectile.mx/en/latest/
(use-package projectile
:ensure t
;; :pin melpa-stable
:commands projectile-mode
:config
(projectile-mode +1)
;; "s-p" was ns-print-buffer
(define-key projectile-mode-map (kbd "s-p") 'projectile-command-map)
(define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map)
(projectile-global-mode t)
(setq-default projectile-project-search-path '("~/Programming/PROJECTS/"))
(setq-default projectile-require-project-root nil)
(setq-default projectile-enable-caching t)
(setq-default projectile-globally-ignored-directories
(append '(
".git"
".svn"
"out"
"repl"
"target"
"venv"
"__pycache__"
)
projectile-globally-ignored-directories))
(setq-default projectile-globally-ignored-file-suffixes
(append '(
".DS_Store"
".gz"
".pyc"
".jar"
".tar.gz"
".tgz"
".zip"
)
projectile-globally-ignored-file-suffixes))
(projectile-mode +1))
(use-package projectile-speedbar
:ensure t
;; :bind ("M-<f2>" . projectile-speedbar-open-current-buffer-in-tree)
:bind ("C-c s" . sr-speedbar-toggle)
:config
(setq-default speedbar-show-unknown-files t)
(custom-set-variables '(speedbar-show-unknown-files t))
(setq speedbar-directory-unshown-regexp "^\(\.\.*$\)\'")
(setq-default speedbar-directory-unshown-regexp "^\\(CVS\\|RCS\\|SCCS\\|\\.\\.*$\\)\\'")
(speedbar-add-supported-extension ".js")
(add-to-list 'speedbar-fetch-etags-parse-list
'("\\.js" . speedbar-parse-c-or-c++tag))
(setq-default speedbar-show-all t))
If you want projectile to ignore files you can create a .projectile file in your project directory and ignore the “old/” directory with:
-/old
the minus ‘-’ is for exclude and ‘+’ would be for include
(use-package rainbow-mode
:ensure t)
Recentf is a minor mode that builds a list of recently opened files. This list is is automatically saved across sessions on exiting Emacs - you can then access this list through a command or the menu.
https://www.emacswiki.org/emacs/RecentFiles
(use-package recentf
:bind ("C-x C-r" . helm-recentf)
:config
(progn
(recentf-mode t)
(setq recentf-max-saved-items 200)))
(use-package rg
:config
;; (rg-enable-default-bindings) ;; this steals C-c s, so would need to rebind that
)
(use-package sass-mode
:defer t
:ensure t
:config
(progn
(linum-mode 1)
(rainbow-mode t))
)
Quickly move to previous and next symbol under the cursor (or replace)
(use-package smartscan
:ensure t
:config (add-hook 'prog-mode-hook 'smartscan-mode)
:bind (("M-n" . smartscan-symbol-go-forward)
("M-p" . smartscan-symbol-go-backward)
("M-'" . smartscan-symbol-replace) ; overrides abbrev-prefix-mark
))
(use-package solidity-mode
:defer t
:ensure t
:config
(progn
(linum-mode 1)
(setq solidity-comment-style 'slash)
(define-key solidity-mode-map (kbd "C-c C-g") 'solidity-estimate-gas-at-point)
))
also company-terraform
(use-package terraform-mode
:ensure t)
(use-package company-terraform
:ensure t
:after (terraform-mode company)
)
I use TextExpander on OS X and Breevy on Windows sharing my textexpander settings through Dropbox. Now I can have them in emacs too. If you’re thinking about the same, note I decided to abandon using non-word characters like semi-colon “;” in my abbreviations to make everything work everywhere.
(use-package textexpander-sync
:load-path "~/.emacs.d/site-lisp"
:init
(setq textexpander-sync-file "~/Dropbox/TextExpander/Settings.textexpander")
(setq-default abbrev-mode t)) ; setq-default to set this globally
Note to self: I should post my fix. Note to self: Not loading this it seems, eg. :no-require
(use-package tla-mode
:no-require
:load-path "~/.emacs.d/site-lisp")
Need google-access-token … see private-data-file
(use-package url-shortener
:defer t
:ensure t)
Use:
M-x goo-url-shorten M-x goo-url-expand
(use-package visual-regexp
:ensure t
:init
(use-package pcre2el :ensure t)
(use-package visual-regexp-steroids :ensure t)
:bind (("C-c r" . vr/replace)
("C-c q" . vr/query-replace)
("C-c m" . vr/mc-mark) ; Need multiple cursors
("C-M-r" . vr/isearch-backward)
("C-M-s" . vr/isearch-forward)))
Usage reminder
C-c q -> enter pattern to search for -> enter pattern for query replacement C-c m -> enter pattern to search for -> start typing in multiple cursor mode
Note: expressions are in python
Multiplying all numbers of at least two digits by 3:
C-c r (\d{2,}) C-c C-c (expression mode) int(\1)*3
1 20 3 50 60 70 80 90 100
Capitalize the first letter of the string after “mc/”
C-c r mc/(.) C-c C-c (expression mode) “mc/” + str(\1).upper()
mc/mark-sgml-tag-pair: Mark the current opening and closing tag. mc/insert-numbers: Insert increasing numbers for each cursor, top to bottom. mc/insert-letters: Insert increasing letters for each cursor, top to bottom.
(use-package web-mode
:defer t
:ensure t
:config
(progn
(local-set-key "\C-cv" 'browse-url-of-file)
;; (add-to-list 'auto-mode-alist '("\\.jsx$" . web-mode))
(add-hook 'html-mode-hook 'web-mode)) ;; enable web mode in html
)
(use-package yaml-mode
:defer t
:ensure t)
See also useful commands yas-mode
mkdir ~/.emacs.d/yasnippets
cd ~/.emacs.d/yasnippets
# if go were not included, I could do this...
# git clone https://github.com/dominikh/yasnippet-go.git
Do NOT use `:defer t` for yasnippet. It took me a long time to figure out why I always had to set global mode and reload manually (hint, it’s becase I had defer on). Maybe this should have been obvious.
(use-package yasnippet
:ensure t
:config
(yas-global-mode 1)
;; (setq yas-key-syntaxes (yas-try-key-from-whitespace "w_.()" "w_." "w_" "w"))
(setq-default yas-snippet-dirs (append yas-snippet-dirs
'("~/.emacs.d/snippets"))))
(use-package yasnippet-snippets
:ensure t
)
(defun python-args-to-google-docstring (text &optional make-fields)
"Return a reST docstring format for the python arguments in yas-text."
(let* ((indent (concat "\n" (make-string (current-column) 32)))
(args (python-split-args text))
(nr 0)
(formatted-args
(mapconcat
(lambda (x)
(concat " " (nth 0 x)
(if make-fields (format " ${%d:arg%d}" (cl-incf nr) nr))
(if (nth 1 x) (concat " \(default " (nth 1 x) "\)"))))
args
indent)))
(unless (string= formatted-args "")
(concat
(mapconcat 'identity
(list "" "Args:" formatted-args)
indent)
"\n"))))
(setq auto-mode-alist
(cons '("\\.zsh$" . sh-mode) auto-mode-alist))
My simple experiments with tracking work. There’s nothing really interesting here.
;; macros for my times.org file (org-mode specific)
(fset 'times-last
(lambda (&optional arg) "Keyboard macro." (interactive "p") (kmacro-exec-ring-item (quote ([134217788 19 42 32 60 19 67108896 19 62 67108896 tab 11 25 tab 18 42 32 60 18 67108896 5 67108896 25] 0 "%d")) arg)))
;; uses the yas snippet to insert to text then adds the date in org-mode
(fset 'times-new
[?\M-< ?\C-s ?* ? ?< ?\C- ?\C-a ?\C-o ?t ?i ?m ?e ?s ?- ?n ?e ?w tab ?\C-c ?. return])
;; move to beginning of link before running these
(fset 'md-link-to-org
[?\C-s ?\] ?\( ?\C- ?\M-z ?\) ?\) ?\C-r ?\[ ?\C- ?\[ ?\[ ?\C-y backspace ?\] ?\C-s ?\) ?\C- backspace backspace ?\]])
(fset 'org-link-to-md
[?\C-s ?\[ ?\[ ?\C- ?\C-b ?\C- ?\C-s ?\] ?\C- ?\C-u ?\C- ?\C-w backspace ?\C-s ?\] ?\] ?\C- backspace ?\( ?\) ?\C-b ?\C-y ?\C- ?\C- backspace ?\C-r ?\[ ?\C- ?\C-d ?\C-s ?\) ?\C- ])
;; This is lazy, but works
;; to use org-link-jira-from-middle:
;; paste into a new line: PTS-XYZ-link title text here
;; place cursor between link and title, then run the macro
(fset 'org-link-jira-from-middle
(kmacro-lambda-form [?\C- ?\C-a ?\C-w ?\[ ?\[ ?\C-y ?\C- ?\M-b ?\M-b ?\M-w ?\M-d ?\M-d ?\C-y ?\C-f ?\[ ?\C-y ?\C-f ?\]] 0 "%d"))
from Kaushal Modi 2015 used in ~/.emacs.d/snippets/go-mode/exampletest
(defun my/capitalize-first-char (&optional string)
"Capitalize only the first character of the input STRING."
(when (and string (> (length string) 0))
(let ((first-char (substring string nil 1))
(rest-str (substring string 1)))
(concat (capitalize first-char) rest-str))))
;; ok, my elisp sucks at this stage, but it's a start (1/97)
;; durant
;; seems to be broken
(defun comment-block (beg end)
"Special commenting block for a region. Line of dashes before and after
as long as the longest line. Strips white space off ends."
(interactive "r") ; ? check if already commented
(let ((max 0)
(dash 45) ; 45 is the ascii value of -, "dash"
(current beg)
(lmargin "") ; lmargin can be a space, " ", "> ",...
(last-line (save-excursion
(goto-char end)
(string-to-int (substring (what-line) 5)))))
(progn
(goto-char current)
(while (<= current end)
(beginning-of-line)
(setq line-begin (point))
(insert lmargin)
(end-of-line)
(delete-horizontal-space)
(setq len (- (point) line-begin))
(if (< max len) (setq max len))
(forward-line)
(setq current (point))))
(message "Longest line is: %d chars long." (- max (length lmargin)))
(goto-char beg)
(beginning-of-line)
(setq beg (point))
(insert-char dash max) ; insert 'max' dashes at begining
(insert "\n")
(setq last-line (+ 2 last-line)) ; add two for lines of dashes
(goto-line last-line)
(insert-char dash max) ; insert 'max' dashes at end
(insert "\n")
(comment-region beg (point))))
(defun insert-python-durant-debug-class ()
"Insert my python debugging class: "
(interactive)
(insert "class Debug:\n")
(insert " \"\"\"Usage in a method call: \n")
(insert "\n")
(insert " DEBUG.where(self)\n")
(insert "\n")
(insert " \"\"\"\n")
(insert " def where(self,instance):\n")
(insert " # `instance.__class__` is '<class A at 10f6caa8>'\n")
(insert " _class = string.split(`instance.__class__`)[1]\n")
(insert " if string.find(_class,'.') > 0:\n")
(insert " _class = string.split(_class,'.')[1]\n")
(insert " method = traceback.extract_stack()[-2][-2]\n")
(insert " print \"DEBUG: In %s.%s\" % (_class,method)\n")
(insert "\n")
(insert "DEBUG = Debug()\n")
(insert "\n"))
(defun insert-python-durant-debug ()
"Insert my python debugging string: "
(interactive)
(insert "DEBUG.where(self)\n")
(insert "print '\\t ', "))
You can see all commands that begin with a prefix by using C-h afterward, e.g `C-x C-h` or `C-x 4 C-h` or `C-c C-h`
C-x is for built-in emacs commands (mnemonic emaX ?)
C-c is for Customized (major and minor mode) commands
Some bindings I’m practicing remembering.
Checkout http://orgmode.org/manual/Tables.html if you haven’t seen them
Key Binding | Description |
---|---|
C-/ | undo or expand word |
does expand word if at the end of a word | |
C-h v | describe-variable |
put cursor on a variable in an elisp file | |
default will be the variable | |
C-u C-space | cycle through previously set marks |
C-x C-e | eval last sexp |
Symbolic EXPression, elisp | |
C-x n w | exit narrow region |
C-x n w | exit narrow region |
C-y | yank |
M-y then cycles through kill ring | |
C-S-delete | delete entire line |
C-S-down | select until last non-empty line |
great for code blocks | |
BETTER: C-= from er/expand-region | |
ALSO USEFUL: M-h to select paragraph | |
C-M-\ | indent-region |
C-x ESC ESC | repeat-complex-command |
or C-x M-: | (but see next row C-x z z z) |
C-x z z z | to repeat most recent command 3 times |
like . in vi | |
C-z | zap to char |
remember, you can set a numeric prefix | |
`C-u 3 C-z x` to delete up to 3rd x | |
C-x 8 <RET> | unicode, eg. snowman ☃ |
enter unicode name, | |
like snowman (has completions) | |
C-x = | what-cursor-position |
C-x C-= | like +, increase font of buffer |
C-x C– | decrease font of buffer |
Pattern | Description |
C-s then C-w then C-s | select and search |
select moving forward by word | |
then find the selection | |
C-s then C-w then M-w | select and copy |
Definitions for these appear later in this file
Key Binding | Description |
---|---|
H-h | Hide a code block |
H-s | Show a code block |
H-t | Toggle hiding a code block |
H-o | ‘browse-url-of-buffer (builtin) |
Command | Description |
---|---|
M-x hs-minor-mode | hide-show |
M-x hs-hide-all | hide all comments |
M-x hs-show-all | show all (comments again) |
Command | Description |
---|---|
C-c C-t | tag |
C-c / | close-tag |
C-c C-v | view in browser |
Command | Description |
---|---|
C-c ! v | flycheck-verify-setup |
Command | Description |
---|---|
C-f | in ido exits |
Command | Description |
---|---|
C-c C-c | in a new #+TODO line will reload org mode |
C-c l | org-store-link |
C-c C-l | org-insert-link |
C-c * | org-toggle-heading |
first select a bunch of lines to promote | |
C-c - | Cycle bullets (‘-’, ‘+’, ‘*’, ‘1.’, ‘1)’) |
or | Place cursor on the bullet |
Shift-<L,R arrow> | C-x z z … to repeat as usual |
<s then <TAB> to get a source block
<q then <TAB> to get a quote
Command | Description |
---|---|
C-c C-c | python-shell-switch-to-shell to execute the current file |
C-c C-z | python-shell-switch-to-shell to view the shell buffer |
A variable can also have a default value which is specified like this: ${1:object}.
see: http://blog.refu.co/?p=1355
Command | Description |
---|---|
M-x yas-describe-tables | gives a table representation of all |
the snippets available in the current mode | |
Use helm to find this with “M-x yas tab” | |
M-x yas-new-snippet | Use helm to find this with “M-x yas new” |
C-c & C-n | it’s easier than rememebering the bound keys |
Command | Description |
---|---|
M-x customize-variable | |
M-x customize-face RET default | |
M-x customize-group | emacs |
grep | |
M-x ffap | find-file-at-point |
M-x list-colors-display |
To select “org-mode-hook” with your mouse, click on the ‘-’ otherwise click on “org” to select only that part.
(defun init ()
"Test to quickly load my init file."
(interactive)
(load (concat user-emacs-directory "init.el")))
Open file work_init.el or home_init.el depending on which computer I’m on. Since they don’t belong in my repo they are listed in my .gitignore file.
I use these files to open default files and set the initial window size.
(setq locations '("home" "work"))
(dolist (loc locations)
(let ((init-file (concat user-emacs-directory (concat loc "_init.el"))))
(if (file-exists-p init-file)
(progn
(message (concat "loading " init-file))
(load init-file)))))