Mercurial > emacs
annotate lisp/emulation/viper-macs.el @ 47576:b31c8ab7336a
Sync with version 2.0.20. Lengthy ChangeLog follows:
2002-09-22 Kai Gro?ohann <grossjoh@ls6.informatik.uni-dortmund.de>
Version 2.0.20 released.
2002-09-20 Kai Gro?ohann <grossjoh@ls6.informatik.uni-dortmund.de>
* net/tramp.el (tramp-completion-function-alist): Escape open
paren in docstring.
(tramp-user-regexp, tramp-host-regexp): Allow empty strings.
(tramp-handle-insert-file-contents): Call tramp-message-for-buffer
instead of tramp-message.
(tramp-open-connection-rsh): Handle empty string as user name.
(tramp-open-connection-su): Handle empty string as host name.
Handle nil user name.
(tramp-handle-file-local-copy, tramp-handle-write-region)
(tramp-completion-handle-file-name-all-completions)
(tramp-open-connection-telnet, tramp-open-connection-rsh)
(tramp-open-connection-su, tramp-post-connection)
(tramp-maybe-open-connection, tramp-method-out-of-band-p)
(tramp-get-connection-function, tramp-get-remote-sh)
(tramp-get-rsh-program, tramp-get-rsh-args)
(tramp-get-rcp-program, tramp-get-rcp-args)
(tramp-get-rcp-keep-date-arg, tramp-get-su-program)
(tramp-get-su-args, tramp-get-telnet-program)
(tramp-get-telnet-args): Use `tramp-find-method', perhaps require
additional args USER, HOST.
(tramp-action-password, tramp-open-connection-telnet)
(tramp-open-connection-su, tramp-open-connection-multi)
(tramp-method-out-of-band-p): `tramp-method-out-of-band-p' now
takes USER and HOST arguments, to be able to use
`tramp-find-method'. Update callers.
(tramp-find-method): New function.
2002-09-20 Kai Gro?ohann <Kai.Grossjohann@CS.Uni-Dortmund.DE>
* net/tramp.el (tramp-handle-insert-directory): Handle "--dired"
in SWITCHES (by removing it).
2002-09-18 Kai Gro?ohann <Kai.Grossjohann@CS.Uni-Dortmund.DE>
* net/tramp.el (tramp-file-name-handler): Add `file-remote-p'
property.
2002-09-17 Kai Gro?ohann <Kai.Grossjohann@CS.Uni-Dortmund.DE>
* net/tramp.el (top-level): Maybe autoload uudecode-decode-region.
2002-09-16 Kai Gro?ohann <Kai.Grossjohann@CS.Uni-Dortmund.DE>
* net/tramp.el (tramp-bug): Add tramp-methods.
2002-09-16 Kai Gro?ohann <Kai.Grossjohann@CS.Uni-Dortmund.DE>
* net/tramp.el (tramp-methods): Update docstring:
tramp-encoding-command, tramp-decoding-command,
tramp-encoding-function and tramp-decoding-function are not
parameters anymore.
(tramp-uuencode-region): Autoload it.
2002-09-13 Kai Gro?ohann <Kai.Grossjohann@CS.Uni-Dortmund.DE>
Version 2.0.19 released.
* net/tramp-uu.el: New file, implements uuencode in Lisp.
* net/tramp.el (tramp-coding-commands): Use
`tramp-uuencode-region' as local encoder for the uuencode based
entries.
2002-09-13 Kai Gro?ohann <Kai.Grossjohann@CS.Uni-Dortmund.DE>
* net/tramp.el (tramp-handle-write-region): Wrong parens.
2002-09-13 Kai Gro?ohann <Kai.Grossjohann@CS.Uni-Dortmund.DE>
Version 2.0.18 released.
* net/tramp.el (tramp-perl-decode): Perl changes to accomodate
older versions of Perl. Now tested with 5.004. Suggestion from
Michael Albinus.
2002-09-12 Kai Gro?ohann <Kai.Grossjohann@CS.Uni-Dortmund.DE>
* net/tramp.el (tramp-find-inline-encoding): Call
tramp-call-local-coding-command with nil for INPUT and OUTPUT.
(tramp-call-local-coding-command): OUTPUT equals nil means to
discard the output. INPUT equals nil means /dev/null.
2002-09-12 Kai Gro?ohann <Kai.Grossjohann@CS.Uni-Dortmund.DE>
* net/tramp.el (tramp-encoding-shell): Default to environment
variable COMSPEC on Windows.
(tramp-handle-write-region): More debugging output.
(tramp-find-inline-encoding): Ditto.
2002-09-11 Michael Albinus <Michael.Albinus@alcatel.de>
* net/tramp.el (tramp-completion-handle-file-name-all-completions):
Define `result1'.
(tramp-parse-hosts-group): Discard IPv6 entries.
2002-09-11 Kai Gro?ohann <grossjoh@ls6.informatik.uni-dortmund.de>
* net/tramp.el (tramp-post-connection): Only send Perl
mime-encode/decode implementations when using inline method.
(tramp-handle-file-local-copy)
(tramp-handle-write-region, tramp-post-connection)
(tramp-coding-commands, tramp-find-inline-encoding): For the
inline encodings, distinguish between local and remote commands,
instead of between commands and functions. (The local commands
can be functions, too.) If the local host is a Windows machine,
we can't expect the same commands to work there as on the remote
host.
(tramp-call-local-coding-command): New function for calling local
encoding and decoding commands.
(tramp-set-remote-encoding, tramp-get-remote-encoding)
(tramp-set-remote-decoding, tramp-get-remote-decoding)
(tramp-set-local-encoding, tramp-get-local-encoding)
(tramp-set-local-decoding, tramp-get-local-decoding): New
functions.
(tramp-get-encoding-command, tramp-set-encoding-command)
(tramp-get-decoding-command, tramp-set-decoding-command)
(tramp-get-encoding-function, tramp-set-encoding-function)
(tramp-get-decoding-function, tramp-set-decoding-function): Old
functions, removed.
2002-09-10 Kai Gro?ohann <Kai.Grossjohann@CS.Uni-Dortmund.DE>
* net/tramp.el (tramp-open-connection-setup-interactive-shell):
Change command to invoke /bin/sh slightly to make it compatible
with the `rc' shell. Suggested by Daniel Pittman.
2002-09-10 Michael Albinus <Michael.Albinus@alcatel.de>
* net/tramp.el (tramp-handle-write-region): Added missing
`)'. Hope it's the right place.
2002-09-09 Kai Gro?ohann <Kai.Grossjohann@CS.Uni-Dortmund.DE>
* net/tramp.el (tramp-open-connection-setup-interactive-shell): Do
"exec env PS1='$ ' /bin/sh" instead of just "exec /bin/sh" in
order to get a sane shell prompt. If people have ${CWD}, say, in
their shell prompt, then the default login shell might display
something harmless, but the /bin/sh will display a dollar sign
which confused the subsequent prompt recognition.
(tramp-multi-action-password): More debugging output.
(tramp-encoding-shell): Renamed from tramp-sh-program. More
documentation. Default to cmd.exe on Windows NT.
(tramp-encoding-command-switch): New variable. Use instead of
hard-wired "-c" which is only good for /bin/sh.
(tramp-encoding-reads-stdin): New variable. If t, commands are
called like "/bin/sh -c COMMAND <INPUT", if nil, they are called
like "/bin/sh -c COMMAND INPUT", ie the input file is the last
argument.
(tramp-multi-sh-program): Always default to tramp-encoding-shell.
(tramp-handle-file-local-copy, tramp-handle-write-region): Respect
tramp-encoding-shell and friends.
(tramp-find-inline-encoding): Use new-style calls for checking if
the local commands work.
2002-09-07 Michael Albinus <Michael.Albinus@alcatel.de>
* net/tramp.el (tramp-methods): Remove `tramp-completion-function'
entries. They are handled now by
`tramp-completion-function-alist'.
(tramp-completion-function): Defvar removed. I've never used
it. Hmm.
(tramp-get-completion-function)
(tramp-get-completion-rsh, tramp-get-completion-ssh)
(tramp-get-completion-telnet, tramp-get-completion-su): Functions
removed as well. Not necessary any longer due to extended
customization means.
(tramp-completion-function-alist): New defcustom. Holds all
FUNCTION FILE pairs used for user and host name completion
relevant for METHOD.
(tramp-completion-function-alist-rsh)
(tramp-completion-function-alist-ssh)
(tramp-completion-function-alist-telnet)
(tramp-completion-function-alist-su): Defconst for initializing
`tramp-completion-function-alist'. Unfortunately, mainly UNIX-like
values are known for me until now. Needs to be completed for at
least VMS++ like operating systems.
(tramp-set-completion-function)
(tramp-get-completion-function): New functions for configuration
of `tramp-completion-function-alist'. The old definition of
`tramp-get-completion-function' has been discarded.
(tramp-completion-handle-file-name-all-completions): Change
function call for user/host completion according to definition in
`tramp-completion-function-alist'.
(tramp-parse-passwd): Added exception handling for "root", because
`tramp-get-completion-su' (the previous place for this stuff)
doesn't exist any longer.
2002-09-07 Kai Gro?ohann <Kai.Grossjohann@CS.Uni-Dortmund.DE>
* net/tramp.el (tramp-enter-password): Use
`tramp-password-end-of-line' to terminate the line.
(tramp-bug): Include new variable `tramp-password-end-of-line'.
(tramp-password-end-of-line): New variable. People who use plink
under Windows might have to issue "\r\n" after the password, but
they need to send just "\n" after the other commands. So this
variable was introduced to complement `tramp-rsh-end-of-line'.
(tramp-wait-for-output, tramp-post-connection): Allow "\r" at end
of line of the output delimiter.
2002-09-06 Kai Gro?ohann <Kai.Grossjohann@CS.Uni-Dortmund.DE>
* net/tramp.el (tramp-handle-file-local-copy, tramp-find-shell)
(tramp-open-connection-setup-interactive-shell): Add some comments
about Douglas Grey Stephen's suggestions to make Tramp work better
with plink under Windows. I'm not sure what to think of them, but
now I have a guinea pig to try it out on. Said guinea pig is
having other problems, though... Also remove some commented-out
code.
2002-09-06 Michael Albinus <Michael.Albinus@alcatel.de>
* net/tramp.el (tramp-get-completion-methods): Algorithm slightly
tuned.
(tramp-get-completion-user-host): Accept user names as they are if
typed until "@".
(tramp-completion-mode): Replace `last-input-char' by modern
`last-input-event'. Check for `event-modifiers'.
2002-09-06 Kai Gro?ohann <Kai.Grossjohann@CS.Uni-Dortmund.DE>
* net/tramp.el (file-expand-wildcards): Corrected check to see if
advising is necessary.
2002-09-05 Michael Albinus <Michael.Albinus@alcatel.de>
* net/tramp.el (tramp-postfix-single-method-format)
(tramp-postfix-multi-method-format)
(tramp-postfix-multi-hop-format)
(tramp-postfix-user-format): New format strings.
(tramp-postfix-single-method-regexp)
(tramp-postfix-multi-method-regexp)
(tramp-postfix-multi-hop-regexp)
(tramp-postfix-user-regexp)
(tramp-make-multi-tramp-file-format)
(tramp-make-tramp-file-name): Apply them.
(tramp-completion-handle-file-name-all-completions): Fix for
invoking ange-ftp in case of "/ftp:xxx" file names.
2002-09-04 Michael Albinus <Michael.Albinus@alcatel.de>
* net/tramp.el (tramp-prefix-format)
(tramp-postfix-host-format): New format strings.
(tramp-prefix-regexp, tramp-method-regexp)
(tramp-postfix-single-method-regexp)
(tramp-postfix-multi-method-regexp)
(tramp-postfix-multi-hop-regexp)
(tramp-user-regexp, tramp-postfix-user-regexp)
(tramp-host-regexp, tramp-postfix-host-regexp)
(tramp-path-regexp): New atomar regular expressions. If
corresponding format strings exist, derived from them.
(tramp-file-name-structure)
(tramp-multi-file-name-structure)
(tramp-multi-file-name-hop-structure)
(tramp-make-multi-tramp-file-format)
(tramp-completion-mode)
(tramp-completion-dissect-file-name)
(tramp-parse-rhosts-group)
(tramp-parse-shosts-group)
(tramp-parse-hosts-group)
(tramp-parse-passwd-group): Apply these expressions.
(tramp-file-name-structure-unified)
(tramp-file-name-structure-separate)
(tramp-make-tramp-file-format-unified)
(tramp-make-tramp-file-format-separate)
(tramp-make-tramp-file-format)
(tramp-make-tramp-file-user-nil-format-unified)
(tramp-make-tramp-file-user-nil-format-separate)
(tramp-make-tramp-file-user-nil-format)
(tramp-multi-file-name-structure-unified)
(tramp-multi-file-name-structure-separate)
(tramp-multi-file-name-hop-structure-unified)
(tramp-multi-file-name-hop-structure-separate)
(tramp-make-multi-tramp-file-format-unified)
(tramp-make-multi-tramp-file-format-separate): Removed.
(tramp-make-tramp-file-name): Allow partial tramp file
names. Generate tramp file format on-the-fly depending on
parameters. Apply atomar format strings resp expressions.
(tramp-get-completion-methods)
(tramp-get-completion-user-host): Apply
`tramp-make-tramp-file-name'.
(tramp-parse-hosts-group): Take all host names and IP addresses
into account.
(tramp-bug): Remove `tramp-make-tramp-file-format'.
2002-09-01 Michael Albinus <Michael.Albinus@alcatel.de>
* net/tramp.el (tramp-methods): Add `tramp-completion-function'
for "su" and "sudo".
(tramp-get-completion-telnet): Implement it.
(tramp-parse-hosts)
(tramp-parse-hosts-group)
(tramp-get-completion-su)
(tramp-parse-passwd)
(tramp-parse-passwd-group): New functions.
2002-08-31 Michael Albinus <Michael.Albinus@alcatel.de>
* net/tramp.el (tramp-completion-mode): Check for
`last-input-char'.
(tramp-completion-file-name-handler-alist): Add handler for
`file-exists-p.
(tramp-completion-handle-file-exists-p): New function.
(tramp-completion-handle-file-name-completion): Simplified.
(tramp-completion-dissect-file-name): Regexp's reorganised.
(tramp-completion-handle-file-name-all-completions): Call
completion-function only if `user' or `host' is given.
(tramp-get-completion-user-host): New function.
(tramp-get-completion-rsh)
(tramp-get-completion-ssh): Apply it.
2002-08-29 Michael Albinus <Michael.Albinus@alcatel.de>
* net/tramp.el (tramp-completion-file-name-handler-alist): Add
handler for `expand-file-name'.
(tramp-completion-handle-expand-file-name): New function.
2002-08-26 Michael Albinus <Michael.Albinus@alcatel.de>
* net/tramp.el (tramp-completion-mode): New function.
(tramp-completion-handle-file-name-directory)
(tramp-completion-handle-file-name-all-completions): Apply it.
(tramp-methods): Remove double definition of `ssh1-old' and
`ssh2-old'.
(tramp-point-at-eol): New defalias.
(tramp-parse-rhosts-group)
(tramp-parse-shosts-group):: Apply it.
2002-08-25 Michael Albinus <Michael.Albinus@alcatel.de>
* net/tramp.el (tramp-get-completion-methods)
(tramp-get-completion-rsh)
(tramp-get-completion-ssh): Add "[" for Xemacs.
(tramp-completion-file-name-regexp-separate): Expression adapted.
(tramp-completion-file-name-handler-alist): Add handler for
`file-name-directory' and `file-name-nondirectory'.
(tramp-completion-handle-file-name-directory)
(tramp-completion-handle-file-name-nondirectory)
(tramp-completion-run-real-handler): New functions.
(tramp-completion-file-name-handler)
(tramp-completion-handle-file-name-all-completions): Apply
`tramp-completion-run-real-handler'.
(tramp-parse-rhosts)
(tramp-parse-shosts): Use `with-temp-buffer'. `result? renamed to
`res' (otherwise side effects in XEmacs).
2002-08-24 Michael Albinus <Michael.Albinus@alcatel.de>
* net/tramp.el (tramp-completion-file-name-regexp)
(tramp-completion-file-name-handler-alist)
(tramp-flatten-list)
(tramp-completion-dissect-file-name)
(tramp-get-completion-rsh)
(tramp-parse-rhosts)
(tramp-parse-rhosts-group)
(tramp-get-completion-ssh): Doc string tuned.
(tramp-methods): Doc string and custom type extended for
`tramp-completion-function'.
(tramp-completion-function): Variable added. Is it really used?
Other variables like `tramp-completion-function' aren't used.
(tramp-completion-file-name-handler-alist): Add handler for
`file-name-completion'.
(tramp-completion-handle-file-name-completion): New function.
2002-08-18 Michael Albinus <Michael.Albinus@alcatel.de>
* net/tramp.el (tramp-parse-rhosts)
(tramp-parse-rhosts-group)
(tramp-parse-shosts)
(tramp-parse-shosts-group): New functions.
2002-08-17 Michael Albinus <Michael.Albinus@alcatel.de>
* net/tramp.el (tramp-completion-dissect-file-name)
(tramp-completion-dissect-file-name1): New functions.
2002-08-16 Michael Albinus <Michael.Albinus@alcatel.de>
* net/tramp.el (tramp-get-completion-function)
(tramp-get-completion-rsh)
(tramp-get-completion-ssh)
(tramp-get-completion-telnet): New functions.
(tramp-methods): Add `tramp-completion-function' for all methods.
2002-08-15 Michael Albinus <Michael.Albinus@alcatel.de>
* net/tramp.el (tramp-get-completion-methods): New function.
(tramp-find-default-method): Allow host to be nil (like user).
2002-08-14 Michael Albinus <Michael.Albinus@alcatel.de>
* net/tramp.el (tramp-completion-file-name-regexp-unified)
(tramp-completion-file-name-regexp-separate)
(tramp-completion-file-name-regexp)
(tramp-completion-file-name-handler-alist): New defcustoms.
(tramp-completion-file-name-handler): New function. Add
`tramp-completion-file-name-handler' to `file-name-handler-alist'.
(tramp-run-real-handler): Add `tramp-completion-file-name-handler'
to `inhibit-file-name-handlers'.
(tramp-completion-handle-file-name-all-completions)
(tramp-completion-handle-file-name-completion): New functions.
2002-08-12 Michael Albinus <Michael.Albinus@alcatel.de>
* net/tramp.el (tramp-invoke-ange-ftp): `tramp-disable-ange-ftp'
must be called again after activating `ange-ftp'.
(tramp-ange-ftp-file-name-p): Check for Xemacs.
2002-08-08 Michael Albinus <Michael.Albinus@alcatel.de>
* net/tramp.el (tramp-do-copy-or-rename-file): Don't pass
KEEP-DATE to tramp-invoke-ange-ftp 'rename.
(tramp-handle-write-region): Don't pass LOCKNAME and CONFIRM to
tramp-invoke-ange-ftp 'write-region.
(tramp-handle-set-file-modes): Change order of FILENAME and MODE
passing to tramp-invoke-ange-ftp 'set-file-modes.
(tramp-flatten-list): New function. Maybe this functionality does
exist already elsewhere in the libraries.
(tramp-invoke-ange-ftp): Apply `tramp-flatten-list' to parameter
list in order to avoid nested lists, f.e. when invoked from
`tramp-handle-dired-call-process'.
2002-09-05 Kai Gro?ohann <Kai.Grossjohann@CS.Uni-Dortmund.DE>
* net/tramp.el (tramp-chunksize): New kluge variable.
(tramp-send-region): If tramp-chunksize is non-nil, send region in
parts and sleep 0.1 seconds between chunks.
2002-09-03 Kai Gro?ohann <Kai.Grossjohann@CS.Uni-Dortmund.DE>
* net/tramp.el (tramp-handle-insert-directory): Use
`insert-buffer-substring' instead of `insert-buffer', which is not
supposed to be used from Lisp. Remember old point in a variable
instead of using `mark'. Suggestion from Stefan Monnier.
(tramp-unified-filenames): New variable. Use it in default value
of other filename variables.
(file-expand-wildcards): Don't advise unless "[" and "]" are used
in the filename format.
2002-09-01 Kai Gro?ohann <Kai.Grossjohann@CS.Uni-Dortmund.DE>
* net/tramp.el (tramp-methods): Remove duplicate definition of
ssh1-old and ssh2-old.
author | Kai Großjohann <kgrossjo@eu.uu.net> |
---|---|
date | Sun, 22 Sep 2002 13:23:36 +0000 |
parents | 633233bf2bbf |
children | 0d8b17d428b5 |
rev | line source |
---|---|
13337 | 1 ;;; viper-macs.el --- functions implementing keyboard macros for Viper |
2 | |
42602
633233bf2bbf
2002-01-07 Michael Kifer <kifer@cs.stonybrook.edu>
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
39215
diff
changeset
|
3 ;; Copyright (C) 1994, 95, 96, 97, 2000, 01, 02 Free Software Foundation, Inc. |
11288 | 4 |
42602
633233bf2bbf
2002-01-07 Michael Kifer <kifer@cs.stonybrook.edu>
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
39215
diff
changeset
|
5 ;; Author: Michael Kifer <kifer@cs.stonybrook.edu> |
39215
8dccf2552307
2001-09-09 Michael Kifer <kifer@cs.sunysb.edu>
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
38414
diff
changeset
|
6 |
10789 | 7 ;; This file is part of GNU Emacs. |
8 | |
9 ;; GNU Emacs is free software; you can redistribute it and/or modify | |
10 ;; it under the terms of the GNU General Public License as published by | |
11 ;; the Free Software Foundation; either version 2, or (at your option) | |
12 ;; any later version. | |
13 | |
14 ;; GNU Emacs is distributed in the hope that it will be useful, | |
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 ;; GNU General Public License for more details. | |
18 | |
19 ;; You should have received a copy of the GNU General Public License | |
14169 | 20 ;; along with GNU Emacs; see the file COPYING. If not, write to the |
21 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
22 ;; Boston, MA 02111-1307, USA. | |
10789 | 23 |
38414
67b464da13ec
Some fixes to follow coding conventions.
Pavel Janík <Pavel@Janik.cz>
parents:
26263
diff
changeset
|
24 ;;; Commentary: |
67b464da13ec
Some fixes to follow coding conventions.
Pavel Janík <Pavel@Janik.cz>
parents:
26263
diff
changeset
|
25 |
67b464da13ec
Some fixes to follow coding conventions.
Pavel Janík <Pavel@Janik.cz>
parents:
26263
diff
changeset
|
26 ;;; Code: |
14909
7ff1df13b124
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
14587
diff
changeset
|
27 |
18047 | 28 (provide 'viper-macs) |
29 | |
30 ;; compiler pacifier | |
19079 | 31 (defvar viper-ex-work-buf) |
32 (defvar viper-custom-file-name) | |
33 (defvar viper-current-state) | |
34 (defvar viper-fast-keyseq-timeout) | |
18047 | 35 |
18172 | 36 ;; loading happens only in non-interactive compilation |
37 ;; in order to spare non-viperized emacs from being viperized | |
38 (if noninteractive | |
39 (eval-when-compile | |
40 (let ((load-path (cons (expand-file-name ".") load-path))) | |
41 (or (featurep 'viper-util) | |
42 (load "viper-util.el" nil nil 'nosuffix)) | |
43 (or (featurep 'viper-keym) | |
44 (load "viper-keym.el" nil nil 'nosuffix)) | |
45 (or (featurep 'viper-mous) | |
46 (load "viper-mous.el" nil nil 'nosuffix)) | |
47 (or (featurep 'viper-cmd) | |
48 (load "viper-cmd.el" nil nil 'nosuffix)) | |
49 ))) | |
18047 | 50 ;; end pacifier |
51 | |
10789 | 52 (require 'viper-util) |
14909
7ff1df13b124
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
14587
diff
changeset
|
53 (require 'viper-keym) |
7ff1df13b124
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
14587
diff
changeset
|
54 |
10789 | 55 |
56 ;;; Variables | |
57 | |
58 ;; Register holding last macro. | |
19079 | 59 (defvar viper-last-macro-reg nil) |
10789 | 60 |
61 ;; format of the elements of kbd alists: | |
62 ;; (name ((buf . macr)...(buf . macr)) ((maj-mode . macr)...) (t . macr)) | |
63 ;; kbd macro alist for Vi state | |
19079 | 64 (defvar viper-vi-kbd-macro-alist nil) |
10789 | 65 ;; same for insert/replace state |
19079 | 66 (defvar viper-insert-kbd-macro-alist nil) |
10789 | 67 ;; same for emacs state |
19079 | 68 (defvar viper-emacs-kbd-macro-alist nil) |
10789 | 69 |
70 ;; Internal var that passes info between start-kbd-macro and end-kbd-macro | |
71 ;; in :map and :map! | |
19079 | 72 (defvar viper-kbd-macro-parameters nil) |
10789 | 73 |
19079 | 74 (defvar viper-this-kbd-macro nil |
10789 | 75 "Vector of keys representing the name of currently running Viper kbd macro.") |
19079 | 76 (defvar viper-last-kbd-macro nil |
10789 | 77 "Vector of keys representing the name of last Viper keyboard macro.") |
78 | |
19079 | 79 (defcustom viper-repeat-from-history-key 'f12 |
18839 | 80 "Prefix key for accessing previously typed Vi commands. |
10789 | 81 |
26263
4f315ca65976
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
19907
diff
changeset
|
82 The previous command is accessible, as usual, via `.'. The command before this |
18839 | 83 can be invoked as `<this key> 1', and the command before that, and the command |
84 before that one is accessible as `<this key> 2'. | |
26263
4f315ca65976
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
19907
diff
changeset
|
85 The notation for these keys is borrowed from XEmacs. Basically, |
10789 | 86 a key is a symbol, e.g., `a', `\\1', `f2', etc., or a list, e.g., |
18839 | 87 `(meta control f1)'." |
19907
819a01a83872
(viper-repeat-from-history-key): Fix customize type.
Richard M. Stallman <rms@gnu.org>
parents:
19079
diff
changeset
|
88 :type 'sexp |
18839 | 89 :group 'viper) |
10789 | 90 |
91 | |
92 | |
93 ;;; Code | |
94 | |
12140
75379a19c5d5
Changed vip-*-frame-* to *-frame-*, incorporated overlay strings,
Karl Heuer <kwzh@gnu.org>
parents:
11288
diff
changeset
|
95 ;; Ex map command |
10789 | 96 (defun ex-map () |
97 (let ((mod-char "") | |
98 macro-name macro-body map-args ins) | |
99 (save-window-excursion | |
19079 | 100 (set-buffer viper-ex-work-buf) |
10789 | 101 (if (looking-at "!") |
102 (progn | |
103 (setq ins t | |
104 mod-char "!") | |
105 (forward-char 1)))) | |
106 (setq map-args (ex-map-read-args mod-char) | |
107 macro-name (car map-args) | |
108 macro-body (cdr map-args)) | |
19079 | 109 (setq viper-kbd-macro-parameters (list ins mod-char macro-name macro-body)) |
10789 | 110 (if macro-body |
19079 | 111 (viper-end-mapping-kbd-macro 'ignore) |
10789 | 112 (ex-fixup-history (format "map%s %S" mod-char |
19079 | 113 (viper-display-macro macro-name))) |
10789 | 114 ;; if defining macro for insert, switch there for authentic WYSIWYG |
19079 | 115 (if ins (viper-change-state-to-insert)) |
10789 | 116 (start-kbd-macro nil) |
19079 | 117 (define-key viper-vi-intercept-map "\C-x)" 'viper-end-mapping-kbd-macro) |
118 (define-key viper-insert-intercept-map "\C-x)" 'viper-end-mapping-kbd-macro) | |
119 (define-key viper-emacs-intercept-map "\C-x)" 'viper-end-mapping-kbd-macro) | |
26263
4f315ca65976
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
19907
diff
changeset
|
120 (message "Mapping %S in %s state. Hit `C-x )' to complete the mapping" |
19079 | 121 (viper-display-macro macro-name) |
10789 | 122 (if ins "Insert" "Vi"))) |
123 )) | |
124 | |
125 | |
12140
75379a19c5d5
Changed vip-*-frame-* to *-frame-*, incorporated overlay strings,
Karl Heuer <kwzh@gnu.org>
parents:
11288
diff
changeset
|
126 ;; Ex unmap |
10789 | 127 (defun ex-unmap () |
128 (let ((mod-char "") | |
129 temp macro-name ins) | |
130 (save-window-excursion | |
19079 | 131 (set-buffer viper-ex-work-buf) |
10789 | 132 (if (looking-at "!") |
133 (progn | |
134 (setq ins t | |
135 mod-char "!") | |
136 (forward-char 1)))) | |
137 | |
138 (setq macro-name (ex-unmap-read-args mod-char)) | |
19079 | 139 (setq temp (viper-fixup-macro (vconcat macro-name))) ;; copy and fixup |
10789 | 140 (ex-fixup-history (format "unmap%s %S" mod-char |
19079 | 141 (viper-display-macro temp))) |
142 (viper-unrecord-kbd-macro macro-name (if ins 'insert-state 'vi-state)) | |
10789 | 143 )) |
144 | |
145 | |
146 ;; read arguments for ex-map | |
147 (defun ex-map-read-args (variant) | |
148 (let ((cursor-in-echo-area t) | |
149 (key-seq []) | |
150 temp key event message | |
151 macro-name macro-body args) | |
152 | |
153 (condition-case nil | |
154 (setq args (concat (ex-get-inline-cmd-args ".*map[!]*[ \t]?" "\n\C-m") | |
155 " nil nil ") | |
156 temp (read-from-string args) | |
157 macro-name (car temp) | |
158 macro-body (car (read-from-string args (cdr temp)))) | |
159 (error | |
160 (signal | |
161 'error | |
162 '("map: Macro name and body must be a quoted string or a vector")))) | |
163 | |
164 ;; We expect macro-name to be a vector, a string, or a quoted string. | |
165 ;; In the second case, it will emerge as a symbol when read from | |
26263
4f315ca65976
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
19907
diff
changeset
|
166 ;; the above read-from-string. So we need to convert it into a string |
10789 | 167 (if macro-name |
168 (cond ((vectorp macro-name) nil) | |
169 ((stringp macro-name) | |
170 (setq macro-name (vconcat macro-name))) | |
171 (t (setq macro-name (vconcat (prin1-to-string macro-name))))) | |
172 (message ":map%s <Name>" variant)(sit-for 2) | |
173 (while | |
174 (not (member key | |
175 '(?\C-m ?\n (control m) (control j) return linefeed))) | |
176 (setq key-seq (vconcat key-seq (if key (vector key) []))) | |
177 ;; the only keys available for editing are these-- no help while there | |
178 (if (member | |
179 key | |
180 '(?\b ?\d '^? '^H (control h) (control \?) backspace delete)) | |
181 (setq key-seq (subseq key-seq 0 (- (length key-seq) 2)))) | |
182 (setq message | |
14585
b6228a159e75
(ex-map-read-args,ex-unmap-read-args): fixed messages.
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
14581
diff
changeset
|
183 (format |
b6228a159e75
(ex-map-read-args,ex-unmap-read-args): fixed messages.
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
14581
diff
changeset
|
184 ":map%s %s" |
b6228a159e75
(ex-map-read-args,ex-unmap-read-args): fixed messages.
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
14581
diff
changeset
|
185 variant (if (> (length key-seq) 0) |
19079 | 186 (prin1-to-string (viper-display-macro key-seq)) |
14585
b6228a159e75
(ex-map-read-args,ex-unmap-read-args): fixed messages.
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
14581
diff
changeset
|
187 ""))) |
14384
854325337547
Moved code around to minimize compiler warnings.
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
14335
diff
changeset
|
188 (message message) |
19079 | 189 (setq event (viper-read-key)) |
190 ;;(setq event (viper-read-event)) | |
10789 | 191 (setq key |
19079 | 192 (if (viper-mouse-event-p event) |
10789 | 193 (progn |
194 (message "%s (No mouse---only keyboard keys, please)" | |
195 message) | |
196 (sit-for 2) | |
197 nil) | |
19079 | 198 (viper-event-key event))) |
10789 | 199 ) |
200 (setq macro-name key-seq)) | |
201 | |
202 (if (= (length macro-name) 0) | |
203 (error "Can't map an empty macro name")) | |
19079 | 204 (setq macro-name (viper-fixup-macro macro-name)) |
205 (if (viper-char-array-p macro-name) | |
206 (setq macro-name (viper-char-array-to-macro macro-name))) | |
10789 | 207 |
208 (if macro-body | |
19079 | 209 (cond ((viper-char-array-p macro-body) |
210 (setq macro-body (viper-char-array-to-macro macro-body))) | |
10789 | 211 ((vectorp macro-body) nil) |
212 (t (error "map: Invalid syntax in macro definition")))) | |
12140
75379a19c5d5
Changed vip-*-frame-* to *-frame-*, incorporated overlay strings,
Karl Heuer <kwzh@gnu.org>
parents:
11288
diff
changeset
|
213 (setq cursor-in-echo-area nil)(sit-for 0) ; this overcomes xemacs tty bug |
75379a19c5d5
Changed vip-*-frame-* to *-frame-*, incorporated overlay strings,
Karl Heuer <kwzh@gnu.org>
parents:
11288
diff
changeset
|
214 (cons macro-name macro-body))) |
10789 | 215 |
216 | |
217 | |
218 ;; read arguments for ex-unmap | |
219 (defun ex-unmap-read-args (variant) | |
220 (let ((cursor-in-echo-area t) | |
221 (macro-alist (if (string= variant "!") | |
19079 | 222 viper-insert-kbd-macro-alist |
223 viper-vi-kbd-macro-alist)) | |
10789 | 224 ;; these are disabled just in case, to avoid surprises when doing |
225 ;; completing-read | |
19079 | 226 viper-vi-kbd-minor-mode viper-insert-kbd-minor-mode |
227 viper-emacs-kbd-minor-mode | |
228 viper-vi-intercept-minor-mode viper-insert-intercept-minor-mode | |
229 viper-emacs-intercept-minor-mode | |
10789 | 230 event message |
231 key key-seq macro-name) | |
232 (setq macro-name (ex-get-inline-cmd-args ".*unma?p?[!]*[ \t]*")) | |
233 | |
234 (if (> (length macro-name) 0) | |
235 () | |
236 (message ":unmap%s <Name>" variant) (sit-for 2) | |
237 (while | |
238 (not | |
239 (member key '(?\C-m ?\n (control m) (control j) return linefeed))) | |
240 (setq key-seq (vconcat key-seq (if key (vector key) []))) | |
241 ;; the only keys available for editing are these-- no help while there | |
242 (cond ((member | |
243 key | |
244 '(?\b ?\d '^? '^H (control h) (control \?) backspace delete)) | |
245 (setq key-seq (subseq key-seq 0 (- (length key-seq) 2)))) | |
246 ((member key '(tab (control i) ?\t)) | |
247 (setq key-seq (subseq key-seq 0 (1- (length key-seq)))) | |
248 (setq message | |
14585
b6228a159e75
(ex-map-read-args,ex-unmap-read-args): fixed messages.
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
14581
diff
changeset
|
249 (format |
b6228a159e75
(ex-map-read-args,ex-unmap-read-args): fixed messages.
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
14581
diff
changeset
|
250 ":unmap%s %s" |
b6228a159e75
(ex-map-read-args,ex-unmap-read-args): fixed messages.
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
14581
diff
changeset
|
251 variant (if (> (length key-seq) 0) |
b6228a159e75
(ex-map-read-args,ex-unmap-read-args): fixed messages.
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
14581
diff
changeset
|
252 (prin1-to-string |
19079 | 253 (viper-display-macro key-seq)) |
14585
b6228a159e75
(ex-map-read-args,ex-unmap-read-args): fixed messages.
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
14581
diff
changeset
|
254 ""))) |
10789 | 255 (setq key-seq |
19079 | 256 (viper-do-sequence-completion key-seq macro-alist message)) |
10789 | 257 )) |
258 (setq message | |
14585
b6228a159e75
(ex-map-read-args,ex-unmap-read-args): fixed messages.
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
14581
diff
changeset
|
259 (format |
b6228a159e75
(ex-map-read-args,ex-unmap-read-args): fixed messages.
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
14581
diff
changeset
|
260 ":unmap%s %s" |
b6228a159e75
(ex-map-read-args,ex-unmap-read-args): fixed messages.
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
14581
diff
changeset
|
261 variant (if (> (length key-seq) 0) |
b6228a159e75
(ex-map-read-args,ex-unmap-read-args): fixed messages.
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
14581
diff
changeset
|
262 (prin1-to-string |
19079 | 263 (viper-display-macro key-seq)) |
14585
b6228a159e75
(ex-map-read-args,ex-unmap-read-args): fixed messages.
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
14581
diff
changeset
|
264 ""))) |
14384
854325337547
Moved code around to minimize compiler warnings.
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
14335
diff
changeset
|
265 (message message) |
19079 | 266 (setq event (viper-read-key)) |
267 ;;(setq event (viper-read-event)) | |
10789 | 268 (setq key |
19079 | 269 (if (viper-mouse-event-p event) |
10789 | 270 (progn |
271 (message "%s (No mouse---only keyboard keys, please)" | |
272 message) | |
273 (sit-for 2) | |
274 nil) | |
19079 | 275 (viper-event-key event))) |
10789 | 276 ) |
277 (setq macro-name key-seq)) | |
278 | |
279 (if (= (length macro-name) 0) | |
280 (error "Can't unmap an empty macro name")) | |
281 | |
282 ;; convert macro names into vector, if starts with a `[' | |
283 (if (memq (elt macro-name 0) '(?\[ ?\")) | |
284 (car (read-from-string macro-name)) | |
285 (vconcat macro-name)) | |
286 )) | |
287 | |
288 | |
14585
b6228a159e75
(ex-map-read-args,ex-unmap-read-args): fixed messages.
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
14581
diff
changeset
|
289 ;; Terminate a Vi kbd macro. |
b6228a159e75
(ex-map-read-args,ex-unmap-read-args): fixed messages.
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
14581
diff
changeset
|
290 ;; optional argument IGNORE, if t, indicates that we are dealing with an |
b6228a159e75
(ex-map-read-args,ex-unmap-read-args): fixed messages.
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
14581
diff
changeset
|
291 ;; existing macro that needs to be registered, but there is no need to |
b6228a159e75
(ex-map-read-args,ex-unmap-read-args): fixed messages.
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
14581
diff
changeset
|
292 ;; terminate a kbd macro. |
19079 | 293 (defun viper-end-mapping-kbd-macro (&optional ignore) |
10789 | 294 (interactive) |
19079 | 295 (define-key viper-vi-intercept-map "\C-x)" nil) |
296 (define-key viper-insert-intercept-map "\C-x)" nil) | |
297 (define-key viper-emacs-intercept-map "\C-x)" nil) | |
10789 | 298 (if (and (not ignore) |
19079 | 299 (or (not viper-kbd-macro-parameters) |
10789 | 300 (not defining-kbd-macro))) |
301 (error "Not mapping a kbd-macro")) | |
19079 | 302 (let ((mod-char (nth 1 viper-kbd-macro-parameters)) |
303 (ins (nth 0 viper-kbd-macro-parameters)) | |
304 (macro-name (nth 2 viper-kbd-macro-parameters)) | |
305 (macro-body (nth 3 viper-kbd-macro-parameters))) | |
306 (setq viper-kbd-macro-parameters nil) | |
10789 | 307 (or ignore |
308 (progn | |
309 (end-kbd-macro nil) | |
19079 | 310 (setq macro-body (viper-events-to-macro last-kbd-macro)) |
10789 | 311 ;; always go back to Vi, since this is where we started |
312 ;; defining macro | |
19079 | 313 (viper-change-state-to-vi))) |
10789 | 314 |
19079 | 315 (viper-record-kbd-macro macro-name |
10789 | 316 (if ins 'insert-state 'vi-state) |
19079 | 317 (viper-display-macro macro-body)) |
10789 | 318 |
319 (ex-fixup-history (format "map%s %S %S" mod-char | |
19079 | 320 (viper-display-macro macro-name) |
321 (viper-display-macro macro-body))) | |
10789 | 322 )) |
323 | |
324 | |
325 | |
326 | |
327 ;;; Recording, unrecording, executing | |
328 | |
26263
4f315ca65976
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
19907
diff
changeset
|
329 ;; Accepts as macro names: strings and vectors. |
10789 | 330 ;; strings must be strings of characters; vectors must be vectors of keys |
26263
4f315ca65976
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
19907
diff
changeset
|
331 ;; in canonic form. The canonic form is essentially the form used in XEmacs |
19079 | 332 (defun viper-record-kbd-macro (macro-name state macro-body &optional scope) |
26263
4f315ca65976
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
19907
diff
changeset
|
333 "Record a Vi macro. Can be used in `.viper' file to define permanent macros. |
4f315ca65976
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
19907
diff
changeset
|
334 MACRO-NAME is a string of characters or a vector of keys. STATE is |
4f315ca65976
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
19907
diff
changeset
|
335 either `vi-state' or `insert-state'. It specifies the Viper state in which to |
4f315ca65976
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
19907
diff
changeset
|
336 define the macro. MACRO-BODY is a string that represents the keyboard macro. |
10789 | 337 Optional SCOPE says whether the macro should be global \(t\), mode-specific |
338 \(a major-mode symbol\), or buffer-specific \(buffer name, a string\). | |
339 If SCOPE is nil, the user is asked to specify the scope." | |
340 (let* (state-name keymap | |
341 (macro-alist-var | |
342 (cond ((eq state 'vi-state) | |
343 (setq state-name "Vi state" | |
19079 | 344 keymap viper-vi-kbd-map) |
345 'viper-vi-kbd-macro-alist) | |
10789 | 346 ((memq state '(insert-state replace-state)) |
347 (setq state-name "Insert state" | |
19079 | 348 keymap viper-insert-kbd-map) |
349 'viper-insert-kbd-macro-alist) | |
10789 | 350 (t |
351 (setq state-name "Emacs state" | |
19079 | 352 keymap viper-emacs-kbd-map) |
353 'viper-emacs-kbd-macro-alist) | |
10789 | 354 )) |
355 new-elt old-elt old-sub-elt msg | |
356 temp lis lis2) | |
357 | |
358 (if (= (length macro-name) 0) | |
359 (error "Can't map an empty macro name")) | |
360 | |
26263
4f315ca65976
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
19907
diff
changeset
|
361 ;; Macro-name is usually a vector. However, command history or macros |
4f315ca65976
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
19907
diff
changeset
|
362 ;; recorded in ~/.viper may be recorded as strings. So, convert to |
4f315ca65976
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
19907
diff
changeset
|
363 ;; vectors. |
19079 | 364 (setq macro-name (viper-fixup-macro macro-name)) |
365 (if (viper-char-array-p macro-name) | |
366 (setq macro-name (viper-char-array-to-macro macro-name))) | |
367 (setq macro-body (viper-fixup-macro macro-body)) | |
368 (if (viper-char-array-p macro-body) | |
369 (setq macro-body (viper-char-array-to-macro macro-body))) | |
10789 | 370 |
371 ;; don't ask if scope is given and is of the right type | |
372 (or (eq scope t) | |
373 (stringp scope) | |
374 (and scope (symbolp scope)) | |
375 (progn | |
376 (setq scope | |
377 (cond | |
378 ((y-or-n-p | |
379 (format | |
380 "Map this macro for buffer `%s' only? " | |
381 (buffer-name))) | |
382 (setq msg | |
383 (format | |
384 "%S is mapped to %s for %s in `%s'" | |
19079 | 385 (viper-display-macro macro-name) |
386 (viper-abbreviate-string | |
10789 | 387 (format |
388 "%S" | |
19079 | 389 (setq temp (viper-display-macro macro-body))) |
10789 | 390 14 "" "" |
391 (if (stringp temp) " ....\"" " ....]")) | |
392 state-name (buffer-name))) | |
393 (buffer-name)) | |
394 ((y-or-n-p | |
395 (format | |
396 "Map this macro for the major mode `%S' only? " | |
397 major-mode)) | |
398 (setq msg | |
399 (format | |
400 "%S is mapped to %s for %s in `%S'" | |
19079 | 401 (viper-display-macro macro-name) |
402 (viper-abbreviate-string | |
10789 | 403 (format |
404 "%S" | |
19079 | 405 (setq temp (viper-display-macro macro-body))) |
10789 | 406 14 "" "" |
407 (if (stringp macro-body) " ....\"" " ....]")) | |
408 state-name major-mode)) | |
409 major-mode) | |
410 (t | |
411 (setq msg | |
412 (format | |
413 "%S is globally mapped to %s in %s" | |
19079 | 414 (viper-display-macro macro-name) |
415 (viper-abbreviate-string | |
10789 | 416 (format |
417 "%S" | |
19079 | 418 (setq temp (viper-display-macro macro-body))) |
10789 | 419 14 "" "" |
420 (if (stringp macro-body) " ....\"" " ....]")) | |
421 state-name)) | |
422 t))) | |
14580
1883960762e0
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
14433
diff
changeset
|
423 (if (y-or-n-p |
1883960762e0
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
14433
diff
changeset
|
424 (format "Save this macro in %s? " |
19079 | 425 (viper-abbreviate-file-name viper-custom-file-name))) |
426 (viper-save-string-in-file | |
427 (format "\n(viper-record-kbd-macro %S '%S %s '%S)" | |
428 (viper-display-macro macro-name) | |
13211
76308c9753ab
(vip-record-kbd-macro): correctly escapes `.' and `[' now.
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
12695
diff
changeset
|
429 state |
76308c9753ab
(vip-record-kbd-macro): correctly escapes `.' and `[' now.
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
12695
diff
changeset
|
430 ;; if we don't let vector macro-body through %S, |
76308c9753ab
(vip-record-kbd-macro): correctly escapes `.' and `[' now.
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
12695
diff
changeset
|
431 ;; the symbols `\.' `\[' etc will be converted into |
76308c9753ab
(vip-record-kbd-macro): correctly escapes `.' and `[' now.
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
12695
diff
changeset
|
432 ;; characters, causing invalid read error on recorded |
19079 | 433 ;; macros in .viper. |
13211
76308c9753ab
(vip-record-kbd-macro): correctly escapes `.' and `[' now.
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
12695
diff
changeset
|
434 ;; I am not sure is macro-body can still be a string at |
76308c9753ab
(vip-record-kbd-macro): correctly escapes `.' and `[' now.
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
12695
diff
changeset
|
435 ;; this point, but I am preserving this option anyway. |
76308c9753ab
(vip-record-kbd-macro): correctly escapes `.' and `[' now.
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
12695
diff
changeset
|
436 (if (vectorp macro-body) |
76308c9753ab
(vip-record-kbd-macro): correctly escapes `.' and `[' now.
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
12695
diff
changeset
|
437 (format "%S" macro-body) |
76308c9753ab
(vip-record-kbd-macro): correctly escapes `.' and `[' now.
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
12695
diff
changeset
|
438 macro-body) |
76308c9753ab
(vip-record-kbd-macro): correctly escapes `.' and `[' now.
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
12695
diff
changeset
|
439 scope) |
19079 | 440 viper-custom-file-name)) |
10789 | 441 |
14384
854325337547
Moved code around to minimize compiler warnings.
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
14335
diff
changeset
|
442 (message msg) |
10789 | 443 )) |
444 | |
445 (setq new-elt | |
446 (cons macro-name | |
447 (cond ((eq scope t) (list nil nil (cons t nil))) | |
448 ((symbolp scope) | |
449 (list nil (list (cons scope nil)) (cons t nil))) | |
450 ((stringp scope) | |
451 (list (list (cons scope nil)) nil (cons t nil)))))) | |
452 (setq old-elt (assoc macro-name (eval macro-alist-var))) | |
453 | |
454 (if (null old-elt) | |
455 (progn | |
456 ;; insert new-elt in macro-alist-var and keep the list sorted | |
457 (define-key | |
458 keymap | |
19079 | 459 (vector (viper-key-to-emacs-key (aref macro-name 0))) |
460 'viper-exec-mapped-kbd-macro) | |
10789 | 461 (setq lis (eval macro-alist-var)) |
19079 | 462 (while (and lis (string< (viper-array-to-string (car (car lis))) |
463 (viper-array-to-string macro-name))) | |
10789 | 464 (setq lis2 (cons (car lis) lis2)) |
465 (setq lis (cdr lis))) | |
466 | |
467 (setq lis2 (reverse lis2)) | |
468 (set macro-alist-var (append lis2 (cons new-elt lis))) | |
469 (setq old-elt new-elt))) | |
470 (setq old-sub-elt | |
19079 | 471 (cond ((eq scope t) (viper-kbd-global-pair old-elt)) |
472 ((symbolp scope) (assoc scope (viper-kbd-mode-alist old-elt))) | |
473 ((stringp scope) (assoc scope (viper-kbd-buf-alist old-elt))))) | |
10789 | 474 (if old-sub-elt |
475 (setcdr old-sub-elt macro-body) | |
476 (cond ((symbolp scope) (setcar (cdr (cdr old-elt)) | |
477 (cons (cons scope macro-body) | |
19079 | 478 (viper-kbd-mode-alist old-elt)))) |
10789 | 479 ((stringp scope) (setcar (cdr old-elt) |
480 (cons (cons scope macro-body) | |
19079 | 481 (viper-kbd-buf-alist old-elt)))))) |
10789 | 482 )) |
483 | |
484 | |
485 | |
19079 | 486 ;; macro name must be a vector of viper-style keys |
487 (defun viper-unrecord-kbd-macro (macro-name state) | |
12140
75379a19c5d5
Changed vip-*-frame-* to *-frame-*, incorporated overlay strings,
Karl Heuer <kwzh@gnu.org>
parents:
11288
diff
changeset
|
488 "Delete macro MACRO-NAME from Viper STATE. |
26263
4f315ca65976
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
19907
diff
changeset
|
489 MACRO-NAME must be a vector of viper-style keys. This command is used by Viper |
19079 | 490 internally, but the user can also use it in ~/.viper to delete pre-defined |
26263
4f315ca65976
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
19907
diff
changeset
|
491 macros supplied with Viper. The best way to avoid mistakes in macro names to |
4f315ca65976
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
19907
diff
changeset
|
492 be passed to this function is to use viper-describe-kbd-macros and copy the |
4f315ca65976
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
19907
diff
changeset
|
493 name from there." |
10789 | 494 (let* (state-name keymap |
495 (macro-alist-var | |
496 (cond ((eq state 'vi-state) | |
497 (setq state-name "Vi state" | |
19079 | 498 keymap viper-vi-kbd-map) |
499 'viper-vi-kbd-macro-alist) | |
10789 | 500 ((memq state '(insert-state replace-state)) |
501 (setq state-name "Insert state" | |
19079 | 502 keymap viper-insert-kbd-map) |
503 'viper-insert-kbd-macro-alist) | |
10789 | 504 (t |
505 (setq state-name "Emacs state" | |
19079 | 506 keymap viper-emacs-kbd-map) |
507 'viper-emacs-kbd-macro-alist) | |
10789 | 508 )) |
509 buf-mapping mode-mapping global-mapping | |
510 macro-pair macro-entry) | |
511 | |
26263
4f315ca65976
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
19907
diff
changeset
|
512 ;; Macro-name is usually a vector. However, command history or macros |
4f315ca65976
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
19907
diff
changeset
|
513 ;; recorded in ~/.viper may appear as strings. So, convert to vectors. |
19079 | 514 (setq macro-name (viper-fixup-macro macro-name)) |
515 (if (viper-char-array-p macro-name) | |
516 (setq macro-name (viper-char-array-to-macro macro-name))) | |
10789 | 517 |
518 (setq macro-entry (assoc macro-name (eval macro-alist-var))) | |
519 (if (= (length macro-name) 0) | |
520 (error "Can't unmap an empty macro name")) | |
521 (if (null macro-entry) | |
522 (error "%S is not mapped to a macro for %s in `%s'" | |
19079 | 523 (viper-display-macro macro-name) |
10789 | 524 state-name (buffer-name))) |
525 | |
19079 | 526 (setq buf-mapping (viper-kbd-buf-pair macro-entry) |
527 mode-mapping (viper-kbd-mode-pair macro-entry) | |
528 global-mapping (viper-kbd-global-pair macro-entry)) | |
10789 | 529 |
530 (cond ((and (cdr buf-mapping) | |
531 (or (and (not (cdr mode-mapping)) (not (cdr global-mapping))) | |
532 (y-or-n-p | |
533 (format "Unmap %S for `%s' only? " | |
19079 | 534 (viper-display-macro macro-name) |
10789 | 535 (buffer-name))))) |
536 (setq macro-pair buf-mapping) | |
537 (message "%S is unmapped for %s in `%s'" | |
19079 | 538 (viper-display-macro macro-name) |
10789 | 539 state-name (buffer-name))) |
540 ((and (cdr mode-mapping) | |
541 (or (not (cdr global-mapping)) | |
542 (y-or-n-p | |
543 (format "Unmap %S for the major mode `%S' only? " | |
19079 | 544 (viper-display-macro macro-name) |
10789 | 545 major-mode)))) |
546 (setq macro-pair mode-mapping) | |
547 (message "%S is unmapped for %s in %S" | |
19079 | 548 (viper-display-macro macro-name) state-name major-mode)) |
549 ((cdr (setq macro-pair (viper-kbd-global-pair macro-entry))) | |
10789 | 550 (message |
18839 | 551 "Global mapping for %S in %s is removed" |
19079 | 552 (viper-display-macro macro-name) state-name)) |
10789 | 553 (t (error "%S is not mapped to a macro for %s in `%s'" |
19079 | 554 (viper-display-macro macro-name) |
10789 | 555 state-name (buffer-name)))) |
556 (setcdr macro-pair nil) | |
557 (or (cdr buf-mapping) | |
558 (cdr mode-mapping) | |
559 (cdr global-mapping) | |
560 (progn | |
561 (set macro-alist-var (delq macro-entry (eval macro-alist-var))) | |
19079 | 562 (if (viper-can-release-key (aref macro-name 0) |
10789 | 563 (eval macro-alist-var)) |
564 (define-key | |
565 keymap | |
19079 | 566 (vector (viper-key-to-emacs-key (aref macro-name 0))) |
10789 | 567 nil)) |
568 )) | |
569 )) | |
570 | |
12140
75379a19c5d5
Changed vip-*-frame-* to *-frame-*, incorporated overlay strings,
Karl Heuer <kwzh@gnu.org>
parents:
11288
diff
changeset
|
571 ;; Check if MACRO-ALIST has an entry for a macro name starting with |
26263
4f315ca65976
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
19907
diff
changeset
|
572 ;; CHAR. If not, this indicates that the binding for this char |
19079 | 573 ;; in viper-vi/insert-kbd-map can be released. |
574 (defun viper-can-release-key (char macro-alist) | |
10789 | 575 (let ((lis macro-alist) |
576 (can-release t) | |
577 macro-name) | |
578 | |
579 (while (and lis can-release) | |
580 (setq macro-name (car (car lis))) | |
581 (if (eq char (aref macro-name 0)) | |
582 (setq can-release nil)) | |
583 (setq lis (cdr lis))) | |
584 can-release)) | |
585 | |
586 | |
19079 | 587 (defun viper-exec-mapped-kbd-macro (count) |
10789 | 588 "Dispatch kbd macro." |
589 (interactive "P") | |
19079 | 590 (let* ((macro-alist (cond ((eq viper-current-state 'vi-state) |
591 viper-vi-kbd-macro-alist) | |
592 ((memq viper-current-state | |
10789 | 593 '(insert-state replace-state)) |
19079 | 594 viper-insert-kbd-macro-alist) |
10789 | 595 (t |
19079 | 596 viper-emacs-kbd-macro-alist))) |
10789 | 597 (unmatched-suffix "") |
598 ;; Macros and keys are executed with other macros turned off | |
599 ;; For macros, this is done to avoid macro recursion | |
19079 | 600 viper-vi-kbd-minor-mode viper-insert-kbd-minor-mode |
601 viper-emacs-kbd-minor-mode | |
10789 | 602 next-best-match keyseq event-seq |
603 macro-first-char macro-alist-elt macro-body | |
604 command) | |
605 | |
606 (setq macro-first-char last-command-event | |
19079 | 607 event-seq (viper-read-fast-keysequence macro-first-char macro-alist) |
608 keyseq (viper-events-to-macro event-seq) | |
10789 | 609 macro-alist-elt (assoc keyseq macro-alist) |
19079 | 610 next-best-match (viper-find-best-matching-macro macro-alist keyseq)) |
10789 | 611 |
612 (if (null macro-alist-elt) | |
613 (setq macro-alist-elt (car next-best-match) | |
614 unmatched-suffix (subseq event-seq (cdr next-best-match)))) | |
615 | |
616 (cond ((null macro-alist-elt)) | |
19079 | 617 ((setq macro-body (viper-kbd-buf-definition macro-alist-elt))) |
618 ((setq macro-body (viper-kbd-mode-definition macro-alist-elt))) | |
619 ((setq macro-body (viper-kbd-global-definition macro-alist-elt)))) | |
10789 | 620 |
621 ;; when defining keyboard macro, don't use the macro mappings | |
622 (if (and macro-body (not defining-kbd-macro)) | |
623 ;; block cmd executed as part of a macro from entering command history | |
624 (let ((command-history command-history)) | |
19079 | 625 (setq viper-this-kbd-macro (car macro-alist-elt)) |
626 (execute-kbd-macro (viper-macro-to-events macro-body) count) | |
627 (setq viper-this-kbd-macro nil | |
628 viper-last-kbd-macro (car macro-alist-elt)) | |
629 (viper-set-unread-command-events unmatched-suffix)) | |
10789 | 630 ;; If not a macro, or the macro is suppressed while defining another |
631 ;; macro, put keyseq back on the event queue | |
19079 | 632 (viper-set-unread-command-events event-seq) |
10789 | 633 ;; if the user typed arg, then use it if prefix arg is not set by |
634 ;; some other command (setting prefix arg can happen if we do, say, | |
26263
4f315ca65976
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
19907
diff
changeset
|
635 ;; 2dw and there is a macro starting with 2. Then control will go to |
10789 | 636 ;; this routine |
637 (or prefix-arg (setq prefix-arg count)) | |
638 (setq command (key-binding (read-key-sequence nil))) | |
639 (if (commandp command) | |
640 (command-execute command) | |
641 (beep 1))) | |
642 )) | |
643 | |
644 | |
645 | |
646 ;;; Displaying and completing macros | |
647 | |
19079 | 648 (defun viper-describe-kbd-macros () |
10789 | 649 "Show currently defined keyboard macros." |
650 (interactive) | |
19079 | 651 (with-output-to-temp-buffer " *viper-info*" |
10789 | 652 (princ "Macros in Vi state:\n===================\n") |
19079 | 653 (mapcar 'viper-describe-one-macro viper-vi-kbd-macro-alist) |
10789 | 654 (princ "\n\nMacros in Insert and Replace states:\n====================================\n") |
19079 | 655 (mapcar 'viper-describe-one-macro viper-insert-kbd-macro-alist) |
10789 | 656 (princ "\n\nMacros in Emacs state:\n======================\n") |
19079 | 657 (mapcar 'viper-describe-one-macro viper-emacs-kbd-macro-alist) |
10789 | 658 )) |
659 | |
19079 | 660 (defun viper-describe-one-macro (macro) |
10789 | 661 (princ (format "\n *** Mappings for %S:\n ------------\n" |
19079 | 662 (viper-display-macro (car macro)))) |
10789 | 663 (princ " ** Buffer-specific:") |
19079 | 664 (if (viper-kbd-buf-alist macro) |
665 (mapcar 'viper-describe-one-macro-elt (viper-kbd-buf-alist macro)) | |
10789 | 666 (princ " none\n")) |
667 (princ "\n ** Mode-specific:") | |
19079 | 668 (if (viper-kbd-mode-alist macro) |
669 (mapcar 'viper-describe-one-macro-elt (viper-kbd-mode-alist macro)) | |
10789 | 670 (princ " none\n")) |
671 (princ "\n ** Global:") | |
19079 | 672 (if (viper-kbd-global-definition macro) |
673 (princ (format "\n %S" (cdr (viper-kbd-global-pair macro)))) | |
10789 | 674 (princ " none")) |
675 (princ "\n")) | |
676 | |
19079 | 677 (defun viper-describe-one-macro-elt (elt) |
10789 | 678 (let ((name (car elt)) |
679 (defn (cdr elt))) | |
680 (princ (format "\n * %S:\n %S\n" name defn)))) | |
681 | |
682 | |
683 | |
684 ;; check if SEQ is a prefix of some car of an element in ALIST | |
19079 | 685 (defun viper-keyseq-is-a-possible-macro (seq alist) |
686 (let ((converted-seq (viper-events-to-macro seq))) | |
10789 | 687 (eval (cons 'or |
688 (mapcar | |
26263
4f315ca65976
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
19907
diff
changeset
|
689 (lambda (elt) (viper-prefix-subseq-p converted-seq elt)) |
19079 | 690 (viper-this-buffer-macros alist)))))) |
10789 | 691 |
692 ;; whether SEQ1 is a prefix of SEQ2 | |
19079 | 693 (defun viper-prefix-subseq-p (seq1 seq2) |
10789 | 694 (let ((len1 (length seq1)) |
695 (len2 (length seq2))) | |
696 (if (<= len1 len2) | |
697 (equal seq1 (subseq seq2 0 len1))))) | |
698 | |
699 ;; find the longest common prefix | |
19079 | 700 (defun viper-common-seq-prefix (&rest seqs) |
10789 | 701 (let* ((first (car seqs)) |
702 (rest (cdr seqs)) | |
703 (pref []) | |
704 (idx 0) | |
705 len) | |
706 (if (= (length seqs) 0) | |
707 (setq len 0) | |
708 (setq len (apply 'min (mapcar 'length seqs)))) | |
709 (while (< idx len) | |
710 (if (eval (cons 'and | |
26263
4f315ca65976
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
19907
diff
changeset
|
711 (mapcar (lambda (s) (equal (elt first idx) (elt s idx))) |
10789 | 712 rest))) |
713 (setq pref (vconcat pref (vector (elt first idx))))) | |
714 (setq idx (1+ idx))) | |
715 pref)) | |
716 | |
717 ;; get all sequences that match PREFIX from a given A-LIST | |
19079 | 718 (defun viper-extract-matching-alist-members (pref alist) |
26263
4f315ca65976
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
19907
diff
changeset
|
719 (delq nil (mapcar (lambda (elt) (if (viper-prefix-subseq-p pref elt) elt)) |
19079 | 720 (viper-this-buffer-macros alist)))) |
10789 | 721 |
19079 | 722 (defun viper-do-sequence-completion (seq alist compl-message) |
723 (let* ((matches (viper-extract-matching-alist-members seq alist)) | |
724 (new-seq (apply 'viper-common-seq-prefix matches)) | |
10789 | 725 ) |
726 (cond ((and (equal seq new-seq) (= (length matches) 1)) | |
727 (message "%s (Sole completion)" compl-message) | |
728 (sit-for 2)) | |
729 ((null matches) | |
730 (message "%s (No match)" compl-message) | |
731 (sit-for 2) | |
732 (setq new-seq seq)) | |
733 ((member seq matches) | |
734 (message "%s (Complete, but not unique)" compl-message) | |
735 (sit-for 2) | |
19079 | 736 (viper-display-vector-completions matches)) |
10789 | 737 ((equal seq new-seq) |
19079 | 738 (viper-display-vector-completions matches))) |
10789 | 739 new-seq)) |
740 | |
741 | |
19079 | 742 (defun viper-display-vector-completions (list) |
10789 | 743 (with-output-to-temp-buffer "*Completions*" |
744 (display-completion-list | |
745 (mapcar 'prin1-to-string | |
19079 | 746 (mapcar 'viper-display-macro list))))) |
10789 | 747 |
748 | |
749 | |
750 ;; alist is the alist of macros | |
751 ;; str is the fast key sequence entered | |
752 ;; returns: (matching-macro-def . unmatched-suffix-start-index) | |
19079 | 753 (defun viper-find-best-matching-macro (alist str) |
10789 | 754 (let ((lis alist) |
755 (def-len 0) | |
756 (str-len (length str)) | |
757 match unmatched-start-idx found macro-def) | |
758 (while (and (not found) lis) | |
759 (setq macro-def (car lis) | |
760 def-len (length (car macro-def))) | |
761 (if (and (>= str-len def-len) | |
762 (equal (car macro-def) (subseq str 0 def-len))) | |
19079 | 763 (if (or (viper-kbd-buf-definition macro-def) |
764 (viper-kbd-mode-definition macro-def) | |
765 (viper-kbd-global-definition macro-def)) | |
10789 | 766 (setq found t)) |
767 ) | |
768 (setq lis (cdr lis))) | |
769 | |
770 (if found | |
771 (setq match macro-def | |
772 unmatched-start-idx def-len) | |
773 (setq match nil | |
774 unmatched-start-idx 0)) | |
775 | |
776 (cons match unmatched-start-idx))) | |
777 | |
778 | |
779 | |
780 ;; returns a list of names of macros defined for the current buffer | |
19079 | 781 (defun viper-this-buffer-macros (macro-alist) |
10789 | 782 (let (candidates) |
783 (setq candidates | |
26263
4f315ca65976
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
19907
diff
changeset
|
784 (mapcar (lambda (elt) |
4f315ca65976
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
19907
diff
changeset
|
785 (if (or (viper-kbd-buf-definition elt) |
4f315ca65976
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
19907
diff
changeset
|
786 (viper-kbd-mode-definition elt) |
4f315ca65976
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
19907
diff
changeset
|
787 (viper-kbd-global-definition elt)) |
4f315ca65976
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
19907
diff
changeset
|
788 (car elt))) |
10789 | 789 macro-alist)) |
790 (setq candidates (delq nil candidates)))) | |
791 | |
792 | |
12140
75379a19c5d5
Changed vip-*-frame-* to *-frame-*, incorporated overlay strings,
Karl Heuer <kwzh@gnu.org>
parents:
11288
diff
changeset
|
793 ;; if seq of Viper key symbols (representing a macro) can be converted to a |
26263
4f315ca65976
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
19907
diff
changeset
|
794 ;; string--do so. Otherwise, do nothing. |
19079 | 795 (defun viper-display-macro (macro-name-or-body) |
796 (cond ((viper-char-symbol-sequence-p macro-name-or-body) | |
14585
b6228a159e75
(ex-map-read-args,ex-unmap-read-args): fixed messages.
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
14581
diff
changeset
|
797 (mapconcat 'symbol-name macro-name-or-body "")) |
19079 | 798 ((viper-char-array-p macro-name-or-body) |
14585
b6228a159e75
(ex-map-read-args,ex-unmap-read-args): fixed messages.
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
14581
diff
changeset
|
799 (mapconcat 'char-to-string macro-name-or-body "")) |
b6228a159e75
(ex-map-read-args,ex-unmap-read-args): fixed messages.
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
14581
diff
changeset
|
800 (t macro-name-or-body))) |
10789 | 801 |
14587
542db2bd7e38
(vip-events-to-macro): discard events represented as lists in macro
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
14585
diff
changeset
|
802 ;; convert sequence of events (that came presumably from emacs kbd macro) into |
542db2bd7e38
(vip-events-to-macro): discard events represented as lists in macro
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
14585
diff
changeset
|
803 ;; Viper's macro, which is a vector of the form |
542db2bd7e38
(vip-events-to-macro): discard events represented as lists in macro
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
14585
diff
changeset
|
804 ;; [ desc desc ... ] |
542db2bd7e38
(vip-events-to-macro): discard events represented as lists in macro
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
14585
diff
changeset
|
805 ;; Each desc is either a symbol of (meta symb), (shift symb), etc. |
26263
4f315ca65976
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
19907
diff
changeset
|
806 ;; Here we purge events that happen to be lists. In most cases, these events |
14587
542db2bd7e38
(vip-events-to-macro): discard events represented as lists in macro
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
14585
diff
changeset
|
807 ;; got into a macro definition unintentionally; say, when the user moves mouse |
542db2bd7e38
(vip-events-to-macro): discard events represented as lists in macro
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
14585
diff
changeset
|
808 ;; during a macro definition, then something like (switch-frame ...) might get |
26263
4f315ca65976
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
19907
diff
changeset
|
809 ;; in. Another reason for purging lists-events is that we can't store them in |
14587
542db2bd7e38
(vip-events-to-macro): discard events represented as lists in macro
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
14585
diff
changeset
|
810 ;; textual form (say, in .emacs) and then read them back. |
19079 | 811 (defun viper-events-to-macro (event-seq) |
26263
4f315ca65976
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
19907
diff
changeset
|
812 (vconcat (delq nil (mapcar (lambda (elt) (if (consp elt) |
4f315ca65976
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
19907
diff
changeset
|
813 nil |
4f315ca65976
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
19907
diff
changeset
|
814 (viper-event-key elt))) |
14587
542db2bd7e38
(vip-events-to-macro): discard events represented as lists in macro
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
14585
diff
changeset
|
815 event-seq)))) |
10789 | 816 |
12140
75379a19c5d5
Changed vip-*-frame-* to *-frame-*, incorporated overlay strings,
Karl Heuer <kwzh@gnu.org>
parents:
11288
diff
changeset
|
817 ;; convert strings or arrays of characters to Viper macro form |
19079 | 818 (defun viper-char-array-to-macro (array) |
10789 | 819 (let ((vec (vconcat array)) |
820 macro) | |
19079 | 821 (if viper-xemacs-p |
10789 | 822 (setq macro (mapcar 'character-to-event vec)) |
823 (setq macro vec)) | |
19079 | 824 (vconcat (mapcar 'viper-event-key macro)))) |
10789 | 825 |
14585
b6228a159e75
(ex-map-read-args,ex-unmap-read-args): fixed messages.
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
14581
diff
changeset
|
826 ;; For macros bodies and names, goes over MACRO and checks if all members are |
10789 | 827 ;; names of keys (actually, it only checks if they are symbols or lists |
14585
b6228a159e75
(ex-map-read-args,ex-unmap-read-args): fixed messages.
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
14581
diff
changeset
|
828 ;; if a digit is found, it is converted into a symbol (e.g., 0 -> \0, etc). |
b6228a159e75
(ex-map-read-args,ex-unmap-read-args): fixed messages.
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
14581
diff
changeset
|
829 ;; If MACRO is not a list or vector -- doesn't change MACRO. |
19079 | 830 (defun viper-fixup-macro (macro) |
10789 | 831 (let ((len (length macro)) |
832 (idx 0) | |
833 elt break) | |
834 (if (or (vectorp macro) (listp macro)) | |
835 (while (and (< idx len) (not break)) | |
836 (setq elt (elt macro idx)) | |
837 (cond ((numberp elt) | |
838 ;; fix number | |
839 (if (and (<= 0 elt) (<= elt 9)) | |
840 (cond ((arrayp macro) | |
841 (aset macro | |
842 idx | |
843 (intern (char-to-string (+ ?0 elt))))) | |
844 ((listp macro) | |
845 (setcar (nthcdr idx macro) | |
846 (intern (char-to-string (+ ?0 elt))))) | |
847 ))) | |
848 ((listp elt) | |
19079 | 849 (viper-fixup-macro elt)) |
10789 | 850 ((symbolp elt) nil) |
851 (t (setq break t))) | |
852 (setq idx (1+ idx)))) | |
853 | |
854 (if break | |
855 (error "Wrong type macro component, symbol-or-listp, %S" elt) | |
856 macro))) | |
857 | |
19079 | 858 (defun viper-macro-to-events (macro-body) |
859 (vconcat (mapcar 'viper-key-to-emacs-key macro-body))) | |
10789 | 860 |
861 | |
862 | |
863 ;;; Reading fast key sequences | |
864 | |
865 ;; Assuming that CHAR was the first character in a fast succession of key | |
26263
4f315ca65976
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
19907
diff
changeset
|
866 ;; strokes, read the rest. Return the vector of keys that was entered in |
10789 | 867 ;; this fast succession of key strokes. |
868 ;; A fast keysequence is one that is terminated by a pause longer than | |
19079 | 869 ;; viper-fast-keyseq-timeout. |
870 (defun viper-read-fast-keysequence (event macro-alist) | |
10789 | 871 (let ((lis (vector event)) |
872 next-event) | |
19079 | 873 (while (and (viper-fast-keysequence-p) |
874 (viper-keyseq-is-a-possible-macro lis macro-alist)) | |
875 (setq next-event (viper-read-key)) | |
876 ;;(setq next-event (viper-read-event)) | |
877 (or (viper-mouse-event-p next-event) | |
10789 | 878 (setq lis (vconcat lis (vector next-event))))) |
879 lis)) | |
880 | |
881 | |
882 ;;; Keyboard macros in registers | |
883 | |
884 ;; sets register to last-kbd-macro carefully. | |
19079 | 885 (defun viper-set-register-macro (reg) |
10789 | 886 (if (get-register reg) |
26263
4f315ca65976
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
19907
diff
changeset
|
887 (if (y-or-n-p "Register contains data. Overwrite? ") |
10789 | 888 () |
889 (error | |
26263
4f315ca65976
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
19907
diff
changeset
|
890 "Macro not saved in register. Can still be invoked via `C-x e'"))) |
10789 | 891 (set-register reg last-kbd-macro)) |
892 | |
19079 | 893 (defun viper-register-macro (count) |
10789 | 894 "Keyboard macros in registers - a modified \@ command." |
895 (interactive "P") | |
896 (let ((reg (downcase (read-char)))) | |
897 (cond ((or (and (<= ?a reg) (<= reg ?z))) | |
19079 | 898 (setq viper-last-macro-reg reg) |
10789 | 899 (if defining-kbd-macro |
900 (progn | |
901 (end-kbd-macro) | |
19079 | 902 (viper-set-register-macro reg)) |
10789 | 903 (execute-kbd-macro (get-register reg) count))) |
904 ((or (= ?@ reg) (= ?\^j reg) (= ?\^m reg)) | |
19079 | 905 (if viper-last-macro-reg |
10789 | 906 nil |
907 (error "No previous kbd macro")) | |
19079 | 908 (execute-kbd-macro (get-register viper-last-macro-reg) count)) |
10789 | 909 ((= ?\# reg) |
910 (start-kbd-macro count)) | |
911 ((= ?! reg) | |
912 (setq reg (downcase (read-char))) | |
913 (if (or (and (<= ?a reg) (<= reg ?z))) | |
914 (progn | |
19079 | 915 (setq viper-last-macro-reg reg) |
916 (viper-set-register-macro reg)))) | |
10789 | 917 (t |
14581
4951b11970a1
*** empty log message ***
Michael Kifer <kifer@cs.stonybrook.edu>
parents:
14580
diff
changeset
|
918 (error "`%c': Unknown register" reg))))) |
10789 | 919 |
920 | |
19079 | 921 (defun viper-global-execute () |
10789 | 922 "Call last keyboad macro for each line in the region." |
923 (if (> (point) (mark t)) (exchange-point-and-mark)) | |
924 (beginning-of-line) | |
925 (call-last-kbd-macro) | |
926 (while (< (point) (mark t)) | |
927 (forward-line 1) | |
928 (beginning-of-line) | |
929 (call-last-kbd-macro))) | |
930 | |
931 | |
38414
67b464da13ec
Some fixes to follow coding conventions.
Pavel Janík <Pavel@Janik.cz>
parents:
26263
diff
changeset
|
932 ;;; viper-macs.el ends here |