Coding Init

I like λ

(defun toby/add-prettified-symbols ()
  (setq prettify-symbols-alist
          ("lambda" . 955)
          ("->"     . 10230)
          ("=>"     . 10233)

(add-hook 'haskell-mode-hook  'toby/add-prettified-symbols)

(global-prettify-symbols-mode 1)

80 Columns is Law

(defun set-window-width (n)
  "Set the current window to width N"
  (adjust-window-trailing-edge (selected-window) (- n (window-width)) t))

(defun set-window-columns ()
  "Set the selected window to 80(ish) columns."
  (set-window-width 80))

(global-set-key "\C-x7" 'set-window-columns)

Hooks Useful in All Programming Environments

Here are a couple functions that can help line up stubborn bits of code:

Activate/deactivate via customize:

(customize-variable-other-window 'global-highlight-changes-mode)
  • TODO clear change marks on commit

    Some variant of the following:

    (defun highlight-changes-remove-after-save ()
      "Remove previous changes after save."
      (make-local-variable 'after-save-hook)
      (add-hook 'after-save-hook
                (lambda ()
                  (highlight-changes-remove-highlight (point-min) (point-max)))))


  • State "EXPERIMENTAL" from [2017-12-06 Wed 17:23]
(require-package 'diff-hl (version-to-list "1.8.4"))
(autoload 'global-diff-hl-mode "diff-hl")
(autoload 'turn-on-diff-hl-mode "diff-hl")
(add-hook 'magit-post-refresh-hook 'diff-hl-magit-post-refresh)

EXPERIMENTAL Auto sex-p management

  • State "EXPERIMENTAL" from [2017-06-30 Fri 09:58]
  • EXPERIMENTAL Need to decide between paredit/smartparens
    • State "EXPERIMENTAL" from "TODO" [2017-12-10 Sun 12:58]
    • State "TODO" from [2017-12-10 Sun 12:58]
    (defun toby/activate-structured-editing (&optional strict?)
      (interactive "P")
      (require-package 'paredit)
      (require-package 'dash (version-to-list "2.13.0"))
      (require-package 'smartparens (version-to-list "1.11.0"))
      (if (require 'smartparens nil 'noerror)
            (require 'smartparens-config)
            (define-key smartparens-mode-map (kbd "C-k") 'sp-kill-sexp)
            (if strict?
                (smartparens-strict-mode t)
              (smartparens-mode t))
            (show-smartparens-mode t)
          (paredit-mode t)
          (show-paren-mode 1))))

Formatting Hooks/Functions

(define-key prog-mode-map (kbd "C-<tab>") 'indent-buffer)

(require-package 'rainbow-delimiters)
(autoload 'rainbow-delimiters-mode "rainbow-delimiters")

(require-package 'dash-at-point)

(require-package 'idle-highlight-mode)
(autoload 'idle-highlight-mode "idle-highlight-mode")
(setq-default indent-tabs-mode nil)     ; TABs can go straight to hell

(defun toby/coding-hooks ()
  (make-local-variable 'column-number-mode)
  (column-number-mode t)

  (set (make-local-variable 'comment-auto-fill-only-comments) t)
  (auto-fill-mode t)

  (when (> (display-color-cells) 8) (hl-line-mode t))

  (setq compilation-scroll-output 'first-error)

  (setq save-place t)

  (tool-bar-mode -1)

   nil '(("\\<\\(FIX\\|TODO\\|FIXME\\|HACK\\|REFACTOR\\):"
          1 font-lock-warning-face t)))

  (idle-highlight-mode t)

  ;; (highlight-changes-mode)


(add-hook 'prog-mode-hook 'toby/coding-hooks)

(defun run-coding-hook ()
  "Enable things that are convenient across all coding buffers.

   Not every programming mode yet inherits from prog-mode (new to
   Emacs 24), so this function provides a short-cut for including
   those hooks in another mode."
  (run-hooks 'prog-mode-hook))

REJECTED electric-align Mode

  • State "REJECTED" from "EXPERIMENTAL" [2017-07-28 Fri 10:15]
  • State "EXPERIMENTAL" from [2017-06-30 Fri 09:53]

Activates when not intended and rarely when actually intended. Also interferes with abbrev-mode and any other mode that advises SPC.

;; (add-to-list 'load-path (concat vendor-dir "electric-align"))
;; (autoload 'electric-align-mode "electric-align.el" nil t)

;; (add-hook 'prog-mode-hook 'electric-align-mode)
;; (remove-hook 'prog-mode-hook 'electric-align-mode)

ADOPTED Embedded Modes

  • State "ADOPTED" from [2017-09-21 Thu 14:26]
  • State "EXPERIMENTAL" from "REJECTED" [2017-09-21 Thu 14:26]
  • State "REJECTED" from "ADOPTED" [2017-09-21 Thu 14:26]
  • State "ADOPTED" from [2017-09-21 Thu 14:26]
(require-package 'mmm-mode)
(require 'mmm-auto)
(setq mmm-global-mode 'maybe)
(setq mmm-submode-decoration-level 1)

(defun toby/heredoc-get-mode (string)
  (message string)
  (string-match "<<[-~]?\\([a-zA-Z0-9_-]+\\)$" string)
  (let ((modename (downcase (match-string 1 string))))
    (message modename)
    (intern (concat modename "-mode"))))

(eval-after-load 'mmm-mode
         :match-submode toby/heredoc-get-mode
         :front "<<[-~]?\\([a-zA-Z0-9_-]+\\)"
         :front-offset (end-of-line 1)
         :face mm-code-submode-face
         :save-matches 1
         :back "^[ \t]*~1$"
         :delimeter-mode nil)))
     (mmm-add-mode-ext-class 'ruby-mode "\\.rb\\'" 'toby/heredoc)))

(add-to-list 'mmm-set-file-name-for-modes 'ruby-mode)


(setq-default indent-tabs-mode nil)
(defun untabify-buffer ()
  (untabify (point-min) (point-max)))

(defun indent-buffer ()
  (indent-region (point-min) (point-max)))

(defun cleanup-buffer ()
  "Perform a bunch of operations on the whitespace content of a buffer."

First, a function that allows another function to act on either a region or the buffer, based on whether a region is curently active.

(defun act-on-region-or-buffer (fn)
  "Given a function that operates between to points, pass it the
active region or the entire buffer."
  (let (p1 p2 bounds)
    (if (use-region-p)
        (setq p1 (region-beginning) p2 (region-end))
      (setq p1 (point-min) p2 (point-max)))
    (funcall fn p1 p2)))

Next, a function that applies a Regular Expression replacement to a region.

(defun replace-in (exp replace p1 p2)
    (narrow-to-region p1 p2)
    (goto-char (point-min))
    (while (re-search-forward exp nil t)
      (replace-match replace))))

Pad out parens: turn (x) into ( x )

(defun fix-parens ()
  "Fix misplaced parens in code buffers."
   (lambda (p1 p2)
     (replace-in "(\\([^[:space:])]\\)" "( \\1" p1 p2)
     (replace-in "\\([^[:space:](]\\))" "\\1 )" p1 p2))))

Do the same for hash-rockets: =>

(defun decompress-hash-rockets ()
  "Fix compressed hash rockets"
   (lambda (p1 p2)
      "\\1 => \\2"
      p1 p2))))

This function converts camel-case to underscores.

(defun underscore-region (start end)
  "Convert camelCase to under_scores in the active region."
  (interactive "r")
  (let ((case-fold-search nil)
        (exp "\\(\\b\\|[[:lower:]]\\)\\([[:upper:]]+\\)"))
      (narrow-to-region start end)
      (goto-char (point-min))
      (while (re-search-forward exp nil t)
          (concat (match-string 1) "_" (downcase (match-string 2))))))))

(defun underscore-word ()
  "Convert camelCase to under_score at the current word."
  (let ((bounds (bounds-of-thing-at-point 'word)))
    (let ((start (car bounds))
            (end   (cdr bounds)))
      (underscore-region start end))))
(provide 'coding-init)

Author: Toby Tripp

Created: 2018-02-09 Fri 15:33