Function: sops-mode
sops-mode is an interactive and natively compiled function defined in
sops.el.
Signature
(sops-mode &optional ARG)
Documentation
Edit the current SOPS-encrypted file transparently.
Decryption happens at find-file; encryption happens at save-buffer.
Plaintext never reaches disk (backups and auto-save are suppressed).
This is a minor mode. If called interactively, toggle the sops mode
mode. If the prefix argument is positive, enable the mode, and if it is
zero or negative, disable the mode.
If called from Lisp, toggle the mode if ARG is toggle. Enable the
mode if ARG is nil, omitted, or is a positive number. Disable the mode
if ARG is a negative number.
To check whether the minor mode is enabled in the current buffer,
evaluate the variable sops-mode(var)/sops-mode(fun).
The mode's hook is called both when the mode is enabled and when it is disabled.
Key Bindings
This command is not in any keymaps.
Source Code
;; Defined in /nix/store/vihl6lkzddv9xrsrsznvqdjq27g2i30p-emacs-packages-deps/share/emacs/site-lisp/elpa/sops-20260920.2121/sops.el
;;;###autoload
(define-minor-mode sops-mode
"Edit the current SOPS-encrypted file transparently.
Decryption happens at `find-file'; encryption happens at `save-buffer'.
Plaintext never reaches disk (backups and auto-save are suppressed)."
:init-value nil
:lighter " sops"
:group 'sops
(cond
(sops-mode
;; Refuse to enable on a buffer whose visited file isn't sops-encrypted.
;; `sops--find-file-hook' and `sops--retry-decrypt-on-revert' both
;; validate via `sops--filestatus' + a successful decrypt before
;; reaching here, so they pre-set `sops--state' to signal "trust me".
;; This guard catches manual `M-x sops-mode' on a regular buffer,
;; which would otherwise install encrypt-on-save hooks that fail at
;; save time -- and the disable branch's modified-buffer guardrail
;; would then trap the user with no clean escape.
(unless sops--state
(unless (and buffer-file-name
(not (file-remote-p buffer-file-name))
(sops--filestatus buffer-file-name))
(setq sops-mode nil)
(user-error "Sops-mode: %s is not a sops-encrypted file"
(or buffer-file-name "this buffer")))
(when (buffer-modified-p)
(setq sops-mode nil)
(user-error "Sops-mode: refusing to decrypt modified buffer; revert first"))
(let ((retrying-decrypt
(eq revert-buffer-function #'sops--retry-decrypt-on-revert)))
(unless (sops--decrypt-buffer)
(setq sops-mode nil)
(user-error "Sops-mode: failed to decrypt %s" buffer-file-name))
(when retrying-decrypt
(setq buffer-read-only nil)))
(setq sops-mode t)
(setq sops--state (sops-state-create :status 'decrypted)))
(setq-local make-backup-files nil)
(setq-local buffer-auto-save-file-name nil)
(setq-local revert-buffer-function #'sops--revert-buffer)
(add-hook 'write-contents-functions #'sops--write-contents-function nil t)
;; External writes (magit discard, git checkout, sops -e from CLI) update
;; the file behind our back. auto-revert-mode picks them up and calls
;; `revert-buffer-function' (= `sops--revert-buffer') so the user sees
;; the new ciphertext re-decrypted instead of a stale buffer + the
;; "really edit?" prompt. Defaults to file-notify (kqueue/inotify) when
;; available, falling back to polling. See test/sops-test.el for why
;; batch tests force polling (the interactive main loop drains queued
;; events between commands; batch does not, and that deadlocks the next
;; `sops--run').
(auto-revert-mode 1)
;; Inhibit apheleia (and any future formatters that respect this var
;; convention). Two reasons: (1) apheleia's before-save formatter runs
;; before our `write-contents-functions' hook and can hang the save flow
;; before sops is even reached; (2) reformatting decrypted plaintext
;; before encrypt would change the ciphertext on every save, producing
;; meaningless `git diff' churn even on no-op edits. apheleia documents
;; `apheleia-inhibit' as its buffer-local opt-out.
(setq-local apheleia-inhibit t)
;; Lazy-install the global major-mode-change restoration hook. Doing
;; this on first `sops-mode' enable rather than at package load keeps
;; `(require \\='sops)' free of global side effects -- users who load
;; sops.el but never visit a SOPS file pay no per-buffer hook cost.
(unless sops--restore-hook-installed
(add-hook 'after-change-major-mode-hook
#'sops--restore-after-major-mode-change)
(setq sops--restore-hook-installed t)))
(t
(when (buffer-modified-p)
(setq sops-mode 1) ; revert the toggle
(user-error
"Sops: buffer modified; revert-buffer first or use M-x read-only-mode"))
(auto-revert-mode -1)
(kill-local-variable 'make-backup-files)
(kill-local-variable 'buffer-auto-save-file-name)
(kill-local-variable 'revert-buffer-function)
(kill-local-variable 'apheleia-inhibit)
(remove-hook 'write-contents-functions #'sops--write-contents-function t)
(setq sops--state nil))))