about summary refs log tree commit diff
path: root/tools/emacs-pkgs
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/emacs-pkgs
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/emacs-pkgs')
-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
4 files changed, 152 insertions, 0 deletions
diff --git a/tools/emacs-pkgs/dottime/default.nix b/tools/emacs-pkgs/dottime/default.nix
new file mode 100644
index 000000000000..b09756dea560
--- /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 000000000000..7caeb2f2c440
--- /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 000000000000..ad96638a054c
--- /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 000000000000..66247d68247c
--- /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)