-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathshut-up.el
150 lines (118 loc) · 5.32 KB
/
shut-up.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
;;; shut-up.el --- Shut up would you! -*- lexical-binding: t; -*-
;; Copyright (C) 2013, 2014 Johan Andersson
;; Copyright (C) 2014, 2015 Sebastian Wiesner <swiesner@lunaryorn.com>
;; Author: Johan Andersson <johan.rejeep@gmail.com>
;; Maintainer: Johan Andersson <johan.rejeep@gmail.com>
;; Package-Requires: ((cl-lib "0.3") (emacs "24"))
;; Version: 0.3.2
;; URL: http://github.com/rejeep/shut-up.el
;; This file is NOT part of GNU Emacs.
;;; License:
;; 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, 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 GNU Emacs; see the file COPYING. If not, write to the
;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
;; Boston, MA 02110-1301, USA.
;;; Commentary:
;;; Code:
(require 'cl-lib)
(eval-when-compile
(defvar dired-use-ls-dired))
;; NOTE: This variable has been added in most recent version of
;; Emacs. It's declared here to support lexical binding and to avoid
;; compiler warnings.
(defvar inhibit-message nil)
(defvar shut-up-ignore nil
"When non-nil, do not hide output inside `shut-up'.
Changes to this variable inside a `shut-up' block has no
effect.")
;; Preserve the original definition of `write-region'
(unless (fboundp 'shut-up-write-region-original)
(fset 'shut-up-write-region-original (symbol-function 'write-region)))
(defun shut-up-write-region (start end filename
&optional append visit lockname mustbenew)
"Like `write-region', but try to suppress any messages."
(unless visit
(setq visit 'no-message))
;; Call our "copy" of `write-region', because if this function is used to
;; override `write-region', calling `write-region' directly here would result
;; in any endless recursion.
(shut-up-write-region-original start end filename
append visit lockname mustbenew))
(unless (fboundp 'shut-up-load-original)
(fset 'shut-up-load-original (symbol-function 'load)))
(defun shut-up-load (file &optional noerror _nomessage nosuffix must-suffix)
"Like `load', but try to be quiet about it."
(shut-up-load-original file noerror :nomessage nosuffix must-suffix))
(defun shut-up-buffer-string (buffer)
"Get the contents of BUFFER.
When BUFFER is alive, return its contents without properties.
Otherwise return nil."
(when (buffer-live-p buffer)
(with-current-buffer buffer
(buffer-substring-no-properties (point-min) (point-max)))))
(defun shut-up-insert-to-buffer (object buffer)
"Insert OBJECT into BUFFER.
If BUFFER is not live, do nothing."
(when (buffer-live-p buffer)
(with-current-buffer buffer
(cl-typecase object
(character (insert-char object 1))
(string (insert object))
(t (princ object #'insert-char))))))
;;;###autoload
(defmacro shut-up (&rest body)
"Evaluate BODY with silenced output.
While BODY is evaluated, all output is redirected to a buffer,
unless `shut-up-ignore' is non-nil. This affects:
- `message'
- All functions using `standard-output' (e.g. `print', `princ', etc.)
Inside BODY, the buffer is bound to the lexical variable
`shut-up-sink'. Additionally provide a lexical function
`shut-up-current-output', which returns the current contents of
`shut-up-sink' when called with no arguments.
Changes to the variable `shut-up-ignore' inside BODY does not
have any affect."
(declare (indent 0))
`(let ((shut-up-sink (generate-new-buffer " *shutup*"))
(inhibit-message t))
(cl-labels ((shut-up-current-output () (or (shut-up-buffer-string shut-up-sink) "")))
(if shut-up-ignore
(progn ,@body)
(unwind-protect
;; Override `standard-output', for `print' and friends, and
;; monkey-patch `message'
(cl-letf ((standard-output
(lambda (char)
(shut-up-insert-to-buffer char shut-up-sink)))
((symbol-function 'message)
(lambda (fmt &rest args)
(when fmt
(let ((text (apply #'format fmt args)))
(shut-up-insert-to-buffer (concat text "\n") shut-up-sink)
text))))
((symbol-function 'write-region) #'shut-up-write-region)
((symbol-function 'load) #'shut-up-load))
,@body)
(and (buffer-name shut-up-sink)
(kill-buffer shut-up-sink)))))))
;;;###autoload
(defun shut-up-silence-emacs ()
"Silence Emacs.
Change Emacs settings to reduce the output.
WARNING: This function has GLOBAL SIDE-EFFECTS. You should only
call this function in `noninteractive' sessions."
;; Loading vc-git...
(remove-hook 'find-file-hooks 'vc-find-file-hook)
;; ls does not support --dired; see `dired-use-ls-dired' for more details.
(eval-after-load "dired"
'(setq dired-use-ls-dired nil)))
(provide 'shut-up)
;;; shut-up.el ends here