diff options
| author | Kenichi Handa | 2010-05-19 10:16:01 +0900 |
|---|---|---|
| committer | Kenichi Handa | 2010-05-19 10:16:01 +0900 |
| commit | 9ba3dd48988911d24100dad2b67e5b45189083dd (patch) | |
| tree | ea1334ba49103db7820757424f7043fd62333890 | |
| parent | 134d1bcded02e066727ece838f14ffc767f76419 (diff) | |
| parent | 134c2f29cef985c940bd9496a1e69dff850b80a3 (diff) | |
| download | emacs-9ba3dd48988911d24100dad2b67e5b45189083dd.tar.gz emacs-9ba3dd48988911d24100dad2b67e5b45189083dd.zip | |
merge trunk
| -rw-r--r-- | etc/NEWS | 4 | ||||
| -rw-r--r-- | lisp/ChangeLog | 39 | ||||
| -rw-r--r-- | lisp/calc/calc-trail.el | 28 | ||||
| -rw-r--r-- | lisp/emacs-lisp/smie.el | 210 | ||||
| -rw-r--r-- | lisp/net/secrets.el | 149 | ||||
| -rw-r--r-- | lisp/subr.el | 10 | ||||
| -rw-r--r-- | src/ChangeLog | 6 | ||||
| -rw-r--r-- | src/character.c | 30 |
8 files changed, 354 insertions, 122 deletions
| @@ -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 |
| 216 | interface to password managers like GNOME Keyring or KDE Wallet. The | 216 | interface to password managers like GNOME Keyring or KDE Wallet. The |
| 217 | Secret Service API requires D-Bus for communication. | 217 | Secret Service API requires D-Bus for communication. The command |
| 218 | `secrets-show-secrets' offers a buffer with a visualization of the | ||
| 219 | secrets. | ||
| 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 | ||
| 7 | 2010-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 | |||
| 13 | 2010-05-18 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 14 | |||
| 15 | * subr.el (read-quoted-char): Resolve modifiers after key | ||
| 16 | remapping (bug#6212). | ||
| 17 | |||
| 18 | 2010-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 | |||
| 27 | 2010-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 | |||
| 7 | 2010-05-18 Juanma Barranquero <lekktu@gmail.com> | 44 | 2010-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 @@ | |||
| 135 | 2010-05-13 Michael Albinus <michael.albinus@gmx.de> | 172 | 2010-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 | |||
| 278 | Each element is of the form (TOKEN LEFT-LEVEL RIGHT-LEVEL). | 290 | Each element is of the form (TOKEN LEFT-LEVEL RIGHT-LEVEL). |
| 279 | Parsing is done using an operator precedence parser.") | 291 | Parsing 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. |
| 328 | NEXT-TOKEN is a function of no argument that moves forward by one | ||
| 329 | token (after skipping comments if needed) and returns it. | ||
| 330 | NEXT-SEXP is a lower-level function to skip one sexp. | ||
| 331 | OP-FORW is the accessor to the forward level of the level data. | ||
| 332 | OP-BACK is the accessor to the backward level of the level data. | ||
| 297 | HALFSEXP if non-nil, means skip over a partial sexp if needed. I.e. if the | 333 | HALFSEXP if non-nil, means skip over a partial sexp if needed. I.e. if the |
| 298 | first token we see is an operator, skip over its left-hand-side argument. | 334 | first token we see is an operator, skip over its left-hand-side argument. |
| 299 | Possible return values: | 335 | Possible 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)) | 398 | HALFSEXP if non-nil, means skip over a partial sexp if needed. I.e. if the |
| 344 | (throw 'return | 399 | first token we see is an operator, skip over its left-hand-side argument. |
| 345 | (prog1 (list (or (car toklevels) t) (point) token) | 400 | Possible 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. |
| 357 | HALFSEXP if non-nil, means skip over a partial sexp if needed. I.e. if the | 416 | HALFSEXP 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. | ||
| 682 | In this mode, widgets represent the search results. | ||
| 683 | |||
| 684 | \\{secrets-mode-map} | ||
| 685 | Turning on Xesam mode runs the normal hook `xesam-mode-hook'. It | ||
| 686 | can be used to set `xesam-notify-function', which must a search | ||
| 687 | engine 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. | ||
| 713 | The collections are in tree view, that means they can be expanded | ||
| 714 | to the corresponding secret items, which could also be expanded | ||
| 715 | to 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 @@ | |||
| 1 | 2010-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 | |||
| 1 | 2010-05-18 Juanma Barranquero <lekktu@gmail.com> | 7 | 2010-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 | ||
| 979 | DEFUN ("unibyte-string", Funibyte_string, Sunibyte_string, 0, MANY, 0, | 984 | DEFUN ("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 | ||
| 1003 | DEFUN ("char-resolve-modifiers", Fchar_resolve_modifiers, | 1013 | DEFUN ("char-resolve-modifiers", Fchar_resolve_modifiers, |