My personal dotfiles
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

README.org 42KB

About

This literate config is best read here or in emacs. This page is generated and kept up to date using a combination of travis ci and ReadTheOrg. If you want to see the script that travis uses here is the bash script it runs and this is the .el file that it runs through emacs to generate the html page (this was mostly stolen from IvanMalison).

Included in this section is also my export headers. These are responsible for including the ReadTheOrg theme as well as some metadata and options like title, author, table of contents etc. If you wish to see the headers I'm using, this is the raw org file.

Variables

Variables come at the beginning so that they're consistently available. If you don't care about these click here to skip over them.


  (defvar wolfe/literate-config-name "README.org"
    "The name of my literate config")

  (defvar wolfe/init-file (concat user-emacs-directory wolfe/literate-config-name)
    "The path to my literate config file")

  (defvar wolfe/linux? (eq system-type 'gnu/linux)
    "Are we on linux?")

(defvar wolfe/windows? (eq system-type 'windows-nt)
    "Are we on windows?")

  (defvar wolfe/org-ellipsis
    (if (display-graphic-p)
        "⤵"
      "...")
    "The indicates if an `org-mode' tree can be expanded")

  (defvar wolfe/project-path
    (cond
     (wolfe/linux? "~/Projects/")
     (wolfe/windows? "C:/dev/")
     (:else nil))
    "Path to my projects directory")

  (defvar wolfe/org-dropbox-path
    (cond
     (wolfe/linux?
      "~/Dropbox/org/")
     (wolfe/windows?
      "C:\\Users\\Josh\\Dropbox\\org\\")
     (:else nil))
    "Path to my org files inside dropbox")

  (defvar wolfe/using-light nil
    "Indicates whether we're using my light theme")

Startup

My graphical settings change depending on whether I'm in terminal and if a command line flag (-light) was specified.

Theme Setup

This should be run regardless of whether I'm in terminal vs gui or dark vs light.


  (setq custom-theme-directory "~/.emacs.d/themes")

  (setq wolfe/using-light (member "-light" command-line-args))
  (setq command-line-args (delete "-light" command-line-args))

Dark

Configuration for my dark theme base16 default dark which is loaded by default.

Common


  (defun wolfe/dark-setup ()
    (use-package base16-theme
      :config
      (load-theme 'base16-default-dark t)

      (if (display-graphic-p)
          (wolfe/dark-gui-setup)
        (wolfe/dark-term-setup))))

Graphical


  (defun wolfe/dark-gui-setup ()
      (defvar my/base16-colors base16-default-dark-colors)
      (setq evil-emacs-state-cursor   `(,(plist-get my/base16-colors :base0D) box)
            evil-insert-state-cursor  `(,(plist-get my/base16-colors :base0D) bar)
            evil-motion-state-cursor  `(,(plist-get my/base16-colors :base0E) box)
            evil-normal-state-cursor  `(,(plist-get my/base16-colors :base07) box)
            evil-replace-state-cursor `(,(plist-get my/base16-colors :base08) bar)
            evil-visual-state-cursor  `(,(plist-get my/base16-colors :base09) box))
      (set-face-attribute 'fringe nil :background nil)

    (custom-set-faces
     '(region ((t (:background "gray19"))))
     '(org-block ((t (:foreground "#d8d8d8"))))
     '(org-done ((t (:box (:line-width 1) :weight bold))))
     '(org-level-1 ((t (:inherit outline-1 :height 1.3))))
     '(org-todo ((t (:box (:line-width 1) :weight bold))))))

Terminal


  (defun wolfe/dark-term-setup ()
    (setq nlinum-format "%d ")
    (custom-set-faces
     '(line-number ((t (:background "color-18" :foreground "brightblack"))))
     '(ivy-current-match ((t (:background "color-18" :foreground "color-16"))))
     '(linum ((t (:background "color-18"))))
     '(region ((t :background "color-19")))
     '(mode-line ((t (:background "color-19" :foreground "brightblue" :box nil))))
     '(mode-line-inactive
       ((t (:background "color-18" :foreground "color-244"))))))

Light

Configuration for my light theme leuven. This is only loaded when the -light flag is specified on the command line.

Common


  (defun wolfe/light-setup ()
    (use-package leuven-theme
      :config
      (load-theme 'leuven t)))

Display check

This checks which setup we're in and calls the appropriate function above.


  (if wolfe/using-light
      (wolfe/light-setup)
    (wolfe/dark-setup))

General Settings

Basic settings I can't really live without.

Splash and Startup

This makes sure I'm presented with a nice blank =*scratch*= buffer when emacs starts up.


  (setq inhibit-splash-screen t
        inhibit-startup-message t
        inhibit-startup-echo-area-message "wolfe"
        initial-scratch-message "") ; No scratch text

Graphics

Bars

I don't really want to have to look at menu bars that I'm not going to use


  (tool-bar-mode -1) ; No toolbar
  (scroll-bar-mode -1) ; Hide scrollbars
  (menu-bar-mode -1) ; No menubar

Fonts

I like Inconsolata so use it if installed.


  (when (member "Inconsolata" (font-family-list)) ; Set default font
    (add-to-list 'default-frame-alist '(font . "Inconsolata-15" ))
    (set-face-attribute 'default t :font "Inconsolata-15"))

Make sure that UTF-8 is used everywhere.


  (set-terminal-coding-system  'utf-8)
  (set-keyboard-coding-system  'utf-8)
  (set-language-environment    'utf-8)
  (set-selection-coding-system 'utf-8)
  (setq locale-coding-system   'utf-8)
  (prefer-coding-system        'utf-8)
  (set-input-method nil)

Column Marker


  (load-file "~/.emacs.d/lisp/column-marker.el")
  (add-hook 'prog-mode-hook (lambda () (interactive) (column-marker-1 81)))
  (custom-set-faces
   '(column-marker-1 ((t (:background "dim gray")))))

Personal Defaults

Nothing to crazy here just the type of behaviour I personally expect as default.


  (show-paren-mode t) ; Highlights matching parens
  (fset 'yes-or-no-p 'y-or-n-p) ; y/n instead of yes/no
  (blink-cursor-mode -1) ; No need to flash the cursor
  (column-number-mode t) ; Show column in mode-line
  (delete-selection-mode 1) ; Replace selection on insert
  (setq-default truncate-lines t) ; Don't wrap
  (setq vc-follow-symlinks t) ; Always follow symlinks
  (setq-default indent-tabs-mode nil)
  (setq custom-file "~/.emacs.d/custom.el") ; Set custom file & don't load it
  (setq tags-revert-without-query t) ; Don't ask to reload TAGS file
  (setq source-directory "~/Projects/emacs/")

Misc

Vim Scrolloff

This makes scrolling gradual rather than by half page. I find that the half page scroll really makes me lose where I am in the file so here I make sure to scroll one line at a time. In addition I want to keep what I'm working on centered so I start scrolling when the cursor is 10 lines away from the margin.

This behaviour in general emulates the scrolloff option in vim.


  (setq scroll-margin 10
        scroll-step 1
        scroll-conservatively 10000
        scroll-preserve-screen-position 1)

Shell Tweaks


  (setq explicit-shell-file-name
        (if (file-readable-p "/usr/bin/zsh") "/usr/bin/zsh" "/bin/bash"))
  (when (eq system-type 'windows-nt)
    (setq explicit-shell-file-name "cmdproxy.exe"))

Mode Line

If we're in GUI emacs we make sure to use powerline otherwise we use a custom mode line configuration.


      (if (display-graphic-p)
          (use-package powerline
            :init
            (defadvice powerline-major-mode (around delight-powerline-major-mode activate)
              (let ((inhibit-mode-name-delight nil))
                ad-do-it))

            :config
            (setq powerline-arrow-shape 'curve
                  powerline-display-buffer-size nil
                  powerline-display-mule-info nil)
            (powerline-default-theme)
            (remove-hook 'focus-out-hook 'powerline-unset-selected-window)
            (setq powerline-height 24))

        (setq-default mode-line-format
         (list
          " "
          ;; is this buffer read-only?
          '(:eval (when buffer-read-only
                    (propertize "RO"
                                'face 'font-lock-type-face
                                'help-echo "Buffer is read-only")))

          ;; was this buffer modified since the last save?
          '(:eval (when (buffer-modified-p)
                    (propertize "M"
                                'face 'font-lock-warning-face
                                'help-echo "Buffer has been modified")))

          " "
          ;; the buffer name; the file name as a tool tip
          '(:eval (propertize "%b " 'face 'font-lock-keyword-face
                              'help-echo (buffer-file-name)))


          ;; the current major mode for the buffer.
          "["

          '(:eval (propertize (format-mode-line mode-name) 'face '(:family "Arial")
                              'help-echo buffer-file-coding-system))
          '(:eval (propertize (format-mode-line minor-mode-alist)
                              'face '(:family "Arial")))
          "]             "

          ;; line and column
          "(" ;; '%02' to set to 2 chars at least; prevents flickering
          (propertize "%02l" 'face 'font-lock-type-face) ","
          (propertize "%02c" 'face 'font-lock-type-face)
          ") "

          ;; relative position, size of file
          "["
          (propertize "%p" 'face 'font-lock-constant-face) ;; % above top
          "/"
          (propertize "%I" 'face 'font-lock-constant-face) ;; size
          "] "

          ;; add the time, with the date and the emacs uptime in the tooltip
          '(:eval (propertize (format-time-string "%H:%M")
                              'help-echo
                              (concat (format-time-string "%c; ")
                                      (emacs-uptime "Uptime:%hh"))))
          )))

Line Numbers

Vim-like relative line numbering. If we're on the latest versions of emacs (i.e. 26.0.50 or higher) then we should use the native line numbering otherwise we fall back to nlinum-relative.


  (if (fboundp 'display-line-numbers-mode)
      (progn
        (setq display-line-numbers 'relative)
        (add-hook 'prog-mode-hook 'display-line-numbers-mode))
    (progn
      (use-package nlinum-relative
        :config
        (nlinum-relative-setup-evil)
        (setq nlinum-relative-redisplay-delay 0.25)
        (setq nlinum-relative-current-symbol "")
        (add-hook 'prog-mode-hook 'nlinum-relative-mode))))

Functions

Face Under Point

Returns the font lock face that's under the cursor.


  (defun what-face (pos)
    (interactive "d")
    (let ((face (or (get-char-property (point) 'read-face-name)
                    (get-char-property (point) 'face))))
      (if face (message "Face: %s" face) (message "No face at %d" pos))))

Compile Project

Compiles the project without a prompt.


  (defun wolfe/compile-no-prompt ()
    (interactive)
    (let ((compilation-read-command nil))
      (compile (eval compile-command))))

Compile Dotfiles

Compiles all el files in the ~/.emacs.d directory.


  (defun wolfe/compile-dot-emacs ()
    "Byte-compile dotfiles."
    (interactive)
    (byte-recompile-directory user-emacs-directory 0))

  (defun wolfe/clear-all-elc ()
    (interactive)
    (shell-command "find ~/.emacs.d/ -name \"*.elc\" -type f -delete"))

  (defun wolfe/remove-elc-on-save ()
    "If you're saving an emacs-lisp file, likely the .elc is no longer valid."
    (add-hook 'after-save-hook
              (lambda ()
                (if (file-exists-p (concat buffer-file-name "c"))
                    (delete-file (concat buffer-file-name "c"))))
              nil t))
  (add-hook 'emacs-lisp-mode-hook 'wolfe/remove-elc-on-save)

Find Tags

Looks up tag under point.


  (defun wolfe/find-tag ()
    "Jump to the tag at point without prompting"
    (interactive)
    (find-tag (find-tag-default)))

  (defun wolfe/create-tags ()
    "Create the tags table"
    (interactive)
    (save-window-excursion (shell-command "etags -R -o ETAGS *")))

  (defadvice xref-find-definitions (around refresh-etags activate)
    "Rerun etags and reload tags if tag not found and redo find-tag.
     If buffer is modified, ask about save before running etags."
    (condition-case err
        ad-do-it
      (error (and (buffer-modified-p) (not (ding))
                  (save-buffer))
             (save-window-excursion (shell-command "etags -R *"))
             ad-do-it)))

Terminal Suspend

Fixes C-z in terminal.


  (defun wolfe/controlz ()
    (interactive)
    (when (eq (display-graphic-p) nil)
      (suspend-frame)))

Dropbox

Utility functions for finding Dropbox directories/files.


  (defun wolfe/org-open (name)
    "Opens the file in the dropbox path"
    (interactive)
    (evil-buffer-new nil (concat wolfe/org-dropbox-path name ".org")))

  (defun wolfe/dropbox-start ()
    (interactive)
    (if (eq nil (file-exists-p "/virtual/wolfejos/dropbox/.dropbox-dist"))
        (call-process-shell-command "(python ~/.emacs.d/dropbox.py start -i&)")
      (call-process-shell-command "(python ~/.emacs.d/dropbox.py start&)")))

  (defun wolfe/dropbox-stop ()
    (interactive)
    (call-process-shell-command "python ~/.emacs.d/dropbox.py stop&"))

Reload

For reloading init.el file without restarting.


  (defun wolfe/load-init ()
    "Reloads init file"
    (interactive)
    (load-file "~/.emacs.d/init.el"))

Narrowing

Better narrowing.


  (defun narrow-or-widen-dwim (p)
    "Widen if buffer is narrowed, narrow-dwim otherwise.
  Dwim means: region, org-src-block, org-subtree, or
  defun, whichever applies first. Narrowing to
  org-src-block actually calls `org-edit-src-code'.

  With prefix P, don't widen, just narrow even if buffer
  is already narrowed."
    (interactive "P")
    (declare (interactive-only))
    (cond ((and (buffer-narrowed-p) (not p)) (widen))
          ((region-active-p)
           (narrow-to-region (region-beginning)
                             (region-end)))
          ((derived-mode-p 'org-mode)
           ;; `org-edit-src-code' is not a real narrowing
           ;; command. Remove this first conditional if
           ;; you don't want it.
           (cond ((ignore-errors (org-edit-src-code) t)
                  (delete-other-windows))
                 ((ignore-errors (org-narrow-to-block) t))
                 (t (org-narrow-to-subtree))))
          ((derived-mode-p 'latex-mode)
           (LaTeX-narrow-to-environment))
          (t (narrow-to-defun))))

  (defun wolfe/man ()
    (if (executable-find "man")
        (man (word-at-point))
      (woman)))

Open C# Project File

This function prompts for a file. It then opens that file and looks for a src/ directory above it. The dir can be any number of levels higher. In that folder it looks for a C# .sln file and starts the an omnisharp server for that project.


  (defun wolfe/csharp-project ()
    (interactive)
    (setq path (read-file-name "File: " wolfe/project-path))
    (setq split-path (split-string path "/"))
    (if (member "src" split-path)
        (catch 'loop
          (dolist (item (reverse split-path))
            (if (string-equal item "src")
                (throw 'loop nil)
              (delete item split-path)))
          (message "src/ directory not found")))

    (if (or (equal '("c:") split-path) (equal '() split-path))
        (message "Could not find src directory for specified project")
      (progn
        (omnisharp-start-omnisharp-server (mapconcat 'identity split-path "/"))
        (find-file path))))

Hot Expand

Is used in one of my hydras wolfe/hydra-org-expand. For inserting org-templates.


  (defun hot-expand (str &optional additional-text)
    "Expand org template."
    (insert str)
    (org-try-structure-completion)
    (when additional-text
      (insert additional-text)
      (next-line)))

Ag Project If In Project

If we're inside of a projectile project we'll use projectile-ag to search the project otherwise just normal ag frow our working directory does the job.


  (defun wolfe/ag-try-project ()
    (interactive)
    (if (projectile-project-p)
        (call-interactively 'projectile-ag)
      (call-interactively 'ag)))

Projectile Invalidate From List

Select project from list of projectile projects to invalidate.


  (defun wolfe/projectile-invalidate-list ()
    (interactive)
    (projectile-invalidate-cache t))

User Pass Tupple

Uses GPG to decrypt file and returns a list of the contents split on spaces.


  (defun wolfe/get-user-pass (file)
    (split-string
     (car (last (split-string
                 (shell-command-to-string (concat "gpg --output - --decrypt "
                                                  (expand-file-name file)))
                 "[|\n]" t "[ 	\n]"))) " "))

Org Mode

General

Setup some basic quality of life org settings.


  (setq org-pretty-entities t
        org-src-fontify-natively t
        org-src-tab-acts-natively t
        org-src-window-setup 'current-window
        org-fontify-whole-heading-line t
        org-fontify-done-headline t
        org-fontify-quote-and-verse-blocks t
        org-log-done 'time
        org-agenda-use-time-grid nil
        org-agenda-skip-deadline-if-done t
        org-agenda-skip-scheduled-if-done t
        org-ellipsis wolfe/org-ellipsis)

  (org-babel-do-load-languages
   'org-babel-load-languages
   '((shell . t)
     (  dot . t)))

  (global-set-key "\C-cl" 'org-store-link)

  ;; ispell ignores SRC blocks
  (add-to-list 'ispell-skip-region-alist '("#\\+BEGIN_SRC" . "#\\+END_SRC"))
  (add-to-list 'ispell-skip-region-alist '("#\\+BEGIN_LATEX" . "#\\+END_LATEX"))

  ;; Refresh images after executing a src block
  (add-hook 'org-babel-after-execute-hook
            '(lambda ()
               (when org-inline-image-overlays
                 (org-redisplay-inline-images))))

  ;; Open PDFs with zathura
  (add-hook 'org-mode-hook
            '(lambda ()
               (setq org-file-apps
                     (append '(("\\.pdf\\'" . "zathura \"%s\"")) org-file-apps))))

Bullets

Replaces the asterisks with nice UTF-8 bullets.


  (use-package org-bullets
    :config
    (add-hook 'org-mode-hook (lambda () (org-bullets-mode 1))))

Agenda

Setup org agenda for managing my life.


  (use-package org-agenda
    :ensure nil
    :bind (("C-c a" . org-agenda)
           :map org-agenda-mode-map
           ("j" . org-agenda-next-item)
           ("k" . org-agenda-previous-item))
    :config
    ;; Formats the agenda into nice columns
    (setq org-agenda-prefix-format
          '((agenda . " %i %-12t% s %-12(car (last (org-get-outline-path)))")
            (timeline . "  % s")
            (todo . " %i %-12:c")
            (tags . " %i %-12:c")
            (search . " %i %-12:c")))

    ;; Sets location of org files
    (setq org-agenda-files '((concat wolfe/org-dropbox-path "everything.org")))
    (setq browse-url-browser-function 'browse-url-chromium))

Export

Setup html for syntax highlighting on export and add the apppropriate minted package for PDF export.


  (use-package htmlize)

  (require 'ox-latex)
  (add-to-list 'org-latex-packages-alist '("" "minted"))
  (setq org-latex-listings 'minted)
  (setq org-latex-pdf-process
        '("pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"
          "pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"
          "pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"))

Keymaps

Hydra

Customizable popup menus.


  (use-package hydra)

Major Modes

C#


  (setq wolfe/hydra-csharp
        (defhydra hydra-csharp (:color blue)
          "Omnisharp"
          ("d" omnisharp-go-to-definition              "Goto definition")
          ("D" omnisharp-go-to-definition-other-window "Pop-open definition")
          ("u" omnisharp-find-usages                   "Find usages")
          ("r" omnisharp-rename                        "Rename symbol")
          ("R" omnisharp-reload-solution               "Reload solution")
          ("i" omnisharp-code-format-region            "Indent region")
          ("I" omnisharp-code-format-entire-file       "Indent entire file")
          ))

Org Mode


  (setq wolfe/hydra-org
        (defhydra hydra-org (:color blue)
          "Org Mode"
          ("t" (funcall wolfe/hydra-org-expand) "Expand template")))

Org Templates


  (setq wolfe/hydra-org-expand
        (defhydra hydra-org-template (:color blue :hint nil)
          "
          _c_enter  _q_uote    _L_aTeX:
          _l_atex   _e_xample  _i_ndex:
          _a_scii   _v_erse    _I_NCLUDE:
          _s_rc     _t_angle   _H_TML:
          _h_tml    _d_ot src  _A_SCII:
          "
          ("s" (hot-expand "<s"))
          ("e" (hot-expand "<e"))
          ("q" (hot-expand "<q"))
          ("v" (hot-expand "<v"))
          ("t" (hot-expand "<s" "emacs-lisp :tangle yes"))
          ("d" (hot-expand "<s" "dot :file TMP.png :cmdline -Kdot -Tpng"))
          ("c" (hot-expand "<c"))
          ("l" (hot-expand "<l"))
          ("h" (hot-expand "<h"))
          ("a" (hot-expand "<a"))
          ("L" (hot-expand "<L"))
          ("i" (hot-expand "<i"))
          ("I" (hot-expand "<I"))
          ("H" (hot-expand "<H"))
          ("A" (hot-expand "<A"))))

Minor Modes

Projectile


  (setq wolfe/hydra-projectile
        (defhydra hydra-projectile (:color blue :columns 4)
          "Projectile"
          ("f" counsel-projectile-find-file        "Find File")
          ("s" counsel-projectile-switch-project   "Switch Project")
          ("k" projectile-kill-buffers             "Kill Buffers")
          ("c" projectile-invalidate-cache         "Clear Cache")

          ("d" counsel-projectile-find-dir         "Find Directory")
          ("o" projectile-multi-occur              "Multi Occur")
          ("P" projectile-clear-known-projects      "Clear Projects")
          ("C" wolfe/projectile-invalidate-list    "Clear A Cache")
          ))

Jira


  (setq wolfe/hydra-jira
        (defhydra hydra-jira (:color blue :columns 4)
          "Jira"
          ("p" org-jira-get-projects             "Get Projects")
          ("b" org-jira-browse-issue             "Browse Issue")
          ("g" org-jira-get-issues               "Get Issues")
          ("u" org-jira-update-issue             "Update Issue")

          ("p" org-jira-progress-issue           "Update Issue Progress")
          ("a" org-jira-assign-issue             "Assign Issue")
          ("r" org-jira-refresh-issue            "Refresh Issue")
          ("R" org-jira-refresh-issues-in-buffer "Refresh Issues in Buffer")

          ("c" org-jira-create-issue             "Create Issue")
          ("y" org-jira-copy-current-issue-key   "Copy Current Issue Key")
          ("s" org-jira-create-subtask           "Create Subtask")
          ("G" org-jira-get-subtasks             "Get Subtasks")

          ("U" org-jira-update-comment           "Update Comment")
          ("t" org-jira-todo-to-jira             "Todo to Jira")
          ("O"  (funcall wolfe/hydra-org-expand)  "Org Hydra")))

Default


  (setq wolfe/hydra-default
        (defhydra hydra-default (:color blue)
          "Default"
          ("o" (funcall wolfe/hydra-org) "Org Mode")
          ("#" (funcall wolfe/hydra-csharp) "C# Mode")))

Selector


  (defun wolfe/hydra-selector ()
    (cond
     ((derived-mode-p 'csharp-mode) wolfe/hydra-csharp)
     ((bound-and-true-p org-jira-mode) wolfe/hydra-jira)
     ((derived-mode-p 'org-mode) wolfe/hydra-org)
     (:else wolfe/hydra-default)))

Evil & General

General


    (use-package general)

Evil


  (use-package evil
    :demand
    :init
    (setq evil-want-C-u-scroll t) ; Unbind <C-u> for evil mode's use
    (setq evil-want-C-i-jump nil)
    :config
    (evil-mode t)
    (setq evil-split-window-below t
          evil-vsplit-window-right t
          evil-lookup-func #'wolfe/man)
    (setq-default evil-symbol-word-search t)
    (custom-set-variables '(evil-search-module (quote evil-search)))
    (evil-ex-define-cmd "re[load]" 'wolfe/load-init) ; Custom reload command
    (evil-ex-define-cmd "Q" 'save-buffers-kill-terminal) ; For typos
    (define-key evil-ex-map "e " 'counsel-find-file) ; Trigger file completion :e
    (global-unset-key (kbd "M-SPC")) ; Unbind secondary leader

    (general-create-definer wolfe/bind-leader
                            :keymaps 'global
                            :states '(normal insert visual emacs)
                            :prefix "SPC"
                            :non-normal-prefix "M-SPC")

    :general
    (:states 'motion
             "k" 'evil-previous-visual-line
             "j" 'evil-next-visual-line)

    (:states 'operator
             "k" 'evil-previous-line
             "j" 'evil-next-line)

    (:states 'visual
             "<" (lambda ()
                   (interactive)
                   (evil-shift-left (region-beginning) (region-end))
                   (evil-normal-state)
                   (evil-visual-restore))
             ">" (lambda ()
                   (interactive)
                   (evil-shift-right (region-beginning) (region-end))
                   (evil-normal-state)
                   (evil-visual-restore)))

    (:states 'normal
             "C-z"  'wolfe/controlz
             "C-l"  'evil-ex-nohighlight)

    (:states 'normal :prefix "g"
             "a" (lambda (beginning end)
                   (interactive "r")
                   (if (use-region-p)
                       (align beginning end)
                     (align-current)))
             "A" 'align-regexp)


    (wolfe/bind-leader
     "w"  'save-buffer
     "S"  'eval-buffer
     "s"  'eval-defun
     "b"  'mode-line-other-buffer
     "k"  'kill-buffer
     "m"  'ivy-switch-buffer
     "t"  'wolfe/find-tag
     "e"  'iedit-mode
     "c"  'wolfe/compile-no-prompt
     "n"  'narrow-or-widen-dwim
     "a"  'org-agenda
     "g"  'magit-status
     "f"  'wolfe/ag-try-project
     "''" 'org-edit-src-exit
     "#" 'wolfe/csharp-project
     "p" (lambda() (interactive) (funcall wolfe/hydra-projectile))
     ";" (lambda() (interactive) (save-excursion (end-of-line) (insert-char ?\;)))
     "id" (lambda() (interactive) (indent-region (point-min) (point-max)))
     "o"   (lambda() (interactive) (wolfe/org-open "everything"))
     "SPC" (lambda() (interactive) (funcall (wolfe/hydra-selector)))
     "init" (lambda() (interactive) (evil-buffer-new nil wolfe/init-file))))


Evil Surround

Tpope's surround


    (use-package evil-surround
      :config
      (global-evil-surround-mode 1))

Evil Magit


    (use-package evil-magit)

Evil Machit


    (use-package evil-matchit
      :config
      (global-evil-matchit-mode 1))

Project Management

Ag

Emacs interface for ag


  (use-package ag)

Magit

Magic git interface from within emacs


  (use-package magit
    :config
    (setq magit-bury-buffer-function
          (lambda (con)
            (kill-buffer)
            (delete-window)))
    (global-set-key "\C-x\g" 'magit-status))

Projectile

Project management


  (use-package projectile
    :config
    (use-package counsel-projectile
      :config
      (counsel-projectile-on))
    (setq projectile-enable-caching t)
    (setq projectile-indexing-method 'alien)
    (setq projectile-globally-ignored-file-suffixes '(".dll" ".exe"))
    (projectile-global-mode))

Languages

Generic Web


  (use-package web-mode
    :config
    (add-to-list 'auto-mode-alist '("\\.html\\'" . web-mode))
    (add-to-list 'auto-mode-alist '("\\.php\\'" . web-mode))
    (add-to-list 'auto-mode-alist '("\\.js\\'" . web-mode))

    (setq web-mode-enable-auto-closing t)
    (setq web-mode-enable-auto-opening t)
    (setq web-mode-enable-auto-indentation t))

  (use-package json-mode)

  (use-package company-restclient
    :after company
    :config
    (add-to-list 'company-backends 'company-restclient))

Javascript


  (use-package company-tern
    :after company
    :config
    (add-to-list 'company-backends 'company-tern)
    (add-hook 'web-mode-hook 'tern-mode))

Lisp Family


  (use-package parinfer
    :bind
    (("C-," . parinfer-toggle-mode))
    :init
    (setq
     parinfer-extensions '(defaults pretty-parens evil smart-tab smart-yank)
     parinfer-lighters '(" Φi" . " Φp"))
    (add-hook 'clojure-mode-hook #'parinfer-mode)
    (add-hook 'emacs-lisp-mode-hook #'parinfer-mode)
    (add-hook 'common-lisp-mode-hook #'parinfer-mode)
    (add-hook 'scheme-mode-hook #'parinfer-mode)
    (add-hook 'lisp-mode-hook #'parinfer-mode))

Racket


  (use-package racket-mode)

Latex


  (use-package latex-preview-pane
    :ensure f)

C/C++


  (setq gdb-many-windows t
        gdb-show-main t
        company-clang-insert-arguments nil)

  (use-package company-irony
    :after company
    :config
    (add-hook 'c++-mode-hook 'irony-mode)
    (add-hook 'c-mode-hook 'irony-mode)
    (eval-after-load 'company
      '(add-to-list 'company-backends 'company-irony)))

C#


  (use-package omnisharp
    :after company
    :config
    (setq omnisharp-server-executable-path "C:/emacs/omnisharp/Omnisharp.exe")
    (add-hook 'csharp-mode-hook 'omnisharp-mode)
    (add-to-list 'company-backends 'company-omnisharp))

Python


  (use-package company-jedi
    :after company
    :config
    (add-to-list 'company-backends 'company-jedi))

Shell Scripts


  (use-package company-shell
    :after company
    :config
    (add-to-list 'company-backends '(company-shell company-shell-env)))

Utility

Ranger


  (use-package ranger
    :config
    (setq ranger-cleanup-on-disable t)
    (ranger-override-dired-mode t))

Iedit

Edit all instances of a string


  (use-package iedit
    :config
    (setq iedit-toggle-key-default nil))

Restclient

Postman inside of emacs.


  (use-package restclient)

Rainbow Mode

Shows hex colors inline.


  (use-package rainbow-mode)

Help Fns+


  (use-package help-fns+)

Org Jira


  (use-package org-jira
    :config
    (setq jiralib-url "https://indigoca.atlassian.net"))

Delight


  (use-package delight
    :config
    (delight '((emacs-lisp-mode       "ξ" :major)
               (lisp-interaction-mode "λ" :major)
               (python-mode           "π" :major)
               (org-mode              "Ø" :major)
               (company-mode          " C" company)
               (ivy-mode              " ι" ivy)
               (projectile-mode       " ρ" projectile)
               (eldoc-mode            " ε" eldoc)
               (flycheck-mode         " ƒ" flycheck)
               (undo-tree-mode        ""   undo-tree)
               (auto-revert-mode      ""   autorevert))))

Completion

Ivy & Counsel


  (use-package ivy
    :demand
    :bind (("M-x" . counsel-M-x)
           ("C-x C-f" . counsel-find-file)
           :map ivy-minibuffer-map
           ("TAB" . ivy-next-line)
           ("RET" . ivy-alt-done))
    :init
    (use-package smex)
    (use-package counsel)
    :config
    (setq ivy-re-builders-alist
          '((t . ivy--regex-ignore-order)))
    (setq ivy-wrap t)
    (ivy-mode 1)
    (eval-after-load "hydra" (use-package ivy-hydra)))

Swiper


(use-package swiper
  :bind (("C-s" . swiper)))

Company

Autocomplete engine


  (use-package company
    :bind (:map company-active-map
           ("C-n" . company-select-next)
           ("C-p" . company-select-previous))
    :init
    (global-company-mode)
    :config
    (setq company-idle-delay 0) ; Delay to complete
    (setq company-minimum-prefix-length 1)
    (setq company-selection-wrap-around t) ; Loops around suggestions

    (if (display-graphic-p)
        (define-key company-active-map [tab] 'company-select-next)
      (define-key company-active-map (kbd "C-i") 'company-select-next))

    (ignore-errors
      (require 'color)
      (let ((bg (face-attribute 'default :background)))
        (custom-set-faces
         `(company-tooltip ((t (:inherit default :background ,(color-lighten-name bg 2)))))
         `(company-scrollbar-bg ((t (:background ,(color-lighten-name bg 10)))))
         `(company-scrollbar-fg ((t (:background ,(color-lighten-name bg 5)))))
         `(company-tooltip-selection ((t (:inherit font-lock-function-name-face))))
         `(company-tooltip-common ((t (:inherit font-lock-constant-face))))))))

Flycheck Linting

On the fly syntax checking


  (use-package flycheck
    :config
    (global-flycheck-mode)
    (with-eval-after-load 'flycheck
      (setq-default flycheck-disabled-checkers '(emacs-lisp-checkdoc))))

Misc

Email


  (when (require 'mu4e nil 'noerror)
    (setq mu4e-msg2pdf "/usr/bin/msg2pdf")
    (setq
     ;; set mu4e as default mail client
     mail-user-agent 'mu4e-user-agent
     ;; root mail directory - can't be switched
     ;; with context, can only be set once
     mu4e-maildir "~/.mail"
     mu4e-attachments-dir "~/Downloads/Attachments"
     ;; update command
     mu4e-get-mail-command "mbsync -q -a"
     ;; update database every seven minutes
     mu4e-update-interval (* 60 7)
     ;; use smtpmail (bundled with emacs) for sending
     message-send-mail-function 'smtpmail-send-it
     ;; optionally log smtp output to a buffer
     smtpmail-debug-info t
     ;; close sent message buffers
     message-kill-buffer-on-exit t
     ;; customize list columns
     mu4e-headers-fields '((:flags . 4)
                           (:from . 20)
                           (:human-date . 10)
                           (:subject))
     ;; for mbsync
     mu4e-change-filenames-when-moving t
     ;; pick first context automatically on launch
     mu4e-context-policy               'pick-first
     ;; use current context for new mail
     mu4e-compose-context-policy       nil
     mu4e-confirm-quit                 nil)

    (global-set-key (kbd "<f12>") 'mu4e)
    (global-set-key (kbd "<C-f12>") 'mu4e-update-mail-and-index)

    (setq mu4e-contexts
          `(,(make-mu4e-context
              :name "gmail"
              :match-func (lambda(msg)
                            (when msg
                              (mu4e-message-contact-field-matches msg :to "@gmail.com")))
              :vars '(
                      ;; local directories, relative to mail root
                      (mu4e-sent-folder . "/gmail/[Gmail]/.Sent Mail")
                      (mu4e-drafts-folder . "/gmail/[Gmail]/.Drafts")
                      (mu4e-trash-folder . "/gmail/[Gmail]/.Trash")
                      (mu4e-refile-folder . "/gmail/[Gmail]/.All Mail")
                      ;; account details
                      (user-mail-address . "joshuafwolfe@gmail.com")
                      (user-full-name . "Josh Wolfe")
                      (mu4e-user-mail-address-list . ( "@gmail.com" ))
                      ;; gmail saves every outgoing message automatically
                      (mu4e-sent-messages-behavior . delete)
                      (mu4e-maildir-shortcuts . (("/gmail/INBOX" . ?j)
                                                 ("/gmail/[Gmail]/.All Mail" . ?a)
                                                 ("/gmail/[Gmail]/.Trash" . ?t)
                                                 ("/gmail/[Gmail]/.Drafts" . ?d)))
                      ;; outbound mail server
                      (smtpmail-smtp-server . "smtp.gmail.com")
                      ;; outbound mail port
                      (smtpmail-smtp-service . 465)
                      ;; use ssl
                      (smtpmail-stream-type . ssl)
                      ;; the All Mail folder has a copy of every other folder's contents,
                      ;; and duplicates search results, which is confusing
                      (mue4e-headers-skip-duplicates . t)))))

    (use-package evil-mu4e))

IRC


  (use-package erc
    :ensure nil
    :config
    (add-hook 'window-configuration-change-hook
              '(lambda ()
                 (setq erc-fill-column (- (window-width) 2))))
    (add-hook 'erc-mode-hook
              '(lambda ()
                  (setq-local scroll-margin 1)))

    (setq erc-rename-buffers t
          erc-interpret-mirc-color t
          erc-lurker-hide-list '("JOIN" "PART" "QUIT")
          erc-autojoin-channels-alist '(("freenode.net" "#emacs")))

    (defun wolfe/irc ()
      (interactive)
      (let* ((tupple (wolfe/get-user-pass "~/.authinfo.gpg"))
             (user (car tupple))
             (pass (cadr tupple)))
        (erc
         :server "irc.freenode.net"
         :port 6667
         :nick user
         :password pass))))

Backups

Stores all backups and temp files in ~/.bak.emacs/


  (setq backup-by-copying t) ; Stop shinanigans with links
  (setq backup-directory-alist '((".*" . "~/.bak.emacs/backup/")))
  ;; Creates directory if it doesn't already exist
  (if (eq nil (file-exists-p "~/.bak.emacs/"))
      (make-directory "~/.bak.emacs/"))
  ;; Creates auto directory if it doesn't already exist
  (if (eq nil (file-exists-p "~/.bak.emacs/auto"))
      (make-directory "~/.bak.emacs/auto"))
  ;; backup in one place. flat, no tree structure
  (setq auto-save-file-name-transforms '((".*" "~/.bak.emacs/auto/" t)))

Testing

Org Project

#+BEGIN_SRC emacs-lisp :tangle yes (load-file "~/Projects/org-project/org-project.el") (setq org-project-use-ag t) #+END_SRC

Extract Dates


  (defun wolfe/extract-dates (file-path)
    "Parse through a file for a list of all the comments"
    (let (already-open
          buf
          start
          (comments '()))
      (setq already-open (find-buffer-visiting file-path)
            buf (find-file-noselect file-path))
      (with-current-buffer buf
        (goto-char (point-min))
        (while (setq start (text-property-any
                            (point) (point-max)
                            'face 'org-date))
          (goto-char start)
          (goto-char (next-single-char-property-change (point) 'face))
          (let ((item (string-trim (buffer-substring-no-properties start (point)))))
            (setq comments (cons item comments)))))
      (unless already-open (kill-buffer buf))
      (reverse comments)))