Hidden Gem Packages

Table of Contents

Author Lee Hinman (lee@elastic.co)
Date 2017-11-02 16:04:23


Let's talk about some "mini" packages that don't warrant a whole talk, but are really useful in a pinch nonetheless!


Hideshow is a buffer-local minor mode that allows you to selectively display portions of a program, called "blocks".

It's turned on and off with hs-minor-mode and most of the bindings hide (hah get it!) behind C-c @:

Key Action
C-c @ C-h Hide the current block (hs-hide-block)
C-c @ C-s Show the current block (hs-show-block)
C-c @ C-c Toggle visibility of the current block (hs-toggle-hiding)
S-mouse-2 Toggle hiding/showing for the block (hs-mouse-toggle-hiding)
C-c @ C-M-h Hide all the top level blocks (hs-hide-all)
C-c @ C-M-s Show all top level blocks (hs-show-all)
C-c @ C-l Hide blocks n levels below this block (hs-hide-level)

And there is a customization I'd recommend also:

;; Automatically open a block if you search for something where it matches
(setq hs-isearch-open t)

Here's what I'd consider a minimal configuration for it:

(use-package hideshow
  :bind (("C-c TAB" . hs-toggle-hiding)
         ("C-\\" . hs-toggle-hiding)
         ("M-+" . hs-show-all))
  :init (add-hook #'prog-mode-hook #'hs-minor-mode)
  :diminish hs-minor-mode
  ;; Add `json-mode' and `javascript-mode' to the list
  (setq hs-special-modes-alist
        (mapcar 'purecopy
                '((c-mode "{" "}" "/[*/]" nil nil)
                  (c++-mode "{" "}" "/[*/]" nil nil)
                  (java-mode "{" "}" "/[*/]" nil nil)
                  (js-mode "{" "}" "/[*/]" nil)
                  (json-mode "{" "}" "/[*/]" nil)
                  (javascript-mode  "{" "}" "/[*/]" nil)))))

The main way I use this is to put the point (represented as | in the code below) inside of an expression and then hit C-c TAB or C-\, which changes

  "foo": {|
    "bar": "baz"
  "eggplant": 11


  "foo": { ... },
  "eggplant": 11

I have another helper that I really like (especially for Java files) that looks like:

(defvar eos/hs-level 2
  "Default level to hide at when calling
    `eos/fold-show-only-methods'. This is buffers may set this to
    be buffer-local.")

(setq eos/hs-fold-show-only-methods-active-p nil)
(defun eos/hs-fold-show-only-methods ()
  "Toggle between hiding all methods using `eos/hs-level' or
showing them."
    (if eos/hs-fold-show-only-methods-active-p
          (setq-local eos/hs-fold-show-only-methods-active-p nil))
        (goto-char (point-min))
        (hs-hide-level eos/hs-level)
        (setq-local eos/hs-fold-show-only-methods-active-p t)))))

(global-set-key (kbd "M-\\") 'eos/hs-fold-show-only-methods)

I can then use M-\ to only show method names and signatures, hiding the bodies.


Expand-region let's you take the current point and expand the selection, this is great with things like transient-mark-mode and delete-selection-mode!

(use-package expand-region
  :ensure t
  :defer t
  :bind (("C-c e" . er/expand-region)
         ;; I almost never use this, so it has an awkward binding
         ("C-M-@" . er/contract-region)))

Since this is hard to explain, I'll show what it does!

Git tools

Besides Magit, there are a bunch of other helpful tools for git, and vcs in general


Git-gutter is a way to show what parts of a file were changed. It pops up configurable symbols (+, -, =) in the margin. It's also a great way to navigate through a file by jumping through the parts that have been changed.

Here's how I like to configure it. Note that the git-gutter-fringe part is entirely optional and I only use for making the fringe look "nice" (I'll demo this). If you don't want it you can remove the custom bitmap definitions.

