danieljamesross / emacs.d

My emacs config

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

org-init

This is my initialisation file for Emacs. Behold!, the code blocks will be compiled at startup, but not these titles or this text.

Optimisations

(setq ;; gc-cons-threshold (* 100 1024 1024)
 read-process-output-max (* 1024 1024)
 create-lockfiles nil ;; lock files will kill `npm start'
 warning-suppress-log-types '((comp) (server)))

Customisations

ace-jump-mode

(use-package ace-jump-mode
  :bind ("C-=" . ace-jump-mode))

autofill

(setq-default fill-column 80)
(toggle-text-mode-auto-fill)
(add-hook 'prog-mode-hook 'turn-on-auto-fill)
(remove-hook 'nxml-mode-hook #'turn-on-auto-fill)
(remove-hook 'jinja2-mode-hook #'turn-on-auto-fill)
(remove-hook 'yaml-mode-hook #'turn-on-auto-fill)

backups

(setq backup-directory-alist
      `(("." . ,(concat user-emacs-directory "backups"))))

case

(put 'downcase-region 'disabled nil)
(put 'upcase-region 'disabled nil)

custom file

(setq custom-file (expand-file-name (concat user-emacs-directory "djr-custom.el")))
(when (file-exists-p custom-file) (load custom-file))

debug

(setq debug-on-error t)

delete

(delete-selection-mode 1)

smart-hungry-delete

;; https://github.com/hrehfeld/emacs-smart-hungry-delete
(use-package smart-hungry-delete
  :bind (("<backspace>" . smart-hungry-delete-backward-char)
         ("<deletechar>" . smart-hungry-delete-forward-char))
  :defer nil ;; dont defer so we can add our functions to hooks
  :config (when (internet-up-p) (smart-hungry-delete-add-default-hooks)))

expand-region

(use-package expand-region
  :bind ("C-`" . er/expand-region))

hippie-expand

