>From e7ca6550d7f33d894e0023e3305938fce365fdba Mon Sep 17 00:00:00 2001 From: Alex Kost Date: Tue, 4 Nov 2014 19:38:27 +0300 Subject: [PATCH] emacs: Add 'pretty-sha-path'. * emacs/pretty-sha-path.el: New file. * emacs.am (ELFILES): Add it. * doc/emacs.texi (Emacs Pretty Path): New node. --- doc/emacs.texi | 41 ++++++++++ emacs.am | 4 +- emacs/pretty-sha-path.el | 200 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 244 insertions(+), 1 deletion(-) create mode 100644 emacs/pretty-sha-path.el diff --git a/doc/emacs.texi b/doc/emacs.texi index 9e8fec4..427700e 100644 --- a/doc/emacs.texi +++ b/doc/emacs.texi @@ -18,6 +18,7 @@ guix package}). Specifically, ``guix.el'' makes it easy to: * Initial Setup: Emacs Initial Setup. Preparing @file{~/.emacs}. * Usage: Emacs Usage. Using the interface. * Configuration: Emacs Configuration. Configuring the interface. +* Pretty SHA Path: Emacs Pretty Path. Prettifying @file{/gnu/store/@dots{}} paths. @end menu @node Emacs Initial Setup @@ -422,3 +423,43 @@ buffers. Various settings for ``info'' buffers. @end table + + address@hidden Emacs Pretty Path address@hidden Pretty SHA Path Mode + +Along with ``guix.el'', address@hidden comes with ``pretty-sha-path.el''. +It provides a minor mode for abbreviating store paths by replacing +SHA-sequences of symbols with address@hidden'': + address@hidden +/gnu/store/onecansee32lettersandnumbershere-foo-0.1 @result{} /gnu/store/…-foo-0.1 address@hidden example + +Once you set up ``guix.el'' (@pxref{Emacs Initial Setup}), the following +commands become available: + address@hidden @kbd + address@hidden M-x pretty-sha-path-mode +Enable/disable prettifying for the current buffer. + address@hidden M-x pretty-sha-path-global-mode +Enable/disable prettifying globally. + address@hidden table + +To automatically enable @code{pretty-sha-path-mode} globally on Emacs +start, add the following line to your init file: + address@hidden +(pretty-sha-path-global-mode) address@hidden example + +If you want to enable it only for specific major modes, add it to the +mode hooks (@pxref{Hooks,,, emacs, The GNU Emacs Manual}), for example: + address@hidden +(add-hook 'shell-mode-hook 'pretty-sha-path-mode) +(add-hook 'dired-mode-hook 'pretty-sha-path-mode) address@hidden example diff --git a/emacs.am b/emacs.am index 35470a3..dba0a0c 100644 --- a/emacs.am +++ b/emacs.am @@ -24,8 +24,10 @@ ELFILES = \ emacs/guix-history.el \ emacs/guix-info.el \ emacs/guix-list.el \ + emacs/guix-messages.el \ emacs/guix-utils.el \ - emacs/guix.el + emacs/guix.el \ + emacs/pretty-sha-path.el if HAVE_EMACS diff --git a/emacs/pretty-sha-path.el b/emacs/pretty-sha-path.el new file mode 100644 index 0000000..d991950 --- /dev/null +++ b/emacs/pretty-sha-path.el @@ -0,0 +1,200 @@ +;;; pretty-sha-path.el --- Prettify Guix store paths + +;; Copyright © 2014 Alex Kost + +;; This file is part of GNU Guix. + +;; GNU Guix is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Guix is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . + +;;; Commentary: + +;; This package provides minor-mode for prettifying Guix/Nix store +;; paths, i.e. after enabling `pretty-sha-path-mode', +;; '/gnu/store/herewehavefancylettersandnumbers-foo-0.1' paths will be +;; replaced with '/gnu/store/…-foo-0.1' paths in the current buffer. +;; There is also `pretty-sha-path-global-mode' for global prettifying. + +;; To install, add the following to your emacs init file: +;; +;; (add-to-list 'load-path "/path/to/pretty-sha-path") +;; (autoload 'pretty-sha-path-mode "pretty-sha-path" nil t) +;; (autoload 'pretty-sha-path-global-mode "pretty-sha-path" nil t) + +;; If you want to enable/disable composition after "M-x font-lock-mode", +;; use the following setting: +;; +;; (setq font-lock-extra-managed-props +;; (cons 'composition font-lock-extra-managed-props)) + +;; Credits: +;; +;; Thanks to Ludovic Courtès for the idea of this package. +;; +;; Thanks to the authors of `prettify-symbols-mode' (part of Emacs 24.4) +;; and "pretty-symbols.el" +;; for the code. It helped to write this package. + +;;; Code: + +(defgroup pretty-sha-path nil + "Prettify Guix/Nix store paths." + :prefix "pretty-sha-path-" + :group 'font-lock + :group 'convenience) + +(defcustom pretty-sha-path-char ?… + "Character used for prettifying." + :type 'character + :group 'pretty-sha-path) + +(defcustom pretty-sha-path-decompose-force nil + "If non-nil, remove any composition. + +By default, after disabling `pretty-sha-path-mode', +compositions (prettifying paths with `pretty-sha-path-char') are +removed only from strings matching `pretty-sha-path-regexp', so +that compositions created by other modes are left untouched. + +Set this variable to non-nil, if you want to remove any +composition unconditionally (like `prettify-symbols-mode' does). +Most likely it will do no harm and will make the process of +disabling `pretty-sha-path-mode' a little faster." + :type 'boolean + :group 'pretty-sha-path) + +(defcustom pretty-sha-path-regexp + (rx "/" + (or "nix" "gnu") + "/store/" + (group (= 32 alnum))) + "Regexp matching SHA paths. + +Disable `pretty-sha-path-mode' before modifying this variable and +make sure to modify `pretty-sha-path-regexp-group' if needed. + +Example of a \"deeper\" prettifying: + + (setq pretty-sha-path-regexp \"store/[[:alnum:]]\\\\\\={32\\\\}\" + pretty-sha-path-regexp-group 0) + +This will transform +'/gnu/store/onecansee32lettersandnumbershere-foo-0.1' into +'/gnu/…-foo-0.1'" + :type 'regexp + :group 'pretty-sha-path) + +(defcustom pretty-sha-path-regexp-group 1 + "Regexp group in `pretty-sha-path-regexp' for prettifying." + :type 'integer + :group 'pretty-sha-path) + +(defvar pretty-sha-path-special-modes + '(guix-info-mode ibuffer-mode) + "List of special modes that support font-locking. + +By default, \\[pretty-sha-path-global-mode] enables prettifying +in all buffers except the ones where `font-lock-defaults' is +nil (see Info node `(elisp) Font Lock Basics'), because it may +break the existing highlighting. + +Modes from this list and all derived modes are exceptions +\(`pretty-sha-path-global-mode' enables prettifying there).") + +(defvar pretty-sha-path-flush-function + (cond ((fboundp 'font-lock-flush) #'font-lock-flush) + ((fboundp 'jit-lock-refontify) #'jit-lock-refontify)) + "Function used to refontify buffer. +This function is called without arguments after +enabling/disabling `pretty-sha-path-mode'. +If nil, do nothing.") + +(defun pretty-sha-path-compose () + "Compose matching region in the current buffer." + (let ((beg (match-beginning pretty-sha-path-regexp-group)) + (end (match-end pretty-sha-path-regexp-group))) + (compose-region beg end pretty-sha-path-char 'decompose-region)) + ;; Return nil because we're not adding any face property. + nil) + +(defun pretty-sha-path-decompose-buffer () + "Remove path compositions from the current buffer." + (with-silent-modifications + (let ((inhibit-read-only t)) + (if pretty-sha-path-decompose-force + (remove-text-properties (point-min) + (point-max) + '(composition nil)) + (save-excursion + (goto-char (point-min)) + (while (re-search-forward pretty-sha-path-regexp nil t) + (remove-text-properties + (match-beginning pretty-sha-path-regexp-group) + (match-end pretty-sha-path-regexp-group) + '(composition nil)))))))) + +;;;###autoload +(define-minor-mode pretty-sha-path-mode + "Toggle Pretty SHA Path mode. + +With a prefix argument ARG, enable Pretty SHA Path mode if ARG is +positive, and disable it otherwise. If called from Lisp, enable +the mode if ARG is omitted or nil. + +When Pretty SHA Path mode is enabled, SHA-parts of the Guix/Nix +store paths (see `pretty-sha-path-regexp') are prettified, +i.e. displayed as `pretty-sha-path-char' character. This mode +can be enabled programmatically using hooks: + + (add-hook 'shell-mode-hook 'pretty-sha-path-mode) + +It is possible to enable the mode in any buffer, however not any +buffer's highlighting may survive after adding new elements to +`font-lock-keywords' (see `pretty-sha-path-special-modes' for +details). + +Also you can use `pretty-sha-path-global-mode' to enable Pretty +SHA Path mode for all modes that support font-locking." + :init-value nil + :lighter " …" + (let ((keywords `((,pretty-sha-path-regexp + (,pretty-sha-path-regexp-group + (pretty-sha-path-compose)))))) + (if pretty-sha-path-mode + ;; Turn on. + (font-lock-add-keywords nil keywords) + ;; Turn off. + (font-lock-remove-keywords nil keywords) + (pretty-sha-path-decompose-buffer)) + (and pretty-sha-path-flush-function + (funcall pretty-sha-path-flush-function)))) + +(defun pretty-sha-path-supported-p () + "Return non-nil, if the mode can be harmlessly enabled in current buffer." + (or font-lock-defaults + (apply #'derived-mode-p pretty-sha-path-special-modes))) + +(defun pretty-sha-path-turn-on () + "Enable `pretty-sha-path-mode' in the current buffer if needed. +See `pretty-sha-path-special-modes' for details." + (and (not pretty-sha-path-mode) + (pretty-sha-path-supported-p) + (pretty-sha-path-mode))) + +;;;###autoload +(define-globalized-minor-mode pretty-sha-path-global-mode + pretty-sha-path-mode pretty-sha-path-turn-on) + +(provide 'pretty-sha-path) + +;;; pretty-sha-path.el ends here -- 2.1.2