(use-package git-gutter
  :ensure t
  :when window-system
  :defer t
  :bind (("C-x P" . git-gutter:popup-hunk)
         ("C-x p" . git-gutter:previous-hunk)
         ("C-x n" . git-gutter:next-hunk)
         ("C-c G" . git-gutter:popup-hunk))
  :diminish ""
  (add-hook 'prog-mode-hook #'git-gutter-mode)
  (add-hook 'text-mode-hook #'git-gutter-mode)
  (use-package git-gutter-fringe
    :ensure t
    (require 'git-gutter-fringe)
    (when (fboundp 'define-fringe-bitmap)
      (define-fringe-bitmap 'git-gutter-fr:added
        [224 224 224 224 224 224 224 224 224 224 224 224 224
             224 224 224 224 224 224 224 224 224 224 224 224]
        nil nil 'center)
      (define-fringe-bitmap 'git-gutter-fr:modified
        [224 224 224 224 224 224 224 224 224 224 224 224 224
             224 224 224 224 224 224 224 224 224 224 224 224]
        nil nil 'center)
      (define-fringe-bitmap 'git-gutter-fr:deleted
        [0 0 0 0 0 0 0 0 0 0 0 0 0 128 192 224 240 248]
        nil nil 'center))))

The other helpful thing is git-gutter:revert-hunk which can be used to revert only a single chunk of change without having to jump back into Magit.


Git-timemachine allows you to go back through the history of a file, seeing how it's been changed. There really isn't much configuration:

(use-package git-timemachine
  :ensure t)

And then do M-x git-timemachine, you can use p and n to jump between the previous and next revision of the file, w or W to copy the short/full hash of the commit you're looking at, and q to quit.

There are a few more keybinds, so check out the project to see what else you can do!


Along the same lines, sometimes all you want to see is the message for the particular line you're at. Git-messenger lets you pop this up and copy the relevant information. I like to bind mine to C-c M:

(use-package git-messenger
  :ensure t
  :commands git-messenger:popup-message
  :bind (("C-c M" . git-messenger:popup-message))
  (setq git-messenger:show-detail t))



Finally, sometimes you need to send someone a link, and you want to open whatever you're currently looking at in the Github, Gitlab, Bitbucket, etc UI. Browse-at-remote lets you do this, and even highlights what ever you have selected in the UI.

(use-package browse-at-remote
  :ensure t
  :commands browse-at-remote
  :bind ("C-c g g" . browse-at-remote))

Let's see what it looks like!


Alert is for notifications, and very easy to use

(use-package alert
  :ensure t
  (when (eq system-type 'darwin)
    (setq alert-default-style 'notifier))
  (when (eq system-type 'gnu/linux)
    (setq alert-default-style 'notifications)))

And then you can do:

(alert "Test alert")
(alert "Give the presentation!" :title "Denver Emacs")
(alert "Don't mess up!" :title "Emacs" :severity 'high)

Use it when your write your own helpers! Like this one that alerts when compilation (M-x compile) finishes:

(defun eos/compile-finished (buffer msg)
  (alert msg :title buffer :category 'compilation))

(add-to-list 'compilation-finish-functions 'eos/compile-finished)


Which-key shows you possible completions when you half-type a shortcut. It's hard to explain so trying it is best, install it with the following:

(use-package which-key
  :ensure t
  (which-key-mode 1))

And then press C-h, wait a few seconds, and then a popup comes up with all the options you can choose. Very helpful! It works with any kind of prefix (try Helm's prefix key, C-x, or C-c for instance)


Sometimes it can be helpful to start up a service, for instance, if you are a Ruby dev you might want to start a Rails server, or if you want to run some service you need for development.

Prodigy lets you have a great UI for this, as well as seeing the state, and viewing the logs

(use-package prodigy
  :ensure t
  :defer t
  (setq prodigy-services '())
    :name "Elasticsearch 5.6.3"
    :cwd "~/ies/elasticsearch-5.6.3"
    :command "~/ies/elasticsearch-5.6.3/bin/elasticsearch"
    :tags '(work test es)
    :port 9200)
    :name "Simple HTTP server"
    :cwd "~/"
    :command "python"
    :args '("-m" "SimpleHTTPServer" "8000")
    :port 8000
    :tags '(http)))

You can then do M-x prodigy to bring up the UI and see what you can run. s starts a command, S stops it, and $ jumps to a buffer showing the logs from the process (g refreshes the view).

Author: Lee Hinman

Created: 2017-11-02 Thu 16:04