(global-set-key [remap dabbrev-expand] 'hippie-expand)

keychord

https://github.com/emacsmirror/emacswiki.org/blob/master/key-chord.el

;; (let ((key-chord (expand-file-name (concat user-emacs-directory "key-chord/")))
;;       (key-chord-repo "https://github.com/emacsmirror/emacswiki.org/blob/master/key-chord.el"))
;;   (check-file-exists-or-clone key-chord key-chord-repo)
;;   (use-package key-chord
;;     :load-path "key-chord/"
;;     :init (key-chord-mode 1)))

open bookmark other frame

(defun my-bookmark-jump-other-frame (bookmark)
  "Jump to BOOKMARK in another frame.  See `bookmark-jump' for more."
  (interactive
   (list (bookmark-completing-read "Jump to bookmark (in another frame)"
                                   bookmark-current-bookmark)))
  (bookmark-jump bookmark 'switch-to-buffer-other-frame))

(global-set-key (kbd "C-x C-5 b") 'my-bookmark-jump-other-frame)

Meta & Escape keys

(set-variable 'meta-flag 't)
(define-key esc-map "?" 'describe-key-briefly)

Move beginning/end of line

(defun xah-beginning-of-line-or-block ()
  "Move cursor to beginning of line or previous paragraph.

• When called first time, move cursor to beginning of char in current line. (if already, move to beginning of line.)
• When called again, move cursor backward by jumping over any sequence of whitespaces containing 2 blank lines.

URL `http://ergoemacs.org/emacs/emacs_keybinding_design_beginning-of-line-or-block.html'
Version 2017-05-13"
  (interactive)
  (let (($p (point)))
    (if (or (equal (point) (line-beginning-position))
            (equal last-command this-command ))
        (if (re-search-backward "\n[\t\n ]*\n+" nil "NOERROR")
            (progn
              (skip-chars-backward "\n\t ")
              (forward-char ))
          (goto-char (point-min)))
      (progn
        (back-to-indentation)
        (when (eq $p (point))
          (beginning-of-line))))))

(defun xah-end-of-line-or-block ()
  "Move cursor to end of line or next paragraph.

• When called first time, move cursor to end of line.
• When called again, move cursor forward by jumping over any sequence of whitespaces containing 2 blank lines.

URL `http://ergoemacs.org/emacs/emacs_keybinding_design_beginning-of-line-or-block.html'
Version 2017-05-30"
  (interactive)
  (if (or (equal (point) (line-end-position))
          (equal last-command this-command ))
      (progn
        (re-search-forward "\n[\t\n ]*\n+" nil "NOERROR" ))
    (end-of-line)))

(global-set-key (kbd "C-a") 'xah-beginning-of-line-or-block)
(global-set-key (kbd "C-e") 'xah-end-of-line-or-block)

open in another App

(defun xah-open-in-external-app (&optional @fname)
  "Open the current file or dired marked files in external app.
   When called in emacs lisp, if @fname is given, open that.
   URL `http://ergoemacs.org/emacs/emacs_dired_open_file_in_ext_apps.html'
   Version 2019-11-04 2021-02-16"
  (interactive)
  (let* (
         ($file-list
          (if @fname
              (progn (list @fname))
            (if (string-equal major-mode "dired-mode")
                (dired-get-marked-files)
              (list (buffer-file-name)))))
         ($do-it-p (if (<= (length $file-list) 5)
                       t
                     (y-or-n-p "Open more than 5 files? "))))
    (when $do-it-p
      (cond
       ((string-equal system-type "windows-nt")
        (mapc
         (lambda ($fpath)
           (shell-command
            (concat "PowerShell -Command \"Invoke-Item -LiteralPath\" "
                    "'"
                    (shell-quote-argument (expand-file-name $fpath )) "'")))
         $file-list))
       ((string-equal system-type "darwin")
        (mapc
         (lambda ($fpath)
           (shell-command
            (concat "open " (shell-quote-argument $fpath))))
         $file-list))
       ((string-equal system-type "gnu/linux")
        (mapc
         (lambda ($fpath) (let ((process-connection-type nil))
                            (start-process "" nil "xdg-open" $fpath)))
         $file-list))))))
(global-set-key (kbd "C-s-o") 'xah-open-in-external-app)

quit

(setq confirm-kill-processes nil)

(defun kill-all-processes ()
  (mapcar 'delete-process (process-list)))

(add-hook 'kill-emacs-hook 'kill-all-processes)

reveal in osx finder

(use-package reveal-in-osx-finder
  :if (eq system-type 'darwin)
  :bind ("C-c o" . reveal-in-osx-finder))

recentf

(recentf-mode 1)

Rainbow delimiters

(use-package rainbow-delimiters
  :hook (prog-mode-hook . rainbow-delimiters-mode))
;;                                       ; (lisp-mode-hook . rainbow-delimiters-mode)
;; :config (cl-loop for index from 1 to rainbow-delimiters-max-face-count
;;                  do
;;                  (let ((face
;;                         (intern (format "rainbow-delimiters-depth-%d-face" index))))
;;                    (cl-callf color-saturate-name (face-foreground face) 30))))

save

;; Persist history over Emacs restarts. Vertico sorts by history position.
(use-package savehist
  :init
  (savehist-mode))

saveplace

(require 'saveplace)
(setq-default save-place t)
(setq make-backup-files nil)

search

(setq case-fold-search t)

startup

(setq inhibit-startup-buffer-menu t
      inhibit-startup-screen t
      initial-scratch-message nil)

tabs & indent

(setq standard-indent 2
      js-indent-level 2)
(setq-default indent-tabs-mode nil)
(setq-default tab-always-indent 'complete)
(global-set-key (kbd "S-M-t") 'indent-rigidly-left)

iedit

(use-package iedit
  :bind ("C-:" . iedit-mode))

Views

all-the-icons

(use-package all-the-icons-ibuffer
  :hook (ibuffer-mode . all-the-icons-ibuffer-mode))

(use-package all-the-icons
  :defer nil
  :init (when (and (internet-up-p)
                   (not (member "all-the-icons" (font-family-list))))
          (all-the-icons-install-fonts t)))

(defun load-all-the-icons-dired ()
  (interactive)
  (let ((icons-dired (expand-file-name (concat user-emacs-directory "all-the-icons-dired/")))
        (icons-repo "https://github.com/jtbm37/all-the-icons-dired.git"))
    (check-file-exists-or-clone icons-dired icons-repo)
    (add-to-list 'load-path icons-dired)
    (load (concat icons-dired "all-the-icons-dired.el")))
  (all-the-icons-dired-mode 1))

(add-hook 'dired-mode-hook 'load-all-the-icons-dired)

dimmer-mode

(use-package dimmer
  :if window-system
  :defer 1
  :config
  (setq dimmer-exclusion-predicates
        '(helm--alive-p window-minibuffer-p echo-area-p))
  (setq dimmer-exclusion-regexp-list
        '("^\\*[h|H]elm.*\\*" "^\\*Minibuf-[0-9]+\\*"
          "^.\\*which-key\\*$" "^*Messages*" "*LV*"
          "^*[e|E]cho [a|A]rea 0*" "*scratch*"
          "transient"))
  (dimmer-mode t))

doom-themes

(use-package doom-themes
  :config
  ;; Global settings (defaults)
  (setq doom-themes-enable-bold t    ; if nil, bold is universally disabled
        doom-themes-enable-italic t) ; if nil, italics is universally disabled
  (load-theme 'doom-monokai-pro t)

  ;; Enable flashing mode-line on errors
  (doom-themes-visual-bell-config)
  ;; Enable custom neotree theme (all-the-icons must be installed!)
  (doom-themes-neotree-config)
  ;; or for treemacs users
  (setq doom-themes-treemacs-theme "doom-atom") ; use "doom-colors" for less minimal icon theme
  (doom-themes-treemacs-config)
  ;; Corrects (and improves) org-mode's native fontification.
  (doom-themes-org-config))

doom-mode-line

(use-package doom-modeline
  :after (doom-themes all-the-icons)
  :hook (after-init . doom-modeline-mode))

fast-scroll

(use-package fast-scroll)

Fonts

UTF-8

;;; utf-8
(setq locale-coding-system 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(set-selection-coding-system 'utf-8)
(prefer-coding-system 'utf-8)

Unicode

;; (use-package unicode-fonts
;;   :config
;;   (unicode-fonts-setup))

fira-code-mode

Taken from here

;; (use-package fira-code-mode
;;   :ensure t
;;   :if window-system
;;   :custom (fira-code-mode-disabled-ligatures '("[]" "x"))  ; ligatures you don't want
;;   :hook prog-mode)

Ligatures

(let ((lig-path (expand-file-name (concat user-emacs-directory "ligature/")))
      (lig-repo "https://github.com/mickeynp/ligature.el.git"))
  (check-file-exists-or-clone lig-path lig-repo)
  (use-package ligature
    :if window-system
    :load-path "ligature"
    :config 
    ;; Enable the "www" ligature in every possible major mode
    (ligature-set-ligatures 't '("www"))
    ;; Enable traditional ligature support in eww-mode, if the
    ;; `variable-pitch' face supports it
    (ligature-set-ligatures 'eww-mode '("ff" "fi" "ffi"))
    ;; Enable all Cascadia Code ligatures in programming modes
    (ligature-set-ligatures 'prog-mode '("|||>" "<|||" "<==>" "<!--" "####" "~~>" "***" "||=" "||>"
                                         ":::" "::=" "=:=" "===" "==>" "=!=" "=>>" "=<<" "=/=" "!=="
                                         "!!." ">=>" ">>=" ">>>" ">>-" ">->" "->>" "-->" "---" "-<<"
                                         "<~~" "<~>" "<*>" "<||" "<|>" "<$>" "<==" "<=>" "<=<" "<->"
                                         "<--" "<-<" "<<=" "<<-" "<<<" "<+>" "</>" "###" "#_(" "..<"
                                         "..." "+++" "/==" "///" "_|_" "www" "&&" "^=" "~~" "~@" "~="
                                         "~>" "~-" "**" "*>" "*/" "||" "|}" "|]" "|=" "|>" "|-" "{|"
                                         "[|" "]#" "::" ":=" ":>" ":<" "$>" "==" "=>" "!=" "!!" ">:"
                                         ">=" ">>" ">-" "-~" "-|" "->" "--" "-<" "<~" "<*" "<|" "<:"
                                         "<$" "<=" "<>" "<-" "<<" "<+" "</" "#{" "#[" "#:" "#=" "#!"
                                         "##" "#(" "#?" "#_" "%%" ".=" ".-" ".." ".?" "+>" "++" "?:"
                                         "?=" "?." "??" ";;" "/*" "/=" "/>" "//" "__" "~~" "(*" "*)"
                                         "\\\\" "://"))
    ;; Enables ligature checks globally in all buffers. You can also do it
    ;; per mode with `ligature-mode'.
    (global-ligature-mode t)))

Fonts

<<fonts>>

(check-font-exists-or-download
 "Hack Nerd Font Mono"
 "https://github.com/pyrho/hack-font-ligature-nerd-font.git"
 13)

Emoji

;; set font for emoji
(when window-system
  (set-fontset-font
   t
   '(#x1f300 . #x1fad0)
   (cond
    ((member "Noto Color Emoji" (font-family-list)) "Noto Color Emoji")
    ((member "Noto Emoji" (font-family-list)) "Noto Emoji")
    ((member "Segoe UI Emoji" (font-family-list)) "Segoe UI Emoji")
    ((member "Symbola" (font-family-list)) "Symbola")
    ((member "Apple Color Emoji" (font-family-list)) "Apple Color Emoji"))
   ;; Apple Color Emoji should be before Symbola, but Richard Stallman disabled it.
   ;; GNU Emacs Removes Color Emoji Support on the Mac
   ;; http://ergoemacs.org/misc/emacs_macos_emoji.html
   ;;
   ))

highlight-indent-guides

Take from here

(use-package highlight-indent-guides
  :if window-system
  :config (setq highlight-indent-guides-character-face "Fira Code Symbol"
                highlight-indent-guides-method 'bitmap
                highlight-indent-guides-auto-character-face-perc 10)
  :hook (prog-mode-hook . highlight-indent-guides-mode))

line-num, highlight, toolbar & fringe

(fringe-mode '(nil . 0))
(tool-bar-mode -1)
(global-hl-line-mode 1)
(set-face-background hl-line-face "OrangeRed4")
(global-display-line-numbers-mode 1)

narrow-to-page

(put 'narrow-to-page 'disabled nil)

prettify-symbols-mode

(global-prettify-symbols-mode 1)
(setq prettify-symbols-alist
      '(("lambda" . 955)))

telephone-line

;; (use-package telephone-line
;;   :if window-system
;;   :ensure t
;;   :config (setq telephone-line-lhs
;;                 '((accent . (telephone-line-vc-segment
;;                              telephone-line-erc-modified-channels-segment
;;                              telephone-line-process-segment))
;;                   (nil    . (telephone-line-buffer-segment
;;                              telephone-line-minor-mode-segment
;;                              )))
;;                 telephone-line-rhs
;;                 '((nil    . (telephone-line-misc-info-segment))
;;                   (accent . (telephone-line-major-mode-segment)))))
;; (telephone-line-mode t)

whitespace

(progn
  ;; Make whitespace-mode with very basic background coloring for whitespaces.
  ;; http://ergoemacs.org/emacs/whitespace-mode.html
  (setq whitespace-style (quote (face spaces tabs newline space-mark tab-mark )))

  ;; Make whitespace-mode and whitespace-newline-mode use “¶” for end of line char and “▷” for tab.
  (setq whitespace-display-mappings
        ;; all numbers are unicode codepoint in decimal. e.g. (insert-char 182 1)
        '(
          (space-mark 32 [183] [46]) ; SPACE 32 「 」, 183 MIDDLE DOT 「·」, 46 FULL STOP 「.」
          (newline-mark 10 [182 10]) ; LINE FEED,
          (tab-mark 9 [9655 9] [92 9]) ; tab
          )))
(global-whitespace-mode 1)

whitespace-cleanup-mode

(use-package whitespace-cleanup-mode
  :config (setq 'whitespace-cleanup-mode t)
  :hook (prog-mode . whitespace-cleanup))

tree-sitter

;; (use-package tree-sitter
;;   :init (global-tree-sitter-mode 1))

(use-package tree-sitter-langs
  :after tree-sitter)

(with-eval-after-load
    'tree-sitter-langs (tree-sitter-require 'tsx)
    'tree-sitter-langs (tree-sitter-require 'json)
    (add-to-list 'tree-sitter-major-mode-language-alist '(web-mode . tsx))
    (add-to-list 'tree-sitter-major-mode-language-alist '(json-mode . json)))

too-long-mode

(global-so-long-mode 1)

transpose-frame

(use-package transpose-frame
  :if window-system
  :bind ("C-x tf" . transpose-frame))

y-or-no-p

(fset 'yes-or-no-p 'y-or-n-p)

zoom mode

(custom-set-variables
 '(zoom-mode t))

Packages and Managers

Quelpa

(use-package quelpa
  :if window-system)

(use-package quelpa-use-package
  :if window-system
  :after quelpa)

Update

(use-package auto-package-update
  :config
  (setq auto-package-update-delete-old-versions t)
  (setq auto-package-update-hide-results t)
  (when (internet-up-p
         (auto-package-update-maybe))))

Non Elpa/Melpa Package Modes

antesc-mode

(let ((antesc-path (concat user-emacs-directory "antesc-mode-master/")))
  (check-file-exists-or-clone antesc-path "https://github.com/programLyrique/antesc-mode.git")
  ;; Antescofo text highlighting
  ;; Thanks to Pierre Donat-Bouillud
  ;; https://github.com/programLyrique/antesc-mode
  (add-to-list 'load-path (expand-file-name antesc-path))
  ;; (autoload 'antesc-mode "antesc-mode" "Major mode for editing Antescofo code" t)

  ;; Extensions for antescofo mode
  (setq auto-mode-alist
        (append '(("\\.\\(score\\|asco\\)\\.txt$" . antesc-mode))
                auto-mode-alist)))

lilypond-mode

(let ((lily-path (concat user-emacs-directory "lilypond-mode/")))
  (check-file-exists-or-clone lily-path "https://github.com/jmgpena/lilypond-mode.git")
  ;; (add-to-list 'load-path (expand-file-name lily-path))
  ;; (load (expand-file-name (concat lily-path "lilypond-init.el")))
  ;; (setq auto-mode-alist (append '(("\\.ly\\'" . lilypond-mode))
  ;;                               auto-mode-alist))

  (use-package lilypond
    :load-path "lilypond-mode/lilypond-init.el"
    :defer t
    :mode "\\.ly\\'"))

kintaro-mode

;; (let ((kintaro-path (concat user-emacs-directory "kintaro-mode")))
;;   (check-file-exists-or-clone kintaro-path "https://github.com/danieljamesross/kintaro-mode.git")
;;   (setq load-path (cons (expand-file-name kintaro-path) load-path))
;;   (require 'kintaro-mode)
;;   (add-to-list 'auto-mode-alist '("\\.ksdl\\'" . kintaro-mode)))

Files, paths, buffers

File Types & modes

(setq auto-mode-alist
      (append '(("\\.c\\'"       . c-mode)
                ("\\.cs\\'"      . csharp-mode)
                ("\\.txt\\'"     . text-mode)
                ("\\.md\\'"      . markdown-mode)
                ("\\.cpp\\'"     . c++-mode)
                ("\\.CPP\\'"     . c++-mode)
                ("\\.h\\'"       . c-mode)
                ("\\.lsp\\'"     . lisp-mode)
                ("\\.cl\\'"      . lisp-mode)
                ("\\.cm\\'"      . lisp-mode)
                ("\\.lisp\\'"    . lisp-mode)
                ("\\.clm\\'"     . lisp-mode)
                ("\\.ins\\'"     . lisp-mode)
                ("\\.el\\'"      . emacs-lisp-mode)
                ("\\.el.gz\\'"   . emacs-lisp-mode)
                ("\\.ws\\'"      . lisp-mode)
                ("\\.asd\\'"     . lisp-mode)
                ("\\.yaml\\'"    . yaml-mode)
                ("\\.py\\'"      . python-mode)
                ("\\.tex\\'"     . latex-mode)
                ("\\.cls\\'"     . latex-mode)
                ("\\.java\\'"    . java-mode)
                ("\\.ascii\\'"   . text-mode)
                ("\\.sql\\'"     . sql-mode)
                ("\\.pl\\'"      . perl-mode)
                ("\\.php\\'"     . php-mode)
                ("\\.jxs\\'"     . shader-mode)
                ("\\.sh\\'"      . shell-mode)
                ("\\.gnuplot\\'" . shell-mode)
                ("\\.svg\\'"     . nxml-mode)
                ("\\.mdx\\'"     . markdown-mode))
              auto-mode-alist))

iBuffer & Dired

iBuffer

(setq ibuffer-saved-filter-groups
      '(("home"
         ("GIT" (or (name . "^magit")
                    (name . "^ediff")
                    (name . "\\.git")))
         ("jsx/tsx" (or (name . "\\.jsx")
                        (name . "\\.tsx")))
         ("js/ts" (or (name . "\\.js")
                      (name . "\\.mjs")
                      (name . "\\.cjs")
                      (name . "\\.ts")))
         ("Web" (or (mode . html-mode)
                        (name . "\\.html")
                        (name . "\\.njk")
                        (mode . jinja2-mode)))
         ("CSS" (or (mode . css-mode)
                    (mode . scss-mode)
                    (mode . sass-mode)
                    (name . "\\.css")
                    (name . "\\.scss")
                    (name . "\\.sass")))
         ("C" (or (mode . c++-mode)
                  (mode . c-mode)))
         ("Python" (or (mode . python-mode)
                       (name . "\\.py")))
         ("JSON/YAML/Config" (or (mode . json-mode)
                                 (name . "\\.json")
                                 (mode . yaml-mode)
                                 (name . "\\.yaml")
                                 (mode . kintaro-mode)
                                 (name . "\\.ksdl")))
         ("SVG" (name . "\\.svg"))
         ("ERC" (mode . erc-mode))
         ("find" (or (mode . xref-mode)
                     (mode . dired-mode)))
         ("emacs-config" (or (name . "emacs-config")
                             (name . "djr-init")
                             (name . "README.org")
                             (name . "init.el")))
         ("Org" (mode . org-mode))
         ("lisp" (or (name . "\\.lisp")
                     (name . "\\.lsp")
                     (name . "\\.el")
                     (name . "\\.asd")
                     (name . "\\.clm")
                     (mode . lisp-mode)))
         ("Shell Scripts" (or (name . "\\.sh")
                              (mode . "sh-mode")))
         ("Shells/Terminals/REPLs" (or (name . "\\*eshell\\*")
                                       (name . "\\*terminal\\*")
                                       (name . "\\*slime-repl sbcl\\*")
                                       (name . "\\*shell\\*")
                                       (name . "\\*vterm")))
         ("Logs" (or (name . "\\*Messages\\*")
                     (name . "\\*slime-events\\*")
                     (name . "\\*inferior-lisp\\*")
                     (name . "\\*lsp")
                     (name . "\\*jsts")
                     (name . "\\*tide")
                     (name . "\\*eslint")))
         ("Help" (or (name . "\\*Help\\*")
                     (name . "\\*Apropos\\*")
                     (name . "\\*Completions\\*")
                     (name . "\\*info\\*")))
         ("Misc" (or  (name . "untitled")
                      (name . "\\*scratch\\*"))))))
(setq ibuffer-expert t
      ibuffer-show-empty-filter-groups nil)
(add-hook 'ibuffer-mode-hook
          #'(lambda ()
              (ibuffer-auto-mode 1)
              (ibuffer-switch-to-saved-filter-groups "home")))
(setq dired-auto-revert-buffer t
      auto-revert-verbose nil)

Dired

(setq dired-sidebar-icon-scale 0.1
      dired-sidebar-mode-line-format
      '("%e" mode-line-front-space mode-line-buffer-identification " " mode-line-end-spaces)
      dired-sidebar-recenter-cursor-on-tui-update nil
      dired-sidebar-should-follow-file t
      dired-sidebar-toggle-hidden-commands '(rotate-windows toggle-window-split balance-windows)
      dired-dwim-target t)
(put 'dired-find-alternate-file 'disabled nil)
(add-hook 'dired-mode-hook
      (lambda ()
        (dired-hide-details-mode)))
Dired Rainbow
(use-package dired-rainbow
  :if window-system
  :defer 2
  :config
  (progn
    (dired-rainbow-define-chmod directory "#6cb2eb" "d.*")
    (dired-rainbow-define html "#eb5286" ("css" "less" "sass" "scss" "htm" "html" "jhtm" "mht" "eml" "mustache" "xhtml"))
    (dired-rainbow-define js "#ff1493" ("js" "jsx" "ts" "tsx" "mjs" "cjs"))
    (dired-rainbow-define xml "#f2d024" ("xml" "xsd" "xsl" "xslt" "wsdl" "bib" "json" "msg" "pgn" "rss" "yaml" "yml" "rdata"))
    (dired-rainbow-define document "#9561e2" ("docm" "doc" "docx" "odb" "odt" "pdb" "pdf" "ps" "rtf" "djvu" "epub" "odp" "ppt" "pptx"))
    (dired-rainbow-define markdown "#ffed4a" ("org" "etx" "info" "markdown" "md" "mkd" "nfo" "pod" "rst" "tex" "textfile" "txt"))
    (dired-rainbow-define database "#6574cd" ("xlsx" "xls" "csv" "accdb" "db" "mdb" "sqlite" "nc"))
    (dired-rainbow-define media "#de751f" ("mp3" "mp4" "mkv" "MP3" "MP4" "avi" "mpeg" "mpg" "flv" "ogg" "mov" "mid" "midi" "wav" "aiff" "flac"))
    (dired-rainbow-define image "#f66d9b" ("tiff" "tif" "cdr" "gif" "ico" "jpeg" "jpg" "png" "psd" "eps" "svg"))
    (dired-rainbow-define log "#c17d11" ("log"))
    (dired-rainbow-define shell "#f6993f" ("awk" "bash" "bat" "sed" "sh" "zsh" "vim"))
    (dired-rainbow-define interpreted "#38c172" ("py" "ipynb" "rb" "pl" "t" "msql" "mysql" "pgsql" "sql" "r" "clj" "cljs" "scala" "js"))
    (dired-rainbow-define compiled "#4dc0b5" ("asm" "cl" "lisp" "el" "c" "h" "c++" "h++" "hpp" "hxx" "m" "cc" "cs" "cp" "cpp" "go" "f" "for" "ftn" "f90" "f95" "f03" "f08" "s" "rs" "hi" "hs" "pyc" ".java"))
    (dired-rainbow-define executable "#8cc4ff" ("exe" "msi"))
    (dired-rainbow-define compressed "#51d88a" ("7z" "zip" "bz2" "tgz" "txz" "gz" "xz" "z" "Z" "jar" "war" "ear" "rar" "sar" "xpi" "apk" "xz" "tar"))
    (dired-rainbow-define packaged "#faad63" ("deb" "rpm" "apk" "jad" "jar" "cab" "pak" "pk3" "vdf" "vpk" "bsp"))
    (dired-rainbow-define encrypted "#ffed4a" ("gpg" "pgp" "asc" "bfe" "enc" "signature" "sig" "p12" "pem"))
    (dired-rainbow-define fonts "#6cb2eb" ("afm" "fon" "fnt" "pfb" "pfm" "ttf" "otf"))
    (dired-rainbow-define partition "#e3342f" ("dmg" "iso" "bin" "nrg" "qcow" "toast" "vcd" "vmdk" "bak"))
    (dired-rainbow-define vc "#0074d9" ("git" "gitignore" "gitattributes" "gitmodules"))
    (dired-rainbow-define-chmod executable-unix "#38c172" "-.*x.*")))

ls

(when (string= system-type "darwin")
  (setq dired-use-ls-dired nil))

exec-path-from-shell

(use-package exec-path-from-shell
  :if (memq window-system '(mac ns x))
  :config (setq default-directory (expand-file-name "~/"))
  (setenv "SHELL" "/bin/zsh")
  (if (and (fboundp 'native-comp-available-p)
           (native-comp-available-p))
      (progn
        (message "Native comp is available")
        ;; Using Emacs.app/Contents/MacOS/bin since it was compiled with
        ;; ./configure --prefix="$PWD/nextstep/Emacs.app/Contents/MacOS"
        (add-to-list 'exec-path (concat invocation-directory "bin") t)
        (setenv "LIBRARY_PATH" (concat (getenv "LIBRARY_PATH")
                                       (when (getenv "LIBRARY_PATH")
                                         ":")
                                       ;; This is where Homebrew puts gcc libraries.
                                       (car (file-expand-wildcards
                                             (expand-file-name "/usr/local/opt/gcc/lib/gcc/*")))))
        ;; Only set after LIBRARY_PATH can find gcc libraries.
        (setq comp-deferred-compilation t))
    (message "Native comp is *not* available"))
  (add-to-list 'exec-path default-directory)
  (add-to-list 'exec-path user-emacs-directory)
  (add-to-list 'exec-path (expand-file-name "~/.local/bin"))
  (exec-path-from-shell-initialize))

Buffers and Frames

buffer boundaries

(setq indicate-buffer-boundaries 'left)

Buffer opening

;; ignore case when switching buffers with C-x b
(setq read-buffer-completion-ignore-case t)

buffer-move

(use-package buffer-move
  :bind (("s-C-<up>" . buf-move-up)
         ("s-C-<down>" . buf-move-down)
         ("s-C-<left>" . buf-move-left)
         ("s-C-<right>" . buf-move-right)))

Frames

(when (display-graphic-p)
  (add-to-list 'initial-frame-alist '(fullscreen . maximized))
  (add-to-list 'default-frame-alist '(fullscreen . maximized)))
(setq one-buffer-one-frame-mode nil)
      ;;; Use the commands "control+x" followed by an arrow to
      ;;; navigate between panes
;; (global-set-key (kbd "C-x <up>") 'windmove-up)
;; (global-set-key (kbd "C-x <down>") 'windmove-down)
;; (global-set-key (kbd "C-x <left>") 'windmove-left)
;; (global-set-key (kbd "C-x <right>") 'windmove-right)

(global-set-key (kbd "s-C-M-i") 'windmove-up)
(global-set-key (kbd "s-C-M-k") 'windmove-down)
(global-set-key (kbd "s-C-M-j") 'windmove-left)
(global-set-key (kbd "s-C-M-l") 'windmove-right)

Node

(use-package add-node-modules-path
  :config)

C, C++

(unless (shell-command "which clang-format")
  (async-shell-command "brew install clang-format"))
(use-package clang-format)

(defun clang-tidy-buffer ()
    (when (locate-dominating-file default-directory ".clang-format")
      (clang-format-buffer)
    ;; Continue to save.
    nil)
  nil
  ;; Buffer local hook.
  t)

(defun clang-format-save-hook-for-this-buffer ()
  "Create a buffer local save hook."
  (add-hook 'before-save-hook #'clang-tidy-buffer))

;; Run this for each mode you want to use the hook.
(add-hook 'c-mode-hook (lambda () (clang-format-save-hook-for-this-buffer)))
(add-hook 'c++-mode-hook (lambda () (clang-format-save-hook-for-this-buffer)))
(add-hook 'glsl-mode-hook (lambda () (clang-format-save-hook-for-this-buffer)))

Web Dev

CSS

Indenting & brackets

(setq css-electric-semi-behavior t
      css-indent-offset  2
      css-tab-mode 'auto)

Prettier CSS

(add-hook 'css-mode-hook #'prettier-js-mode)

Remove leading zeros

This undoes the formatting by `prettier` to conform with Google’s style guide. i.e. `0.3s` becomes `.3s`

(defun remove-decimal-zero ()
  (interactive)
  (save-excursion
    (beginning-of-buffer)
    (replace-regexp "0\\." ".")))

;; (add-hook 'css-mode-hook
;;           #'(lambda ()
;;               (add-hook 'before-save-hook 'remove-decimal-zero nil 'local)))
;; (add-hook 'scss-mode-hook
;;           #'(lambda ()
;;               (add-hook 'before-save-hook 'remove-decimal-zero nil 'local)))

Css sort

;; (use-package com-css-sort
;;   :ensure t
;;   :config
;;   (setq com-css-sort-sort-type 'alphabetic-sort))

;; (add-hook 'css-mode-hook
;;           #'(lambda ()
;;               (add-hook 'before-save-hook 'com-css-sort-attributes-document nil 'local)))
;; (add-hook 'scss-mode-hook
;;           #'(lambda ()
;;               (add-hook 'before-save-hook 'com-css-sort-attributes-document nil 'local)))

SASS

(use-package sass-mode
  :defer t
  :config
  (enable-minor-mode '("\\.sass?\\'" . sass-mode)))

js-comint

(use-package js-comint
  :config
  (setq inferior-js-program-command "/usr/bin/java org.mozilla.javascript.tools.shell.Main")
  (add-hook 'js2-mode-hook
            #'(lambda ()
                (local-set-key "\C-x\C-e" 'js-send-last-sexp)
                (local-set-key "\C-\M-x" 'js-send-last-sexp-and-go)
                (local-set-key "\C-cb" 'js-send-buffer)
                (local-set-key "\C-c\C-b" 'js-send-buffer-and-go)
                (local-set-key "\C-cl" 'js-load-file-and-go))))

emmet

;; (use-package emmet-mode
;;   :ensure t
;;   :hook ((web-mode . (lambda () (emmet-mode)))
;;          (css-mode . (lambda () (emmet-mode)))
;;          local-write-file-hooks . (lambda () (delete-trailing-whitespace) nil)))

web-mode

(use-package web-mode
  :mode "\\.html\\'"
  :after (tree-sitter-mode tree-sitter-langs)
  :config
  (setq web-mode-enable-auto-quoting nil)
  (tree-sitter-mode 1)
  (tree-sitter-hl-mode 1))

web-mode-indent

(defun my-setup-indent (n)
  ;; java/c/c++
  (setq-local c-basic-offset n)
  ;; web development
  (setq-local indent-tabs-mode nil)
  (setq-local tab-width n)
  (setq typescript-indent-level n)
  (setq-local web-mode-markup-indent-offset n) ; web-mode, html tag in html file
  (setq-local web-mode-css-indent-offset n) ; web-mode, css in html file
  (setq-local web-mode-code-indent-offset n) ; web-mode, js code in html file
  (setq-local css-indent-offset n)) ; css-mode

(defun my-web-code-style ()
  (interactive)
  (my-setup-indent 2))

(add-hook 'web-mode-hook 'my-web-code-style)

prettier-js-mode

(let ((prettier-path "~/.nvm/versions/node/**/bin/prettier"))
  (unless (file-exists-p (expand-file-name (cl-first (file-expand-wildcards prettier-path))))
    (async-shell-command "npm i -g prettier")))

(defun args-from-prettier (prettierrc)
  (let* ((json-key-type 'string)
         (json (json-read-file prettierrc)))
    (cl-loop for (a . b) in json
             collect (format "--%s" a)
             collect (if (null (json-encode-keyword b)) "false" (json-encode-keyword b)))))

(defun set-prettier-args ()
  (require 'projectile)
  (let* ((node-path "node_modules/.bin")
         (prettier-args '("--arrow-parens" "always"
                          "--semi" "true"
                          "--bracket-spacing" "true"
                          "--single-quote" "true"
                          "--jsx-bracket-same-line" "true"
                          "--print-width" "80"
                          "--use-tabs" "false"
                          "--tab-width" "2"))
         (default-directory (projectile-acquire-root))
         (prettier-config (file-expand-wildcards ".prettierrc*" t)))
    (if (and prettier-config (first prettier-config) (file-exists-p (first prettier-config)))
        (progn (message "local prettier found")
               (let ((local-prettier-args (args-from-prettier (first prettier-config))))
                 (setq prettier-js-args local-prettier-args)))
      (progn (message "no local prettier found")
             (setq prettier-js-args prettier-args)))))

(use-package prettier-js
  :defer t
  :config (set-prettier-args))

(defun init-prettier ()
  (interactive)
  ;; (enable-minor-mode
  ;;  '("\\.(jsx?\\|tsx?\\|json)\\'" . prettier-js-mode))
  (prettier-js-mode 1)
  (message "prettier inited"))

(eval-after-web-mode-load 'init-prettier)

tide-mode

(defun setup-tide-mode ()
  (interactive)
  (tide-setup)
  (flycheck-mode +1)
  (setq flycheck-check-syntax-automatically '(save mode-enabled))
  (eldoc-mode +1)
  (tide-hl-identifier-mode +1)
  (setq tide-completion-ignore-case t)
  (eldoc-mode +1)
  (tide-hl-identifier-mode +1)
  (message "setup-tide-mode"))

;; aligns annotation to the right hand side

rsjx-mode

(use-package rjsx-mode)

tide

(defun trigger-tide-setup ()
  (interactive)
  (enable-minor-mode
   '("\\.ts[x]?" . setup-tide-mode)))

(use-package tide
  :after
  (rjsx-mode flycheck)
  (typescript-mode  flycheck)
  (web-mode  flycheck)
  :hook (typescript-mode . setup-tide-mode)
  (js-mode . setup-tide-mode)
  (rjsx-mode . setup-tide-mode))
;; :hook ((before-save . tide-format-before-save))
(eval-after-web-mode-load 'trigger-tide-setup)

jinja

;;      (use-package jinja2-mode
;;        :ensure t
;;        :mode "\\.jinja\\'")

yaml

(use-package yaml-mode)

js-mode

(defun init-js ()
  (interactive)
  (init-prettier)
  (lsp)
  (setup-tide-mode)
  (tree-sitter-mode 1)
  (tree-sitter-hl-mode 1))

;; (add-to-list 'auto-mode-alist '("\\.js\\'" . js-mode))
(add-hook 'js-mode-hook #'init-js)
(with-eval-after-load 'js-mode
  (define-key js-mode-map (kbd "M-.") nil))

tsx-mode

(use-package tsx-mode
  :init
  (use-package coverlay)
  (use-package graphql-mode)
  (check-file-exists-or-clone
   (concat user-emacs-directory "tsx/")
   "https://github.com/orzechowskid/tsx-mode.el.git")
  (add-to-list 'load-path (expand-file-name (concat user-emacs-directory "tsx/")))
  (check-file-exists-or-clone
   (concat user-emacs-directory "tsi/")
   "https://github.com/orzechowskid/tsi.el.git")
  (add-to-list 'load-path (expand-file-name (concat user-emacs-directory "tsi/")))
  (check-file-exists-or-clone
   (concat user-emacs-directory "origami/")
   "https://github.com/gregsexton/origami.el.git")
  (add-to-list 'load-path (expand-file-name (concat user-emacs-directory "origami/")))
  :load-path "~/.emacs.d/tsx"
  :hook (tsx-mode . init-prettier)
  :mode (("\\.[mc]?[tj]sx?\\'" . tsx-mode)))

Shortcuts

lorem

(use-package lorem-ipsum)

new UNTITLED file

;; keybinding for this is in the key bindings menu
;; `C-c n'
(defun djr-new-buffer-frame ()
  "Create a new frame with a new empty buffer."
  (interactive)
  (let ((buffer (generate-new-buffer "untitled")))
    (set-buffer-major-mode buffer)
    (display-buffer buffer '(display-buffer-pop-up-frame . nil))))

Shortcuts

Aliases

(defalias 'pi 'package-install)
(defalias 'pl 'package-list-packages)
(defalias 'pr 'package-refresh-contents)
(defalias 'wm 'web-mode)
(defalias 'j2 'js2-mode)
(defalias 'mt 'multi-term)
(defalias 'rb 'revert-buffer)
(defalias 'scd 'sc-deftest-template)
(defalias 'tf 'transpose-frame)
(defalias 'rbp 'react-boilerplate)

Key bindings

(global-set-key "\M-3" #'(lambda() (interactive) (insert "#")))
(global-set-key (kbd "C-c n") #'djr-new-buffer-frame)
(global-set-key "\C-x\l" #'(lambda () (interactive)
                             (switch-to-buffer "*slime-repl sbcl*")))
(global-set-key (kbd "C-x C-b") 'ibuffer) ;; Use Ibuffer for Buffer List
;; Becasue I just can't quite those MacOS bindings, and why should I?
(global-set-key (kbd "s-<right>") 'move-end-of-line)
(global-set-key (kbd "s-<left>") 'move-beginning-of-line)
(global-set-key (kbd "s-<up>") 'beginning-of-buffer)
(global-set-key (kbd "s-<down>") 'end-of-buffer)
(global-set-key (kbd "M-<up>") 'scroll-down-command)
(global-set-key (kbd "M-<down>") 'scroll-up-command)
(global-set-key (kbd "s-w") 'delete-frame)
(global-set-key (kbd "s-<backspace>") 'kill-whole-line)
;; Resize Windows
;; (global-set-key (kbd "S-s-C-<down>") 'shrink-window-horizontally)
;; (global-set-key (kbd "S-s-C-<up>") 'enlarge-window-horizontally)
(global-set-key (kbd "C-x C-g") 'project-find-regexp)

Wrap with brackets and quotes

;; turn on highlight selection
(transient-mark-mode 1)

(defun xah-insert-bracket-pair (@left-bracket @right-bracket &optional @wrap-method)
  "Insert brackets around selection, word, at point, and maybe move cursor in between.

 *left-bracket and *right-bracket are strings. *wrap-method must be either 'line or 'block. 'block means between empty lines.

• if there's a region, add brackets around region.
• If *wrap-method is 'line, wrap around line.
• If *wrap-method is 'block, wrap around block.
• if cursor is at beginning of line and its not empty line and contain at least 1 space, wrap around the line.
• If cursor is at end of a word or buffer, one of the following will happen:
 xyz▮ → xyz(▮)
 xyz▮ → (xyz▮)       if in one of the lisp modes.
• wrap brackets around word if any. e.g. xy▮z → (xyz▮). Or just (▮)

URL `http://ergoemacs.org/emacs/elisp_insert_brackets_by_pair.html'
Version 2017-01-17"
  (if (use-region-p)
      (progn ; there's active region
        (let (
              ($p1 (region-beginning))
              ($p2 (region-end)))
          (goto-char $p2)
          (insert @right-bracket)
          (goto-char $p1)
          (insert @left-bracket)
          (goto-char (+ $p2 2))))
    (progn ; no text selection
      (let ($p1 $p2)
        (cond
         ((eq @wrap-method 'line)
          (setq $p1 (line-beginning-position) $p2 (line-end-position))
          (goto-char $p2)
          (insert @right-bracket)
          (goto-char $p1)
          (insert @left-bracket)
          (goto-char (+ $p2 (length @left-bracket))))
         ((eq @wrap-method 'block)
          (save-excursion
            (progn
              (if (re-search-backward "\n[ \t]*\n" nil 'move)
                  (progn (re-search-forward "\n[ \t]*\n")
                         (setq $p1 (point)))
                (setq $p1 (point)))
              (if (re-search-forward "\n[ \t]*\n" nil 'move)
                  (progn (re-search-backward "\n[ \t]*\n")
                         (setq $p2 (point)))
                (setq $p2 (point))))
            (goto-char $p2)
            (insert @right-bracket)
            (goto-char $p1)
            (insert @left-bracket)
            (goto-char (+ $p2 (length @left-bracket)))))
         ( ;  do line. line must contain space
          (and
           (eq (point) (line-beginning-position))
           ;; (string-match " " (buffer-substring-no-properties (line-beginning-position) (line-end-position)))
           (not (eq (line-beginning-position) (line-end-position))))
          (insert @left-bracket )
          (end-of-line)
          (insert  @right-bracket))
         ((and
           (or ; cursor is at end of word or buffer. i.e. xyz▮
            (looking-at "[^-_[:alnum:]]")
            (eq (point) (point-max)))
           (not (or
                 (string-equal major-mode "xah-elisp-mode")
                 (string-equal major-mode "emacs-lisp-mode")
                 (string-equal major-mode "lisp-mode")
                 (string-equal major-mode "lisp-interaction-mode")
                 (string-equal major-mode "common-lisp-mode")
                 (string-equal major-mode "clojure-mode")
                 (string-equal major-mode "xah-clojure-mode")
                 (string-equal major-mode "scheme-mode"))))
          (progn
            (setq $p1 (point) $p2 (point))
            (insert @left-bracket @right-bracket)
            (search-backward @right-bracket )))
         (t (progn
              ;; wrap around “word”. basically, want all alphanumeric, plus hyphen and underscore, but don't want space or punctuations. Also want chinese chars
              ;; 我有一帘幽梦,不知与谁能共。多少秘密在其中,欲诉无人能懂。
              (skip-chars-backward "-_[:alnum:]")
              (setq $p1 (point))
              (skip-chars-forward "-_[:alnum:]")
              (setq $p2 (point))
              (goto-char $p2)
              (insert @right-bracket)
              (goto-char $p1)
              (insert @left-bracket)
              (goto-char (+ $p2 (length @left-bracket))))))))))

(defun xah-insert-paren ()
  (interactive)
  (xah-insert-bracket-pair "(" ")") )

(defun xah-insert-bracket ()
  (interactive)
  (xah-insert-bracket-pair "[" "]") )

(defun xah-insert-brace ()
  (interactive)
  (xah-insert-bracket-pair "{" "}") )

(defun xah-insert-quote ()
  (interactive)
  (xah-insert-bracket-pair "\'" "\'") )

(defun xah-insert-double-quote ()
  (interactive)
  (xah-insert-bracket-pair "\"" "\"") )

(defun xah-insert-back-quote ()
  (interactive)
  (xah-insert-bracket-pair "`" "`") )

(global-set-key (kbd "M-(") 'xah-insert-paren)
(global-set-key (kbd "M-[") 'xah-insert-bracket)
(global-set-key (kbd "M-{") 'xah-insert-brace)
(global-set-key (kbd "M-\"") 'xah-insert-double-quote)
(global-set-key (kbd "M-'") 'xah-insert-quote)
(global-set-key (kbd "M-`") 'xah-insert-back-quote)

Xah Move Cursor

(defvar xah-brackets nil "string of left/right brackets pairs.")
(setq xah-brackets "()[]{}<>()[]{}⦅⦆〚〛⦃⦄“”‘’‹›«»「」〈〉《》【】〔〕⦗⦘『』〖〗〘〙「」⟦⟧⟨⟩⟪⟫⟮⟯⟬⟭⌈⌉⌊⌋⦇⦈⦉⦊❛❜❝❞❨❩❪❫❴❵❬❭❮❯❰❱❲❳〈〉⦑⦒⧼⧽﹙﹚﹛﹜﹝﹞⁽⁾₍₎⦋⦌⦍⦎⦏⦐⁅⁆⸢⸣⸤⸥⟅⟆⦓⦔⦕⦖⸦⸧⸨⸩⦅⦆⧘⧙⧚⧛⸜⸝⸌⸍⸂⸃⸄⸅⸉⸊᚛᚜༺༻༼༽⏜⏝⎴⎵⏞⏟⏠⏡﹁﹂﹃﹄︹︺︻︼︗︘︿﹀︽︾﹇﹈︷︸")

(defvar xah-left-brackets '("(" "{" "[" "<" "" "" "" "" "" "" "" "" "" "" "«" )
  "List of left bracket chars.")
(progn
  ;; make xah-left-brackets based on xah-brackets
  (setq xah-left-brackets '())
  (dotimes ($x (- (length xah-brackets) 1))
    (when (= (% $x 2) 0)
      (push (char-to-string (elt xah-brackets $x))
            xah-left-brackets)))
  (setq xah-left-brackets (reverse xah-left-brackets)))

(defvar xah-right-brackets '(")" "]" "}" ">" "" "" "" "" "" "" "" "" "" "" "»")
  "list of right bracket chars.")
(progn
  (setq xah-right-brackets '())
  (dotimes ($x (- (length xah-brackets) 1))
    (when (= (% $x 2) 1)
      (push (char-to-string (elt xah-brackets $x))
            xah-right-brackets)))
  (setq xah-right-brackets (reverse xah-right-brackets)))

(defun xah-backward-left-bracket ()
  "Move cursor to the previous occurrence of left bracket.
The list of brackets to jump to is defined by `xah-left-brackets'.
URL `http://ergoemacs.org/emacs/emacs_navigating_keys_for_brackets.html'
Version 2015-10-01"
  (interactive)
  (re-search-backward (regexp-opt xah-left-brackets) nil t))

(defun xah-forward-right-bracket ()
  "Move cursor to the next occurrence of right bracket.
The list of brackets to jump to is defined by `xah-right-brackets'.
URL `http://ergoemacs.org/emacs/emacs_navigating_keys_for_brackets.html'
Version 2015-10-01"
  (interactive)
  (re-search-forward (regexp-opt xah-right-brackets) nil t))

(global-set-key (kbd "S-M-C-<right>") 'xah-forward-right-bracket)
(global-set-key (kbd "S-M-C-<left>") 'xah-backward-left-bracket)

Xah Matching Brackets

(defun xah-goto-matching-bracket ()
  "Move cursor to the matching bracket.
If cursor is not on a bracket, call `backward-up-list'.
The list of brackets to jump to is defined by `xah-left-brackets' and `xah-right-brackets'.
URL `http://ergoemacs.org/emacs/emacs_navigating_keys_for_brackets.html'
Version 2016-11-22"
  (interactive)
  (if (nth 3 (syntax-ppss))
      (backward-up-list 1 'ESCAPE-STRINGS 'NO-SYNTAX-CROSSING)
    (cond
     ((eq (char-after) ?\") (forward-sexp))
     ((eq (char-before) ?\") (backward-sexp ))
     ((looking-at (regexp-opt xah-left-brackets))
      (forward-sexp))
     ((looking-back (regexp-opt xah-right-brackets) (max (- (point) 1) 1))
      (backward-sexp))
     (t (backward-up-list 1 'ESCAPE-STRINGS 'NO-SYNTAX-CROSSING)))))

(global-set-key (kbd "S-M-C-<down>") 'xah-goto-matching-bracket)

Generate Code

THREE box

(defun three-box ()
  (interactive)
  (insert "<mesh>")
  (newline)
  (insert "  <boxBufferGeometry attach='geometry' args={[1, 1, 1]} />")
  (newline)
  (insert "  <meshStandardMaterial attach='material' />")
  (newline)
  (insert "</mesh>"))

Add sc-deftest

(defun sc-deftest-template (test)
  (interactive "sdef-test name: ")
  (insert "(sc-deftest test-")
  (insert test)
  (insert " ()")
  (newline)
  (insert "  (let* (())")
  (newline)
  (insert "    (sc-test-check ")
  (newline)
  (insert "    )))"))

js-80-slash

(defun js-80-slash ()
  (interactive)
  (cl-loop repeat 80 do (insert "/")))

lisp-80-slash

(defun lisp-80-slash ()
  (interactive)
  (cl-loop repeat 80 do (insert ";")))

React boilerplate

(defun react-boilerplate (name)
  (interactive "sFunction Name: ")
  (js2-mode)
  (insert "import React from 'react';")
  (newline)
  (newline)
  (insert "function ")
  (insert name)
  (insert "() {")
  (newline)
  (newline)
  (insert "    return ();")
  (newline)
  (insert "};")
  (newline)
  (newline)
  (insert "export default ")
  (insert name)
  (insert ";"))

Web boilerplate

(defun web-boilerplate (page-title)
  (interactive "sHTML Title: ")
  (web-mode)
  (insert "<!DOCTYPE html>")
  (newline)
  (insert "<html>")
  (newline)
  (insert "    <head>")
  (newline)
  (insert "      <title>")
  (insert page-title)
  (insert "</title>")
  (newline)
  (insert "    </head>")
  (newline)
  (insert "    <body>")
  (newline)
  (newline)
  (insert "       <h1>This is a Heading</h1>")
  (newline)
  (insert "        <p>This is a paragraph.</p>")
  (newline)
  (newline)
  (insert "    </body>")
  (newline)
  (insert "</html>"))

ROBODOC

(defun elisp-depend-filename (fullpath)
  "Return filename without extension and path.
   FULLPATH is the full path of file."
  (file-name-sans-extension (file-name-nondirectory fullpath)))
(defun robodoc-fun ()
  ;; "Put robodoc code around a funciton definition"
  ;; (interactive "r")
  (interactive)
  (save-excursion
    (backward-sexp)
    (let* ((beg (point))
           (end (progn (forward-sexp) (point)))
           (name (buffer-substring beg end))
           (buffer (elisp-depend-filename (buffer-file-name)))
           ;; (buffer-name))
           ;; is this defun or defmethod
           (letter (progn
                     (backward-sexp 2)
                     (let* ((beg (point))
                            (end (progn (forward-sexp) (point)))
                            (fun (buffer-substring beg end)))
                       ;; (insert (preceding-sexp))
                       (if (string= fun "defun")
                           "f"
                         "m")))))
      (beginning-of-line)
      (newline)
      (previous-line)
      (newline)
      (insert
       ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;")
      (newline)
      (insert ";;; ****" letter "* " buffer "/" name)
      ;; (insert ";;; ****" letter "*" buffer "/" name)
      (newline)
      ;; (insert ";;; FUNCTION")
      ;; (newline)
      (insert ";;; AUTHOR")
      (newline)
      (insert ";;; Daniel Ross (mr.danielross[at]gmail[dot]com) ")
      (newline)
      (insert ";;; ")
      (newline)
      (robodoc-fun-aux "DATE")
      (robodoc-fun-aux "DESCRIPTION")
      ;; (insert ";;; " name ":")
      ;; (newline)
      ;; (insert ";;;")
      ;; (newline)
      ;; (insert ";;;")
      ;; (newline)
      (robodoc-fun-aux "ARGUMENTS")
      (robodoc-fun-aux "OPTIONAL ARGUMENTS")
      (robodoc-fun-aux "RETURN VALUE")
      (insert ";;; EXAMPLE")
      (newline)
      (insert "#|")
      (newline)
      (newline)
      (insert "|#")
      (newline)
      (insert ";;; SYNOPSIS")
      (next-line)
      (forward-sexp 2)
      (newline)
      (insert ";;; ****"))))

(defun robodoc-fun-aux (tag)
  (insert ";;; " tag)
  (newline)
  (insert ";;; ")
  (newline)
  (insert ";;; ")
  (newline))

string-inflection

(use-package string-inflection
  :init (global-set-key (kbd "C-x C-/") 'string-inflection-all-cycle))

Completions

vertico

;; Enable vertico
(use-package vertico
  :init
  (vertico-mode)

  ;; Grow and shrink the Vertico minibuffer
  (setq vertico-resize t)

  ;; Optionally enable cycling for `vertico-next' and `vertico-previous'.
  (setq vertico-cycle t))

;; A few more useful configurations...
(use-package emacs
  :init
  ;; Add prompt indicator to `completing-read-multiple'.
  ;; Alternatively try `consult-completing-read-multiple'.
  (defun crm-indicator (args)
    (cons (concat "[CRM] " (car args)) (cdr args)))
  (advice-add #'completing-read-multiple :filter-args #'crm-indicator)

  ;; Do not allow the cursor in the minibuffer prompt
  (setq minibuffer-prompt-properties
        '(read-only t cursor-intangible t face minibuffer-prompt))
  (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode)

  (setq completion-cycle-threshold 3)
  ;; Emacs 28: Hide commands in M-x which do not work in the current mode.
  ;; Vertico commands are hidden in normal buffers.
  (setq read-extended-command-predicate
        #'command-completion-default-include-p)
  ;; Enable recursive minibuffers
  (setq enable-recursive-minibuffers t))

corfu

(use-package corfu
  ;; Optional customizations
  :custom
  (corfu-cycle t)                ;; Enable cycling for `corfu-next/previous'
  ;; (corfu-auto t)                 ;; Enable auto completion
  ;; (corfu-separator ?\s)          ;; Orderless field separator
  ;; (corfu-quit-at-boundary nil)   ;; Never quit at completion boundary
  ;; (corfu-quit-no-match nil)      ;; Never quit, even if there is no match
  ;; (corfu-preview-current nil)    ;; Disable current candidate preview
  ;; (corfu-preselect-first nil)    ;; Disable candidate preselection
  ;; (corfu-on-exact-match nil)     ;; Configure handling of exact matches
  ;; (corfu-echo-documentation nil) ;; Disable documentation in the echo area
  ;; (corfu-scroll-margin 5)        ;; Use scroll margin

  ;; Enable Corfu only for certain modes.
  ;; :hook ((prog-mode . corfu-mode)
  ;;        (shell-mode . corfu-mode)
  ;;        (eshell-mode . corfu-mode))

  ;; Recommended: Enable Corfu globally.
  ;; This is recommended since Dabbrev can be used globally (M-/).
  ;; See also `corfu-excluded-modes'.
  :ensure t
  :init (global-corfu-mode))

Flyspell

Taken from here. You need to install the ASpell spell checker. You can install it with homebrew with `brew install aspell`.

;; flyspell
(unless (file-exists-p "/usr/local/bin/aspell")
  (shell-command "brew install aspell"))
(dolist (hook '(text-mode-hook markdown-mode-hook))
  (add-hook hook 'flyspell-mode))
(add-hook 'prog-mode-hook 'flyspell-prog-mode)
(setq ispell-dictionary "british")
(setq flyspell-issue-message-flag nil)
(defun flyspell-emacs-popup-textual (event poss word)
  "A textual flyspell popup menu."
  (unless (package-installed-p 'popup)
    (use-package popup))
  (when (package-installed-p 'popup)
    (require 'popup)
    (let* ((corrects (if flyspell-sort-corrections
                         (sort (car (cdr (cdr poss))) 'string<)
                       (car (cdr (cdr poss)))))
           ;; sssss
           ;; shljdsljhslhjslh 
           (cor-menu (if (consp corrects)
                         (mapcar (lambda (correct)
                                   (list correct correct))
                                 corrects)
                       '()))
           (affix (car (cdr (cdr (cdr poss)))))
           show-affix-info
           (base-menu  (let ((save (if (and (consp affix) show-affix-info)
                                       (list
                                        (list (concat "Save affix: " (car affix))
                                              'save)
                                        '("Accept (session)" session)
                                        '("Accept (buffer)" buffer))
                                     '(("Save word" save)
                                       ("Accept (session)" session)
                                       ("Accept (buffer)" buffer)))))
                         (if (consp cor-menu)
                             (append cor-menu (cons "" save))
                           save)))
           (menu (mapcar
                  (lambda (arg) (if (consp arg) (car arg) arg))
                  base-menu)))
      (cadr (assoc (popup-menu* menu :scroll-bar t) base-menu))))
  (eval-after-load "flyspell"
    '(progn
       (fset 'flyspell-emacs-popup 'flyspell-emacs-popup-textual))))

;; two-finger clicks for mac
(eval-after-load "flyspell"
  '(progn
     (define-key flyspell-mouse-map [down-mouse-3] #'flyspell-correct-word)
     (define-key flyspell-mouse-map [mouse-3] #'undefined)))

Flycheck

(use-package flycheck
  :ensure t
  :init (global-flycheck-mode))

Minibuffer auto-complete

(setq completion-styles '(basic initials partial-completion flex)) ; > Emacs 27.1
(setq completion-cycle-threshold 10)

Fido

;;     (setq fido-mode t)

Bash completion

(use-package bash-completion
  :defer t
  :config (bash-completion-setup))

selectrum

(use-package selectrum
  :config (selectrum-mode +1))

(use-package selectrum-prescient
  :config
  ;; to make sorting and filtering more intelligent
  (selectrum-prescient-mode +1)
  ;; to save your command history on disk, so the sorting gets more
  ;; intelligent over time
  (prescient-persist-mode +1))

Marginalia

;; Enable richer annotations using the Marginalia package
(use-package marginalia
  ;; Either bind `marginalia-cycle` globally or only in the minibuffer
  :bind (("M-A" . marginalia-cycle)
         :map minibuffer-local-map
         ("M-A" . marginalia-cycle))

  ;; The :init configuration is always executed (Not lazy!)
  :init

  ;; Must be in the :init section of use-package such that the mode gets
  ;; enabled right away. Note that this forces loading the package.
  (marginalia-mode))

Orderless

(use-package orderless
  :custom (completion-styles '(orderless)))

consult

;; Example configuration for Consult
(use-package consult
  ;; Replace bindings. Lazily loaded due by `use-package'.
  :bind (;; C-c bindings (mode-specific-map)
         ("C-c h" . consult-history)
         ("C-c m" . consult-mode-command)
         ("C-c b" . consult-bookmark)
         ("C-c k" . consult-kmacro)
         ;; C-x bindings (ctl-x-map)
         ("C-x M-:" . consult-complex-command)     ;; orig. repeat-complex-command
         ;; ("C-x b" . consult-buffer)                ;; orig. switch-to-buffer
         ;; ("C-x 4 b" . consult-buffer-other-window) ;; orig. switch-to-buffer-other-window
         ;; ("C-x 5 b" . consult-buffer-other-frame)  ;; orig. switch-to-buffer-other-frame
         ;; Custom M-# bindings for fast register access
         ("M-#" . consult-register-load)
         ;; ("M-'" . consult-register-store)          ;; orig. abbrev-prefix-mark (unrelated)
         ("C-M-#" . consult-register)
         ;; Other custom bindings
         ("M-y" . consult-yank-pop)                ;; orig. yank-pop
         ("<help> a" . consult-apropos)            ;; orig. apropos-command
         ;; M-g bindings (goto-map)
         ("M-g e" . consult-compile-error)
         ("M-g f" . consult-flymake)               ;; Alternative: consult-flycheck
         ("M-g g" . consult-goto-line)             ;; orig. goto-line
         ("M-g M-g" . consult-goto-line)           ;; orig. goto-line
         ("M-g o" . consult-outline)               ;; Alternative: consult-org-heading
         ("M-g m" . consult-mark)
         ("M-g k" . consult-global-mark)
         ("M-g i" . consult-imenu)
         ("M-g I" . consult-imenu-multi)
         ;; M-s bindings (search-map)
         ("M-s f" . consult-find)
         ("M-s F" . consult-locate)
         ("M-s g" . consult-grep)
         ("M-s G" . consult-git-grep)
         ("M-s r" . consult-ripgrep)
         ("M-s l" . consult-line)
         ("M-s L" . consult-line-multi)
         ("M-s m" . consult-multi-occur)
         ("M-s k" . consult-keep-lines)
         ("M-s u" . consult-focus-lines)
         ;; Isearch integration
         ("M-s e" . consult-isearch)
         :map isearch-mode-map
         ;; ("M-e" . consult-isearch)                 ;; orig. isearch-edit-string
         ("M-s e" . consult-isearch)               ;; orig. isearch-edit-string
         ("M-s l" . consult-line)                  ;; needed by consult-line to detect isearch
         ("M-s L" . consult-line-multi))           ;; needed by consult-line to detect isearch

  ;; Enable automatic preview at point in the *Completions* buffer.
  ;; This is relevant when you use the default completion UI,
  ;; and not necessary for Vertico, Selectrum, etc.
  ;; :hook (completion-list-mode . consult-preview-at-point-mode)

  ;; The :init configuration is always executed (Not lazy)
  :init

  ;; Optionally configure the register formatting. This improves the register
  ;; preview for `consult-register', `consult-register-load',
  ;; `consult-register-store' and the Emacs built-ins.
  (setq register-preview-delay 0
        register-preview-function #'consult-register-format)

  ;; Optionally tweak the register preview window.
  ;; This adds thin lines, sorting and hides the mode line of the window.
  (advice-add #'register-preview :override #'consult-register-window)

  ;; Optionally replace `completing-read-multiple' with an enhanced version.
  (advice-add #'completing-read-multiple :override #'consult-completing-read-multiple)

  ;; Use Consult to select xref locations with preview
  ;; (setq xref-show-xrefs-function #'consult-xref
  ;;       xref-show-definitions-function #'consult-xref)

  ;; Configure other variables and modes in the :config section,
  ;; after lazily loading the package.
  :config

  ;; Optionally configure preview. The default value
  ;; is 'any, such that any key triggers the preview.
  ;; (setq consult-preview-key 'any)
  ;; (setq consult-preview-key (kbd "M-."))
  ;; (setq consult-preview-key (list (kbd "<S-down>") (kbd "<S-up>")))
  ;; For some commands and buffer sources it is useful to configure the
  ;; :preview-key on a per-command basis using the `consult-customize' macro.
  (consult-customize
   consult-theme
   :preview-key '(:debounce 0.2 any)
   consult-ripgrep consult-git-grep consult-grep
   consult-bookmark consult-recent-file consult-xref
   ;; consult--source-file consult--source-project-file consult--source-bookmark
   :preview-key (kbd "M-."))

  ;; Optionally configure the narrowing key.
  ;; Both < and C-+ work reasonably well.
  (setq consult-narrow-key "<") ;; (kbd "C-+")

  ;; Optionally make narrowing help available in the minibuffer.
  ;; You may want to use `embark-prefix-help-command' or which-key instead.
  ;; (define-key consult-narrow-map (vconcat consult-narrow-key "?") #'consult-narrow-help)

  ;; Optionally configure a function which returns the project root directory.
  ;; There are multiple reasonable alternatives to chose from.
  ;;;; 1. project.el (project-roots)
  (setq consult-project-root-function
        (lambda ()
          (when-let (project (project-current))
            (car (project-roots project)))))
  ;;;; 2. projectile.el (projectile-project-root)
  ;; (autoload 'projectile-project-root "projectile")
  ;; (setq consult-project-root-function #'projectile-project-root)
  ;;;; 3. vc.el (vc-root-dir)
  ;; (setq consult-project-root-function #'vc-root-dir)
  ;;;; 4. locate-dominating-file
  ;; (setq consult-project-root-function (lambda () (locate-dominating-file "." ".git")))
  )

embark

(use-package embark

  :bind
  (("C-." . embark-act)         ;; pick some comfortable binding
   ("C-;" . embark-dwim)        ;; good alternative: M-.
   ("C-h B" . embark-bindings)) ;; alternative for `describe-bindings'

  :init

  ;; Optionally replace the key help with a completing-read interface
  (setq prefix-help-command #'embark-prefix-help-command)

  :config

  ;; Hide the mode line of the Embark live/completions buffers
  (add-to-list 'display-buffer-alist
               '("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
                 nil
                 (window-parameters (mode-line-format . none)))))

;; Consult users will also want the embark-consult package.
(use-package embark-consult
  :after (embark consult)
  :demand t ; only necessary if you have the hook below
  ;; if you want to have consult previews as you move around an
  ;; auto-updating embark collect buffer
  :hook
  (embark-collect-mode . consult-preview-at-point-mode))

lsp-mode

Got this from LSP support for Emacs site

(defun enable-lsp-for-web-mode ()
  (interactive)
  (enable-minor-mode
   '("\\.js[x]?\\|\\.ts[x]?" . lsp-deferred)))

(use-package lsp-mode
  :if window-system
  :no-require t
  :commands (lsp lsp-deferred)
  :config (setq lsp-keymap-prefix "C-c l"
                lsp-headerline-breadcrumb-mode nil
                lsp-log-io nil
                lsp-auto-guess-root t
                lsp-restart 'auto-restart
                lsp-enable-symbol-highlighting nil
                lsp-enable-on-type-formatting nil
                lsp-signature-auto-activate nil
                lsp-signature-render-documentation nil
                lsp-eldoc-hook nil
                lsp-modeline-code-actions-enable nil
                lsp-modeline-diagnostics-enable nil
                lsp-semantic-tokens-enable nil
                lsp-enable-folding nil
                lsp-enable-imenu nil
                lsp-enable-snippet nil
                read-process-output-max (* 1024 1024) ;; 1MB
                lsp-idle-delay 0.5)
      (add-to-list 'lsp-language-id-configuration  '("\\.[mc]js$" . "javascript")))

(eval-after-web-mode-load 'enable-lsp-for-web-mode)

lsp-ui

(use-package lsp-ui
  :commands lsp-ui-mode
  :after lsp-mode
  :config
  (setq lsp-ui-doc-enable nil)
  (setq lsp-ui-doc-header t)
  (setq lsp-ui-doc-include-signature t)
  (setq lsp-ui-doc-border (face-foreground 'default))
  (setq lsp-ui-sideline-show-code-actions t)
  (setq lsp-ui-sideline-delay 0.05))

lsp-treemacs

(use-package lsp-treemacs
  :after lsp-mode)

JSON

(use-package json-mode
  :mode "\\.json"
  :hook (init-js))

Lisp

paren-mode

(show-paren-mode 1)

SBCL

(when (not (executable-find "sbcl"))
  (shell-command "brew install sbcl"))
;; Set your lisp system and, optionally, some contribs
(setq inferior-lisp-program "/opt/sbcl/bin/sbcl")
(let ((sbcl-local (car (file-expand-wildcards
                        "/usr/local/Cellar/sbcl/*/lib/sbcl/sbcl.core"))))
  (setq slime-lisp-implementations
        `((sbcl ("/usr/local/bin/sbcl"
                 "--core"
                 ;; replace with correct path of sbcl
                 ,sbcl-local
                 "--dynamic-space-size" "2147")))))

slime

;; slime
;; (use-package slime
;;   :hook (slime-repl-mode-hook . slime-repl-ansi-color-mode))

slime-repl-ansi-color

;; (use-package slime-repl-ansi-color
;;   :after slime-repl
;;   :requires slime)

paredit

Man, this is slow. Removing it for now.

;; (autoload 'enable-paredit-mode "paredit" "Turn on pseudo-structural editing of Lisp code." t)
;; (add-hook 'emacs-lisp-mode-hook       #'enable-paredit-mode)
;; (add-hook 'eval-expression-minibuffer-setup-hook #'enable-paredit-mode)
;; (add-hook 'ielm-mode-hook             #'enable-paredit-mode)
;; (add-hook 'lisp-mode-hook             #'enable-paredit-mode)
;; (add-hook 'lisp-interaction-mode-hook #'enable-paredit-mode)
;; (add-hook 'scheme-mode-hook           #'enable-paredit-mode)
;; (add-hook 'slime-repl-mode-hook (lambda () (paredit-mode +1)))
;; ;; Stop SLIME's REPL from grabbing DEL,
;; ;; which is annoying when backspacing over a '('
;; (defun override-slime-repl-bindings-with-paredit ()
;;   (define-key slime-repl-mode-map
;;     (read-kbd-macro paredit-backward-delete-key) nil))
;; (add-hook 'slime-repl-mode-hook 'override-slime-repl-bindings-with-paredit)

smartparens

This also slow, removing

;; (require 'smartparens-config)
;; (add-hook 'web-mode-hook #'smartparens-mode)
;; (add-hook 'emacs-lisp-mode-hook #'smartparens-mode)
;; (add-hook 'lisp-mode-hook #'smartparens-mode)
;; (add-hook 'latex-mode-hook #'SMARTPARENS-MODE)

lisp extra font lock

(use-package lisp-extra-font-lock
  :config (lisp-extra-font-lock-global-mode 1)
  (font-lock-add-keywords
   'emacs-lisp-mode
   '(("(\\s-*\\(\\_<\\(?:\\sw\\|\\s_\\)+\\)\\_>"
      1 'font-lock-function-name-face))
   'append)) ;; <-- Add after all other rules

Word Processing

auctex

Taken from this github issue.

(use-package  auctex
  :defines (latex-help-cmd-alist latex-help-file)
  :mode ("\\.tex\\'" . TeX-latex-mode)
  :init
  (setq reftex-plug-into-AUCTeX t)
  (setenv "PATH" (concat "/Library/TeX/texbin:"
                         (getenv "PATH")))
  (add-to-list 'exec-path "/Library/TeX/texbin")
  :config
  (defun latex-help-get-cmd-alist () ;corrected version:
    "Scoop up the commands in the index of the latex info manual.
 The values are saved in `latex-help-cmd-alist' for speed."
    ;; mm, does it contain any cached entries
    (if (not (assoc "\\begin" latex-help-cmd-alist))
        (save-window-excursion
          (setq latex-help-cmd-alist nil)
          (info-goto-node (concat latex-help-file "Command Index"))
          (goto-char (point-max))
          (while (re-search-backward "^\\* \\(.+\\): *\\(.+\\)\\." nil t)
            (let ((key (buffer-substring (match-beginning 1) (match-end 1)))
                  (value (buffer-substring (match-beginning 2)
                                           (match-end 2))))
              (add-to-list 'latex-help-cmd-alist (cons key value))))))
    latex-help-cmd-alist))

(use-package latex-preview-pane
  :after auctex)
;; (use-package preview)
(use-package info-look)
(use-package latex
  :ensure auctex
  :defer t
  :config
  (latex-preview-pane-enable)
  (use-package info-look)
  (add-hook 'LaTeX-mode-hook 'reftex-mode)
  (info-lookup-add-help :mode 'LaTeX-mode
                        :regexp ".*"
                        :parse-rule "\\\\?[a-zA-Z]+\\|\\\\[^a-zA-Z]"
                        :doc-spec '(("(latex2e)Concept Index" )
                                    ("(latex2e)Command Index"))))

markdown pandoc

(unless (executable-find "pandoc")
  (shell-command "brew install pandoc"))
(setq markdown-command "/usr/local/bin/pandoc")

LaTeX

;; (use-package auctex
;;   :ensure t
;;   :if window-system
;;   :config
;;     (latex-preview-pane-enable)
;;     (require 'latex-pretty-symbols))

Projectile

(use-package projectile
  :ensure t
  :bind-keymap ("C-c p" . projectile-command-map)
  :config (setq projectile-switch-project-action #'projectile-dired
                projectile-indexing-method 'native
                projectile-enable-caching t)
  :init (projectile-mode +1))

Org

(setq org-support-shift-select t)

org-agenda

(setq org-directory (expand-file-name "~/org")
      org-agenda-files (list org-directory)
      org-log-into-drawer nil)

org-mode dates

(setq-default org-display-custom-times t)
(setq org-time-stamp-custom-formats '("<%e %B %Y>" . "<%a, %e %b %Y %H:%M>"))
;; (use-package ox
;;   :ensure t)
(require 'ox)
(defun endless/filter-timestamp (trans back _comm)
  "Remove <> around time-stamps."
  (pcase back
    ((or `jekyll `html)
     (replace-regexp-in-string "&[lg]t;" "" trans))
    (`latex
     (replace-regexp-in-string "[<>]" "" trans))))
(add-to-list 'org-export-filter-timestamp-functions
             #'endless/filter-timestamp)

Org tempo

(require 'org-tempo)
(add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp"))

org-reveal

;; Reveal.js + Org mode
(use-package ox-reveal
  :config (setq Org-Reveal-root (concat "file://" (expand-file-name "~/reveal.js/"))
                Org-Reveal-title-slide nil))

org bullets

(use-package org-bullets
  :if window-system
  :after org
  :hook (org-mode . org-bullets-mode)
  :custom
  (org-bullets-bullet-list '("" "" "" "" "" "" "")))

;; Replace list hyphen with dot
(font-lock-add-keywords 'org-mode
                        '(("^ *\\([-]\\) "
                           (0 (prog1 () (compose-region (match-beginning 1) (match-end 1) ""))))))
(when (member "Cantarell" (font-family-list))
  (dolist (face '((org-level-1 . 1.2)
                  (org-level-2 . 1.1)
                  (org-level-3 . 1.05)
                  (org-level-4 . 1.0)
                  (org-level-5 . 1.1)
                  (org-level-6 . 1.1)
                  (org-level-7 . 1.1)
                  (org-level-8 . 1.1)))
    (set-face-attribute (car face) nil :font "Cantarell" :weight 'regular :height (cdr face))))

org capture

(custom-set-variables
 '(org-directory (expand-file-name "~/org"))
 '(org-agenda-files (list org-directory)))
(setq org-default-notes-file (concat org-directory "/notes.org"))

custom TODOs

(setq org-todo-keyword-faces
      '(("IN_PROGRESS" . "orange")
        ("BLOCKED" . "blue")
        ("CR" . "orange")
        ("QA" . "green")
        ("POSTPONED" . "blue")
        ("CANCELLED" . "grey")))
(setq org-todo-keywords
      '((sequence "TODO(t)" "|" "IN_PROGRESS(i)" "POSTPONED(p)"
                  "|" "DONE(d)" "CR(r)" "QA(q)" "CANCELLED(c)" "BLOCKED(b)")))

org-jira

This relies on their being auth credentials in the file ~/.authinfo Details here: https://github.com/ahungry/org-jira

;; (use-package org-jira
;;   :ensure t
;;   :if window-system
;;   :config (unless (file-exists-p "~/.org-jira")
;;             (make-directory "~/.org-jira"))
;;   (setq jiralib-url "https://phantomstudios.atlassian.net/")
;;   (setq org-jira-done-states '("Merged" "Done" "Closed"))
;;   (setq org-jira-jira-status-to-org-keyword-alist
;;         '(("In Progress" . "IN_PROGRESS")
;;           ("To Do" . "TODO")
;;           ("Reopened" . "TODO")
;;           ("Blocked" . "BLOCKED")
;;           ("In Review" . "CR")
;;           ("Merged" . "+2")
;;           ("Ready for QA" . "QA")
;;           ("In QA" . "QA")
;;           ("Done" . "DONE")
;;           ("Ready for Deployment" . "DONE")
;;           ("Closed" . "DONE")))
;;   (setq org-jira-progress-issue-flow
;;         '(("To Do" . "In Progress")
;;           ("Reopened/Blocked" . "In Progress")
;;           ("In CR" . "Merged")
;;           ("Ready for QA" . "Done")
;;           ("Ready for Deployment" . "Closed"))))

Regexp

(defvar my/re-builder-positions nil
  "Store point and region bounds before calling re-builder")
(advice-add 're-builder
            :before
            (defun my/re-builder-save-state (&rest _)
              "Save into `my/re-builder-positions' the point and region
     positions before calling `re-builder'."
              (setq my/re-builder-positions
                    (cons (point)
                          (when (region-active-p)
                            (list (region-beginning)
                                  (region-end)))))))

(defun reb-replace-regexp (&optional delimited)
  "Run `query-replace-regexp' with the contents of re-builder. With
     non-nil optional argument DELIMITED, only replace matches
     surrounded by word boundaries."
  (interactive "P")
  (reb-update-regexp)
  (let* ((re (reb-target-binding reb-regexp))
         (replacement (query-replace-read-to
                       re
                       (concat "Query replace"
                               (if current-prefix-arg
                                   (if (eq current-prefix-arg '-) " backward" " word")
                                 "")
                               " regexp"
                               (if (with-selected-window reb-target-window
                                     (region-active-p)) " in region" ""))
                       t))
         (pnt (car my/re-builder-positions))
         (beg (cadr my/re-builder-positions))
         (end (caddr my/re-builder-positions)))
    (with-selected-window reb-target-window
      (goto-char pnt) ; replace with (goto-char (match-beginning 0)) if you want
                                        ; to control where in the buffer the replacement starts
                                        ; with re-builder
      (setq my/re-builder-positions nil)
      (reb-quit)
      (query-replace-regexp re replacement delimited beg end))))
(require 're-builder)
(define-key reb-mode-map (kbd "RET") #'reb-replace-regexp)
(define-key reb-lisp-mode-map (kbd "RET") #'reb-replace-regexp)
(global-set-key (kbd "C-M-%") #'re-builder)

Multiple Cursors

(use-package multiple-cursors
  :defer nil
  :ensure t)

Magit

(use-package magit
  :ensure t
  :bind (("C-x g" . magit-status))
  :defer t)

diff

(use-package diff-hl
  :init (turn-on-diff-hl-mode)
  :hook ((prog-mode-hook vc-dir-mode-hook) . turn-on-diff-hl-mode))

glsl-mode

(check-file-exists-or-clone (concat user-emacs-directory "glsl/")
                            "https://github.com/jimhourihan/glsl-mode.git")
(dolist (file '("\\.glsl\\'" "\\.frag\\'" "\\.vert\\'"))
  (add-to-list 'auto-mode-alist `(,file . glsl-mode)))

smerge

(use-package smerge-mode
  :bind (("C-c C-n" . smerge-next)
         ("C-c C-p" . smerge-prev)
         ("C-c C-a" . smerge-keep-all)
         ("C-c C-u" . smerge-keep-upper)
         ("C-c C-l" . smerge-keep-lower)))

shader-mode

(use-package shader-mode
  :ensure t
  :defer t)

editorconfig

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

Shells & Terminal Emulators

shell highlight

(use-package shx
  :defer t
  :config (shx-global-mode 1))

vterm

(use-package vterm
  :config (defun get-full-list ()
            (let ((program-list (split-string (shell-command-to-string "compgen -c") "\n" t ))
                  (file-directory-list (split-string (shell-command-to-string "compgen -f") "\n" t ))
                  (history-list (with-temp-buffer
                                  (insert-file-contents "~/.zsh_history")
                                  (split-string (buffer-string) "\n" t))))

              (delete-dups (append ;;program-list file-directory-list
                            history-list))))

  ;;         (defun vterm-completion-choose-item ()
  ;;           (completing-read "Choose: " (get-full-list) nil nil  (thing-at-point 'word 'no-properties))
  ;;           )
  ;; (setq-local thing-at-point-provider-alist
  ;;             (append thing-at-point-provider-alist
  ;;                     \\='((candidate . remove-before-semi-colon))))
  ;;         (defun vterm-completion ()
  ;;           (interactive)
  ;;           ;; (vterm-directory-sync)
  ;;           (let ((vterm-chosen-item (vterm-completion-choose-item)))
  ;;             (when (thing-at-point 'word)
  ;;               (vterm-send-meta-backspace))
  ;;             (when (stringp vterm-chosen-item)
  ;;               (setq vterm-chosen-item (cdr (split-string vterm-chosen-item ";"))))
  ;;             (vterm-send-string vterm-chosen-item ";")))

  ;;         (defun vterm-directory-sync ()
  ;;           "Synchronize current working directory."
  ;;           (interactive)
  ;;           (when vterm--process
  ;;             (let* ((pid (process-id vterm--process))
  ;;                    (dir (file-truename (format "/proc/%d/cwd/" pid))))
  ;;               (setq default-directory dir))))

  ;;         :bind (:map vterm-mode-map ("<tab>" . 'vterm-completion))
  )

multi-vterm

(use-package multi-vterm
  :bind (("C-c vt" . multi-vterm-project)
         ("C-c vn" . multi-vterm-next)
         ("C-c vp" . multi-vterm-prev)))

Eshell syntax highlighting

Taken from here.

(use-package eshell-syntax-highlighting
  :if window-system
  :after eshell-mode ;; Install if not already installed.
  :config
  ;; Enable in all Eshell buffers.
  (eshell-syntax-highlighting-global-mode +1))

polymode

(use-package polymode)

poly-styled-components-mode

;; (setq css-indent-offset 2)
;; (define-hostmode styled-components-hostmode
;;   :mode 'web-mode
;;   :protect-font-lock t)

;; (define-innermode poly-css-styled-components-innermode
;;   :mode 'scss-mode
;;   :head-matcher "[(?<!\\$){ css keyframes styled]\[^\n\t \]*`\n"
;;   :tail-matcher (cons "^\\s-*\\(`;\\)" 1)
;;   :body-indent-offset css-indent-offset
;;   :head-mode 'host
;;   :tail-mode 'host)

;; (define-innermode poly-js-inner-block-innermode
;;   :mode 'host
;;   :head-matcher "\\${"
;;   :tail-matcher #'pm-forward-sexp-tail-matcher
;;   :body-indent-offset css-indent-offset
;;   :can-nest t
;;   :head-mode 'host
;;   :tail-mode 'host)

;; (define-polymode styled-components-mode
;;   :hostmode 'styled-components-hostmode
;;   :innermodes '(poly-css-styled-components-innermode
;;                 poly-js-inner-block-innermode))

;; (setq auto-mode-alist
;;       (append '(("style\\.[jt]?s[x]?\\'". styled-components-mode))
;;               auto-mode-alist))

emacs-webkit

;; (use-package webkit
;;   :bind (("s-b" . xwidget-webkit-browse-url)) ;; Bind to whatever global key binding you want if you want
;;   :config
;;   (require 'webkit-ace) ;; If you want link hinting
;;   (require 'webkit-dark)) ;; If you want to use the simple dark mode

About

My emacs config


Languages

Language:Emacs Lisp 100.0%