about summary refs log tree commit diff
diff options
context:
space:
mode:
authorWilliam Carroll <wpcarro@gmail.com>2020-01-16T14·49+0000
committerWilliam Carroll <wpcarro@gmail.com>2020-01-17T10·56+0000
commita3077677f967ad299f49f8898cb9af4072462ce9 (patch)
treea55da518f706172f144dc6e2f9a405f79272d5aa
parent47faf8d6f0786279899d2ffcde8dd8786cf73338 (diff)
Rename clipmenu.el to ivy-clipmenu.el
TL;DR: Preparing ivy-clipmenu for publishing.

Also:
- Removes lingering TODO items.
- Clarifies module and function documentation.
- Defines groups for custom variables.
- Supports history variable for ivy-read.
-rw-r--r--configs/shared/.emacs.d/wpc/clipmenu.el149
-rw-r--r--configs/shared/.emacs.d/wpc/ivy-clipmenu.el134
2 files changed, 134 insertions, 149 deletions
diff --git a/configs/shared/.emacs.d/wpc/clipmenu.el b/configs/shared/.emacs.d/wpc/clipmenu.el
deleted file mode 100644
index ba48a909117c..000000000000
--- a/configs/shared/.emacs.d/wpc/clipmenu.el
+++ /dev/null
@@ -1,149 +0,0 @@
-;;; clipmenu.el --- Emacs client for clipmenu -*- lexical-binding: t -*-
-;; Author: William Carroll <wpcarro@gmail.com>
-
-;;; Commentary:
-;; Ivy integration with the excellent program, clipmenu.
-;;
-;; clipmenu is a simple clipboard manager xsel. Usually clipmenu integrates with
-;; dmenu.  This Emacs module integrates with ivy.  Launch this when you want to
-;; select a clip.
-;;
-;; The following environment variables allow you to customize clipmenu's
-;; behavior:
-;;
-;; - CM_DIR: specify the base directory to store the cache dir in
-;;   (default: $XDG_RUNTIME_DIR, $TMPDIR, or /tmp)
-;; - CM_HISTLENGTH: specify the number of lines to show in ivy. (default: 8)
-;;
-;; Other variables for customizing clipmenu are defined herein.
-;;
-;; For more information, see `clipmenu --help`.
-
-;;; Code:
-
-;; TODO: Support an ivy action of deleting an entry from clipmenu.
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Dependencies
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(require 'f)
-(require 's)
-(require 'dash)
-
-(prelude/assert
- (prelude/executable-exists? "clipmenud"))
-
-(prelude/assert
- (prelude/executable-exists? "clipmenu"))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Variables
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-;; TODO: Remove this if you're publishing it.
-(defcustom clipmenu/install-kbds? t
-  "When t, install the keybindings defined herein")
-
-(defcustom clipmenu/directory
-  (or (getenv "XDG_RUNTIME_DIR")
-      (getenv "TMPDIR")
-      "/tmp")
-  "Base directory for clipmenu data.")
-
-(defconst clipmenu/major-version 5
-   "The major version number for clipmenu.")
-
-(defconst clipmenu/cache-directory
-  (f-join clipmenu/directory
-          (format "clipmenu.%s.%s"
-                  clipmenu/major-version
-                  (getenv "USER")))
-  "Directory where the clips are stored.")
-
-(defconst clipmenu/cache-file-pattern
-  (f-join clipmenu/cache-directory "line_cache_*")
-  "Glob pattern matching the locations on disk for clipmenu's labels.")
-
-(defcustom clipmenu/history-length
-  (or (getenv "CM_HISTLENGTH") 50)
-  "Limit the number of clips in the history.
-This value defaults to 50.")
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Functions
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(defun clipmenu/parse-line (x)
-  "Parse the entry in the clipmenu's line-cache."
-  (string-to-number
-   (list/join "" (parsec-with-input x (parsec-count 19 (parsec-digit))))))
-
-(defun clipmenu/parse-content (x)
-  "Parse the label from the entry in clipmenu's line-cache."
-  (list/join
-   ""
-   (parsec-with-input x
-     (parsec-count 19 (parsec-digit))
-     (parsec-str " ")
-     (parsec-many (parsec-any-ch)))))
-
-(defun clipmenu/list-clips ()
-  "Return a list of the content of all of the clips."
-  (->> clipmenu/cache-file-pattern
-       f-glob
-       (-map (lambda (path)
-               (s-split "\n" (f-read path) t)))
-       -flatten
-       (-reject #'s-blank?)
-       (-sort (lambda (a b)
-                (< (clipmenu/parse-line a)
-                   (clipmenu/parse-line b))))
-       (-map #'clipmenu/parse-content)
-       list/dedupe-adjacent
-       (-take clipmenu/history-length)))
-
-;; TODO: Add tests.
-(defun clipmenu/escape-quotes (x)
-  "Escape double and single quotes in X."
-  (->> x
-       (s-replace "\"" "\\\"")
-       (s-replace "'" "\\'")))
-
-(defun clipmenu/line-to-clip (line)
-  "Map the chosen LINE to a clip stored on disk."
-  (->> line
-       clipmenu/checksum
-       (f-join clipmenu/cache-directory)
-       f-read
-       clipboard/copy))
-
-;; TODO: Consider supporting :history keyword.
-
-;; TODO: Ensure you can handle special characters like:
-;; r}_rh,pmj~kCR.<5w"PUk#Z^>.
-
-(defun clipmenu/ivy-copy ()
-  "Use `ivy-read' to select and copy a clip."
-  (interactive)
-  (let ((ivy-sort-functions-alist nil))
-    (ivy-read "Clipmenu: "
-              (clipmenu/list-clips)
-              :action #'clipmenu/line-to-clip)))
-
-(defun clipmenu/checksum (content)
-  "Return the CRC checksum of CONTENT."
-  (s-trim-right
-   (prelude/call-process-to-string
-    "/bin/bash" "-c" (string/format "/usr/bin/cksum <<<'%s'" content))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Keybindings
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(when clipmenu/install-kbds?
-  (exwm-input-set-key
-   (kbd "C-M-v") #'clipmenu/ivy-copy))
-
-(provide 'clipmenu)
-;;; clipmenu.el ends here
diff --git a/configs/shared/.emacs.d/wpc/ivy-clipmenu.el b/configs/shared/.emacs.d/wpc/ivy-clipmenu.el
new file mode 100644
index 000000000000..f3896137bd9f
--- /dev/null
+++ b/configs/shared/.emacs.d/wpc/ivy-clipmenu.el
@@ -0,0 +1,134 @@
+;;; ivy-clipmenu.el --- Emacs client for clipmenu -*- lexical-binding: t -*-
+;; Author: William Carroll <wpcarro@gmail.com>
+
+;;; Commentary:
+;; Ivy integration with the clipboard manager, clipmenu.  Essentially, clipmenu
+;; turns your system clipboard into a list.
+;;
+;; To use this module, you must first install clipmenu and ensure that the
+;; clipmenud daemon is running.  Refer to the installation instructions at
+;; github.com/cdown/clipmenu for those details.
+;;
+;; This module intentionally does not define any keybindings since I'd prefer
+;; not to presume my users' preferences.  Personally, I use EXWM as my window
+;; manager, so I call `exwm-input-set-key' and map it to `ivy-clipmenu/copy'.
+;;
+;; Usually clipmenu integrates with rofi or dmenu.  This Emacs module integrates
+;; with ivy.  Launch this when you want to select a clip.
+;;
+;; Clipmenu itself supports a variety of environment variables that allow you to
+;; customize its behavior.  These variables are respected herein.  If you'd
+;; prefer to customize clipmenu's behavior from within Emacs, refer to the
+;; variables defined in this module.
+;;
+;; For more information:
+;; - See `clipmenu --help`.
+;; - Visit github.com/cdown/clipmenu.
+
+;;; Code:
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Dependencies
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(require 'f)
+(require 's)
+(require 'dash)
+(require 'ivy)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Variables
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defgroup ivy-clipmenu nil
+  "Ivy integration for clipmenu."
+  :group 'ivy)
+
+(defcustom ivy-clipmenu/directory
+  (or (getenv "XDG_RUNTIME_DIR")
+      (getenv "TMPDIR")
+      "/tmp")
+  "Base directory for clipmenu's data."
+  :type 'string
+  :group 'ivy-clipmenu)
+
+(defconst ivy-clipmenu/executable-version 5
+   "The major version number for the clipmenu executable.")
+
+(defconst ivy-clipmenu/cache-directory
+  (f-join ivy-clipmenu/directory
+          (format "clipmenu.%s.%s"
+                  ivy-clipmenu/executable-version
+                  (getenv "USER")))
+  "Directory where the clips are stored.")
+
+(defconst ivy-clipmenu/cache-file-pattern
+  (f-join ivy-clipmenu/cache-directory "line_cache_*")
+  "Glob pattern matching the locations on disk for clipmenu's labels.")
+
+(defcustom ivy-clipmenu/history-length
+  (or (getenv "CM_HISTLENGTH") 25)
+  "Limit the number of clips in the history.
+This value defaults to 25.")
+
+(defvar ivy-clipmenu/history nil
+  "History for `ivy-clipmenu/copy'.")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Functions
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun ivy-clipmenu/parse-content (x)
+  "Parse the label from the entry in clipmenu's line-cache."
+  (->> (s-split " " x)
+       (-drop 1)
+       (s-join " ")))
+
+(defun ivy-clipmenu/list-clips ()
+  "Return a list of the content of all of the clips."
+  (->> ivy-clipmenu/cache-file-pattern
+       f-glob
+       (-map (lambda (path)
+               (s-split "\n" (f-read path) t)))
+       -flatten
+       (-reject #'s-blank?)
+       (-sort #'string>)
+       (-map #'ivy-clipmenu/parse-content)
+       delete-dups
+       (-take ivy-clipmenu/history-length)))
+
+(defun ivy-clipmenu/checksum (content)
+  "Return the CRC checksum of CONTENT."
+  (s-trim-right
+   (with-temp-buffer
+     (call-process "/bin/bash" nil (current-buffer) nil "-c"
+                   (format "cksum <<<'%s'" content))
+     (buffer-string))))
+
+(defun ivy-clipmenu/line-to-content (line)
+  "Map the chosen LINE from the line cache its content from disk."
+  (->> line
+       ivy-clipmenu/checksum
+       (f-join ivy-clipmenu/cache-directory)
+       f-read))
+
+(defun ivy-clipmenu/do-copy (x)
+  "Copy string, X, to the system clipboard."
+  (kill-new x)
+  (message "[ivy-clipmenu.el] Copied!"))
+
+(defun ivy-clipmenu/copy ()
+  "Use `ivy-read' to select and copy a clip.
+It's recommended to bind this function to a globally available keymap."
+  (interactive)
+  (let ((ivy-sort-functions-alist nil))
+    (ivy-read "Clipmenu: "
+              (ivy-clipmenu/list-clips)
+              :history 'ivy-clipmenu/history
+              :action (lambda (line)
+                        (->> line
+                             ivy-clipmenu/line-to-content
+                             ivy-clipmenu/do-copy)))))
+
+(provide 'ivy-clipmenu)
+;;; ivy-clipmenu.el ends here