- Configuration
- JS2 Mode
This is an Emacs literate configuration template. It contains the basic structure of a literate config along with some optimizations to ensure a fast load time.
There are a few tweaks included in this org file that make it a little easier to work with.
First there is a property defined on the file:
header-args :tangle yes
This tells emacs to automatically tangle (include) all code blocks in this file when
generating the code for the config, unless the code block explicitly includes
:tangle no
as the above code block does.
Next we have a property defined on the Configuration heading that defines the visibility that tells org to show it’s direct children on startup. This way a clean outline of all sub headings under Configuration is shown each time this file is opened in org-mode.
Finally, there is a Table of Contents heading that includes the tag: :TOC_3_gh:
. This
tells an org-mode package toc-org
to generate a table of contents under this heading
that has a max depth of 3 and is created using Github-style hrefs. This table of contents
is updated everytime the file is saved and makes for a functional table of contents that
works property directly on github.
Let’s set some variables with basic user information.
(setq user-full-name "Andrés Gasson"
user-mail-address "[email protected]")
We’re going to increase the gc-cons-threshold to a very high number to decrease the load and compile time. We’ll lower this value significantly after initialization has completed. We don’t want to keep this value too high or it will result in long GC pauses during normal usage.
(eval-and-compile
(setq gc-cons-threshold 402653184
gc-cons-percentage 0.6))
Disable certain byte compiler warnings to cut down on the noise. This is a personal choice and can be removed if you would like to see any and all byte compiler warnings.
(setq byte-compile-warnings '(not free-vars unresolved noruntime lexical make-local))
Some default settings aka sanity defaults
;;; Code:
;; menu shit remove
(mapc
(lambda (mode)
(when (fboundp mode)
(funcall mode -1)))
'(menu-bar-mode tool-bar-mode scroll-bar-mode))
;;; Initialisation
(setq inhibit-default-init t
inhibit-startup-echo-area-message t
inhibit-startup-screen t
initial-scratch-message nil)
;; warn when opening files bigger than 100MB
(setq large-file-warning-threshold 100000000)
(defconst gas-savefile-dir (expand-file-name "savefile" user-emacs-directory))
;; create the savefile dir if it doesn't exist
(unless (file-exists-p gas-savefile-dir)
(make-directory gas-savefile-dir))
;;; UI
;; the blinking cursor is nothing, but an annoyance
(blink-cursor-mode -1)
;; disable the annoying bell ring
(setq ring-bell-function 'ignore)
;; disable startup screen
(setq inhibit-startup-screen t)
;; nice scrolling
(setq scroll-margin 0
scroll-conservatively 100000
scroll-preserve-screen-position 1)
;; mode line settings
(line-number-mode t)
(column-number-mode t)
(size-indication-mode t)
;; enable y/n answers
(fset 'yes-or-no-p 'y-or-n-p)
;; more useful frame title, that show either a file or a
;; buffer name (if the buffer isn't visiting a file)
(setq frame-title-format
'((:eval (if (buffer-file-name)
(abbreviate-file-name (buffer-file-name))
"%b"))))
;; Productive default mode
(setq initial-major-mode 'org-mode)
;; When on a tab, make the cursor the tab length.
(setq-default x-stretch-cursor t)
;; Keep emacs Custom-settings in separate file.
(setq custom-file (expand-file-name "custom.el" user-emacs-directory))
(when (file-exists-p custom-file)
(load custom-file))
;; store all backup and autosave files in the tmp dir
(setq backup-directory-alist
`((".*" . ,temporary-file-directory)))
(setq auto-save-file-name-transforms
`((".*" ,temporary-file-directory t)))
;; revert buffers automatically when underlying files are changed externally
(global-auto-revert-mode t)
;; Make backups of files, even when they're in version control.
(setq vc-make-backup-files t)
;; Fix empty pasteboard error.
(setq save-interprogram-paste-before-kill nil)
We’re going to set the load-path
ourselves and avoid calling (package-initilize)
(for
performance reasons) so we need to set package--init-file-ensured
to true to tell package.el
to not automatically call it on our behalf. Additionally we’re setting
package-enable-at-startup
to nil so that packages will not automatically be loaded for us since
use-package
will be handling that.
(eval-and-compile
(setq load-prefer-newer t
package-user-dir "~/.emacs.d/elpa"
package--init-file-ensured t
package-enable-at-startup nil)
(unless (file-directory-p package-user-dir)
(make-directory package-user-dir t)))
Tell use-package
to always defer loading packages unless explicitly told otherwise. This speeds up
initialization significantly as many packages are only loaded later when they are explicitly used.
(setq use-package-always-defer t
use-package-verbose t)
We’re going to set the load path ourselves so that we don’t have to call package-initialize
at
runtime and incur a large performance hit. This load-path will actually be faster than the one
created by package-initialize
because it appends the elpa packages to the end of the load path.
Otherwise any time a builtin package was required it would have to search all of third party paths
first.
(eval-and-compile
(setq load-path (append load-path (directory-files package-user-dir t "^[^.]" t))))
Next we are going to require package.el
and add our additional package archives, ‘melpa’ and ‘org’.
Afterwards we need to initialize our packages and then ensure that use-package
is installed, which
we promptly install if it’s missing. Finally we load use-package
and tell it to always install any
missing packages.
Note that this entire block is wrapped in eval-when-compile
. The effect of this is to perform all
of the package initialization during compilation so that when byte compiled, all of this time consuming
code is skipped. This can be done because the result of byte compiling use-package
statements results
in the macro being fully expanded at which point use-package
isn’t actually required any longer.
Since the code is automatically compiled during runtime, if the configuration hasn’t already been previously compiled manually then all of the package initialization will still take place at startup.
(eval-when-compile
(require 'package)
(unless (assoc-default "melpa" package-archives)
(add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/") t))
(unless (assoc-default "org" package-archives)
(add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/") t))
(package-initialize)
(unless (package-installed-p 'use-package)
(package-refresh-contents)
(package-install 'use-package))
(unless (package-installed-p 'bind-key)
(package-refresh-contents)
(package-install 'bind-key))
(require 'use-package)
(require 'bind-key)
(setq use-package-always-ensure t))
;;(add-to-list 'custom-theme-load-path "~/.emacs.d/elpa/monokai-theme-3.4.0/")
(use-package monokai-theme
:ensure t
; :disabled t
:config
(load-theme 'monokai 'no-confirm))
;;(load-theme 'monokai t)
;;
;; Update the colour of the company-mode context menu to fit the Monokai theme
;; @source: https://github.com/search?q=deftheme+company-tooltip&type=Code
;;
(deftheme monokai-overrides)
(let ((class '((class color) (min-colors 257)))
(terminal-class '((class color) (min-colors 89))))
(custom-theme-set-faces
'monokai-overrides
;; Linum and mode-line improvements (only in sRGB).
`(linum
((,class :foreground "#75715E"
:background "#49483E")))
`(mode-line-inactive
((,class (:box (:line-width 1 :color "#2c2d26" :style nil)
:background "#2c2d26"))))
;; Custom region colouring.
`(region
((,class :foreground "#75715E"
:background "#49483E")
(,terminal-class :foreground "#1B1E1C"
:background "#8B8878")))
;; Additional modes
;; Company tweaks.
`(company-tooltip-common
((t :foreground "#F8F8F0"
:background "#474747"
:underline t)))
`(company-template-field
((t :inherit company-tooltip
:foreground "#C2A1FF")))
`(company-tooltip-selection
((t :background "#349B8D"
:foreground "#BBF7EF")))
`(company-tooltip-common-selection
((t :foreground "#F8F8F0"
:background "#474747"
:underline t)))
`(company-scrollbar-fg
((t :background "#BBF7EF")))
`(company-tooltip-annotation
((t :inherit company-tooltip
:foreground "#C2A1FF")))
;; Popup menu tweaks.
`(popup-menu-face
((t :foreground "#A1EFE4"
:background "#49483E")))
`(popup-menu-selection-face
((t :background "#349B8D"
:foreground "#BBF7EF")))
;; Circe
`(circe-prompt-face
((t (:foreground "#C2A1FF" :weight bold))))
`(circe-server-face
((t (:foreground "#75715E"))))
`(circe-highlight-nick-face
((t (:foreground "#AE81FF" :weight bold))))
`(circe-my-message-face
((t (:foreground "#E6DB74"))))
`(circe-originator-face
((t (:weight bold))))))
old Use material theme
(use-package material-theme
:ensure t
:disabled t
:config
(load-theme 'material 'no-confirm))
(use-package zenburn-theme
:ensure t
:disabled t
:init
(load-theme 'zenburn 'no-confirm))
(use-package time
:config
(setq display-time-24hr-format t
display-time-default-load-average nil)
;; (display-time-mode)
)
(use-package windmove
:config
;; use shift + arrow keys to switch between visible buffers
(windmove-default-keybindings))
;; diminish mode symbols
(use-package diminish
:ensure t
)
;; delight minor and major modes
(use-package delight
:ensure t
)
highlights
;; highlight the current line
(global-hl-line-mode +1)
(use-package diff-hl
:ensure t
:config
(global-diff-hl-mode +1)
(add-hook 'dired-mode-hook 'diff-hl-dired-mode)
(add-hook 'magit-post-refresh-hook 'diff-hl-magit-post-refresh))
(setq linum-format "%4d")
(defun my-linum-mode-hook ()
(linum-mode t))
(add-hook 'find-file-hook 'my-linum-mode-hook)
(defun format-date (format)
(let ((system-time-locale "en_NZ.UTF-8"))
(insert (format-time-string format))))
(defun insert-date ()
(interactive)
(format-date "%A, %B %d %Y"))
(defun insert-date-and-time ()
(interactive)
(format-date "%Y-%m-%d %H:%M:%S"))
There is a new wonderful coding font that I discovered recently called the Input (Font for Code). This is a really neat font that works particularly well. You just have to go to their site, define the characteristics you want for it, download and install it locally.
;;Use the Input Sans font size 12
(set-frame-font "Input Sans Condensed-12")
And the best coloured highlighting of selected text needs to be both
bright, but not obscure the white text in the foreground (see
list-colors-display
). Favorites so far are purple4
and DarkOrange3
:
(set-face-background 'region "DarkOrange3")
(use-package dynamic-fonts
:disabled t
:ensure t
:config
(progn
(setq dynamic-fonts-preferred-monospace-point-size 10
dynamic-fonts-preferred-monospace-fonts
(-union '("Source Code Pro") dynamic-fonts-preferred-monospace-fonts))
(dynamic-fonts-setup)))
;; Emacs modes typically provide a standard means to change the
;; indentation width -- eg. c-basic-offset: use that to adjust your
;; personal indentation width, while maintaining the style (and
;; meaning) of any files you load.
(setq-default indent-tabs-mode nil) ;; don't use tabs to indent
(setq-default tab-width 4) ;; but maintain correct appearance
;; Newline at end of file
(setq require-final-newline t)
;; delete the selection with a keypress
(delete-selection-mode t)
(use-package whitespace
:bind ("C-c T w" . whitespace-mode)
:delight " 🗒️"
:init
(setq whitespace-line-column nil
whitespace-display-mappings '((space-mark 32 [183] [46])
(newline-mark 10 [9166 10])
(tab-mark 9 [9654 9] [92 9])))
;(dolist (hook '(prog-mode-hook text-mode-hook))
; (add-hook hook #'whitespace-mode))
(add-hook 'before-save-hook #'whitespace-cleanup)
:config
(setq whitespace-line-column 80) ;; limit line length
(setq whitespace-style '(face tabs empty trailing lines-tail))
(set-face-attribute 'whitespace-space nil :foreground "#666666" :background nil)
(set-face-attribute 'whitespace-newline nil :foreground "#666666" :background nil)
(set-face-attribute 'whitespace-indentation nil :foreground "#666666" :background nil)
)
options for dealing with text and words
(prefer-coding-system 'utf-8)
(set-default-coding-systems 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
;; hippie expand is dabbrev expand on steroids
(setq hippie-expand-try-functions-list '(try-expand-dabbrev
try-expand-dabbrev-all-buffers
try-expand-dabbrev-from-kill
try-complete-file-name-partially
try-complete-file-name
try-expand-all-abbrevs
try-expand-list
try-expand-line
try-complete-lisp-symbol-partially
try-complete-lisp-symbol))
;; use hippie-expand instead of dabbrev
(global-set-key (kbd "M-/") #'hippie-expand)
(global-set-key (kbd "s-/") #'hippie-expand)
;; abbrev mode setup
(use-package abbrev
:ensure nil
:diminish abbrev-mode
:config
(if (file-exists-p abbrev-file-name)
(quietly-read-abbrev-file)))
(use-package flyspell
:config
(when (eq system-type 'windows-nt)
(add-to-list 'exec-path "C:/Program Files (x86)/Aspell/bin/"))
(setq ispell-program-name "aspell" ; use aspell instead of ispell
ispell-extra-args '("--sug-mode=ultra"))
(add-hook 'text-mode-hook #'flyspell-mode)
(add-hook 'prog-mode-hook #'flyspell-prog-mode)
:delight "")
(use-package flycheck
:ensure t
:config
(add-hook 'after-init-hook #'global-flycheck-mode)
:delight "")
Various keywords (in comments) are now flagged in a Red Error font:
(add-hook 'prog-common-hook
(lambda ()
(font-lock-add-keywords nil
'(("\\<\\(FIX\\|FIXME\\|TODO\\|BUG\\|HACK\\):"
1 font-lock-warning-face t)))))
Automatically wrapping when you get to the end of a line (or the fill-region):
(use-package fill
:bind (("C-c T f" . auto-fill-mode)
("C-c T t" . toggle-truncate-lines))
:init (add-hook 'org-mode-hook 'turn-on-auto-fill)
:diminish auto-fill-mode)
company mode TAB
(global-set-key (kbd "TAB") #'company-indent-or-complete-common)
Many command sequences may be logical, but who can remember them all? While I used to use guide-key to display the final function name, it isn’t as nice as which-key.
(use-package which-key
:ensure t
:config
(which-key-mode +1))
Use dired Plus dired-x
(use-package dired
:ensure nil
; :defer t
:config
;; dired - reuse current buffer by pressing 'a'
(progn
(put 'dired-find-alternate-file 'disabled nil)
;; always delete and copy recursively
(setq dired-recursive-deletes 'always)
(setq dired-recursive-copies 'always)
;; if there is a dired buffer displayed in the next window, use its
;; current subdir, instead of the current subdir of this dired buffer
(setq dired-dwim-target t)
;; enable some really cool extensions like C-x C-j(dired-jump)
(require 'dired-x)
)
)
;; revert buffers automatically when underlying files are changed externally
(global-auto-revert-mode t)
;;; Completion, snippets
(use-package company
:diminish company-mode
:ensure t
:defer t
:config
(progn
(global-company-mode)
(bind-key "M-TAB" 'company-select-next company-active-map)
(setq company-tooltip-align-annotations t
company-dabbrev-downcase nil
company-dabbrev-code-everywhere t
company-dabbrev-ignore-case nil))
)
save place and recent files
;; Save point position between sessions.
(use-package saveplace
:ensure nil ;; as not loading packages
:config
(setq save-place-file (expand-file-name "saveplace" gas-savefile-dir))
;; activate if for all buffers
(setq-default save-place t)
)
(use-package savehist
:config
(setq savehist-additional-variables
;; search entries
'(search-ring regexp-search-ring)
;; save every minute
savehist-autosave-interval 60
;; keep the home clean
savehist-file (expand-file-name "savehist" gas-savefile-dir))
(savehist-mode +1)
)
(use-package recentf
:config
(setq recentf-save-file (expand-file-name "recentf" gas-savefile-dir)
recentf-max-saved-items 500
recentf-max-menu-items 15
;; disable recentf-cleanup on Emacs start, because it can cause
;; problems with remote files aka tramp
recentf-auto-cleanup 'never)
(recentf-mode +1)
)
;; Looks like a big mess, but it works.
(defun recentf-ido-find-file ()
"Find a recent file using ido."
(interactive)
(let ((file (ido-completing-read "Choose recent file: " recentf-list nil t)))
(when file
(find-file file))))
(bind-key "C-x f" 'recentf-ido-find-file )
I like git-gutter-fringe:
(use-package git-gutter-fringe
:ensure t
:diminish git-gutter-mode
:init (setq git-gutter-fr:side 'right-fringe)
:config (global-git-gutter-mode t))
I want to have special mode for Git’s configuration
file:
(use-package gitconfig-mode
:ensure t)
(use-package gitignore-mode
:ensure t)
What about being able to see the Git blame in a buffer?
(use-package mo-git-blame
:ensure t)
Run mo-git-blame-current
to see the goodies.
Git is already part of Emacs. However, Magit is sweet. Don’t believe me? Check out this video.
(use-package magit
:ensure t
:commands magit-status magit-blame
:init
(defadvice magit-status (around magit-fullscreen activate)
(window-configuration-to-register :magit-fullscreen)
ad-do-it
(delete-other-windows))
:config
(setq magit-branch-arguments nil
;; use ido to look for branches
magit-completing-read-function 'magit-ido-completing-read
;; don't put "origin-" in front of new branch names by default
magit-default-tracking-name-function 'magit-default-tracking-name-branch-only
magit-push-always-verify nil
;; Get rid of the previous advice to go into fullscreen
magit-restore-window-configuration t)
:bind ("C-x g" . magit-status))
I like having Magit to run in a full screen mode, and add the
above defadvice
idea from Sven Magnars.
Note: Use the smerge-mode that is now part of Emacs.
Projectile is a quick and easy project management package that “just works”. We’re going to install it and make sure it’s loaded immediately.
(use-package projectile
:ensure projectile
;; :demand t
;; :bind ("s-p" . projectile-command-map)
:config
(progn
(setq projectile-enable-caching t)
(setq projectile-require-project-root nil)
(setq projectile-completion-system 'ivy)
(add-to-list 'projectile-globally-ignored-files ".DS_Store")
)
:defer (projectile-cleanup-known-projects)
:delight '(:eval (concat "𝓟/" (projectile-project-name)))
)
(use-package ivy
:ensure t
:config
(ivy-mode 1)
(setq ivy-use-virtual-buffers t)
(setq enable-recursive-minibuffers t)
(global-set-key (kbd "C-c C-r") 'ivy-resume)
(global-set-key (kbd "<f6>") 'ivy-resume)
:delight )
(use-package swiper
:ensure t
:config
(global-set-key "\C-s" 'swiper)
)
(use-package counsel
:ensure t
:config
(global-set-key (kbd "M-x") 'counsel-M-x)
(global-set-key (kbd "C-x C-f") 'counsel-find-file)
(global-set-key (kbd "<f1> f") 'counsel-describe-function)
(global-set-key (kbd "<f1> v") 'counsel-describe-variable)
(global-set-key (kbd "<f1> l") 'counsel-find-library)
(global-set-key (kbd "<f2> i") 'counsel-info-lookup-symbol)
(global-set-key (kbd "<f2> u") 'counsel-unicode-char)
(global-set-key (kbd "C-c g") 'counsel-git)
(global-set-key (kbd "C-c j") 'counsel-git-grep)
(global-set-key (kbd "C-c k") 'counsel-ag)
(global-set-key (kbd "C-x l") 'counsel-locate)
(define-key minibuffer-local-map (kbd "C-r") 'counsel-minibuffer-history)
)
(use-package ibuffer
:bind ("C-x C-b" . ibuffer))
(use-package ibuffer-projectile
:ensure t
:config
(add-hook 'ibuffer-hook #'ibuffer-projectile-set-filter-groups))
(use-package ido
:ensure t
:init (ido-mode)
:config
(setq ido-enable-flex-matching t
ido-completion-buffer nil
ido-use-faces nil))
(use-package flx-ido
:ensure t
:init (flx-ido-mode))
(use-package ido-vertical-mode
:ensure t
:init (ido-vertical-mode))
(use-package undo-tree
:diminish undo-tree-mode
:ensure t)
;; Add parts of each file's directory to the buffer name if not unique
(use-package uniquify
:ensure nil
:config
(setq uniquify-buffer-name-style 'forward)
(setq uniquify-separator "/")
(setq uniquify-after-kill-buffer-p t)
(setq uniquify-ignore-buffers-re "^\\*"))
Let’s include a newer version of org-mode than the one that is built in. We’re going to manually remove the org directories from the load path, to ensure the version we want is prioritized instead.
(use-package org
:ensure org-plus-contrib
:delight org-mode "✎"
:pin org
:defer t)
;; Ensure ELPA org is prioritized above built-in org.
(require 'cl)
(setq load-path (remove-if (lambda (x) (string-match-p "org$" x)) load-path))
MacOS Customisations
;; Are we on a mac?
(setq is-mac (equal system-type 'darwin))
(when (display-graphic-p)
(if is-mac
(menu-bar-mode 1)))
;; Make Meta command and add Hyper.
(when is-mac
;; Change command to meta.
(setq mac-command-modifier 'super)
(setq mac-option-modifier 'meta)
;; not sure what hyper is (setq ns-function-modifier 'hyper)
;; Use right option for special characters.
;; (setq mac-right-option-modifier 'none)
;; Remove date and battery status from modeline
(display-time-mode -1)
(display-battery-mode -1)
)
Let’s install and load the toc-org
package after org mode is loaded. This is the
package that automatically generates an up to date table of contents for us.
(use-package toc-org
:after org
:init (add-hook 'org-mode-hook #'toc-org-enable))
(use-package eldoc
:defer t
:diminish eldoc-mode)
;; ----- Base set of pretty symbols.
(defvar base-prettify-symbols-alist '(("<=" . ?≤)
(">=" . ?≥)
("<-" . ?←)
("->" . ?→)
("<=" . ?⇐)
("=>" . ?⇒)
("lambda" . ?λ ))
)
(defun gas-lisp-prettify-symbols-hook ()
"Set pretty symbols for lisp modes."
(setq prettify-symbols-alist base-prettify-symbols-alist))
(defun gas-js-prettify-symbols-hook ()
"Set pretty symbols for JavaScript."
(setq prettify-symbols-alist
(append '(("function" . ?ƒ)) base-prettify-symbols-alist)))
(defun gas-clj-prettify-symbols-hook ()
"Set pretty symbols for Clojure(script)."
(setq prettify-symbols-alist
(append '(("fn" . λ)) base-prettify-symbols-alist)))
(defun other-prettify-symbols-hook ()
"Set pretty symbols for non-lisp programming modes."
(setq prettify-symbols-alist
(append '(("==" . ?≡)
("!=" . ?≠))
base-prettify-symbols-alist)))
;; Hook 'em up.
(add-hook 'emacs-lisp-mode-hook #'gas-lisp-prettify-symbols-hook)
(add-hook 'web-mode-hook #'other-prettify-symbols-hook)
(add-hook 'js-mode-hook #'gas-js-prettify-symbols-hook)
(add-hook 'prog-mode-hook #'other-prettify-symbols-hook)
(add-hook 'clojure-mode-hook #'gas-clj-prettify-symbols-hook)
(global-prettify-symbols-mode 1)
(use-package lisp-mode
:ensure nil
;; :delight "lisp"
:config
;; (defun gas-visit-ielm ()
;; "Switch to default `ielm' buffer.
;;Start `ielm' if it's not already running."
;; (interactive)
;; (crux-start-or-switch-to 'ielm "*ielm*"))
(add-hook 'emacs-lisp-mode-hook #'eldoc-mode)
(add-hook 'emacs-lisp-mode-hook #'rainbow-delimiters-mode)
;; (define-key emacs-lisp-mode-map (kbd "C-c C-z") #'gas-visit-ielm)
(define-key emacs-lisp-mode-map (kbd "C-c C-c") #'eval-defun)
(define-key emacs-lisp-mode-map (kbd "C-c C-b") #'eval-buffer)
(add-hook 'lisp-interaction-mode-hook #'eldoc-mode)
(add-hook 'eval-expression-minibuffer-setup-hook #'eldoc-mode))
(use-package ielm
:config
(add-hook 'ielm-mode-hook #'eldoc-mode)
(add-hook 'ielm-mode-hook #'rainbow-delimiters-mode))
lets try out aggressive-indent
(use-package aggressive-indent
:ensure t)
The clojure-mode project seems to be the best (and works well with Cider).
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; inferior lisp
(setq inferior-lisp-program "lein figwheel")
;; inf-clojure test
(use-package inf-clojure
:ensure t
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; inf-clojure
(setq inf-clojure-lein-cmd "lein figwheel")
;; minor-mode adds key-bindings
;(add-hook 'clojure-mode-hook 'inf-clojure-minor-mode)
(use-package clojure-mode
:ensure t
:mode ("\\.\\(clj\\|cljs\\|edn\\|boot\\)$" . clojure-mode )
:config
(progn
(setq clojure-align-forms-automatically t)
(add-hook 'clojure-mode-hook #'company-mode)
(add-hook 'clojure-mode-hook #'linum-mode)
(add-hook 'clojure-mode-hook #'subword-mode)
;;(add-hook 'clojure-mode-hook #'paredit-mode)
(add-hook 'clojure-mode-hook #'smartparens-strict-mode)
(add-hook 'clojure-mode-hook #'rainbow-delimiters-mode)
(add-hook 'clojure-mode-hook #'eldoc-mode))
;; (add-hook 'clojure-mode-hook #'idle-highlight-mode)
;; :bind (("C-c d f" . cider-code))
:delight "clj"
)
(use-package paren
:ensure nil
:config
(show-paren-mode +1))
Use paredit
(use-package paredit
:disabled t
:delight " ⎎"
:ensure t
:config
(add-hook 'emacs-lisp-mode-hook #'paredit-mode)
;; enable in the *scratch* buffer
(add-hook 'lisp-interaction-mode-hook #'paredit-mode)
(add-hook 'ielm-mode-hook #'paredit-mode)
(add-hook 'lisp-mode-hook #'paredit-mode)
(add-hook 'clojure-mode-hook #'paredit-mode)
(add-hook 'eval-expression-minibuffer-setup-hook #'paredit-mode))
Use smartparens
(use-package smartparens :ensure smartparens :init (progn (require 'smartparens) (load-library "smartparens-config")) :config (progn (smartparens-global-mode t) (sp-local-pair 'emacs-lisp-mode "`" nil :when '(sp-in-string-p)) (sp-with-modes '(html-mode sgml-mode nxml-mode web-mode) (sp-local-pair "<" ">")) :bind (("C-M-k" . sp-kill-sexp-with-a-twist-of-lime) ("C-M-f" . sp-forward-sexp) ("C-M-b" . sp-backward-sexp) ("C-M-n" . sp-up-sexp) ("C-M-d" . sp-down-sexp) ("C-M-u" . sp-backward-up-sexp) ("C-M-p" . sp-backward-down-sexp) ("C-M-w" . sp-copy-sexp) ("M-s" . sp-splice-sexp) ("M-r" . sp-splice-sexp-killing-around) ("C-)" . sp-forward-slurp-sexp) ("C-}" . sp-forward-barf-sexp) ("C-(" . sp-backward-slurp-sexp) ("C-{" . sp-backward-barf-sexp) ("M-S" . sp-split-sexp) ("M-J" . sp-join-sexp) ("C-M-t" . sp-transpose-sexp)) :delight " ⎎")
use rainbow delimiters
(use-package rainbow-delimiters
:ensure t)
;; Don't show anything for rainbow-mode.
(use-package rainbow-mode
:delight)
da-bomb!
(use-package cider
:ensure t
;; :commands (cider cider-connect cider-jack-in)
:init
(setq cider-auto-select-error-buffer t
;; go right to the REPL buffer when it's finished connecting
cider-repl-pop-to-buffer-on-connect 'display-only
cider-repl-use-clojure-font-lock t
;; Wrap when navigating history.
cider-repl-wrap-history t
cider-repl-history-size 1000
;; When there's a cider error, show its buffer and switch to it
cider-show-error-buffer t
cider-auto-select-error-buffer t
nrepl-hide-special-buffers t
;; Stop error buffer from popping up while working in buffers other than the REPL:
nrepl-popup-stacktraces nil
;; Where to store the cider history.
cider-repl-history-file "~/.emacs.d/cider-history"
)
:config
(progn ;; (defalias 'cji 'cider-jack-in)
(add-hook 'cider-mode-hook #'eldoc-mode)
(add-hook 'cider-repl-mode-hook #'eldoc-mode)
;; (add-hook 'cider-repl-mode-hook #'smartparens-strict-mode)
(add-hook 'cider-repl-mode-hook #'company-mode)
(add-hook 'cider-mode-hook #'company-mode)
(add-hook 'cider-repl-mode-hook #'cider-company-enable-fuzzy-completion)
(add-hook 'cider-mode-hook #'cider-company-enable-fuzzy-completion)
;; (add-hook 'cider-repl-mode-hook #'paredit-mode)
(add-hook 'cider-repl-mode-hook #'rainbow-delimiters-mode)
)
:diminish (cider-mode . "☤")
)
(setq cider-cljs-lein-repl
"(cond
(and (resolve 'user/run) (resolve 'user/browser-repl)) ;; Chestnut projects
(eval '(do (user/run)
(user/browser-repl)))
(try
(require 'figwheel-sidecar.repl-api)
(resolve 'figwheel-sidecar.repl-api/start-figwheel!)
(catch Throwable _))
(eval '(do (figwheel-sidecar.repl-api/start-figwheel!)
(figwheel-sidecar.repl-api/cljs-repl)))
(try
(require 'cemerick.piggieback)
(resolve 'cemerick.piggieback/cljs-repl)
(catch Throwable _))
(eval '(cemerick.piggieback/cljs-repl (cljs.repl.rhino/repl-env)))
:else
(throw (ex-info \"Failed to initialise CLJS repl. Add com.cemerick/piggieback
and optionally figwheel-sidecar to your project.\" {})))")
JavaScript should have three parts:
- Syntax highlight (already included)
- Syntax verification (with flycheck)
- Interactive REPL … using Skewer
I like the extras found in Steve Yegge’s js2-mode.
(use-package js2-mode
:ensure t
:interpreter ("node" . js2-mode)
:init
(setq js-basic-indent 2)
(setq-default js2-basic-indent 2
js2-basic-offset 2
js2-auto-indent-p t
js2-cleanup-whitespace t
js2-enter-indents-newline t
js2-indent-on-enter-key t
js2-global-externs (list "window" "module" "require" "buster" "sinon" "assert" "refute" "setTimeout" "clearTimeout" "setInterval" "clearInterval" "location" "__dirname" "console" "JSON" "jQuery" "$"))
(add-hook 'js2-mode-hook
(lambda ()
(push '("function" . ?ƒ) prettify-symbols-alist)))
(add-to-list 'auto-mode-alist '("\\.js$" . js2-mode)))
Colour defined variables with color-identifiers-mode:
(use-package color-identifiers-mode
:ensure t
:init
(add-hook 'js2-mode-hook 'color-identifiers-mode))
While editing JavaScript is baked into Emacs, it is quite important
to have flycheck validate the source based on jshint, and eslint.
Let’s prefer eslint
:
(add-hook 'js2-mode-hook
(lambda () (flycheck-select-checker "javascript-eslint")))
Now load and edit a JavaScript file, like jshint-code-test.js.
The js2-refactor mode should start with C-c .
and then a two-letter
mnemonic shortcut.
ef
isextract-function
: Extracts the marked expressions out into a new named function.em
isextract-method
: Extracts the marked expressions out into a new named method in an object literal.ip
isintroduce-parameter
: Changes the marked expression to a parameter in a local function.lp
islocalize-parameter
: Changes a parameter to a local var in a local function.eo
isexpand-object
: Converts a one line object literal to multiline.co
iscontract-object
: Converts a multiline object literal to one line.eu
isexpand-function
: Converts a one line function to multiline (expecting semicolons as statement delimiters).cu
iscontract-function
: Converts a multiline function to one line (expecting semicolons as statement delimiters).ea
isexpand-array
: Converts a one line array to multiline.ca
iscontract-array
: Converts a multiline array to one line.wi
iswrap-buffer-in-iife
: Wraps the entire buffer in an immediately invoked function expressionig
isinject-global-in-iife
: Creates a shortcut for a marked global by injecting it in the wrapping immediately invoked function expressionag
isadd-to-globals-annotation
: Creates a/*global */
annotation if it is missing, and adds the var at point to it.ev
isextract-var
: Takes a marked expression and replaces it with a var.iv
isinline-var
: Replaces all instances of a variable with its initial value.rv
isrename-var
: Renames the variable on point and all occurrences in its lexical scope.vt
isvar-to-this
: Changes localvar a
to bethis.a
instead.ao
isarguments-to-object
: Replaces arguments to a function call with an object literal of named arguments. Requires yasnippets.3i
isternary-to-if
: Converts ternary operator to if-statement.sv
issplit-var-declaration
: Splits avar
with multiple vars declared, into severalvar
statements.uw
isunwrap
: Replaces the parent statement with the selected region.
(use-package js2-refactor
:ensure t
:init (add-hook 'js2-mode-hook 'js2-refactor-mode)
:config (js2r-add-keybindings-with-prefix "C-c ."))
I also configure Skewer for my HTML and CSS files, we need to do the same for JavaScript:
(use-package skewer-mode
:ensure t
:init (add-hook 'js2-mode-hook 'skewer-mode))
Kick things off with run-skewer
, and then:
- C-x C-e
- `skewer-eval-last-expression’
- C-M-x
- `skewer-eval-defun’
- C-c C-k
- `skewer-load-buffer’
(use-package json-mode
:ensure json-mode
:config (bind-keys :map json-mode-map
("C-c i" . json-mode-beautify))
:mode ("\\.\\(json\\)$" . json-mode))
(use-package yaml-mode
:mode ("\\.\\(yml\\|yaml\\|\\config\\|sls\\)$" . yaml-mode)
:ensure yaml-mode
:defer t)
(use-package cc-mode
:config
(progn
(add-hook 'c-mode-hook (lambda () (c-set-style "bsd")))
(add-hook 'java-mode-hook (lambda () (c-set-style "bsd")))
(setq tab-width 2)
(setq c-basic-offset 2)))
(use-package css-mode
:config (setq css-indent-offset 2)
)
pretty terraform highlighting
;;(use-package terraform-mode
;; :defer t
;; :init
;; (progn
;; (require 'company-terraform)
;; (company-terraform-init)
;; )
;; :config (setq terraform-indent-level 2)
;; )
Let’s lower our GC thresholds back down to a sane level.
(setq gc-cons-threshold 16777216
gc-cons-percentage 0.1)