Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
427 lines (351 sloc) 16.7 KB

Client Configuration for Emacs

The settings in this file are only included on a Macintosh, Linux, or other systems with a graphical front-end.

Key Bindings

Bind a number of global keys for use with the Command key (need to use both the A- and s- modifiers so that it works with both Mac and Linux).

(bind-keys
 ("s-z" . undo-tree-undo)
 ("A-z" . undo-tree-undo)
 ("s-y" . undo-tree-redo)
 ("A-y" . undo-tree-redo)
 ("s-Z" . undo-tree-redo)
 ("A-Z" . undo-tree-redo)
 ("s-x" . kill-region)
 ("A-x" . kill-region)
 ("s-c" . kill-ring-save)
 ("A-c" . kill-ring-save)
 ("s-v" . yank)
 ("A-v" . yank)

 ("s-a" . mark-whole-buffer)
 ("A-a" . mark-whole-buffer)
 ("s-f" . isearch-forward-regexp)
 ("A-f" . isearch-forward-regexp)

 ("s-s" . save-buffer)
 ("A-s" . save-buffer)
 ("s-+" . text-scale-increase)
 ("A-+" . text-scale-increase)
 ("s-=" . text-scale-increase)
 ("A-=" . text-scale-increase)
 ("s--" . text-scale-decrease)
 ("A--" . text-scale-decrease)
 ("s-_" . text-scale-decrease)
 ("A-_" . text-scale-decrease)
 ("s-l" . goto-line)
 ("A-l" . goto-line)
 ("s-w" . bury-buffer)
 ("A-w" . bury-buffer)
 ("s-M-w" . kill-this-buffer)
 ("A-M-w" . kill-this-buffer)

 ("s-<up>" . beginning-of-buffer)
 ("A-<up>" . beginning-of-buffer)
 ("s-<down>" . end-of-buffer)
 ("A-<down>" . end-of-buffer)
 ("s-<left>" . smarter-move-beginning-of-line)
 ("A-<left>" . smarter-move-beginning-of-line)
 ("s-<right>" . move-end-of-line)
 ("A-<right>" . move-end-of-line)

 ("M-<up>" . backward-page)
 ("M-<down>" . forward-page)
 ("M-<left>" . backward-word)
 ("M-<right>" . forward-word))

According to this article, we can update the text-scale-XYZ functions to work on a frame instead of just a buffer:

