|
1 |
| -command-chain |
2 |
| -============= |
| 1 | +# command-chain.el |
3 | 2 |
|
4 |
| -Emacs extension: command-chain.el --- Multiple commands on one key |
| 3 | +This package is an integration and generalization of `smartchr.el` |
| 4 | +and `sequencial-command.el`, allows one to use multiple commands on |
| 5 | +one key like `C-l` in Emacs default. |
| 6 | + |
| 7 | +`smartchr.el`, porting of smartchr in vim, provides different insertion |
| 8 | +for pressing one key multiple times. |
| 9 | +`sequencial-command.el` does different commands without buffer and |
| 10 | +point recovered. |
| 11 | +They are essentially the same so this package provides that. |
| 12 | + |
| 13 | + |
| 14 | + |
| 15 | +## Requirement |
| 16 | + |
| 17 | +ERFI (`erfi-macros.el`, `erfi-srfi-1.el`) |
| 18 | + |
| 19 | + |
| 20 | + |
| 21 | +## Installation |
| 22 | + |
| 23 | +### With el-get |
| 24 | + |
| 25 | +Write the below to your .emacs file: |
| 26 | + |
| 27 | + (setq el-get-sources |
| 28 | + (append el-get-sources |
| 29 | + '((:name erfi |
| 30 | + :type github |
| 31 | + :website "https://github.com/kenoss/erfi" |
| 32 | + :description "Emacs Lisp Reconstruction for Indivisuals" |
| 33 | + :pkgname "kenoss/erfi") |
| 34 | + (:name command-chain |
| 35 | + :type github |
| 36 | + :website "https://github.com/kenoss/command-chain" |
| 37 | + :description "Multiple commands on one key" |
| 38 | + :pkgname "kenoss/erfi")))) |
| 39 | + (require 'command-chain) |
| 40 | + |
| 41 | +### Manual install |
| 42 | + |
| 43 | +At the terminal, |
| 44 | + |
| 45 | + $ git clone https://github.com/kenoss/erfi |
| 46 | + $ git clone https://github.com/kenoss/command-chain |
| 47 | + |
| 48 | +Or download zip file and extract. Write the below to your .emacs file: |
| 49 | + |
| 50 | + (setq load-path |
| 51 | + (append load-path '("/path/to/erfi" "/path/to/command-chain"))) |
| 52 | + (require 'command-chain) |
| 53 | + |
| 54 | + |
| 55 | + |
| 56 | +## Examples |
| 57 | + |
| 58 | +`command-chain` takes a list of items and return interactive function. |
| 59 | +For string, returned function insert it. Command sequence ends as list ends. |
| 60 | +As the command sequence proceed, inserted text are deleted and point are recovered. |
| 61 | + |
| 62 | +config: |
| 63 | + |
| 64 | + (define-key global-map (kbd ";") (command-chain '("a" "b" "c"))) |
| 65 | + |
| 66 | +effect: |
| 67 | + |
| 68 | + ; => a |
| 69 | + ;; => b |
| 70 | + ;;; => c |
| 71 | + ;;;; => |
| 72 | + ;;;;; => a (new command sequence start) |
| 73 | + |
| 74 | + |
| 75 | +### Keyword `:loop` |
| 76 | + |
| 77 | +Key word `:loop` indicates following items constitute a loop. |
| 78 | + |
| 79 | +config: |
| 80 | + |
| 81 | + (define-key global-map (kbd ";") (command-chain '(:loop "a" "b" "c"))) |
| 82 | + |
| 83 | +effect: |
| 84 | + |
| 85 | + ; => a |
| 86 | + ;; => b |
| 87 | + ;;; => c |
| 88 | + ;;;; => a |
| 89 | + ;;;;; => b |
| 90 | + |
| 91 | +config: |
| 92 | + |
| 93 | + (define-key global-map (kbd ";") (command-chain '("a" :loop "b" "c"))) |
| 94 | + |
| 95 | +effect: |
| 96 | + |
| 97 | + ; => a |
| 98 | + ;; => b |
| 99 | + ;;; => c |
| 100 | + ;;;; => b |
| 101 | + ;;;;; => c |
| 102 | + |
| 103 | +Key word `:loop` may appear at most once. |
| 104 | + |
| 105 | +invalid config: |
| 106 | + |
| 107 | + (define-key global-map (kbd ";") (command-chain '("a" :loop "b" "c" :loop a))) |
| 108 | + |
| 109 | + |
| 110 | +### String |
| 111 | + |
| 112 | +The variable `command-chain-cursor-regexp` in string indicate where point should move after insertion. |
| 113 | +Default is "\_|\_". One can use pairs alternatively. |
| 114 | + |
| 115 | +config: |
| 116 | + |
| 117 | + (define-key global-map (kbd ";") (command-chain '("a" "b_|_b" ("c" . "c")))) |
| 118 | + |
| 119 | +effect: |
| 120 | + |
| 121 | + ; => a_|_ (here _|_ is the point) |
| 122 | + ;; => b_|_b |
| 123 | + ;;; => c_|_c |
| 124 | + ;;;; => _|_ |
| 125 | + ;;;;; => a_|_ |
| 126 | + |
| 127 | + |
| 128 | +### Function |
| 129 | + |
| 130 | +For function, returned function execute it. |
| 131 | + |
| 132 | +config: |
| 133 | + |
| 134 | + (define-key global-map (kbd ";") |
| 135 | + (command-chain '(beginning-of-line |
| 136 | + end-of-line |
| 137 | + " hoge "))) |
| 138 | + |
| 139 | +effect: |
| 140 | + |
| 141 | + => some_|_thing (assume buffer contents is such thing) |
| 142 | + ; => _|_something |
| 143 | + ;; => something_|_ |
| 144 | + ;;; => some hoge _|_thing (recall that point is recovered each time) |
| 145 | + ;;;; => some_|_thing |
| 146 | + |
| 147 | + |
| 148 | +### List |
| 149 | + |
| 150 | +How do we write inserting text in the beginnig of line? |
| 151 | +For list of items (not restricted to string nor function), returned function execute that sequence at one key pressing. |
| 152 | + |
| 153 | +config: |
| 154 | + |
| 155 | + (define-key global-map (kbd ";") |
| 156 | + (command-chain '(beginning-of-line |
| 157 | + (beginning-of-line "just a ") |
| 158 | + (end-of-line " wrong" beginning-of-line)))) |
| 159 | + |
| 160 | +effect: |
| 161 | + |
| 162 | + => some_|_thing |
| 163 | + ; => just a _|_something |
| 164 | + ;; => _|_something wrong |
| 165 | + ;;; => some_|_thing |
| 166 | + |
| 167 | +Of course text recovery works correctly. |
| 168 | + |
| 169 | +config: |
| 170 | + |
| 171 | + (define-key global-map (kbd ";") |
| 172 | + (command-chain '(" a " |
| 173 | + (" b_|_b " " c_|_c " " d ") |
| 174 | + (" e_|_e " " f " beginning-of-line "hoge ")))) |
| 175 | + |
| 176 | +effect: |
| 177 | + |
| 178 | + => some_|_thing |
| 179 | + ; => some a _|_thing |
| 180 | + ;; => some b c d _|_c b thing |
| 181 | + ;;; => hoge _|_some e f e thing |
| 182 | + ;;;; => some_|_thing |
| 183 | + |
| 184 | + |
| 185 | +### Struct `command-chain-fnpair` |
| 186 | + |
| 187 | +The above examples are expanded to this form. One can use this for full control. (See below.) |
| 188 | + |
| 189 | + |
| 190 | +## Optional keywords |
| 191 | + |
| 192 | +`:prefix-fallback` designate a fall-back function used in the case prefix numerical argument (not equal to 1) given. |
| 193 | + |
| 194 | +config: |
| 195 | + |
| 196 | + (define-key global-map (kbd ";") (command-chain '("a" "b" "c") :prefix-fallback ";")) |
| 197 | + |
| 198 | +effect: |
| 199 | + |
| 200 | + ; => a |
| 201 | + C-u ; => ; |
| 202 | + |
| 203 | +config: |
| 204 | + |
| 205 | + (define-key global-map (kbd ";") (command-chain '("a" "b" "c") :prefix-fallback 'self-insert-command)) |
| 206 | + |
| 207 | +effect: |
| 208 | + |
| 209 | + ; => a |
| 210 | + C-u ; => ;;;; |
| 211 | + ;; C-u ; => b;;;;a |
| 212 | + |
| 213 | + |
| 214 | + |
| 215 | +## More examples |
| 216 | + |
| 217 | +The above examples all recover point. One can write as following to realize "insertion loop". |
| 218 | + |
| 219 | +config: |
| 220 | + |
| 221 | + (define-key global-map (kbd ";") |
| 222 | + (command-chain '("a" "b" |
| 223 | + :loop |
| 224 | + (:insert-fn (lambda () |
| 225 | + (command-chain-turn-off-point-recovery) |
| 226 | + (insert (apply 'concat (make-list (prefix-numeric-value current-prefix-arg) "A")))) |
| 227 | + :cleanup-fn nil)))) |
| 228 | + |
| 229 | +effect: |
| 230 | + |
| 231 | + ; => a |
| 232 | + ;; => b |
| 233 | + ;;; => A |
| 234 | + ;;;; => AA |
| 235 | + ;;;;; => AAA |
| 236 | + |
| 237 | + |
| 238 | +Like `C-l`, one may want `C-w` do `kill-region` and do nothing modulo 2, and `kill-ring-save` with prefix `C-u`: |
| 239 | + |
| 240 | + (define-key global-map (kbd "C-w") |
| 241 | + (command-chain '((:insert-fn (lambda () (interactive) |
| 242 | + (prog1 nil |
| 243 | + (call-interactively 'kill-region))) |
| 244 | + :cleanup-fn undo)) |
| 245 | + :prefix-fallback 'kill-ring-save)) |
| 246 | + |
| 247 | +The above register region to kill-ring as one repeats. The right definition is the following: |
| 248 | + |
| 249 | + (define-key global-map (kbd "C-w") |
| 250 | + (command-chain '((:insert-fn (lambda () (interactive) |
| 251 | + (prog1 nil |
| 252 | + (call-interactively 'kill-region))) |
| 253 | + :cleanup-fn undo) |
| 254 | + :loop |
| 255 | + (:insert-fn nil :cleanup-fn nil) |
| 256 | + (:insert-fn (lambda () (interactive) |
| 257 | + (prog1 nil |
| 258 | + (call-interactively 'kill-region) |
| 259 | + (setcdr kill-ring (cddr kill-ring)))) |
| 260 | + :cleanup-fn undo)) |
| 261 | + :prefix-fallback 'kill-ring-save)) |
0 commit comments