├── Makefile ├── lisp └── compile.el ├── init.el └── readme.org /Makefile: -------------------------------------------------------------------------------- 1 | clean: 2 | @rm -f init.elc readme.el readme.elc 3 | 4 | compile: init.el readme.org clean 5 | @emacs -Q --batch -l 'lisp/compile.el' 6 | -------------------------------------------------------------------------------- /lisp/compile.el: -------------------------------------------------------------------------------- 1 | (require 'org) 2 | (org-babel-tangle-file "readme.org") 3 | (setq byte-compile-warnings '(not free-vars unresolved noruntime lexical make-local)) 4 | (byte-compile-file "readme.el") 5 | (byte-compile-file "init.el") 6 | -------------------------------------------------------------------------------- /init.el: -------------------------------------------------------------------------------- 1 | ;;; Package --- Summary 2 | 3 | ;;; Commentary: 4 | ;; Emacs init file responsible for either loading a pre-compiled configuration 5 | ;; file or tangling and loading a literate org configuration file. 6 | 7 | ;; Don't attempt to find/apply special file handlers to files loaded during 8 | ;; startup. 9 | (let ((file-name-handler-alist nil)) 10 | ;; If config is pre-compiled, then load that 11 | (if (file-exists-p (expand-file-name "readme.elc" user-emacs-directory)) 12 | (load-file (expand-file-name "readme.elc" user-emacs-directory)) 13 | ;; Otherwise use org-babel to tangle and load the configuration 14 | (require 'org) 15 | (org-babel-load-file (expand-file-name "readme.org" user-emacs-directory)))) 16 | 17 | ;;; init.el ends here 18 | -------------------------------------------------------------------------------- /readme.org: -------------------------------------------------------------------------------- 1 | #+TITLE: Atea Emacs Literate Configuration 2 | #+AUTHOR: Andrés Gasson 3 | #+PROPERTY: header-args :tangle yes 4 | 5 | * Configuration 6 | :PROPERTIES: 7 | :VISIBILITY: children 8 | :END: 9 | 10 | ** Table of Contents :TOC_3_gh: 11 | - [[#configuration][Configuration]] 12 | - [[#about-this-file][About this file]] 13 | - [[#org-file-tweaks][Org File Tweaks]] 14 | - [[#automatically-tangle][Automatically Tangle]] 15 | - [[#visibility-settings][Visibility Settings]] 16 | - [[#table-of-contents][Table of Contents]] 17 | - [[#personal-information][Personal Information]] 18 | - [[#emacs-initialisation][Emacs Initialisation]] 19 | - [[#settings][Settings]] 20 | - [[#package-management][Package Management]] 21 | - [[#packages][Packages]] 22 | - [[#display][Display]] 23 | - [[#linenumbers][LineNumbers]] 24 | - [[#timestamps][Timestamps]] 25 | - [[#fonts][Fonts]] 26 | - [[#whitespace][Whitespace]] 27 | - [[#wordsmithing][Wordsmithing]] 28 | - [[#fill-mode][Fill Mode]] 29 | - [[#global-keys][Global keys]] 30 | - [[#which-key][Which-key]] 31 | - [[#files][Files]] 32 | - [[#git][Git]] 33 | - [[#magit][Magit]] 34 | - [[#projectile][Projectile]] 35 | - [[#ido][Ido]] 36 | - [[#undo][Undo]] 37 | - [[#org][Org]] 38 | - [[#macos][MacOS]] 39 | - [[#toc-org][Toc-org]] 40 | - [[#programming][Programming]] 41 | - [[#eldoc][Eldoc]] 42 | - [[#prettify-code][Prettify code]] 43 | - [[#elisp][Elisp]] 44 | - [[#clojure][Clojure]] 45 | - [[#parens][Parens]] 46 | - [[#cider][Cider]] 47 | - [[#javascript][Javascript]] 48 | - [[#js2-mode][JS2 Mode]] 49 | - [[#yaml][YAML]] 50 | - [[#c][C]] 51 | - [[#css][CSS]] 52 | - [[#terraform][Terraform]] 53 | - [[#post-initialisation][Post Initialisation]] 54 | 55 | ** About this file 56 | This is an Emacs literate configuration template. It contains the basic structure 57 | of a literate config along with some optimizations to ensure a fast load time. 58 | 59 | ** Org File Tweaks 60 | There are a few tweaks included in this org file that make it a little easier to 61 | work with. 62 | 63 | *** Automatically Tangle 64 | First there is a property defined on the file: 65 | 66 | #+BEGIN_SRC :tangle no 67 | header-args :tangle yes 68 | #+END_SRC 69 | 70 | This tells emacs to automatically tangle (include) all code blocks in this file when 71 | generating the code for the config, unless the code block explicitly includes 72 | =:tangle no= as the above code block does. 73 | 74 | *** Visibility Settings 75 | Next we have a property defined on the [[Configuration][Configuration]] heading that defines the visibility 76 | that tells org to show it's direct children on startup. This way a clean outline of all 77 | sub headings under Configuration is shown each time this file is opened in org-mode. 78 | 79 | *** Table of Contents 80 | Finally, there is a [[Table of Contents][Table of Contents]] heading that includes the tag: =:TOC_3_gh:=. This 81 | tells an org-mode package =toc-org= to generate a table of contents under this heading 82 | that has a max depth of 3 and is created using Github-style hrefs. This table of contents 83 | is updated everytime the file is saved and makes for a functional table of contents that 84 | works property directly on github. 85 | 86 | ** Personal Information 87 | Let's set some variables with basic user information. 88 | 89 | #+BEGIN_SRC emacs-lisp 90 | (setq user-full-name "Andrés Gasson" 91 | user-mail-address "agasson@ateasystems.com") 92 | #+END_SRC 93 | 94 | ** Emacs Initialisation 95 | 96 | *** Settings 97 | We're going to increase the gc-cons-threshold to a very high number to decrease the load and compile time. 98 | We'll lower this value significantly after initialization has completed. We don't want to keep this value 99 | too high or it will result in long GC pauses during normal usage. 100 | 101 | #+BEGIN_SRC emacs-lisp 102 | (eval-and-compile 103 | (setq gc-cons-threshold 402653184 104 | gc-cons-percentage 0.6)) 105 | #+END_SRC 106 | 107 | Disable certain byte compiler warnings to cut down on the noise. This is a personal choice and can be removed 108 | if you would like to see any and all byte compiler warnings. 109 | 110 | #+BEGIN_SRC emacs-lisp 111 | (setq byte-compile-warnings '(not free-vars unresolved noruntime lexical make-local)) 112 | #+END_SRC 113 | 114 | Some default settings aka sanity defaults 115 | #+BEGIN_SRC emacs-lisp 116 | ;;; Code: 117 | ;; menu shit remove 118 | (mapc 119 | (lambda (mode) 120 | (when (fboundp mode) 121 | (funcall mode -1))) 122 | '(menu-bar-mode tool-bar-mode scroll-bar-mode)) 123 | 124 | ;;; Initialisation 125 | (setq inhibit-default-init t 126 | inhibit-startup-echo-area-message t 127 | inhibit-startup-screen t 128 | initial-scratch-message nil) 129 | 130 | ;; warn when opening files bigger than 100MB 131 | (setq large-file-warning-threshold 100000000) 132 | 133 | (defconst gas-savefile-dir (expand-file-name "savefile" user-emacs-directory)) 134 | 135 | ;; create the savefile dir if it doesn't exist 136 | (unless (file-exists-p gas-savefile-dir) 137 | (make-directory gas-savefile-dir)) 138 | 139 | ;;; UI 140 | ;; the blinking cursor is nothing, but an annoyance 141 | (blink-cursor-mode -1) 142 | 143 | ;; disable the annoying bell ring 144 | (setq ring-bell-function 'ignore) 145 | 146 | ;; disable startup screen 147 | (setq inhibit-startup-screen t) 148 | 149 | ;; nice scrolling 150 | (setq scroll-margin 0 151 | scroll-conservatively 100000 152 | scroll-preserve-screen-position 1) 153 | 154 | ;; mode line settings 155 | (line-number-mode t) 156 | (column-number-mode t) 157 | (size-indication-mode t) 158 | 159 | ;; enable y/n answers 160 | (fset 'yes-or-no-p 'y-or-n-p) 161 | 162 | ;; more useful frame title, that show either a file or a 163 | ;; buffer name (if the buffer isn't visiting a file) 164 | (setq frame-title-format 165 | '((:eval (if (buffer-file-name) 166 | (abbreviate-file-name (buffer-file-name)) 167 | "%b")))) 168 | 169 | ;; Productive default mode 170 | (setq initial-major-mode 'org-mode) 171 | 172 | ;; When on a tab, make the cursor the tab length. 173 | (setq-default x-stretch-cursor t) 174 | 175 | ;; Keep emacs Custom-settings in separate file. 176 | (setq custom-file (expand-file-name "custom.el" user-emacs-directory)) 177 | (when (file-exists-p custom-file) 178 | (load custom-file)) 179 | 180 | ;; store all backup and autosave files in the tmp dir 181 | (setq backup-directory-alist 182 | `((".*" . ,temporary-file-directory))) 183 | (setq auto-save-file-name-transforms 184 | `((".*" ,temporary-file-directory t))) 185 | 186 | ;; revert buffers automatically when underlying files are changed externally 187 | (global-auto-revert-mode t) 188 | 189 | ;; Make backups of files, even when they're in version control. 190 | (setq vc-make-backup-files t) 191 | 192 | ;; Fix empty pasteboard error. 193 | (setq save-interprogram-paste-before-kill nil) 194 | 195 | 196 | #+END_SRC 197 | *** Package Management 198 | 199 | **** Package Settings 200 | We're going to set the =load-path= ourselves and avoid calling =(package-initilize)= (for 201 | performance reasons) so we need to set =package--init-file-ensured= to true to tell =package.el= 202 | to not automatically call it on our behalf. Additionally we're setting 203 | =package-enable-at-startup= to nil so that packages will not automatically be loaded for us since 204 | =use-package= will be handling that. 205 | 206 | #+BEGIN_SRC emacs-lisp 207 | (eval-and-compile 208 | (setq load-prefer-newer t 209 | package-user-dir "~/.emacs.d/elpa" 210 | package--init-file-ensured t 211 | package-enable-at-startup nil) 212 | 213 | (unless (file-directory-p package-user-dir) 214 | (make-directory package-user-dir t))) 215 | #+END_SRC 216 | 217 | **** Use-Package Settings 218 | Tell =use-package= to always defer loading packages unless explicitly told otherwise. This speeds up 219 | initialization significantly as many packages are only loaded later when they are explicitly used. 220 | 221 | #+BEGIN_SRC emacs-lisp 222 | (setq use-package-always-defer t 223 | use-package-verbose t) 224 | #+END_SRC 225 | 226 | **** Manually Set Load Path 227 | We're going to set the load path ourselves so that we don't have to call =package-initialize= at 228 | runtime and incur a large performance hit. This load-path will actually be faster than the one 229 | created by =package-initialize= because it appends the elpa packages to the end of the load path. 230 | Otherwise any time a builtin package was required it would have to search all of third party paths 231 | first. 232 | 233 | #+BEGIN_SRC emacs-lisp 234 | (eval-and-compile 235 | (setq load-path (append load-path (directory-files package-user-dir t "^[^.]" t)))) 236 | #+END_SRC 237 | 238 | **** Initialise Package Management 239 | Next we are going to require =package.el= and add our additional package archives, 'melpa' and 'org'. 240 | Afterwards we need to initialize our packages and then ensure that =use-package= is installed, which 241 | we promptly install if it's missing. Finally we load =use-package= and tell it to always install any 242 | missing packages. 243 | 244 | Note that this entire block is wrapped in =eval-when-compile=. The effect of this is to perform all 245 | of the package initialization during compilation so that when byte compiled, all of this time consuming 246 | code is skipped. This can be done because the result of byte compiling =use-package= statements results 247 | in the macro being fully expanded at which point =use-package= isn't actually required any longer. 248 | 249 | Since the code is automatically compiled during runtime, if the configuration hasn't already been 250 | previously compiled manually then all of the package initialization will still take place at startup. 251 | 252 | #+BEGIN_SRC emacs-lisp 253 | (eval-when-compile 254 | (require 'package) 255 | 256 | (unless (assoc-default "melpa" package-archives) 257 | (add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/") t)) 258 | (unless (assoc-default "org" package-archives) 259 | (add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/") t)) 260 | 261 | (package-initialize) 262 | (unless (package-installed-p 'use-package) 263 | (package-refresh-contents) 264 | (package-install 'use-package)) 265 | (unless (package-installed-p 'bind-key) 266 | (package-refresh-contents) 267 | (package-install 'bind-key)) 268 | (require 'use-package) 269 | (require 'bind-key) 270 | (setq use-package-always-ensure t)) 271 | #+END_SRC 272 | 273 | 274 | ** Packages 275 | 276 | *** Display 277 | 278 | #+BEGIN_SRC elisp 279 | ;;(add-to-list 'custom-theme-load-path "~/.emacs.d/elpa/monokai-theme-3.4.0/") 280 | (use-package monokai-theme 281 | :ensure t 282 | ; :disabled t 283 | :config 284 | (load-theme 'monokai 'no-confirm)) 285 | ;;(load-theme 'monokai t) 286 | 287 | ;; 288 | ;; Update the colour of the company-mode context menu to fit the Monokai theme 289 | ;; @source: https://github.com/search?q=deftheme+company-tooltip&type=Code 290 | ;; 291 | (deftheme monokai-overrides) 292 | 293 | (let ((class '((class color) (min-colors 257))) 294 | (terminal-class '((class color) (min-colors 89)))) 295 | 296 | (custom-theme-set-faces 297 | 'monokai-overrides 298 | 299 | ;; Linum and mode-line improvements (only in sRGB). 300 | `(linum 301 | ((,class :foreground "#75715E" 302 | :background "#49483E"))) 303 | `(mode-line-inactive 304 | ((,class (:box (:line-width 1 :color "#2c2d26" :style nil) 305 | :background "#2c2d26")))) 306 | 307 | ;; Custom region colouring. 308 | `(region 309 | ((,class :foreground "#75715E" 310 | :background "#49483E") 311 | (,terminal-class :foreground "#1B1E1C" 312 | :background "#8B8878"))) 313 | 314 | ;; Additional modes 315 | ;; Company tweaks. 316 | `(company-tooltip-common 317 | ((t :foreground "#F8F8F0" 318 | :background "#474747" 319 | :underline t))) 320 | 321 | `(company-template-field 322 | ((t :inherit company-tooltip 323 | :foreground "#C2A1FF"))) 324 | 325 | `(company-tooltip-selection 326 | ((t :background "#349B8D" 327 | :foreground "#BBF7EF"))) 328 | 329 | `(company-tooltip-common-selection 330 | ((t :foreground "#F8F8F0" 331 | :background "#474747" 332 | :underline t))) 333 | 334 | `(company-scrollbar-fg 335 | ((t :background "#BBF7EF"))) 336 | 337 | `(company-tooltip-annotation 338 | ((t :inherit company-tooltip 339 | :foreground "#C2A1FF"))) 340 | 341 | ;; Popup menu tweaks. 342 | `(popup-menu-face 343 | ((t :foreground "#A1EFE4" 344 | :background "#49483E"))) 345 | 346 | `(popup-menu-selection-face 347 | ((t :background "#349B8D" 348 | :foreground "#BBF7EF"))) 349 | 350 | ;; Circe 351 | `(circe-prompt-face 352 | ((t (:foreground "#C2A1FF" :weight bold)))) 353 | 354 | `(circe-server-face 355 | ((t (:foreground "#75715E")))) 356 | 357 | `(circe-highlight-nick-face 358 | ((t (:foreground "#AE81FF" :weight bold)))) 359 | 360 | `(circe-my-message-face 361 | ((t (:foreground "#E6DB74")))) 362 | 363 | `(circe-originator-face 364 | ((t (:weight bold)))))) 365 | #+END_SRC 366 | 367 | old Use material theme 368 | 369 | #+BEGIN_SRC emacs-lisp 370 | (use-package material-theme 371 | :ensure t 372 | :disabled t 373 | :config 374 | (load-theme 'material 'no-confirm)) 375 | 376 | (use-package zenburn-theme 377 | :ensure t 378 | :disabled t 379 | :init 380 | (load-theme 'zenburn 'no-confirm)) 381 | 382 | (use-package time 383 | :config 384 | (setq display-time-24hr-format t 385 | display-time-default-load-average nil) 386 | ;; (display-time-mode) 387 | ) 388 | 389 | (use-package windmove 390 | :config 391 | ;; use shift + arrow keys to switch between visible buffers 392 | (windmove-default-keybindings)) 393 | 394 | ;; diminish mode symbols 395 | (use-package diminish 396 | :ensure t 397 | ) 398 | ;; delight minor and major modes 399 | (use-package delight 400 | :ensure t 401 | ) 402 | #+END_SRC 403 | highlights 404 | 405 | #+BEGIN_SRC emacs-lisp 406 | ;; highlight the current line 407 | (global-hl-line-mode +1) 408 | 409 | (use-package diff-hl 410 | :ensure t 411 | :config 412 | (global-diff-hl-mode +1) 413 | (add-hook 'dired-mode-hook 'diff-hl-dired-mode) 414 | (add-hook 'magit-post-refresh-hook 'diff-hl-magit-post-refresh)) 415 | #+END_SRC 416 | *** LineNumbers 417 | #+BEGIN_SRC elisp 418 | (setq linum-format "%4d") 419 | 420 | (defun my-linum-mode-hook () 421 | (linum-mode t)) 422 | 423 | (add-hook 'find-file-hook 'my-linum-mode-hook) 424 | #+END_SRC 425 | *** Timestamps 426 | #+BEGIN_SRC elisp 427 | (defun format-date (format) 428 | (let ((system-time-locale "en_NZ.UTF-8")) 429 | (insert (format-time-string format)))) 430 | 431 | (defun insert-date () 432 | (interactive) 433 | (format-date "%A, %B %d %Y")) 434 | 435 | (defun insert-date-and-time () 436 | (interactive) 437 | (format-date "%Y-%m-%d %H:%M:%S")) 438 | #+END_SRC 439 | 440 | *** Fonts 441 | There is a new wonderful coding font that I discovered recently called the Input (Font for Code). 442 | This is a really neat font that works particularly well. You just have to go to their site, 443 | define the characteristics you want for it, download and install it locally. 444 | #+BEGIN_SRC emacs-lisp 445 | ;;Use the Input Sans font size 12 446 | (set-frame-font "Input Sans Condensed-12") 447 | #+END_SRC 448 | 449 | And the best coloured highlighting of selected text needs to be both 450 | bright, but not obscure the white text in the foreground (see 451 | =list-colors-display=). Favorites so far are =purple4= and =DarkOrange3=: 452 | 453 | #+BEGIN_SRC emacs-lisp 454 | (set-face-background 'region "DarkOrange3") 455 | #+END_SRC 456 | 457 | #+BEGIN_SRC emacs-lisp 458 | (use-package dynamic-fonts 459 | :disabled t 460 | :ensure t 461 | :config 462 | (progn 463 | (setq dynamic-fonts-preferred-monospace-point-size 10 464 | dynamic-fonts-preferred-monospace-fonts 465 | (-union '("Source Code Pro") dynamic-fonts-preferred-monospace-fonts)) 466 | (dynamic-fonts-setup))) 467 | #+END_SRC 468 | *** Whitespace 469 | #+BEGIN_SRC emacs-lisp 470 | ;; Emacs modes typically provide a standard means to change the 471 | ;; indentation width -- eg. c-basic-offset: use that to adjust your 472 | ;; personal indentation width, while maintaining the style (and 473 | ;; meaning) of any files you load. 474 | (setq-default indent-tabs-mode nil) ;; don't use tabs to indent 475 | (setq-default tab-width 4) ;; but maintain correct appearance 476 | 477 | ;; Newline at end of file 478 | (setq require-final-newline t) 479 | 480 | ;; delete the selection with a keypress 481 | (delete-selection-mode t) 482 | 483 | (use-package whitespace 484 | :bind ("C-c T w" . whitespace-mode) 485 | :delight " 🗒️" 486 | :init 487 | (setq whitespace-line-column nil 488 | whitespace-display-mappings '((space-mark 32 [183] [46]) 489 | (newline-mark 10 [9166 10]) 490 | (tab-mark 9 [9654 9] [92 9]))) 491 | ;(dolist (hook '(prog-mode-hook text-mode-hook)) 492 | ; (add-hook hook #'whitespace-mode)) 493 | (add-hook 'before-save-hook #'whitespace-cleanup) 494 | :config 495 | (setq whitespace-line-column 80) ;; limit line length 496 | (setq whitespace-style '(face tabs empty trailing lines-tail)) 497 | (set-face-attribute 'whitespace-space nil :foreground "#666666" :background nil) 498 | (set-face-attribute 'whitespace-newline nil :foreground "#666666" :background nil) 499 | (set-face-attribute 'whitespace-indentation nil :foreground "#666666" :background nil) 500 | ) 501 | #+END_SRC 502 | *** Wordsmithing 503 | options for dealing with text and words 504 | #+BEGIN_SRC emacs-lisp 505 | (prefer-coding-system 'utf-8) 506 | (set-default-coding-systems 'utf-8) 507 | (set-terminal-coding-system 'utf-8) 508 | (set-keyboard-coding-system 'utf-8) 509 | 510 | ;; hippie expand is dabbrev expand on steroids 511 | (setq hippie-expand-try-functions-list '(try-expand-dabbrev 512 | try-expand-dabbrev-all-buffers 513 | try-expand-dabbrev-from-kill 514 | try-complete-file-name-partially 515 | try-complete-file-name 516 | try-expand-all-abbrevs 517 | try-expand-list 518 | try-expand-line 519 | try-complete-lisp-symbol-partially 520 | try-complete-lisp-symbol)) 521 | 522 | ;; use hippie-expand instead of dabbrev 523 | (global-set-key (kbd "M-/") #'hippie-expand) 524 | (global-set-key (kbd "s-/") #'hippie-expand) 525 | 526 | ;; abbrev mode setup 527 | (use-package abbrev 528 | :ensure nil 529 | :diminish abbrev-mode 530 | :config 531 | (if (file-exists-p abbrev-file-name) 532 | (quietly-read-abbrev-file))) 533 | 534 | (use-package flyspell 535 | :config 536 | (when (eq system-type 'windows-nt) 537 | (add-to-list 'exec-path "C:/Program Files (x86)/Aspell/bin/")) 538 | (setq ispell-program-name "aspell" ; use aspell instead of ispell 539 | ispell-extra-args '("--sug-mode=ultra")) 540 | (add-hook 'text-mode-hook #'flyspell-mode) 541 | (add-hook 'prog-mode-hook #'flyspell-prog-mode) 542 | :delight "") 543 | 544 | (use-package flycheck 545 | :ensure t 546 | :config 547 | (add-hook 'after-init-hook #'global-flycheck-mode) 548 | :delight "") 549 | 550 | #+END_SRC 551 | **** Red Warnings 552 | 553 | Various keywords (in comments) are now flagged in a Red Error font: 554 | 555 | #+BEGIN_SRC emacs-lisp 556 | (add-hook 'prog-common-hook 557 | (lambda () 558 | (font-lock-add-keywords nil 559 | '(("\\<\\(FIX\\|FIXME\\|TODO\\|BUG\\|HACK\\):" 560 | 1 font-lock-warning-face t))))) 561 | #+END_SRC 562 | 563 | *** Fill Mode 564 | 565 | Automatically wrapping when you get to the end of a line (or the 566 | fill-region): 567 | 568 | #+BEGIN_SRC elisp 569 | (use-package fill 570 | :bind (("C-c T f" . auto-fill-mode) 571 | ("C-c T t" . toggle-truncate-lines)) 572 | :init (add-hook 'org-mode-hook 'turn-on-auto-fill) 573 | :diminish auto-fill-mode) 574 | #+END_SRC 575 | 576 | *** Global keys 577 | company mode TAB 578 | #+BEGIN_SRC emacs-lisp 579 | (global-set-key (kbd "TAB") #'company-indent-or-complete-common) 580 | #+END_SRC 581 | *** Which-key 582 | Many command sequences may be logical, but who can remember them 583 | all? While I used to use [[https://github.com/kai2nenobu/guide-key][guide-key]] to display the final function 584 | name, it isn't as nice as [[https://github.com/justbur/emacs-which-key][which-key]]. 585 | 586 | #+name: global-keys 587 | #+BEGIN_SRC emacs-lisp 588 | (use-package which-key 589 | :ensure t 590 | :config 591 | (which-key-mode +1)) 592 | #+END_SRC 593 | 594 | *** Files 595 | 596 | Use dired Plus dired-x 597 | #+BEGIN_SRC emacs-lisp 598 | (use-package dired 599 | :ensure nil 600 | ; :defer t 601 | :config 602 | ;; dired - reuse current buffer by pressing 'a' 603 | (progn 604 | (put 'dired-find-alternate-file 'disabled nil) 605 | 606 | ;; always delete and copy recursively 607 | (setq dired-recursive-deletes 'always) 608 | (setq dired-recursive-copies 'always) 609 | 610 | ;; if there is a dired buffer displayed in the next window, use its 611 | ;; current subdir, instead of the current subdir of this dired buffer 612 | (setq dired-dwim-target t) 613 | 614 | ;; enable some really cool extensions like C-x C-j(dired-jump) 615 | (require 'dired-x) 616 | ) 617 | ) 618 | 619 | ;; revert buffers automatically when underlying files are changed externally 620 | (global-auto-revert-mode t) 621 | 622 | ;;; Completion, snippets 623 | 624 | (use-package company 625 | :diminish company-mode 626 | :ensure t 627 | :defer t 628 | :config 629 | (progn 630 | (global-company-mode) 631 | (bind-key "M-TAB" 'company-select-next company-active-map) 632 | (setq company-tooltip-align-annotations t 633 | company-dabbrev-downcase nil 634 | company-dabbrev-code-everywhere t 635 | company-dabbrev-ignore-case nil)) 636 | ) 637 | 638 | 639 | #+END_SRC 640 | save place and recent files 641 | #+BEGIN_SRC emacs-lisp 642 | ;; Save point position between sessions. 643 | (use-package saveplace 644 | :ensure nil ;; as not loading packages 645 | :config 646 | (setq save-place-file (expand-file-name "saveplace" gas-savefile-dir)) 647 | ;; activate if for all buffers 648 | (setq-default save-place t) 649 | ) 650 | 651 | (use-package savehist 652 | :config 653 | (setq savehist-additional-variables 654 | ;; search entries 655 | '(search-ring regexp-search-ring) 656 | ;; save every minute 657 | savehist-autosave-interval 60 658 | ;; keep the home clean 659 | savehist-file (expand-file-name "savehist" gas-savefile-dir)) 660 | (savehist-mode +1) 661 | ) 662 | 663 | (use-package recentf 664 | :config 665 | (setq recentf-save-file (expand-file-name "recentf" gas-savefile-dir) 666 | recentf-max-saved-items 500 667 | recentf-max-menu-items 15 668 | ;; disable recentf-cleanup on Emacs start, because it can cause 669 | ;; problems with remote files aka tramp 670 | recentf-auto-cleanup 'never) 671 | (recentf-mode +1) 672 | ) 673 | 674 | ;; Looks like a big mess, but it works. 675 | (defun recentf-ido-find-file () 676 | "Find a recent file using ido." 677 | (interactive) 678 | (let ((file (ido-completing-read "Choose recent file: " recentf-list nil t))) 679 | (when file 680 | (find-file file)))) 681 | 682 | (bind-key "C-x f" 'recentf-ido-find-file ) 683 | 684 | #+END_SRC 685 | *** Git 686 | 687 | I like [[https://github.com/syohex/emacs-git-gutter-fringe][git-gutter-fringe]]: 688 | 689 | #+BEGIN_SRC elisp 690 | (use-package git-gutter-fringe 691 | :ensure t 692 | :diminish git-gutter-mode 693 | :init (setq git-gutter-fr:side 'right-fringe) 694 | :config (global-git-gutter-mode t)) 695 | #+END_SRC 696 | 697 | I want to have special mode for Git's =configuration= file: 698 | 699 | #+BEGIN_SRC elisp 700 | (use-package gitconfig-mode 701 | :ensure t) 702 | 703 | (use-package gitignore-mode 704 | :ensure t) 705 | #+END_SRC 706 | 707 | What about being able to see the [[https://github.com/voins/mo-git-blame][Git blame]] in a buffer? 708 | 709 | #+BEGIN_SRC elisp 710 | (use-package mo-git-blame 711 | :ensure t) 712 | #+END_SRC 713 | 714 | Run =mo-git-blame-current= to see the goodies. 715 | 716 | *** Magit 717 | 718 | Git is [[http://emacswiki.org/emacs/Git][already part of Emacs]]. However, [[http://philjackson.github.com/magit/magit.html][Magit]] is sweet. 719 | Don't believe me? Check out [[https://www.youtube.com/watch?v=vQO7F2Q9DwA][this video]]. 720 | 721 | #+BEGIN_SRC elisp 722 | (use-package magit 723 | :ensure t 724 | :commands magit-status magit-blame 725 | :init 726 | (defadvice magit-status (around magit-fullscreen activate) 727 | (window-configuration-to-register :magit-fullscreen) 728 | ad-do-it 729 | (delete-other-windows)) 730 | :config 731 | (setq magit-branch-arguments nil 732 | ;; use ido to look for branches 733 | magit-completing-read-function 'magit-ido-completing-read 734 | ;; don't put "origin-" in front of new branch names by default 735 | magit-default-tracking-name-function 'magit-default-tracking-name-branch-only 736 | magit-push-always-verify nil 737 | ;; Get rid of the previous advice to go into fullscreen 738 | magit-restore-window-configuration t) 739 | 740 | :bind ("C-x g" . magit-status)) 741 | #+END_SRC 742 | 743 | I like having Magit to run in a /full screen/ mode, and add the 744 | above =defadvice= idea from [[https://github.com/magnars/.emacs.d/blob/master/setup-magit.el][Sven Magnars]]. 745 | 746 | *Note:* Use the [[https://github.com/jwiegley/emacs-release/blob/master/lisp/vc/smerge-mode.el][smerge-mode]] that is now part of Emacs. 747 | 748 | 749 | *** Projectile 750 | Projectile is a quick and easy project management package that "just works". We're 751 | going to install it and make sure it's loaded immediately. 752 | 753 | #+BEGIN_SRC emacs-lisp 754 | (use-package projectile 755 | :ensure projectile 756 | ;; :demand t 757 | ;; :bind ("s-p" . projectile-command-map) 758 | :config 759 | (progn 760 | (setq projectile-enable-caching t) 761 | (setq projectile-require-project-root nil) 762 | (setq projectile-completion-system 'ivy) 763 | (add-to-list 'projectile-globally-ignored-files ".DS_Store") 764 | ) 765 | :defer (projectile-cleanup-known-projects) 766 | :delight '(:eval (concat "𝓟/" (projectile-project-name))) 767 | ) 768 | 769 | (use-package ivy 770 | :ensure t 771 | :config 772 | (ivy-mode 1) 773 | (setq ivy-use-virtual-buffers t) 774 | (setq enable-recursive-minibuffers t) 775 | (global-set-key (kbd "C-c C-r") 'ivy-resume) 776 | (global-set-key (kbd "") 'ivy-resume) 777 | :delight ) 778 | 779 | (use-package swiper 780 | :ensure t 781 | :config 782 | (global-set-key "\C-s" 'swiper) 783 | ) 784 | 785 | (use-package counsel 786 | :ensure t 787 | :config 788 | (global-set-key (kbd "M-x") 'counsel-M-x) 789 | (global-set-key (kbd "C-x C-f") 'counsel-find-file) 790 | (global-set-key (kbd " f") 'counsel-describe-function) 791 | (global-set-key (kbd " v") 'counsel-describe-variable) 792 | (global-set-key (kbd " l") 'counsel-find-library) 793 | (global-set-key (kbd " i") 'counsel-info-lookup-symbol) 794 | (global-set-key (kbd " u") 'counsel-unicode-char) 795 | (global-set-key (kbd "C-c g") 'counsel-git) 796 | (global-set-key (kbd "C-c j") 'counsel-git-grep) 797 | (global-set-key (kbd "C-c k") 'counsel-ag) 798 | (global-set-key (kbd "C-x l") 'counsel-locate) 799 | (define-key minibuffer-local-map (kbd "C-r") 'counsel-minibuffer-history) 800 | ) 801 | #+END_SRC 802 | 803 | *** Ido 804 | 805 | #+BEGIN_SRC emacs-lisp 806 | (use-package ibuffer 807 | :bind ("C-x C-b" . ibuffer)) 808 | 809 | (use-package ibuffer-projectile 810 | :ensure t 811 | :config 812 | (add-hook 'ibuffer-hook #'ibuffer-projectile-set-filter-groups)) 813 | 814 | (use-package ido 815 | :ensure t 816 | :init (ido-mode) 817 | :config 818 | (setq ido-enable-flex-matching t 819 | ido-completion-buffer nil 820 | ido-use-faces nil)) 821 | 822 | (use-package flx-ido 823 | :ensure t 824 | :init (flx-ido-mode)) 825 | 826 | (use-package ido-vertical-mode 827 | :ensure t 828 | :init (ido-vertical-mode)) 829 | #+END_SRC 830 | *** Undo 831 | #+BEGIN_SRC emacs-lisp 832 | (use-package undo-tree 833 | :diminish undo-tree-mode 834 | :ensure t) 835 | 836 | ;; Add parts of each file's directory to the buffer name if not unique 837 | (use-package uniquify 838 | :ensure nil 839 | :config 840 | (setq uniquify-buffer-name-style 'forward) 841 | (setq uniquify-separator "/") 842 | (setq uniquify-after-kill-buffer-p t) 843 | (setq uniquify-ignore-buffers-re "^\\*")) 844 | 845 | #+END_SRC 846 | *** Org 847 | Let's include a newer version of org-mode than the one that is built in. We're going 848 | to manually remove the org directories from the load path, to ensure the version we 849 | want is prioritized instead. 850 | 851 | #+BEGIN_SRC emacs-lisp 852 | (use-package org 853 | :ensure org-plus-contrib 854 | :delight org-mode "✎" 855 | :pin org 856 | :defer t) 857 | 858 | ;; Ensure ELPA org is prioritized above built-in org. 859 | (require 'cl) 860 | (setq load-path (remove-if (lambda (x) (string-match-p "org$" x)) load-path)) 861 | #+END_SRC 862 | 863 | *** MacOS 864 | MacOS Customisations 865 | #+BEGIN_SRC emacs-lisp 866 | ;; Are we on a mac? 867 | (setq is-mac (equal system-type 'darwin)) 868 | 869 | (when (display-graphic-p) 870 | (if is-mac 871 | (menu-bar-mode 1))) 872 | 873 | ;; Make Meta command and add Hyper. 874 | (when is-mac 875 | ;; Change command to meta. 876 | (setq mac-command-modifier 'super) 877 | (setq mac-option-modifier 'meta) 878 | ;; not sure what hyper is (setq ns-function-modifier 'hyper) 879 | 880 | ;; Use right option for special characters. 881 | ;; (setq mac-right-option-modifier 'none) 882 | 883 | ;; Remove date and battery status from modeline 884 | (display-time-mode -1) 885 | (display-battery-mode -1) 886 | 887 | 888 | ) 889 | 890 | #+END_SRC 891 | *** Toc-org 892 | Let's install and load the =toc-org= package after org mode is loaded. This is the 893 | package that automatically generates an up to date table of contents for us. 894 | 895 | #+BEGIN_SRC emacs-lisp 896 | (use-package toc-org 897 | :after org 898 | :init (add-hook 'org-mode-hook #'toc-org-enable)) 899 | #+END_SRC 900 | 901 | 902 | ** Programming 903 | *** Eldoc 904 | #+BEGIN_SRC emacs-lisp 905 | (use-package eldoc 906 | :defer t 907 | :diminish eldoc-mode) 908 | #+END_SRC 909 | *** Prettify code 910 | #+BEGIN_SRC emacs-lisp 911 | ;; ----- Base set of pretty symbols. 912 | (defvar base-prettify-symbols-alist '(("<=" . ?≤) 913 | (">=" . ?≥) 914 | ("<-" . ?←) 915 | ("->" . ?→) 916 | ("<=" . ?⇐) 917 | ("=>" . ?⇒) 918 | ("lambda" . ?λ )) 919 | ) 920 | 921 | (defun gas-lisp-prettify-symbols-hook () 922 | "Set pretty symbols for lisp modes." 923 | (setq prettify-symbols-alist base-prettify-symbols-alist)) 924 | 925 | (defun gas-js-prettify-symbols-hook () 926 | "Set pretty symbols for JavaScript." 927 | (setq prettify-symbols-alist 928 | (append '(("function" . ?ƒ)) base-prettify-symbols-alist))) 929 | 930 | (defun gas-clj-prettify-symbols-hook () 931 | "Set pretty symbols for Clojure(script)." 932 | (setq prettify-symbols-alist 933 | (append '(("fn" . λ)) base-prettify-symbols-alist))) 934 | 935 | (defun other-prettify-symbols-hook () 936 | "Set pretty symbols for non-lisp programming modes." 937 | (setq prettify-symbols-alist 938 | (append '(("==" . ?≡) 939 | ("!=" . ?≠)) 940 | base-prettify-symbols-alist))) 941 | 942 | ;; Hook 'em up. 943 | (add-hook 'emacs-lisp-mode-hook #'gas-lisp-prettify-symbols-hook) 944 | (add-hook 'web-mode-hook #'other-prettify-symbols-hook) 945 | (add-hook 'js-mode-hook #'gas-js-prettify-symbols-hook) 946 | (add-hook 'prog-mode-hook #'other-prettify-symbols-hook) 947 | (add-hook 'clojure-mode-hook #'gas-clj-prettify-symbols-hook) 948 | 949 | (global-prettify-symbols-mode 1) 950 | 951 | #+END_SRC 952 | *** Elisp 953 | #+BEGIN_SRC emacs-lisp 954 | (use-package lisp-mode 955 | :ensure nil 956 | ;; :delight "lisp" 957 | :config 958 | ;; (defun gas-visit-ielm () 959 | ;; "Switch to default `ielm' buffer. 960 | ;;Start `ielm' if it's not already running." 961 | ;; (interactive) 962 | ;; (crux-start-or-switch-to 'ielm "*ielm*")) 963 | 964 | (add-hook 'emacs-lisp-mode-hook #'eldoc-mode) 965 | (add-hook 'emacs-lisp-mode-hook #'rainbow-delimiters-mode) 966 | ;; (define-key emacs-lisp-mode-map (kbd "C-c C-z") #'gas-visit-ielm) 967 | (define-key emacs-lisp-mode-map (kbd "C-c C-c") #'eval-defun) 968 | (define-key emacs-lisp-mode-map (kbd "C-c C-b") #'eval-buffer) 969 | (add-hook 'lisp-interaction-mode-hook #'eldoc-mode) 970 | (add-hook 'eval-expression-minibuffer-setup-hook #'eldoc-mode)) 971 | 972 | (use-package ielm 973 | :config 974 | (add-hook 'ielm-mode-hook #'eldoc-mode) 975 | (add-hook 'ielm-mode-hook #'rainbow-delimiters-mode)) 976 | #+END_SRC 977 | *** Clojure 978 | lets try out aggressive-indent 979 | #+BEGIN_SRC emacs-lisp 980 | (use-package aggressive-indent 981 | :ensure t) 982 | #+END_SRC 983 | The [[https://github.com/clojure-emacs/clojure-mode][clojure-mode]] project seems to be the best (and works well with [[*Cider][Cider]]). 984 | 985 | #+BEGIN_SRC emacs-lisp 986 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 987 | ;; inferior lisp 988 | (setq inferior-lisp-program "lein figwheel") 989 | 990 | ;; inf-clojure test 991 | (use-package inf-clojure 992 | :ensure t 993 | ) 994 | 995 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 996 | ;; inf-clojure 997 | 998 | (setq inf-clojure-lein-cmd "lein figwheel") 999 | ;; minor-mode adds key-bindings 1000 | ;(add-hook 'clojure-mode-hook 'inf-clojure-minor-mode) 1001 | 1002 | (use-package clojure-mode 1003 | :ensure t 1004 | :mode ("\\.\\(clj\\|cljs\\|edn\\|boot\\)$" . clojure-mode ) 1005 | :config 1006 | (progn 1007 | (setq clojure-align-forms-automatically t) 1008 | (add-hook 'clojure-mode-hook #'company-mode) 1009 | (add-hook 'clojure-mode-hook #'linum-mode) 1010 | (add-hook 'clojure-mode-hook #'subword-mode) 1011 | ;;(add-hook 'clojure-mode-hook #'paredit-mode) 1012 | (add-hook 'clojure-mode-hook #'smartparens-strict-mode) 1013 | (add-hook 'clojure-mode-hook #'rainbow-delimiters-mode) 1014 | (add-hook 'clojure-mode-hook #'eldoc-mode)) 1015 | ;; (add-hook 'clojure-mode-hook #'idle-highlight-mode) 1016 | ;; :bind (("C-c d f" . cider-code)) 1017 | :delight "clj" 1018 | ) 1019 | 1020 | #+END_SRC 1021 | 1022 | *** Parens 1023 | 1024 | 1025 | #+BEGIN_SRC emacs-lisp 1026 | (use-package paren 1027 | :ensure nil 1028 | :config 1029 | (show-paren-mode +1)) 1030 | #+END_SRC 1031 | Use paredit 1032 | 1033 | #+BEGIN_SRC emacs-lisp 1034 | (use-package paredit 1035 | :disabled t 1036 | :delight " ⎎" 1037 | :ensure t 1038 | :config 1039 | (add-hook 'emacs-lisp-mode-hook #'paredit-mode) 1040 | ;; enable in the *scratch* buffer 1041 | (add-hook 'lisp-interaction-mode-hook #'paredit-mode) 1042 | (add-hook 'ielm-mode-hook #'paredit-mode) 1043 | (add-hook 'lisp-mode-hook #'paredit-mode) 1044 | (add-hook 'clojure-mode-hook #'paredit-mode) 1045 | (add-hook 'eval-expression-minibuffer-setup-hook #'paredit-mode)) 1046 | 1047 | #+END_SRC 1048 | 1049 | Use smartparens 1050 | #+BEGIN_SRC 1051 | (use-package smartparens 1052 | :ensure smartparens 1053 | :init (progn 1054 | (require 'smartparens) 1055 | (load-library "smartparens-config")) 1056 | 1057 | :config (progn 1058 | (smartparens-global-mode t) 1059 | (sp-local-pair 'emacs-lisp-mode "`" nil :when '(sp-in-string-p)) 1060 | (sp-with-modes '(html-mode sgml-mode nxml-mode web-mode) 1061 | (sp-local-pair "<" ">")) 1062 | :bind 1063 | (("C-M-k" . sp-kill-sexp-with-a-twist-of-lime) 1064 | ("C-M-f" . sp-forward-sexp) 1065 | ("C-M-b" . sp-backward-sexp) 1066 | ("C-M-n" . sp-up-sexp) 1067 | ("C-M-d" . sp-down-sexp) 1068 | ("C-M-u" . sp-backward-up-sexp) 1069 | ("C-M-p" . sp-backward-down-sexp) 1070 | ("C-M-w" . sp-copy-sexp) 1071 | ("M-s" . sp-splice-sexp) 1072 | ("M-r" . sp-splice-sexp-killing-around) 1073 | ("C-)" . sp-forward-slurp-sexp) 1074 | ("C-}" . sp-forward-barf-sexp) 1075 | ("C-(" . sp-backward-slurp-sexp) 1076 | ("C-{" . sp-backward-barf-sexp) 1077 | ("M-S" . sp-split-sexp) 1078 | ("M-J" . sp-join-sexp) 1079 | ("C-M-t" . sp-transpose-sexp)) 1080 | :delight " ⎎") 1081 | #+END_SRC 1082 | 1083 | use rainbow delimiters 1084 | #+BEGIN_SRC emacs-lisp 1085 | (use-package rainbow-delimiters 1086 | :ensure t) 1087 | 1088 | ;; Don't show anything for rainbow-mode. 1089 | (use-package rainbow-mode 1090 | :delight) 1091 | #+END_SRC 1092 | 1093 | #+END_SRC 1094 | *** Cider 1095 | da-bomb! 1096 | #+BEGIN_SRC emacs-lisp 1097 | (use-package cider 1098 | :ensure t 1099 | ;; :commands (cider cider-connect cider-jack-in) 1100 | :init 1101 | (setq cider-auto-select-error-buffer t 1102 | ;; go right to the REPL buffer when it's finished connecting 1103 | cider-repl-pop-to-buffer-on-connect 'display-only 1104 | cider-repl-use-clojure-font-lock t 1105 | ;; Wrap when navigating history. 1106 | cider-repl-wrap-history t 1107 | cider-repl-history-size 1000 1108 | ;; When there's a cider error, show its buffer and switch to it 1109 | cider-show-error-buffer t 1110 | cider-auto-select-error-buffer t 1111 | nrepl-hide-special-buffers t 1112 | ;; Stop error buffer from popping up while working in buffers other than the REPL: 1113 | nrepl-popup-stacktraces nil 1114 | ;; Where to store the cider history. 1115 | cider-repl-history-file "~/.emacs.d/cider-history" 1116 | ) 1117 | 1118 | :config 1119 | (progn ;; (defalias 'cji 'cider-jack-in) 1120 | (add-hook 'cider-mode-hook #'eldoc-mode) 1121 | (add-hook 'cider-repl-mode-hook #'eldoc-mode) 1122 | ;; (add-hook 'cider-repl-mode-hook #'smartparens-strict-mode) 1123 | (add-hook 'cider-repl-mode-hook #'company-mode) 1124 | (add-hook 'cider-mode-hook #'company-mode) 1125 | (add-hook 'cider-repl-mode-hook #'cider-company-enable-fuzzy-completion) 1126 | (add-hook 'cider-mode-hook #'cider-company-enable-fuzzy-completion) 1127 | ;; (add-hook 'cider-repl-mode-hook #'paredit-mode) 1128 | (add-hook 'cider-repl-mode-hook #'rainbow-delimiters-mode) 1129 | ) 1130 | :diminish (cider-mode . "☤") 1131 | ) 1132 | 1133 | (setq cider-cljs-lein-repl 1134 | "(cond 1135 | (and (resolve 'user/run) (resolve 'user/browser-repl)) ;; Chestnut projects 1136 | (eval '(do (user/run) 1137 | (user/browser-repl))) 1138 | 1139 | (try 1140 | (require 'figwheel-sidecar.repl-api) 1141 | (resolve 'figwheel-sidecar.repl-api/start-figwheel!) 1142 | (catch Throwable _)) 1143 | (eval '(do (figwheel-sidecar.repl-api/start-figwheel!) 1144 | (figwheel-sidecar.repl-api/cljs-repl))) 1145 | 1146 | (try 1147 | (require 'cemerick.piggieback) 1148 | (resolve 'cemerick.piggieback/cljs-repl) 1149 | (catch Throwable _)) 1150 | (eval '(cemerick.piggieback/cljs-repl (cljs.repl.rhino/repl-env))) 1151 | 1152 | :else 1153 | (throw (ex-info \"Failed to initialise CLJS repl. Add com.cemerick/piggieback 1154 | and optionally figwheel-sidecar to your project.\" {})))") 1155 | 1156 | 1157 | #+END_SRC 1158 | *** Javascript 1159 | JavaScript should have three parts: 1160 | - Syntax highlight (already included) 1161 | - Syntax verification (with flycheck) 1162 | - Interactive REPL ... using Skewer 1163 | 1164 | * JS2 Mode 1165 | 1166 | I like the extras found in [[http://www.emacswiki.org/emacs-test/SteveYegge][Steve Yegge]]'s [[https://github.com/mooz/js2-mode][js2-mode]]. 1167 | 1168 | #+BEGIN_SRC elisp 1169 | (use-package js2-mode 1170 | :ensure t 1171 | :interpreter ("node" . js2-mode) 1172 | :init 1173 | (setq js-basic-indent 2) 1174 | (setq-default js2-basic-indent 2 1175 | js2-basic-offset 2 1176 | js2-auto-indent-p t 1177 | js2-cleanup-whitespace t 1178 | js2-enter-indents-newline t 1179 | js2-indent-on-enter-key t 1180 | js2-global-externs (list "window" "module" "require" "buster" "sinon" "assert" "refute" "setTimeout" "clearTimeout" "setInterval" "clearInterval" "location" "__dirname" "console" "JSON" "jQuery" "$")) 1181 | 1182 | (add-hook 'js2-mode-hook 1183 | (lambda () 1184 | (push '("function" . ?ƒ) prettify-symbols-alist))) 1185 | 1186 | (add-to-list 'auto-mode-alist '("\\.js$" . js2-mode))) 1187 | #+END_SRC 1188 | 1189 | Colour /defined/ variables with [[https://github.com/ankurdave/color-identifiers-mode][color-identifiers-mode]]: 1190 | 1191 | #+BEGIN_SRC elisp 1192 | (use-package color-identifiers-mode 1193 | :ensure t 1194 | :init 1195 | (add-hook 'js2-mode-hook 'color-identifiers-mode)) 1196 | #+END_SRC 1197 | 1198 | **** Flycheck and JSHint 1199 | 1200 | While editing JavaScript is baked into Emacs, it is quite important 1201 | to have [[http://flycheck.readthedocs.org/][flycheck]] validate the source based on [[http://www.jshint.com/][jshint]], and [[https://github.com/eslint/eslint][eslint]]. 1202 | Let’s prefer =eslint=: 1203 | 1204 | #+BEGIN_SRC elisp 1205 | (add-hook 'js2-mode-hook 1206 | (lambda () (flycheck-select-checker "javascript-eslint"))) 1207 | #+END_SRC 1208 | 1209 | Now load and edit a JavaScript file, like [[file:~/jshint-code-test.js][jshint-code-test.js]]. 1210 | 1211 | **** Refactoring JavaScript 1212 | 1213 | The [[https://github.com/magnars/js2-refactor.el][js2-refactor]] mode should start with =C-c .= and then a two-letter 1214 | mnemonic shortcut. 1215 | 1216 | * =ef= is =extract-function=: Extracts the marked expressions out into a new named function. 1217 | * =em= is =extract-method=: Extracts the marked expressions out into a new named method in an object literal. 1218 | * =ip= is =introduce-parameter=: Changes the marked expression to a parameter in a local function. 1219 | * =lp= is =localize-parameter=: Changes a parameter to a local var in a local function. 1220 | * =eo= is =expand-object=: Converts a one line object literal to multiline. 1221 | * =co= is =contract-object=: Converts a multiline object literal to one line. 1222 | * =eu= is =expand-function=: Converts a one line function to multiline (expecting semicolons as statement delimiters). 1223 | * =cu= is =contract-function=: Converts a multiline function to one line (expecting semicolons as statement delimiters). 1224 | * =ea= is =expand-array=: Converts a one line array to multiline. 1225 | * =ca= is =contract-array=: Converts a multiline array to one line. 1226 | * =wi= is =wrap-buffer-in-iife=: Wraps the entire buffer in an immediately invoked function expression 1227 | * =ig= is =inject-global-in-iife=: Creates a shortcut for a marked global by injecting it in the wrapping immediately invoked function expression 1228 | * =ag= is =add-to-globals-annotation=: Creates a =/*global */= annotation if it is missing, and adds the var at point to it. 1229 | * =ev= is =extract-var=: Takes a marked expression and replaces it with a var. 1230 | * =iv= is =inline-var=: Replaces all instances of a variable with its initial value. 1231 | * =rv= is =rename-var=: Renames the variable on point and all occurrences in its lexical scope. 1232 | * =vt= is =var-to-this=: Changes local =var a= to be =this.a= instead. 1233 | * =ao= is =arguments-to-object=: Replaces arguments to a function call with an object literal of named arguments. Requires yasnippets. 1234 | * =3i= is =ternary-to-if=: Converts ternary operator to if-statement. 1235 | * =sv= is =split-var-declaration=: Splits a =var= with multiple vars declared, into several =var= statements. 1236 | * =uw= is =unwrap=: Replaces the parent statement with the selected region. 1237 | 1238 | #+BEGIN_SRC elisp 1239 | (use-package js2-refactor 1240 | :ensure t 1241 | :init (add-hook 'js2-mode-hook 'js2-refactor-mode) 1242 | :config (js2r-add-keybindings-with-prefix "C-c .")) 1243 | #+END_SRC 1244 | 1245 | **** Skewer 1246 | 1247 | I also configure Skewer for my [[file:emacs-web.org][HTML and CSS]] files, we need to do the 1248 | same for JavaScript: 1249 | 1250 | #+BEGIN_SRC elisp 1251 | (use-package skewer-mode 1252 | :ensure t 1253 | :init (add-hook 'js2-mode-hook 'skewer-mode)) 1254 | #+END_SRC 1255 | 1256 | Kick things off with =run-skewer=, and then: 1257 | 1258 | * C-x C-e :: `skewer-eval-last-expression' 1259 | * C-M-x :: `skewer-eval-defun' 1260 | * C-c C-k :: `skewer-load-buffer' 1261 | 1262 | **** JSON mode 1263 | #+BEGIN_SRC emacs-lisp 1264 | (use-package json-mode 1265 | :ensure json-mode 1266 | :config (bind-keys :map json-mode-map 1267 | ("C-c i" . json-mode-beautify)) 1268 | :mode ("\\.\\(json\\)$" . json-mode)) 1269 | 1270 | #+END_SRC 1271 | *** YAML 1272 | #+BEGIN_SRC emacs-lisp 1273 | (use-package yaml-mode 1274 | :mode ("\\.\\(yml\\|yaml\\|\\config\\|sls\\)$" . yaml-mode) 1275 | :ensure yaml-mode 1276 | :defer t) 1277 | 1278 | #+END_SRC 1279 | *** C 1280 | #+BEGIN_SRC emacs-lisp 1281 | (use-package cc-mode 1282 | :config 1283 | (progn 1284 | (add-hook 'c-mode-hook (lambda () (c-set-style "bsd"))) 1285 | (add-hook 'java-mode-hook (lambda () (c-set-style "bsd"))) 1286 | (setq tab-width 2) 1287 | (setq c-basic-offset 2))) 1288 | #+END_SRC 1289 | *** CSS 1290 | #+BEGIN_SRC emacs-lisp 1291 | (use-package css-mode 1292 | :config (setq css-indent-offset 2) 1293 | ) 1294 | #+END_SRC 1295 | *** Terraform 1296 | pretty terraform highlighting 1297 | #+BEGIN_SRC emacs-lisp 1298 | ;;(use-package terraform-mode 1299 | ;; :defer t 1300 | ;; :init 1301 | ;; (progn 1302 | ;; (require 'company-terraform) 1303 | ;; (company-terraform-init) 1304 | ;; ) 1305 | ;; :config (setq terraform-indent-level 2) 1306 | ;; ) 1307 | #+END_SRC 1308 | 1309 | #+RESULTS: 1310 | 1311 | ** Post Initialisation 1312 | Let's lower our GC thresholds back down to a sane level. 1313 | 1314 | #+BEGIN_SRC emacs-lisp 1315 | (setq gc-cons-threshold 16777216 1316 | gc-cons-percentage 0.1) 1317 | #+END_SRC 1318 | --------------------------------------------------------------------------------