(defun ha/text-scale-frame-change (fn)
  (let* ((current-font-name (frame-parameter nil 'font))
         (decomposed-font-name (x-decompose-font-name current-font-name))
         (font-size (string-to-int (aref decomposed-font-name 5))))
    (aset decomposed-font-name 5 (int-to-string (funcall fn font-size)))
    (set-frame-font (x-compose-font-name decomposed-font-name))))

(defun ha/text-scale-frame-increase ()
  (interactive)
  (ha/text-scale-frame-change '1+))

(defun ha/text-scale-frame-decrease ()
  (interactive)
  (ha/text-scale-frame-change '1-))

(bind-keys
 ("s-C-+" . ha/text-scale-frame-increase)
 ("A-C-+" . ha/text-scale-frame-increase)
 ("s-C-=" . ha/text-scale-frame-increase)
 ("A-C-=" . ha/text-scale-frame-increase)
 ("s-C--" . ha/text-scale-frame-decrease)
 ("A-C--" . ha/text-scale-frame-decrease))

Gotta get rid of the bloody C-x C-c, for it is too close to the tangling key binding of C-c C-v … besides, I never quit Emacs.

(setq confirm-kill-emacs 'yes-or-no-p)

Font Settings

I love syntax highlighting.

(global-font-lock-mode 1)

Am I really a monospace font slut? I think so. I keep changing my font based on the monospace du jour… While I M+ because it is thinner and has more white space between lines, but Source Code Pro is so attractive, oh, and then there is Anonymous Pro…

While thicker, Fira does symbol ligatures. However, Hasklig is a nice font that is thinner and easier to read, with some symbolic ligatures that doesn’t interfere with my org-mode header bullets.

(defvar ha/fixed-font-family
  (cond ((x-list-fonts "Hasklig")         "Hasklig")
        ((x-list-fonts "Source Code Pro") "Source Code Pro")
        ((x-list-fonts "Anonymous Pro")   "Anonymous Pro")
        ((x-list-fonts "M+ 1mn")          "M+ 1mn"))
  "My fixed width font based on what is installed, `nil' if not defined.")

Since the headers are based on Adobe’s open source font pair of the proportional font, Source Sans Pro, will match the non-proportional font, Source Code Pro.

(defvar ha/variable-font-tuple
  (cond ((x-list-fonts "Source Sans Pro") '(:font "Source Sans Pro"))
        ((x-list-fonts "Lucida Grande")   '(:font "Lucida Grande"))
        ((x-list-fonts "Verdana")         '(:font "Verdana"))
        ((x-family-fonts "Sans Serif")    '(:family "Sans Serif"))
        (nil (warn "Cannot find a Sans Serif Font.  Install Source Sans Pro.")))
  "My variable width font available to org-mode files and whatnot.")

Color Theme

Use the color theme project by following these instructions. We now can do M-x color-theme-<TAB> RET

(use-package color-theme
  :ensure t
  :init (require 'color-theme)
  :config (use-package color-theme-sanityinc-tomorrow
           :ensure t))

The color themes work quite well, except they don’t know about the org-mode source code blocks, so we need to set up a couple functions that we can use to set them.

(defun org-src-color-blocks-light ()
  "Colors the block headers and footers to make them stand out more for lighter themes"
  (interactive)
  (custom-set-faces
   '(org-block-begin-line
    ((t (:underline "#A7A6AA" :foreground "#008ED1" :background "#EAEAFF"))))
   '(org-block-background
     ((t (:background "#FFFFEA"))))
   '(org-block
     ((t (:background "#FFFFEA"))))
   '(org-block-end-line
     ((t (:overline "#A7A6AA" :foreground "#008ED1" :background "#EAEAFF"))))))

(defun org-src-color-blocks-dark ()
  "Colors the block headers and footers to make them stand out more for dark themes"
  (interactive)
  (custom-set-faces
   '(org-block-begin-line
     ((t (:foreground "#008ED1" :background "#002E41"))))
   '(org-block-background
     ((t (:background "#000000"))))
   '(org-block
     ((t (:background "#000000"))))
   '(org-block-end-line
     ((t (:foreground "#008ED1" :background "#002E41"))))))

No matter, the theme, I like some of the ideas in the EMagicians Starter Kit, particularly in how the headers are larger, instead of different colors.

(deftheme ha/org-theme "Sub-theme to beautify org mode")

Since I’m using the Powerline project, switching my Emacs color theme, requires me to call powerline-reset in order to get the colors to apply to the mode line.

We put all of these requirements in a single function call:

(defun ha/change-theme (theme org-block-style)
  "Changes the color scheme and reset the mode line."
  (funcall theme)
  (funcall org-block-style)

  (let* ((ha/fixed-font-tuple (list :font ha/fixed-font-family))
         ; (ha/varible-font-tuple (list :font ha/variable-font-family))
         (base-font-color     (face-foreground 'default nil 'default))
         (background-color    (face-background 'default nil 'default))
         (primary-color       (face-foreground 'mode-line nil))
         (secondary-color     (face-background 'secondary-selection nil 'region))
         (base-height         (face-attribute 'default :height))
         (headline           `(:inherit default :weight bold :foreground ,base-font-color)))

    (when ha/fixed-font-family
      (set-frame-font ha/fixed-font-family)
      (set-face-attribute 'default nil :font ha/fixed-font-family :height 140)
      (set-face-font 'default ha/fixed-font-family))

    ;; Noticeable?
    ;; (set-face-attribute 'region nil :background "#ffff50" :foreground "black")
    ;; Subtle?
    (set-face-attribute 'region nil :background "#0000bb" :foreground 'unspecified)

    (custom-theme-set-faces 'ha/org-theme
                            `(org-agenda-structure ((t (:inherit default :height 2.0 :underline nil))))
                            `(org-verbatim ((t (:inherit 'fixed-pitched :foreground "#aef"))))
                            `(org-table ((t (:inherit 'fixed-pitched))))
                            `(org-block ((t (:inherit 'fixed-pitched))))
                            `(org-block-background ((t (:inherit 'fixed-pitched))))
                            `(org-block-begin-line ((t (:inherit 'fixed-pitched))))
                            `(org-block-end-line ((t (:inherit 'fixed-pitched))))
                            `(org-level-8 ((t (,@headline ,@ha/variable-font-tuple))))
                            `(org-level-7 ((t (,@headline ,@ha/variable-font-tuple))))
                            `(org-level-6 ((t (,@headline ,@ha/variable-font-tuple))))
                            `(org-level-5 ((t (,@headline ,@ha/variable-font-tuple))))
                            `(org-level-4 ((t (,@headline ,@ha/variable-font-tuple
                                                          :height 1.1))))
                            `(org-level-3 ((t (,@headline ,@ha/variable-font-tuple
                                                          :height 1.1))))
                            `(org-level-2 ((t (,@headline ,@ha/variable-font-tuple
                                                          :height 1.1))))
                            `(org-level-1 ((t (,@headline ,@ha/variable-font-tuple
                                                          :height 2.1))))
                            `(org-document-title ((t (,@headline ,@ha/variable-font-tuple :height 1.5 :underline nil)))))))

And the default startup goes to…night…

(ha/change-theme 'color-theme-sanityinc-tomorrow-night 'org-src-color-blocks-dark)

(custom-set-faces
 '(mode-line           ((t (:background "blue4"   :foreground "gray90"))))
 '(mode-line-inactive  ((t (:background "#404045" :foreground "gray60"))))
 '(mode-line-buffer-id ((t (                      :foreground "gold1"   :weight ultra-bold))))
 '(which-func          ((t (                      :foreground "orange"))))
 '(show-paren-match    ((t (:background "default" :foreground "#afa"    :weight ultra-bold))))
 '(show-paren-mismatch ((t (:background "default" :foreground "#cc6666" :weight ultra-bold)))))

(set-face-attribute 'region nil :background "#00a")

Frame and Window Size

I often want to put the window fullscreen:

(defun frame-fullscreen ()
  "Set the frame window to cover the full screen."
  (interactive)
  (set-frame-parameter nil 'fullscreen 'fullboth))

When I am using my large monitors with a full-screen Emacs session with two or three side-by-side windows, I want set them to a fixed width:

(defun set-window-width (&optional width)
  "Sets the size of the current window to a specific width.
If no width is specified, it defaults to ~ 80 characters."
  (interactive "p")
  (save-excursion
    (if (not width)
        (setq width 78))
    (if (> (window-width) width)
        (shrink-window-horizontally (- (window-width) width))
      (enlarge-window-horizontally (- width (window-width))))))

The bell is pretty obnoxious when it dings during scrolling.

(setq ring-bell-function 'ignore)

Dimming and Finding Cursor

When I type, I would rather not see the cursor, for at the point where I am typing, I know where I am typing. Of course, when I’m moving around the screen (or even when Emacs is idle), I want to know clearly the location of cursor.

I’ve previously made the cursor an obnoxious color, and let’s save that value:

(defvar cursor-initial-color (face-attribute 'cursor :background)
    "The initial value of the cursor that will be use when re-showing it.")

If I type a character or maybe two, I don’t want to hide the cursor… only when I start to really get typing:

(defvar cursor-number-chars-before-hiding 2
   "The number of characters one needs to type before we hide the cursor.")

Of course, I need to have some sort of state variable that counts the number of characters that have been typed:

(defvar cursor-current-number-chars 0)

Now let’s have a couple of functions that will show and hide the cursor (or at least, lessen its visibility):

(defun cursor-hide (&optional arg)
  "Hides cursor by setting the color to the background color.
This only happens after a number of characters have been
typed (defined by the `cursor-number-chars-before-hiding'
variable)."
  (setq cursor-current-number-chars (1+ cursor-current-number-chars))
  (when (> cursor-current-number-chars cursor-number-chars-before-hiding)
    (set-cursor-color (or (background-color-at-point) "#1d1f21"))))

(defun cursor-show ()
  "Shows the cursor. At least, sets it to a particular
color (stored/defined in `cursor-initial-color'. Note: This also
resets the `cursor-current-number-chars' variable, so that it
won't be hid until a number of characters have been typed."
  (setq cursor-current-number-chars 0)
  (set-cursor-color cursor-initial-color))

After entering a text that is inserted into a buffer, hide the cursor by using some advice:

(advice-add 'self-insert-command :after #'cursor-hide)

After I’m done typing (that is, when the cursor is idle), show the cursor:

(setq my-cursor-timer (run-with-idle-timer 1 t #'cursor-show))

Let’s make the cursor more noticeable whenever the window scrolls (which seems to be the time when I need to visually look for it):

(use-package beacon
  :ensure t
  :defer  t
  :diminish 'beacon-mode
  :init  (beacon-mode +1)
  :config (setq beacon-color cursor-initial-color))

Twitter

I know, I know, reading my twitter feed in Emacs is pretty geeking awesome. And I can filter out tweets that match a pattern that annoys me:

(use-package twittering-mode
  :init
  (setq twittering-tweet-filters '("NPR" "#burritowatch"))

  (defun twittering-filter-tweets ()
    "Call string-match on all new tweets"
    (setq non-matching-statuses '())
    (dolist (status twittering-new-tweets-statuses)
      (setq matched-tweets 0)
      (dolist (pat twittering-tweet-filters)
        (if (string-match pat (cdr (assoc 'text status)))
            (setq matched-tweets (+ 1 matched-tweets))))
      (if (= 0 matched-tweets)
          (setq non-matching-statuses
                (append non-matching-statuses `(,status)))))
    (setq new-statuses non-matching-statuses))

  (add-hook 'twittering-edit-mode-hook 'flyspell-mode)
  (add-hook 'twittering-new-tweets-hook 'twittering-filter-tweets))

Technical Artifacts

Load up the particular operating system variation.

(if (eq system-type 'darwin)
    (require 'init-mac)
  (require 'init-linux))

Notice “Windows” is not listed. That is by design.

Make sure that we can simply require this library.

(provide 'init-client)

Before you can build this on a new system, make sure that you put the cursor over any of these properties, and hit: C-c C-c