Index Emagician Base Install Meta Interface Programming Text Org Lamp Journal Snippets jonnay.netFork on Github

General Programming

Table of Contents

1 Interface

1.1 Display

1.1.1 Line Numbers

I spend anywhere between 10%-90% of my week pair programming.

On a projector.

Being able to point to a line and give it a name like 45 is important.

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

1.1.2 Which Function

Display the function on the mode line.

Only because I am an info-junkie. Not because it is particularly useful from a UI perspective.

(which-function-mode t)

1.1.3 Check Parens

Enforce checking of parens in programming modes. Not 100% sure about this yet. But 90% sure.

(defun emagician/check-parens ()
  (when after-init-time   ; Don't check parens if we're initializing. 
    (condition-case err
        (check-parens)
      ((error) (message "Buffer has unmatched Parens or quote!")))))

(add-hook 'prog-mode-hook 'emagician/check-parens t)

1.1.4 Show Paren Mode

This config could use tweaking.

(setq show-paren-style 'mixed)
(setq show-paren-delay 0)
(show-paren-mode)

1.1.5 Rainbow Delimiters

Not 100% sure about this yet.

Rainbow Delimiters are static. It's always the same color regardless of where the point is.

(use-package rainbow-delimiters
  :demand
  :init
  (emagician/minor-in-major-mode rainbow-delimiters-mode prog-mode-hook)
  :config
  (set-face-attribute 'rainbow-delimiters-depth-1-face nil :foreground "grey43")
  (set-face-attribute 'rainbow-delimiters-depth-2-face nil :foreground "grey45")
  (set-face-attribute 'rainbow-delimiters-depth-3-face nil :foreground "grey47")
  (set-face-attribute 'rainbow-delimiters-depth-4-face nil :foreground "grey50")
  (set-face-attribute 'rainbow-delimiters-depth-5-face nil :foreground "grey55")
  (set-face-attribute 'rainbow-delimiters-depth-6-face nil :foreground "grey60")
  (set-face-attribute 'rainbow-delimiters-depth-7-face nil :foreground "grey65")
  (set-face-attribute 'rainbow-delimiters-depth-8-face nil :foreground "grey70")
  (set-face-attribute 'rainbow-delimiters-depth-9-face nil :foreground "grey75"))

1.1.6 Rainbow Blocks   disabled

Trying an experiment. Syntax highlight blocks based on overline.

It sould have been hella cool, but what happens is that the rainbow-block-face over-rides the entire face.

I'll need to learn more about emacs faces to continue.

(use-package rainbow-blocks
  :demand
  :init
  (emagician/minor-in-major-mode rainbow-blocks-mode prog-mode-hook)
  :config
  (custom-set-faces
   '(rainbow-blocks-depth-1-face ((t (:overline "grey10"))))
   '(rainbow-blocks-depth-2-face ((t (:overline "grey20"))))
   '(rainbow-blocks-depth-3-face ((t (:overline "grey30"))))
   '(rainbow-blocks-depth-4-face ((t (:overline "grey40"))))
   '(rainbow-blocks-depth-5-face ((t (:overline "grey50"))))
   '(rainbow-blocks-depth-6-face ((t (:overline "grey60"))))
   '(rainbow-blocks-depth-7-face ((t (:overline "grey70"))))
   '(rainbow-blocks-depth-8-face ((t (:overline "grey80"))))
   '(rainbow-blocks-depth-9-face ((t (:overline "grey90"))))))

(foo (bar (baz BLag) (bar baz (foo bar (foo bar ) baz blarg (foo BLag) (bar baz (foo bar (foo bar ) baz blarg (foo ) ) far ) b00) barg ) blarg ) foo foo)

1.1.7 Color Identifiers

Like manna from heaven.

This is one of the coolest modes so far. Yeah, it's slightly angry fruit salad, but it is also just… wow. It doesn't NEED a mode lighter, but it deserves it.

(use-package color-identifiers-mode
  :diminish (color-identifiers-mode . "🎨 ")
  :init
  (add-hook 'after-init-hook 'global-color-identifiers-mode))

1.1.8 Show whitespace

Whitespace unicode does good stuff with whitespace. Use that.

With unicode setup, it is much better.

(use-package whitespace
  :diminish "· "
  :init
  (add-hook 'prog-mode-hook 'whitespace-mode)
  (use-package unicode-whitespace
    :config
    (unicode-whitespace-setup 'subdued-faces)))

1.1.9 Prettify Symbols

Oh man, with the unicode pretty symbols, this is sweet. I have been considering making the jump to FiraCode, but there is so many weird little things about it I am unsure of.

Prettify Symbols is 80% there, and looks freaking hawt.

(global-prettify-symbols-mode 1)
1.1.9.1 Prettify Symbols List

Thanks to Artur Malabarba http://endlessparentheses.com/using-prettify-symbols-in-clojure-and-elisp-without-breaking-indentation.html , Inspired by: https://github.com/tonsky/FiraCode.

 (defvar emagician/prettify-list
   '(("lambda" . 955)
     ("<=" . (?\s  (Br . Bl) ?\s (Bc . Bc) ?≤))
     (">=" . (?\s  (Br . Bl) ?\s (Bc . Bc) ?≥))
     ("->" . ?⟶)
     ("=>" . ?⟹)
     ("==" . ?⩵)
     ("//" . (?\s  (Br . Bl) ?\s (Bc . Bc) ?⫽))
     ("!=" . (?\s  (Br . Bl) ?\s (Bc . Bc) ?≠))
     ("->>" .  (?\s (Br . Bl) ?\s (Br . Bl) ?\s
                    (Bl . Bl) ?- (Bc . Br) ?- (Bc . Bc) ?>
                    (Bc . Bl) ?- (Br . Br) ?>))))

(setq prettify-symbols-unprettify-at-point 'right-edge)

(emagician/defhook emagician-prettify-code prog-mode-hook
   (setq prettify-symbols-alist emagician/prettify-list))
You enter Displayed
lambda λ
<=
>=
->
=>
//
!=
==

Using http://unicode-table.com/ helped a LOT

1.1.9.1.1 How does this jiggery-pokery work?

Prettify is basically a call to compose region, it automagickally sets start and end, and the second arg of the a-list is components

So for ("lambda" . 955), "lambda" just gets turned into char 955, or λ.

But for ("<=" . (?\s (Br . Bl) ?\s (Bc . Bc) ?≥))?

If it is a vector or list, it is a sequence of alternate characters and composition rules, where (2N)th elements are characters and (2N+1)th elements are composition rules to specify how to compose (2N+2)th elements with previously composed N glyphs.

A composition rule is a cons of global and new glyph reference point symbols. See the documentation of reference-point-alist for more details.

Rrrriiiiggghhhhht.

I don't entirely understand this yet.

1.1.10 Outline Mode

Sexy Org-mode mana from heaven inside of code.

(use-package outshine
  :init
  (add-hook 'outline-minor-mode-hook 'outshine-hook-function)
  (add-hook 'prog-mode-hook 'outline-minor-mode))

1.2 Editing

1.2.1 Tabs

Probably one of the most disputed things when "growing up" as a programmer. It's seemed to have settled town to a tab stop of 2, with no physical Control I tabs.

Or maybe that's just age. I used to really want 4-space-wide physical tabs, but now, not so much. Explicit spaces are probably the easiest for everyone involved.

In short, it's fucking moot. Go with the project, and find peace. If it's really brutal, make computers format it for you incoming, and reformat it for everyone else outgoing.

(setq-default indent-tabs-mode nil)

1.2.2 Spell Checking on Programming Modes

Gah. So bad at this.

emagician/minor-in-major-mode doesn't work because flyspell-prog-mode doesn't take an argument.

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

1.2.3 Yanking

This is such a handy piece of functionality. It just works.

(defadvice yank (after indent-region activate)
  "indent the region after a yank if we're in a programming mode."
  (if (derived-mode-p 'prog-mode)
      (indent-region (region-beginning) (region-end) nil)))

1.2.4 YAS

The more boilerplate your language requires, the more abstractions it can afford the user.

There is always a little bit of boiler-plate that is required.

(add-hook 'prog-mode-hook 'yas-minor-mode-on)

1.2.5 Smart Paren Mode

I am not 100% convinced about these keybindings. Honestly I snarfed and barfed from another config somewhere.

(use-package smartparens
  :diminish "⒮"
  :bind (("M-9" . sp-backward-sexp)
         ("M-0" . sp-forward-sexp)
         :map smartparens-mode-map
         (("C-<right>" . sp-forward-slurp-sexp)
          ("C-<left>" . sp-forward-barf-sexp)
          ("C-M-<right>" . sp-backward-barf-sexp)
          ("C-M-<left>" . sp-backward-slurp-sexp)
          ("M-S-s" . sp-splice-sexp)))
  :init
  (add-hook 'prog-mode-hook #'turn-on-smartparens-mode)
  :config
  (add-to-list 'sp-sexp-suffix '(json-mode regex ""))
  (add-to-list 'sp-sexp-suffix '(es-mode regex ""))

  (require 'smartparens-config)
  (require 'smartparens-ruby)
  (add-hook 'sh-mode-hook
            (lambda ()
              ;; Remove when https://github.com/Fuco1/smartparens/issues/257
              ;; is fixed
              (setq sp-autoescape-string-quote nil)))

  ;; Remove '' pairing in elisp because quoting is used a ton
  (sp-local-pair 'minibuffer-inactive-mode "'" nil :actions nil)
  (sp-local-pair 'web-mode "<" nil :actions nil)
)

1.2.6 TODO Fix pairs for webmode,

2 Tools

2.1 Flycheck

Flycheck is good, but not great.

SACRE-BLEU! How could I say such a thing?

But it doesn't work over tramp. Fine if you are editing a file remotely, less fine if it's just a VM.

(use-package flycheck
  :diminish "🦋 "
  :init
  (global-flycheck-mode))

(remove-hook 'prog-mode-hook 'turn-on-flycheck-color-mode-line-mode)

2.2 DZ, make it easy to run secondary services

This is one of those packages that hasn't updated in forever.

And doesn't need to.

(use-package dizzee)

2.3 Org Source… babel babel babel!

I use org babel a lot. (duh).

It's nice to have helpers to see if we are in org-babel mode.

(defun emagician/org-src-mode-p () 
  "Test to see wehther the current mode is in org-src mode"
  (member 'org-src-mode minor-mode-list))

(ert-deftest emagician/org-src-mode-p ()
  (let ((minor-mode-list '()))
    (should-not (emagician/org-src-mode-p)))
  (let ((minor-mode-list '(foo bar)))
    (should-not (emagician/org-src-mode-p)))
  (let ((minor-mode-list '(org-src-mode)))
    (should (emagician/org-src-mode-p))))

2.4 Ediff

Tweak Ediff to be better

(setq ediff-window-setup-function 'ediff-setup-windows-plain
      ediff-split-window-function 'split-window-horizontally)

2.5 Jenkins

So far so good.

(use-package jenkins
  :load-path "~/projects/emacs/jenkins.el/") 

2.5.1 My wishlist

2.5.1.1 TODO Refresh PR accepted
2.5.1.2 TODO Add an idle refresh timer
2.5.1.3 TODO Check to make sure it's async. If not, make it.

2.6 Helm Dash for manuals

The secret sauce here is activating the doc set.

(use-package helm-dash
  :init
  (setq helm-dash-browser-func 'eww))

2.6.1 TODO fix this and make it work.

2.6.2 TODO bugfix for the shell-command-to-string bug

2.7 Version control

Version control Gets it's own section.

Don't manage ancient version control backends.

(setq vc-handled-backends '(Git))

2.7.1 Editing

Modes for editing git-specific files.

(use-package git-commit)
(use-package gitconfig-mode)
(use-package gitignore-mode)

2.7.2 Magit

Magit is like manna from heaven.

It is seriously one of the coolest Emacs packages out there.

(use-package magit
  :diminish "🔮 "
  :init
  (when (locate-file "git-achievements" exec-path)
    (setq magit-git-executable "git-achievements"))
  :bind 
  ("C-c m" . magit-status)
  :config)
2.7.2.1 Interact with github

I haven't given up on this yet, but I am getting close. :/

It doesn't quite work.

(use-package magit-gh-pulls
  :diminish "🆙 "
  :init
  (add-hook 'magit-mode-hook 'turn-on-magit-gh-pulls))
2.7.2.2 Add a function for automagickally setting the config
(defun emagician/set-github-gh-pull-config (user repo)
  "Set the proper config for gh-pulls."
  (interactive "sUser/Org: \nsRepo: ")
  (magit-git-command-topdir (format "config magit.gh-pulls-repo %s/%s" user repo)
                            (magit-toplevel)))

2.7.3 Git Gutter

So pleasant.

(use-package git-gutter-fringe+
  :diminish (git-gutter+-mode . "")
  :init
  (setq git-gutter-fr+-side 'right-fringe)
  (add-hook 'text-mode-hook 'git-gutter+-mode)
  (add-hook 'prog-mode-hook 'git-gutter+-mode))

2.8 Project Management

2.8.1 Projectile

The last time I used projectile it was not what I needed at all.

But that was a long time ago.

Trying it again, it does not play well with tramp. A bit of a pity.

Now that I am off of tramp, maybe projectile will start to work again?

(use-package projectile
  :init
  (setq projectile-mode-line '(:eval (format " 📂[%s]" (projectile-project-name))))
  (projectile-global-mode))

(with-eval-after-load 'helm
  (use-package helm-projectile))

2.9 SQL Mode

2.9.1 TODO company backend for mysql completions. Should totally either be a thing, or a thing I make.

3 Languages

Each language gets it's own file.

(emagician/load "Programming-Lisp")
(emagician/load "Programming-Ruby")
(emagician/load "Programming-Web")
(emagician/load "Programming-Sh")

4 Quazi-related Modes

4.1 Yaml

(use-package yaml-mode
  :mode "\\.yml\\'")

Footnotes:

Author: Jonathan Arkell

Created: 2018-05-18 Fri 10:30

Validate