Commit | Line | Data |
---|---|---|
62f261d8 AK |
1 | ;;; guix-messages.el --- Minibuffer messages |
2 | ||
3 | ;; Copyright © 2014 Alex Kost <alezost@gmail.com> | |
4 | ||
5 | ;; This file is part of GNU Guix. | |
6 | ||
7 | ;; GNU Guix is free software; you can redistribute it and/or modify | |
8 | ;; it under the terms of the GNU General Public License as published by | |
9 | ;; the Free Software Foundation, either version 3 of the License, or | |
10 | ;; (at your option) any later version. | |
11 | ||
12 | ;; GNU Guix is distributed in the hope that it will be useful, | |
13 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | ;; GNU General Public License for more details. | |
16 | ||
17 | ;; You should have received a copy of the GNU General Public License | |
18 | ;; along with this program. If not, see <http://www.gnu.org/licenses/>. | |
19 | ||
20 | ;;; Commentary: | |
21 | ||
22 | ;; This file provides `guix-result-message' function used to show a | |
23 | ;; minibuffer message after displaying packages/generations in a | |
24 | ;; list/info buffer. | |
25 | ||
26 | ;;; Code: | |
27 | ||
28 | (require 'cl-lib) | |
29 | (require 'guix-utils) | |
30 | ||
31 | (defvar guix-messages | |
32 | `((package | |
33 | (id | |
34 | (0 "Packages not found.") | |
35 | (1 "") | |
36 | (many "%d packages." count)) | |
37 | (name | |
38 | ,(lambda (_ entries names) | |
39 | (guix-message-packages-by-name entries 'package names))) | |
40 | (regexp | |
41 | (0 "No packages matching '%s'." val) | |
42 | (1 "A single package matching '%s'." val) | |
43 | (many "%d packages matching '%s'." count val)) | |
44 | (all-available | |
45 | (0 "No packages are available for some reason.") | |
46 | (1 "A single available package (that's strange).") | |
47 | (many "%d available packages." count)) | |
48 | (newest-available | |
49 | (0 "No packages are available for some reason.") | |
50 | (1 "A single newest available package (that's strange).") | |
51 | (many "%d newest available packages." count)) | |
52 | (installed | |
53 | (0 "No packages installed in profile '%s'." profile) | |
54 | (1 "A single package installed in profile '%s'." profile) | |
55 | (many "%d packages installed in profile '%s'." count profile)) | |
56 | (obsolete | |
57 | (0 "No obsolete packages in profile '%s'." profile) | |
58 | (1 "A single obsolete package in profile '%s'." profile) | |
59 | (many "%d obsolete packages in profile '%s'." count profile)) | |
60 | (generation | |
61 | (0 "No packages installed in generation %d of profile '%s'." | |
62 | val profile) | |
63 | (1 "A single package installed in generation %d of profile '%s'." | |
64 | val profile) | |
65 | (many "%d packages installed in generation %d of profile '%s'." | |
66 | count val profile))) | |
67 | ||
68 | (output | |
69 | (id | |
70 | (0 "Package outputs not found.") | |
71 | (1 "") | |
72 | (many "%d package outputs." count)) | |
73 | (name | |
74 | ,(lambda (_ entries names) | |
75 | (guix-message-packages-by-name entries 'output names))) | |
76 | (regexp | |
77 | (0 "No package outputs matching '%s'." val) | |
78 | (1 "A single package output matching '%s'." val) | |
79 | (many "%d package outputs matching '%s'." count val)) | |
80 | (all-available | |
81 | (0 "No package outputs are available for some reason.") | |
82 | (1 "A single available package output (that's strange).") | |
83 | (many "%d available package outputs." count)) | |
84 | (newest-available | |
85 | (0 "No package outputs are available for some reason.") | |
86 | (1 "A single newest available package output (that's strange).") | |
87 | (many "%d newest available package outputs." count)) | |
88 | (installed | |
89 | (0 "No package outputs installed in profile '%s'." profile) | |
90 | (1 "A single package output installed in profile '%s'." profile) | |
91 | (many "%d package outputs installed in profile '%s'." count profile)) | |
92 | (obsolete | |
93 | (0 "No obsolete package outputs in profile '%s'." profile) | |
94 | (1 "A single obsolete package output in profile '%s'." profile) | |
95 | (many "%d obsolete package outputs in profile '%s'." count profile)) | |
96 | (generation | |
97 | (0 "No package outputs installed in generation %d of profile '%s'." | |
98 | val profile) | |
99 | (1 "A single package output installed in generation %d of profile '%s'." | |
100 | val profile) | |
101 | (many "%d package outputs installed in generation %d of profile '%s'." | |
d38bd08c AK |
102 | count val profile)) |
103 | (generation-diff | |
104 | guix-message-outputs-by-diff)) | |
62f261d8 AK |
105 | |
106 | (generation | |
107 | (id | |
108 | (0 "Generations not found.") | |
109 | (1 "") | |
110 | (many "%d generations." count)) | |
111 | (last | |
112 | (0 "No generations in profile '%s'." profile) | |
113 | (1 "The last generation of profile '%s'." profile) | |
114 | (many "%d last generations of profile '%s'." count profile)) | |
115 | (all | |
116 | (0 "No generations in profile '%s'." profile) | |
117 | (1 "A single generation available in profile '%s'." profile) | |
118 | (many "%d generations available in profile '%s'." count profile)) | |
119 | (time | |
120 | guix-message-generations-by-time)))) | |
121 | ||
122 | (defun guix-message-string-name (name) | |
123 | "Return a quoted name string." | |
124 | (concat "'" name "'")) | |
125 | ||
126 | (defun guix-message-string-entry-type (entry-type &optional plural) | |
127 | "Return a string denoting an ENTRY-TYPE." | |
128 | (cl-ecase entry-type | |
129 | (package | |
130 | (if plural "packages" "package")) | |
131 | (output | |
132 | (if plural "package outputs" "package output")) | |
133 | (generation | |
134 | (if plural "generations" "generation")))) | |
135 | ||
136 | (defun guix-message-string-entries (count entry-type) | |
137 | "Return a string denoting the COUNT of ENTRY-TYPE entries." | |
138 | (cl-case count | |
139 | (0 (concat "No " | |
140 | (guix-message-string-entry-type | |
141 | entry-type 'plural))) | |
142 | (1 (concat "A single " | |
143 | (guix-message-string-entry-type | |
144 | entry-type))) | |
145 | (t (format "%d %s" | |
146 | count | |
147 | (guix-message-string-entry-type | |
148 | entry-type 'plural))))) | |
149 | ||
150 | (defun guix-message-packages-by-name (entries entry-type names) | |
151 | "Display a message for packages or outputs searched by NAMES." | |
152 | (let* ((count (length entries)) | |
153 | (str-beg (guix-message-string-entries count entry-type)) | |
154 | (str-end (if (cdr names) | |
155 | (concat "matching the following names: " | |
156 | (mapconcat #'guix-message-string-name | |
157 | names ", ")) | |
158 | (concat "with name " | |
159 | (guix-message-string-name (car names)))))) | |
160 | (message "%s %s." str-beg str-end))) | |
161 | ||
162 | (defun guix-message-generations-by-time (profile entries times) | |
163 | "Display a message for generations searched by TIMES." | |
164 | (let* ((count (length entries)) | |
165 | (str-beg (guix-message-string-entries count 'generation)) | |
166 | (time-beg (guix-get-time-string (car times))) | |
167 | (time-end (guix-get-time-string (cadr times)))) | |
168 | (message (concat "%s of profile '%s'\n" | |
169 | "matching time period '%s' - '%s'.") | |
170 | str-beg profile time-beg time-end))) | |
171 | ||
d38bd08c AK |
172 | (defun guix-message-outputs-by-diff (profile entries generations) |
173 | "Display a message for outputs searched by GENERATIONS difference." | |
174 | (let* ((count (length entries)) | |
175 | (str-beg (guix-message-string-entries count 'output)) | |
176 | (gen1 (car generations)) | |
177 | (gen2 (cadr generations))) | |
178 | (cl-multiple-value-bind (new old str-action) | |
179 | (if (> gen1 gen2) | |
180 | (list gen1 gen2 "added to") | |
181 | (list gen2 gen1 "removed from")) | |
182 | (message (concat "%s %s generation %d comparing with " | |
183 | "generation %d of profile '%s'.") | |
184 | str-beg str-action new old profile)))) | |
185 | ||
62f261d8 AK |
186 | (defun guix-result-message (profile entries entry-type |
187 | search-type search-vals) | |
188 | "Display an appropriate message after displaying ENTRIES." | |
189 | (let* ((type-spec (guix-get-key-val guix-messages | |
190 | entry-type search-type)) | |
191 | (fun-or-count-spec (car type-spec))) | |
192 | (if (functionp fun-or-count-spec) | |
193 | (funcall fun-or-count-spec profile entries search-vals) | |
194 | (let* ((count (length entries)) | |
195 | (count-key (if (> count 1) 'many count)) | |
196 | (msg-spec (guix-get-key-val type-spec count-key)) | |
197 | (msg (car msg-spec)) | |
198 | (args (cdr msg-spec))) | |
199 | (mapc (lambda (subst) | |
200 | (setq args (cl-substitute (cdr subst) (car subst) args))) | |
201 | `((count . ,count) | |
202 | (val . ,(car search-vals)) | |
203 | (profile . ,profile))) | |
204 | (apply #'message msg args))))) | |
205 | ||
206 | (provide 'guix-messages) | |
207 | ||
208 | ;;; guix-messages.el ends here |