Skip to content

Latest commit

 

History

History
executable file
·
666 lines (503 loc) · 20.7 KB

config.org

File metadata and controls

executable file
·
666 lines (503 loc) · 20.7 KB

Emacs configuration file

Start config:

(defvar my-config-el-start-time (current-time) "Time when config.el was started")
(setenv "PATH" (concat (getenv "PATH") ":/Users/islinger/bin"))
;(profiler-start 'cpu);; test startup performance - create report with M-x profiler-report

Package initialisation

Use use-package as much as possible so just bootstrap that to get other packages.

Bootstrap use-package

(require 'package)
(setq package-enable-at-startup nil)
(add-to-list 'package-archives
             '("melpa" . "https://melpa.org/packages/"))

(package-initialize)

;; Bootstrap `use-package'
(unless (package-installed-p 'use-package)
  (package-refresh-contents)
  (package-install 'use-package))

(eval-when-compile
  (require 'use-package))

(setq use-package-always-ensure t)

;; The default setting is too low for lsp-mode's needs due to the fact that client/server communication generates a lot of memory/garbage. 
(setq gc-cons-threshold (* 100 1000 1000))
;; Again the emacs default is too low 4k considering that the some of the language server responses are in 800k - 3M range.
(setq read-process-output-max (* 2 1024 1024)) ;; 2mb

The packages

Look ‘n’ Feel

;; Nice theme
(use-package monokai-theme 
  :config
  (load-theme 'monokai t))

;; Nice modeline from spacemacs
(use-package spaceline
  :demand t
  :init
  (setq powerline-default-separator 'arrow-fade)
  :config
  (require 'spaceline-config)
  ;; (spaceline-spacemacs-theme)
  (spaceline-emacs-theme)
  (spaceline-toggle-buffer-size-off)) 

;; Only do auto save in buffers where it is not likely to screw up a live site somewhere over tramp
(use-package real-auto-save
  :ensure t
  :config
    (add-hook 'org-mode-hook 'real-auto-save-mode)
    (setq real-auto-save-interval 7))

;; Try company mode again to get nice completion in clojure buffers
(use-package company
  :ensure t
  :diminish company-mode
  :init
  (add-hook 'cider-repl-mode-hook #'company-mode)
  (add-hook 'cider-mode-hook #'company-mode)
  :bind
  ("M-/" . company-complete-common)
  :config
  (setq company-idle-delay nil) ;; only trigger when asked?
  (global-set-key (kbd "TAB") #'company-indent-or-complete-common))

;; nice utf-8 bullets in org mode
(use-package org-bullets
  :ensure t
  :config
  (add-hook 'org-mode-hook (lambda () (org-bullets-mode 1))))

 ; nice but REALLY slows down editing
 ;(use-package smartparens
 ; :defer t
 ; :ensure t
 ; :diminish smartparens-mode
 ; :init
 ; (setq sp-override-key-bindings
 ;       '(("C-k" . sp-kill-sexp)
 ;         ("M-s" . sp-splice-exp)))
 ; :config
 ; (require 'smartparens-config)
 ; (sp-use-smartparens-bindings)
 ; (sp--update-override-key-bindings)
 ; (show-smartparens-global-mode t)
 ; (add-hook 'minibuffer-setup-hook 'turn-on-smartparens-strict-mode)
 ; :commands (smartparens-mode show-smartparens-mode))

 ;(use-package aggressive-indent
 ; :diminish aggressive-indent-mode
 ; :config
 ;   (global-aggressive-indent-mode 1)) 

;; key bindings and code colorization for Clojure
(use-package clojure-mode
   :ensure t
   :defer t
   :mode (("\\.clj\\'" . clojure-mode)
          ("\\.edn\\'" . clojure-mode)
          ("\\.cljs\\'" . clojurescript-mode))
   :init
   (add-hook 'clojure-mode-hook #'yas-minor-mode)         
   (remove-hook 'clojure-mode-hook #'subword-mode)           
   ;;(add-hook 'clojure-mode-hook #'smartparens-mode)       
   (add-hook 'clojure-mode-hook #'rainbow-delimiters-mode)
   (add-hook 'clojure-mode-hook #'eldoc-mode)
   (add-hook 'cider-mode-hook #'paredit-mode)
   (global-set-key (kbd "<f5>") 'cider-eval-defun-at-point)

   :config
   ;; _ and - are part of a word
   (modify-syntax-entry ?_ "w" clojure-mode-syntax-table)
   (modify-syntax-entry ?- "w" clojure-mode-syntax-table))


;; M-x kibit to check for style in clojure
;(use-package kibit-helper)

;; integration with a Clojure REPL
(use-package cider
  :ensure t 
  :defer t
  ; :init 
  :diminish subword-mode

  :config
  (setq nrepl-log-messages t                  
        ;;cider-repl-display-in-current-window t
        cider-repl-use-clojure-font-lock t    
        cider-prompt-save-file-on-load 'always-save
        cider-font-lock-dynamically '(macro core function var)
        nrepl-hide-special-buffers t            
        cider-overlays-use-font-lock t)
  (setq cider-cljs-lein-repl
        "(do (require 'figwheel-sidecar.repl-api)
           (figwheel-sidecar.repl-api/start-figwheel!)
           (figwheel-sidecar.repl-api/cljs-repl))"))

(use-package paredit
  :diminish paredit-mode
  :init
  (add-hook 'clojure-mode-hook 'enable-paredit-mode)
  (add-hook 'cider-repl-mode-hook 'enable-paredit-mode)
  (add-hook 'lisp-mode-hook 'enable-paredit-mode)
  (add-hook 'emacs-lisp-mode-hook 'enable-paredit-mode)
  (add-hook 'lisp-interaction-mode-hook 'enable-paredit-mode)
  (add-hook 'ielm-mode-hook 'enable-paredit-mode)
  (add-hook 'json-mode-hook 'enable-paredit-mode))


;; Project management
 ;; (use-package projectile 
 ;;  :diminish projectile-mode
 ;;  :init
 ;;    (projectile-global-mode))

;; colorful parenthesis matching
(use-package rainbow-delimiters
  :ensure
  :init
  (progn
    (add-hook 'emacs-lisp-mode-hook (lambda()
                      (rainbow-delimiters-mode t)))))

;; edit html tags like sexps
(use-package tagedit
  :defer)

(use-package web-mode
  :diminish web-mode
  :config 
    (add-to-list 'auto-mode-alist '("\\.phtml\\'" . web-mode))
    (add-to-list 'auto-mode-alist '("\\.tpl\\.php\\'" . web-mode))  
    (add-to-list 'auto-mode-alist '("\\.[agj]sp\\'" . web-mode))
    (add-to-list 'auto-mode-alist '("\\.as[cp]x\\'" . web-mode))
    (add-to-list 'auto-mode-alist '("\\.erb\\'" . web-mode))
    (add-to-list 'auto-mode-alist '("\\.mustache\\'" . web-mode))
    (add-to-list 'auto-mode-alist '("\\.djhtml\\'" . web-mode)))

;; git integration
(use-package magit
  :defer
  :config 
  (setq magit-auto-revert-mode nil))

;;; this fails on load
;;; (diminish 'auto-revert-mode)

;; On OS X, an Emacs instance started from the graphical user
;; interface will have a different environment than a shell in a
;; terminal window, because OS X does not run a shell during the
;; login. Obviously this will lead to unexpected results when
;; calling external utilities like make from Emacs.
;; This library works around this problem by copying important
;; environment variables from the user's shell.
;; https://github.com/purcell/exec-path-from-shell

;; THIS IS REALLY SLOW TO START UP! DO WE NEED IT?
;; (use-package exec-path-from-shell
;;   :ensure t
;;   :config (when (memq window-system '(mac ns))
;; 	    (exec-path-from-shell-initialize)
;;      (exec-path-from-shell-copy-envs '("PATH"))))

(use-package visual-regexp-steroids
  :diminish isearch-mode
  :ensure
  :demand
  :bind (("C-M-r" . vr/isearch-backward)
         ("C-M-s" . vr/isearch-forward)
         ("M-%" . vr/query-replace)))

(use-package yaml-mode
  :mode ("\\.\\(e?ya?\\|ra\\)ml\\'" . yaml-mode))

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

  (use-package git-gutter                                                                                              
  :ensure t                                                                                                          
  :init                                                                                                              
  (when (display-graphic-p)                                                                                          
      (use-package git-gutter-fringe                                                                                 
        :ensure t))                                                                                                  
  (global-git-gutter-mode))   

(use-package editorconfig
  :ensure t
  :config
  (editorconfig-mode 1))

Development

(use-package jinja2-mode
)

;; optional if you want which-key integration
(use-package which-key
    :config
    (which-key-mode))

(use-package lsp-mode
  :init
  ;; set prefix for lsp-command-keymap (few alternatives - "C-l", "C-c l")
  (setq lsp-keymap-prefix "M-z")
  :hook (;; replace XXX-mode with concrete major-mode(e. g. python-mode)
         (python-mode . lsp-deferred))
         :commands (lsp lsp-deferred))

(setq lsp-headerline-breadcrumb-enable nil)

;; optionally
;;(use-package lsp-ui :commands lsp-ui-mode)
;; if you are helm user
(use-package helm-lsp :commands helm-lsp-workspace-symbol)
;; if you are ivy user
;;(use-package lsp-ivy :commands lsp-ivy-workspace-symbol)
;;(use-package lsp-treemacs :commands lsp-treemacs-errors-list)

;; optionally if you want to use debugger
;;(use-package dap-mode)
;; (use-package dap-LANGUAGE) to load the dap adapter for your language






;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


Helm stuff

(use-package helm
  :bind (("M-x" . helm-M-x)
         ("M-<f5>" . helm-find-files)
         ("C-x C-b" . helm-buffers-list)
         ([S-f10] . helm-recentf)
         ("C-x C-f" . helm-find-files))

  :init
     (progn
       (setq helm-buffers-fuzzy-matching t 
             helm-buffer-max-length nil)))
     

(use-package helm-swoop)

;; (use-package helm-projectile
;;   :bind (("C-x C-b" . helm-projectile-switch-to-buffer))
;;   :init
;;     (helm-projectile-on))

;; allow helm to rifle through org buffers
(use-package helm-org-rifle)

;; Highlight and replace symbols
(use-package highlight-symbol
  :init
  (global-set-key [(control f3)] 'highlight-symbol)
  (global-set-key [f3] 'highlight-symbol-next)
  (global-set-key [(shift f3)] 'highlight-symbol-prev)
  (global-set-key [(meta f3)] 'highlight-symbol-query-replace))

Specific package setup

Org mode

(setq org-return-follows-link 1)

(setq org-hide-leading-stars t)
(setq org-startup-indented t)

;; Don't let M-Ret split lines - why would you?
(setq org-M-RET-may-split-line '((item . nil)))

;; Syntax highlighting in org code blocks
(setq org-src-fontify-natively t)

;; Hide /italic/ *bold* markers
(setq org-hide-emphasis-markers t)

Clojure

 ;; This is useful for working with camel-case tokens, like names of
 ;; Java classes (e.g. JavaClassName)
 (add-hook 'clojure-mode-hook 'subword-mode)

 ;; A little more syntax highlighting
 (use-package clojure-mode-extra-font-locking)

;;;;;;;;
;; Cider
;;;;;;;;

;; provides minibuffer documentation for the code you're typing into the repl
;;(add-hook 'cider-mode-hook 'eldoc-mode)

;; go right to the REPL buffer when it's finished connecting
;;etq cider-repl-pop-to-buffer-on-connect t)

;; ;; When there's a cider error, show its buffer and switch to it
;; (setq cider-show-error-buffer t)
;; (setq cider-auto-select-error-buffer t)

;; ;; Where to store the cider history.
;; (setq cider-repl-history-file "~/.emacs.d/cider-history")

;; Wrap when navigating history.
(setq cider-repl-wrap-history t)

;; ;; Use clojure mode for other extensions
(add-to-list 'auto-mode-alist '("\\.edn$" . clojure-mode))
(add-to-list 'auto-mode-alist '("\\.boot$" . clojure-mode))
(add-to-list 'auto-mode-alist '("\\.cljs.*$" . clojure-mode))
(add-to-list 'auto-mode-alist '("lein-env" . enh-ruby-mode))

Editing

Customizations relating to editing a buffer.

(add-to-list 'exec-path "/usr/local/bin")
(add-to-list 'exec-path "~/bin")

;; "When several buffers visit identically-named files,
;; Emacs must give the buffers distinct names. The usual method
;; for making buffer names unique adds ‘<2>’, ‘<3>’, etc. to the end
;; of the buffer names (all but one of them).
;; The forward naming method includes part of the file's directory
;; name at the beginning of the buffer name
;; https://www.gnu.org/software/emacs/manual/html_node/emacs/Uniquify.html
(use-package uniquify
  :ensure nil
  :config
  (setq uniquify-buffer-name-style 'forward))


;; Highlights matching parenthesis
(show-paren-mode 1)

;; DON'T Highlight current line except in GUI mode (later)
(global-hl-line-mode -1)

;; When you visit a file, point goes to the last place where it
;; was when you previously visited the same file.
;; http://www.emacswiki.org/emacs/SavePlace
(use-package saveplace
  :config
  (setq-default save-place t)
  ;; keep track of saved places in ~/.emacs.d/places
  (setq save-place-file (concat user-emacs-directory "places")))
  
;; use 2 spaces for tabs
(defun kill-tabs ()
  (interactive)
  (set-variable 'tab-width 2)
  (mark-whole-buffer)
  (untabify (region-beginning) (region-end))
  (keyboard-quit))

(setq electric-indent-mode nil)

;; Something overrides macro start - restore it
(global-set-key (quote [f3]) (quote start-kbd-macro))

Stuff to do only in GUI mode

Some stuff only applies in GUI mode anyway, and other stuff is because we want to keep the startup short in terminal

(if (not  (display-graphic-p))
    (message "Skipping GUI stuff in non GUI environment...")
  
;; Different size heading levels
(let* ((variable-tuple (cond ((x-list-fonts "Source Sans Pro") '(:font "Source Sans Pro"))
                             ((x-list-fonts "Lucida Grande")   '(:font "Lucida Grande"))
                             ((x-list-fonts "Verdana")         '(:font "Verdana"))
                             ((x-family-fonts "Sans Serif")    '(:family "Sans Serif"))
                             (nil (warn "Cannot find a Sans Serif Font.  Install Source Sans Pro."))))
       (base-font-color     (face-foreground 'default nil 'default))
       (headline           `(:inherit default  )))

 (custom-theme-set-faces 'user
                        `(org-level-8 ((t (,@headline ,@variable-tuple))))
                        `(org-level-7 ((t (,@headline ,@variable-tuple))))
                        `(org-level-6 ((t (,@headline ,@variable-tuple))))
                        `(org-level-5 ((t (,@headline ,@variable-tuple))))
                        `(org-level-4 ((t (,@headline ,@variable-tuple :height 1.05))))
                        `(org-level-3 ((t (,@headline ,@variable-tuple :height 1.1))))
                        `(org-level-2 ((t (,@headline ,@variable-tuple :height 1.2))))
                        `(org-level-1 ((t (,@headline ,@variable-tuple :height 1.2))))
                        `(org-document-title ((t (,@headline ,@variable-tuple :height 1.5 :underline nil))))))

  ;; Strike through for DONE items
  (setq org-fontify-done-headline t)
  (custom-set-faces
        '(org-done ((t (:foreground "PaleGreen"   
                      :weight normal
                      :strike-through t))))
        '(org-headline-done 
               ((((class color) (min-colors 16) (background dark)) 
               (:foreground "LightSalmon" :strike-through t)))))

  ;; Remove the graphical toolbar at the top.  
  (when (fboundp 'tool-bar-mode)
    (tool-bar-mode -1))
  
  ;; Don't show native OS scroll bars for buffers because they're redundant
  (when (fboundp 'scroll-bar-mode)
    (scroll-bar-mode -1))

  ;; Color Themes
  ;; Read http://batsov.com/articles/2012/02/19/color-theming-in-emacs-reloaded/
  ;; for a great explanation of emacs color themes.
  ;; https://www.gnu.org/software/emacs/manual/html_node/emacs/Custom-Themes.html
  ;; for a more technical explanation.
  (add-to-list 'custom-theme-load-path "~/.emacs.d/themes")
  (add-to-list 'load-path "~/.emacs.d/themes")
  ;;  (load-theme 'zenburn t)
  (load-theme 'wombat t)  ;; Even nicer

   ;; Highlight whole expression on paren match, not just other bracket
  (setq show-paren-style 'mixed)
  ;;;; doesn't work in emacs 26
  ;;;; (set-face-background 'show-paren-match-face "#996666")

  ;; These settings relate to how emacs interacts with your operating system
  (setq ;; makes killing/yanking interact with the clipboard
   x-select-enable-clipboard t

   ;; I'm actually not sure what this does but it's recommended?
   x-select-enable-primary t

   ;; Save clipboard strings into kill ring before replacing them.
   ;; When one selects something in another program to paste it into Emacs,
   ;; but kills something in Emacs before actually pasting it,
   ;; this selection is gone unless this variable is non-nil
   save-interprogram-paste-before-kill t

   ;; Shows all options when running apropos. For more info,
   ;; https://www.gnu.org/software/emacs/manual/html_node/emacs/Apropos.html
   apropos-do-all t

   ;; Mouse yank commands yank at point instead of at click.
   mouse-yank-at-point t
   
   ;; no bell
   ring-bell-function 'ignore)

  ;; No cursor blinking, it's distracting
  (blink-cursor-mode 0)

  ;; full path in title bar
  (setq-default frame-title-format "%b (%f)")

  ;; don't pop up font menu
  (global-set-key (kbd "s-t") '(lambda () (interactive)))

  ;; Only do this in graphics mode - random command line edits don't need it.
  ;; Keeps asking to save, clashes with main invocation of emacs
  (desktop-save-mode 1)
  
  ;; don't exit in GUI mode in case I did C-x C-c by mistake
  (setq confirm-kill-emacs 'y-or-n-p)

  ;; Nicer cursor
  (setq-default cursor-type 'bar)
  (setq default-frame-alist
        '((cursor-color . "white")))

  ;; Copy on select
  (setq mouse-drag-copy-region t)

  ;; Sane mouse scroll wheel
  (setq mouse-wheel-scroll-amount '(3))
  (setq mouse-wheel-progressive-speed nil)
  
  ;; highlight line is reasonably subtle in gui
  (global-hl-line-mode t)

  ;; Neo tree
  (use-package all-the-icons)
  (use-package neotree
  :bind
    ("<f8>" . neotree-toggle)
  :config
    ;; needs package all-the-icons
    (setq neo-theme (if (display-graphic-p) 'icons 'arrow))
    (setq neo-window-fixed-size nil)    

    ;; Disable line-numbers minor mode for neotree
    (add-hook 'neo-after-create-hook
    (lambda (&optional dummy) (display-line-numbers-mode -1)))

    ;; Every time when the neotree window is opened, let it find current
    ;; file and jump to node.
    (setq neo-smart-open t)

    ;; track ‘projectile-switch-project’ (C-c p p),
    (setq projectile-switch-project-action 'neotree-projectile-action))





  ;; Pretty face
  (set-face-attribute 'default nil :height 140)

  
  ;; increase font size for better readability
  (set-face-attribute 'default nil :height 160))

 
  ;; Nicer font on OSX
  (set-face-attribute 'default nil :family "Monospace" :weight 'Light  :height 120)
  (setq-default cursor-type 'box)
  
  ;; Set selection colour to something actually visible in this theme
  (set-face-attribute 'region nil :background "#6666")

More IJS Specific customisations

My preferences for a comfortable environment.

;; Use plists for deserialization in lsp-mode
(setq lsp-use-plists 1)

;; Auto save is ok in org mode
(setq auto-save-default nil) ;; disable by default
(setq auto-save-timeout 5)
(add-hook 'org-mode-hook #'auto-save-mode)  ;; enable in org-mode

;; Set remote user to root by default
(setq tramp-default-user "root")

;(setq cider-repl-use-pretty-printing t)

;; Set up cider for clojurescript dev
;(setq cider-cljs-lein-repl
;	"(do (require 'figwheel-sidecar.repl-api)
;         (figwheel-sidecar.repl-api/start-figwheel!)
;         (figwheel-sidecar.repl-api/cljs-repl))")

;; Mmmmmm hoopy symbols like λ in lisp
(global-prettify-symbols-mode +1)

;; Restore/undo last window config with C-c left and C-c right
(winner-mode 1)
(global-set-key (kbd "C-c <C-left>") 'winner-undo)
(global-set-key (kbd "C-c <C-right>") 'winner-redo)

;; New comment key in 25.1. M-; toggles comments sensibly
(global-set-key [remap comment-dwim] #'comment-line)

; Turn off elpy vertical bars. Yuk.
(add-hook 'elpy-mode-hook (lambda () (highlight-indentation-mode -1)))

(global-set-key (kbd "<f8>") 'other-window)

Wind up config

(message "→★ finished loading config.org in %.2fs" (float-time (time-subtract (current-time) my-config-el-start-time)))