Motivation
While working on a completely unrelated task, I wanted to share a screenshot of my current Emacs frame, but not of the actual text contents. And while GIMP's pixelate filter did the job, I didn't want to fire up my image manipulation program just to share a picture of a custom theme or some functionality.
I thought that Emacs must have some functionality to hide certain information on the displayed text. I remembered toggle-rot13-mode
, but anyone interested in the text could decrypt it rather quickly. So instead, I had a look into its implementation and put my Emacs Lisp hat on to find my own solution.
Screenshot
On the left, the original buffer. On the right, an indirect clone with secret-mode
enabled.
(Note: this is the wombat
theme, with Fira Code in Emacs 27.2 on Windows.)
Code
I'm using two code blocks here to keep the noise from the actual lisp implementation. The actual code is just a single lisp file (secret-mode.el
).
;;; secret-mode.el --- hide text in buffer -*- lexical-binding: t; -*-
;; Copyright (C) 2021 (omitted*)
;; Author: (omitted*)
;; Keywords: games
;; Version: 0.0.1
;; This program 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.
;; This program 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 <https://www.gnu.org/licenses/>.
;;; Commentary:
;; This package provides `secret-mode', a buffer-local mode that uses
;; `buffer-display-table' to replace the displayed glyphs with Unicode
;; blocks.
;;; Code:
(defconst secret-mode-table
(let ((disptbl (make-display-table)))
(dotimes (i 1024)
(aset disptbl i
(pcase (get-char-code-property i 'general-category)
((or 'Cc 'Cf 'Zs 'Zl 'Zp) nil)
('Lu (vector (make-glyph-code ?▆)))
(_ (vector (make-glyph-code ?▃))))))
disptbl)
"Display table for the command `secret-mode'.")
;;;###autoload
(define-minor-mode secret-mode
"Hide text."
:lighter " Secret"
(if secret-mode
(setq buffer-display-table secret-mode-table)
(setq buffer-display-table nil)))
(provide 'secret-mode)
;;; secret-mode.el ends here
What I'm looking for
Any kind of feedback is welcome. Feel free to trash the use of Display Tables if its unidiomatic or if there is a more practical way with another feature.
Since I'm pretty happy with the result, I would like to publish this package, so feel especially encouraged to point anything out that needs to be done beforehand, as it will be my first published package.