about summary refs log tree commit diff
path: root/tools
diff options
context:
space:
mode:
authorVincent Ambo <tazjin@google.com>2019-12-15T22·59+0000
committerGitHub <noreply@github.com>2019-12-15T22·59+0000
commite8b184adcc56e2ce6c0cbb86d45344e4f1ac98af (patch)
tree8f9573801796c6524ad253bed9a19401b6b336e7 /tools
parent00c9060c2f0ec581db8841aa34fd92c0e9953693 (diff)
parent458163910b4ab08c885e076e5f3b9ecf1b3521af (diff)
merge(PR#11): Move bits of Emacs configuration into local packages r/156
As requested by @wpcarro, some bits of my Emacs configuration are now in separate local packages (located at `//depot/tools/emacs-pkgs/`).

Specifically this change introduces:

* `tools.emacs-pkgs.dottime`: A package to render time in the modeline as [dottime](https://dotti.me)
* `tools.emacs-pkgs.term-switcher`: A package to quickly switch between and open new terminal instances in EXWM using ivy

My Emacs configuration is updated to accomodate these refactorings.
Diffstat (limited to 'tools')
-rw-r--r--tools/emacs-pkgs/dottime/default.nix7
-rw-r--r--tools/emacs-pkgs/dottime/dottime.el59
-rw-r--r--tools/emacs-pkgs/term-switcher/default.nix14
-rw-r--r--tools/emacs-pkgs/term-switcher/term-switcher.el72
-rw-r--r--tools/emacs/config/desktop.el2
-rw-r--r--tools/emacs/config/init.el22
-rw-r--r--tools/emacs/config/look-and-feel.el15
-rw-r--r--tools/emacs/config/modes.el3
-rw-r--r--tools/emacs/config/term-setup.el36
-rw-r--r--tools/emacs/default.nix26
10 files changed, 169 insertions, 87 deletions
diff --git a/tools/emacs-pkgs/dottime/default.nix b/tools/emacs-pkgs/dottime/default.nix
new file mode 100644
index 0000000000..b09756dea5
--- /dev/null
+++ b/tools/emacs-pkgs/dottime/default.nix
@@ -0,0 +1,7 @@
+{ pkgs, ... }:
+
+pkgs.third_party.emacsPackagesNg.trivialBuild rec {
+  pname = "dottime";
+  version = "1.0";
+  src = ./dottime.el;
+}
diff --git a/tools/emacs-pkgs/dottime/dottime.el b/tools/emacs-pkgs/dottime/dottime.el
new file mode 100644
index 0000000000..7caeb2f2c4
--- /dev/null
+++ b/tools/emacs-pkgs/dottime/dottime.el
@@ -0,0 +1,59 @@
+;;; dottime.el --- use dottime in the modeline
+;;
+;; Copyright (C) 2019 Google Inc.
+;;
+;; Author: Vincent Ambo <tazjin@google.com>
+;; Version: 1.0
+;; Package-Requires: (cl-lib)
+;;
+;;; Commentary:
+;;
+;; This package changes the display of time in the modeline to use
+;; dottime (see https://dotti.me/) instead of the standard time
+;; display.
+;;
+;; Modeline dottime display is enabled by calling
+;; `dottime-display-mode' and dottime can be used in Lisp code via
+;; `dottime-format'.
+
+(require 'cl-lib)
+(require 'time)
+
+(defun dottime--format-string ()
+  "Creates the dottime format string for `format-time-string'
+  based on the local timezone."
+
+  (let* ((offset-sec (car (current-time-zone)))
+         (offset-hours (/ offset-sec 60 60)))
+    (if (/= offset-hours 0)
+        (concat "%m-%dT%H·%M" (format "%0+3d" offset-hours))
+      "%m-%dT%H·%M")))
+
+(defun dottime--display-time-update-advice (orig)
+  "Function used as advice to `display-time-update' with a
+  rebound definition of `format-time-string' that renders all
+  timestamps as dottime."
+
+  (cl-letf* ((format-orig (symbol-function 'format-time-string))
+             ((symbol-function 'format-time-string)
+              (lambda (&rest _)
+                (funcall format-orig (dottime--format-string) nil t))))
+    (funcall orig)))
+
+(defun dottime-format (&optional time)
+  "Format the given TIME in dottime. If TIME is nil, the current
+  time will be used."
+
+  (format-time-string (dottime--format-string) time t))
+
+(defun dottime-display-mode (arg)
+  "Enable time display as dottime. Disables dottime if called
+  with prefix 0 or nil."
+
+  (interactive "p")
+  (if (or (eq arg 0) (eq arg nil))
+      (advice-remove 'display-time-update #'dottime--display-time-update-advice)
+    (advice-add 'display-time-update :around #'dottime--display-time-update-advice))
+  (display-time-update))
+
+(provide 'dottime)
diff --git a/tools/emacs-pkgs/term-switcher/default.nix b/tools/emacs-pkgs/term-switcher/default.nix
new file mode 100644
index 0000000000..ad96638a05
--- /dev/null
+++ b/tools/emacs-pkgs/term-switcher/default.nix
@@ -0,0 +1,14 @@
+{ pkgs, ... }:
+
+with pkgs.third_party.emacsPackagesNg;
+
+melpaBuild rec {
+  pname = "term-switcher";
+  version = "1.0";
+  src = ./term-switcher.el;
+  packageRequires = [ dash ivy s ];
+
+  recipe = builtins.toFile "recipe" ''
+    (term-switcher :fetcher github :repo "tazjin/depot")
+  '';
+}
diff --git a/tools/emacs-pkgs/term-switcher/term-switcher.el b/tools/emacs-pkgs/term-switcher/term-switcher.el
new file mode 100644
index 0000000000..66247d6824
--- /dev/null
+++ b/tools/emacs-pkgs/term-switcher/term-switcher.el
@@ -0,0 +1,72 @@
+;;; term-switcher.el --- Easily switch between open X11 terminals
+;;
+;; Copyright (C) 2019 Google Inc.
+;;
+;; Author: Vincent Ambo <tazjin@google.com>
+;; Version: 1.0
+;; Package-Requires: (dash ivy s)
+;;
+;;; Commentary:
+;;
+;; This package adds a function that lets users quickly switch between
+;; different open X11 terminals using ivy.
+;;
+;; It is primarily intended to be used by EXWM users who use graphical
+;; terminals inside of Emacs.
+;;
+;; Users MUST configure the group `term-switcher' and can then bind
+;; `ts/switch-to-terminal' to an appropriate key.
+
+(require 'dash)
+(require 'ivy)
+(require 's)
+
+(defgroup term-switcher nil
+  "Customization options for configuring `term-switcher' with the
+  user's terminal emulator of choice.")
+
+(defcustom term-switcher-program "gnome-terminal"
+  "X11 terminal application to use."
+  :type '(string)
+  :group 'term-switcher)
+
+(defcustom term-switcher-buffer-prefix "Term"
+  "String prefix for X11 terminal buffers. For example, if your
+  EXWM configuration renames X11 terminal buffers to
+  `Term</foo/bar>' you might want to use `Term' as the matching
+  prefix."
+  :type '(string)
+  :group 'term-switcher)
+
+(defun ts/run-terminal-program ()
+  (message "Starting %s..." term-switcher-program)
+  (start-process-shell-command term-switcher-program nil term-switcher-program))
+
+(defun ts/open-or-create-terminal-buffer (buffer-name)
+  "Switch to the buffer with BUFFER-NAME or create a new buffer
+  running the configured X11 terminal."
+  (let ((buffer (get-buffer buffer-name)))
+    (if (not buffer)
+        (ts/run-terminal-program)
+      (switch-to-buffer buffer))))
+
+(defun ts/is-terminal-buffer (buffer)
+  "Determine whether BUFFER runs an X11 terminal."
+  (and (equal 'exwm-mode (buffer-local-value 'major-mode buffer))
+       (s-starts-with? term-switcher-buffer-prefix (buffer-name buffer))))
+
+(defun ts/switch-to-terminal ()
+  "Switch to an X11 terminal buffer, or create a new one."
+  (interactive)
+  (let ((terms (-map #'buffer-name
+                     (-filter #'ts/is-terminal-buffer (buffer-list)))))
+    (if terms
+        (ivy-read "Switch to terminal buffer: "
+                  (cons "New terminal" terms)
+                  :caller 'ts/switch-to-terminal
+                  :preselect (s-concat "^" term-switcher-buffer-prefix)
+                  :require-match t
+                  :action #'ts/open-or-create-terminal-buffer)
+      (ts/run-terminal-program))))
+
+(provide 'term-switcher)
diff --git a/tools/emacs/config/desktop.el b/tools/emacs/config/desktop.el
index dcc3538337..a19b3f6745 100644
--- a/tools/emacs/config/desktop.el
+++ b/tools/emacs/config/desktop.el
@@ -148,7 +148,7 @@
 (exwm-input-set-key (kbd "s-p") #'ivy-password-store)
 
 ;; Add X11 terminal selector to a key
-(exwm-input-set-key (kbd "C-x t") #'counsel-switch-to-terminal)
+(exwm-input-set-key (kbd "C-x t") #'ts/switch-to-terminal)
 
 ;; Toggle between line-mode / char-mode
 (exwm-input-set-key (kbd "C-c C-t C-t") #'exwm-input-toggle-keyboard)
diff --git a/tools/emacs/config/init.el b/tools/emacs/config/init.el
index a27a17c6dd..7d40813d83 100644
--- a/tools/emacs/config/init.el
+++ b/tools/emacs/config/init.el
@@ -19,11 +19,11 @@
 
 (use-package ace-window
   :bind (("C-x o" . ace-window))
-  :init
+  :config
   (setq aw-keys '(?f ?j ?d ?k ?s ?l ?a)
         aw-scope 'frame))
 
-(use-package auth-source-pass :init (auth-source-pass-enable))
+(use-package auth-source-pass :config (auth-source-pass-enable))
 
 (use-package avy
   :bind (("M-j" . avy-goto-char)
@@ -34,10 +34,11 @@
 
 (use-package company
   :hook ((prog-mode . company-mode))
-  :init (setq company-tooltip-align-annotations t))
+  :config (setq company-tooltip-align-annotations t))
 
 (use-package dash)
 (use-package dash-functional)
+(use-package dottime :config (dottime-display-mode t))
 (use-package gruber-darker-theme)
 (use-package ht)
 (use-package hydra)
@@ -46,19 +47,19 @@
                             (emacs-lisp-mode . paredit-mode)))
 (use-package multiple-cursors)
 (use-package pinentry
-  :init
+  :config
   (setq epa-pinentry-mode 'loopback)
   (pinentry-start))
 
 (use-package rainbow-delimiters :hook (prog-mode . rainbow-delimiters-mode))
 (use-package rainbow-mode)
 (use-package s)
-(use-package smartparens :init (smartparens-global-mode))
 (use-package string-edit)
 (use-package telephone-line) ;; configuration happens outside of use-package
-(use-package undo-tree :init (global-undo-tree-mode))
+(use-package term-switcher)
+(use-package undo-tree :config (global-undo-tree-mode))
 (use-package uuidgen)
-(use-package which-key :init (which-key-mode t))
+(use-package which-key :config (which-key-mode t))
 
 ;;
 ;; Applications in emacs
@@ -66,7 +67,7 @@
 
 (use-package magit
   :bind ("C-c g" . magit-status)
-  :init (setq magit-repository-directories '(("/home/vincent/projects" . 2))))
+  :config (setq magit-repository-directories '(("/home/vincent/projects" . 2))))
 
 (use-package password-store)
 (use-package pg)
@@ -100,7 +101,7 @@
 (use-package haskell-mode)
 
 (use-package jq-mode
-  :init (add-to-list 'auto-mode-alist '("\\.jq\\'" . jq-mode)))
+  :config (add-to-list 'auto-mode-alist '("\\.jq\\'" . jq-mode)))
 
 (use-package kotlin-mode
   :hook ((kotlin-mode . (lambda ()
@@ -109,7 +110,7 @@
 (use-package lsp-mode)
 
 (use-package markdown-mode
-  :init
+  :config
   (add-to-list 'auto-mode-alist '("\\.txt\\'" . markdown-mode))
   (add-to-list 'auto-mode-alist '("\\.markdown\\'" . markdown-mode))
   (add-to-list 'auto-mode-alist '("\\.md\\'" . markdown-mode)))
@@ -151,7 +152,6 @@
                  settings
                  modes
                  bindings
-                 term-setup
                  eshell-setup))
 (telephone-line-setup)
 (ace-window-display-mode)
diff --git a/tools/emacs/config/look-and-feel.el b/tools/emacs/config/look-and-feel.el
index 8f42133fb8..88cab18ed2 100644
--- a/tools/emacs/config/look-and-feel.el
+++ b/tools/emacs/config/look-and-feel.el
@@ -27,21 +27,6 @@
                               (font . ,font)))
   (set-frame-font font t t))
 
-;; Display modeline time in dottime (see https://dotti.me)
-;;
-;; This is done in a way that initially seems more complicated than
-;; one would like, but this is unfortunately required due to the way
-;; `format-time-string' handles timezones.
-(defun format-dottime-advice (orig _ &optional _ _)
-  (let* ((offset-sec (car (current-time-zone)))
-         (offset-hours (/ offset-sec 60 60))
-         (dottime (if (/= offset-hours 0)
-                      (concat "%M-%Dt%H·%M" (format "%0+3d" offset-hours))
-                    "%m-%dT%H·%M")))
-    (apply orig '("%m-%dT%H·%M" nil t))))
-
-(advice-add 'format-time-string :around #'format-dottime-advice)
-
 ;; Configure telephone-line
 (defun telephone-misc-if-last-window ()
   "Renders the mode-line-misc-info string for display in the
diff --git a/tools/emacs/config/modes.el b/tools/emacs/config/modes.el
index 19ed2a6843..ceef84b962 100644
--- a/tools/emacs/config/modes.el
+++ b/tools/emacs/config/modes.el
@@ -19,8 +19,7 @@
 (show-paren-mode 1)
 
 ;; Always auto-close parantheses and other pairs
-;; (replaced by smartparens)
-;; (electric-pair-mode)
+(electric-pair-mode)
 
 ;; Keep track of recent files
 (recentf-mode)
diff --git a/tools/emacs/config/term-setup.el b/tools/emacs/config/term-setup.el
deleted file mode 100644
index cd4f9c25ef..0000000000
--- a/tools/emacs/config/term-setup.el
+++ /dev/null
@@ -1,36 +0,0 @@
-;; Utilities for X11 terminal buffers.
-
-(defvar x11-terminal-program "gnome-terminal"
-  "Which X11 terminal application to use.")
-
-(defvar x11-terminal-buffer-prefix "Term"
-  "String prefix for X11 terminal buffer names.")
-
-(defun open-or-create-terminal-buffer (buffer-name)
-  "Switch to the buffer with BUFFER-NAME or create a new buffer
-  running the configured X11 terminal."
-  (let ((buffer (get-buffer buffer-name)))
-    (if (not buffer)
-        (run-external-command x11-terminal-program)
-      (switch-to-buffer buffer))))
-
-(defun is-terminal-buffer (buffer)
-  "Determine whether BUFFER runs an X11 terminal."
-  (and (equal 'exwm-mode (buffer-local-value 'major-mode buffer))
-       (s-starts-with? x11-terminal-buffer-prefix (buffer-name buffer))))
-
-(defun counsel-switch-to-terminal ()
-  "Switch to an X11 terminal buffer, or create a new one."
-  (interactive)
-  (let ((terms (-map #'buffer-name
-                     (-filter #'is-terminal-buffer (buffer-list)))))
-    (if terms
-        (ivy-read "Switch to terminal buffer: "
-                  (cons "New terminal" terms)
-                  :caller 'counsel-switch-to-terminal
-                  :preselect (s-concat "^" x11-terminal-buffer-prefix)
-                  :require-match t
-                  :action #'open-or-create-terminal-buffer)
-      (run-external-command x11-terminal-program))))
-
-(provide 'term-setup)
diff --git a/tools/emacs/default.nix b/tools/emacs/default.nix
index 0589b274e2..02ffb36605 100644
--- a/tools/emacs/default.nix
+++ b/tools/emacs/default.nix
@@ -5,29 +5,12 @@
 
 with pkgs;
 with third_party.emacsPackagesNg;
+with third_party.emacs;
 
 let
+  localPackages = pkgs.tools.emacs-pkgs;
   emacsWithPackages = (third_party.emacsPackagesNgGen third_party.emacs26).emacsWithPackages;
 
-  carpMode = melpaBuild {
-    pname = "carp-mode";
-    ename = "carp-mode";
-    version = "3.0";
-    recipe = builtins.toFile "recipe" ''
-      (carp-mode :fetcher github
-                 :repo "carp-lang/carp"
-                 :files ("emacs/*.el"))
-    '';
-
-    packageRequires = [ clojure-mode ];
-    src = third_party.fetchFromGitHub {
-      owner = "carp-lang";
-      repo = "carp";
-      rev = "6954642cadee730885717201c3180c7acfb1bfa9";
-      sha256 = "1pz4x2qkwjbz789bwc6nkacrjpzlxawxhl2nv0xdp731y7q7xyk9";
-    };
-  };
-
   tazjinsEmacs = (emacsWithPackages(epkgs:
   # Actual ELPA packages (the enlightened!)
   (with epkgs.elpaPackages; [
@@ -82,7 +65,6 @@ let
     rainbow-delimiters
     restclient
     sly
-    smartparens
     string-edit
     swiper
     telephone-line
@@ -99,7 +81,7 @@ let
   ]) ++
 
   # Custom packages
-  [ carpMode ]
+  [ carp-mode localPackages.dottime localPackages.term-switcher ]
   ));
 in third_party.writeShellScriptBin "tazjins-emacs" ''
   exec ${tazjinsEmacs}/bin/emacs \
@@ -108,5 +90,5 @@ in third_party.writeShellScriptBin "tazjins-emacs" ''
     --no-site-lisp \
     --no-init-file \
     --directory ${./config} \
-    --eval "(require 'init)"
+    --eval "(require 'init)" $@
 ''