aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenichi Handa2010-05-19 10:16:01 +0900
committerKenichi Handa2010-05-19 10:16:01 +0900
commit9ba3dd48988911d24100dad2b67e5b45189083dd (patch)
treeea1334ba49103db7820757424f7043fd62333890
parent134d1bcded02e066727ece838f14ffc767f76419 (diff)
parent134c2f29cef985c940bd9496a1e69dff850b80a3 (diff)
downloademacs-9ba3dd48988911d24100dad2b67e5b45189083dd.tar.gz
emacs-9ba3dd48988911d24100dad2b67e5b45189083dd.zip
merge trunk
-rw-r--r--etc/NEWS4
-rw-r--r--lisp/ChangeLog39
-rw-r--r--lisp/calc/calc-trail.el28
-rw-r--r--lisp/emacs-lisp/smie.el210
-rw-r--r--lisp/net/secrets.el149
-rw-r--r--lisp/subr.el10
-rw-r--r--src/ChangeLog6
-rw-r--r--src/character.c30
8 files changed, 354 insertions, 122 deletions
diff --git a/etc/NEWS b/etc/NEWS
index df68e42cd66..0d07a160ac1 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -214,7 +214,9 @@ threads simultaneously.
214 214
215** secrets.el is an implementation of the Secret Service API, an 215** secrets.el is an implementation of the Secret Service API, an
216interface to password managers like GNOME Keyring or KDE Wallet. The 216interface to password managers like GNOME Keyring or KDE Wallet. The
217Secret Service API requires D-Bus for communication. 217Secret Service API requires D-Bus for communication. The command
218`secrets-show-secrets' offers a buffer with a visualization of the
219secrets.
218 220
219 221
220* Incompatible Lisp Changes in Emacs 24.1 222* Incompatible Lisp Changes in Emacs 24.1
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index d0fc357c4ea..545311d6530 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -4,6 +4,43 @@
4 composition-function-table only for combining characters (Mn, Mc, 4 composition-function-table only for combining characters (Mn, Mc,
5 Me). 5 Me).
6 6
72010-05-18 Jay Belanger <jay.p.belanger@gmail.com>
8
9 * calc/calc-trail.el (calc-trail-isearch-forward)
10 (calc-trail-isearch-backward): Ensure that the new window
11 point is set correctly.
12
132010-05-18 Stefan Monnier <monnier@iro.umontreal.ca>
14
15 * subr.el (read-quoted-char): Resolve modifiers after key
16 remapping (bug#6212).
17
182010-05-18 Michael Albinus <michael.albinus@gmx.de>
19
20 Add visualization code for secrets.
21 * net/secrets.el (secrets-mode): New major mode.
22 (secrets-show-secrets, secrets-show-collections)
23 (secrets-expand-collection, secrets-expand-item)
24 (secrets-tree-widget-after-toggle-function)
25 (secrets-tree-widget-show-password): New defuns.
26
272010-05-18 Stefan Monnier <monnier@iro.umontreal.ca>
28
29 * emacs-lisp/smie.el (smie-next-sexp): Break inf-loop at BOB.
30 (smie-backward-sexp, smie-forward-sexp): Remove boundary condition now
31 handled in smie-next-sexp.
32 (smie-indent-calculate): Provide a starting indentation (so the
33 recursion is well-founded ;-).
34
35 Fix handling of non-associative equal levels.
36 * emacs-lisp/smie.el (smie-prec2-levels): Choose distinct levels even
37 when it's not needed.
38 (smie-op-left, smie-op-right): New functions.
39 (smie-next-sexp): New function, extracted from smie-backward-sexp.
40 Better handle equal levels to distinguish the associative case from
41 the "multi-keyword construct" case.
42 (smie-backward-sexp, smie-forward-sexp): Use it.
43
72010-05-18 Juanma Barranquero <lekktu@gmail.com> 442010-05-18 Juanma Barranquero <lekktu@gmail.com>
8 45
9 * progmodes/prolog.el (smie-indent-basic): Declare for byte-compiler. 46 * progmodes/prolog.el (smie-indent-basic): Declare for byte-compiler.
@@ -135,7 +172,7 @@
1352010-05-13 Michael Albinus <michael.albinus@gmx.de> 1722010-05-13 Michael Albinus <michael.albinus@gmx.de>
136 173
137 * net/tramp.el (with-progress-reporter): Create reporter object 174 * net/tramp.el (with-progress-reporter): Create reporter object
138 only when the message would be displayed. Handled nested calls. 175 only when the message would be displayed. Handle nested calls.
139 (tramp-handle-load, tramp-handle-file-local-copy) 176 (tramp-handle-load, tramp-handle-file-local-copy)
140 (tramp-handle-insert-file-contents, tramp-handle-write-region) 177 (tramp-handle-insert-file-contents, tramp-handle-write-region)
141 (tramp-maybe-send-script, tramp-find-shell): 178 (tramp-maybe-send-script, tramp-find-shell):
diff --git a/lisp/calc/calc-trail.el b/lisp/calc/calc-trail.el
index 9bbb4178fd3..20dc1d1b99e 100644
--- a/lisp/calc/calc-trail.el
+++ b/lisp/calc/calc-trail.el
@@ -108,20 +108,28 @@
108(defun calc-trail-isearch-forward () 108(defun calc-trail-isearch-forward ()
109 (interactive) 109 (interactive)
110 (calc-with-trail-buffer 110 (calc-with-trail-buffer
111 (save-window-excursion 111 (let ((win (get-buffer-window (current-buffer)))
112 (select-window (get-buffer-window (current-buffer))) 112 pos)
113 (let ((search-exit-char ?\r)) 113 (save-window-excursion
114 (isearch-forward))) 114 (select-window win)
115 (calc-trail-here))) 115 (isearch-forward)
116 (setq pos (point)))
117 (goto-char pos)
118 (set-window-point win pos)
119 (calc-trail-here))))
116 120
117(defun calc-trail-isearch-backward () 121(defun calc-trail-isearch-backward ()
118 (interactive) 122 (interactive)
119 (calc-with-trail-buffer 123 (calc-with-trail-buffer
120 (save-window-excursion 124 (let ((win (get-buffer-window (current-buffer)))
121 (select-window (get-buffer-window (current-buffer))) 125 pos)
122 (let ((search-exit-char ?\r)) 126 (save-window-excursion
123 (isearch-backward))) 127 (select-window win)
124 (calc-trail-here))) 128 (isearch-backward)
129 (setq pos (point)))
130 (goto-char pos)
131 (set-window-point win pos)
132 (calc-trail-here))))
125 133
126(defun calc-trail-yank (arg) 134(defun calc-trail-yank (arg)
127 (interactive "P") 135 (interactive "P")
diff --git a/lisp/emacs-lisp/smie.el b/lisp/emacs-lisp/smie.el
index 27ddeb762af..9ea2cf56890 100644
--- a/lisp/emacs-lisp/smie.el
+++ b/lisp/emacs-lisp/smie.el
@@ -252,11 +252,23 @@ PREC2 is a table as returned by `smie-precs-precedence-table' or
252 (dolist (cst csts) 252 (dolist (cst csts)
253 (unless (memq (car cst) rhvs) 253 (unless (memq (car cst) rhvs)
254 (setq progress t) 254 (setq progress t)
255 ;; We could give each var in a given iteration the same value,
256 ;; but we can also give them arbitrarily different values.
257 ;; Basically, these are vars between which there is no
258 ;; constraint (neither equality nor inequality), so
259 ;; anything will do.
260 ;; We give them arbitrary values, which means that we
261 ;; replace the "no constraint" case with either > or <
262 ;; but not =. The reason we do that is so as to try and
263 ;; distinguish associative operators (which will have
264 ;; left = right).
265 (unless (caar cst)
255 (setcar (car cst) i) 266 (setcar (car cst) i)
267 (incf i))
256 (setq csts (delq cst csts)))) 268 (setq csts (delq cst csts))))
257 (unless progress 269 (unless progress
258 (error "Can't resolve the precedence table to precedence levels"))) 270 (error "Can't resolve the precedence table to precedence levels")))
259 (incf i)) 271 (incf i 10))
260 ;; Propagate equalities back to their source. 272 ;; Propagate equalities back to their source.
261 (dolist (eq (nreverse eqs)) 273 (dolist (eq (nreverse eqs))
262 (assert (null (caar eq))) 274 (assert (null (caar eq)))
@@ -278,6 +290,9 @@ PREC2 is a table as returned by `smie-precs-precedence-table' or
278Each element is of the form (TOKEN LEFT-LEVEL RIGHT-LEVEL). 290Each element is of the form (TOKEN LEFT-LEVEL RIGHT-LEVEL).
279Parsing is done using an operator precedence parser.") 291Parsing is done using an operator precedence parser.")
280 292
293(defalias 'smie-op-left 'car)
294(defalias 'smie-op-right 'cadr)
295
281(defun smie-backward-token () 296(defun smie-backward-token ()
282 ;; FIXME: This may be an OK default but probably needs a hook. 297 ;; FIXME: This may be an OK default but probably needs a hook.
283 (buffer-substring (point) 298 (buffer-substring (point)
@@ -292,66 +307,110 @@ Parsing is done using an operator precedence parser.")
292 (skip-syntax-forward "w_'")) 307 (skip-syntax-forward "w_'"))
293 (point)))) 308 (point))))
294 309
295(defun smie-backward-sexp (&optional halfsexp) 310(defun smie-associative-p (toklevels)
311 ;; in "a + b + c" we want to stop at each +, but in
312 ;; "if a then b else c" we don't want to stop at each keyword.
313 ;; To distinguish the two cases, we made smie-prec2-levels choose
314 ;; different levels for each part of "if a then b else c", so that
315 ;; by checking if the left-level is equal to the right level, we can
316 ;; figure out that it's an associative operator.
317 ;; This is not 100% foolproof, tho, since a grammar like
318 ;; (exp ("A" exp "C") ("A" exp "B" exp "C"))
319 ;; will cause "B" to have equal left and right levels, even though
320 ;; it is not an associative operator.
321 ;; A better check would be the check the actual previous operator
322 ;; against this one to see if it's the same, but we'd have to change
323 ;; `levels' to keep a stack of operators rather than only levels.
324 (eq (smie-op-left toklevels) (smie-op-right toklevels)))
325
326(defun smie-next-sexp (next-token next-sexp op-forw op-back halfsexp)
296 "Skip over one sexp. 327 "Skip over one sexp.
328NEXT-TOKEN is a function of no argument that moves forward by one
329token (after skipping comments if needed) and returns it.
330NEXT-SEXP is a lower-level function to skip one sexp.
331OP-FORW is the accessor to the forward level of the level data.
332OP-BACK is the accessor to the backward level of the level data.
297HALFSEXP if non-nil, means skip over a partial sexp if needed. I.e. if the 333HALFSEXP if non-nil, means skip over a partial sexp if needed. I.e. if the
298first token we see is an operator, skip over its left-hand-side argument. 334first token we see is an operator, skip over its left-hand-side argument.
299Possible return values: 335Possible return values:
300 (LEFT-LEVEL POS TOKEN): we couldn't skip TOKEN because its right-level 336 (FORW-LEVEL POS TOKEN): we couldn't skip TOKEN because its back-level
301 is too high. LEFT-LEVEL is the left-level of TOKEN, 337 is too high. FORW-LEVEL is the forw-level of TOKEN,
302 POS is its start position in the buffer. 338 POS is its start position in the buffer.
303 (t POS TOKEN): same thing but for an open-paren or the beginning of buffer. 339 (t POS TOKEN): same thing when we bump on the wrong side of a paren.
304 (nil POS TOKEN): we skipped over a paren-like pair. 340 (nil POS TOKEN): we skipped over a paren-like pair.
305 nil: we skipped over an identifier, matched parentheses, ..." 341 nil: we skipped over an identifier, matched parentheses, ..."
306 (if (bobp) (list t (point)) 342 (catch 'return
307 (catch 'return 343 (let ((levels ()))
308 (let ((levels ())) 344 (while
309 (while 345 (let* ((pos (point))
310 (let* ((pos (point)) 346 (token (funcall next-token))
311 (token (progn (forward-comment (- (point-max))) 347 (toklevels (cdr (assoc token smie-op-levels))))
312 (smie-backward-token))) 348
313 (toklevels (cdr (assoc token smie-op-levels)))) 349 (cond
314 350 ((null toklevels)
351 (when (equal token "")
352 (condition-case err
353 (progn (goto-char pos) (funcall next-sexp 1) nil)
354 (scan-error (throw 'return (list t (caddr err)))))
355 (if (eq pos (point))
356 ;; We did not move, so let's abort the loop.
357 (throw 'return (list t (point))))))
358 ((null (funcall op-back toklevels))
359 ;; A token like a paren-close.
360 (assert (funcall op-forw toklevels)) ;Otherwise, why mention it?
361 (push (funcall op-forw toklevels) levels))
362 (t
363 (while (and levels (< (funcall op-back toklevels) (car levels)))
364 (setq levels (cdr levels)))
315 (cond 365 (cond
316 ((null toklevels) 366 ((null levels)
317 (if (equal token "") 367 (if (and halfsexp (funcall op-forw toklevels))
318 (condition-case err 368 (push (funcall op-forw toklevels) levels)
319 (progn (goto-char pos) (backward-sexp 1) nil) 369 (throw 'return
320 (scan-error (throw 'return (list t (caddr err))))))) 370 (prog1 (list (or (car toklevels) t) (point) token)
321 ((null (nth 1 toklevels)) 371 (goto-char pos)))))
322 ;; A token like a paren-close.
323 (assert (nth 0 toklevels)) ;Otherwise, why mention it?
324 (push (nth 0 toklevels) levels))
325 (t 372 (t
326 (while (and levels (< (nth 1 toklevels) (car levels))) 373 (if (and levels (= (funcall op-back toklevels) (car levels)))
327 (setq levels (cdr levels))) 374 (setq levels (cdr levels)))
328 (cond 375 (cond
329 ((null levels) 376 ((null levels)
330 (if (and halfsexp (nth 0 toklevels)) 377 (cond
331 (push (nth 0 toklevels) levels) 378 ((null (funcall op-forw toklevels))
379 (throw 'return (list nil (point) token)))
380 ((smie-associative-p toklevels)
332 (throw 'return 381 (throw 'return
333 (prog1 (list (or (car toklevels) t) (point) token) 382 (prog1 (list (or (car toklevels) t) (point) token)
334 (goto-char pos))))) 383 (goto-char pos))))
384 ;; We just found a match to the previously pending operator
385 ;; but this new operator is still part of a larger RHS.
386 ;; E.g. we're now looking at the "then" in
387 ;; "if a then b else c". So we have to keep parsing the
388 ;; rest of the construct.
389 (t (push (funcall op-forw toklevels) levels))))
335 (t 390 (t
336 (while (and levels (= (nth 1 toklevels) (car levels))) 391 (if (funcall op-forw toklevels)
337 (setq levels (cdr levels))) 392 (push (funcall op-forw toklevels) levels))))))))
338 (cond 393 levels)
339 ((null levels) 394 (setq halfsexp nil)))))
340 (cond 395
341 ((null (nth 0 toklevels)) 396(defun smie-backward-sexp (&optional halfsexp)
342 (throw 'return (list nil (point) token))) 397 "Skip over one sexp.
343 ((eq (nth 0 toklevels) (nth 1 toklevels)) 398HALFSEXP if non-nil, means skip over a partial sexp if needed. I.e. if the
344 (throw 'return 399first token we see is an operator, skip over its left-hand-side argument.
345 (prog1 (list (or (car toklevels) t) (point) token) 400Possible return values:
346 (goto-char pos)))) 401 (LEFT-LEVEL POS TOKEN): we couldn't skip TOKEN because its right-level
347 (t (debug)))) ;Not sure yet what to do here. 402 is too high. LEFT-LEVEL is the left-level of TOKEN,
348 (t 403 POS is its start position in the buffer.
349 (if (nth 0 toklevels) 404 (t POS TOKEN): same thing but for an open-paren or the beginning of buffer.
350 (push (nth 0 toklevels) levels)))))))) 405 (nil POS TOKEN): we skipped over a paren-like pair.
351 levels) 406 nil: we skipped over an identifier, matched parentheses, ..."
352 (setq halfsexp nil)))))) 407 (smie-next-sexp
353 408 (lambda () (forward-comment (- (point-max))) (smie-backward-token))
354;; Mirror image, not used for indentation. 409 (indirect-function 'backward-sexp)
410 (indirect-function 'smie-op-left)
411 (indirect-function 'smie-op-right)
412 halfsexp))
413
355(defun smie-forward-sexp (&optional halfsexp) 414(defun smie-forward-sexp (&optional halfsexp)
356 "Skip over one sexp. 415 "Skip over one sexp.
357HALFSEXP if non-nil, means skip over a partial sexp if needed. I.e. if the 416HALFSEXP if non-nil, means skip over a partial sexp if needed. I.e. if the
@@ -363,53 +422,12 @@ Possible return values:
363 (t POS TOKEN): same thing but for an open-paren or the beginning of buffer. 422 (t POS TOKEN): same thing but for an open-paren or the beginning of buffer.
364 (nil POS TOKEN): we skipped over a paren-like pair. 423 (nil POS TOKEN): we skipped over a paren-like pair.
365 nil: we skipped over an identifier, matched parentheses, ..." 424 nil: we skipped over an identifier, matched parentheses, ..."
366 (if (eobp) (list t (point)) 425 (smie-next-sexp
367 (catch 'return 426 (lambda () (forward-comment (point-max)) (smie-forward-token))
368 (let ((levels ())) 427 (indirect-function 'forward-sexp)
369 (while 428 (indirect-function 'smie-op-right)
370 (let* ((pos (point)) 429 (indirect-function 'smie-op-left)
371 (token (progn (forward-comment (point-max)) 430 halfsexp))
372 (smie-forward-token)))
373 (toklevels (cdr (assoc token smie-op-levels))))
374
375 (cond
376 ((null toklevels)
377 (if (equal token "")
378 (condition-case err
379 (progn (goto-char pos) (forward-sexp 1) nil)
380 (scan-error (throw 'return (list t (caddr err)))))))
381 ((null (nth 0 toklevels))
382 ;; A token like a paren-close.
383 (assert (nth 1 toklevels)) ;Otherwise, why mention it?
384 (push (nth 1 toklevels) levels))
385 (t
386 (while (and levels (< (nth 0 toklevels) (car levels)))
387 (setq levels (cdr levels)))
388 (cond
389 ((null levels)
390 (if (and halfsexp (nth 1 toklevels))
391 (push (nth 1 toklevels) levels)
392 (throw 'return
393 (prog1 (list (or (nth 1 toklevels) t) (point) token)
394 (goto-char pos)))))
395 (t
396 (while (and levels (= (nth 0 toklevels) (car levels)))
397 (setq levels (cdr levels)))
398 (cond
399 ((null levels)
400 (cond
401 ((null (nth 1 toklevels))
402 (throw 'return (list nil (point) token)))
403 ((eq (nth 1 toklevels) (nth 0 toklevels))
404 (throw 'return
405 (prog1 (list (or (nth 1 toklevels) t) (point) token)
406 (goto-char pos))))
407 (t (debug)))) ;Not sure yet what to do here.
408 (t
409 (if (nth 1 toklevels)
410 (push (nth 1 toklevels) levels))))))))
411 levels)
412 (setq halfsexp nil))))))
413 431
414(defun smie-backward-sexp-command (&optional n) 432(defun smie-backward-sexp-command (&optional n)
415 "Move backward through N logical elements." 433 "Move backward through N logical elements."
@@ -496,6 +514,10 @@ VIRTUAL can take two different non-nil values:
496 (and virtual 514 (and virtual
497 (if (eq virtual :hanging) (not (smie-indent-hanging-p)) (smie-bolp)) 515 (if (eq virtual :hanging) (not (smie-indent-hanging-p)) (smie-bolp))
498 (current-column)) 516 (current-column))
517 ;; Start the file at column 0.
518 (save-excursion
519 (forward-comment (- (point-max)))
520 (if (bobp) 0))
499 ;; Align close paren with opening paren. 521 ;; Align close paren with opening paren.
500 (save-excursion 522 (save-excursion
501 ;; (forward-comment (point-max)) 523 ;; (forward-comment (point-max))
diff --git a/lisp/net/secrets.el b/lisp/net/secrets.el
index c45f6fbb276..a7225d663e3 100644
--- a/lisp/net/secrets.el
+++ b/lisp/net/secrets.el
@@ -129,6 +129,9 @@
129;; (secrets-search-items "session" :user "joe") 129;; (secrets-search-items "session" :user "joe")
130;; => ("my item" "another item") 130;; => ("my item" "another item")
131 131
132;; Interactively, collections, items and their attributes could be
133;; inspected by the command `secrets-show-secrets'.
134
132;;; Code: 135;;; Code:
133 136
134;; It has been tested with GNOME Keyring 2.29.92. An implementation 137;; It has been tested with GNOME Keyring 2.29.92. An implementation
@@ -148,6 +151,13 @@
148 151
149(require 'dbus) 152(require 'dbus)
150 153
154(declare-function tree-widget-set-theme "tree-widget")
155(declare-function widget-create-child-and-convert "wid-edit")
156(declare-function widget-default-value-set "wid-edit")
157(declare-function widget-field-end "wid-edit")
158(declare-function widget-member "wid-edit")
159(defvar tree-widget-after-toggle-functions)
160
151(defvar secrets-enabled nil 161(defvar secrets-enabled nil
152 "Whether there is a daemon offering the Secret Service API.") 162 "Whether there is a daemon offering the Secret Service API.")
153 163
@@ -665,6 +675,145 @@ If there is no such item, or the item doesn't own this attribute, return nil."
665 :session secrets-service item-path 675 :session secrets-service item-path
666 secrets-interface-item "Delete"))))) 676 secrets-interface-item "Delete")))))
667 677
678;;; Visualization.
679
680(define-derived-mode secrets-mode nil "Secrets"
681 "Major mode for presenting search results of a Xesam search.
682In this mode, widgets represent the search results.
683
684\\{secrets-mode-map}
685Turning on Xesam mode runs the normal hook `xesam-mode-hook'. It
686can be used to set `xesam-notify-function', which must a search
687engine specific, widget :notify function to visualize xesam:url."
688 ;; Keymap.
689 (setq secrets-mode-map (copy-keymap special-mode-map))
690 (set-keymap-parent secrets-mode-map widget-keymap)
691 (define-key secrets-mode-map "z" 'kill-this-buffer)
692
693 ;; When we toggle, we must set temporary widgets.
694 (set (make-local-variable 'tree-widget-after-toggle-functions)
695 '(secrets-tree-widget-after-toggle-function))
696
697 (when (not (called-interactively-p 'interactive))
698 ;; Initialize buffer.
699 (setq buffer-read-only t)
700 (let ((inhibit-read-only t))
701 (erase-buffer))))
702
703;; It doesn't make sense to call it interactively.
704(put 'secrets-mode 'disabled t)
705
706;; The very first buffer created with `secrets-mode' does not have the
707;; keymap etc. So we create a dummy buffer. Stupid.
708(with-temp-buffer (secrets-mode))
709
710;;;###autoload
711(defun secrets-show-secrets ()
712 "Display a list of collections from the Secret Service API.
713The collections are in tree view, that means they can be expanded
714to the corresponding secret items, which could also be expanded
715to their attributes."
716 (interactive)
717 ;; Create the search buffer.
718 (with-current-buffer (get-buffer-create "*Secrets*")
719 (switch-to-buffer-other-window (current-buffer))
720 ;; Inialize buffer with `secrets-mode'.
721 (secrets-mode)
722 (secrets-show-collections)))
723
724(defun secrets-show-collections ()
725 "Show all available collections."
726 (let ((inhibit-read-only t)
727 (alias (secrets-get-alias "default")))
728 (erase-buffer)
729 (tree-widget-set-theme "folder")
730 (dolist (coll (secrets-list-collections))
731 (widget-create
732 `(tree-widget
733 :tag ,coll
734 :collection ,coll
735 :open nil
736 :sample-face bold
737 :expander secrets-expand-collection)))))
738
739(defun secrets-expand-collection (widget)
740 "Expand items of collection shown as WIDGET."
741 (let ((coll (widget-get widget :collection)))
742 (mapcar
743 (lambda (item)
744 `(tree-widget
745 :tag ,item
746 :collection ,coll
747 :item ,item
748 :open nil
749 :sample-face bold
750 :expander secrets-expand-item))
751 (secrets-list-items coll))))
752
753(defun secrets-expand-item (widget)
754 "Expand password and attributes of item shown as WIDGET."
755 (let* ((coll (widget-get widget :collection))
756 (item (widget-get widget :item))
757 (attributes (secrets-get-attributes coll item))
758 ;; padding is needed to format attribute names.
759 (padding
760 (1+
761 (apply
762 'max
763 (cons
764 (length "password")
765 (mapcar
766 (lambda (attribute) (length (symbol-name (car attribute))))
767 attributes))))))
768 (cons
769 ;; The password widget.
770 `(editable-field :tag "password"
771 :secret ?*
772 :value ,(secrets-get-secret coll item)
773 :sample-face widget-button-pressed
774 ;; We specify :size in order to limit the field.
775 :size 0
776 :format ,(concat
777 "%{%t%}:"
778 (make-string (- padding (length "password")) ? )
779 "%v\n"))
780 (mapcar
781 (lambda (attribute)
782 (let ((name (symbol-name (car attribute)))
783 (value (cdr attribute)))
784 ;; The attribute widget.
785 `(editable-field :tag ,name
786 :value ,value
787 :sample-face widget-documentation
788 ;; We specify :size in order to limit the field.
789 :size 0
790 :format ,(concat
791 "%{%t%}:"
792 (make-string (- padding (length name)) ? )
793 "%v\n"))))
794 attributes))))
795
796(defun secrets-tree-widget-after-toggle-function (widget &rest ignore)
797 "Add a temporary widget to show the password."
798 (dolist (child (widget-get widget :children))
799 (when (widget-member child :secret)
800 (goto-char (widget-field-end child))
801 (widget-insert " ")
802 (widget-create-child-and-convert
803 child 'push-button
804 :notify 'secrets-tree-widget-show-password
805 "Show password")))
806 (widget-setup))
807
808(defun secrets-tree-widget-show-password (widget &rest ignore)
809 "Show password, and remove temporary widget."
810 (let ((parent (widget-get widget :parent)))
811 (widget-put parent :secret nil)
812 (widget-default-value-set parent (widget-get parent :value))
813 (widget-setup)))
814
815;;; Initialization.
816
668(when (dbus-ping :session secrets-service 100) 817(when (dbus-ping :session secrets-service 100)
669 818
670 ;; We must reset all variables, when there is a new instance of the 819 ;; We must reset all variables, when there is a new instance of the
diff --git a/lisp/subr.el b/lisp/subr.el
index 1c399f89b9c..fb84f95c805 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -1868,16 +1868,14 @@ any other non-digit terminates the character code and is then used as input."))
1868 (if inhibit-quit (setq quit-flag nil))) 1868 (if inhibit-quit (setq quit-flag nil)))
1869 ;; Translate TAB key into control-I ASCII character, and so on. 1869 ;; Translate TAB key into control-I ASCII character, and so on.
1870 ;; Note: `read-char' does it using the `ascii-character' property. 1870 ;; Note: `read-char' does it using the `ascii-character' property.
1871 ;; We could try and use read-key-sequence instead, but then C-q ESC 1871 ;; We should try and use read-key instead.
1872 ;; or C-q C-x might not return immediately since ESC or C-x might be 1872 (let ((translation (lookup-key local-function-key-map (vector char))))
1873 ;; bound to some prefix in function-key-map or key-translation-map. 1873 (if (arrayp translation)
1874 (setq translated (aref translation 0))))
1874 (setq translated 1875 (setq translated
1875 (if (integerp char) 1876 (if (integerp char)
1876 (char-resolve-modifiers char) 1877 (char-resolve-modifiers char)
1877 char)) 1878 char))
1878 (let ((translation (lookup-key local-function-key-map (vector char))))
1879 (if (arrayp translation)
1880 (setq translated (aref translation 0))))
1881 (cond ((null translated)) 1879 (cond ((null translated))
1882 ((not (integerp translated)) 1880 ((not (integerp translated))
1883 (setq unread-command-events (list char) 1881 (setq unread-command-events (list char)
diff --git a/src/ChangeLog b/src/ChangeLog
index b0965f8e514..46346931085 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,9 @@
12010-05-18 Chong Yidong <cyd@stupidchicken.com>
2
3 * character.c (Fstring, Funibyte_string): Use SAFE_ALLOCA to
4 prevent stack overflow if number of arguments is too large
5 (Bug#6214).
6
12010-05-18 Juanma Barranquero <lekktu@gmail.com> 72010-05-18 Juanma Barranquero <lekktu@gmail.com>
2 8
3 * charset.c (load_charset_map_from_file): Don't call close after fclose. 9 * charset.c (load_charset_map_from_file): Don't call close after fclose.
diff --git a/src/character.c b/src/character.c
index 5912a70d0ce..7cd1eedcef4 100644
--- a/src/character.c
+++ b/src/character.c
@@ -961,10 +961,13 @@ usage: (string &rest CHARACTERS) */)
961 int n; 961 int n;
962 Lisp_Object *args; 962 Lisp_Object *args;
963{ 963{
964 int i; 964 int i, c;
965 unsigned char *buf = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH * n); 965 unsigned char *buf, *p;
966 unsigned char *p = buf; 966 Lisp_Object str;
967 int c; 967 USE_SAFE_ALLOCA;
968
969 SAFE_ALLOCA (buf, unsigned char *, MAX_MULTIBYTE_LENGTH * n);
970 p = buf;
968 971
969 for (i = 0; i < n; i++) 972 for (i = 0; i < n; i++)
970 { 973 {
@@ -973,7 +976,9 @@ usage: (string &rest CHARACTERS) */)
973 p += CHAR_STRING (c, p); 976 p += CHAR_STRING (c, p);
974 } 977 }
975 978
976 return make_string_from_bytes ((char *) buf, n, p - buf); 979 str = make_string_from_bytes ((char *) buf, n, p - buf);
980 SAFE_FREE ();
981 return str;
977} 982}
978 983
979DEFUN ("unibyte-string", Funibyte_string, Sunibyte_string, 0, MANY, 0, 984DEFUN ("unibyte-string", Funibyte_string, Sunibyte_string, 0, MANY, 0,
@@ -983,10 +988,13 @@ usage: (unibyte-string &rest BYTES) */)
983 int n; 988 int n;
984 Lisp_Object *args; 989 Lisp_Object *args;
985{ 990{
986 int i; 991 int i, c;
987 unsigned char *buf = (unsigned char *) alloca (n); 992 unsigned char *buf, *p;
988 unsigned char *p = buf; 993 Lisp_Object str;
989 unsigned c; 994 USE_SAFE_ALLOCA;
995
996 SAFE_ALLOCA (buf, unsigned char *, n);
997 p = buf;
990 998
991 for (i = 0; i < n; i++) 999 for (i = 0; i < n; i++)
992 { 1000 {
@@ -997,7 +1005,9 @@ usage: (unibyte-string &rest BYTES) */)
997 *p++ = c; 1005 *p++ = c;
998 } 1006 }
999 1007
1000 return make_string_from_bytes ((char *) buf, n, p - buf); 1008 str = make_string_from_bytes ((char *) buf, n, p - buf);
1009 SAFE_FREE ();
1010 return str;
1001} 1011}
1002 1012
1003DEFUN ("char-resolve-modifiers", Fchar_resolve_modifiers, 1013DEFUN ("char-resolve-modifiers", Fchar_resolve_modifiers,