diff options
| author | Richard M. Stallman | 1996-09-01 19:47:48 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1996-09-01 19:47:48 +0000 |
| commit | 670ce6ea7a4e4d19333020c4eb84d98a658e22d6 (patch) | |
| tree | 5b04160d73a2c17b389ce24be509b66e2b29e3e1 /lisp | |
| parent | 6ec8bbd20d14dadb850f993d828b42bb97deba32 (diff) | |
| download | emacs-670ce6ea7a4e4d19333020c4eb84d98a658e22d6.tar.gz emacs-670ce6ea7a4e4d19333020c4eb84d98a658e22d6.zip | |
(tmm-add-one-shortcut): New subroutine.
(tmm-add-shortcuts): Code moved to tmm-add-one-shortcut.
Handle tmm-shortcut-style and tmm-shortcut-words.
(tmm-define-keys): Use suppress-keymap.
Moved use-local-map from the caller here.
tmm-short-cuts is now a list of chars, not of one-char strings.
(tmm-completion-delete-prompt): New function, used in
completion-setup-hook.
(tmm-shortcut-style): New variable.
(tmm-shortcut-words): New variable.
(tmm-shortcut): Handle tmm-shortcut-style.
The shortcut searched in tmm-short-cuts is now a char, not a string.
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/tmm.el | 156 |
1 files changed, 99 insertions, 57 deletions
diff --git a/lisp/tmm.el b/lisp/tmm.el index 0b1b4c47663..b016e8231bf 100644 --- a/lisp/tmm.el +++ b/lisp/tmm.el | |||
| @@ -42,6 +42,7 @@ | |||
| 42 | (defvar tmm-old-comp-map) | 42 | (defvar tmm-old-comp-map) |
| 43 | (defvar tmm-c-prompt) | 43 | (defvar tmm-c-prompt) |
| 44 | (defvar tmm-km-list) | 44 | (defvar tmm-km-list) |
| 45 | (defvar tmm-next-shortcut-digit) | ||
| 45 | (defvar tmm-table-undef) | 46 | (defvar tmm-table-undef) |
| 46 | 47 | ||
| 47 | ;;;###autoload (define-key global-map "\M-`" 'tmm-menubar) | 48 | ;;;###autoload (define-key global-map "\M-`" 'tmm-menubar) |
| @@ -94,7 +95,9 @@ See the documentation for `tmm-prompt'." | |||
| 94 | (tmm-menubar (car (posn-x-y (event-start event))))) | 95 | (tmm-menubar (car (posn-x-y (event-start event))))) |
| 95 | 96 | ||
| 96 | (defvar tmm-mid-prompt "==>" | 97 | (defvar tmm-mid-prompt "==>" |
| 97 | "String to insert between shortcut and menu item or nil.") | 98 | "*String to insert between shortcut and menu item. |
| 99 | If nil, there will be no shortcuts. It should not consist only of spaces, | ||
| 100 | or else the correct item might not be found in the `*Completions*' buffer.") | ||
| 98 | 101 | ||
| 99 | (defvar tmm-mb-map nil | 102 | (defvar tmm-mb-map nil |
| 100 | "A place to store minibuffer map.") | 103 | "A place to store minibuffer map.") |
| @@ -105,9 +108,19 @@ Alternatively, you can use Up/Down keys (or your History keys) to change | |||
| 105 | the item in the minibuffer, and press RET when you are done, or press the | 108 | the item in the minibuffer, and press RET when you are done, or press the |
| 106 | marked letters to pick up your choice. Type C-g or ESC ESC ESC to cancel. | 109 | marked letters to pick up your choice. Type C-g or ESC ESC ESC to cancel. |
| 107 | " | 110 | " |
| 108 | "String to insert at top of completion buffer. | 111 | "*Help text to insert on the top of the completion buffer. |
| 109 | If this is nil, delete even the usual help text | 112 | To save space, you can set this to nil, |
| 110 | and show just the alternatives.") | 113 | in which case the standard introduction text is deleted too.") |
| 114 | |||
| 115 | (defvar tmm-shortcut-style '(downcase upcase) | ||
| 116 | "*What letters to use as menu shortcuts. | ||
| 117 | Must be either one of the symbols `downcase' or `upcase', | ||
| 118 | or else a list of the two in the order you prefer.") | ||
| 119 | |||
| 120 | (defvar tmm-shortcut-words 2 | ||
| 121 | "*How many successive words to try for shortcuts, nil means all. | ||
| 122 | If you use only one of `downcase' or `upcase' for `tmm-shortcut-style', | ||
| 123 | specify nil for this variable.") | ||
| 111 | 124 | ||
| 112 | ;;;###autoload | 125 | ;;;###autoload |
| 113 | (defun tmm-prompt (menu &optional in-popup default-item) | 126 | (defun tmm-prompt (menu &optional in-popup default-item) |
| @@ -221,77 +234,106 @@ Its value should be an event that has a binding in MENU." | |||
| 221 | (call-interactively choice)) | 234 | (call-interactively choice)) |
| 222 | choice))))) | 235 | choice))))) |
| 223 | 236 | ||
| 224 | |||
| 225 | (defun tmm-add-shortcuts (list) | 237 | (defun tmm-add-shortcuts (list) |
| 226 | "Adds shortcuts to cars of elements of the list. | 238 | "Adds shortcuts to cars of elements of the list. |
| 227 | Takes a list of lists with a string as car, returns list with | 239 | Takes a list of lists with a string as car, returns list with |
| 228 | shortcuts added to these cars. | 240 | shortcuts added to these cars. |
| 229 | Stores a list of all the shortcuts in the free variable `tmm-short-cuts'." | 241 | Stores a list of all the shortcuts in the free variable `tmm-short-cuts'." |
| 230 | (let ((next-shortcut-number 0)) | 242 | (let ((tmm-next-shortcut-digit ?0)) |
| 231 | (mapcar (lambda (elt) | 243 | (mapcar 'tmm-add-one-shortcut (reverse list)))) |
| 232 | (let ((str (car elt)) f b) | 244 | |
| 233 | (setq f (upcase (substring str 0 1))) | 245 | (defsubst tmm-add-one-shortcut (elt) |
| 234 | ;; If does not work, try beginning of the other word | 246 | ;; uses the free vars tmm-next-shortcut-digit and tmm-short-cuts |
| 235 | (if (and (member f tmm-short-cuts) | 247 | (let* ((str (car elt)) |
| 236 | (string-match " \\([^ ]\\)" str)) | 248 | (paren (string-match "(" str)) |
| 237 | (setq f (upcase (substring | 249 | (pos 0) (word 0) char) |
| 238 | str | 250 | (catch 'done ; ??? is this slow? |
| 239 | (setq b (match-beginning 1)) (1+ b))))) | 251 | (while (and (or (not tmm-shortcut-words) ; no limit on words |
| 240 | ;; If we don't have an unique letter shortcut, | 252 | (< word tmm-shortcut-words)) ; try n words |
| 241 | ;; pick a digit as a shortcut instead. | 253 | (setq pos (string-match "\\w+" str pos)) ; get next word |
| 242 | (if (member f tmm-short-cuts) | 254 | (not (and paren (> pos paren)))) ; don't go past "(binding.." |
| 243 | (if (< next-shortcut-number 10) | 255 | (if (or (= pos 0) |
| 244 | (setq f (format "%d" next-shortcut-number) | 256 | (/= (aref str (1- pos)) ?.)) ; avoid file extensions |
| 245 | next-shortcut-number (1+ next-shortcut-number)) | 257 | (let ((shortcut-style |
| 246 | (setq f nil))) | 258 | (if (listp tmm-shortcut-style) ; convert to list |
| 247 | (if (null f) | 259 | tmm-shortcut-style |
| 248 | elt | 260 | (list tmm-shortcut-style)))) |
| 249 | (setq tmm-short-cuts (cons f tmm-short-cuts)) | 261 | (while shortcut-style ; try upcase and downcase variants |
| 250 | (cons (concat f tmm-mid-prompt str) (cdr elt))))) | 262 | (setq char (funcall (car shortcut-style) (aref str pos))) |
| 251 | (reverse list)))) | 263 | (if (not (memq char tmm-short-cuts)) (throw 'done char)) |
| 252 | 264 | (setq shortcut-style (cdr shortcut-style))))) | |
| 265 | (setq word (1+ word)) | ||
| 266 | (setq pos (match-end 0))) | ||
| 267 | (while (<= tmm-next-shortcut-digit ?9) ; no letter shortcut, pick a digit | ||
| 268 | (setq char tmm-next-shortcut-digit) | ||
| 269 | (setq tmm-next-shortcut-digit (1+ tmm-next-shortcut-digit)) | ||
| 270 | (if (not (memq char tmm-short-cuts)) (throw 'done char))) | ||
| 271 | (setq char nil)) | ||
| 272 | (if char (setq tmm-short-cuts (cons char tmm-short-cuts))) | ||
| 273 | (cons (concat (if char (concat (char-to-string char) tmm-mid-prompt) | ||
| 274 | ;; keep them lined up in columns | ||
| 275 | (make-string (1+ (length tmm-mid-prompt)) ?\ )) | ||
| 276 | str) | ||
| 277 | (cdr elt)))) | ||
| 278 | |||
| 279 | ;; This returns the old map. | ||
| 253 | (defun tmm-define-keys (minibuffer) | 280 | (defun tmm-define-keys (minibuffer) |
| 254 | (mapcar (lambda (str) | 281 | (let ((map (make-sparse-keymap))) |
| 255 | (define-key (current-local-map) str 'tmm-shortcut) | 282 | (suppress-keymap map t) |
| 256 | (define-key (current-local-map) (downcase str) 'tmm-shortcut)) | 283 | (mapcar |
| 257 | tmm-short-cuts) | 284 | (function |
| 258 | (if minibuffer | 285 | (lambda (c) |
| 259 | (progn | 286 | (if (listp tmm-shortcut-style) |
| 260 | (define-key (current-local-map) [pageup] 'tmm-goto-completions) | 287 | (define-key map (char-to-string c) 'tmm-shortcut) |
| 261 | (define-key (current-local-map) [prior] 'tmm-goto-completions) | 288 | ;; only one kind of letters are shortcuts, so map both upcase and |
| 262 | (define-key (current-local-map) "\ev" 'tmm-goto-completions) | 289 | ;; downcase input to the same |
| 263 | (define-key (current-local-map) "\C-n" 'next-history-element) | 290 | (define-key map (char-to-string (downcase c)) 'tmm-shortcut) |
| 264 | (define-key (current-local-map) "\C-p" 'previous-history-element)))) | 291 | (define-key map (char-to-string (upcase c)) 'tmm-shortcut)))) |
| 292 | tmm-short-cuts) | ||
| 293 | (if minibuffer | ||
| 294 | (progn | ||
| 295 | (define-key map [pageup] 'tmm-goto-completions) | ||
| 296 | (define-key map [prior] 'tmm-goto-completions) | ||
| 297 | (define-key map "\ev" 'tmm-goto-completions) | ||
| 298 | (define-key map "\C-n" 'next-history-element) | ||
| 299 | (define-key map "\C-p" 'previous-history-element))) | ||
| 300 | (prog1 (current-local-map) | ||
| 301 | (use-local-map (append map (current-local-map)))))) | ||
| 302 | |||
| 303 | (defun tmm-completion-delete-prompt () | ||
| 304 | (set-buffer standard-output) | ||
| 305 | (goto-char 1) | ||
| 306 | (delete-region 1 (search-forward "Possible completions are:\n"))) | ||
| 265 | 307 | ||
| 266 | (defun tmm-add-prompt () | 308 | (defun tmm-add-prompt () |
| 267 | (remove-hook 'minibuffer-setup-hook 'tmm-add-prompt) | 309 | (remove-hook 'minibuffer-setup-hook 'tmm-add-prompt) |
| 268 | (make-local-hook 'minibuffer-exit-hook) | 310 | (make-local-hook 'minibuffer-exit-hook) |
| 269 | (add-hook 'minibuffer-exit-hook 'tmm-delete-map nil t) | 311 | (add-hook 'minibuffer-exit-hook 'tmm-delete-map nil t) |
| 270 | (let ((win (selected-window))) | 312 | (let ((win (selected-window))) |
| 271 | (setq tmm-old-mb-map (current-local-map)) | 313 | (setq tmm-old-mb-map (tmm-define-keys t)) |
| 272 | (use-local-map (append (make-sparse-keymap) tmm-old-mb-map)) | ||
| 273 | (tmm-define-keys t) | ||
| 274 | ;; Get window and hide it for electric mode to get correct size | 314 | ;; Get window and hide it for electric mode to get correct size |
| 275 | (save-window-excursion | 315 | (save-window-excursion |
| 276 | (let ((completions | 316 | (let ((completions |
| 277 | (mapcar 'car minibuffer-completion-table))) | 317 | (mapcar 'car minibuffer-completion-table))) |
| 318 | (or tmm-completion-prompt | ||
| 319 | (add-hook 'completion-setup-hook | ||
| 320 | 'tmm-completion-delete-prompt 'append)) | ||
| 278 | (with-output-to-temp-buffer "*Completions*" | 321 | (with-output-to-temp-buffer "*Completions*" |
| 279 | (display-completion-list completions))) | 322 | (display-completion-list completions)) |
| 323 | (remove-hook 'completion-setup-hook 'tmm-completion-delete-prompt)) | ||
| 324 | (if tmm-completion-prompt | ||
| 325 | (progn | ||
| 280 | (set-buffer "*Completions*") | 326 | (set-buffer "*Completions*") |
| 281 | (goto-char 1) | 327 | (goto-char 1) |
| 282 | (if tmm-completion-prompt | 328 | (insert tmm-completion-prompt))) |
| 283 | (insert tmm-completion-prompt) | ||
| 284 | ;; Delete even the usual help info that all completion buffers have. | ||
| 285 | (goto-char 1) | ||
| 286 | (delete-region 1 (search-forward "Possible completions are:\n"))) | ||
| 287 | ) | 329 | ) |
| 288 | (save-excursion | 330 | (save-excursion |
| 289 | (other-window 1) ; Electric-pop-up-window does | 331 | (other-window 1) ; Electric-pop-up-window does |
| 290 | ; not work in minibuffer | 332 | ; not work in minibuffer |
| 291 | (set-buffer (window-buffer (Electric-pop-up-window "*Completions*"))) | 333 | (set-buffer (window-buffer (Electric-pop-up-window "*Completions*"))) |
| 292 | (setq tmm-old-comp-map (current-local-map)) | 334 | |
| 293 | (use-local-map (append (make-sparse-keymap) tmm-old-comp-map)) | 335 | (setq tmm-old-comp-map (tmm-define-keys nil)) |
| 294 | (tmm-define-keys nil) | 336 | |
| 295 | (select-window win) ; Cannot use | 337 | (select-window win) ; Cannot use |
| 296 | ; save-window-excursion, since | 338 | ; save-window-excursion, since |
| 297 | ; it restores the size | 339 | ; it restores the size |
| @@ -306,13 +348,15 @@ Stores a list of all the shortcuts in the free variable `tmm-short-cuts'." | |||
| 306 | (defun tmm-shortcut () | 348 | (defun tmm-shortcut () |
| 307 | "Choose the shortcut that the user typed." | 349 | "Choose the shortcut that the user typed." |
| 308 | (interactive) | 350 | (interactive) |
| 309 | (let ((c (upcase (char-to-string last-command-char))) s) | 351 | (let ((c last-command-char) s) |
| 310 | (if (member c tmm-short-cuts) | 352 | (if (symbolp tmm-shortcut-style) |
| 353 | (setq c (funcall tmm-shortcut-style c))) | ||
| 354 | (if (memq c tmm-short-cuts) | ||
| 311 | (if (equal (buffer-name) "*Completions*") | 355 | (if (equal (buffer-name) "*Completions*") |
| 312 | (progn | 356 | (progn |
| 313 | (beginning-of-buffer) | 357 | (beginning-of-buffer) |
| 314 | (re-search-forward | 358 | (re-search-forward |
| 315 | (concat "\\(^\\|[ \t]\\)" c tmm-mid-prompt)) | 359 | (concat "\\(^\\|[ \t]\\)" (char-to-string c) tmm-mid-prompt)) |
| 316 | (choose-completion)) | 360 | (choose-completion)) |
| 317 | (erase-buffer) ; In minibuffer | 361 | (erase-buffer) ; In minibuffer |
| 318 | (mapcar (lambda (elt) | 362 | (mapcar (lambda (elt) |
| @@ -320,7 +364,7 @@ Stores a list of all the shortcuts in the free variable `tmm-short-cuts'." | |||
| 320 | (substring (car elt) 0 | 364 | (substring (car elt) 0 |
| 321 | (min (1+ (length tmm-mid-prompt)) | 365 | (min (1+ (length tmm-mid-prompt)) |
| 322 | (length (car elt)))) | 366 | (length (car elt)))) |
| 323 | (concat c tmm-mid-prompt)) | 367 | (concat (char-to-string c) tmm-mid-prompt)) |
| 324 | (setq s (car elt)))) | 368 | (setq s (car elt)))) |
| 325 | tmm-km-list) | 369 | tmm-km-list) |
| 326 | (insert s) | 370 | (insert s) |
| @@ -334,7 +378,6 @@ Stores a list of all the shortcuts in the free variable `tmm-short-cuts'." | |||
| 334 | (search-forward tmm-c-prompt) | 378 | (search-forward tmm-c-prompt) |
| 335 | (search-backward tmm-c-prompt)) | 379 | (search-backward tmm-c-prompt)) |
| 336 | 380 | ||
| 337 | |||
| 338 | (defun tmm-get-keymap (elt &optional in-x-menu) | 381 | (defun tmm-get-keymap (elt &optional in-x-menu) |
| 339 | "Prepends (DOCSTRING EVENT BINDING) to free variable `tmm-km-list'. | 382 | "Prepends (DOCSTRING EVENT BINDING) to free variable `tmm-km-list'. |
| 340 | The values are deduced from the argument ELT, that should be an | 383 | The values are deduced from the argument ELT, that should be an |
| @@ -389,7 +432,6 @@ It uses the free variable `tmm-table-undef' to keep undefined keys." | |||
| 389 | (cons (cons str (cons event km)) tmm-km-list))) | 432 | (cons (cons str (cons event km)) tmm-km-list))) |
| 390 | )))) | 433 | )))) |
| 391 | 434 | ||
| 392 | |||
| 393 | (defun tmm-get-keybind (keyseq) | 435 | (defun tmm-get-keybind (keyseq) |
| 394 | "Return the current binding of KEYSEQ, merging prefix definitions. | 436 | "Return the current binding of KEYSEQ, merging prefix definitions. |
| 395 | If KEYSEQ is a prefix key that has local and global bindings, | 437 | If KEYSEQ is a prefix key that has local and global bindings, |