Skip to content

Latest commit

 

History

History
729 lines (584 loc) · 22.1 KB

emacs.org

File metadata and controls

729 lines (584 loc) · 22.1 KB
;; supress debugger by default
;; (setq debug-on-error t)
(setq user-full-name "Richard Hunter"
      user-mail-address "")

Startup Config

Basic Internals

Turn off mouse interface early in startup to avoid momentary display Additionally, hide certain elements if in GUI emacs including scroll bar, tool bar and fringes

(if (fboundp 'menu-bar-mode) (menu-bar-mode -1))
(if (fboundp 'tool-bar-mode) (tool-bar-mode -1))
(if (fboundp 'scroll-bar-mode) (scroll-bar-mode -1))
(if (fboundp 'fringe-mode) (set-fringe-mode 0))
(setq initial-frame-alist '((top . 20) (left . 300) (width . 200) (height . 80)))

Require some internal libs

(require 'linum)
(require 'paren)

Activate some internal features

  • auto-compression:: automatiaclly handle decompressing/compressing of zipped files
  • column-number-mode:: display column number in the mode line
  • global-auto-revert-mode:: automatically update buffers when they are changed on disk
  • global-font-lock-mode:: syntax highlighting
  • global-hl-line-mode:: enables highlighting
  • display-line-number-mode:: display line numbers by default. See section on Line Numbers for a list of modes where this is disabled
  • show-paren-mode:: highlight matching parens/brackets etc
  • transient-mark-mode:: highlighting regions
  • which-function-mode:: display current function name in the mode line
(auto-compression-mode 1)
(column-number-mode 1)
(global-auto-revert-mode 1)
(global-font-lock-mode 1)
(global-hl-line-mode 1)
(global-display-line-numbers-mode 1)
(show-paren-mode 1)
(transient-mark-mode 1)
(which-function-mode 1)

No need to backup. Let’s be brave.

(setq backup-inhibited t
      make-backup-files nil
      auto-save-default nil
      create-lockfiles nil)

Location and settings for temp files

  • Don’t delink hardlinks
  • Use version numbers on backups
  • Automatically delete excess backuos
  • Keep only 20 versions
  • Keep only 5 old versions
(setq backup-directory-alist '(("." . "~/.emacs.d/backup"))
    backup-by-copying t
    version-control t
    delete-old-versions t
    kept-new-versions 20
    kept-old-versions 5)

Startup message and scratch buffer setup

(setq initial-scratch-message (format ";; Scratch buffer - started on %s\n\n" (current-time-string))
      inhibit-startup-message t
      inhibit-splash-screen t)

Uniquify the buffer’s name

(setq uniquify-buffer-name-style 'forward uniquify-separator "/")

Reset some standard keybindings

;; In GUI emacs, C-z minimizes window, which is useless.
;; (global-unset-key (kbd "C-z"))
;; UNDOING THIS FOR NOW, SINCE IT SWALLOWS c-Z in apple terminal

Auto refresh buffers

(global-auto-revert-mode 1)
;; Disable the *Messages* Buffer
(setq-default message-log-max nil)
(kill-buffer "*Messages*")

;; Disable the *Completions* buffer
(add-hook 'minibuffer-exit-hook
          (lambda ()
             (let ((buffer "*Completions*"))
               (and (get-buffer buffer)
                    (kill-buffer buffer)))))

GUI Emacs add env path for gui

Set PATH for GUI emacs

(setq exec-path (append exec-path '("/usr/local/bin")))
(setenv "PATH" (concat (getenv "PATH") ":/usr/local/bin"))

UX Customizations

;; don't auto split vertically
(setq split-height-threshold nil)

;; (require 'move-text)
(fset 'yes-or-no-p 'y-or-n-p)

;; replace line wrap char with whitespace
(set-display-table-slot standard-display-table 'wrap ?\ )

;; Disable tab characters in indentation
(setq-default indent-tabs-mode nil)

;; Remove extra check for killing processes
(setq confirm-kill-processes nil)

;; Don't ring the bell
(setq ring-bell-function 'ignore)


Package System Setup

Setup the package manager

(require 'package)

(setq package-user-dir (expand-file-name "~/.emacs.d/lisp/vendor"))

(setq package-archives
      '(("melpa"        . "http://melpa.org/packages/")
        ("gnu"          . "http://elpa.gnu.org/packages/")
        ("org"          . "http://orgmode.org/elpa/")))

(package-initialize)

(when (not package-archive-contents)
  (package-refresh-contents))

Install and configure use-package

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

;; Configure `use-package' prior to loading it.
(eval-and-compile
  (setq use-package-always-ensure nil)
  (setq use-package-always-defer nil)
  (setq use-package-always-demand nil)
  (setq use-package-expand-minimally nil)
  (setq use-package-enable-imenu-support t)
  (setq use-package-compute-statistics nil)
  ;; The following is VERY IMPORTANT.  Write hooks using their real name
  ;; instead of a shorter version: after-init ==> `after-init-hook'.
  ;;
  ;; This is to empower help commands with their contextual awareness,
  ;; such as `describe-symbol'.
  (setq use-package-hook-name-suffix nil))

Appearance & UI

Mouse & Scroll Preferences

Enable smooth scroll and scroll window under mouse

(setq hscroll-step 1)
(setq scroll-conservatively 1000)
(setq mouse-wheel-follow-mouse 't)
(setq use-dialog-box t)               ; only for mouse events
(setq use-file-dialog nil)

Extended Display Preferences

  • Set default size of the window frame on load
  • Padding between buffer and line number
(setq initial-frame-alist '((top . 20) (left . 300) (width . 180) (height . 70)))
(setq linum-format "%d ")

OSX Specific Settings

Improve appearance of title bar on osx GUI emacs, white on black

(add-to-list 'default-frame-alist '(ns-transparent-titlebar . t))
(add-to-list 'default-frame-alist '(ns-appearance . dark))

Default Theme

Install and configure modus-themes

By default, use modus-vivendi theme, a dark theme by the talented Prot.

(unless (package-installed-p 'modus-themes)
  (package-install 'modus-themes))
(load-theme 'modus-vivendi t)

Modeline

Custom Utility Functions

Here we add custom utility functions

;; Remove tabs
(defun untabify-buffer ()
  (interactive)
  (untabify (point-min) (point-max)))

;; Indent a region
(defun indent-buffer ()
  (interactive)
  (indent-region (point-min) (point-max)))

(defun cleanup-buffer ()
  "Perform a bunch of operations on the whitespace content of a buffer.
  Including indent-buffer, which should not be called automatically on save."
  (interactive)
  (untabify-buffer)
  (delete-trailing-whitespace)
  (indent-buffer))

(defun func/open-package-installer ()
  (interactive)
  (package-refresh-contents)
  (package-list-packages))

Custom Keybindings

Configuration

  • Make ESC quit prompts
  • set keys for Apple keyboard, for emacs in OS X unsure it works…
(global-set-key (kbd "<escape>") 'keyboard-escape-quit)

(setq mac-command-modifier 'super) ; make cmd key do super
(setq ns-function-modifier 'hyper)  ; make Fn key do Hyper

Function Key Bindings

;; [F1] -- Go to a specific line number in the current buffer (file)
(global-set-key [f1] 'goto-line)

;; [F2] -- Comment out a Marked (highlighted) region of text
(global-set-key [f2] 'comment-region)

;; [F3] -- Comment out a Marked (highlighted) region of text
(global-set-key [f3] 'uncomment-region)

;; [F4] -- Cleanup all trailing whitespace
(global-set-key [f4] 'whitespace-cleanup)

;; [F5] -- Switch to next buffer (file), burying current
(global-set-key [f5] 'bury-buffer)

;; [F8] -- Toggle Treemacs
(global-set-key [f8] 'treemacs)

Marking Regions and Navigating

;; [Ctrl+c -> TAB] -- Mark the entire file
;; Hint: Useful for auto-formatting the entire file by pressing (Ctrl+c -> TAB -> TAB)
(global-set-key (kbd "C-c TAB") 'mark-whole-buffer)

(global-set-key (kbd "<C-s-up>")     'buf-move-up)
(global-set-key (kbd "<C-s-down>")   'buf-move-down)
(global-set-key (kbd "<C-s-left>")   'buf-move-left)
(global-set-key (kbd "<C-s-right>")  'buf-move-right)
(global-set-key (kbd "M-n") (lambda() (interactive) (scroll-up 1)))
(global-set-key (kbd "M-p") (lambda() (interactive) (scroll-down 1)))

Additional Key Bindings

  • TODO: it would be nice to reorganize key bindings so they are assigned along with the packages they work on. More research neeeded on on method for this.
;; [Ctrl+c -> l -- Org store link]
;; [Ctrl+c -> a -- Org open agenda]
(define-key global-map "\C-cl" 'org-store-link)
(define-key global-map "\C-ca" 'org-agenda)
(global-set-key "\C-cc" 'org-capture)
(global-set-key "\C-cb" 'org-switchb)
(setq org-log-done t)

(global-set-key (kbd "C-c i") 'func/open-package-installer)

;; [Ctrl+c -> TAB] -- Mark the entire file
;; Hint: Useful for auto-formatting the entire file by pressing (Ctrl+c -> TAB -> TAB)
(global-set-key (kbd "C-c TAB") 'mark-whole-buffer)

;; [Ctrl+x -> Ctrl+b -- Open iBuffer instead of buffers]
(global-set-key (kbd "C-x C-b")  'ibuffer)

Completions

Orderless

Install and configure orderless a completetions framework helper. I use it in tandem with the built-in icomplete.

(unless (package-installed-p 'orderless)
  (package-install 'orderless))

(use-package orderless
  :ensure t
  :init (icomplete-mode) ; optional but recommended!
  :custom (completion-styles '(orderless)))

Buffer Move

Install buffer-move for arranging buffers

(unless (package-installed-p 'buffer-move)
  (package-install 'buffer-move))

Dired

Configuration

Setup dired the way I like it.

(require 'dired-x) ;; enable extra features by default
(setq insert-directory-program "gls" dired-use-ls-dired t)
(use-package dired
  :config
  (setq dired-dwim-target t)
  (setq dired-listing-switches
        "-GFhlva --group-directories-first --time-style=long-iso")
  ;; Note that the the syntax for `use-package' hooks is controlled by
  ;; the `use-package-hook-name-suffix' variable.  The "-hook" suffix is
  ;; not an error of mine.
  :hook ((dired-mode-hook . dired-hide-details-mode)
         (dired-mode-hook . (lambda() (display-line-numbers-mode -1)))
         (dired-mode-hook . hl-line-mode)))

Also auto refresh dired, but be quiet about it

(setq global-auto-revert-non-file-buffers t)
(setq auto-revert-verbose nil)

Custom Functions

Use “F” to open all marked files. Code lifted from here.

(eval-after-load "dired"
  '(progn
     (define-key dired-mode-map "F" 'my-dired-find-file)
     (defun my-dired-find-file (&optional arg)
       "Open each of the marked files, or the file under the point, or when prefix arg, the next N files "
       (interactive "P")
       (let* ((fn-list (dired-get-marked-files nil arg)))
         (mapc 'find-file fn-list)))))

LSP & Company

LSP

(setq package-selected-packages '(lsp-mode lsp-ui yasnippet lsp-treemacs helm-lsp company hydra avy which-key helm-xref dap-mode))
(when (cl-find-if-not #'package-installed-p package-selected-packages)
  (package-refresh-contents)
  (mapc #'package-install package-selected-packages))

(helm-mode)
(require 'helm-xref)
(define-key global-map [remap find-file] #'helm-find-files)
(define-key global-map [remap execute-extended-command] #'helm-M-x)
(define-key global-map [remap switch-to-buffer] #'helm-mini)

(which-key-mode)

;; This will turn LSP on for every programming language mode
;; For now isolate this to JavaScript (see Languages)
;; (add-hook 'prog-mode-hook #'lsp)
(setq gc-cons-threshold (* 100 1024 1024)
      read-process-output-max (* 1024 1024)
      company-idle-delay 0.0
      company-tooltip-align-annotations t
      company-minimum-prefix-length 1
      create-lockfiles nil) ;; lock files will kill `npm start'

(with-eval-after-load 'lsp-mode
  (require 'dap-chrome)
  (add-hook 'lsp-mode-hook #'lsp-enable-which-key-integration)
  (yas-global-mode))

;; don't spam my repos with logfiles
(setenv "TSSERVER_LOG_FILE" "/tmp/tsserver.log")

Additional Hooks

Prog Mode

Set the prog-mode hook. prog-mode is a major mode provided by Emacs. Typically, it is not used directly, instead many programming-related major modes are derived from this mode. Any hooks defined here will be applied to all modes that derive from it, inluding js-mode and more.

(defun hook-prog-mode ()
  "Hook for Prog mode."
  (local-set-key (kbd "C-c <right>") 'hs-show-block)
  (local-set-key (kbd "C-c <left>")  'hs-hide-block)
  (local-set-key (kbd "C-c <up>")    'hs-hide-all)
  (local-set-key (kbd "C-c <down>")  'hs-show-all)
  (hs-minor-mode t))

(add-hook 'prog-mode-hook #'hook-prog-mode)

Text Mode

Set the text-mode hook. We increase the “padding” between line numbers with the linum-format variable.

(defun hook-text-mode ()
  "Hook  for Text mode."
  ;; (linum-mode 1)
  (make-local-variable 'linum-format)
  (setq linum-format " %d "))

(add-hook 'text-mode-hook #'hook-text-mode)

Ibuffer

I prefer Ibuffer to buffer window. Pretty colors and such. The keybinding C-b is overridden to open Ibuffer instead of vanilla buffer window.

(use-package ibuffer
  :config
  (setq ibuffer-expert t)
  (setq ibuffer-display-summary nil)
  (setq ibuffer-use-other-window nil)
  (setq ibuffer-show-empty-filter-groups nil)
  (setq ibuffer-movement-cycle nil)
  (setq ibuffer-default-sorting-mode 'filename/process)
  (setq ibuffer-use-header-line t)
  (setq ibuffer-default-shrink-to-minimum-size nil)
  (setq ibuffer-formats
        '((mark modified read-only locked " "
                (name 30 30 :left :elide)
                " "
                (size 9 -1 :right)
                " "
                (mode 16 16 :left :elide)
                " " filename-and-process)
          (mark " "
                (name 16 -1)
                " " filename)))
  (setq ibuffer-saved-filter-groups nil)
  (setq ibuffer-old-time 48)
  :hook ((ibuffer-mode-hook . (lambda() (display-line-numbers-mode -1)))
  (ibuffer-mode-hook . auto-revert-mode)))

Line numbers

Disable line numbers for the following modes

(dolist (mode '(org-mode-hook
                org-agenda-mode-hook
                treemacs-mode-hook
                term-mode-hook
                eshell-mode-hook
                shell-mode-hook
                image-mode-hook
                markdown-mode-hook))
  (add-hook mode (lambda() (display-line-numbers-mode -1))))

Languages

JavaScript

;; Make it so all '.js' files auto load 'js-mode'
(add-to-list 'auto-mode-alist '("\\.js\\'" . js-mode))

;; Make it so all '.jsx' files auto load 'js-mode'
(add-to-list 'auto-mode-alist '("\\.jsx\\'" . js-mode))

(defun setup-js-mode ()
  "Setup function for JavaScript"
  (interactive)
  ;; (flycheck-mode +1)
  ;; (setq flycheck-check-syntax-automatically '(save mode-enabled))
  ;; (eldoc-mode +1)
  (company-mode +1))

(add-hook 'js-mode-hook #'setup-js-mode)

;; turn on lsp mode
(add-hook 'js-mode-hook #'lsp)

;; Use 2 spaces when tabbing HTML elements
(setq-default sgml-basic-offset 2)

;; Use 2 spaces when tabbing JS elements
(setq-default js-indent-level 2)

;; Indent switch statements normally
(setq js2-indent-switch-body t)


(setq-default flycheck-disabled-checkers '(lsp))

;; use eslint in js mode over lsp
(add-hook 'js2-mode-local-vars-hook
          (lambda ()
            (when (flycheck-may-enable-checker 'javascript-eslint)
              (flycheck-select-checker 'javascript-eslint))))

;; use eslint installed locally
(defun my/use-eslint-from-node-modules ()
  (let* ((root (locate-dominating-file
                (or (buffer-file-name) default-directory)
                "node_modules"))
         (eslint
          (and root
               (expand-file-name "node_modules/.bin/eslint"
                                 root))))
    (when (and eslint (file-executable-p eslint))
      (setq-local flycheck-javascript-eslint-executable eslint))))

(add-hook 'flycheck-mode-hook #'my/use-eslint-from-node-modules)


;; Local node modules located here

(unless (package-installed-p 'add-node-modules-path)
  (package-install 'add-node-modules-path))

(require 'add-node-modules-path)
(eval-after-load 'js-mode
  (add-hook 'js-mode-hook #'add-node-modules-path))

(unless (package-installed-p 'prettier-js)
  (package-install 'prettier-js))

;; Load prettier in js-mode
(require 'prettier-js)
(add-hook 'js-mode-hook 'prettier-js-mode)

Flycheck

(unless (package-installed-p 'flycheck)
  (package-install 'flycheck))
;; http://www.flycheck.org/manual/latest/index.html
(require 'flycheck)

;; turn on flychecking globally
;; (add-hook 'after-init-hook #'global-flycheck-mode)

YAML

(use-package yaml-mode
  :ensure t
)

Docker

Markdown

Define a function my-markdown-preview for conveniently previewing markdown files in the GitHub style.

(setq markdown-preview-stylesheets (list "~/github-markdown.css"))

(use-package markdown-mode
  :ensure t
  :mode ("\\.md\\'" . gfm-mode)
  :commands (markdown-mode gfm-mode)
  :config
  (setq markdown-command "pandoc -t html5"))
  ;;(setq markdown-command "markdown"))

(use-package simple-httpd
  :ensure t
  :config
  (setq httpd-port 7070)
  (setq httpd-host (system-name)))

(use-package impatient-mode
  :ensure t
  :commands impatient-mode)

(defun my-markdown-filter (buffer)
  (princ
   (with-temp-buffer
     (let ((tmp (buffer-name)))
       (set-buffer buffer)
       (set-buffer (markdown tmp))
       (format "<!DOCTYPE html><html><title>Markdown preview</title><link rel=\"stylesheet\" href = \"https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/3.0.1/github-markdown.min.css\"/>
<body><article class=\"markdown-body\" style=\"box-sizing: border-box;min-width: 200px;max-width: 980px;margin: 0 auto;padding: 45px;\">%s</article></body></html>" (buffer-string))))
   (current-buffer)))

(defun my-markdown-preview ()
  "Preview markdown."
  (interactive)
  (unless (process-status "httpd")
    (httpd-start))
  (impatient-mode)
  (imp-set-user-filter 'my-markdown-filter)
  (imp-visit-buffer))

Org Mode

(use-package org-bullets
  :ensure t
  :after org
  :hook (org-mode . org-bullets-mode)
  :custom
  (org-bullets-bullet-list '("" "" "" "" "" "" "")))

;; load language support
(org-babel-do-load-languages
 'org-babel-load-languages
 '((emacs-lisp . t)
   (python . t)
   (shell . t)))


(setq org-todo-keywords
      '((sequence "TODO" "IN PROGRESS" "|" "DONE")))

;; set maximum indentation for description lists
(setq org-list-description-max-indent 5)

;; set up display of org mode docs

(defun org-mode-visual-fill ()
  (setq visual-fill-column-width 160
        visual-fill-column-center-text t
        visual-fill-column-mode 1))


(unless (package-installed-p 'visual-fill-column)
  (package-install 'visual-fill-column))

(use-package visual-fill-column
  :defer t
  :hook (org-mode-hook . org-mode-visual-fill))

;; Set up
(defun org-mode-setup ()
  (org-bullets-mode)
  (org-indent-mode)
  (visual-line-mode 1)
  )

(use-package org
  :hook ((org-mode-hook . org-mode-setup))
  :config
  (setq org-ellipsis ""))

Mac OSX terminal swallows some keybindings, redefine

(global-set-key (kbd "C-c y") 'org-insert-structure-template)

Magit

Pull magit and launch it with C-x g

(use-package magit
  :ensure t
)

;; (unless (package-installed-p 'magit)
;;   (package-install 'magit))

(global-set-key (kbd "C-x g") 'magit-status)

Custom Interface Interactions

;; (unless (package-installed-p 'goto-last-change)
;;   (package-install 'goto-last-change))

;; (use-package goto-last-change
;;   ;; :straight t
;;   :bind ("C-z" . goto-last-change))

Bootstrap

We create a bootstrap file to load all the lisp files that were generated by the code blocks above

(add-to-list 'load-path "~/.emacs.d/lisp")
(load-library "common")
(load-library "packages")
(load-library "hooks")
(load-library "keybindings")

All we can do is try.