13337
|
1 ;;; term.el --- general command interpreter in a window stuff
|
|
2
|
74442
|
3 ;; Copyright (C) 1988, 1990, 1992, 1994, 1995, 2001, 2002, 2003,
|
79721
|
4 ;; 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
|
17283
|
5
|
57548
|
6 ;; Author: Per Bothner <per@bothner.com>
|
|
7 ;; Maintainer: Dan Nicolaescu <dann@ics.uci.edu>, Per Bothner <per@bothner.com>
|
38414
|
8 ;; Based on comint mode written by: Olin Shivers <shivers@cs.cmu.edu>
|
|
9 ;; Keywords: processes
|
17283
|
10
|
24044
|
11 ;; This file is part of GNU Emacs.
|
|
12
|
94678
|
13 ;; GNU Emacs is free software: you can redistribute it and/or modify
|
24044
|
14 ;; it under the terms of the GNU General Public License as published by
|
94678
|
15 ;; the Free Software Foundation, either version 3 of the License, or
|
|
16 ;; (at your option) any later version.
|
24044
|
17
|
|
18 ;; GNU Emacs is distributed in the hope that it will be useful,
|
|
19 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
20 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
21 ;; GNU General Public License for more details.
|
|
22
|
|
23 ;; You should have received a copy of the GNU General Public License
|
94678
|
24 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
|
24044
|
25
|
36763
00b03757e45b
These changes are based on a patch sent from Yong Lu <lyongu@yahoo.com>.
Kenichi Handa <handa@m17n.org>
diff
changeset
|
26 ;;; Marck 13 2001
|
00b03757e45b
These changes are based on a patch sent from Yong Lu <lyongu@yahoo.com>.
Kenichi Handa <handa@m17n.org>
diff
changeset
|
27 ;;; Fixes for CJK support by Yong Lu <lyongu@yahoo.com>.
|
00b03757e45b
These changes are based on a patch sent from Yong Lu <lyongu@yahoo.com>.
Kenichi Handa <handa@m17n.org>
diff
changeset
|
28
|
17283
|
29 ;;; Dir/Hostname tracking and ANSI colorization by
|
|
30 ;;; Marco Melgazzi <marco@techie.com>.
|
|
31
|
|
32 ;;; To see what I've modified and where it came from search for '-mm'
|
|
33
|
38414
|
34 ;;; Commentary:
|
|
35
|
17283
|
36 ;;; Speed considerations and a few caveats
|
|
37 ;;; --------------------------------------
|
|
38 ;;;
|
|
39 ;;; While the message passing and the colorization surely introduce some
|
|
40 ;;; overhead this has became so small that IMHO is surely outweighted by
|
|
41 ;;; the benefits you get but, as usual, YMMV
|
|
42 ;;;
|
|
43 ;;; Important caveat, when deciding the cursor/'grey keys' keycodes I had to
|
|
44 ;;; make a choice: on my Linux box this choice allows me to run all the
|
|
45 ;;; ncurses applications without problems but make these keys
|
|
46 ;;; uncomprehensible to all the cursesX programs. Your mileage may vary so
|
|
47 ;;; you may consider changing the default 'emulation'. Just search for this
|
|
48 ;;; piece of code and modify it as you like:
|
|
49 ;;;
|
|
50 ;;; ;; Which would be better: "\e[A" or "\eOA"? readline accepts either.
|
|
51 ;;; ;; For my configuration it's definitely better \eOA but YMMV. -mm
|
|
52 ;;; ;; For example: vi works with \eOA while elm wants \e[A ...
|
|
53 ;;; (defun term-send-up () (interactive) (term-send-raw-string "\eOA"))
|
|
54 ;;; (defun term-send-down () (interactive) (term-send-raw-string "\eOB"))
|
|
55 ;;; (defun term-send-right () (interactive) (term-send-raw-string "\eOC"))
|
|
56 ;;; (defun term-send-left () (interactive) (term-send-raw-string "\eOD"))
|
|
57 ;;;
|
|
58 ;;;
|
|
59 ;;; IMPORTANT: additions & changes
|
|
60 ;;; ------------------------------
|
|
61 ;;;
|
|
62 ;;; With this enhanced ansi-term.el you will get a reliable mechanism of
|
|
63 ;;; directory/username/host tracking: the only drawback is that you will
|
|
64 ;;; have to modify your shell start-up script. It's worth it, believe me :).
|
|
65 ;;;
|
|
66 ;;; When you rlogin/su/telnet and the account you access has a modified
|
|
67 ;;; startup script, you will be able to access the remote files as usual
|
|
68 ;;; with C-x C-f, if it's needed you will have to enter a password,
|
|
69 ;;; otherwise the file should get loaded straight away.
|
|
70 ;;;
|
|
71 ;;; This is useful even if you work only on one host: it often happens that,
|
|
72 ;;; for maintenance reasons, you have to edit files 'as root': before
|
|
73 ;;; patching term.el, I su-ed in a term.el buffer and used vi :), now I
|
|
74 ;;; simply do a C-x C-f and, via ange-ftp, the file is automatically loaded
|
|
75 ;;; 'as-root'. ( If you don't want to enter the root password every time you
|
|
76 ;;; can put it in your .netrc: note that this is -not- advisable if you're
|
|
77 ;;; connected to the internet or if somebody else works on your workstation!)
|
|
78 ;;;
|
|
79 ;;; If you use wu-ftpd you can use some of its features to avoid root ftp
|
|
80 ;;; access to the rest of the world: just put in /etc/ftphosts something like
|
|
81 ;;;
|
|
82 ;;; # Local access
|
|
83 ;;; allow root 127.0.0.1
|
|
84 ;;;
|
|
85 ;;; # By default nobody can't do anything
|
|
86 ;;; deny root *
|
|
87 ;;;
|
|
88 ;;;
|
|
89 ;;; ----------------------------------------
|
|
90 ;;;
|
|
91 ;;; If, instead of 'term', you call 'ansi-term', you get multiple term
|
|
92 ;;; buffers, after every new call ansi-term opens a new *ansi-term*<xx> window,
|
|
93 ;;; where <xx> is, as usual, a number...
|
|
94 ;;;
|
|
95 ;;; ----------------------------------------
|
|
96 ;;;
|
|
97 ;;; With the term-buffer-maximum-size you can finally decide how many
|
|
98 ;;; scrollback lines to keep: its default is 2048 but you can change it as
|
|
99 ;;; usual.
|
|
100 ;;;
|
|
101 ;;; ----------------------------------------
|
|
102 ;;;
|
|
103 ;;;
|
|
104 ;;; ANSI colorization should work well, I've decided to limit the interpreter
|
|
105 ;;; to five outstanding commands (like ESC [ 01;04;32;41;07m.
|
|
106 ;;; You shouldn't need more, if you do, tell me and I'll increase it. It's
|
|
107 ;;; so easy you could do it yourself...
|
|
108 ;;;
|
|
109 ;;; Blink, is not supported. Currently it's mapped as bold.
|
|
110 ;;;
|
|
111 ;;; Important caveat:
|
|
112 ;;; -----------------
|
|
113 ;;; if you want custom colors in term.el redefine term-default-fg-color
|
|
114 ;;; and term-default-bg-color BEFORE loading it.
|
|
115 ;;;
|
|
116 ;;; ----------------------------------------
|
|
117 ;;;
|
|
118 ;;; If you'd like to check out my complete configuration, you can download
|
|
119 ;;; it from http://www.polito.it/~s64912/things.html, it's ~500k in size and
|
|
120 ;;; contains my .cshrc, .emacs and my whole site-lisp subdirectory. (notice
|
|
121 ;;; that this term.el may be newer/older than the one in there, please
|
|
122 ;;; check!)
|
|
123 ;;;
|
|
124 ;;; This complete configuration contains, among other things, a complete
|
|
125 ;;; rectangular marking solution (based on rect-mark.el and
|
|
126 ;;; pc-bindings.el) and should be a good example of how extensively Emacs
|
|
127 ;;; can be configured on a ppp-connected ws.
|
|
128 ;;;
|
|
129 ;;; ----------------------------------------
|
|
130 ;;;
|
|
131 ;;; TODO:
|
|
132 ;;;
|
|
133 ;;; - Add hooks to allow raw-mode keys to be configurable
|
|
134 ;;; - Which keys are better ? \eOA or \e[A ?
|
|
135 ;;;
|
|
136 ;;;
|
|
137 ;;; Changes:
|
|
138 ;;;
|
|
139 ;;; V4.0 January 1997
|
|
140 ;;;
|
|
141 ;;; - Huge reworking of the faces code: now we only have roughly 20-30
|
|
142 ;;; faces for everything so we're even faster than the old md-term.el !
|
|
143 ;;; - Finished removing all the J-Shell code.
|
|
144 ;;;
|
|
145 ;;; V3.0 January 1997
|
|
146 ;;;
|
|
147 ;;; - Now all the supportable ANSI commands work well.
|
|
148 ;;; - Reworked a little the code: much less jsh-inspired stuff
|
|
149 ;;;
|
|
150 ;;; V2.3 November
|
|
151 ;;;
|
|
152 ;;; - Now all the faces are accessed through an array: much cleaner code.
|
|
153 ;;;
|
|
154 ;;; V2.2 November 4 1996
|
|
155 ;;;
|
|
156 ;;; - Implemented ANSI output colorization ( a bit rough but enough for
|
|
157 ;;; color_ls )
|
|
158 ;;;
|
|
159 ;;; - Implemented a maximum limit for the scroll buffer (stolen from
|
|
160 ;;; comint.el)
|
|
161 ;;;
|
|
162 ;;; v2.1 October 28 1996, first public release
|
|
163 ;;;
|
|
164 ;;; - Some new keybindings for term-char mode ( notably home/end/...)
|
|
165 ;;; - Directory, hostname and username tracking via ange-ftp
|
|
166 ;;; - Multi-term capability via the ansi-term call
|
|
167 ;;;
|
|
168 ;;; ----------------------------------------------------------------
|
|
169 ;;; You should/could have something like this in your .emacs to take
|
|
170 ;;; full advantage of this package
|
|
171 ;;;
|
|
172 ;;; (add-hook 'term-mode-hook
|
|
173 ;;; (function
|
|
174 ;;; (lambda ()
|
|
175 ;;; (setq term-prompt-regexp "^[^#$%>\n]*[#$%>] *")
|
|
176 ;;; (make-local-variable 'mouse-yank-at-point)
|
|
177 ;;; (make-local-variable 'transient-mark-mode)
|
|
178 ;;; (setq mouse-yank-at-point t)
|
|
179 ;;; (setq transient-mark-mode nil)
|
|
180 ;;; (auto-fill-mode -1)
|
|
181 ;;; (setq tab-width 8 ))))
|
|
182 ;;;
|
|
183 ;;;
|
|
184 ;;; ----------------------------------------
|
|
185 ;;;
|
|
186 ;;; If you want to use color ls the best setup is to have a different file
|
|
187 ;;; when you use eterm ( see above, mine is named .emacs_dircolors ). This
|
|
188 ;;; is necessary because some terminals, rxvt for example, need non-ansi
|
|
189 ;;; hacks to work ( for example on my rxvt white is wired to fg, and to
|
|
190 ;;; obtain normal white I have to do bold-white :)
|
|
191 ;;;
|
|
192 ;;; ----------------------------------------
|
|
193 ;;;
|
|
194 ;;;
|
|
195 ;;; # Configuration file for the color ls utility
|
|
196 ;;; # This file goes in the /etc directory, and must be world readable.
|
|
197 ;;; # You can copy this file to .dir_colors in your $HOME directory to
|
|
198 ;;; # override the system defaults.
|
|
199 ;;;
|
|
200 ;;; # COLOR needs one of these arguments: 'tty' colorizes output to ttys, but
|
|
201 ;;; # not pipes. 'all' adds color characters to all output. 'none' shuts
|
|
202 ;;; # colorization off.
|
|
203 ;;; COLOR tty
|
|
204 ;;; OPTIONS -F
|
|
205 ;;;
|
|
206 ;;; # Below, there should be one TERM entry for each termtype that is
|
|
207 ;;; # colorizable
|
|
208 ;;; TERM eterm
|
|
209 ;;;
|
|
210 ;;; # EIGHTBIT, followed by '1' for on, '0' for off. (8-bit output)
|
|
211 ;;; EIGHTBIT 1
|
|
212 ;;;
|
|
213 ;;; # Below are the color init strings for the basic file types. A color init
|
|
214 ;;; # string consists of one or more of the following numeric codes:
|
|
215 ;;; # Attribute codes:
|
|
216 ;;; # 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed
|
|
217 ;;; # Text color codes:
|
|
218 ;;; # 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white
|
|
219 ;;; # Background color codes:
|
|
220 ;;; # 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white
|
|
221 ;;; NORMAL 00 # global default, although everything should be something.
|
|
222 ;;; FILE 00 # normal file
|
|
223 ;;; DIR 00;37 # directory
|
|
224 ;;; LINK 00;36 # symbolic link
|
|
225 ;;; FIFO 00;37 # pipe
|
|
226 ;;; SOCK 40;35 # socket
|
|
227 ;;; BLK 33;01 # block device driver
|
|
228 ;;; CHR 33;01 # character device driver
|
|
229 ;;;
|
|
230 ;;; # This is for files with execute permission:
|
|
231 ;;; EXEC 00;32
|
|
232 ;;;
|
|
233 ;;; # List any file extensions like '.gz' or '.tar' that you would like ls
|
|
234 ;;; # to colorize below. Put the extension, a space, and the color init
|
|
235 ;;; # string. (and any comments you want to add after a '#')
|
|
236 ;;; .tar 01;33 # archives or compressed
|
|
237 ;;; .tgz 01;33
|
|
238 ;;; .arj 01;33
|
|
239 ;;; .taz 01;33
|
|
240 ;;; .lzh 01;33
|
|
241 ;;; .zip 01;33
|
|
242 ;;; .z 01;33
|
|
243 ;;; .Z 01;33
|
|
244 ;;; .gz 01;33
|
|
245 ;;; .jpg 01;35 # image formats
|
|
246 ;;; .gif 01;35
|
|
247 ;;; .bmp 01;35
|
|
248 ;;; .xbm 01;35
|
|
249 ;;; .xpm 01;35
|
|
250 ;;;
|
|
251 ;;;
|
|
252 ;;; ----------------------------------------
|
|
253 ;;;
|
|
254 ;;; Notice: for directory/host/user tracking you need to have something
|
|
255 ;;; like this in your shell startup script ( this is for tcsh but should
|
|
256 ;;; be quite easy to port to other shells )
|
|
257 ;;;
|
|
258 ;;; ----------------------------------------
|
|
259 ;;;
|
|
260 ;;;
|
|
261 ;;; set os = `uname`
|
|
262 ;;; set host = `hostname`
|
|
263 ;;; set date = `date`
|
|
264 ;;;
|
|
265 ;;; # su does not change this but I'd like it to
|
|
266 ;;;
|
|
267 ;;; set user = `whoami`
|
|
268 ;;;
|
|
269 ;;; # ...
|
|
270 ;;;
|
|
271 ;;; if ( eterm =~ $TERM ) then
|
|
272 ;;;
|
|
273 ;;; echo --------------------------------------------------------------
|
|
274 ;;; echo Hello $user
|
|
275 ;;; echo Today is $date
|
|
276 ;;; echo We are on $host running $os under Emacs term mode
|
|
277 ;;; echo --------------------------------------------------------------
|
|
278 ;;;
|
|
279 ;;; setenv EDITOR emacsclient
|
|
280 ;;;
|
|
281 ;;; # Notice: $host and $user have been set before to 'hostname' and 'whoami'
|
|
282 ;;; # this is necessary because, f.e., certain versions of 'su' do not change
|
|
283 ;;; # $user, YMMV: if you don't want to fiddle with them define a couple
|
|
284 ;;; # of new variables and use these instead.
|
|
285 ;;; # NOTICE that there is a space between "AnSiT?" and $whatever NOTICE
|
|
286 ;;;
|
|
287 ;;; # These are because we want the real cwd in the messages, not the login
|
|
288 ;;; # time one !
|
|
289 ;;;
|
|
290 ;;; set cwd_hack='$cwd'
|
|
291 ;;; set host_hack='$host'
|
|
292 ;;; set user_hack='$user'
|
|
293 ;;;
|
|
294 ;;; # Notice that the ^[ character is an ESC, not two chars. You can
|
|
295 ;;; # get it in various ways, for example by typing
|
|
296 ;;; # echo -e '\033' > escape.file
|
|
297 ;;; # or by using your favourite editor
|
|
298 ;;;
|
|
299 ;;; foreach temp (cd pushd)
|
|
300 ;;; alias $temp "$temp \!* ; echo 'AnSiTc' $cwd_hack"
|
|
301 ;;; end
|
|
302 ;;; alias popd 'popd ;echo "AnSiTc" $cwd'
|
|
303 ;;;
|
|
304 ;;; # Every command that can modify the user/host/directory should be aliased
|
|
305 ;;; # as follows for the tracking mechanism to work.
|
|
306 ;;;
|
|
307 ;;; foreach temp ( rlogin telnet rsh sh ksh csh tcsh zsh bash tcl su )
|
|
308 ;;; alias $temp "$temp \!* ; echo 'AnSiTh' $host_hack ; \
|
|
309 ;;; echo 'AnSiTu' $user_hack ;echo 'AnSiTc' $cwd_hack"
|
|
310 ;;; end
|
|
311 ;;;
|
|
312 ;;; # Start up & use color ls
|
|
313 ;;;
|
|
314 ;;; echo "AnSiTh" $host
|
|
315 ;;; echo "AnSiTu" $user
|
|
316 ;;; echo "AnSiTc" $cwd
|
|
317 ;;;
|
|
318 ;;; # some housekeeping
|
|
319 ;;;
|
|
320 ;;; unset cwd_hack
|
|
321 ;;; unset host_hack
|
|
322 ;;; unset user_hack
|
|
323 ;;; unset temp
|
|
324 ;;;
|
|
325 ;;; eval `/bin/dircolors /home/marco/.emacs_dircolors`
|
|
326 ;;; endif
|
|
327 ;;;
|
|
328 ;;; # ...
|
|
329 ;;;
|
|
330 ;;; # Let's not clutter user space
|
|
331 ;;;
|
|
332 ;;; unset os
|
|
333 ;;; unset date
|
|
334 ;;;
|
|
335 ;;;
|
|
336
|
|
337 ;;; Original Commentary:
|
|
338 ;;; --------------------
|
9509
|
339
|
14169
|
340 ;; The changelog is at the end of this file.
|
9509
|
341
|
14169
|
342 ;; Please send me bug reports, bug fixes, and extensions, so that I can
|
|
343 ;; merge them into the master source.
|
|
344 ;; - Per Bothner (bothner@cygnus.com)
|
9509
|
345
|
14169
|
346 ;; This file defines a general command-interpreter-in-a-buffer package
|
17283
|
347 ;; (term mode). The idea is that you can build specific process-in-a-buffer
|
14169
|
348 ;; modes on top of term mode -- e.g., lisp, shell, scheme, T, soar, ....
|
17283
|
349 ;; This way, all these specific packages share a common base functionality,
|
14169
|
350 ;; and a common set of bindings, which makes them easier to use (and
|
|
351 ;; saves code, implementation time, etc., etc.).
|
9509
|
352
|
14169
|
353 ;; For hints on converting existing process modes (e.g., tex-mode,
|
|
354 ;; background, dbx, gdb, kermit, prolog, telnet) to use term-mode
|
|
355 ;; instead of shell-mode, see the notes at the end of this file.
|
9509
|
356
|
|
357
|
14169
|
358 ;; Brief Command Documentation:
|
|
359 ;;============================================================================
|
|
360 ;; Term Mode Commands: (common to all derived modes, like cmushell & cmulisp
|
|
361 ;; mode)
|
|
362 ;;
|
|
363 ;; m-p term-previous-input Cycle backwards in input history
|
|
364 ;; m-n term-next-input Cycle forwards
|
|
365 ;; m-r term-previous-matching-input Previous input matching a regexp
|
|
366 ;; m-s comint-next-matching-input Next input that matches
|
|
367 ;; return term-send-input
|
|
368 ;; c-c c-a term-bol Beginning of line; skip prompt.
|
|
369 ;; c-d term-delchar-or-maybe-eof Delete char unless at end of buff.
|
|
370 ;; c-c c-u term-kill-input ^u
|
|
371 ;; c-c c-w backward-kill-word ^w
|
|
372 ;; c-c c-c term-interrupt-subjob ^c
|
|
373 ;; c-c c-z term-stop-subjob ^z
|
|
374 ;; c-c c-\ term-quit-subjob ^\
|
|
375 ;; c-c c-o term-kill-output Delete last batch of process output
|
|
376 ;; c-c c-r term-show-output Show last batch of process output
|
|
377 ;; c-c c-h term-dynamic-list-input-ring List input history
|
|
378 ;;
|
|
379 ;; Not bound by default in term-mode
|
|
380 ;; term-send-invisible Read a line w/o echo, and send to proc
|
|
381 ;; (These are bound in shell-mode)
|
|
382 ;; term-dynamic-complete Complete filename at point.
|
|
383 ;; term-dynamic-list-completions List completions in help buffer.
|
|
384 ;; term-replace-by-expanded-filename Expand and complete filename at point;
|
|
385 ;; replace with expanded/completed name.
|
|
386 ;; term-kill-subjob No mercy.
|
|
387 ;; term-show-maximum-output Show as much output as possible.
|
|
388 ;; term-continue-subjob Send CONT signal to buffer's process
|
17283
|
389 ;; group. Useful if you accidentally
|
14169
|
390 ;; suspend your process (with C-c C-z).
|
9509
|
391
|
17283
|
392 ;; term-mode-hook is the term mode hook. Basically for your keybindings.
|
14169
|
393 ;; term-load-hook is run after loading in this package.
|
9509
|
394
|
38414
|
395 ;;; Code:
|
9509
|
396
|
14169
|
397 ;; This is passed to the inferior in the EMACS environment variable,
|
|
398 ;; so it is important to increase it if there are protocol-relevant changes.
|
57123
|
399 (defconst term-protocol-version "0.96")
|
9509
|
400
|
25330
|
401 (eval-when-compile
|
|
402 (require 'ange-ftp))
|
9509
|
403 (require 'ring)
|
|
404 (require 'ehelp)
|
17407
|
405
|
|
406 (defgroup term nil
|
64024
|
407 "General command interpreter in a window."
|
82304
|
408 :group 'processes)
|
17407
|
409
|
9509
|
410
|
|
411 ;;; Buffer Local Variables:
|
|
412 ;;;============================================================================
|
|
413 ;;; Term mode buffer local variables:
|
|
414 ;;; term-prompt-regexp - string term-bol uses to match prompt.
|
|
415 ;;; term-delimiter-argument-list - list For delimiters and arguments
|
|
416 ;;; term-last-input-start - marker Handy if inferior always echoes
|
|
417 ;;; term-last-input-end - marker For term-kill-output command
|
10671
|
418 ;; For the input history mechanism:
|
|
419 (defvar term-input-ring-size 32 "Size of input history ring.")
|
|
420 ;;; term-input-ring-size - integer
|
|
421 ;;; term-input-ring - ring
|
9509
|
422 ;;; term-input-ring-index - number ...
|
|
423 ;;; term-input-autoexpand - symbol ...
|
|
424 ;;; term-input-ignoredups - boolean ...
|
|
425 ;;; term-last-input-match - string ...
|
|
426 ;;; term-dynamic-complete-functions - hook For the completion mechanism
|
|
427 ;;; term-completion-fignore - list ...
|
17283
|
428 ;;; term-get-old-input - function Hooks for specific
|
9509
|
429 ;;; term-input-filter-functions - hook process-in-a-buffer
|
|
430 ;;; term-input-filter - function modes.
|
|
431 ;;; term-input-send - function
|
|
432 ;;; term-scroll-to-bottom-on-output - symbol ...
|
|
433 ;;; term-scroll-show-maximum-output - boolean...
|
10671
|
434 (defvar term-height) ;; Number of lines in window.
|
|
435 (defvar term-width) ;; Number of columns in window.
|
|
436 (defvar term-home-marker) ;; Marks the "home" position for cursor addressing.
|
|
437 (defvar term-saved-home-marker nil) ;; When using alternate sub-buffer,
|
|
438 ;; contains saved term-home-marker from original sub-buffer .
|
|
439 (defvar term-start-line-column 0) ;; (current-column) at start of screen line,
|
|
440 ;; or nil if unknown.
|
|
441 (defvar term-current-column 0) ;; If non-nil, is cache for (current-column).
|
|
442 (defvar term-current-row 0) ;; Current vertical row (relative to home-marker)
|
|
443 ;; or nil if unknown.
|
|
444 (defvar term-insert-mode nil)
|
|
445 (defvar term-vertical-motion)
|
|
446 (defvar term-terminal-state 0) ;; State of the terminal emulator:
|
|
447 ;; state 0: Normal state
|
|
448 ;; state 1: Last character was a graphic in the last column.
|
|
449 ;; If next char is graphic, first move one column right
|
|
450 ;; (and line warp) before displaying it.
|
|
451 ;; This emulates (more or less) the behavior of xterm.
|
|
452 ;; state 2: seen ESC
|
|
453 ;; state 3: seen ESC [ (or ESC [ ?)
|
|
454 ;; state 4: term-terminal-parameter contains pending output.
|
|
455 (defvar term-kill-echo-list nil) ;; A queue of strings whose echo
|
|
456 ;; we want suppressed.
|
|
457 (defvar term-terminal-parameter)
|
|
458 (defvar term-terminal-previous-parameter)
|
57123
|
459 (defvar term-current-face 'default)
|
10671
|
460 (defvar term-scroll-start 0) ;; Top-most line (inclusive) of scrolling region.
|
|
461 (defvar term-scroll-end) ;; Number of line (zero-based) after scrolling region.
|
|
462 (defvar term-pager-count nil) ;; If nil, paging is disabled.
|
|
463 ;; Otherwise, number of lines before we need to page.
|
|
464 (defvar term-saved-cursor nil)
|
|
465 (defvar term-command-hook)
|
|
466 (defvar term-log-buffer nil)
|
|
467 (defvar term-scroll-with-delete nil) ;; term-scroll-with-delete is t if
|
|
468 ;; forward scrolling should be implemented by delete to
|
|
469 ;; top-most line(s); and nil if scrolling should be implemented
|
78492
|
470 ;; by moving term-home-marker. It is set to t if there is a
|
10671
|
471 ;; (non-default) scroll-region OR the alternate buffer is used.
|
10933
|
472 (defvar term-pending-delete-marker) ;; New user input in line mode needs to
|
|
473 ;; be deleted, because it gets echoed by the inferior.
|
|
474 ;; To reduce flicker, we defer the delete until the next output.
|
10671
|
475 (defvar term-old-mode-map nil) ;; Saves the old keymap when in char mode.
|
|
476 (defvar term-old-mode-line-format) ;; Saves old mode-line-format while paging.
|
|
477 (defvar term-pager-old-local-map nil) ;; Saves old keymap while paging.
|
|
478 (defvar term-pager-old-filter) ;; Saved process-filter while paging.
|
9509
|
479
|
17407
|
480 (defcustom explicit-shell-file-name nil
|
|
481 "*If non-nil, is file name to use for explicitly requested inferior shell."
|
|
482 :type '(choice (const nil) file)
|
|
483 :group 'term)
|
9509
|
484
|
|
485 (defvar term-prompt-regexp "^"
|
63508
|
486 "Regexp to recognize prompts in the inferior process.
|
9509
|
487 Defaults to \"^\", the null string at BOL.
|
|
488
|
|
489 Good choices:
|
|
490 Canonical Lisp: \"^[^> \\n]*>+:? *\" (Lucid, franz, kcl, T, cscheme, oaklisp)
|
|
491 Lucid Common Lisp: \"^\\\\(>\\\\|\\\\(->\\\\)+\\\\) *\"
|
|
492 franz: \"^\\\\(->\\\\|<[0-9]*>:\\\\) *\"
|
|
493 kcl: \"^>+ *\"
|
|
494 shell: \"^[^#$%>\\n]*[#$%>] *\"
|
|
495 T: \"^>+ *\"
|
|
496
|
|
497 This is a good thing to set in mode hooks.")
|
|
498
|
|
499 (defvar term-delimiter-argument-list ()
|
63508
|
500 "List of characters to recognize as separate arguments in input.
|
9509
|
501 Strings comprising a character in this list will separate the arguments
|
|
502 surrounding them, and also be regarded as arguments in their own right (unlike
|
|
503 whitespace). See `term-arguments'.
|
|
504 Defaults to the empty list.
|
|
505
|
23311
|
506 For shells, a good value is (?\\| ?& ?< ?> ?\\( ?\\) ?\\;).
|
9509
|
507
|
|
508 This is a good thing to set in mode hooks.")
|
|
509
|
17407
|
510 (defcustom term-input-autoexpand nil
|
9509
|
511 "*If non-nil, expand input command history references on completion.
|
|
512 This mirrors the optional behavior of tcsh (its autoexpand and histlit).
|
|
513
|
|
514 If the value is `input', then the expansion is seen on input.
|
|
515 If the value is `history', then the expansion is only when inserting
|
|
516 into the buffer's input ring. See also `term-magic-space' and
|
|
517 `term-dynamic-complete'.
|
|
518
|
17407
|
519 This variable is buffer-local."
|
|
520 :type '(choice (const nil) (const t) (const input) (const history))
|
|
521 :group 'term)
|
|
522
|
|
523 (defcustom term-input-ignoredups nil
|
9509
|
524 "*If non-nil, don't add input matching the last on the input ring.
|
|
525 This mirrors the optional behavior of bash.
|
|
526
|
17407
|
527 This variable is buffer-local."
|
|
528 :type 'boolean
|
|
529 :group 'term)
|
|
530
|
|
531 (defcustom term-input-ring-file-name nil
|
9509
|
532 "*If non-nil, name of the file to read/write input history.
|
|
533 See also `term-read-input-ring' and `term-write-input-ring'.
|
|
534
|
17407
|
535 This variable is buffer-local, and is a good thing to set in mode hooks."
|
|
536 :type 'boolean
|
|
537 :group 'term)
|
|
538
|
|
539 (defcustom term-scroll-to-bottom-on-output nil
|
9509
|
540 "*Controls whether interpreter output causes window to scroll.
|
|
541 If nil, then do not scroll. If t or `all', scroll all windows showing buffer.
|
|
542 If `this', scroll only the selected window.
|
|
543 If `others', scroll only those that are not the selected window.
|
|
544
|
|
545 The default is nil.
|
|
546
|
|
547 See variable `term-scroll-show-maximum-output'.
|
17407
|
548 This variable is buffer-local."
|
|
549 :type 'boolean
|
|
550 :group 'term)
|
|
551
|
|
552 (defcustom term-scroll-show-maximum-output nil
|
9509
|
553 "*Controls how interpreter output causes window to scroll.
|
|
554 If non-nil, then show the maximum output when the window is scrolled.
|
|
555
|
|
556 See variable `term-scroll-to-bottom-on-output'.
|
17407
|
557 This variable is buffer-local."
|
|
558 :type 'boolean
|
|
559 :group 'term)
|
9509
|
560
|
|
561 ;; Where gud-display-frame should put the debugging arrow. This is
|
|
562 ;; set by the marker-filter, which scans the debugger's output for
|
|
563 ;; indications of the current pc.
|
|
564 (defvar term-pending-frame nil)
|
|
565
|
|
566 ;;; Here are the per-interpreter hooks.
|
|
567 (defvar term-get-old-input (function term-get-old-input-default)
|
|
568 "Function that submits old text in term mode.
|
|
569 This function is called when return is typed while the point is in old text.
|
|
570 It returns the text to be submitted as process input. The default is
|
63558
|
571 `term-get-old-input-default', which grabs the current line, and strips off
|
|
572 leading text matching `term-prompt-regexp'.")
|
9509
|
573
|
|
574 (defvar term-dynamic-complete-functions
|
|
575 '(term-replace-by-expanded-history term-dynamic-complete-filename)
|
|
576 "List of functions called to perform completion.
|
|
577 Functions should return non-nil if completion was performed.
|
|
578 See also `term-dynamic-complete'.
|
|
579
|
|
580 This is a good thing to set in mode hooks.")
|
|
581
|
|
582 (defvar term-input-filter
|
|
583 (function (lambda (str) (not (string-match "\\`\\s *\\'" str))))
|
|
584 "Predicate for filtering additions to input history.
|
|
585 Only inputs answering true to this function are saved on the input
|
63558
|
586 history list. Default is to save anything that isn't all whitespace.")
|
9509
|
587
|
|
588 (defvar term-input-filter-functions '()
|
|
589 "Functions to call before input is sent to the process.
|
|
590 These functions get one argument, a string containing the text to send.
|
|
591
|
|
592 This variable is buffer-local.")
|
|
593
|
|
594 (defvar term-input-sender (function term-simple-send)
|
|
595 "Function to actually send to PROCESS the STRING submitted by user.
|
63558
|
596 Usually this is just `term-simple-send', but if your mode needs to
|
17283
|
597 massage the input string, this is your hook. This is called from
|
63558
|
598 the user command `term-send-input'. `term-simple-send' just sends
|
9509
|
599 the string plus a newline.")
|
|
600
|
17407
|
601 (defcustom term-eol-on-send t
|
10933
|
602 "*Non-nil means go to the end of the line before sending input.
|
17407
|
603 See `term-send-input'."
|
|
604 :type 'boolean
|
|
605 :group 'term)
|
|
606
|
|
607 (defcustom term-mode-hook '()
|
63558
|
608 "Called upon entry into term mode.
|
17407
|
609 This is run before the process is cranked up."
|
|
610 :type 'hook
|
|
611 :group 'term)
|
|
612
|
|
613 (defcustom term-exec-hook '()
|
63558
|
614 "Called each time a process is exec'd by `term-exec'.
|
9509
|
615 This is called after the process is cranked up. It is useful for things that
|
63558
|
616 must be done each time a process is executed in a term mode buffer (e.g.,
|
|
617 `process-kill-without-query'). In contrast, `term-mode-hook' is only
|
17407
|
618 executed once when the buffer is created."
|
|
619 :type 'hook
|
|
620 :group 'term)
|
9509
|
621
|
92493
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
622 (defvar term-mode-map
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
623 (let ((map (make-sparse-keymap)))
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
624 (define-key map "\ep" 'term-previous-input)
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
625 (define-key map "\en" 'term-next-input)
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
626 (define-key map "\er" 'term-previous-matching-input)
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
627 (define-key map "\es" 'term-next-matching-input)
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
628 (unless (featurep 'xemacs)
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
629 (define-key map [?\A-\M-r]
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
630 'term-previous-matching-input-from-input)
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
631 (define-key map [?\A-\M-s] 'term-next-matching-input-from-input))
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
632 (define-key map "\e\C-l" 'term-show-output)
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
633 (define-key map "\C-m" 'term-send-input)
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
634 (define-key map "\C-d" 'term-delchar-or-maybe-eof)
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
635 (define-key map "\C-c\C-a" 'term-bol)
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
636 (define-key map "\C-c\C-u" 'term-kill-input)
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
637 (define-key map "\C-c\C-w" 'backward-kill-word)
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
638 (define-key map "\C-c\C-c" 'term-interrupt-subjob)
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
639 (define-key map "\C-c\C-z" 'term-stop-subjob)
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
640 (define-key map "\C-c\C-\\" 'term-quit-subjob)
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
641 (define-key map "\C-c\C-m" 'term-copy-old-input)
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
642 (define-key map "\C-c\C-o" 'term-kill-output)
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
643 (define-key map "\C-c\C-r" 'term-show-output)
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
644 (define-key map "\C-c\C-e" 'term-show-maximum-output)
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
645 (define-key map "\C-c\C-l" 'term-dynamic-list-input-ring)
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
646 (define-key map "\C-c\C-n" 'term-next-prompt)
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
647 (define-key map "\C-c\C-p" 'term-previous-prompt)
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
648 (define-key map "\C-c\C-d" 'term-send-eof)
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
649 (define-key map "\C-c\C-k" 'term-char-mode)
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
650 (define-key map "\C-c\C-j" 'term-line-mode)
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
651 (define-key map "\C-c\C-q" 'term-pager-toggle)
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
652
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
653 ;; ;; completion:
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
654 ;; (define-key map [menu-bar completion]
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
655 ;; (cons "Complete" (make-sparse-keymap "Complete")))
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
656 ;; (define-key map [menu-bar completion complete-expand]
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
657 ;; '("Expand File Name" . term-replace-by-expanded-filename))
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
658 ;; (define-key map [menu-bar completion complete-listing]
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
659 ;; '("File Completion Listing" . term-dynamic-list-filename-completions))
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
660 ;; (define-key map [menu-bar completion complete-file]
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
661 ;; '("Complete File Name" . term-dynamic-complete-filename))
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
662 ;; (define-key map [menu-bar completion complete]
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
663 ;; '("Complete Before Point" . term-dynamic-complete))
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
664 ;; ;; Put them in the menu bar:
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
665 ;; (setq menu-bar-final-items (append '(terminal completion inout signals)
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
666 ;; menu-bar-final-items))
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
667 map))
|
402ee2cfca27
* bindings.el (mode-line-remote): Add mouse-face. Improve tooltip.
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
668
|
9509
|
669 (defvar term-raw-map nil
|
|
670 "Keyboard map for sending characters directly to the inferior process.")
|
12229
|
671 (defvar term-escape-char nil
|
63558
|
672 "Escape character for char sub-mode of term mode.
|
77169
8905fec7d280
(term-buffer-maximum-size, term-exec, term-escape-char, term-set-escape-char,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
673 Do not change it directly; use `term-set-escape-char' instead.")
|
9509
|
674 (defvar term-raw-escape-map nil)
|
|
675
|
|
676 (defvar term-pager-break-map nil)
|
|
677
|
|
678 (defvar term-ptyp t
|
|
679 "True if communications via pty; false if by pipe. Buffer local.
|
17283
|
680 This is to work around a bug in Emacs process signaling.")
|
9509
|
681
|
|
682 (defvar term-last-input-match ""
|
|
683 "Last string searched for by term input history search, for defaulting.
|
17283
|
684 Buffer local variable.")
|
9509
|
685
|
|
686 (defvar term-input-ring nil)
|
|
687 (defvar term-last-input-start)
|
|
688 (defvar term-last-input-end)
|
|
689 (defvar term-input-ring-index nil
|
|
690 "Index of last matched history element.")
|
|
691 (defvar term-matching-input-from-input-string ""
|
|
692 "Input previously used to match input history.")
|
|
693 ; This argument to set-process-filter disables reading from the process,
|
17283
|
694 ; assuming this is Emacs 19.20 or newer.
|
9509
|
695 (defvar term-pager-filter t)
|
|
696
|
|
697 (put 'term-replace-by-expanded-history 'menu-enable 'term-input-autoexpand)
|
|
698 (put 'term-input-ring 'permanent-local t)
|
|
699 (put 'term-input-ring-index 'permanent-local t)
|
|
700 (put 'term-input-autoexpand 'permanent-local t)
|
|
701 (put 'term-input-filter-functions 'permanent-local t)
|
|
702 (put 'term-scroll-to-bottom-on-output 'permanent-local t)
|
|
703 (put 'term-scroll-show-maximum-output 'permanent-local t)
|
|
704 (put 'term-ptyp 'permanent-local t)
|
|
705
|
|
706 (defmacro term-in-char-mode () '(eq (current-local-map) term-raw-map))
|
|
707 (defmacro term-in-line-mode () '(not (term-in-char-mode)))
|
10671
|
708 ;; True if currently doing PAGER handling.
|
|
709 (defmacro term-pager-enabled () 'term-pager-count)
|
|
710 (defmacro term-handling-pager () 'term-pager-old-local-map)
|
|
711 (defmacro term-using-alternate-sub-buffer () 'term-saved-home-marker)
|
|
712
|
|
713 (defvar term-signals-menu)
|
|
714 (defvar term-terminal-menu)
|
9509
|
715
|
17283
|
716 ;;; Let's silence the byte-compiler -mm
|
|
717 (defvar term-ansi-at-host nil)
|
|
718 (defvar term-ansi-at-dir nil)
|
|
719 (defvar term-ansi-at-user nil)
|
|
720 (defvar term-ansi-at-message nil)
|
|
721 (defvar term-ansi-at-save-user nil)
|
|
722 (defvar term-ansi-at-save-pwd nil)
|
|
723 (defvar term-ansi-at-save-anon nil)
|
61481
d4014c213e7e
* term.el (term-ansi-current-bold, term-ansi-current-underline)
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
724 (defvar term-ansi-current-bold nil)
|
17283
|
725 (defvar term-ansi-current-color 0)
|
61481
d4014c213e7e
* term.el (term-ansi-current-bold, term-ansi-current-underline)
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
726 (defvar term-ansi-face-already-done nil)
|
17283
|
727 (defvar term-ansi-current-bg-color 0)
|
61481
d4014c213e7e
* term.el (term-ansi-current-bold, term-ansi-current-underline)
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
728 (defvar term-ansi-current-underline nil)
|
d4014c213e7e
* term.el (term-ansi-current-bold, term-ansi-current-underline)
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
729 (defvar term-ansi-current-reverse nil)
|
d4014c213e7e
* term.el (term-ansi-current-bold, term-ansi-current-underline)
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
730 (defvar term-ansi-current-invisible nil)
|
17283
|
731
|
|
732 ;;; Four should be enough, if you want more, just add. -mm
|
|
733 (defvar term-terminal-more-parameters 0)
|
|
734 (defvar term-terminal-previous-parameter-2 -1)
|
|
735 (defvar term-terminal-previous-parameter-3 -1)
|
|
736 (defvar term-terminal-previous-parameter-4 -1)
|
|
737 ;;;
|
|
738
|
|
739 ;;; faces -mm
|
|
740
|
78414
781746b1e97f
Honor term-default-fg-color and term-default-bg-color settings when modifying term-current-face.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
diff
changeset
|
741 (defcustom term-default-fg-color (face-foreground term-current-face)
|
49591
|
742 "Default color for foreground in `term'."
|
|
743 :group 'term
|
|
744 :type 'string)
|
|
745
|
78414
781746b1e97f
Honor term-default-fg-color and term-default-bg-color settings when modifying term-current-face.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
diff
changeset
|
746 (defcustom term-default-bg-color (face-background term-current-face)
|
49591
|
747 "Default color for background in `term'."
|
|
748 :group 'term
|
|
749 :type 'string)
|
|
750
|
61830
|
751 ;;; Use the same colors that xterm uses, see `xterm-standard-colors'.
|
49591
|
752 (defvar ansi-term-color-vector
|
61830
|
753 [unspecified "black" "red3" "green3" "yellow3" "blue2"
|
|
754 "magenta3" "cyan3" "white"])
|
17283
|
755
|
|
756 ;;; Inspiration came from comint.el -mm
|
|
757 (defvar term-buffer-maximum-size 2048
|
|
758 "*The maximum size in lines for term buffers.
|
|
759 Term buffers are truncated from the top to be no greater than this number.
|
77169
8905fec7d280
(term-buffer-maximum-size, term-exec, term-escape-char, term-set-escape-char,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
760 Notice that a setting of 0 means \"don't truncate anything\". This variable
|
17283
|
761 is buffer-local.")
|
|
762 ;;;
|
49591
|
763
|
71054
|
764 (when (featurep 'xemacs)
|
|
765 (defvar term-terminal-menu
|
|
766 '("Terminal"
|
|
767 [ "Character mode" term-char-mode (term-in-line-mode)]
|
|
768 [ "Line mode" term-line-mode (term-in-char-mode)]
|
|
769 [ "Enable paging" term-pager-toggle (not term-pager-count)]
|
|
770 [ "Disable paging" term-pager-toggle term-pager-count])))
|
9509
|
771
|
|
772 ;; Menu bars:
|
71054
|
773 (unless (featurep 'xemacs)
|
10671
|
774 ;; terminal:
|
|
775 (let (newmap)
|
|
776 (setq newmap (make-sparse-keymap "Terminal"))
|
|
777 (define-key newmap [terminal-pager-enable]
|
93674
|
778 '(menu-item "Enable paging" term-fake-pager-enable
|
|
779 :help "Enable paging feature"))
|
10671
|
780 (define-key newmap [terminal-pager-disable]
|
93674
|
781 '(menu-item "Disable paging" term-fake-pager-disable
|
|
782 :help "Disable paging feature"))
|
10671
|
783 (define-key newmap [terminal-char-mode]
|
93674
|
784 '(menu-item "Character mode" term-char-mode
|
|
785 :help "Switch to char (raw) sub-mode of term mode"))
|
10671
|
786 (define-key newmap [terminal-line-mode]
|
93674
|
787 '(menu-item "Line mode" term-line-mode
|
93807
|
788 :help "Switch to line (cooked) sub-mode of term mode"))
|
15420
|
789 (setq term-terminal-menu (cons "Terminal" newmap))
|
10671
|
790
|
|
791 ;; completion: (line mode only)
|
|
792 (defvar term-completion-menu (make-sparse-keymap "Complete"))
|
17283
|
793 (define-key term-mode-map [menu-bar completion]
|
10671
|
794 (cons "Complete" term-completion-menu))
|
|
795 (define-key term-completion-menu [complete-expand]
|
|
796 '("Expand File Name" . term-replace-by-expanded-filename))
|
|
797 (define-key term-completion-menu [complete-listing]
|
|
798 '("File Completion Listing" . term-dynamic-list-filename-completions))
|
|
799 (define-key term-completion-menu [menu-bar completion complete-file]
|
|
800 '("Complete File Name" . term-dynamic-complete-filename))
|
|
801 (define-key term-completion-menu [menu-bar completion complete]
|
|
802 '("Complete Before Point" . term-dynamic-complete))
|
9509
|
803
|
10671
|
804 ;; Input history: (line mode only)
|
|
805 (defvar term-inout-menu (make-sparse-keymap "In/Out"))
|
17283
|
806 (define-key term-mode-map [menu-bar inout]
|
10671
|
807 (cons "In/Out" term-inout-menu))
|
|
808 (define-key term-inout-menu [kill-output]
|
|
809 '("Kill Current Output Group" . term-kill-output))
|
|
810 (define-key term-inout-menu [next-prompt]
|
|
811 '("Forward Output Group" . term-next-prompt))
|
|
812 (define-key term-inout-menu [previous-prompt]
|
|
813 '("Backward Output Group" . term-previous-prompt))
|
|
814 (define-key term-inout-menu [show-maximum-output]
|
|
815 '("Show Maximum Output" . term-show-maximum-output))
|
|
816 (define-key term-inout-menu [show-output]
|
|
817 '("Show Current Output Group" . term-show-output))
|
|
818 (define-key term-inout-menu [kill-input]
|
|
819 '("Kill Current Input" . term-kill-input))
|
|
820 (define-key term-inout-menu [copy-input]
|
|
821 '("Copy Old Input" . term-copy-old-input))
|
|
822 (define-key term-inout-menu [forward-matching-history]
|
|
823 '("Forward Matching Input..." . term-forward-matching-input))
|
|
824 (define-key term-inout-menu [backward-matching-history]
|
|
825 '("Backward Matching Input..." . term-backward-matching-input))
|
|
826 (define-key term-inout-menu [next-matching-history]
|
|
827 '("Next Matching Input..." . term-next-matching-input))
|
|
828 (define-key term-inout-menu [previous-matching-history]
|
|
829 '("Previous Matching Input..." . term-previous-matching-input))
|
|
830 (define-key term-inout-menu [next-matching-history-from-input]
|
|
831 '("Next Matching Current Input" . term-next-matching-input-from-input))
|
|
832 (define-key term-inout-menu [previous-matching-history-from-input]
|
17283
|
833 '("Previous Matching Current Input" .
|
|
834 term-previous-matching-input-from-input))
|
10671
|
835 (define-key term-inout-menu [next-history]
|
|
836 '("Next Input" . term-next-input))
|
|
837 (define-key term-inout-menu [previous-history]
|
|
838 '("Previous Input" . term-previous-input))
|
|
839 (define-key term-inout-menu [list-history]
|
|
840 '("List Input History" . term-dynamic-list-input-ring))
|
|
841 (define-key term-inout-menu [expand-history]
|
|
842 '("Expand History Before Point" . term-replace-by-expanded-history))
|
9509
|
843
|
10671
|
844 ;; Signals
|
|
845 (setq newmap (make-sparse-keymap "Signals"))
|
|
846 (define-key term-mode-map [menu-bar signals]
|
|
847 (setq term-signals-menu (cons "Signals" newmap)))
|
93674
|
848 (define-key newmap [eof]
|
|
849 '(menu-item "EOF" term-send-eof
|
|
850 :help "Send an EOF to the current buffer's process"))
|
|
851 (define-key newmap [kill]
|
|
852 '(menu-item "KILL" term-kill-subjob
|
|
853 :help "Send kill signal to the current subjob"))
|
|
854 (define-key newmap [quit]
|
|
855 '(menu-item "QUIT" term-quit-subjob
|
|
856 :help "Send quit signal to the current subjob."))
|
|
857 (define-key newmap [cont]
|
|
858 '(menu-item "CONT" term-continue-subjob
|
|
859 :help "Send CONT signal to process buffer's process group"))
|
|
860 (define-key newmap [stop]
|
|
861 '(menu-item "STOP" term-stop-subjob
|
|
862 :help "Stop the current subjob"))
|
|
863 (define-key newmap [brk]
|
|
864 '(menu-item "BREAK" term-interrupt-subjob
|
|
865 :help "Interrupt the current subjob"))
|
71054
|
866 ))
|
49591
|
867
|
|
868 ;; Set up term-raw-map, etc.
|
|
869
|
|
870 (defun term-set-escape-char (c)
|
77169
8905fec7d280
(term-buffer-maximum-size, term-exec, term-escape-char, term-set-escape-char,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
871 "Change `term-escape-char' and keymaps that depend on it."
|
71054
|
872 (when term-escape-char
|
|
873 (define-key term-raw-map term-escape-char 'term-send-raw))
|
49591
|
874 (setq c (make-string 1 c))
|
|
875 (define-key term-raw-map c term-raw-escape-map)
|
|
876 ;; Define standard bindings in term-raw-escape-map
|
|
877 (define-key term-raw-escape-map "\C-v"
|
|
878 (lookup-key (current-global-map) "\C-v"))
|
|
879 (define-key term-raw-escape-map "\C-u"
|
|
880 (lookup-key (current-global-map) "\C-u"))
|
|
881 (define-key term-raw-escape-map c 'term-send-raw)
|
|
882 (define-key term-raw-escape-map "\C-q" 'term-pager-toggle)
|
|
883 ;; The keybinding for term-char-mode is needed by the menubar code.
|
|
884 (define-key term-raw-escape-map "\C-k" 'term-char-mode)
|
|
885 (define-key term-raw-escape-map "\C-j" 'term-line-mode)
|
|
886 ;; It's convenient to have execute-extended-command here.
|
|
887 (define-key term-raw-escape-map [?\M-x] 'execute-extended-command))
|
|
888
|
|
889 (let* ((map (make-keymap))
|
|
890 (esc-map (make-keymap))
|
|
891 (i 0))
|
|
892 (while (< i 128)
|
|
893 (define-key map (make-string 1 i) 'term-send-raw)
|
61830
|
894 ;; Avoid O and [. They are used in escape sequences for various keys.
|
63176
7a34bd511117
(term-mode, term-check-proc, term-input-sender, term-simple-send,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
895 (unless (or (eq i ?O) (eq i 91))
|
61830
|
896 (define-key esc-map (make-string 1 i) 'term-send-raw-meta))
|
49591
|
897 (setq i (1+ i)))
|
|
898 (define-key map "\e" esc-map)
|
|
899 (setq term-raw-map map)
|
|
900 (setq term-raw-escape-map
|
|
901 (copy-keymap (lookup-key (current-global-map) "\C-x")))
|
|
902
|
|
903 ;;; Added nearly all the 'grey keys' -mm
|
|
904
|
71054
|
905 (if (featurep 'xemacs)
|
|
906 (define-key term-raw-map [button2] 'term-mouse-paste)
|
|
907 (define-key term-raw-map [mouse-2] 'term-mouse-paste)
|
|
908 (define-key term-raw-map [menu-bar terminal] term-terminal-menu)
|
|
909 (define-key term-raw-map [menu-bar signals] term-signals-menu))
|
|
910 (define-key term-raw-map [up] 'term-send-up)
|
|
911 (define-key term-raw-map [down] 'term-send-down)
|
|
912 (define-key term-raw-map [right] 'term-send-right)
|
|
913 (define-key term-raw-map [left] 'term-send-left)
|
|
914 (define-key term-raw-map [delete] 'term-send-del)
|
|
915 (define-key term-raw-map [deletechar] 'term-send-del)
|
|
916 (define-key term-raw-map [backspace] 'term-send-backspace)
|
|
917 (define-key term-raw-map [home] 'term-send-home)
|
|
918 (define-key term-raw-map [end] 'term-send-end)
|
|
919 (define-key term-raw-map [insert] 'term-send-insert)
|
|
920 (define-key term-raw-map [S-prior] 'scroll-down)
|
|
921 (define-key term-raw-map [S-next] 'scroll-up)
|
|
922 (define-key term-raw-map [S-insert] 'term-paste)
|
|
923 (define-key term-raw-map [prior] 'term-send-prior)
|
|
924 (define-key term-raw-map [next] 'term-send-next))
|
49591
|
925
|
|
926 (term-set-escape-char ?\C-c)
|
54725
|
927
|
95841
|
928 (defvar overflow-newline-into-fringe)
|
|
929
|
54725
|
930 (defun term-window-width ()
|
|
931 (if (featurep 'xemacs)
|
|
932 (1- (window-width))
|
56965
|
933 (if (and window-system overflow-newline-into-fringe)
|
54725
|
934 (window-width)
|
|
935 (1- (window-width)))))
|
|
936
|
49591
|
937
|
|
938 (put 'term-mode 'mode-class 'special)
|
|
939
|
57234
|
940
|
|
941 ;;; Use this variable as a display table for `term-mode'.
|
|
942 (defvar term-display-table
|
|
943 (let ((dt (or (copy-sequence standard-display-table)
|
|
944 (make-display-table)))
|
|
945 i)
|
|
946 ;; avoid changing the display table for ^J
|
63176
7a34bd511117
(term-mode, term-check-proc, term-input-sender, term-simple-send,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
947 (setq i 0)
|
57234
|
948 (while (< i 10)
|
|
949 (aset dt i (vector i))
|
|
950 (setq i (1+ i)))
|
63176
7a34bd511117
(term-mode, term-check-proc, term-input-sender, term-simple-send,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
951 (setq i 11)
|
57234
|
952 (while (< i 32)
|
|
953 (aset dt i (vector i))
|
|
954 (setq i (1+ i)))
|
|
955 (setq i 128)
|
|
956 (while (< i 256)
|
|
957 (aset dt i (vector i))
|
|
958 (setq i (1+ i)))
|
|
959 dt))
|
|
960
|
49591
|
961 (defun term-mode ()
|
|
962 "Major mode for interacting with an inferior interpreter.
|
|
963 The interpreter name is same as buffer name, sans the asterisks.
|
|
964
|
|
965 There are two submodes: line mode and char mode. By default, you are
|
|
966 in char mode. In char sub-mode, each character (except
|
58486
|
967 `term-escape-char') is sent immediately to the subprocess.
|
|
968 The escape character is equivalent to the usual meaning of C-x.
|
49591
|
969
|
|
970 In line mode, you send a line of input at a time; use
|
|
971 \\[term-send-input] to send.
|
|
972
|
|
973 In line mode, this maintains an input history of size
|
|
974 `term-input-ring-size', and you can access it with the commands
|
|
975 \\[term-next-input], \\[term-previous-input], and
|
|
976 \\[term-dynamic-list-input-ring]. Input ring history expansion can be
|
|
977 achieved with the commands \\[term-replace-by-expanded-history] or
|
|
978 \\[term-magic-space]. Input ring expansion is controlled by the
|
|
979 variable `term-input-autoexpand', and addition is controlled by the
|
|
980 variable `term-input-ignoredups'.
|
|
981
|
|
982 Input to, and output from, the subprocess can cause the window to scroll to
|
|
983 the end of the buffer. See variables `term-scroll-to-bottom-on-input',
|
|
984 and `term-scroll-to-bottom-on-output'.
|
|
985
|
|
986 If you accidentally suspend your process, use \\[term-continue-subjob]
|
|
987 to continue it.
|
|
988
|
63176
7a34bd511117
(term-mode, term-check-proc, term-input-sender, term-simple-send,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
989 This mode can be customized to create specific modes for running
|
49591
|
990 particular subprocesses. This can be done by setting the hooks
|
|
991 `term-input-filter-functions', `term-input-filter',
|
|
992 `term-input-sender' and `term-get-old-input' to appropriate functions,
|
|
993 and the variable `term-prompt-regexp' to the appropriate regular
|
|
994 expression.
|
|
995
|
|
996 Commands in raw mode:
|
|
997
|
|
998 \\{term-raw-map}
|
|
999
|
|
1000 Commands in line mode:
|
|
1001
|
|
1002 \\{term-mode-map}
|
|
1003
|
|
1004 Entry to this mode runs the hooks on `term-mode-hook'."
|
|
1005 (interactive)
|
|
1006 ;; Do not remove this. All major modes must do this.
|
|
1007 (kill-all-local-variables)
|
|
1008 (setq major-mode 'term-mode)
|
|
1009 (setq mode-name "Term")
|
|
1010 (use-local-map term-mode-map)
|
57234
|
1011 ;; we do not want indent to sneak in any tabs
|
|
1012 (setq indent-tabs-mode nil)
|
|
1013 (setq buffer-display-table term-display-table)
|
49591
|
1014 (make-local-variable 'term-home-marker)
|
|
1015 (setq term-home-marker (copy-marker 0))
|
|
1016 (make-local-variable 'term-saved-home-marker)
|
|
1017 (make-local-variable 'term-height)
|
|
1018 (make-local-variable 'term-width)
|
54725
|
1019 (setq term-width (term-window-width))
|
49591
|
1020 (setq term-height (1- (window-height)))
|
|
1021 (make-local-variable 'term-terminal-parameter)
|
|
1022 (make-local-variable 'term-saved-cursor)
|
|
1023 (make-local-variable 'term-last-input-start)
|
|
1024 (setq term-last-input-start (make-marker))
|
|
1025 (make-local-variable 'term-last-input-end)
|
|
1026 (setq term-last-input-end (make-marker))
|
|
1027 (make-local-variable 'term-last-input-match)
|
|
1028 (setq term-last-input-match "")
|
|
1029 (make-local-variable 'term-prompt-regexp) ; Don't set; default
|
|
1030 (make-local-variable 'term-input-ring-size) ; ...to global val.
|
|
1031 (make-local-variable 'term-input-ring)
|
|
1032 (make-local-variable 'term-input-ring-file-name)
|
|
1033 (or (and (boundp 'term-input-ring) term-input-ring)
|
|
1034 (setq term-input-ring (make-ring term-input-ring-size)))
|
|
1035 (make-local-variable 'term-input-ring-index)
|
|
1036 (or (and (boundp 'term-input-ring-index) term-input-ring-index)
|
|
1037 (setq term-input-ring-index nil))
|
|
1038
|
|
1039 (make-local-variable 'term-command-hook)
|
|
1040 (setq term-command-hook (symbol-function 'term-command-hook))
|
|
1041
|
|
1042 ;;; I'm not sure these saves are necessary but, since I
|
|
1043 ;;; haven't tested the whole thing on a net connected machine with
|
|
1044 ;;; a properly configured ange-ftp, I've decided to be conservative
|
|
1045 ;;; and put them in. -mm
|
|
1046
|
|
1047 (make-local-variable 'term-ansi-at-host)
|
|
1048 (setq term-ansi-at-host (system-name))
|
|
1049
|
|
1050 (make-local-variable 'term-ansi-at-dir)
|
|
1051 (setq term-ansi-at-dir default-directory)
|
|
1052
|
|
1053 (make-local-variable 'term-ansi-at-message)
|
|
1054 (setq term-ansi-at-message nil)
|
|
1055
|
|
1056 ;;; For user tracking purposes -mm
|
|
1057 (make-local-variable 'ange-ftp-default-user)
|
|
1058 (make-local-variable 'ange-ftp-default-password)
|
|
1059 (make-local-variable 'ange-ftp-generate-anonymous-password)
|
|
1060
|
|
1061 ;;; You may want to have different scroll-back sizes -mm
|
|
1062 (make-local-variable 'term-buffer-maximum-size)
|
|
1063
|
|
1064 ;;; Of course these have to be buffer-local -mm
|
|
1065 (make-local-variable 'term-ansi-current-bold)
|
|
1066 (make-local-variable 'term-ansi-current-color)
|
|
1067 (make-local-variable 'term-ansi-face-already-done)
|
|
1068 (make-local-variable 'term-ansi-current-bg-color)
|
|
1069 (make-local-variable 'term-ansi-current-underline)
|
|
1070 (make-local-variable 'term-ansi-current-reverse)
|
|
1071 (make-local-variable 'term-ansi-current-invisible)
|
|
1072
|
68203
|
1073 (make-local-variable 'term-terminal-parameter)
|
|
1074 (make-local-variable 'term-terminal-previous-parameter)
|
|
1075 (make-local-variable 'term-terminal-previous-parameter-2)
|
|
1076 (make-local-variable 'term-terminal-previous-parameter-3)
|
|
1077 (make-local-variable 'term-terminal-previous-parameter-4)
|
|
1078 (make-local-variable 'term-terminal-more-parameters)
|
|
1079
|
49591
|
1080 (make-local-variable 'term-terminal-state)
|
|
1081 (make-local-variable 'term-kill-echo-list)
|
|
1082 (make-local-variable 'term-start-line-column)
|
|
1083 (make-local-variable 'term-current-column)
|
|
1084 (make-local-variable 'term-current-row)
|
|
1085 (make-local-variable 'term-log-buffer)
|
|
1086 (make-local-variable 'term-scroll-start)
|
|
1087 (make-local-variable 'term-scroll-end)
|
|
1088 (setq term-scroll-end term-height)
|
|
1089 (make-local-variable 'term-scroll-with-delete)
|
|
1090 (make-local-variable 'term-pager-count)
|
|
1091 (make-local-variable 'term-pager-old-local-map)
|
|
1092 (make-local-variable 'term-old-mode-map)
|
|
1093 (make-local-variable 'term-insert-mode)
|
|
1094 (make-local-variable 'term-dynamic-complete-functions)
|
|
1095 (make-local-variable 'term-completion-fignore)
|
|
1096 (make-local-variable 'term-get-old-input)
|
|
1097 (make-local-variable 'term-matching-input-from-input-string)
|
|
1098 (make-local-variable 'term-input-autoexpand)
|
|
1099 (make-local-variable 'term-input-ignoredups)
|
|
1100 (make-local-variable 'term-delimiter-argument-list)
|
|
1101 (make-local-variable 'term-input-filter-functions)
|
|
1102 (make-local-variable 'term-input-filter)
|
|
1103 (make-local-variable 'term-input-sender)
|
|
1104 (make-local-variable 'term-eol-on-send)
|
|
1105 (make-local-variable 'term-scroll-to-bottom-on-output)
|
|
1106 (make-local-variable 'term-scroll-show-maximum-output)
|
|
1107 (make-local-variable 'term-ptyp)
|
|
1108 (make-local-variable 'term-exec-hook)
|
|
1109 (make-local-variable 'term-vertical-motion)
|
|
1110 (make-local-variable 'term-pending-delete-marker)
|
|
1111 (setq term-pending-delete-marker (make-marker))
|
|
1112 (make-local-variable 'term-current-face)
|
78414
781746b1e97f
Honor term-default-fg-color and term-default-bg-color settings when modifying term-current-face.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
diff
changeset
|
1113 (setq term-current-face (list :background term-default-bg-color
|
781746b1e97f
Honor term-default-fg-color and term-default-bg-color settings when modifying term-current-face.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
diff
changeset
|
1114 :foreground term-default-fg-color))
|
49591
|
1115 (make-local-variable 'term-pending-frame)
|
|
1116 (setq term-pending-frame nil)
|
77169
8905fec7d280
(term-buffer-maximum-size, term-exec, term-escape-char, term-set-escape-char,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
1117 ;; Cua-mode's keybindings interfere with the term keybindings, disable it.
|
64323
|
1118 (set (make-local-variable 'cua-mode) nil)
|
62744
|
1119 (run-mode-hooks 'term-mode-hook)
|
71054
|
1120 (when (featurep 'xemacs)
|
|
1121 (set-buffer-menubar
|
|
1122 (append current-menubar (list term-terminal-menu))))
|
49591
|
1123 (or term-input-ring
|
|
1124 (setq term-input-ring (make-ring term-input-ring-size)))
|
|
1125 (term-update-mode-line))
|
|
1126
|
9509
|
1127 (defun term-reset-size (height width)
|
|
1128 (setq term-height height)
|
|
1129 (setq term-width width)
|
|
1130 (setq term-start-line-column nil)
|
|
1131 (setq term-current-row nil)
|
|
1132 (setq term-current-column nil)
|
68203
|
1133 (term-set-scroll-region 0 height))
|
9509
|
1134
|
|
1135 ;; Recursive routine used to check if any string in term-kill-echo-list
|
|
1136 ;; matches part of the buffer before point.
|
|
1137 ;; If so, delete that matched part of the buffer - this suppresses echo.
|
|
1138 ;; Also, remove that string from the term-kill-echo-list.
|
|
1139 ;; We *also* remove any older string on the list, as a sanity measure,
|
|
1140 ;; in case something gets out of sync. (Except for type-ahead, there
|
|
1141 ;; should only be one element in the list.)
|
|
1142
|
|
1143 (defun term-check-kill-echo-list ()
|
|
1144 (let ((cur term-kill-echo-list) (found nil) (save-point (point)))
|
|
1145 (unwind-protect
|
|
1146 (progn
|
|
1147 (end-of-line)
|
|
1148 (while cur
|
|
1149 (let* ((str (car cur)) (len (length str)) (start (- (point) len)))
|
|
1150 (if (and (>= start (point-min))
|
|
1151 (string= str (buffer-substring start (point))))
|
|
1152 (progn (delete-backward-char len)
|
|
1153 (setq term-kill-echo-list (cdr cur))
|
|
1154 (setq term-current-column nil)
|
|
1155 (setq term-current-row nil)
|
|
1156 (setq term-start-line-column nil)
|
|
1157 (setq cur nil found t))
|
|
1158 (setq cur (cdr cur))))))
|
71054
|
1159 (when (not found)
|
|
1160 (goto-char save-point)))
|
9509
|
1161 found))
|
|
1162
|
|
1163 (defun term-check-size (process)
|
71054
|
1164 (when (or (/= term-height (1- (window-height)))
|
|
1165 (/= term-width (term-window-width)))
|
|
1166 (term-reset-size (1- (window-height)) (term-window-width))
|
|
1167 (set-process-window-size process term-height term-width)))
|
9509
|
1168
|
|
1169 (defun term-send-raw-string (chars)
|
|
1170 (let ((proc (get-buffer-process (current-buffer))))
|
|
1171 (if (not proc)
|
|
1172 (error "Current buffer has no process")
|
|
1173 ;; Note that (term-current-row) must be called *after*
|
|
1174 ;; (point) has been updated to (process-mark proc).
|
|
1175 (goto-char (process-mark proc))
|
71054
|
1176 (when (term-pager-enabled)
|
|
1177 (setq term-pager-count (term-current-row)))
|
15246
|
1178 (process-send-string proc chars))))
|
9509
|
1179
|
|
1180 (defun term-send-raw ()
|
|
1181 "Send the last character typed through the terminal-emulator
|
17283
|
1182 without any interpretation."
|
9509
|
1183 (interactive)
|
|
1184 ;; Convert `return' to C-m, etc.
|
71054
|
1185 (when (and (symbolp last-input-char)
|
|
1186 (get last-input-char 'ascii-character))
|
|
1187 (setq last-input-char (get last-input-char 'ascii-character)))
|
9509
|
1188 (term-send-raw-string (make-string 1 last-input-char)))
|
|
1189
|
|
1190 (defun term-send-raw-meta ()
|
|
1191 (interactive)
|
30169
|
1192 (let ((char last-input-char))
|
|
1193 (when (symbolp last-input-char)
|
10671
|
1194 ;; Convert `return' to C-m, etc.
|
30169
|
1195 (let ((tmp (get char 'event-symbol-elements)))
|
|
1196 (when tmp
|
|
1197 (setq char (car tmp)))
|
|
1198 (when (symbolp char)
|
|
1199 (setq tmp (get char 'ascii-character))
|
|
1200 (when tmp
|
|
1201 (setq char tmp)))))
|
|
1202 (setq char (event-basic-type char))
|
|
1203 (term-send-raw-string (if (and (numberp char)
|
|
1204 (> char 127)
|
|
1205 (< char 256))
|
|
1206 (make-string 1 char)
|
|
1207 (format "\e%c" char)))))
|
9509
|
1208
|
|
1209 (defun term-mouse-paste (click arg)
|
|
1210 "Insert the last stretch of killed text at the position clicked on."
|
|
1211 (interactive "e\nP")
|
71054
|
1212 (if (featurep 'xemacs)
|
77169
8905fec7d280
(term-buffer-maximum-size, term-exec, term-escape-char, term-set-escape-char,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
1213 (term-send-raw-string
|
71054
|
1214 (or (condition-case () (x-get-selection) (error ()))
|
|
1215 (x-get-cutbuffer)
|
|
1216 (error "No selection or cut buffer available")))
|
|
1217 ;; Give temporary modes such as isearch a chance to turn off.
|
|
1218 (run-hooks 'mouse-leave-buffer-hook)
|
|
1219 (setq this-command 'yank)
|
|
1220 (mouse-set-point click)
|
|
1221 (term-send-raw-string (current-kill (cond
|
|
1222 ((listp arg) 0)
|
|
1223 ((eq arg '-) -1)
|
|
1224 (t (1- arg)))))))
|
9509
|
1225
|
57234
|
1226 (defun term-paste ()
|
|
1227 "Insert the last stretch of killed text at point."
|
|
1228 (interactive)
|
|
1229 (term-send-raw-string (current-kill 0)))
|
|
1230
|
9509
|
1231 ;; Which would be better: "\e[A" or "\eOA"? readline accepts either.
|
17283
|
1232 ;; For my configuration it's definitely better \eOA but YMMV. -mm
|
|
1233 ;; For example: vi works with \eOA while elm wants \e[A ...
|
66461
|
1234 ;;; (terminfo: kcuu1, kcud1, kcuf1, kcub1, khome, kend, kpp, knp, kdch1, kbs)
|
17283
|
1235 (defun term-send-up () (interactive) (term-send-raw-string "\eOA"))
|
|
1236 (defun term-send-down () (interactive) (term-send-raw-string "\eOB"))
|
|
1237 (defun term-send-right () (interactive) (term-send-raw-string "\eOC"))
|
|
1238 (defun term-send-left () (interactive) (term-send-raw-string "\eOD"))
|
24044
|
1239 (defun term-send-home () (interactive) (term-send-raw-string "\e[1~"))
|
68203
|
1240 (defun term-send-insert() (interactive) (term-send-raw-string "\e[2~"))
|
24044
|
1241 (defun term-send-end () (interactive) (term-send-raw-string "\e[4~"))
|
17283
|
1242 (defun term-send-prior () (interactive) (term-send-raw-string "\e[5~"))
|
|
1243 (defun term-send-next () (interactive) (term-send-raw-string "\e[6~"))
|
57234
|
1244 (defun term-send-del () (interactive) (term-send-raw-string "\e[3~"))
|
|
1245 (defun term-send-backspace () (interactive) (term-send-raw-string "\C-?"))
|
49591
|
1246
|
9509
|
1247 (defun term-char-mode ()
|
10515
|
1248 "Switch to char (\"raw\") sub-mode of term mode.
|
|
1249 Each character you type is sent directly to the inferior without
|
17283
|
1250 intervention from Emacs, except for the escape character (usually C-c)."
|
9509
|
1251 (interactive)
|
|
1252 ;; FIXME: Emit message? Cfr ilisp-raw-message
|
71054
|
1253 (when (term-in-line-mode)
|
|
1254 (setq term-old-mode-map (current-local-map))
|
|
1255 (use-local-map term-raw-map)
|
|
1256
|
|
1257 ;; Send existing partial line to inferior (without newline).
|
|
1258 (let ((pmark (process-mark (get-buffer-process (current-buffer))))
|
|
1259 (save-input-sender term-input-sender))
|
|
1260 (when (> (point) pmark)
|
|
1261 (unwind-protect
|
|
1262 (progn
|
|
1263 (setq term-input-sender
|
|
1264 (symbol-function 'term-send-string))
|
|
1265 (end-of-line)
|
|
1266 (term-send-input))
|
|
1267 (setq term-input-sender save-input-sender))))
|
|
1268 (term-update-mode-line)))
|
9509
|
1269
|
|
1270 (defun term-line-mode ()
|
10515
|
1271 "Switch to line (\"cooked\") sub-mode of term mode.
|
17283
|
1272 This means that Emacs editing commands work as normally, until
|
10515
|
1273 you type \\[term-send-input] which sends the current line to the inferior."
|
9509
|
1274 (interactive)
|
71054
|
1275 (when (term-in-char-mode)
|
|
1276 (use-local-map term-old-mode-map)
|
|
1277 (term-update-mode-line)))
|
10671
|
1278
|
|
1279 (defun term-update-mode-line ()
|
95879
|
1280 (let ((term-mode (if (term-in-char-mode) "char" "line"))
|
|
1281 (term-page (when (term-pager-enabled) " page"))
|
|
1282 (serial-item-speed)
|
|
1283 (serial-item-config)
|
|
1284 (temp)
|
|
1285 (proc (get-buffer-process (current-buffer))))
|
|
1286 (when (and (term-check-proc (current-buffer))
|
|
1287 (equal (process-type nil) 'serial))
|
|
1288 (let ((temp (serial-speed)))
|
|
1289 (setq serial-item-speed
|
|
1290 `(:propertize
|
|
1291 ,(or (and temp (format " %d" temp)) "")
|
|
1292 help-echo "mouse-1: Change the speed of the serial port"
|
|
1293 mouse-face mode-line-highlight
|
|
1294 local-map (keymap (mode-line keymap
|
|
1295 (down-mouse-1 . serial-mode-line-speed-menu-1))))))
|
|
1296 (let ((temp (process-contact proc :summary)))
|
|
1297 (setq serial-item-config
|
|
1298 `(:propertize
|
|
1299 ,(or (and temp (format " %s" temp)) "")
|
|
1300 help-echo "mouse-1: Change the configuration of the serial port"
|
|
1301 mouse-face mode-line-highlight
|
|
1302 local-map (keymap (mode-line keymap
|
|
1303 (down-mouse-1 . serial-mode-line-config-menu-1)))))))
|
|
1304 (setq mode-line-process
|
|
1305 (list ": " term-mode term-page
|
|
1306 serial-item-speed
|
|
1307 serial-item-config
|
|
1308 " %s")))
|
11570
f210b0ee984a
(term-update-mode-line, term-process-pager): Use force-mode-line-update.
Karl Heuer <kwzh@gnu.org>
diff
changeset
|
1309 (force-mode-line-update))
|
9509
|
1310
|
|
1311 (defun term-check-proc (buffer)
|
95879
|
1312 "True if there is a process associated w/buffer BUFFER, and it
|
|
1313 is alive. BUFFER can be either a buffer or the name of one."
|
9509
|
1314 (let ((proc (get-buffer-process buffer)))
|
95879
|
1315 (and proc (memq (process-status proc) '(run stop open listen connect)))))
|
9509
|
1316
|
|
1317 ;;;###autoload
|
|
1318 (defun make-term (name program &optional startfile &rest switches)
|
|
1319 "Make a term process NAME in a buffer, running PROGRAM.
|
|
1320 The name of the buffer is made by surrounding NAME with `*'s.
|
|
1321 If there is already a running process in that buffer, it is not restarted.
|
17283
|
1322 Optional third arg STARTFILE is the name of a file to send the contents of to
|
9509
|
1323 the process. Any more args are arguments to PROGRAM."
|
|
1324 (let ((buffer (get-buffer-create (concat "*" name "*"))))
|
|
1325 ;; If no process, or nuked process, crank up a new one and put buffer in
|
17283
|
1326 ;; term mode. Otherwise, leave buffer and existing process alone.
|
9509
|
1327 (cond ((not (term-check-proc buffer))
|
|
1328 (save-excursion
|
|
1329 (set-buffer buffer)
|
|
1330 (term-mode)) ; Install local vars, mode, keymap, ...
|
|
1331 (term-exec buffer name program startfile switches)))
|
|
1332 buffer))
|
|
1333
|
|
1334 ;;;###autoload
|
|
1335 (defun term (program)
|
49591
|
1336 "Start a terminal-emulator in a new buffer.
|
|
1337 The buffer is in Term mode; see `term-mode' for the
|
|
1338 commands to use in that buffer.
|
|
1339
|
|
1340 \\<term-raw-map>Type \\[switch-to-buffer] to switch to another buffer."
|
9509
|
1341 (interactive (list (read-from-minibuffer "Run program: "
|
|
1342 (or explicit-shell-file-name
|
|
1343 (getenv "ESHELL")
|
|
1344 (getenv "SHELL")
|
|
1345 "/bin/sh"))))
|
|
1346 (set-buffer (make-term "terminal" program))
|
|
1347 (term-mode)
|
|
1348 (term-char-mode)
|
|
1349 (switch-to-buffer "*terminal*"))
|
|
1350
|
|
1351 (defun term-exec (buffer name command startfile switches)
|
|
1352 "Start up a process in buffer for term modes.
|
17283
|
1353 Blasts any old process running in the buffer. Doesn't set the buffer mode.
|
9509
|
1354 You can use this to cheaply run a series of processes in the same term
|
77169
8905fec7d280
(term-buffer-maximum-size, term-exec, term-escape-char, term-set-escape-char,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
1355 buffer. The hook `term-exec-hook' is run after each exec."
|
9509
|
1356 (save-excursion
|
|
1357 (set-buffer buffer)
|
|
1358 (let ((proc (get-buffer-process buffer))) ; Blast any old process.
|
71054
|
1359 (when proc (delete-process proc)))
|
9509
|
1360 ;; Crank up a new process
|
|
1361 (let ((proc (term-exec-1 name buffer command switches)))
|
|
1362 (make-local-variable 'term-ptyp)
|
42205
|
1363 (setq term-ptyp process-connection-type) ; t if pty, nil if pipe.
|
9509
|
1364 ;; Jump to the end, and set the process mark.
|
|
1365 (goto-char (point-max))
|
|
1366 (set-marker (process-mark proc) (point))
|
|
1367 (set-process-filter proc 'term-emulate-terminal)
|
53413
|
1368 (set-process-sentinel proc 'term-sentinel)
|
9509
|
1369 ;; Feed it the startfile.
|
|
1370 (cond (startfile
|
|
1371 ;;This is guaranteed to wait long enough
|
|
1372 ;;but has bad results if the term does not prompt at all
|
|
1373 ;; (while (= size (buffer-size))
|
|
1374 ;; (sleep-for 1))
|
|
1375 ;;I hope 1 second is enough!
|
|
1376 (sleep-for 1)
|
|
1377 (goto-char (point-max))
|
|
1378 (insert-file-contents startfile)
|
|
1379 (setq startfile (buffer-substring (point) (point-max)))
|
|
1380 (delete-region (point) (point-max))
|
|
1381 (term-send-string proc startfile)))
|
|
1382 (run-hooks 'term-exec-hook)
|
|
1383 buffer)))
|
|
1384
|
77169
8905fec7d280
(term-buffer-maximum-size, term-exec, term-escape-char, term-set-escape-char,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
1385 (defun term-sentinel (proc msg)
|
53413
|
1386 "Sentinel for term buffers.
|
|
1387 The main purpose is to get rid of the local keymap."
|
|
1388 (let ((buffer (process-buffer proc)))
|
71054
|
1389 (when (memq (process-status proc) '(signal exit))
|
|
1390 (if (null (buffer-name buffer))
|
|
1391 ;; buffer killed
|
|
1392 (set-process-buffer proc nil)
|
|
1393 (let ((obuf (current-buffer)))
|
|
1394 ;; save-excursion isn't the right thing if
|
|
1395 ;; process-buffer is current-buffer
|
|
1396 (unwind-protect
|
|
1397 (progn
|
|
1398 ;; Write something in the compilation buffer
|
|
1399 ;; and hack its mode line.
|
|
1400 (set-buffer buffer)
|
|
1401 ;; Get rid of local keymap.
|
|
1402 (use-local-map nil)
|
|
1403 (term-handle-exit (process-name proc)
|
|
1404 msg)
|
|
1405 ;; Since the buffer and mode line will show that the
|
|
1406 ;; process is dead, we can delete it now. Otherwise it
|
|
1407 ;; will stay around until M-x list-processes.
|
|
1408 (delete-process proc))
|
|
1409 (set-buffer obuf)))
|
|
1410 ))))
|
53413
|
1411
|
|
1412 (defun term-handle-exit (process-name msg)
|
|
1413 "Write process exit (or other change) message MSG in the current buffer."
|
|
1414 (let ((buffer-read-only nil)
|
|
1415 (omax (point-max))
|
|
1416 (opoint (point)))
|
|
1417 ;; Record where we put the message, so we can ignore it
|
|
1418 ;; later on.
|
|
1419 (goto-char omax)
|
|
1420 (insert ?\n "Process " process-name " " msg)
|
|
1421 ;; Force mode line redisplay soon.
|
|
1422 (force-mode-line-update)
|
71054
|
1423 (when (and opoint (< opoint omax))
|
|
1424 (goto-char opoint))))
|
53413
|
1425
|
|
1426
|
9509
|
1427 ;;; Name to use for TERM.
|
|
1428 ;;; Using "emacs" loses, because bash disables editing if TERM == emacs.
|
66242
|
1429 (defvar term-term-name "eterm-color")
|
17283
|
1430 ; Format string, usage:
|
|
1431 ; (format term-termcap-string emacs-term-name "TERMCAP=" 24 80)
|
9509
|
1432 (defvar term-termcap-format
|
10044
|
1433 "%s%s:li#%d:co#%d:cl=\\E[H\\E[J:cd=\\E[J:bs:am:xn:cm=\\E[%%i%%d;%%dH\
|
9509
|
1434 :nd=\\E[C:up=\\E[A:ce=\\E[K:ho=\\E[H:pt\
|
57123
|
1435 :al=\\E[L:dl=\\E[M:DL=\\E[%%dM:AL=\\E[%%dL:cs=\\E[%%i%%d;%%dr:sf=^J\
|
10044
|
1436 :dc=\\E[P:DC=\\E[%%dP:IC=\\E[%%d@:im=\\E[4h:ei=\\E[4l:mi:\
|
9509
|
1437 :so=\\E[7m:se=\\E[m:us=\\E[4m:ue=\\E[m:md=\\E[1m:mr=\\E[7m:me=\\E[m\
|
57123
|
1438 :UP=\\E[%%dA:DO=\\E[%%dB:LE=\\E[%%dD:RI=\\E[%%dC\
|
|
1439 :kl=\\EOD:kd=\\EOB:kr=\\EOC:ku=\\EOA:kN=\\E[6~:kP=\\E[5~:@7=\\E[4~:kh=\\E[1~\
|
|
1440 :mk=\\E[8m:cb=\\E[1K:op=\\E[39;49m:Co#8:pa#64:AB=\\E[4%%dm:AF=\\E[3%%dm:cr=^M\
|
66891
|
1441 :bl=^G:do=^J:le=^H:ta=^I:se=\\E[27m:ue=\\E24m\
|
|
1442 :kb=^?:kD=^[[3~:sc=\\E7:rc=\\E8:r1=\\Ec:"
|
9509
|
1443 ;;; : -undefine ic
|
57234
|
1444 ;;; don't define :te=\\E[2J\\E[?47l\\E8:ti=\\E7\\E[?47h\
|
77169
8905fec7d280
(term-buffer-maximum-size, term-exec, term-escape-char, term-set-escape-char,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
1445 "Termcap capabilities supported.")
|
9509
|
1446
|
|
1447 ;;; This auxiliary function cranks up the process for term-exec in
|
|
1448 ;;; the appropriate environment.
|
|
1449
|
|
1450 (defun term-exec-1 (name buffer command switches)
|
10044
|
1451 ;; We need to do an extra (fork-less) exec to run stty.
|
17283
|
1452 ;; (This would not be needed if we had suitable Emacs primitives.)
|
10044
|
1453 ;; The 'if ...; then shift; fi' hack is because Bourne shell
|
|
1454 ;; loses one arg when called with -c, and newer shells (bash, ksh) don't.
|
|
1455 ;; Thus we add an extra dummy argument "..", and then remove it.
|
|
1456 (let ((process-environment
|
|
1457 (nconc
|
|
1458 (list
|
|
1459 (format "TERM=%s" term-term-name)
|
57123
|
1460 (format "TERMINFO=%s" data-directory)
|
|
1461 (format term-termcap-format "TERMCAP="
|
|
1462 term-term-name term-height term-width)
|
74284
|
1463 ;; We are going to get rid of the binding for EMACS,
|
|
1464 ;; probably in Emacs 23, because it breaks
|
|
1465 ;; `./configure' of some packages that expect it to
|
|
1466 ;; say where to find EMACS.
|
10679
|
1467 (format "EMACS=%s (term:%s)" emacs-version term-protocol-version)
|
74284
|
1468 (format "INSIDE_EMACS=%s,term:%s" emacs-version term-protocol-version)
|
10044
|
1469 (format "LINES=%d" term-height)
|
|
1470 (format "COLUMNS=%d" term-width))
|
15491
|
1471 process-environment))
|
20153
|
1472 (process-connection-type t)
|
|
1473 ;; We should suppress conversion of end-of-line format.
|
|
1474 (inhibit-eol-conversion t)
|
57234
|
1475 ;; The process's output contains not just chars but also binary
|
|
1476 ;; escape codes, so we need to see the raw output. We will have to
|
|
1477 ;; do the decoding by hand on the parts that are made of chars.
|
|
1478 (coding-system-for-read 'binary))
|
10044
|
1479 (apply 'start-process name buffer
|
|
1480 "/bin/sh" "-c"
|
|
1481 (format "stty -nl echo rows %d columns %d sane 2>/dev/null;\
|
|
1482 if [ $1 = .. ]; then shift; fi; exec \"$@\""
|
|
1483 term-height term-width)
|
|
1484 ".."
|
|
1485 command switches)))
|
9509
|
1486
|
|
1487
|
|
1488 ;;; Input history processing in a buffer
|
|
1489 ;;; ===========================================================================
|
|
1490 ;;; Useful input history functions, courtesy of the Ergo group.
|
|
1491
|
|
1492 ;;; Eleven commands:
|
|
1493 ;;; term-dynamic-list-input-ring List history in help buffer.
|
|
1494 ;;; term-previous-input Previous input...
|
|
1495 ;;; term-previous-matching-input ...matching a string.
|
|
1496 ;;; term-previous-matching-input-from-input ... matching the current input.
|
|
1497 ;;; term-next-input Next input...
|
|
1498 ;;; term-next-matching-input ...matching a string.
|
|
1499 ;;; term-next-matching-input-from-input ... matching the current input.
|
|
1500 ;;; term-backward-matching-input Backwards input...
|
|
1501 ;;; term-forward-matching-input ...matching a string.
|
|
1502 ;;; term-replace-by-expanded-history Expand history at point;
|
|
1503 ;;; replace with expanded history.
|
|
1504 ;;; term-magic-space Expand history and insert space.
|
|
1505 ;;;
|
|
1506 ;;; Three functions:
|
|
1507 ;;; term-read-input-ring Read into term-input-ring...
|
|
1508 ;;; term-write-input-ring Write to term-input-ring-file-name.
|
|
1509 ;;; term-replace-by-expanded-history-before-point Workhorse function.
|
|
1510
|
|
1511 (defun term-read-input-ring (&optional silent)
|
|
1512 "Sets the buffer's `term-input-ring' from a history file.
|
|
1513 The name of the file is given by the variable `term-input-ring-file-name'.
|
|
1514 The history ring is of size `term-input-ring-size', regardless of file size.
|
|
1515 If `term-input-ring-file-name' is nil this function does nothing.
|
|
1516
|
|
1517 If the optional argument SILENT is non-nil, we say nothing about a
|
|
1518 failure to read the history file.
|
|
1519
|
|
1520 This function is useful for major mode commands and mode hooks.
|
|
1521
|
|
1522 The structure of the history file should be one input command per line,
|
|
1523 with the most recent command last.
|
|
1524 See also `term-input-ignoredups' and `term-write-input-ring'."
|
|
1525 (cond ((or (null term-input-ring-file-name)
|
|
1526 (equal term-input-ring-file-name ""))
|
|
1527 nil)
|
|
1528 ((not (file-readable-p term-input-ring-file-name))
|
|
1529 (or silent
|
|
1530 (message "Cannot read history file %s"
|
|
1531 term-input-ring-file-name)))
|
|
1532 (t
|
|
1533 (let ((history-buf (get-buffer-create " *temp*"))
|
|
1534 (file term-input-ring-file-name)
|
|
1535 (count 0)
|
|
1536 (ring (make-ring term-input-ring-size)))
|
|
1537 (unwind-protect
|
|
1538 (save-excursion
|
|
1539 (set-buffer history-buf)
|
|
1540 (widen)
|
|
1541 (erase-buffer)
|
|
1542 (insert-file-contents file)
|
|
1543 ;; Save restriction in case file is already visited...
|
|
1544 ;; Watch for those date stamps in history files!
|
|
1545 (goto-char (point-max))
|
|
1546 (while (and (< count term-input-ring-size)
|
|
1547 (re-search-backward "^[ \t]*\\([^#\n].*\\)[ \t]*$"
|
|
1548 nil t))
|
|
1549 (let ((history (buffer-substring (match-beginning 1)
|
|
1550 (match-end 1))))
|
71054
|
1551 (when (or (null term-input-ignoredups)
|
|
1552 (ring-empty-p ring)
|
|
1553 (not (string-equal (ring-ref ring 0) history)))
|
9509
|
1554 (ring-insert-at-beginning ring history)))
|
|
1555 (setq count (1+ count))))
|
|
1556 (kill-buffer history-buf))
|
|
1557 (setq term-input-ring ring
|
|
1558 term-input-ring-index nil)))))
|
|
1559
|
|
1560 (defun term-write-input-ring ()
|
|
1561 "Writes the buffer's `term-input-ring' to a history file.
|
|
1562 The name of the file is given by the variable `term-input-ring-file-name'.
|
|
1563 The original contents of the file are lost if `term-input-ring' is not empty.
|
|
1564 If `term-input-ring-file-name' is nil this function does nothing.
|
|
1565
|
|
1566 Useful within process sentinels.
|
|
1567
|
|
1568 See also `term-read-input-ring'."
|
|
1569 (cond ((or (null term-input-ring-file-name)
|
|
1570 (equal term-input-ring-file-name "")
|
|
1571 (null term-input-ring) (ring-empty-p term-input-ring))
|
|
1572 nil)
|
|
1573 ((not (file-writable-p term-input-ring-file-name))
|
|
1574 (message "Cannot write history file %s" term-input-ring-file-name))
|
|
1575 (t
|
|
1576 (let* ((history-buf (get-buffer-create " *Temp Input History*"))
|
|
1577 (ring term-input-ring)
|
|
1578 (file term-input-ring-file-name)
|
|
1579 (index (ring-length ring)))
|
|
1580 ;; Write it all out into a buffer first. Much faster, but messier,
|
|
1581 ;; than writing it one line at a time.
|
|
1582 (save-excursion
|
|
1583 (set-buffer history-buf)
|
|
1584 (erase-buffer)
|
|
1585 (while (> index 0)
|
|
1586 (setq index (1- index))
|
|
1587 (insert (ring-ref ring index) ?\n))
|
|
1588 (write-region (buffer-string) nil file nil 'no-message)
|
|
1589 (kill-buffer nil))))))
|
|
1590
|
|
1591
|
|
1592 (defun term-dynamic-list-input-ring ()
|
|
1593 "List in help buffer the buffer's input history."
|
|
1594 (interactive)
|
|
1595 (if (or (not (ring-p term-input-ring))
|
|
1596 (ring-empty-p term-input-ring))
|
|
1597 (message "No history")
|
|
1598 (let ((history nil)
|
|
1599 (history-buffer " *Input History*")
|
|
1600 (index (1- (ring-length term-input-ring)))
|
|
1601 (conf (current-window-configuration)))
|
|
1602 ;; We have to build up a list ourselves from the ring vector.
|
|
1603 (while (>= index 0)
|
|
1604 (setq history (cons (ring-ref term-input-ring index) history)
|
|
1605 index (1- index)))
|
|
1606 ;; Change "completion" to "history reference"
|
|
1607 ;; to make the display accurate.
|
|
1608 (with-output-to-temp-buffer history-buffer
|
|
1609 (display-completion-list history)
|
|
1610 (set-buffer history-buffer)
|
|
1611 (forward-line 3)
|
|
1612 (while (search-backward "completion" nil 'move)
|
|
1613 (replace-match "history reference")))
|
|
1614 (sit-for 0)
|
|
1615 (message "Hit space to flush")
|
|
1616 (let ((ch (read-event)))
|
64024
|
1617 (if (eq ch ?\s)
|
9509
|
1618 (set-window-configuration conf)
|
|
1619 (setq unread-command-events (list ch)))))))
|
|
1620
|
|
1621
|
|
1622 (defun term-regexp-arg (prompt)
|
|
1623 ;; Return list of regexp and prefix arg using PROMPT.
|
20021
|
1624 (let* (;; Don't clobber this.
|
9509
|
1625 (last-command last-command)
|
|
1626 (regexp (read-from-minibuffer prompt nil nil nil
|
|
1627 'minibuffer-history-search-history)))
|
|
1628 (list (if (string-equal regexp "")
|
|
1629 (setcar minibuffer-history-search-history
|
|
1630 (nth 1 minibuffer-history-search-history))
|
|
1631 regexp)
|
|
1632 (prefix-numeric-value current-prefix-arg))))
|
|
1633
|
|
1634 (defun term-search-arg (arg)
|
|
1635 ;; First make sure there is a ring and that we are after the process mark
|
|
1636 (cond ((not (term-after-pmark-p))
|
|
1637 (error "Not at command line"))
|
|
1638 ((or (null term-input-ring)
|
|
1639 (ring-empty-p term-input-ring))
|
|
1640 (error "Empty input ring"))
|
|
1641 ((zerop arg)
|
|
1642 ;; arg of zero resets search from beginning, and uses arg of 1
|
|
1643 (setq term-input-ring-index nil)
|
|
1644 1)
|
|
1645 (t
|
|
1646 arg)))
|
|
1647
|
|
1648 (defun term-search-start (arg)
|
|
1649 ;; Index to start a directional search, starting at term-input-ring-index
|
|
1650 (if term-input-ring-index
|
|
1651 ;; If a search is running, offset by 1 in direction of arg
|
|
1652 (mod (+ term-input-ring-index (if (> arg 0) 1 -1))
|
|
1653 (ring-length term-input-ring))
|
|
1654 ;; For a new search, start from beginning or end, as appropriate
|
|
1655 (if (>= arg 0)
|
|
1656 0 ; First elt for forward search
|
|
1657 (1- (ring-length term-input-ring))))) ; Last elt for backward search
|
|
1658
|
|
1659 (defun term-previous-input-string (arg)
|
|
1660 "Return the string ARG places along the input ring.
|
|
1661 Moves relative to `term-input-ring-index'."
|
|
1662 (ring-ref term-input-ring (if term-input-ring-index
|
17283
|
1663 (mod (+ arg term-input-ring-index)
|
9509
|
1664 (ring-length term-input-ring))
|
|
1665 arg)))
|
|
1666
|
|
1667 (defun term-previous-input (arg)
|
|
1668 "Cycle backwards through input history."
|
|
1669 (interactive "*p")
|
|
1670 (term-previous-matching-input "." arg))
|
|
1671
|
|
1672 (defun term-next-input (arg)
|
|
1673 "Cycle forwards through input history."
|
|
1674 (interactive "*p")
|
|
1675 (term-previous-input (- arg)))
|
|
1676
|
|
1677 (defun term-previous-matching-input-string (regexp arg)
|
|
1678 "Return the string matching REGEXP ARG places along the input ring.
|
|
1679 Moves relative to `term-input-ring-index'."
|
|
1680 (let* ((pos (term-previous-matching-input-string-position regexp arg)))
|
71054
|
1681 (when pos (ring-ref term-input-ring pos))))
|
9509
|
1682
|
17283
|
1683 (defun term-previous-matching-input-string-position
|
|
1684 (regexp arg &optional start)
|
9509
|
1685 "Return the index matching REGEXP ARG places along the input ring.
|
|
1686 Moves relative to START, or `term-input-ring-index'."
|
71054
|
1687 (when (or (not (ring-p term-input-ring))
|
|
1688 (ring-empty-p term-input-ring))
|
|
1689 (error "No history"))
|
9509
|
1690 (let* ((len (ring-length term-input-ring))
|
|
1691 (motion (if (> arg 0) 1 -1))
|
|
1692 (n (mod (- (or start (term-search-start arg)) motion) len))
|
|
1693 (tried-each-ring-item nil)
|
|
1694 (prev nil))
|
|
1695 ;; Do the whole search as many times as the argument says.
|
|
1696 (while (and (/= arg 0) (not tried-each-ring-item))
|
|
1697 ;; Step once.
|
|
1698 (setq prev n
|
|
1699 n (mod (+ n motion) len))
|
|
1700 ;; If we haven't reached a match, step some more.
|
|
1701 (while (and (< n len) (not tried-each-ring-item)
|
|
1702 (not (string-match regexp (ring-ref term-input-ring n))))
|
|
1703 (setq n (mod (+ n motion) len)
|
|
1704 ;; If we have gone all the way around in this search.
|
|
1705 tried-each-ring-item (= n prev)))
|
|
1706 (setq arg (if (> arg 0) (1- arg) (1+ arg))))
|
|
1707 ;; Now that we know which ring element to use, if we found it, return that.
|
71054
|
1708 (when (string-match regexp (ring-ref term-input-ring n))
|
|
1709 n)))
|
9509
|
1710
|
|
1711 (defun term-previous-matching-input (regexp arg)
|
|
1712 "Search backwards through input history for match for REGEXP.
|
|
1713 \(Previous history elements are earlier commands.)
|
|
1714 With prefix argument N, search for Nth previous match.
|
|
1715 If N is negative, find the next or Nth next match."
|
|
1716 (interactive (term-regexp-arg "Previous input matching (regexp): "))
|
|
1717 (setq arg (term-search-arg arg))
|
|
1718 (let ((pos (term-previous-matching-input-string-position regexp arg)))
|
|
1719 ;; Has a match been found?
|
|
1720 (if (null pos)
|
|
1721 (error "Not found")
|
|
1722 (setq term-input-ring-index pos)
|
|
1723 (message "History item: %d" (1+ pos))
|
17283
|
1724 (delete-region
|
9509
|
1725 ;; Can't use kill-region as it sets this-command
|
|
1726 (process-mark (get-buffer-process (current-buffer))) (point))
|
|
1727 (insert (ring-ref term-input-ring pos)))))
|
|
1728
|
|
1729 (defun term-next-matching-input (regexp arg)
|
|
1730 "Search forwards through input history for match for REGEXP.
|
|
1731 \(Later history elements are more recent commands.)
|
|
1732 With prefix argument N, search for Nth following match.
|
|
1733 If N is negative, find the previous or Nth previous match."
|
|
1734 (interactive (term-regexp-arg "Next input matching (regexp): "))
|
|
1735 (term-previous-matching-input regexp (- arg)))
|
|
1736
|
|
1737 (defun term-previous-matching-input-from-input (arg)
|
|
1738 "Search backwards through input history for match for current input.
|
|
1739 \(Previous history elements are earlier commands.)
|
|
1740 With prefix argument N, search for Nth previous match.
|
|
1741 If N is negative, search forwards for the -Nth following match."
|
|
1742 (interactive "p")
|
71054
|
1743 (when (not (memq last-command '(term-previous-matching-input-from-input
|
9509
|
1744 term-next-matching-input-from-input)))
|
71054
|
1745 ;; Starting a new search
|
|
1746 (setq term-matching-input-from-input-string
|
|
1747 (buffer-substring
|
|
1748 (process-mark (get-buffer-process (current-buffer)))
|
|
1749 (point))
|
|
1750 term-input-ring-index nil))
|
9509
|
1751 (term-previous-matching-input
|
|
1752 (concat "^" (regexp-quote term-matching-input-from-input-string))
|
|
1753 arg))
|
|
1754
|
|
1755 (defun term-next-matching-input-from-input (arg)
|
|
1756 "Search forwards through input history for match for current input.
|
|
1757 \(Following history elements are more recent commands.)
|
|
1758 With prefix argument N, search for Nth following match.
|
|
1759 If N is negative, search backwards for the -Nth previous match."
|
|
1760 (interactive "p")
|
|
1761 (term-previous-matching-input-from-input (- arg)))
|
|
1762
|
|
1763
|
|
1764 (defun term-replace-by-expanded-history (&optional silent)
|
|
1765 "Expand input command history references before point.
|
|
1766 Expansion is dependent on the value of `term-input-autoexpand'.
|
|
1767
|
|
1768 This function depends on the buffer's idea of the input history, which may not
|
|
1769 match the command interpreter's idea, assuming it has one.
|
|
1770
|
17283
|
1771 Assumes history syntax is like typical Un*x shells'. However, since Emacs
|
9509
|
1772 cannot know the interpreter's idea of input line numbers, assuming it has one,
|
|
1773 it cannot expand absolute input line number references.
|
|
1774
|
|
1775 If the optional argument SILENT is non-nil, never complain
|
|
1776 even if history reference seems erroneous.
|
|
1777
|
|
1778 See `term-magic-space' and `term-replace-by-expanded-history-before-point'.
|
|
1779
|
|
1780 Returns t if successful."
|
|
1781 (interactive)
|
71054
|
1782 (when (and term-input-autoexpand
|
|
1783 (string-match "[!^]" (funcall term-get-old-input))
|
|
1784 (save-excursion (beginning-of-line)
|
|
1785 (looking-at term-prompt-regexp)))
|
|
1786 ;; Looks like there might be history references in the command.
|
|
1787 (let ((previous-modified-tick (buffer-modified-tick)))
|
|
1788 (message "Expanding history references...")
|
|
1789 (term-replace-by-expanded-history-before-point silent)
|
|
1790 (/= previous-modified-tick (buffer-modified-tick)))))
|
9509
|
1791
|
|
1792
|
|
1793 (defun term-replace-by-expanded-history-before-point (silent)
|
|
1794 "Expand directory stack reference before point.
|
|
1795 See `term-replace-by-expanded-history'. Returns t if successful."
|
|
1796 (save-excursion
|
|
1797 (let ((toend (- (save-excursion (end-of-line nil) (point)) (point)))
|
|
1798 (start (progn (term-bol nil) (point))))
|
|
1799 (while (progn
|
|
1800 (skip-chars-forward "^!^"
|
|
1801 (save-excursion
|
|
1802 (end-of-line nil) (- (point) toend)))
|
|
1803 (< (point)
|
|
1804 (save-excursion
|
|
1805 (end-of-line nil) (- (point) toend))))
|
|
1806 ;; This seems a bit complex. We look for references such as !!, !-num,
|
|
1807 ;; !foo, !?foo, !{bar}, !?{bar}, ^oh, ^my^, ^god^it, ^never^ends^.
|
|
1808 ;; If that wasn't enough, the plings can be suffixed with argument
|
|
1809 ;; range specifiers.
|
|
1810 ;; Argument ranges are complex too, so we hive off the input line,
|
|
1811 ;; referenced with plings, with the range string to `term-args'.
|
|
1812 (setq term-input-ring-index nil)
|
|
1813 (cond ((or (= (preceding-char) ?\\)
|
|
1814 (term-within-quotes start (point)))
|
|
1815 ;; The history is quoted, or we're in quotes.
|
|
1816 (goto-char (1+ (point))))
|
|
1817 ((looking-at "![0-9]+\\($\\|[^-]\\)")
|
|
1818 ;; We cannot know the interpreter's idea of input line numbers.
|
|
1819 (goto-char (match-end 0))
|
|
1820 (message "Absolute reference cannot be expanded"))
|
|
1821 ((looking-at "!-\\([0-9]+\\)\\(:?[0-9^$*-]+\\)?")
|
|
1822 ;; Just a number of args from `number' lines backward.
|
|
1823 (let ((number (1- (string-to-number
|
|
1824 (buffer-substring (match-beginning 1)
|
|
1825 (match-end 1))))))
|
|
1826 (if (<= number (ring-length term-input-ring))
|
|
1827 (progn
|
|
1828 (replace-match
|
|
1829 (term-args (term-previous-input-string number)
|
|
1830 (match-beginning 2) (match-end 2))
|
|
1831 t t)
|
|
1832 (setq term-input-ring-index number)
|
|
1833 (message "History item: %d" (1+ number)))
|
|
1834 (goto-char (match-end 0))
|
|
1835 (message "Relative reference exceeds input history size"))))
|
|
1836 ((or (looking-at "!!?:?\\([0-9^$*-]+\\)") (looking-at "!!"))
|
|
1837 ;; Just a number of args from the previous input line.
|
|
1838 (replace-match
|
|
1839 (term-args (term-previous-input-string 0)
|
|
1840 (match-beginning 1) (match-end 1))
|
|
1841 t t)
|
|
1842 (message "History item: previous"))
|
|
1843 ((looking-at
|
|
1844 "!\\??\\({\\(.+\\)}\\|\\(\\sw+\\)\\)\\(:?[0-9^$*-]+\\)?")
|
|
1845 ;; Most recent input starting with or containing (possibly
|
|
1846 ;; protected) string, maybe just a number of args. Phew.
|
|
1847 (let* ((mb1 (match-beginning 1)) (me1 (match-end 1))
|
|
1848 (mb2 (match-beginning 2)) (me2 (match-end 2))
|
|
1849 (exp (buffer-substring (or mb2 mb1) (or me2 me1)))
|
|
1850 (pref (if (save-match-data (looking-at "!\\?")) "" "^"))
|
|
1851 (pos (save-match-data
|
|
1852 (term-previous-matching-input-string-position
|
|
1853 (concat pref (regexp-quote exp)) 1))))
|
|
1854 (if (null pos)
|
|
1855 (progn
|
|
1856 (goto-char (match-end 0))
|
|
1857 (or silent
|
|
1858 (progn (message "Not found")
|
|
1859 (ding))))
|
|
1860 (setq term-input-ring-index pos)
|
|
1861 (replace-match
|
|
1862 (term-args (ring-ref term-input-ring pos)
|
|
1863 (match-beginning 4) (match-end 4))
|
|
1864 t t)
|
|
1865 (message "History item: %d" (1+ pos)))))
|
|
1866 ((looking-at "\\^\\([^^]+\\)\\^?\\([^^]*\\)\\^?")
|
|
1867 ;; Quick substitution on the previous input line.
|
|
1868 (let ((old (buffer-substring (match-beginning 1) (match-end 1)))
|
|
1869 (new (buffer-substring (match-beginning 2) (match-end 2)))
|
|
1870 (pos nil))
|
|
1871 (replace-match (term-previous-input-string 0) t t)
|
|
1872 (setq pos (point))
|
|
1873 (goto-char (match-beginning 0))
|
|
1874 (if (not (search-forward old pos t))
|
|
1875 (or silent
|
|
1876 (error "Not found"))
|
|
1877 (replace-match new t t)
|
|
1878 (message "History item: substituted"))))
|
|
1879 (t
|
|
1880 (goto-char (match-end 0))))))))
|
|
1881
|
|
1882
|
|
1883 (defun term-magic-space (arg)
|
|
1884 "Expand input history references before point and insert ARG spaces.
|
|
1885 A useful command to bind to SPC. See `term-replace-by-expanded-history'."
|
|
1886 (interactive "p")
|
|
1887 (term-replace-by-expanded-history)
|
|
1888 (self-insert-command arg))
|
|
1889
|
|
1890 (defun term-within-quotes (beg end)
|
|
1891 "Return t if the number of quotes between BEG and END is odd.
|
|
1892 Quotes are single and double."
|
|
1893 (let ((countsq (term-how-many-region "\\(^\\|[^\\\\]\\)\'" beg end))
|
|
1894 (countdq (term-how-many-region "\\(^\\|[^\\\\]\\)\"" beg end)))
|
|
1895 (or (= (mod countsq 2) 1) (= (mod countdq 2) 1))))
|
|
1896
|
|
1897 (defun term-how-many-region (regexp beg end)
|
|
1898 "Return number of matches for REGEXP from BEG to END."
|
|
1899 (let ((count 0))
|
|
1900 (save-excursion
|
|
1901 (save-match-data
|
|
1902 (goto-char beg)
|
|
1903 (while (re-search-forward regexp end t)
|
|
1904 (setq count (1+ count)))))
|
|
1905 count))
|
|
1906
|
|
1907 (defun term-args (string begin end)
|
|
1908 ;; From STRING, return the args depending on the range specified in the text
|
|
1909 ;; from BEGIN to END. If BEGIN is nil, assume all args. Ignore leading `:'.
|
|
1910 ;; Range can be x-y, x-, -y, where x/y can be [0-9], *, ^, $.
|
|
1911 (save-match-data
|
|
1912 (if (null begin)
|
|
1913 (term-arguments string 0 nil)
|
|
1914 (let* ((range (buffer-substring
|
|
1915 (if (eq (char-after begin) ?:) (1+ begin) begin) end))
|
|
1916 (nth (cond ((string-match "^[*^]" range) 1)
|
|
1917 ((string-match "^-" range) 0)
|
|
1918 ((string-equal range "$") nil)
|
|
1919 (t (string-to-number range))))
|
|
1920 (mth (cond ((string-match "[-*$]$" range) nil)
|
|
1921 ((string-match "-" range)
|
|
1922 (string-to-number (substring range (match-end 0))))
|
|
1923 (t nth))))
|
|
1924 (term-arguments string nth mth)))))
|
|
1925
|
|
1926 ;; Return a list of arguments from ARG. Break it up at the
|
|
1927 ;; delimiters in term-delimiter-argument-list. Returned list is backwards.
|
|
1928 (defun term-delim-arg (arg)
|
|
1929 (if (null term-delimiter-argument-list)
|
|
1930 (list arg)
|
|
1931 (let ((args nil)
|
|
1932 (pos 0)
|
|
1933 (len (length arg)))
|
|
1934 (while (< pos len)
|
|
1935 (let ((char (aref arg pos))
|
|
1936 (start pos))
|
|
1937 (if (memq char term-delimiter-argument-list)
|
|
1938 (while (and (< pos len) (eq (aref arg pos) char))
|
|
1939 (setq pos (1+ pos)))
|
|
1940 (while (and (< pos len)
|
|
1941 (not (memq (aref arg pos)
|
|
1942 term-delimiter-argument-list)))
|
|
1943 (setq pos (1+ pos))))
|
|
1944 (setq args (cons (substring arg start pos) args))))
|
|
1945 args)))
|
|
1946
|
|
1947 (defun term-arguments (string nth mth)
|
|
1948 "Return from STRING the NTH to MTH arguments.
|
|
1949 NTH and/or MTH can be nil, which means the last argument.
|
|
1950 Returned arguments are separated by single spaces.
|
|
1951 We assume whitespace separates arguments, except within quotes.
|
|
1952 Also, a run of one or more of a single character
|
|
1953 in `term-delimiter-argument-list' is a separate argument.
|
|
1954 Argument 0 is the command name."
|
|
1955 (let ((argpart "[^ \n\t\"'`]+\\|\\(\"[^\"]*\"\\|'[^']*'\\|`[^`]*`\\)")
|
|
1956 (args ()) (pos 0)
|
|
1957 (count 0)
|
15246
|
1958 beg str quotes)
|
9509
|
1959 ;; Build a list of all the args until we have as many as we want.
|
|
1960 (while (and (or (null mth) (<= count mth))
|
|
1961 (string-match argpart string pos))
|
|
1962 (if (and beg (= pos (match-beginning 0)))
|
|
1963 ;; It's contiguous, part of the same arg.
|
|
1964 (setq pos (match-end 0)
|
|
1965 quotes (or quotes (match-beginning 1)))
|
|
1966 ;; It's a new separate arg.
|
|
1967 (if beg
|
|
1968 ;; Put the previous arg, if there was one, onto ARGS.
|
|
1969 (setq str (substring string beg pos)
|
|
1970 args (if quotes (cons str args)
|
|
1971 (nconc (term-delim-arg str) args))
|
|
1972 count (1+ count)))
|
|
1973 (setq quotes (match-beginning 1))
|
|
1974 (setq beg (match-beginning 0))
|
|
1975 (setq pos (match-end 0))))
|
|
1976 (if beg
|
|
1977 (setq str (substring string beg pos)
|
|
1978 args (if quotes (cons str args)
|
|
1979 (nconc (term-delim-arg str) args))
|
|
1980 count (1+ count)))
|
|
1981 (let ((n (or nth (1- count)))
|
|
1982 (m (if mth (1- (- count mth)) 0)))
|
|
1983 (mapconcat
|
|
1984 (function (lambda (a) a)) (nthcdr n (nreverse (nthcdr m args))) " "))))
|
|
1985
|
|
1986 ;;;
|
|
1987 ;;; Input processing stuff [line mode]
|
|
1988 ;;;
|
|
1989
|
17283
|
1990 (defun term-send-input ()
|
9509
|
1991 "Send input to process.
|
|
1992 After the process output mark, sends all text from the process mark to
|
|
1993 point as input to the process. Before the process output mark, calls value
|
|
1994 of variable term-get-old-input to retrieve old input, copies it to the
|
|
1995 process mark, and sends it. A terminal newline is also inserted into the
|
|
1996 buffer and sent to the process. The list of function names contained in the
|
|
1997 value of `term-input-filter-functions' is called on the input before sending
|
|
1998 it. The input is entered into the input history ring, if the value of variable
|
|
1999 term-input-filter returns non-nil when called on the input.
|
|
2000
|
|
2001 Any history reference may be expanded depending on the value of the variable
|
|
2002 `term-input-autoexpand'. The list of function names contained in the value
|
|
2003 of `term-input-filter-functions' is called on the input before sending it.
|
|
2004 The input is entered into the input history ring, if the value of variable
|
|
2005 `term-input-filter' returns non-nil when called on the input.
|
|
2006
|
10933
|
2007 If variable `term-eol-on-send' is non-nil, then point is moved to the
|
|
2008 end of line before sending the input.
|
|
2009
|
9509
|
2010 The values of `term-get-old-input', `term-input-filter-functions', and
|
|
2011 `term-input-filter' are chosen according to the command interpreter running
|
|
2012 in the buffer. E.g.,
|
|
2013
|
|
2014 If the interpreter is the csh,
|
|
2015 term-get-old-input is the default: take the current line, discard any
|
|
2016 initial string matching regexp term-prompt-regexp.
|
|
2017 term-input-filter-functions monitors input for \"cd\", \"pushd\", and
|
17283
|
2018 \"popd\" commands. When it sees one, it cd's the buffer.
|
42205
|
2019 term-input-filter is the default: returns t if the input isn't all white
|
9509
|
2020 space.
|
|
2021
|
17283
|
2022 If the term is Lucid Common Lisp,
|
9509
|
2023 term-get-old-input snarfs the sexp ending at point.
|
|
2024 term-input-filter-functions does nothing.
|
42205
|
2025 term-input-filter returns nil if the input matches input-filter-regexp,
|
9509
|
2026 which matches (1) all whitespace (2) :a, :c, etc.
|
|
2027
|
|
2028 Similarly for Soar, Scheme, etc."
|
|
2029 (interactive)
|
|
2030 ;; Note that the input string does not include its terminal newline.
|
|
2031 (let ((proc (get-buffer-process (current-buffer))))
|
|
2032 (if (not proc) (error "Current buffer has no process")
|
|
2033 (let* ((pmark (process-mark proc))
|
|
2034 (pmark-val (marker-position pmark))
|
10933
|
2035 (input-is-new (>= (point) pmark-val))
|
|
2036 (intxt (if input-is-new
|
|
2037 (progn (if term-eol-on-send (end-of-line))
|
|
2038 (buffer-substring pmark (point)))
|
9509
|
2039 (funcall term-get-old-input)))
|
|
2040 (input (if (not (eq term-input-autoexpand 'input))
|
|
2041 ;; Just whatever's already there
|
|
2042 intxt
|
|
2043 ;; Expand and leave it visible in buffer
|
|
2044 (term-replace-by-expanded-history t)
|
|
2045 (buffer-substring pmark (point))))
|
|
2046 (history (if (not (eq term-input-autoexpand 'history))
|
|
2047 input
|
|
2048 ;; This is messy 'cos ultimately the original
|
|
2049 ;; functions used do insertion, rather than return
|
|
2050 ;; strings. We have to expand, then insert back.
|
|
2051 (term-replace-by-expanded-history t)
|
|
2052 (let ((copy (buffer-substring pmark (point))))
|
|
2053 (delete-region pmark (point))
|
|
2054 (insert input)
|
|
2055 copy))))
|
71054
|
2056 (when (term-pager-enabled)
|
|
2057 (save-excursion
|
|
2058 (goto-char (process-mark proc))
|
|
2059 (setq term-pager-count (term-current-row))))
|
|
2060 (when (and (funcall term-input-filter history)
|
|
2061 (or (null term-input-ignoredups)
|
|
2062 (not (ring-p term-input-ring))
|
|
2063 (ring-empty-p term-input-ring)
|
|
2064 (not (string-equal (ring-ref term-input-ring 0)
|
|
2065 history))))
|
|
2066 (ring-insert term-input-ring history))
|
9509
|
2067 (let ((functions term-input-filter-functions))
|
|
2068 (while functions
|
|
2069 (funcall (car functions) (concat input "\n"))
|
|
2070 (setq functions (cdr functions))))
|
|
2071 (setq term-input-ring-index nil)
|
10933
|
2072
|
9509
|
2073 ;; Update the markers before we send the input
|
|
2074 ;; in case we get output amidst sending the input.
|
|
2075 (set-marker term-last-input-start pmark)
|
|
2076 (set-marker term-last-input-end (point))
|
71054
|
2077 (when input-is-new
|
|
2078 ;; Set up to delete, because inferior should echo.
|
|
2079 (when (marker-buffer term-pending-delete-marker)
|
|
2080 (delete-region term-pending-delete-marker pmark))
|
|
2081 (set-marker term-pending-delete-marker pmark-val)
|
|
2082 (set-marker (process-mark proc) (point)))
|
10933
|
2083 (goto-char pmark)
|
9509
|
2084 (funcall term-input-sender proc input)))))
|
|
2085
|
|
2086 (defun term-get-old-input-default ()
|
77169
8905fec7d280
(term-buffer-maximum-size, term-exec, term-escape-char, term-set-escape-char,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
2087 "Default for `term-get-old-input'.
|
9509
|
2088 Take the current line, and discard any initial text matching
|
77169
8905fec7d280
(term-buffer-maximum-size, term-exec, term-escape-char, term-set-escape-char,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
2089 `term-prompt-regexp'."
|
9509
|
2090 (save-excursion
|
|
2091 (beginning-of-line)
|
|
2092 (term-skip-prompt)
|
|
2093 (let ((beg (point)))
|
|
2094 (end-of-line)
|
|
2095 (buffer-substring beg (point)))))
|
|
2096
|
|
2097 (defun term-copy-old-input ()
|
|
2098 "Insert after prompt old input at point as new input to be edited.
|
|
2099 Calls `term-get-old-input' to get old input."
|
|
2100 (interactive)
|
|
2101 (let ((input (funcall term-get-old-input))
|
|
2102 (process (get-buffer-process (current-buffer))))
|
|
2103 (if (not process)
|
|
2104 (error "Current buffer has no process")
|
|
2105 (goto-char (process-mark process))
|
|
2106 (insert input))))
|
|
2107
|
|
2108 (defun term-skip-prompt ()
|
77169
8905fec7d280
(term-buffer-maximum-size, term-exec, term-escape-char, term-set-escape-char,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
2109 "Skip past the text matching regexp `term-prompt-regexp'.
|
9509
|
2110 If this takes us past the end of the current line, don't skip at all."
|
|
2111 (let ((eol (save-excursion (end-of-line) (point))))
|
71054
|
2112 (when (and (looking-at term-prompt-regexp)
|
|
2113 (<= (match-end 0) eol))
|
|
2114 (goto-char (match-end 0)))))
|
9509
|
2115
|
|
2116
|
|
2117 (defun term-after-pmark-p ()
|
|
2118 "Is point after the process output marker?"
|
|
2119 ;; Since output could come into the buffer after we looked at the point
|
17283
|
2120 ;; but before we looked at the process marker's value, we explicitly
|
|
2121 ;; serialise. This is just because I don't know whether or not Emacs
|
9509
|
2122 ;; services input during execution of lisp commands.
|
|
2123 (let ((proc-pos (marker-position
|
|
2124 (process-mark (get-buffer-process (current-buffer))))))
|
|
2125 (<= proc-pos (point))))
|
|
2126
|
|
2127 (defun term-simple-send (proc string)
|
|
2128 "Default function for sending to PROC input STRING.
|
17283
|
2129 This just sends STRING plus a newline. To override this,
|
63176
7a34bd511117
(term-mode, term-check-proc, term-input-sender, term-simple-send,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
2130 set the hook `term-input-sender'."
|
9509
|
2131 (term-send-string proc string)
|
|
2132 (term-send-string proc "\n"))
|
|
2133
|
|
2134 (defun term-bol (arg)
|
|
2135 "Goes to the beginning of line, then skips past the prompt, if any.
|
17283
|
2136 If a prefix argument is given (\\[universal-argument]), then no prompt skip
|
9509
|
2137 -- go straight to column 0.
|
|
2138
|
|
2139 The prompt skip is done by skipping text matching the regular expression
|
77169
8905fec7d280
(term-buffer-maximum-size, term-exec, term-escape-char, term-set-escape-char,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
2140 `term-prompt-regexp', a buffer local variable."
|
9509
|
2141 (interactive "P")
|
|
2142 (beginning-of-line)
|
71054
|
2143 (when (null arg) (term-skip-prompt)))
|
9509
|
2144
|
|
2145 ;;; These two functions are for entering text you don't want echoed or
|
|
2146 ;;; saved -- typically passwords to ftp, telnet, or somesuch.
|
|
2147 ;;; Just enter m-x term-send-invisible and type in your line.
|
|
2148
|
|
2149 (defun term-read-noecho (prompt &optional stars)
|
17283
|
2150 "Read a single line of text from user without echoing, and return it.
|
9509
|
2151 Prompt with argument PROMPT, a string. Optional argument STARS causes
|
|
2152 input to be echoed with '*' characters on the prompt line. Input ends with
|
|
2153 RET, LFD, or ESC. DEL or C-h rubs out. C-u kills line. C-g aborts (if
|
|
2154 `inhibit-quit' is set because e.g. this function was called from a process
|
|
2155 filter and C-g is pressed, this function returns nil rather than a string).
|
|
2156
|
|
2157 Note that the keystrokes comprising the text can still be recovered
|
|
2158 \(temporarily) with \\[view-lossage]. This may be a security bug for some
|
|
2159 applications."
|
|
2160 (let ((ans "")
|
|
2161 (c 0)
|
|
2162 (echo-keystrokes 0)
|
|
2163 (cursor-in-echo-area t)
|
|
2164 (done nil))
|
|
2165 (while (not done)
|
|
2166 (if stars
|
|
2167 (message "%s%s" prompt (make-string (length ans) ?*))
|
14332
|
2168 (message "%s" prompt))
|
9509
|
2169 (setq c (read-char))
|
|
2170 (cond ((= c ?\C-g)
|
|
2171 ;; This function may get called from a process filter, where
|
17283
|
2172 ;; inhibit-quit is set. In later versions of Emacs read-char
|
9509
|
2173 ;; may clear quit-flag itself and return C-g. That would make
|
|
2174 ;; it impossible to quit this loop in a simple way, so
|
|
2175 ;; re-enable it here (for backward-compatibility the check for
|
|
2176 ;; quit-flag below would still be necessary, so this seems
|
|
2177 ;; like the simplest way to do things).
|
|
2178 (setq quit-flag t
|
|
2179 done t))
|
|
2180 ((or (= c ?\r) (= c ?\n) (= c ?\e))
|
|
2181 (setq done t))
|
|
2182 ((= c ?\C-u)
|
|
2183 (setq ans ""))
|
|
2184 ((and (/= c ?\b) (/= c ?\177))
|
|
2185 (setq ans (concat ans (char-to-string c))))
|
|
2186 ((> (length ans) 0)
|
|
2187 (setq ans (substring ans 0 -1)))))
|
|
2188 (if quit-flag
|
|
2189 ;; Emulate a true quit, except that we have to return a value.
|
|
2190 (prog1
|
|
2191 (setq quit-flag nil)
|
|
2192 (message "Quit")
|
|
2193 (beep t))
|
|
2194 (message "")
|
|
2195 ans)))
|
|
2196
|
|
2197 (defun term-send-invisible (str &optional proc)
|
|
2198 "Read a string without echoing.
|
17283
|
2199 Then send it to the process running in the current buffer. A new-line
|
|
2200 is additionally sent. String is not saved on term input history list.
|
9509
|
2201 Security bug: your string can still be temporarily recovered with
|
|
2202 \\[view-lossage]."
|
|
2203 (interactive "P") ; Defeat snooping via C-x esc
|
71054
|
2204 (when (not (stringp str))
|
|
2205 (setq str (term-read-noecho "Non-echoed text: " t)))
|
|
2206 (when (not proc)
|
|
2207 (setq proc (get-buffer-process (current-buffer))))
|
9509
|
2208 (if (not proc) (error "Current buffer has no process")
|
|
2209 (setq term-kill-echo-list (nconc term-kill-echo-list
|
|
2210 (cons str nil)))
|
|
2211 (term-send-string proc str)
|
|
2212 (term-send-string proc "\n")))
|
|
2213
|
|
2214
|
|
2215 ;;; Low-level process communication
|
|
2216
|
|
2217 (defvar term-input-chunk-size 512
|
|
2218 "*Long inputs send to term processes are broken up into chunks of this size.
|
|
2219 If your process is choking on big inputs, try lowering the value.")
|
|
2220
|
|
2221 (defun term-send-string (proc str)
|
63176
7a34bd511117
(term-mode, term-check-proc, term-input-sender, term-simple-send,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
2222 "Send to PROC the contents of STR as input.
|
77169
8905fec7d280
(term-buffer-maximum-size, term-exec, term-escape-char, term-set-escape-char,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
2223 This is equivalent to `process-send-string', except that long input strings
|
8905fec7d280
(term-buffer-maximum-size, term-exec, term-escape-char, term-set-escape-char,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
2224 are broken up into chunks of size `term-input-chunk-size'. Processes
|
17283
|
2225 are given a chance to output between chunks. This can help prevent processes
|
9509
|
2226 from hanging when you send them long inputs on some OS's."
|
|
2227 (let* ((len (length str))
|
|
2228 (i (min len term-input-chunk-size)))
|
|
2229 (process-send-string proc (substring str 0 i))
|
|
2230 (while (< i len)
|
|
2231 (let ((next-i (+ i term-input-chunk-size)))
|
|
2232 (accept-process-output)
|
|
2233 (process-send-string proc (substring str i (min len next-i)))
|
|
2234 (setq i next-i)))))
|
|
2235
|
|
2236 (defun term-send-region (proc start end)
|
63176
7a34bd511117
(term-mode, term-check-proc, term-input-sender, term-simple-send,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
2237 "Send to PROC the region delimited by START and END.
|
77169
8905fec7d280
(term-buffer-maximum-size, term-exec, term-escape-char, term-set-escape-char,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
2238 This is a replacement for `process-send-region' that tries to keep
|
63176
7a34bd511117
(term-mode, term-check-proc, term-input-sender, term-simple-send,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
2239 your process from hanging on long inputs. See `term-send-string'."
|
9509
|
2240 (term-send-string proc (buffer-substring start end)))
|
|
2241
|
|
2242
|
|
2243 ;;; Random input hackage
|
|
2244
|
|
2245 (defun term-kill-output ()
|
|
2246 "Kill all output from interpreter since last input."
|
|
2247 (interactive)
|
|
2248 (let ((pmark (process-mark (get-buffer-process (current-buffer)))))
|
|
2249 (kill-region term-last-input-end pmark)
|
17283
|
2250 (goto-char pmark)
|
9509
|
2251 (insert "*** output flushed ***\n")
|
|
2252 (set-marker pmark (point))))
|
|
2253
|
|
2254 (defun term-show-output ()
|
|
2255 "Display start of this batch of interpreter output at top of window.
|
|
2256 Sets mark to the value of point when this command is run."
|
|
2257 (interactive)
|
|
2258 (goto-char term-last-input-end)
|
|
2259 (backward-char)
|
|
2260 (beginning-of-line)
|
|
2261 (set-window-start (selected-window) (point))
|
|
2262 (end-of-line))
|
|
2263
|
|
2264 (defun term-interrupt-subjob ()
|
|
2265 "Interrupt the current subjob."
|
|
2266 (interactive)
|
|
2267 (interrupt-process nil term-ptyp))
|
|
2268
|
|
2269 (defun term-kill-subjob ()
|
|
2270 "Send kill signal to the current subjob."
|
|
2271 (interactive)
|
|
2272 (kill-process nil term-ptyp))
|
|
2273
|
|
2274 (defun term-quit-subjob ()
|
|
2275 "Send quit signal to the current subjob."
|
|
2276 (interactive)
|
|
2277 (quit-process nil term-ptyp))
|
|
2278
|
|
2279 (defun term-stop-subjob ()
|
|
2280 "Stop the current subjob.
|
|
2281 WARNING: if there is no current subjob, you can end up suspending
|
17283
|
2282 the top-level process running in the buffer. If you accidentally do
|
|
2283 this, use \\[term-continue-subjob] to resume the process. (This
|
9509
|
2284 is not a problem with most shells, since they ignore this signal.)"
|
|
2285 (interactive)
|
|
2286 (stop-process nil term-ptyp))
|
|
2287
|
|
2288 (defun term-continue-subjob ()
|
|
2289 "Send CONT signal to process buffer's process group.
|
|
2290 Useful if you accidentally suspend the top-level process."
|
|
2291 (interactive)
|
|
2292 (continue-process nil term-ptyp))
|
|
2293
|
|
2294 (defun term-kill-input ()
|
|
2295 "Kill all text from last stuff output by interpreter to point."
|
|
2296 (interactive)
|
|
2297 (let* ((pmark (process-mark (get-buffer-process (current-buffer))))
|
|
2298 (p-pos (marker-position pmark)))
|
71054
|
2299 (when (> (point) p-pos)
|
|
2300 (kill-region pmark (point)))))
|
9509
|
2301
|
|
2302 (defun term-delchar-or-maybe-eof (arg)
|
17283
|
2303 "Delete ARG characters forward, or send an EOF to process if at end of
|
|
2304 buffer."
|
9509
|
2305 (interactive "p")
|
|
2306 (if (eobp)
|
|
2307 (process-send-eof)
|
71054
|
2308 (delete-char arg)))
|
9509
|
2309
|
|
2310 (defun term-send-eof ()
|
|
2311 "Send an EOF to the current buffer's process."
|
|
2312 (interactive)
|
|
2313 (process-send-eof))
|
|
2314
|
|
2315 (defun term-backward-matching-input (regexp arg)
|
|
2316 "Search backward through buffer for match for REGEXP.
|
|
2317 Matches are searched for on lines that match `term-prompt-regexp'.
|
|
2318 With prefix argument N, search for Nth previous match.
|
|
2319 If N is negative, find the next or Nth next match."
|
|
2320 (interactive (term-regexp-arg "Backward input matching (regexp): "))
|
|
2321 (let* ((re (concat term-prompt-regexp ".*" regexp))
|
|
2322 (pos (save-excursion (end-of-line (if (> arg 0) 0 1))
|
71054
|
2323 (when (re-search-backward re nil t arg)
|
|
2324 (point)))))
|
9509
|
2325 (if (null pos)
|
|
2326 (progn (message "Not found")
|
|
2327 (ding))
|
|
2328 (goto-char pos)
|
|
2329 (term-bol nil))))
|
|
2330
|
|
2331 (defun term-forward-matching-input (regexp arg)
|
|
2332 "Search forward through buffer for match for REGEXP.
|
|
2333 Matches are searched for on lines that match `term-prompt-regexp'.
|
|
2334 With prefix argument N, search for Nth following match.
|
|
2335 If N is negative, find the previous or Nth previous match."
|
|
2336 (interactive (term-regexp-arg "Forward input matching (regexp): "))
|
|
2337 (term-backward-matching-input regexp (- arg)))
|
|
2338
|
|
2339
|
|
2340 (defun term-next-prompt (n)
|
|
2341 "Move to end of Nth next prompt in the buffer.
|
|
2342 See `term-prompt-regexp'."
|
|
2343 (interactive "p")
|
|
2344 (let ((paragraph-start term-prompt-regexp))
|
|
2345 (end-of-line (if (> n 0) 1 0))
|
|
2346 (forward-paragraph n)
|
|
2347 (term-skip-prompt)))
|
|
2348
|
|
2349 (defun term-previous-prompt (n)
|
|
2350 "Move to end of Nth previous prompt in the buffer.
|
|
2351 See `term-prompt-regexp'."
|
|
2352 (interactive "p")
|
|
2353 (term-next-prompt (- n)))
|
|
2354
|
|
2355 ;;; Support for source-file processing commands.
|
|
2356 ;;;============================================================================
|
|
2357 ;;; Many command-interpreters (e.g., Lisp, Scheme, Soar) have
|
|
2358 ;;; commands that process files of source text (e.g. loading or compiling
|
17283
|
2359 ;;; files). So the corresponding process-in-a-buffer modes have commands
|
|
2360 ;;; for doing this (e.g., lisp-load-file). The functions below are useful
|
9509
|
2361 ;;; for defining these commands.
|
|
2362 ;;;
|
|
2363 ;;; Alas, these guys don't do exactly the right thing for Lisp, Scheme
|
|
2364 ;;; and Soar, in that they don't know anything about file extensions.
|
|
2365 ;;; So the compile/load interface gets the wrong default occasionally.
|
|
2366 ;;; The load-file/compile-file default mechanism could be smarter -- it
|
|
2367 ;;; doesn't know about the relationship between filename extensions and
|
17283
|
2368 ;;; whether the file is source or executable. If you compile foo.lisp
|
9509
|
2369 ;;; with compile-file, then the next load-file should use foo.bin for
|
17283
|
2370 ;;; the default, not foo.lisp. This is tricky to do right, particularly
|
9509
|
2371 ;;; because the extension for executable files varies so much (.o, .bin,
|
|
2372 ;;; .lbin, .mo, .vo, .ao, ...).
|
|
2373
|
|
2374
|
|
2375 ;;; TERM-SOURCE-DEFAULT -- determines defaults for source-file processing
|
|
2376 ;;; commands.
|
|
2377 ;;;
|
|
2378 ;;; TERM-CHECK-SOURCE -- if FNAME is in a modified buffer, asks you if you
|
|
2379 ;;; want to save the buffer before issuing any process requests to the command
|
|
2380 ;;; interpreter.
|
|
2381 ;;;
|
|
2382 ;;; TERM-GET-SOURCE -- used by the source-file processing commands to prompt
|
|
2383 ;;; for the file to process.
|
|
2384
|
|
2385 ;;; (TERM-SOURCE-DEFAULT previous-dir/file source-modes)
|
|
2386 ;;;============================================================================
|
|
2387 ;;; This function computes the defaults for the load-file and compile-file
|
17283
|
2388 ;;; commands for tea, soar, cmulisp, and cmuscheme modes.
|
|
2389 ;;;
|
|
2390 ;;; - PREVIOUS-DIR/FILE is a pair (directory . filename) from the last
|
|
2391 ;;; source-file processing command, or nil if there hasn't been one yet.
|
9509
|
2392 ;;; - SOURCE-MODES is a list used to determine what buffers contain source
|
|
2393 ;;; files: if the major mode of the buffer is in SOURCE-MODES, it's source.
|
|
2394 ;;; Typically, (lisp-mode) or (scheme-mode).
|
17283
|
2395 ;;;
|
9509
|
2396 ;;; If the command is given while the cursor is inside a string, *and*
|
|
2397 ;;; the string is an existing filename, *and* the filename is not a directory,
|
17283
|
2398 ;;; then the string is taken as default. This allows you to just position
|
9509
|
2399 ;;; your cursor over a string that's a filename and have it taken as default.
|
|
2400 ;;;
|
|
2401 ;;; If the command is given in a file buffer whose major mode is in
|
42706
|
2402 ;;; SOURCE-MODES, then the filename is the default file, and the
|
9509
|
2403 ;;; file's directory is the default directory.
|
17283
|
2404 ;;;
|
9509
|
2405 ;;; If the buffer isn't a source file buffer (e.g., it's the process buffer),
|
|
2406 ;;; then the default directory & file are what was used in the last source-file
|
|
2407 ;;; processing command (i.e., PREVIOUS-DIR/FILE). If this is the first time
|
|
2408 ;;; the command has been run (PREVIOUS-DIR/FILE is nil), the default directory
|
17283
|
2409 ;;; is the cwd, with no default file. (\"no default file\" = nil)
|
|
2410 ;;;
|
9509
|
2411 ;;; SOURCE-REGEXP is typically going to be something like (tea-mode)
|
|
2412 ;;; for T programs, (lisp-mode) for Lisp programs, (soar-mode lisp-mode)
|
|
2413 ;;; for Soar programs, etc.
|
17283
|
2414 ;;;
|
9509
|
2415 ;;; The function returns a pair: (default-directory . default-file).
|
|
2416
|
|
2417 (defun term-source-default (previous-dir/file source-modes)
|
|
2418 (cond ((and buffer-file-name (memq major-mode source-modes))
|
|
2419 (cons (file-name-directory buffer-file-name)
|
|
2420 (file-name-nondirectory buffer-file-name)))
|
|
2421 (previous-dir/file)
|
|
2422 (t
|
|
2423 (cons default-directory nil))))
|
|
2424
|
|
2425
|
|
2426 ;;; (TERM-CHECK-SOURCE fname)
|
|
2427 ;;;============================================================================
|
|
2428 ;;; Prior to loading or compiling (or otherwise processing) a file (in the CMU
|
|
2429 ;;; process-in-a-buffer modes), this function can be called on the filename.
|
|
2430 ;;; If the file is loaded into a buffer, and the buffer is modified, the user
|
|
2431 ;;; is queried to see if he wants to save the buffer before proceeding with
|
|
2432 ;;; the load or compile.
|
|
2433
|
|
2434 (defun term-check-source (fname)
|
|
2435 (let ((buff (get-file-buffer fname)))
|
71054
|
2436 (when (and buff
|
|
2437 (buffer-modified-p buff)
|
|
2438 (y-or-n-p (format "Save buffer %s first? "
|
|
2439 (buffer-name buff))))
|
|
2440 ;; save BUFF.
|
|
2441 (let ((old-buffer (current-buffer)))
|
|
2442 (set-buffer buff)
|
|
2443 (save-buffer)
|
|
2444 (set-buffer old-buffer)))))
|
9509
|
2445
|
|
2446
|
|
2447 ;;; (TERM-GET-SOURCE prompt prev-dir/file source-modes mustmatch-p)
|
|
2448 ;;;============================================================================
|
|
2449 ;;; TERM-GET-SOURCE is used to prompt for filenames in command-interpreter
|
|
2450 ;;; commands that process source files (like loading or compiling a file).
|
|
2451 ;;; It prompts for the filename, provides a default, if there is one,
|
|
2452 ;;; and returns the result filename.
|
17283
|
2453 ;;;
|
9509
|
2454 ;;; See TERM-SOURCE-DEFAULT for more on determining defaults.
|
17283
|
2455 ;;;
|
|
2456 ;;; PROMPT is the prompt string. PREV-DIR/FILE is the (directory . file) pair
|
9509
|
2457 ;;; from the last source processing command. SOURCE-MODES is a list of major
|
|
2458 ;;; modes used to determine what file buffers contain source files. (These
|
17283
|
2459 ;;; two arguments are used for determining defaults). If MUSTMATCH-P is true,
|
9509
|
2460 ;;; then the filename reader will only accept a file that exists.
|
17283
|
2461 ;;;
|
9509
|
2462 ;;; A typical use:
|
|
2463 ;;; (interactive (term-get-source "Compile file: " prev-lisp-dir/file
|
|
2464 ;;; '(lisp-mode) t))
|
|
2465
|
17283
|
2466 ;;; This is pretty stupid about strings. It decides we're in a string
|
9509
|
2467 ;;; if there's a quote on both sides of point on the current line.
|
|
2468 (defun term-extract-string ()
|
63176
7a34bd511117
(term-mode, term-check-proc, term-input-sender, term-simple-send,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
2469 "Return string around `point' that starts the current line or nil."
|
9509
|
2470 (save-excursion
|
|
2471 (let* ((point (point))
|
|
2472 (bol (progn (beginning-of-line) (point)))
|
|
2473 (eol (progn (end-of-line) (point)))
|
17283
|
2474 (start (progn (goto-char point)
|
|
2475 (and (search-backward "\"" bol t)
|
9509
|
2476 (1+ (point)))))
|
|
2477 (end (progn (goto-char point)
|
|
2478 (and (search-forward "\"" eol t)
|
|
2479 (1- (point))))))
|
|
2480 (and start end
|
|
2481 (buffer-substring start end)))))
|
|
2482
|
|
2483 (defun term-get-source (prompt prev-dir/file source-modes mustmatch-p)
|
|
2484 (let* ((def (term-source-default prev-dir/file source-modes))
|
|
2485 (stringfile (term-extract-string))
|
|
2486 (sfile-p (and stringfile
|
|
2487 (condition-case ()
|
|
2488 (file-exists-p stringfile)
|
|
2489 (error nil))
|
|
2490 (not (file-directory-p stringfile))))
|
|
2491 (defdir (if sfile-p (file-name-directory stringfile)
|
|
2492 (car def)))
|
|
2493 (deffile (if sfile-p (file-name-nondirectory stringfile)
|
|
2494 (cdr def)))
|
|
2495 (ans (read-file-name (if deffile (format "%s(default %s) "
|
|
2496 prompt deffile)
|
|
2497 prompt)
|
|
2498 defdir
|
|
2499 (concat defdir deffile)
|
|
2500 mustmatch-p)))
|
|
2501 (list (expand-file-name (substitute-in-file-name ans)))))
|
|
2502
|
17283
|
2503 ;;; I am somewhat divided on this string-default feature. It seems
|
9509
|
2504 ;;; to violate the principle-of-least-astonishment, in that it makes
|
|
2505 ;;; the default harder to predict, so you actually have to look and see
|
17283
|
2506 ;;; what the default really is before choosing it. This can trip you up.
|
|
2507 ;;; On the other hand, it can be useful, I guess. I would appreciate feedback
|
9509
|
2508 ;;; on this.
|
|
2509 ;;; -Olin
|
|
2510
|
|
2511
|
|
2512 ;;; Simple process query facility.
|
|
2513 ;;; ===========================================================================
|
|
2514 ;;; This function is for commands that want to send a query to the process
|
17283
|
2515 ;;; and show the response to the user. For example, a command to get the
|
9509
|
2516 ;;; arglist for a Common Lisp function might send a "(arglist 'foo)" query
|
|
2517 ;;; to an inferior Common Lisp process.
|
17283
|
2518 ;;;
|
9509
|
2519 ;;; This simple facility just sends strings to the inferior process and pops
|
|
2520 ;;; up a window for the process buffer so you can see what the process
|
|
2521 ;;; responds with. We don't do anything fancy like try to intercept what the
|
|
2522 ;;; process responds with and put it in a pop-up window or on the message
|
17283
|
2523 ;;; line. We just display the buffer. Low tech. Simple. Works good.
|
|
2524
|
|
2525 ;;; Send to the inferior process PROC the string STR. Pop-up but do not select
|
9509
|
2526 ;;; a window for the inferior process so that its response can be seen.
|
|
2527 (defun term-proc-query (proc str)
|
|
2528 (let* ((proc-buf (process-buffer proc))
|
|
2529 (proc-mark (process-mark proc)))
|
|
2530 (display-buffer proc-buf)
|
|
2531 (set-buffer proc-buf) ; but it's not the selected *window*
|
|
2532 (let ((proc-win (get-buffer-window proc-buf))
|
|
2533 (proc-pt (marker-position proc-mark)))
|
|
2534 (term-send-string proc str) ; send the query
|
|
2535 (accept-process-output proc) ; wait for some output
|
|
2536 ;; Try to position the proc window so you can see the answer.
|
17283
|
2537 ;; This is bogus code. If you delete the (sit-for 0), it breaks.
|
|
2538 ;; I don't know why. Wizards invited to improve it.
|
71054
|
2539 (when (not (pos-visible-in-window-p proc-pt proc-win))
|
|
2540 (let ((opoint (window-point proc-win)))
|
|
2541 (set-window-point proc-win proc-mark) (sit-for 0)
|
|
2542 (if (not (pos-visible-in-window-p opoint proc-win))
|
|
2543 (push-mark opoint)
|
|
2544 (set-window-point proc-win opoint)))))))
|
9509
|
2545
|
|
2546 ;;; Returns the current column in the current screen line.
|
|
2547 ;;; Note: (current-column) yields column in buffer line.
|
|
2548
|
|
2549 (defun term-horizontal-column ()
|
|
2550 (- (term-current-column) (term-start-line-column)))
|
|
2551
|
61481
d4014c213e7e
* term.el (term-ansi-current-bold, term-ansi-current-underline)
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
2552 ;; Calls either vertical-motion or term-buffer-vertical-motion
|
9509
|
2553 (defmacro term-vertical-motion (count)
|
|
2554 (list 'funcall 'term-vertical-motion count))
|
|
2555
|
|
2556 ;; An emulation of vertical-motion that is independent of having a window.
|
|
2557 ;; Instead, it uses the term-width variable as the logical window width.
|
|
2558
|
61481
d4014c213e7e
* term.el (term-ansi-current-bold, term-ansi-current-underline)
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
2559 (defun term-buffer-vertical-motion (count)
|
9509
|
2560 (cond ((= count 0)
|
|
2561 (move-to-column (* term-width (/ (current-column) term-width)))
|
|
2562 0)
|
|
2563 ((> count 0)
|
|
2564 (let ((H)
|
|
2565 (todo (+ count (/ (current-column) term-width))))
|
|
2566 (end-of-line)
|
13961
|
2567 ;; The loop iterates over buffer lines;
|
9509
|
2568 ;; H is the number of screen lines in the current line, i.e.
|
|
2569 ;; the ceiling of dividing the buffer line width by term-width.
|
|
2570 (while (and (<= (setq H (max (/ (+ (current-column) term-width -1)
|
|
2571 term-width)
|
|
2572 1))
|
|
2573 todo)
|
|
2574 (not (eobp)))
|
|
2575 (setq todo (- todo H))
|
|
2576 (forward-char) ;; Move past the ?\n
|
|
2577 (end-of-line)) ;; and on to the end of the next line.
|
|
2578 (if (and (>= todo H) (> todo 0))
|
|
2579 (+ (- count todo) H -1) ;; Hit end of buffer.
|
|
2580 (move-to-column (* todo term-width))
|
|
2581 count)))
|
|
2582 (t ;; (< count 0) ;; Similar algorithm, but for upward motion.
|
|
2583 (let ((H)
|
|
2584 (todo (- count)))
|
|
2585 (while (and (<= (setq H (max (/ (+ (current-column) term-width -1)
|
|
2586 term-width)
|
|
2587 1))
|
|
2588 todo)
|
|
2589 (progn (beginning-of-line)
|
|
2590 (not (bobp))))
|
|
2591 (setq todo (- todo H))
|
13961
|
2592 (backward-char)) ;; Move to end of previous line.
|
9509
|
2593 (if (and (>= todo H) (> todo 0))
|
|
2594 (+ count todo (- 1 H)) ;; Hit beginning of buffer.
|
|
2595 (move-to-column (* (- H todo 1) term-width))
|
|
2596 count)))))
|
|
2597
|
|
2598 ;;; The term-start-line-column variable is used as a cache.
|
|
2599 (defun term-start-line-column ()
|
|
2600 (cond (term-start-line-column)
|
|
2601 ((let ((save-pos (point)))
|
|
2602 (term-vertical-motion 0)
|
|
2603 (setq term-start-line-column (current-column))
|
|
2604 (goto-char save-pos)
|
|
2605 term-start-line-column))))
|
|
2606
|
|
2607 ;;; Same as (current-column), but uses term-current-column as a cache.
|
|
2608 (defun term-current-column ()
|
|
2609 (cond (term-current-column)
|
|
2610 ((setq term-current-column (current-column)))))
|
|
2611
|
36763
00b03757e45b
These changes are based on a patch sent from Yong Lu <lyongu@yahoo.com>.
Kenichi Handa <handa@m17n.org>
diff
changeset
|
2612 ;;; Move DELTA column right (or left if delta < 0 limiting at column 0).
|
9509
|
2613
|
|
2614 (defun term-move-columns (delta)
|
36763
00b03757e45b
These changes are based on a patch sent from Yong Lu <lyongu@yahoo.com>.
Kenichi Handa <handa@m17n.org>
diff
changeset
|
2615 (setq term-current-column (max 0 (+ (term-current-column) delta)))
|
61010
|
2616 (let (point-at-eol)
|
|
2617 (save-excursion
|
|
2618 (end-of-line)
|
|
2619 (setq point-at-eol (point)))
|
|
2620 (move-to-column term-current-column t)
|
|
2621 ;; If move-to-column extends the current line it will use the face
|
|
2622 ;; from the last character on the line, set the face for the chars
|
|
2623 ;; to default.
|
|
2624 (when (> (point) point-at-eol)
|
|
2625 (put-text-property point-at-eol (point) 'face 'default))))
|
9509
|
2626
|
|
2627 ;; Insert COUNT copies of CHAR in the default face.
|
|
2628 (defun term-insert-char (char count)
|
|
2629 (let ((old-point (point)))
|
|
2630 (insert-char char count)
|
|
2631 (put-text-property old-point (point) 'face 'default)))
|
|
2632
|
|
2633 (defun term-current-row ()
|
|
2634 (cond (term-current-row)
|
|
2635 ((setq term-current-row
|
|
2636 (save-restriction
|
|
2637 (save-excursion
|
|
2638 (narrow-to-region term-home-marker (point-max))
|
|
2639 (- (term-vertical-motion -9999))))))))
|
|
2640
|
|
2641 (defun term-adjust-current-row-cache (delta)
|
57299
|
2642 (when term-current-row
|
63176
7a34bd511117
(term-mode, term-check-proc, term-input-sender, term-simple-send,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
2643 (setq term-current-row
|
57299
|
2644 (max 0 (+ term-current-row delta)))))
|
9509
|
2645
|
|
2646 (defun term-terminal-pos ()
|
|
2647 (save-excursion ; save-restriction
|
|
2648 (let ((save-col (term-current-column))
|
10671
|
2649 x y)
|
9509
|
2650 (term-vertical-motion 0)
|
|
2651 (setq x (- save-col (current-column)))
|
|
2652 (setq y (term-vertical-motion term-height))
|
|
2653 (cons x y))))
|
|
2654
|
17283
|
2655 ;;;Function that handles term messages: code by rms ( and you can see the
|
|
2656 ;;;difference ;-) -mm
|
|
2657
|
|
2658 (defun term-handle-ansi-terminal-messages (message)
|
|
2659 ;; Is there a command here?
|
|
2660 (while (string-match "\eAnSiT.+\n" message)
|
|
2661 ;; Extract the command code and the argument.
|
|
2662 (let* ((start (match-beginning 0))
|
|
2663 (end (match-end 0))
|
|
2664 (command-code (aref message (+ start 6)))
|
|
2665 (argument
|
|
2666 (save-match-data
|
|
2667 (substring message
|
|
2668 (+ start 8)
|
|
2669 (string-match "\r?\n" message
|
|
2670 (+ start 8)))))
|
|
2671 ignore)
|
|
2672 ;; Delete this command from MESSAGE.
|
|
2673 (setq message (replace-match "" t t message))
|
|
2674
|
|
2675 ;; If we recognize the type of command, set the appropriate variable.
|
|
2676 (cond ((= command-code ?c)
|
|
2677 (setq term-ansi-at-dir argument))
|
|
2678 ((= command-code ?h)
|
|
2679 (setq term-ansi-at-host argument))
|
|
2680 ((= command-code ?u)
|
|
2681 (setq term-ansi-at-user argument))
|
|
2682 ;; Otherwise ignore this one.
|
|
2683 (t
|
|
2684 (setq ignore t)))
|
|
2685
|
|
2686 ;; Update default-directory based on the changes this command made.
|
|
2687 (if ignore
|
|
2688 nil
|
|
2689 (setq default-directory
|
|
2690 (file-name-as-directory
|
|
2691 (if (and (string= term-ansi-at-host (system-name))
|
|
2692 (string= term-ansi-at-user (user-real-login-name)))
|
|
2693 (expand-file-name term-ansi-at-dir)
|
|
2694 (if (string= term-ansi-at-user (user-real-login-name))
|
|
2695 (concat "/" term-ansi-at-host ":" term-ansi-at-dir)
|
|
2696 (concat "/" term-ansi-at-user "@" term-ansi-at-host ":"
|
|
2697 term-ansi-at-dir)))))
|
|
2698
|
|
2699 ;; I'm not sure this is necessary,
|
|
2700 ;; but it's best to be on the safe side.
|
|
2701 (if (string= term-ansi-at-host (system-name))
|
|
2702 (progn
|
|
2703 (setq ange-ftp-default-user term-ansi-at-save-user)
|
|
2704 (setq ange-ftp-default-password term-ansi-at-save-pwd)
|
|
2705 (setq ange-ftp-generate-anonymous-password term-ansi-at-save-anon))
|
|
2706 (setq term-ansi-at-save-user ange-ftp-default-user)
|
|
2707 (setq term-ansi-at-save-pwd ange-ftp-default-password)
|
|
2708 (setq term-ansi-at-save-anon ange-ftp-generate-anonymous-password)
|
|
2709 (setq ange-ftp-default-user nil)
|
|
2710 (setq ange-ftp-default-password nil)
|
|
2711 (setq ange-ftp-generate-anonymous-password nil)))))
|
|
2712 message)
|
|
2713
|
|
2714
|
9509
|
2715 ;;; Terminal emulation
|
|
2716 ;;; This is the standard process filter for term buffers.
|
|
2717 ;;; It emulates (most of the features of) a VT100/ANSI-style terminal.
|
|
2718
|
|
2719 (defun term-emulate-terminal (proc str)
|
57163
|
2720 (with-current-buffer (process-buffer proc)
|
98333
aedea0a2dba4
(term-emulate-terminal): Encode input string before checking its
Chong Yidong <cyd@stupidchicken.com>
diff
changeset
|
2721 (let* ((i 0) char funny
|
aedea0a2dba4
(term-emulate-terminal): Encode input string before checking its
Chong Yidong <cyd@stupidchicken.com>
diff
changeset
|
2722 count ; number of decoded chars in substring
|
aedea0a2dba4
(term-emulate-terminal): Encode input string before checking its
Chong Yidong <cyd@stupidchicken.com>
diff
changeset
|
2723 count-bytes ; number of bytes
|
aedea0a2dba4
(term-emulate-terminal): Encode input string before checking its
Chong Yidong <cyd@stupidchicken.com>
diff
changeset
|
2724 decoded-substring
|
aedea0a2dba4
(term-emulate-terminal): Encode input string before checking its
Chong Yidong <cyd@stupidchicken.com>
diff
changeset
|
2725 save-point save-marker old-point temp win
|
57163
|
2726 (buffer-undo-list t)
|
|
2727 (selected (selected-window))
|
|
2728 last-win
|
67608
997221d30164
(term-emulate-terminal): Let term-handle-ansi-terminal-messages override
Eli Zaretskii <eliz@gnu.org>
diff
changeset
|
2729 handled-ansi-message
|
57163
|
2730 (str-length (length str)))
|
|
2731 (save-selected-window
|
|
2732
|
|
2733 ;; Let's handle the messages. -mm
|
|
2734
|
67608
997221d30164
(term-emulate-terminal): Let term-handle-ansi-terminal-messages override
Eli Zaretskii <eliz@gnu.org>
diff
changeset
|
2735 (let* ((newstr (term-handle-ansi-terminal-messages str)))
|
71054
|
2736 (when (not (eq str newstr))
|
|
2737 (setq handled-ansi-message t
|
|
2738 str newstr)))
|
67608
997221d30164
(term-emulate-terminal): Let term-handle-ansi-terminal-messages override
Eli Zaretskii <eliz@gnu.org>
diff
changeset
|
2739 (setq str-length (length str))
|
57163
|
2740
|
71054
|
2741 (when (marker-buffer term-pending-delete-marker)
|
|
2742 ;; Delete text following term-pending-delete-marker.
|
|
2743 (delete-region term-pending-delete-marker (process-mark proc))
|
|
2744 (set-marker term-pending-delete-marker nil))
|
57163
|
2745
|
|
2746 (if (eq (window-buffer) (current-buffer))
|
|
2747 (progn
|
|
2748 (setq term-vertical-motion (symbol-function 'vertical-motion))
|
|
2749 (term-check-size proc))
|
|
2750 (setq term-vertical-motion
|
61481
d4014c213e7e
* term.el (term-ansi-current-bold, term-ansi-current-underline)
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
2751 (symbol-function 'term-buffer-vertical-motion)))
|
57163
|
2752
|
|
2753 (setq save-marker (copy-marker (process-mark proc)))
|
|
2754
|
71054
|
2755 (when (/= (point) (process-mark proc))
|
|
2756 (setq save-point (point-marker))
|
|
2757 (goto-char (process-mark proc)))
|
57163
|
2758
|
|
2759 (save-restriction
|
|
2760 ;; If the buffer is in line mode, and there is a partial
|
|
2761 ;; input line, save the line (by narrowing to leave it
|
|
2762 ;; outside the restriction ) until we're done with output.
|
71054
|
2763 (when (and (> (point-max) (process-mark proc))
|
|
2764 (term-in-line-mode))
|
|
2765 (narrow-to-region (point-min) (process-mark proc)))
|
|
2766
|
|
2767 (when term-log-buffer
|
|
2768 (princ str term-log-buffer))
|
57163
|
2769 (cond ((eq term-terminal-state 4) ;; Have saved pending output.
|
|
2770 (setq str (concat term-terminal-parameter str))
|
|
2771 (setq term-terminal-parameter nil)
|
|
2772 (setq str-length (length str))
|
|
2773 (setq term-terminal-state 0)))
|
|
2774
|
|
2775 (while (< i str-length)
|
|
2776 (setq char (aref str i))
|
|
2777 (cond ((< term-terminal-state 2)
|
|
2778 ;; Look for prefix of regular chars
|
|
2779 (setq funny
|
|
2780 (string-match "[\r\n\000\007\033\t\b\032\016\017]"
|
|
2781 str i))
|
71054
|
2782 (when (not funny) (setq funny str-length))
|
57163
|
2783 (cond ((> funny i)
|
98334
|
2784 ;; Decode the string before counting
|
|
2785 ;; characters, to avoid garbling of certain
|
|
2786 ;; multibyte characters (bug#1006).
|
98333
aedea0a2dba4
(term-emulate-terminal): Encode input string before checking its
Chong Yidong <cyd@stupidchicken.com>
diff
changeset
|
2787 (setq decoded-substring
|
aedea0a2dba4
(term-emulate-terminal): Encode input string before checking its
Chong Yidong <cyd@stupidchicken.com>
diff
changeset
|
2788 (decode-coding-string
|
aedea0a2dba4
(term-emulate-terminal): Encode input string before checking its
Chong Yidong <cyd@stupidchicken.com>
diff
changeset
|
2789 (substring str i funny)
|
aedea0a2dba4
(term-emulate-terminal): Encode input string before checking its
Chong Yidong <cyd@stupidchicken.com>
diff
changeset
|
2790 locale-coding-system))
|
57163
|
2791 (cond ((eq term-terminal-state 1)
|
57234
|
2792 ;; We are in state 1, we need to wrap
|
|
2793 ;; around. Go to the beginning of
|
|
2794 ;; the next line and switch to state
|
|
2795 ;; 0.
|
68203
|
2796 (term-down 1 t)
|
57234
|
2797 (term-move-columns (- (term-current-column)))
|
57163
|
2798 (setq term-terminal-state 0)))
|
98333
aedea0a2dba4
(term-emulate-terminal): Encode input string before checking its
Chong Yidong <cyd@stupidchicken.com>
diff
changeset
|
2799 (setq count (length decoded-substring))
|
57163
|
2800 (setq temp (- (+ (term-horizontal-column) count)
|
|
2801 term-width))
|
|
2802 (cond ((<= temp 0)) ;; All count chars fit in line.
|
|
2803 ((> count temp) ;; Some chars fit.
|
|
2804 ;; This iteration, handle only what fits.
|
|
2805 (setq count (- count temp))
|
98333
aedea0a2dba4
(term-emulate-terminal): Encode input string before checking its
Chong Yidong <cyd@stupidchicken.com>
diff
changeset
|
2806 (setq count-bytes
|
aedea0a2dba4
(term-emulate-terminal): Encode input string before checking its
Chong Yidong <cyd@stupidchicken.com>
diff
changeset
|
2807 (length
|
aedea0a2dba4
(term-emulate-terminal): Encode input string before checking its
Chong Yidong <cyd@stupidchicken.com>
diff
changeset
|
2808 (encode-coding-string
|
aedea0a2dba4
(term-emulate-terminal): Encode input string before checking its
Chong Yidong <cyd@stupidchicken.com>
diff
changeset
|
2809 (substring decoded-substring 0 count)
|
aedea0a2dba4
(term-emulate-terminal): Encode input string before checking its
Chong Yidong <cyd@stupidchicken.com>
diff
changeset
|
2810 'binary)))
|
57234
|
2811 (setq temp 0)
|
98333
aedea0a2dba4
(term-emulate-terminal): Encode input string before checking its
Chong Yidong <cyd@stupidchicken.com>
diff
changeset
|
2812 (setq funny (+ count-bytes i)))
|
57163
|
2813 ((or (not (or term-pager-count
|
|
2814 term-scroll-with-delete))
|
|
2815 (> (term-handle-scroll 1) 0))
|
|
2816 (term-adjust-current-row-cache 1)
|
|
2817 (setq count (min count term-width))
|
98333
aedea0a2dba4
(term-emulate-terminal): Encode input string before checking its
Chong Yidong <cyd@stupidchicken.com>
diff
changeset
|
2818 (setq count-bytes
|
aedea0a2dba4
(term-emulate-terminal): Encode input string before checking its
Chong Yidong <cyd@stupidchicken.com>
diff
changeset
|
2819 (length
|
aedea0a2dba4
(term-emulate-terminal): Encode input string before checking its
Chong Yidong <cyd@stupidchicken.com>
diff
changeset
|
2820 (encode-coding-string
|
aedea0a2dba4
(term-emulate-terminal): Encode input string before checking its
Chong Yidong <cyd@stupidchicken.com>
diff
changeset
|
2821 (substring decoded-substring 0 count)
|
aedea0a2dba4
(term-emulate-terminal): Encode input string before checking its
Chong Yidong <cyd@stupidchicken.com>
diff
changeset
|
2822 'binary)))
|
aedea0a2dba4
(term-emulate-terminal): Encode input string before checking its
Chong Yidong <cyd@stupidchicken.com>
diff
changeset
|
2823 (setq funny (+ count-bytes i))
|
57163
|
2824 (setq term-start-line-column
|
|
2825 term-current-column))
|
|
2826 (t ;; Doing PAGER processing.
|
|
2827 (setq count 0 funny i)
|
|
2828 (setq term-current-column nil)
|
|
2829 (setq term-start-line-column nil)))
|
|
2830 (setq old-point (point))
|
|
2831
|
|
2832 ;; Insert a string, check how many columns
|
|
2833 ;; we moved, then delete that many columns
|
|
2834 ;; following point if not eob nor insert-mode.
|
|
2835 (let ((old-column (current-column))
|
|
2836 columns pos)
|
98333
aedea0a2dba4
(term-emulate-terminal): Encode input string before checking its
Chong Yidong <cyd@stupidchicken.com>
diff
changeset
|
2837 (insert decoded-substring)
|
57163
|
2838 (setq term-current-column (current-column)
|
|
2839 columns (- term-current-column old-column))
|
|
2840 (when (not (or (eobp) term-insert-mode))
|
|
2841 (setq pos (point))
|
|
2842 (term-move-columns columns)
|
57299
|
2843 (delete-region pos (point)))
|
68203
|
2844 ;; In insert mode if the current line
|
57299
|
2845 ;; has become too long it needs to be
|
|
2846 ;; chopped off.
|
63176
7a34bd511117
(term-mode, term-check-proc, term-input-sender, term-simple-send,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
2847 (when term-insert-mode
|
57299
|
2848 (setq pos (point))
|
|
2849 (end-of-line)
|
|
2850 (when (> (current-column) term-width)
|
63176
7a34bd511117
(term-mode, term-check-proc, term-input-sender, term-simple-send,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
2851 (delete-region (- (point) (- (current-column) term-width))
|
57299
|
2852 (point)))
|
|
2853 (goto-char pos)))
|
57163
|
2854 (setq term-current-column nil)
|
|
2855
|
|
2856 (put-text-property old-point (point)
|
|
2857 'face term-current-face)
|
|
2858 ;; If the last char was written in last column,
|
|
2859 ;; back up one column, but remember we did so.
|
|
2860 ;; Thus we emulate xterm/vt100-style line-wrapping.
|
|
2861 (cond ((eq temp 0)
|
|
2862 (term-move-columns -1)
|
|
2863 (setq term-terminal-state 1)))
|
|
2864 (setq i (1- funny)))
|
|
2865 ((and (setq term-terminal-state 0)
|
57234
|
2866 (eq char ?\^I)) ; TAB (terminfo: ht)
|
57163
|
2867 (setq count (term-current-column))
|
57299
|
2868 ;; The line cannot exceed term-width. TAB at
|
|
2869 ;; the end of a line should not cause wrapping.
|
63176
7a34bd511117
(term-mode, term-check-proc, term-input-sender, term-simple-send,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
2870 (setq count (min term-width
|
57299
|
2871 (+ count 8 (- (mod count 8)))))
|
|
2872 (if (> term-width count)
|
71054
|
2873 (progn
|
|
2874 (term-move-columns
|
|
2875 (- count (term-current-column)))
|
|
2876 (setq term-current-column count))
|
57299
|
2877 (when (> term-width (term-current-column))
|
63176
7a34bd511117
(term-mode, term-check-proc, term-input-sender, term-simple-send,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
2878 (term-move-columns
|
57299
|
2879 (1- (- term-width (term-current-column)))))
|
|
2880 (when (= term-width (term-current-column))
|
|
2881 (term-move-columns -1))))
|
66461
|
2882 ((eq char ?\r) ;; (terminfo: cr)
|
68203
|
2883 (term-vertical-motion 0)
|
|
2884 (setq term-current-column term-start-line-column))
|
66461
|
2885 ((eq char ?\n) ;; (terminfo: cud1, ind)
|
68203
|
2886 (unless (and term-kill-echo-list
|
|
2887 (term-check-kill-echo-list))
|
|
2888 (term-down 1 t)))
|
57234
|
2889 ((eq char ?\b) ;; (terminfo: cub1)
|
57163
|
2890 (term-move-columns -1))
|
|
2891 ((eq char ?\033) ; Escape
|
|
2892 (setq term-terminal-state 2))
|
|
2893 ((eq char 0)) ; NUL: Do nothing
|
|
2894 ((eq char ?\016)) ; Shift Out - ignored
|
|
2895 ((eq char ?\017)) ; Shift In - ignored
|
66461
|
2896 ((eq char ?\^G) ;; (terminfo: bel)
|
|
2897 (beep t))
|
67608
997221d30164
(term-emulate-terminal): Let term-handle-ansi-terminal-messages override
Eli Zaretskii <eliz@gnu.org>
diff
changeset
|
2898 ((and (eq char ?\032)
|
997221d30164
(term-emulate-terminal): Let term-handle-ansi-terminal-messages override
Eli Zaretskii <eliz@gnu.org>
diff
changeset
|
2899 (not handled-ansi-message))
|
57163
|
2900 (let ((end (string-match "\r?$" str i)))
|
|
2901 (if end
|
|
2902 (funcall term-command-hook
|
|
2903 (prog1 (substring str (1+ i) end)
|
|
2904 (setq i (match-end 0))))
|
66461
|
2905 (setq term-terminal-parameter (substring str i))
|
57163
|
2906 (setq term-terminal-state 4)
|
|
2907 (setq i str-length))))
|
|
2908 (t ; insert char FIXME: Should never happen
|
|
2909 (term-move-columns 1)
|
|
2910 (backward-delete-char 1)
|
|
2911 (insert char))))
|
|
2912 ((eq term-terminal-state 2) ; Seen Esc
|
|
2913 (cond ((eq char ?\133) ;; ?\133 = ?[
|
17283
|
2914
|
|
2915 ;;; Some modifications to cope with multiple settings like ^[[01;32;43m -mm
|
|
2916 ;;; Note that now the init value of term-terminal-previous-parameter has
|
|
2917 ;;; been changed to -1
|
|
2918
|
57163
|
2919 (setq term-terminal-parameter 0)
|
|
2920 (setq term-terminal-previous-parameter -1)
|
|
2921 (setq term-terminal-previous-parameter-2 -1)
|
|
2922 (setq term-terminal-previous-parameter-3 -1)
|
|
2923 (setq term-terminal-previous-parameter-4 -1)
|
|
2924 (setq term-terminal-more-parameters 0)
|
|
2925 (setq term-terminal-state 3))
|
|
2926 ((eq char ?D) ;; scroll forward
|
|
2927 (term-handle-deferred-scroll)
|
|
2928 (term-down 1 t)
|
|
2929 (setq term-terminal-state 0))
|
57299
|
2930 ;; ((eq char ?E) ;; (terminfo: nw), not used for
|
|
2931 ;; ;; now, but this is a working
|
|
2932 ;; ;; implementation
|
|
2933 ;; (term-down 1)
|
|
2934 ;; (term-goto term-current-row 0)
|
|
2935 ;; (setq term-terminal-state 0))
|
|
2936 ((eq char ?M) ;; scroll reversed (terminfo: ri)
|
68203
|
2937 (if (or (< (term-current-row) term-scroll-start)
|
77169
8905fec7d280
(term-buffer-maximum-size, term-exec, term-escape-char, term-set-escape-char,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
2938 (>= (1- (term-current-row))
|
68203
|
2939 term-scroll-start))
|
|
2940 ;; Scrolling up will not move outside
|
|
2941 ;; the scroll region.
|
|
2942 (term-down -1)
|
|
2943 ;; Scrolling the scroll region is needed.
|
|
2944 (term-down -1 t))
|
57163
|
2945 (setq term-terminal-state 0))
|
57234
|
2946 ((eq char ?7) ;; Save cursor (terminfo: sc)
|
57163
|
2947 (term-handle-deferred-scroll)
|
|
2948 (setq term-saved-cursor
|
68203
|
2949 (list (term-current-row)
|
|
2950 (term-horizontal-column)
|
|
2951 term-ansi-current-bg-color
|
|
2952 term-ansi-current-bold
|
|
2953 term-ansi-current-color
|
|
2954 term-ansi-current-invisible
|
|
2955 term-ansi-current-reverse
|
|
2956 term-ansi-current-underline
|
|
2957 term-current-face)
|
|
2958 )
|
57163
|
2959 (setq term-terminal-state 0))
|
57234
|
2960 ((eq char ?8) ;; Restore cursor (terminfo: rc)
|
68203
|
2961 (when term-saved-cursor
|
|
2962 (term-goto (nth 0 term-saved-cursor)
|
|
2963 (nth 1 term-saved-cursor))
|
77169
8905fec7d280
(term-buffer-maximum-size, term-exec, term-escape-char, term-set-escape-char,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
2964 (setq term-ansi-current-bg-color
|
68203
|
2965 (nth 2 term-saved-cursor)
|
|
2966 term-ansi-current-bold
|
|
2967 (nth 3 term-saved-cursor)
|
|
2968 term-ansi-current-color
|
|
2969 (nth 4 term-saved-cursor)
|
|
2970 term-ansi-current-invisible
|
|
2971 (nth 5 term-saved-cursor)
|
|
2972 term-ansi-current-reverse
|
|
2973 (nth 6 term-saved-cursor)
|
|
2974 term-ansi-current-underline
|
|
2975 (nth 7 term-saved-cursor)
|
|
2976 term-current-face
|
|
2977 (nth 8 term-saved-cursor)))
|
57163
|
2978 (setq term-terminal-state 0))
|
63176
7a34bd511117
(term-mode, term-check-proc, term-input-sender, term-simple-send,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
2979 ((eq char ?c) ;; \Ec - Reset (terminfo: rs1)
|
58892
|
2980 ;; This is used by the "clear" program.
|
|
2981 (setq term-terminal-state 0)
|
|
2982 (term-reset-terminal))
|
57299
|
2983 ;; The \E#8 reset sequence for xterm. We
|
|
2984 ;; probably don't need to handle it, but this
|
|
2985 ;; is the code to parse it.
|
|
2986 ;; ((eq char ?#)
|
|
2987 ;; (when (eq (aref str (1+ i)) ?8)
|
|
2988 ;; (setq i (1+ i))
|
68203
|
2989 ;; (setq term-scroll-start 0)
|
|
2990 ;; (setq term-scroll-end term-height)
|
57299
|
2991 ;; (setq term-terminal-state 0)))
|
57163
|
2992 ((setq term-terminal-state 0))))
|
|
2993 ((eq term-terminal-state 3) ; Seen Esc [
|
|
2994 (cond ((and (>= char ?0) (<= char ?9))
|
|
2995 (setq term-terminal-parameter
|
|
2996 (+ (* 10 term-terminal-parameter) (- char ?0))))
|
|
2997 ((eq char ?\;)
|
17283
|
2998 ;;; Some modifications to cope with multiple settings like ^[[01;32;43m -mm
|
57163
|
2999 (setq term-terminal-more-parameters 1)
|
|
3000 (setq term-terminal-previous-parameter-4
|
|
3001 term-terminal-previous-parameter-3)
|
|
3002 (setq term-terminal-previous-parameter-3
|
|
3003 term-terminal-previous-parameter-2)
|
|
3004 (setq term-terminal-previous-parameter-2
|
|
3005 term-terminal-previous-parameter)
|
|
3006 (setq term-terminal-previous-parameter
|
|
3007 term-terminal-parameter)
|
|
3008 (setq term-terminal-parameter 0))
|
|
3009 ((eq char ??)) ; Ignore ?
|
|
3010 (t
|
|
3011 (term-handle-ansi-escape proc char)
|
|
3012 (setq term-terminal-more-parameters 0)
|
|
3013 (setq term-terminal-previous-parameter-4 -1)
|
|
3014 (setq term-terminal-previous-parameter-3 -1)
|
|
3015 (setq term-terminal-previous-parameter-2 -1)
|
|
3016 (setq term-terminal-previous-parameter -1)
|
|
3017 (setq term-terminal-state 0)))))
|
71054
|
3018 (when (term-handling-pager)
|
|
3019 ;; Finish stuff to get ready to handle PAGER.
|
|
3020 (if (> (% (current-column) term-width) 0)
|
|
3021 (setq term-terminal-parameter
|
|
3022 (substring str i))
|
|
3023 ;; We're at column 0. Goto end of buffer; to compensate,
|
|
3024 ;; prepend a ?\r for later. This looks more consistent.
|
|
3025 (if (zerop i)
|
|
3026 (setq term-terminal-parameter
|
|
3027 (concat "\r" (substring str i)))
|
|
3028 (setq term-terminal-parameter (substring str (1- i)))
|
|
3029 (aset term-terminal-parameter 0 ?\r))
|
|
3030 (goto-char (point-max)))
|
|
3031 (setq term-terminal-state 4)
|
|
3032 (make-local-variable 'term-pager-old-filter)
|
|
3033 (setq term-pager-old-filter (process-filter proc))
|
|
3034 (set-process-filter proc term-pager-filter)
|
|
3035 (setq i str-length))
|
57163
|
3036 (setq i (1+ i))))
|
|
3037
|
71054
|
3038 (when (>= (term-current-row) term-height)
|
|
3039 (term-handle-deferred-scroll))
|
57163
|
3040
|
|
3041 (set-marker (process-mark proc) (point))
|
71054
|
3042 (when save-point
|
|
3043 (goto-char save-point)
|
|
3044 (set-marker save-point nil))
|
57163
|
3045
|
|
3046 ;; Check for a pending filename-and-line number to display.
|
|
3047 ;; We do this before scrolling, because we might create a new window.
|
71054
|
3048 (when (and term-pending-frame
|
|
3049 (eq (window-buffer selected) (current-buffer)))
|
|
3050 (term-display-line (car term-pending-frame)
|
|
3051 (cdr term-pending-frame))
|
|
3052 (setq term-pending-frame nil)
|
|
3053 ;; We have created a new window, so check the window size.
|
|
3054 (term-check-size proc))
|
57163
|
3055
|
|
3056 ;; Scroll each window displaying the buffer but (by default)
|
|
3057 ;; only if the point matches the process-mark we started with.
|
|
3058 (setq win selected)
|
|
3059 ;; Avoid infinite loop in strange case where minibuffer window
|
|
3060 ;; is selected but not active.
|
|
3061 (while (window-minibuffer-p win)
|
|
3062 (setq win (next-window win nil t)))
|
|
3063 (setq last-win win)
|
|
3064 (while (progn
|
|
3065 (setq win (next-window win nil t))
|
71054
|
3066 (when (eq (window-buffer win) (process-buffer proc))
|
|
3067 (let ((scroll term-scroll-to-bottom-on-output))
|
|
3068 (select-window win)
|
|
3069 (when (or (= (point) save-marker)
|
57163
|
3070 (eq scroll t) (eq scroll 'all)
|
|
3071 ;; Maybe user wants point to jump to the end.
|
|
3072 (and (eq selected win)
|
|
3073 (or (eq scroll 'this) (not save-point)))
|
|
3074 (and (eq scroll 'others)
|
|
3075 (not (eq selected win))))
|
71054
|
3076 (goto-char term-home-marker)
|
|
3077 (recenter 0)
|
|
3078 (goto-char (process-mark proc))
|
|
3079 (if (not (pos-visible-in-window-p (point) win))
|
|
3080 (recenter -1)))
|
|
3081 ;; Optionally scroll so that the text
|
|
3082 ;; ends at the bottom of the window.
|
|
3083 (when (and term-scroll-show-maximum-output
|
57163
|
3084 (>= (point) (process-mark proc)))
|
71054
|
3085 (save-excursion
|
|
3086 (goto-char (point-max))
|
|
3087 (recenter -1)))))
|
57163
|
3088 (not (eq win last-win))))
|
9509
|
3089
|
17283
|
3090 ;;; Stolen from comint.el and adapted -mm
|
71054
|
3091 (when (> term-buffer-maximum-size 0)
|
|
3092 (save-excursion
|
|
3093 (goto-char (process-mark (get-buffer-process (current-buffer))))
|
|
3094 (forward-line (- term-buffer-maximum-size))
|
|
3095 (beginning-of-line)
|
|
3096 (delete-region (point-min) (point))))
|
94213
c09516cc5cf4
(term-emulate-terminal): Perform redisplay after the process filter
Chong Yidong <cyd@stupidchicken.com>
diff
changeset
|
3097 (set-marker save-marker nil)))
|
c09516cc5cf4
(term-emulate-terminal): Perform redisplay after the process filter
Chong Yidong <cyd@stupidchicken.com>
diff
changeset
|
3098 ;; This might be expensive, but we need it to handle something
|
c09516cc5cf4
(term-emulate-terminal): Perform redisplay after the process filter
Chong Yidong <cyd@stupidchicken.com>
diff
changeset
|
3099 ;; like `sleep 5 | less -c' in more-or-less real time.
|
c09516cc5cf4
(term-emulate-terminal): Perform redisplay after the process filter
Chong Yidong <cyd@stupidchicken.com>
diff
changeset
|
3100 (when (get-buffer-window (current-buffer))
|
c09516cc5cf4
(term-emulate-terminal): Perform redisplay after the process filter
Chong Yidong <cyd@stupidchicken.com>
diff
changeset
|
3101 (redisplay))))
|
9509
|
3102
|
12229
|
3103 (defun term-handle-deferred-scroll ()
|
|
3104 (let ((count (- (term-current-row) term-height)))
|
71054
|
3105 (when (>= count 0)
|
|
3106 (save-excursion
|
|
3107 (goto-char term-home-marker)
|
|
3108 (term-vertical-motion (1+ count))
|
|
3109 (set-marker term-home-marker (point))
|
|
3110 (setq term-current-row (1- term-height))))))
|
12229
|
3111
|
58892
|
3112 ;;; Reset the terminal, delete all the content and set the face to the
|
63176
7a34bd511117
(term-mode, term-check-proc, term-input-sender, term-simple-send,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
3113 ;;; default one.
|
58892
|
3114 (defun term-reset-terminal ()
|
|
3115 (erase-buffer)
|
61010
|
3116 (setq term-current-row 0)
|
58892
|
3117 (setq term-current-column 1)
|
68203
|
3118 (setq term-scroll-start 0)
|
|
3119 (setq term-scroll-end term-height)
|
58892
|
3120 (setq term-insert-mode nil)
|
78414
781746b1e97f
Honor term-default-fg-color and term-default-bg-color settings when modifying term-current-face.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
diff
changeset
|
3121 (setq term-current-face (list :background term-default-bg-color
|
781746b1e97f
Honor term-default-fg-color and term-default-bg-color settings when modifying term-current-face.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
diff
changeset
|
3122 :foreground term-default-fg-color))
|
61481
d4014c213e7e
* term.el (term-ansi-current-bold, term-ansi-current-underline)
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
3123 (setq term-ansi-current-underline nil)
|
d4014c213e7e
* term.el (term-ansi-current-bold, term-ansi-current-underline)
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
3124 (setq term-ansi-current-bold nil)
|
d4014c213e7e
* term.el (term-ansi-current-bold, term-ansi-current-underline)
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
3125 (setq term-ansi-current-reverse nil)
|
58892
|
3126 (setq term-ansi-current-color 0)
|
61481
d4014c213e7e
* term.el (term-ansi-current-bold, term-ansi-current-underline)
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
3127 (setq term-ansi-current-invisible nil)
|
d4014c213e7e
* term.el (term-ansi-current-bold, term-ansi-current-underline)
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
3128 (setq term-ansi-face-already-done nil)
|
58892
|
3129 (setq term-ansi-current-bg-color 0))
|
|
3130
|
17283
|
3131 ;;; New function to deal with ansi colorized output, as you can see you can
|
|
3132 ;;; have any bold/underline/fg/bg/reverse combination. -mm
|
|
3133
|
|
3134 (defun term-handle-colors-array (parameter)
|
17814
|
3135 (cond
|
17283
|
3136
|
58892
|
3137 ;;; Bold (terminfo: bold)
|
17814
|
3138 ((eq parameter 1)
|
61481
d4014c213e7e
* term.el (term-ansi-current-bold, term-ansi-current-underline)
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
3139 (setq term-ansi-current-bold t))
|
17283
|
3140
|
|
3141 ;;; Underline
|
17814
|
3142 ((eq parameter 4)
|
61481
d4014c213e7e
* term.el (term-ansi-current-bold, term-ansi-current-underline)
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
3143 (setq term-ansi-current-underline t))
|
17283
|
3144
|
|
3145 ;;; Blink (unsupported by Emacs), will be translated to bold.
|
|
3146 ;;; This may change in the future though.
|
17814
|
3147 ((eq parameter 5)
|
61481
d4014c213e7e
* term.el (term-ansi-current-bold, term-ansi-current-underline)
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
3148 (setq term-ansi-current-bold t))
|
17283
|
3149
|
66461
|
3150 ;;; Reverse (terminfo: smso)
|
17814
|
3151 ((eq parameter 7)
|
61481
d4014c213e7e
* term.el (term-ansi-current-bold, term-ansi-current-underline)
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
3152 (setq term-ansi-current-reverse t))
|
17283
|
3153
|
|
3154 ;;; Invisible
|
17814
|
3155 ((eq parameter 8)
|
61481
d4014c213e7e
* term.el (term-ansi-current-bold, term-ansi-current-underline)
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
3156 (setq term-ansi-current-invisible t))
|
17814
|
3157
|
66461
|
3158 ;;; Reset underline (terminfo: rmul)
|
57234
|
3159 ((eq parameter 24)
|
61481
d4014c213e7e
* term.el (term-ansi-current-bold, term-ansi-current-underline)
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
3160 (setq term-ansi-current-underline nil))
|
57234
|
3161
|
66461
|
3162 ;;; Reset reverse (terminfo: rmso)
|
57234
|
3163 ((eq parameter 27)
|
61481
d4014c213e7e
* term.el (term-ansi-current-bold, term-ansi-current-underline)
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
3164 (setq term-ansi-current-reverse nil))
|
57123
|
3165
|
24966
|
3166 ;;; Foreground
|
17814
|
3167 ((and (>= parameter 30) (<= parameter 37))
|
|
3168 (setq term-ansi-current-color (- parameter 29)))
|
|
3169
|
24966
|
3170 ;;; Reset foreground
|
|
3171 ((eq parameter 39)
|
|
3172 (setq term-ansi-current-color 0))
|
|
3173
|
|
3174 ;;; Background
|
17814
|
3175 ((and (>= parameter 40) (<= parameter 47))
|
|
3176 (setq term-ansi-current-bg-color (- parameter 39)))
|
17283
|
3177
|
24966
|
3178 ;;; Reset background
|
|
3179 ((eq parameter 49)
|
|
3180 (setq term-ansi-current-bg-color 0))
|
|
3181
|
17283
|
3182 ;;; 0 (Reset) or unknown (reset anyway)
|
17814
|
3183 (t
|
78414
781746b1e97f
Honor term-default-fg-color and term-default-bg-color settings when modifying term-current-face.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
diff
changeset
|
3184 (setq term-current-face (list :background term-default-bg-color
|
781746b1e97f
Honor term-default-fg-color and term-default-bg-color settings when modifying term-current-face.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
diff
changeset
|
3185 :foreground term-default-fg-color))
|
61481
d4014c213e7e
* term.el (term-ansi-current-bold, term-ansi-current-underline)
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
3186 (setq term-ansi-current-underline nil)
|
d4014c213e7e
* term.el (term-ansi-current-bold, term-ansi-current-underline)
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
3187 (setq term-ansi-current-bold nil)
|
d4014c213e7e
* term.el (term-ansi-current-bold, term-ansi-current-underline)
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
3188 (setq term-ansi-current-reverse nil)
|
17814
|
3189 (setq term-ansi-current-color 0)
|
61481
d4014c213e7e
* term.el (term-ansi-current-bold, term-ansi-current-underline)
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
3190 (setq term-ansi-current-invisible nil)
|
d4014c213e7e
* term.el (term-ansi-current-bold, term-ansi-current-underline)
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
3191 (setq term-ansi-face-already-done t)
|
17814
|
3192 (setq term-ansi-current-bg-color 0)))
|
17283
|
3193
|
|
3194 ; (message "Debug: U-%d R-%d B-%d I-%d D-%d F-%d B-%d"
|
|
3195 ; term-ansi-current-underline
|
|
3196 ; term-ansi-current-reverse
|
|
3197 ; term-ansi-current-bold
|
|
3198 ; term-ansi-current-invisible
|
49591
|
3199 ; term-ansi-face-already-done
|
17283
|
3200 ; term-ansi-current-color
|
|
3201 ; term-ansi-current-bg-color)
|
|
3202
|
|
3203
|
61481
d4014c213e7e
* term.el (term-ansi-current-bold, term-ansi-current-underline)
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
3204 (unless term-ansi-face-already-done
|
d4014c213e7e
* term.el (term-ansi-current-bold, term-ansi-current-underline)
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
3205 (if term-ansi-current-reverse
|
d4014c213e7e
* term.el (term-ansi-current-bold, term-ansi-current-underline)
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
3206 (if term-ansi-current-invisible
|
49591
|
3207 (setq term-current-face
|
|
3208 (if (= term-ansi-current-color 0)
|
|
3209 (list :background
|
|
3210 term-default-fg-color
|
|
3211 :foreground
|
|
3212 term-default-fg-color)
|
|
3213 (list :background
|
|
3214 (elt ansi-term-color-vector term-ansi-current-color)
|
|
3215 :foreground
|
|
3216 (elt ansi-term-color-vector term-ansi-current-color)))
|
|
3217 ;; No need to bother with anything else if it's invisible
|
|
3218 )
|
|
3219 (setq term-current-face
|
|
3220 (list :background
|
57123
|
3221 (if (= term-ansi-current-color 0)
|
78414
781746b1e97f
Honor term-default-fg-color and term-default-bg-color settings when modifying term-current-face.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
diff
changeset
|
3222 term-default-fg-color
|
71054
|
3223 (elt ansi-term-color-vector term-ansi-current-color))
|
49591
|
3224 :foreground
|
57123
|
3225 (if (= term-ansi-current-bg-color 0)
|
78414
781746b1e97f
Honor term-default-fg-color and term-default-bg-color settings when modifying term-current-face.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
diff
changeset
|
3226 term-default-bg-color
|
71054
|
3227 (elt ansi-term-color-vector term-ansi-current-bg-color))))
|
61481
d4014c213e7e
* term.el (term-ansi-current-bold, term-ansi-current-underline)
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
3228 (when term-ansi-current-bold
|
71054
|
3229 (setq term-current-face
|
|
3230 (append '(:weight bold) term-current-face)))
|
61481
d4014c213e7e
* term.el (term-ansi-current-bold, term-ansi-current-underline)
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
3231 (when term-ansi-current-underline
|
71054
|
3232 (setq term-current-face
|
|
3233 (append '(:underline t) term-current-face))))
|
61481
d4014c213e7e
* term.el (term-ansi-current-bold, term-ansi-current-underline)
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
3234 (if term-ansi-current-invisible
|
49591
|
3235 (setq term-current-face
|
|
3236 (if (= term-ansi-current-bg-color 0)
|
|
3237 (list :background
|
|
3238 term-default-bg-color
|
|
3239 :foreground
|
|
3240 term-default-bg-color)
|
|
3241 (list :foreground
|
|
3242 (elt ansi-term-color-vector term-ansi-current-bg-color)
|
|
3243 :background
|
|
3244 (elt ansi-term-color-vector term-ansi-current-bg-color)))
|
|
3245 ;; No need to bother with anything else if it's invisible
|
|
3246 )
|
17814
|
3247 (setq term-current-face
|
49591
|
3248 (list :foreground
|
78414
781746b1e97f
Honor term-default-fg-color and term-default-bg-color settings when modifying term-current-face.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
diff
changeset
|
3249 (if (= term-ansi-current-color 0)
|
781746b1e97f
Honor term-default-fg-color and term-default-bg-color settings when modifying term-current-face.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
diff
changeset
|
3250 term-default-fg-color
|
781746b1e97f
Honor term-default-fg-color and term-default-bg-color settings when modifying term-current-face.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
diff
changeset
|
3251 (elt ansi-term-color-vector term-ansi-current-color))
|
49591
|
3252 :background
|
78414
781746b1e97f
Honor term-default-fg-color and term-default-bg-color settings when modifying term-current-face.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
diff
changeset
|
3253 (if (= term-ansi-current-bg-color 0)
|
781746b1e97f
Honor term-default-fg-color and term-default-bg-color settings when modifying term-current-face.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
diff
changeset
|
3254 term-default-bg-color
|
781746b1e97f
Honor term-default-fg-color and term-default-bg-color settings when modifying term-current-face.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
diff
changeset
|
3255 (elt ansi-term-color-vector term-ansi-current-bg-color))))
|
61481
d4014c213e7e
* term.el (term-ansi-current-bold, term-ansi-current-underline)
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
3256 (when term-ansi-current-bold
|
71054
|
3257 (setq term-current-face
|
|
3258 (append '(:weight bold) term-current-face)))
|
61481
d4014c213e7e
* term.el (term-ansi-current-bold, term-ansi-current-underline)
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
3259 (when term-ansi-current-underline
|
71054
|
3260 (setq term-current-face
|
|
3261 (append '(:underline t) term-current-face))))))
|
77169
8905fec7d280
(term-buffer-maximum-size, term-exec, term-escape-char, term-set-escape-char,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
3262
|
56684
|
3263 ;;; (message "Debug %S" term-current-face)
|
61481
d4014c213e7e
* term.el (term-ansi-current-bold, term-ansi-current-underline)
Dan Nicolaescu <dann@ics.uci.edu>
diff
changeset
|
3264 (setq term-ansi-face-already-done nil))
|
17283
|
3265
|
|
3266
|
9509
|
3267 ;;; Handle a character assuming (eq terminal-state 2) -
|
13961
|
3268 ;;; i.e. we have previously seen Escape followed by ?[.
|
9509
|
3269
|
10671
|
3270 (defun term-handle-ansi-escape (proc char)
|
9509
|
3271 (cond
|
68203
|
3272 ((or (eq char ?H) ;; cursor motion (terminfo: cup,home)
|
|
3273 ;; (eq char ?f) ;; xterm seems to handle this sequence too, not
|
57299
|
3274 ;; needed for now
|
63176
7a34bd511117
(term-mode, term-check-proc, term-input-sender, term-simple-send,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
3275 )
|
71054
|
3276 (when (<= term-terminal-parameter 0)
|
|
3277 (setq term-terminal-parameter 1))
|
|
3278 (when (<= term-terminal-previous-parameter 0)
|
|
3279 (setq term-terminal-previous-parameter 1))
|
|
3280 (when (> term-terminal-previous-parameter term-height)
|
|
3281 (setq term-terminal-previous-parameter term-height))
|
|
3282 (when (> term-terminal-parameter term-width)
|
|
3283 (setq term-terminal-parameter term-width))
|
9509
|
3284 (term-goto
|
|
3285 (1- term-terminal-previous-parameter)
|
|
3286 (1- term-terminal-parameter)))
|
57299
|
3287 ;; \E[A - cursor up (terminfo: cuu, cuu1)
|
9509
|
3288 ((eq char ?A)
|
12229
|
3289 (term-handle-deferred-scroll)
|
68203
|
3290 (let ((tcr (term-current-row)))
|
77169
8905fec7d280
(term-buffer-maximum-size, term-exec, term-escape-char, term-set-escape-char,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
3291 (term-down
|
68203
|
3292 (if (< (- tcr term-terminal-parameter) term-scroll-start)
|
|
3293 ;; If the amount to move is before scroll start, move
|
|
3294 ;; to scroll start.
|
|
3295 (- term-scroll-start tcr)
|
|
3296 (if (>= term-terminal-parameter tcr)
|
|
3297 (- tcr)
|
|
3298 (- (max 1 term-terminal-parameter)))) t)))
|
57299
|
3299 ;; \E[B - cursor down (terminfo: cud)
|
9509
|
3300 ((eq char ?B)
|
68203
|
3301 (let ((tcr (term-current-row)))
|
|
3302 (unless (= tcr (1- term-scroll-end))
|
77169
8905fec7d280
(term-buffer-maximum-size, term-exec, term-escape-char, term-set-escape-char,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
3303 (term-down
|
68203
|
3304 (if (> (+ tcr term-terminal-parameter) term-scroll-end)
|
|
3305 (- term-scroll-end 1 tcr)
|
|
3306 (max 1 term-terminal-parameter)) t))))
|
66461
|
3307 ;; \E[C - cursor right (terminfo: cuf, cuf1)
|
9509
|
3308 ((eq char ?C)
|
63176
7a34bd511117
(term-mode, term-check-proc, term-input-sender, term-simple-send,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
3309 (term-move-columns
|
7a34bd511117
(term-mode, term-check-proc, term-input-sender, term-simple-send,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
3310 (max 1
|
57299
|
3311 (if (>= (+ term-terminal-parameter (term-current-column)) term-width)
|
|
3312 (- term-width (term-current-column) 1)
|
|
3313 term-terminal-parameter))))
|
|
3314 ;; \E[D - cursor left (terminfo: cub)
|
9509
|
3315 ((eq char ?D)
|
|
3316 (term-move-columns (- (max 1 term-terminal-parameter))))
|
57234
|
3317 ;; \E[J - clear to end of screen (terminfo: ed, clear)
|
9509
|
3318 ((eq char ?J)
|
|
3319 (term-erase-in-display term-terminal-parameter))
|
57234
|
3320 ;; \E[K - clear to end of line (terminfo: el, el1)
|
9509
|
3321 ((eq char ?K)
|
|
3322 (term-erase-in-line term-terminal-parameter))
|
57234
|
3323 ;; \E[L - insert lines (terminfo: il, il1)
|
9509
|
3324 ((eq char ?L)
|
|
3325 (term-insert-lines (max 1 term-terminal-parameter)))
|
66461
|
3326 ;; \E[M - delete lines (terminfo: dl, dl1)
|
9509
|
3327 ((eq char ?M)
|
|
3328 (term-delete-lines (max 1 term-terminal-parameter)))
|
66461
|
3329 ;; \E[P - delete chars (terminfo: dch, dch1)
|
9509
|
3330 ((eq char ?P)
|
|
3331 (term-delete-chars (max 1 term-terminal-parameter)))
|
66461
|
3332 ;; \E[@ - insert spaces (terminfo: ich)
|
|
3333 ((eq char ?@)
|
9509
|
3334 (term-insert-spaces (max 1 term-terminal-parameter)))
|
|
3335 ;; \E[?h - DEC Private Mode Set
|
|
3336 ((eq char ?h)
|
57234
|
3337 (cond ((eq term-terminal-parameter 4) ;; (terminfo: smir)
|
9509
|
3338 (setq term-insert-mode t))
|
57234
|
3339 ;; ((eq term-terminal-parameter 47) ;; (terminfo: smcup)
|
|
3340 ;; (term-switch-to-alternate-sub-buffer t))
|
|
3341 ))
|
10044
|
3342 ;; \E[?l - DEC Private Mode Reset
|
9509
|
3343 ((eq char ?l)
|
57234
|
3344 (cond ((eq term-terminal-parameter 4) ;; (terminfo: rmir)
|
9509
|
3345 (setq term-insert-mode nil))
|
57234
|
3346 ;; ((eq term-terminal-parameter 47) ;; (terminfo: rmcup)
|
|
3347 ;; (term-switch-to-alternate-sub-buffer nil))
|
|
3348 ))
|
17283
|
3349
|
|
3350 ;;; Modified to allow ansi coloring -mm
|
63176
7a34bd511117
(term-mode, term-check-proc, term-input-sender, term-simple-send,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
3351 ;; \E[m - Set/reset modes, set bg/fg
|
57234
|
3352 ;;(terminfo: smso,rmso,smul,rmul,rev,bold,sgr0,invis,op,setab,setaf)
|
9509
|
3353 ((eq char ?m)
|
17814
|
3354 (when (= term-terminal-more-parameters 1)
|
68203
|
3355 (when (>= term-terminal-previous-parameter-4 0)
|
|
3356 (term-handle-colors-array term-terminal-previous-parameter-4))
|
|
3357 (when (>= term-terminal-previous-parameter-3 0)
|
|
3358 (term-handle-colors-array term-terminal-previous-parameter-3))
|
|
3359 (when (>= term-terminal-previous-parameter-2 0)
|
|
3360 (term-handle-colors-array term-terminal-previous-parameter-2))
|
17814
|
3361 (term-handle-colors-array term-terminal-previous-parameter))
|
|
3362 (term-handle-colors-array term-terminal-parameter))
|
17283
|
3363
|
10671
|
3364 ;; \E[6n - Report cursor position
|
|
3365 ((eq char ?n)
|
12229
|
3366 (term-handle-deferred-scroll)
|
10671
|
3367 (process-send-string proc
|
|
3368 (format "\e[%s;%sR"
|
|
3369 (1+ (term-current-row))
|
|
3370 (1+ (term-horizontal-column)))))
|
68203
|
3371 ;; \E[r - Set scrolling region (terminfo: csr)
|
|
3372 ((eq char ?r)
|
|
3373 (term-set-scroll-region
|
9509
|
3374 (1- term-terminal-previous-parameter)
|
70374
|
3375 (1- term-terminal-parameter)))
|
9509
|
3376 (t)))
|
|
3377
|
68203
|
3378 (defun term-set-scroll-region (top bottom)
|
9509
|
3379 "Set scrolling region.
|
|
3380 TOP is the top-most line (inclusive) of the new scrolling region,
|
13961
|
3381 while BOTTOM is the line following the new scrolling region (e.g. exclusive).
|
9509
|
3382 The top-most line is line 0."
|
|
3383 (setq term-scroll-start
|
|
3384 (if (or (< top 0) (>= top term-height))
|
|
3385 0
|
|
3386 top))
|
|
3387 (setq term-scroll-end
|
10671
|
3388 (if (or (<= bottom term-scroll-start) (> bottom term-height))
|
9509
|
3389 term-height
|
|
3390 bottom))
|
|
3391 (setq term-scroll-with-delete
|
|
3392 (or (term-using-alternate-sub-buffer)
|
|
3393 (not (and (= term-scroll-start 0)
|
57299
|
3394 (= term-scroll-end term-height)))))
|
|
3395 (term-move-columns (- (term-current-column)))
|
68203
|
3396 (term-goto 0 0))
|
9509
|
3397
|
57234
|
3398 ;; (defun term-switch-to-alternate-sub-buffer (set)
|
|
3399 ;; ;; If asked to switch to (from) the alternate sub-buffer, and already (not)
|
|
3400 ;; ;; using it, do nothing. This test is needed for some programs (including
|
|
3401 ;; ;; Emacs) that emit the ti termcap string twice, for unknown reason.
|
|
3402 ;; (term-handle-deferred-scroll)
|
|
3403 ;; (if (eq set (not (term-using-alternate-sub-buffer)))
|
|
3404 ;; (let ((row (term-current-row))
|
|
3405 ;; (col (term-horizontal-column)))
|
|
3406 ;; (cond (set
|
|
3407 ;; (goto-char (point-max))
|
|
3408 ;; (if (not (eq (preceding-char) ?\n))
|
|
3409 ;; (term-insert-char ?\n 1))
|
|
3410 ;; (setq term-scroll-with-delete t)
|
|
3411 ;; (setq term-saved-home-marker (copy-marker term-home-marker))
|
|
3412 ;; (set-marker term-home-marker (point)))
|
|
3413 ;; (t
|
|
3414 ;; (setq term-scroll-with-delete
|
|
3415 ;; (not (and (= term-scroll-start 0)
|
|
3416 ;; (= term-scroll-end term-height))))
|
|
3417 ;; (set-marker term-home-marker term-saved-home-marker)
|
|
3418 ;; (set-marker term-saved-home-marker nil)
|
|
3419 ;; (setq term-saved-home-marker nil)
|
|
3420 ;; (goto-char term-home-marker)))
|
|
3421 ;; (setq term-current-column nil)
|
|
3422 ;; (setq term-current-row 0)
|
|
3423 ;; (term-goto row col))))
|
9509
|
3424
|
|
3425 ;; Default value for the symbol term-command-hook.
|
|
3426
|
|
3427 (defun term-command-hook (string)
|
49591
|
3428 (cond ((equal string "")
|
|
3429 t)
|
|
3430 ((= (aref string 0) ?\032)
|
9509
|
3431 ;; gdb (when invoked with -fullname) prints:
|
|
3432 ;; \032\032FULLFILENAME:LINENUMBER:CHARPOS:BEG_OR_MIDDLE:PC\n
|
|
3433 (let* ((first-colon (string-match ":" string 1))
|
|
3434 (second-colon
|
|
3435 (string-match ":" string (1+ first-colon)))
|
|
3436 (filename (substring string 1 first-colon))
|
62402
|
3437 (fileline (string-to-number
|
9509
|
3438 (substring string (1+ first-colon) second-colon))))
|
|
3439 (setq term-pending-frame (cons filename fileline))))
|
|
3440 ((= (aref string 0) ?/)
|
|
3441 (cd (substring string 1)))
|
17283
|
3442 ;; Allowing the inferior to call functions in Emacs is
|
10515
|
3443 ;; probably too big a security hole.
|
|
3444 ;; ((= (aref string 0) ?!)
|
|
3445 ;; (eval (car (read-from-string string 1))))
|
9509
|
3446 (t)));; Otherwise ignore it
|
|
3447
|
|
3448 ;; Make sure the file named TRUE-FILE is in a buffer that appears on the screen
|
|
3449 ;; and that its line LINE is visible.
|
|
3450 ;; Put the overlay-arrow on the line LINE in that buffer.
|
|
3451 ;; This is mainly used by gdb.
|
|
3452
|
|
3453 (defun term-display-line (true-file line)
|
|
3454 (term-display-buffer-line (find-file-noselect true-file) line))
|
|
3455
|
|
3456 (defun term-display-buffer-line (buffer line)
|
|
3457 (let* ((window (display-buffer buffer t))
|
|
3458 (pos))
|
|
3459 (save-excursion
|
|
3460 (set-buffer buffer)
|
|
3461 (save-restriction
|
|
3462 (widen)
|
|
3463 (goto-line line)
|
|
3464 (setq pos (point))
|
|
3465 (setq overlay-arrow-string "=>")
|
|
3466 (or overlay-arrow-position
|
|
3467 (setq overlay-arrow-position (make-marker)))
|
|
3468 (set-marker overlay-arrow-position (point) (current-buffer)))
|
|
3469 (cond ((or (< pos (point-min)) (> pos (point-max)))
|
|
3470 (widen)
|
|
3471 (goto-char pos))))
|
|
3472 (set-window-point window overlay-arrow-position)))
|
|
3473
|
|
3474 ;;; The buffer-local marker term-home-marker defines the "home position"
|
|
3475 ;;; (in terms of cursor motion). However, we move the term-home-marker
|
|
3476 ;;; "down" as needed so that is no more that a window-full above (point-max).
|
|
3477
|
|
3478 (defun term-goto-home ()
|
12229
|
3479 (term-handle-deferred-scroll)
|
9509
|
3480 (goto-char term-home-marker)
|
|
3481 (setq term-current-row 0)
|
|
3482 (setq term-current-column (current-column))
|
|
3483 (setq term-start-line-column term-current-column))
|
|
3484
|
|
3485 (defun term-goto (row col)
|
12229
|
3486 (term-handle-deferred-scroll)
|
|
3487 (cond ((and term-current-row (>= row term-current-row))
|
|
3488 ;; I assume this is a worthwhile optimization.
|
|
3489 (term-vertical-motion 0)
|
|
3490 (setq term-current-column term-start-line-column)
|
|
3491 (setq row (- row term-current-row)))
|
|
3492 (t
|
|
3493 (term-goto-home)))
|
|
3494 (term-down row)
|
|
3495 (term-move-columns col))
|
9509
|
3496
|
|
3497 ; The page is full, so enter "pager" mode, and wait for input.
|
|
3498
|
|
3499 (defun term-process-pager ()
|
71054
|
3500 (when (not term-pager-break-map)
|
|
3501 (let* ((map (make-keymap))
|
|
3502 (i 0) tmp)
|
9509
|
3503 ; (while (< i 128)
|
|
3504 ; (define-key map (make-string 1 i) 'term-send-raw)
|
|
3505 ; (setq i (1+ i)))
|
71054
|
3506 (define-key map "\e"
|
|
3507 (lookup-key (current-global-map) "\e"))
|
|
3508 (define-key map "\C-x"
|
|
3509 (lookup-key (current-global-map) "\C-x"))
|
|
3510 (define-key map "\C-u"
|
|
3511 (lookup-key (current-global-map) "\C-u"))
|
|
3512 (define-key map " " 'term-pager-page)
|
|
3513 (define-key map "\r" 'term-pager-line)
|
|
3514 (define-key map "?" 'term-pager-help)
|
|
3515 (define-key map "h" 'term-pager-help)
|
|
3516 (define-key map "b" 'term-pager-back-page)
|
|
3517 (define-key map "\177" 'term-pager-back-line)
|
|
3518 (define-key map "q" 'term-pager-discard)
|
|
3519 (define-key map "D" 'term-pager-disable)
|
|
3520 (define-key map "<" 'term-pager-bob)
|
|
3521 (define-key map ">" 'term-pager-eob)
|
|
3522
|
|
3523 ;; Add menu bar.
|
|
3524 (unless (featurep 'xemacs)
|
|
3525 (define-key map [menu-bar terminal] term-terminal-menu)
|
|
3526 (define-key map [menu-bar signals] term-signals-menu)
|
|
3527 (setq tmp (make-sparse-keymap "More pages?"))
|
|
3528 (define-key tmp [help] '("Help" . term-pager-help))
|
|
3529 (define-key tmp [disable]
|
|
3530 '("Disable paging" . term-fake-pager-disable))
|
|
3531 (define-key tmp [discard]
|
|
3532 '("Discard remaining output" . term-pager-discard))
|
|
3533 (define-key tmp [eob] '("Goto to end" . term-pager-eob))
|
|
3534 (define-key tmp [bob] '("Goto to beginning" . term-pager-bob))
|
|
3535 (define-key tmp [line] '("1 line forwards" . term-pager-line))
|
|
3536 (define-key tmp [bline] '("1 line backwards" . term-pager-back-line))
|
|
3537 (define-key tmp [back] '("1 page backwards" . term-pager-back-page))
|
|
3538 (define-key tmp [page] '("1 page forwards" . term-pager-page))
|
|
3539 (define-key map [menu-bar page] (cons "More pages?" tmp))
|
|
3540 )
|
|
3541
|
|
3542 (setq term-pager-break-map map)))
|
9509
|
3543 ; (let ((process (get-buffer-process (current-buffer))))
|
17283
|
3544 ; (stop-process process))
|
9509
|
3545 (setq term-pager-old-local-map (current-local-map))
|
|
3546 (use-local-map term-pager-break-map)
|
|
3547 (make-local-variable 'term-old-mode-line-format)
|
|
3548 (setq term-old-mode-line-format mode-line-format)
|
|
3549 (setq mode-line-format
|
|
3550 (list "-- **MORE** "
|
|
3551 mode-line-buffer-identification
|
|
3552 " [Type ? for help] "
|
10515
|
3553 "%-"))
|
11570
f210b0ee984a
(term-update-mode-line, term-process-pager): Use force-mode-line-update.
Karl Heuer <kwzh@gnu.org>
diff
changeset
|
3554 (force-mode-line-update))
|
9509
|
3555
|
|
3556 (defun term-pager-line (lines)
|
|
3557 (interactive "p")
|
|
3558 (let* ((moved (vertical-motion (1+ lines)))
|
|
3559 (deficit (- lines moved)))
|
71054
|
3560 (when (> moved lines)
|
|
3561 (backward-char))
|
9509
|
3562 (cond ((<= deficit 0) ;; OK, had enough in the buffer for request.
|
|
3563 (recenter (1- term-height)))
|
|
3564 ((term-pager-continue deficit)))))
|
|
3565
|
|
3566 (defun term-pager-page (arg)
|
77169
8905fec7d280
(term-buffer-maximum-size, term-exec, term-escape-char, term-set-escape-char,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
3567 "Proceed past the **MORE** break, allowing the next page of output to appear."
|
9509
|
3568 (interactive "p")
|
|
3569 (term-pager-line (* arg term-height)))
|
|
3570
|
|
3571 ; Pager mode command to go to beginning of buffer
|
|
3572 (defun term-pager-bob ()
|
|
3573 (interactive)
|
|
3574 (goto-char (point-min))
|
71054
|
3575 (when (= (vertical-motion term-height) term-height)
|
|
3576 (backward-char))
|
9509
|
3577 (recenter (1- term-height)))
|
|
3578
|
|
3579 ; pager mode command to go to end of buffer
|
|
3580 (defun term-pager-eob ()
|
|
3581 (interactive)
|
|
3582 (goto-char term-home-marker)
|
|
3583 (recenter 0)
|
|
3584 (goto-char (process-mark (get-buffer-process (current-buffer)))))
|
|
3585
|
|
3586 (defun term-pager-back-line (lines)
|
|
3587 (interactive "p")
|
|
3588 (vertical-motion (- 1 lines))
|
|
3589 (if (not (bobp))
|
|
3590 (backward-char)
|
|
3591 (beep)
|
|
3592 ;; Move cursor to end of window.
|
|
3593 (vertical-motion term-height)
|
|
3594 (backward-char))
|
|
3595 (recenter (1- term-height)))
|
|
3596
|
|
3597 (defun term-pager-back-page (arg)
|
|
3598 (interactive "p")
|
|
3599 (term-pager-back-line (* arg term-height)))
|
|
3600
|
|
3601 (defun term-pager-discard ()
|
|
3602 (interactive)
|
|
3603 (setq term-terminal-parameter "")
|
|
3604 (interrupt-process nil t)
|
|
3605 (term-pager-continue term-height))
|
|
3606
|
|
3607 ; Disable pager processing.
|
|
3608 ; Only callable while in pager mode. (Contrast term-disable-pager.)
|
|
3609 (defun term-pager-disable ()
|
|
3610 (interactive)
|
|
3611 (if (term-handling-pager)
|
|
3612 (term-pager-continue nil)
|
10671
|
3613 (setq term-pager-count nil))
|
|
3614 (term-update-mode-line))
|
17283
|
3615
|
9509
|
3616 ; Enable pager processing.
|
|
3617 (defun term-pager-enable ()
|
|
3618 (interactive)
|
10671
|
3619 (or (term-pager-enabled)
|
|
3620 (setq term-pager-count 0)) ;; Or maybe set to (term-current-row) ??
|
|
3621 (term-update-mode-line))
|
9509
|
3622
|
10515
|
3623 (defun term-pager-toggle ()
|
|
3624 (interactive)
|
10671
|
3625 (if (term-pager-enabled) (term-pager-disable) (term-pager-enable)))
|
10515
|
3626
|
71054
|
3627 (unless (featurep 'xemacs)
|
10515
|
3628 (defalias 'term-fake-pager-enable 'term-pager-toggle)
|
|
3629 (defalias 'term-fake-pager-disable 'term-pager-toggle)
|
|
3630 (put 'term-char-mode 'menu-enable '(term-in-line-mode))
|
|
3631 (put 'term-line-mode 'menu-enable '(term-in-char-mode))
|
|
3632 (put 'term-fake-pager-enable 'menu-enable '(not term-pager-count))
|
|
3633 (put 'term-fake-pager-disable 'menu-enable 'term-pager-count))
|
|
3634
|
9509
|
3635 (defun term-pager-help ()
|
77169
8905fec7d280
(term-buffer-maximum-size, term-exec, term-escape-char, term-set-escape-char,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
3636 "Provide help on commands available in a terminal-emulator **MORE** break."
|
9509
|
3637 (interactive)
|
|
3638 (message "Terminal-emulator pager break help...")
|
|
3639 (sit-for 0)
|
|
3640 (with-electric-help
|
|
3641 (function (lambda ()
|
|
3642 (princ (substitute-command-keys
|
|
3643 "\\<term-pager-break-map>\
|
|
3644 Terminal-emulator MORE break.\n\
|
|
3645 Type one of the following keys:\n\n\
|
|
3646 \\[term-pager-page]\t\tMove forward one page.\n\
|
|
3647 \\[term-pager-line]\t\tMove forward one line.\n\
|
|
3648 \\[universal-argument] N \\[term-pager-page]\tMove N pages forward.\n\
|
|
3649 \\[universal-argument] N \\[term-pager-line]\tMove N lines forward.\n\
|
|
3650 \\[universal-argument] N \\[term-pager-back-line]\tMove N lines back.\n\
|
|
3651 \\[universal-argument] N \\[term-pager-back-page]\t\tMove N pages back.\n\
|
|
3652 \\[term-pager-bob]\t\tMove to the beginning of the buffer.\n\
|
|
3653 \\[term-pager-eob]\t\tMove to the end of the buffer.\n\
|
|
3654 \\[term-pager-discard]\t\tKill pending output and kill process.\n\
|
|
3655 \\[term-pager-disable]\t\tDisable PAGER handling.\n\n\
|
|
3656 \\{term-pager-break-map}\n\
|
|
3657 Any other key is passed through to the program
|
|
3658 running under the terminal emulator and disables pager processing until
|
|
3659 all pending output has been dealt with."))
|
|
3660 nil))))
|
|
3661
|
|
3662 (defun term-pager-continue (new-count)
|
|
3663 (let ((process (get-buffer-process (current-buffer))))
|
|
3664 (use-local-map term-pager-old-local-map)
|
|
3665 (setq term-pager-old-local-map nil)
|
|
3666 (setq mode-line-format term-old-mode-line-format)
|
11570
f210b0ee984a
(term-update-mode-line, term-process-pager): Use force-mode-line-update.
Karl Heuer <kwzh@gnu.org>
diff
changeset
|
3667 (force-mode-line-update)
|
9509
|
3668 (setq term-pager-count new-count)
|
|
3669 (set-process-filter process term-pager-old-filter)
|
|
3670 (funcall term-pager-old-filter process "")
|
|
3671 (continue-process process)))
|
|
3672
|
|
3673 ;; Make sure there are DOWN blank lines below the current one.
|
|
3674 ;; Return 0 if we're unable (because of PAGER handling), else return DOWN.
|
|
3675
|
|
3676 (defun term-handle-scroll (down)
|
|
3677 (let ((scroll-needed
|
77169
8905fec7d280
(term-buffer-maximum-size, term-exec, term-escape-char, term-set-escape-char,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
3678 (- (+ (term-current-row) down)
|
68203
|
3679 (if (< down 0) term-scroll-start term-scroll-end))))
|
77169
8905fec7d280
(term-buffer-maximum-size, term-exec, term-escape-char, term-set-escape-char,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
3680 (when (or (and (< down 0) (< scroll-needed 0))
|
71054
|
3681 (and (> down 0) (> scroll-needed 0)))
|
|
3682 (let ((save-point (copy-marker (point))) (save-top))
|
|
3683 (goto-char term-home-marker)
|
|
3684 (cond (term-scroll-with-delete
|
|
3685 (if (< down 0)
|
|
3686 (progn
|
|
3687 ;; Delete scroll-needed lines at term-scroll-end,
|
|
3688 ;; then insert scroll-needed lines.
|
71351
|
3689 (term-vertical-motion term-scroll-end)
|
71054
|
3690 (end-of-line)
|
|
3691 (setq save-top (point))
|
|
3692 (term-vertical-motion scroll-needed)
|
|
3693 (end-of-line)
|
|
3694 (delete-region save-top (point))
|
|
3695 (goto-char save-point)
|
|
3696 (setq down (- scroll-needed down))
|
|
3697 (term-vertical-motion down))
|
|
3698 ;; Delete scroll-needed lines at term-scroll-start.
|
|
3699 (term-vertical-motion term-scroll-start)
|
|
3700 (setq save-top (point))
|
9509
|
3701 (term-vertical-motion scroll-needed)
|
71054
|
3702 (delete-region save-top (point))
|
|
3703 (goto-char save-point)
|
|
3704 (term-vertical-motion down)
|
|
3705 (term-adjust-current-row-cache (- scroll-needed)))
|
|
3706 (setq term-current-column nil)
|
|
3707 (term-insert-char ?\n (abs scroll-needed)))
|
|
3708 ((and (numberp term-pager-count)
|
|
3709 (< (setq term-pager-count (- term-pager-count down))
|
|
3710 0))
|
|
3711 (setq down 0)
|
|
3712 (term-process-pager))
|
|
3713 (t
|
|
3714 (term-adjust-current-row-cache (- scroll-needed))
|
|
3715 (term-vertical-motion scroll-needed)
|
|
3716 (set-marker term-home-marker (point))))
|
|
3717 (goto-char save-point)
|
|
3718 (set-marker save-point nil))))
|
9509
|
3719 down)
|
|
3720
|
12229
|
3721 (defun term-down (down &optional check-for-scroll)
|
|
3722 "Move down DOWN screen lines vertically."
|
9509
|
3723 (let ((start-column (term-horizontal-column)))
|
66891
|
3724 (when (and check-for-scroll (or term-scroll-with-delete term-pager-count))
|
|
3725 (setq down (term-handle-scroll down)))
|
|
3726 (unless (and (= term-current-row 0) (< down 0))
|
|
3727 (term-adjust-current-row-cache down)
|
|
3728 (when (or (/= (point) (point-max)) (< down 0))
|
|
3729 (setq down (- down (term-vertical-motion down)))))
|
68203
|
3730 (cond ((>= down 0)
|
66891
|
3731 ;; Extend buffer with extra blank lines if needed.
|
12229
|
3732 (term-insert-char ?\n down)
|
|
3733 (setq term-current-column 0)
|
|
3734 (setq term-start-line-column 0))
|
|
3735 (t
|
66891
|
3736 (when (= term-current-row 0)
|
|
3737 ;; Insert lines if at the beginning.
|
|
3738 (save-excursion (term-insert-char ?\n (- down)))
|
|
3739 (save-excursion
|
|
3740 (let (p)
|
|
3741 ;; Delete lines from the end.
|
|
3742 (forward-line term-height)
|
|
3743 (setq p (point))
|
|
3744 (forward-line (- down))
|
|
3745 (delete-region p (point)))))
|
|
3746 (setq term-current-column 0)
|
12229
|
3747 (setq term-start-line-column (current-column))))
|
66891
|
3748 (when start-column
|
|
3749 (term-move-columns start-column))))
|
9509
|
3750
|
|
3751 ;; Assuming point is at the beginning of a screen line,
|
|
3752 ;; if the line above point wraps around, add a ?\n to undo the wrapping.
|
|
3753 ;; FIXME: Probably should be called more than it is.
|
|
3754 (defun term-unwrap-line ()
|
71054
|
3755 (when (not (bolp)) (insert-before-markers ?\n)))
|
9509
|
3756
|
|
3757 (defun term-erase-in-line (kind)
|
71054
|
3758 (when (= kind 1) ;; erase left of point
|
|
3759 (let ((cols (term-horizontal-column)) (saved-point (point)))
|
|
3760 (term-vertical-motion 0)
|
|
3761 (delete-region (point) saved-point)
|
|
3762 (term-insert-char ? cols)))
|
|
3763 (when (not (eq kind 1)) ;; erase right of point
|
|
3764 (let ((saved-point (point))
|
|
3765 (wrapped (and (zerop (term-horizontal-column))
|
|
3766 (not (zerop (term-current-column))))))
|
|
3767 (term-vertical-motion 1)
|
|
3768 (delete-region saved-point (point))
|
|
3769 ;; wrapped is true if we're at the beginning of screen line,
|
|
3770 ;; but not a buffer line. If we delete the current screen line
|
|
3771 ;; that will make the previous line no longer wrap, and (because
|
|
3772 ;; of the way Emacs display works) point will be at the end of
|
|
3773 ;; the previous screen line rather then the beginning of the
|
|
3774 ;; current one. To avoid that, we make sure that current line
|
|
3775 ;; contain a space, to force the previous line to continue to wrap.
|
|
3776 ;; We could do this always, but it seems preferable to not add the
|
|
3777 ;; extra space when wrapped is false.
|
77169
8905fec7d280
(term-buffer-maximum-size, term-exec, term-escape-char, term-set-escape-char,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
3778 (when wrapped
|
71054
|
3779 (insert ? ))
|
|
3780 (insert ?\n)
|
|
3781 (put-text-property saved-point (point) 'face 'default)
|
|
3782 (goto-char saved-point))))
|
9509
|
3783
|
|
3784 (defun term-erase-in-display (kind)
|
|
3785 "Erases (that is blanks out) part of the window.
|
|
3786 If KIND is 0, erase from (point) to (point-max);
|
82252
|
3787 if KIND is 1, erase from home to point; else erase from home to point-max."
|
12229
|
3788 (term-handle-deferred-scroll)
|
9509
|
3789 (cond ((eq term-terminal-parameter 0)
|
82252
|
3790 (let ((need-unwrap (bolp)))
|
|
3791 (delete-region (point) (point-max))
|
|
3792 (when need-unwrap (term-unwrap-line))))
|
9509
|
3793 ((let ((row (term-current-row))
|
|
3794 (col (term-horizontal-column))
|
|
3795 (start-region term-home-marker)
|
|
3796 (end-region (if (eq kind 1) (point) (point-max))))
|
|
3797 (delete-region start-region end-region)
|
|
3798 (term-unwrap-line)
|
57299
|
3799 (when (eq kind 1)
|
|
3800 (term-insert-char ?\n row))
|
9509
|
3801 (setq term-current-column nil)
|
|
3802 (setq term-current-row nil)
|
|
3803 (term-goto row col)))))
|
|
3804
|
|
3805 (defun term-delete-chars (count)
|
|
3806 (let ((save-point (point)))
|
|
3807 (term-vertical-motion 1)
|
|
3808 (term-unwrap-line)
|
|
3809 (goto-char save-point)
|
|
3810 (move-to-column (+ (term-current-column) count) t)
|
|
3811 (delete-region save-point (point))))
|
|
3812
|
12229
|
3813 ;;; Insert COUNT spaces after point, but do not change any of
|
|
3814 ;;; following screen lines. Hence we may have to delete characters
|
66891
|
3815 ;;; at the end of this screen line to make room.
|
12229
|
3816
|
9509
|
3817 (defun term-insert-spaces (count)
|
68203
|
3818 (let ((save-point (point)) (save-eol) (pnt-at-eol))
|
9509
|
3819 (term-vertical-motion 1)
|
68203
|
3820 (when (bolp)
|
|
3821 (backward-char))
|
9509
|
3822 (setq save-eol (point))
|
61010
|
3823 (save-excursion
|
|
3824 (end-of-line)
|
68203
|
3825 (setq pnt-at-eol (point)))
|
9509
|
3826 (move-to-column (+ (term-start-line-column) (- term-width count)) t)
|
61010
|
3827 ;; If move-to-column extends the current line it will use the face
|
|
3828 ;; from the last character on the line, set the face for the chars
|
|
3829 ;; to default.
|
68203
|
3830 (when (>= (point) pnt-at-eol)
|
|
3831 (put-text-property pnt-at-eol (point) 'face 'default))
|
|
3832 (when (> save-eol (point))
|
|
3833 (delete-region (point) save-eol))
|
9509
|
3834 (goto-char save-point)
|
|
3835 (term-insert-char ? count)
|
|
3836 (goto-char save-point)))
|
|
3837
|
|
3838 (defun term-delete-lines (lines)
|
|
3839 (let ((start (point))
|
|
3840 (save-current-column term-current-column)
|
|
3841 (save-start-line-column term-start-line-column)
|
|
3842 (save-current-row (term-current-row)))
|
71351
|
3843 ;; The number of inserted lines shouldn't exceed the scroll region end.
|
71404
|
3844 ;; The `term-scroll-end' line is part of the scrolling region, so
|
|
3845 ;; we need to go one line past it in order to ensure correct
|
|
3846 ;; scrolling.
|
71351
|
3847 (when (> (+ save-current-row lines) (1+ term-scroll-end))
|
|
3848 (setq lines (- lines (- (+ save-current-row lines) (1+ term-scroll-end)))))
|
12229
|
3849 (term-down lines)
|
9509
|
3850 (delete-region start (point))
|
71351
|
3851 (term-down (- (1+ term-scroll-end) save-current-row lines))
|
9509
|
3852 (term-insert-char ?\n lines)
|
|
3853 (setq term-current-column save-current-column)
|
|
3854 (setq term-start-line-column save-start-line-column)
|
|
3855 (setq term-current-row save-current-row)
|
|
3856 (goto-char start)))
|
|
3857
|
|
3858 (defun term-insert-lines (lines)
|
|
3859 (let ((start (point))
|
|
3860 (start-deleted)
|
|
3861 (save-current-column term-current-column)
|
|
3862 (save-start-line-column term-start-line-column)
|
|
3863 (save-current-row (term-current-row)))
|
68203
|
3864 ;; Inserting lines should take into account the scroll region.
|
71404
|
3865 ;; The `term-scroll-end' line is part of the scrolling region, so
|
|
3866 ;; we need to go one line past it in order to ensure correct
|
|
3867 ;; scrolling.
|
68203
|
3868 (if (< save-current-row term-scroll-start)
|
77169
8905fec7d280
(term-buffer-maximum-size, term-exec, term-escape-char, term-set-escape-char,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
3869 ;; If point is before scroll start,
|
8905fec7d280
(term-buffer-maximum-size, term-exec, term-escape-char, term-set-escape-char,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
3870 (progn
|
68203
|
3871 (setq lines (- lines (- term-scroll-start save-current-row)))
|
|
3872 (term-down (- term-scroll-start save-current-row))
|
|
3873 (setq start (point)))
|
|
3874 ;; The number of inserted lines shouldn't exceed the scroll region end.
|
71351
|
3875 (when (> (+ save-current-row lines) (1+ term-scroll-end))
|
|
3876 (setq lines (- lines (- (+ save-current-row lines)(1+ term-scroll-end)))))
|
|
3877 (term-down (- (1+ term-scroll-end) save-current-row lines)))
|
9509
|
3878 (setq start-deleted (point))
|
12229
|
3879 (term-down lines)
|
9509
|
3880 (delete-region start-deleted (point))
|
|
3881 (goto-char start)
|
|
3882 (setq term-current-column save-current-column)
|
|
3883 (setq term-start-line-column save-start-line-column)
|
|
3884 (setq term-current-row save-current-row)
|
|
3885 (term-insert-char ?\n lines)
|
|
3886 (goto-char start)))
|
|
3887
|
57234
|
3888 (defun term-start-output-log (name)
|
9509
|
3889 "Record raw inferior process output in a buffer."
|
|
3890 (interactive (list (if term-log-buffer
|
|
3891 nil
|
|
3892 (read-buffer "Record output in buffer: "
|
|
3893 (format "%s output-log"
|
|
3894 (buffer-name (current-buffer)))
|
|
3895 nil))))
|
|
3896 (if (or (null name) (equal name ""))
|
|
3897 (progn (setq term-log-buffer nil)
|
|
3898 (message "Output logging off."))
|
|
3899 (if (get-buffer name)
|
|
3900 nil
|
|
3901 (save-excursion
|
|
3902 (set-buffer (get-buffer-create name))
|
|
3903 (fundamental-mode)
|
|
3904 (buffer-disable-undo (current-buffer))
|
|
3905 (erase-buffer)))
|
|
3906 (setq term-log-buffer (get-buffer name))
|
|
3907 (message "Recording terminal emulator output into buffer \"%s\""
|
|
3908 (buffer-name term-log-buffer))))
|
|
3909
|
57234
|
3910 (defun term-stop-output-log ()
|
9509
|
3911 "Discontinue raw inferior process logging."
|
|
3912 (interactive)
|
57234
|
3913 (term-start-output-log nil))
|
9509
|
3914
|
|
3915 (defun term-show-maximum-output ()
|
|
3916 "Put the end of the buffer at the bottom of the window."
|
|
3917 (interactive)
|
|
3918 (goto-char (point-max))
|
|
3919 (recenter -1))
|
|
3920
|
|
3921 ;;; Do the user's customisation...
|
|
3922
|
|
3923 (defvar term-load-hook nil
|
|
3924 "This hook is run when term is loaded in.
|
|
3925 This is a good place to put keybindings.")
|
17283
|
3926
|
9509
|
3927 (run-hooks 'term-load-hook)
|
|
3928
|
|
3929
|
|
3930 ;;; Filename/command/history completion in a buffer
|
|
3931 ;;; ===========================================================================
|
|
3932 ;;; Useful completion functions, courtesy of the Ergo group.
|
|
3933
|
|
3934 ;;; Six commands:
|
|
3935 ;;; term-dynamic-complete Complete or expand command, filename,
|
|
3936 ;;; history at point.
|
|
3937 ;;; term-dynamic-complete-filename Complete filename at point.
|
|
3938 ;;; term-dynamic-list-filename-completions List completions in help buffer.
|
|
3939 ;;; term-replace-by-expanded-filename Expand and complete filename at point;
|
|
3940 ;;; replace with expanded/completed name.
|
|
3941 ;;; term-dynamic-simple-complete Complete stub given candidates.
|
|
3942
|
17283
|
3943 ;;; These are not installed in the term-mode keymap. But they are
|
|
3944 ;;; available for people who want them. Shell-mode installs them:
|
9509
|
3945 ;;; (define-key shell-mode-map "\t" 'term-dynamic-complete)
|
|
3946 ;;; (define-key shell-mode-map "\M-?"
|
|
3947 ;;; 'term-dynamic-list-filename-completions)))
|
|
3948 ;;;
|
|
3949 ;;; Commands like this are fine things to put in load hooks if you
|
|
3950 ;;; want them present in specific modes.
|
|
3951
|
|
3952 (defvar term-completion-autolist nil
|
13961
|
3953 "*If non-nil, automatically list possibilities on partial completion.
|
9509
|
3954 This mirrors the optional behavior of tcsh.")
|
|
3955
|
|
3956 (defvar term-completion-addsuffix t
|
|
3957 "*If non-nil, add a `/' to completed directories, ` ' to file names.
|
17147
|
3958 If a cons pair, it should be of the form (DIRSUFFIX . FILESUFFIX) where
|
|
3959 DIRSUFFIX and FILESUFFIX are strings added on unambiguous or exact
|
|
3960 completion. This mirrors the optional behavior of tcsh.")
|
9509
|
3961
|
|
3962 (defvar term-completion-recexact nil
|
|
3963 "*If non-nil, use shortest completion if characters cannot be added.
|
|
3964 This mirrors the optional behavior of tcsh.
|
|
3965
|
|
3966 A non-nil value is useful if `term-completion-autolist' is non-nil too.")
|
|
3967
|
|
3968 (defvar term-completion-fignore nil
|
|
3969 "*List of suffixes to be disregarded during file completion.
|
|
3970 This mirrors the optional behavior of bash and tcsh.
|
|
3971
|
|
3972 Note that this applies to `term-dynamic-complete-filename' only.")
|
|
3973
|
|
3974 (defvar term-file-name-prefix ""
|
|
3975 "Prefix prepended to absolute file names taken from process input.
|
|
3976 This is used by term's and shell's completion functions, and by shell's
|
|
3977 directory tracking functions.")
|
|
3978
|
|
3979
|
|
3980 (defun term-directory (directory)
|
|
3981 ;; Return expanded DIRECTORY, with `term-file-name-prefix' if absolute.
|
|
3982 (expand-file-name (if (file-name-absolute-p directory)
|
|
3983 (concat term-file-name-prefix directory)
|
|
3984 directory)))
|
|
3985
|
|
3986
|
|
3987 (defun term-word (word-chars)
|
63176
7a34bd511117
(term-mode, term-check-proc, term-input-sender, term-simple-send,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
3988 "Return the word of WORD-CHARS at point, or nil if none is found.
|
9509
|
3989 Word constituents are considered to be those in WORD-CHARS, which is like the
|
|
3990 inside of a \"[...]\" (see `skip-chars-forward')."
|
|
3991 (save-excursion
|
|
3992 (let ((limit (point))
|
|
3993 (word (concat "[" word-chars "]"))
|
|
3994 (non-word (concat "[^" word-chars "]")))
|
71054
|
3995 (when (re-search-backward non-word nil 'move)
|
|
3996 (forward-char 1))
|
9509
|
3997 ;; Anchor the search forwards.
|
|
3998 (if (or (eolp) (looking-at non-word))
|
|
3999 nil
|
|
4000 (re-search-forward (concat word "+") limit)
|
|
4001 (buffer-substring (match-beginning 0) (match-end 0))))))
|
|
4002
|
|
4003
|
|
4004 (defun term-match-partial-filename ()
|
63176
7a34bd511117
(term-mode, term-check-proc, term-input-sender, term-simple-send,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
4005 "Return the filename at point, or nil if none is found.
|
9509
|
4006 Environment variables are substituted. See `term-word'."
|
|
4007 (let ((filename (term-word "~/A-Za-z0-9+@:_.$#,={}-")))
|
|
4008 (and filename (substitute-in-file-name filename))))
|
|
4009
|
|
4010
|
|
4011 (defun term-dynamic-complete ()
|
|
4012 "Dynamically perform completion at point.
|
|
4013 Calls the functions in `term-dynamic-complete-functions' to perform
|
|
4014 completion until a function returns non-nil, at which point completion is
|
|
4015 assumed to have occurred."
|
|
4016 (interactive)
|
|
4017 (let ((functions term-dynamic-complete-functions))
|
|
4018 (while (and functions (null (funcall (car functions))))
|
|
4019 (setq functions (cdr functions)))))
|
|
4020
|
|
4021
|
|
4022 (defun term-dynamic-complete-filename ()
|
|
4023 "Dynamically complete the filename at point.
|
|
4024 Completes if after a filename. See `term-match-partial-filename' and
|
|
4025 `term-dynamic-complete-as-filename'.
|
|
4026 This function is similar to `term-replace-by-expanded-filename', except that
|
|
4027 it won't change parts of the filename already entered in the buffer; it just
|
|
4028 adds completion characters to the end of the filename. A completions listing
|
|
4029 may be shown in a help buffer if completion is ambiguous.
|
|
4030
|
|
4031 Completion is dependent on the value of `term-completion-addsuffix',
|
|
4032 `term-completion-recexact' and `term-completion-fignore', and the timing of
|
|
4033 completions listing is dependent on the value of `term-completion-autolist'.
|
|
4034
|
|
4035 Returns t if successful."
|
|
4036 (interactive)
|
71054
|
4037 (when (term-match-partial-filename)
|
|
4038 (prog2 (or (eq (selected-window) (minibuffer-window))
|
|
4039 (message "Completing file name..."))
|
|
4040 (term-dynamic-complete-as-filename))))
|
9509
|
4041
|
|
4042 (defun term-dynamic-complete-as-filename ()
|
|
4043 "Dynamically complete at point as a filename.
|
|
4044 See `term-dynamic-complete-filename'. Returns t if successful."
|
|
4045 (let* ((completion-ignore-case nil)
|
|
4046 (completion-ignored-extensions term-completion-fignore)
|
|
4047 (success t)
|
17147
|
4048 (dirsuffix (cond ((not term-completion-addsuffix) "")
|
|
4049 ((not (consp term-completion-addsuffix)) "/")
|
|
4050 (t (car term-completion-addsuffix))))
|
|
4051 (filesuffix (cond ((not term-completion-addsuffix) "")
|
|
4052 ((not (consp term-completion-addsuffix)) " ")
|
49597
|
4053 (t (cdr term-completion-addsuffix))))
|
9509
|
4054 (filename (or (term-match-partial-filename) ""))
|
|
4055 (pathdir (file-name-directory filename))
|
|
4056 (pathnondir (file-name-nondirectory filename))
|
|
4057 (directory (if pathdir (term-directory pathdir) default-directory))
|
|
4058 (completion (file-name-completion pathnondir directory))
|
|
4059 (mini-flag (eq (selected-window) (minibuffer-window))))
|
|
4060 (cond ((null completion)
|
|
4061 (message "No completions of %s" filename)
|
|
4062 (setq success nil))
|
|
4063 ((eq completion t) ; Means already completed "file".
|
71054
|
4064 (when term-completion-addsuffix (insert " "))
|
9509
|
4065 (or mini-flag (message "Sole completion")))
|
|
4066 ((string-equal completion "") ; Means completion on "directory/".
|
|
4067 (term-dynamic-list-filename-completions))
|
|
4068 (t ; Completion string returned.
|
|
4069 (let ((file (concat (file-name-as-directory directory) completion)))
|
|
4070 (insert (substring (directory-file-name completion)
|
|
4071 (length pathnondir)))
|
|
4072 (cond ((symbolp (file-name-completion completion directory))
|
|
4073 ;; We inserted a unique completion.
|
17147
|
4074 (insert (if (file-directory-p file) dirsuffix filesuffix))
|
9509
|
4075 (or mini-flag (message "Completed")))
|
|
4076 ((and term-completion-recexact term-completion-addsuffix
|
|
4077 (string-equal pathnondir completion)
|
|
4078 (file-exists-p file))
|
|
4079 ;; It's not unique, but user wants shortest match.
|
17147
|
4080 (insert (if (file-directory-p file) dirsuffix filesuffix))
|
9509
|
4081 (or mini-flag (message "Completed shortest")))
|
|
4082 ((or term-completion-autolist
|
|
4083 (string-equal pathnondir completion))
|
|
4084 ;; It's not unique, list possible completions.
|
|
4085 (term-dynamic-list-filename-completions))
|
|
4086 (t
|
|
4087 (or mini-flag (message "Partially completed")))))))
|
|
4088 success))
|
|
4089
|
|
4090
|
|
4091 (defun term-replace-by-expanded-filename ()
|
|
4092 "Dynamically expand and complete the filename at point.
|
63508
|
4093 Replace the filename with an expanded, canonicalized and completed replacement.
|
9509
|
4094 \"Expanded\" means environment variables (e.g., $HOME) and `~'s are replaced
|
63508
|
4095 with the corresponding directories. \"Canonicalized\" means `..' and `.' are
|
9509
|
4096 removed, and the filename is made absolute instead of relative. For expansion
|
|
4097 see `expand-file-name' and `substitute-in-file-name'. For completion see
|
|
4098 `term-dynamic-complete-filename'."
|
|
4099 (interactive)
|
|
4100 (replace-match (expand-file-name (term-match-partial-filename)) t t)
|
|
4101 (term-dynamic-complete-filename))
|
|
4102
|
|
4103
|
|
4104 (defun term-dynamic-simple-complete (stub candidates)
|
|
4105 "Dynamically complete STUB from CANDIDATES list.
|
|
4106 This function inserts completion characters at point by completing STUB from
|
|
4107 the strings in CANDIDATES. A completions listing may be shown in a help buffer
|
|
4108 if completion is ambiguous.
|
|
4109
|
|
4110 Returns nil if no completion was inserted.
|
|
4111 Returns `sole' if completed with the only completion match.
|
|
4112 Returns `shortest' if completed with the shortest of the completion matches.
|
|
4113 Returns `partial' if completed as far as possible with the completion matches.
|
|
4114 Returns `listed' if a completion listing was shown.
|
|
4115
|
|
4116 See also `term-dynamic-complete-filename'."
|
|
4117 (let* ((completion-ignore-case nil)
|
|
4118 (candidates (mapcar (function (lambda (x) (list x))) candidates))
|
|
4119 (completions (all-completions stub candidates)))
|
|
4120 (cond ((null completions)
|
|
4121 (message "No completions of %s" stub)
|
|
4122 nil)
|
|
4123 ((= 1 (length completions)) ; Gotcha!
|
|
4124 (let ((completion (car completions)))
|
|
4125 (if (string-equal completion stub)
|
|
4126 (message "Sole completion")
|
|
4127 (insert (substring completion (length stub)))
|
|
4128 (message "Completed"))
|
71054
|
4129 (when term-completion-addsuffix (insert " "))
|
9509
|
4130 'sole))
|
|
4131 (t ; There's no unique completion.
|
|
4132 (let ((completion (try-completion stub candidates)))
|
|
4133 ;; Insert the longest substring.
|
|
4134 (insert (substring completion (length stub)))
|
|
4135 (cond ((and term-completion-recexact term-completion-addsuffix
|
|
4136 (string-equal stub completion)
|
|
4137 (member completion completions))
|
|
4138 ;; It's not unique, but user wants shortest match.
|
|
4139 (insert " ")
|
|
4140 (message "Completed shortest")
|
|
4141 'shortest)
|
|
4142 ((or term-completion-autolist
|
|
4143 (string-equal stub completion))
|
|
4144 ;; It's not unique, list possible completions.
|
|
4145 (term-dynamic-list-completions completions)
|
|
4146 'listed)
|
|
4147 (t
|
|
4148 (message "Partially completed")
|
|
4149 'partial)))))))
|
|
4150
|
|
4151
|
|
4152 (defun term-dynamic-list-filename-completions ()
|
|
4153 "List in help buffer possible completions of the filename at point."
|
|
4154 (interactive)
|
|
4155 (let* ((completion-ignore-case nil)
|
|
4156 (filename (or (term-match-partial-filename) ""))
|
|
4157 (pathdir (file-name-directory filename))
|
|
4158 (pathnondir (file-name-nondirectory filename))
|
|
4159 (directory (if pathdir (term-directory pathdir) default-directory))
|
|
4160 (completions (file-name-all-completions pathnondir directory)))
|
|
4161 (if completions
|
|
4162 (term-dynamic-list-completions completions)
|
|
4163 (message "No completions of %s" filename))))
|
|
4164
|
|
4165
|
|
4166 (defun term-dynamic-list-completions (completions)
|
|
4167 "List in help buffer sorted COMPLETIONS.
|
|
4168 Typing SPC flushes the help buffer."
|
|
4169 (let ((conf (current-window-configuration)))
|
|
4170 (with-output-to-temp-buffer "*Completions*"
|
|
4171 (display-completion-list (sort completions 'string-lessp)))
|
|
4172 (message "Hit space to flush")
|
|
4173 (let (key first)
|
|
4174 (if (save-excursion
|
|
4175 (set-buffer (get-buffer "*Completions*"))
|
|
4176 (setq key (read-key-sequence nil)
|
|
4177 first (aref key 0))
|
|
4178 (and (consp first)
|
|
4179 (eq (window-buffer (posn-window (event-start first)))
|
|
4180 (get-buffer "*Completions*"))
|
|
4181 (eq (key-binding key) 'mouse-choose-completion)))
|
|
4182 ;; If the user does mouse-choose-completion with the mouse,
|
|
4183 ;; execute the command, then delete the completion window.
|
|
4184 (progn
|
|
4185 (mouse-choose-completion first)
|
|
4186 (set-window-configuration conf))
|
64024
|
4187 (if (eq first ?\s)
|
9509
|
4188 (set-window-configuration conf)
|
|
4189 (setq unread-command-events (listify-key-sequence key)))))))
|
17283
|
4190
|
|
4191 ;;; I need a make-term that doesn't surround with *s -mm
|
|
4192 (defun term-ansi-make-term (name program &optional startfile &rest switches)
|
|
4193 "Make a term process NAME in a buffer, running PROGRAM.
|
|
4194 The name of the buffer is NAME.
|
|
4195 If there is already a running process in that buffer, it is not restarted.
|
|
4196 Optional third arg STARTFILE is the name of a file to send the contents of to
|
|
4197 the process. Any more args are arguments to PROGRAM."
|
|
4198 (let ((buffer (get-buffer-create name )))
|
|
4199 ;; If no process, or nuked process, crank up a new one and put buffer in
|
|
4200 ;; term mode. Otherwise, leave buffer and existing process alone.
|
|
4201 (cond ((not (term-check-proc buffer))
|
|
4202 (save-excursion
|
|
4203 (set-buffer buffer)
|
|
4204 (term-mode)) ; Install local vars, mode, keymap, ...
|
|
4205 (term-exec buffer name program startfile switches)))
|
|
4206 buffer))
|
|
4207
|
|
4208 (defvar term-ansi-buffer-name nil)
|
|
4209 (defvar term-ansi-default-program nil)
|
|
4210 (defvar term-ansi-buffer-base-name nil)
|
|
4211
|
|
4212 ;;;###autoload
|
|
4213 (defun ansi-term (program &optional new-buffer-name)
|
|
4214 "Start a terminal-emulator in a new buffer."
|
|
4215 (interactive (list (read-from-minibuffer "Run program: "
|
|
4216 (or explicit-shell-file-name
|
|
4217 (getenv "ESHELL")
|
|
4218 (getenv "SHELL")
|
|
4219 "/bin/sh"))))
|
|
4220
|
|
4221 ;; Pick the name of the new buffer.
|
|
4222 (setq term-ansi-buffer-name
|
|
4223 (if new-buffer-name
|
|
4224 new-buffer-name
|
|
4225 (if term-ansi-buffer-base-name
|
|
4226 (if (eq term-ansi-buffer-base-name t)
|
|
4227 (file-name-nondirectory program)
|
|
4228 term-ansi-buffer-base-name)
|
|
4229 "ansi-term")))
|
|
4230
|
|
4231 (setq term-ansi-buffer-name (concat "*" term-ansi-buffer-name "*"))
|
|
4232
|
|
4233 ;; In order to have more than one term active at a time
|
|
4234 ;; I'd like to have the term names have the *term-ansi-term<?>* form,
|
|
4235 ;; for now they have the *term-ansi-term*<?> form but we'll see...
|
|
4236
|
|
4237 (setq term-ansi-buffer-name (generate-new-buffer-name term-ansi-buffer-name))
|
|
4238 (setq term-ansi-buffer-name (term-ansi-make-term term-ansi-buffer-name program))
|
|
4239
|
|
4240 (set-buffer term-ansi-buffer-name)
|
|
4241 (term-mode)
|
|
4242 (term-char-mode)
|
|
4243
|
|
4244 ;; I wanna have find-file on C-x C-f -mm
|
|
4245 ;; your mileage may definitely vary, maybe it's better to put this in your
|
|
4246 ;; .emacs ...
|
|
4247
|
|
4248 (term-set-escape-char ?\C-x)
|
|
4249
|
|
4250 (switch-to-buffer term-ansi-buffer-name))
|
|
4251
|
9509
|
4252
|
95879
|
4253 ;;; Serial terminals
|
|
4254 ;;; ===========================================================================
|
|
4255 (defun serial-port-is-file-p ()
|
|
4256 "Guess whether serial ports are files on this system.
|
|
4257 Return t if this is a Unix-based system, where serial ports are
|
|
4258 files, such as /dev/ttyS0.
|
|
4259 Return nil if this is Windows or DOS, where serial ports have
|
|
4260 special identifiers such as COM1."
|
|
4261 (not (member system-type (list 'windows-nt 'cygwin 'ms-dos))))
|
|
4262
|
|
4263 (defvar serial-name-history
|
|
4264 (if (serial-port-is-file-p)
|
|
4265 (or (when (file-exists-p "/dev/ttys0") (list "/dev/ttys0"))
|
|
4266 (when (file-exists-p "/dev/ttyS0") (list "/dev/ttyS0")))
|
|
4267 (list "COM1"))
|
|
4268 "History of serial ports used by `serial-read-name'.")
|
|
4269
|
|
4270 (defvar serial-speed-history
|
|
4271 ;; Initialised with reasonable values for newbies.
|
|
4272 (list "9600" ;; Given twice because 9600 b/s is the most common speed
|
|
4273 "1200" "2400" "4800" "9600" "14400" "19200"
|
|
4274 "28800" "38400" "57600" "115200")
|
|
4275 "History of serial port speeds used by `serial-read-speed'.")
|
|
4276
|
|
4277 (defun serial-nice-speed-history ()
|
|
4278 "Return `serial-speed-history' cleaned up for a mouse-menu."
|
|
4279 (let ((x) (y))
|
|
4280 (setq x
|
|
4281 (sort
|
|
4282 (copy-sequence serial-speed-history)
|
|
4283 '(lambda (a b) (when (and (stringp a) (stringp b))
|
|
4284 (> (string-to-number a) (string-to-number b))))))
|
|
4285 (dolist (i x) (when (not (equal i (car y))) (push i y)))
|
|
4286 y))
|
|
4287
|
|
4288 (defconst serial-no-speed "nil"
|
|
4289 "String for `serial-read-speed' for special serial ports.
|
|
4290 If `serial-read-speed' reads this string from the user, it
|
|
4291 returns nil, which is recognized by `serial-process-configure'
|
|
4292 for special serial ports that cannot be configured.")
|
|
4293
|
|
4294 (defun serial-supported-or-barf ()
|
|
4295 "Signal an error if serial processes are not supported"
|
|
4296 (unless (fboundp 'make-serial-process)
|
|
4297 (error "Serial processes are not supported on this system")))
|
|
4298
|
|
4299 (defun serial-read-name ()
|
|
4300 "Read a serial port name from the user.
|
|
4301 Try to be nice by providing useful defaults and history.
|
|
4302 On Windows, prepend \\.\ to the port name unless it already
|
|
4303 contains a backslash. This handles the legacy ports COM1-COM9 as
|
|
4304 well as the newer ports COM10 and higher."
|
|
4305 (serial-supported-or-barf)
|
|
4306 (let* ((file-name-history serial-name-history)
|
|
4307 (h (car file-name-history))
|
|
4308 (x (if (serial-port-is-file-p)
|
|
4309 (read-file-name
|
|
4310 ;; `prompt': The most recently used port is provided as
|
|
4311 ;; the default value, which is used when the user
|
|
4312 ;; simply presses return.
|
|
4313 (if (stringp h) (format "Serial port (default %s): " h)
|
|
4314 "Serial port: ")
|
|
4315 ;; `directory': Most systems have their serial ports
|
|
4316 ;; in the same directory, so start in the directory
|
|
4317 ;; of the most recently used port, or in a reasonable
|
|
4318 ;; default directory.
|
|
4319 (or (and h (file-name-directory h))
|
|
4320 (and (file-exists-p "/dev/") "/dev/")
|
|
4321 (and (file-exists-p "/") "/"))
|
|
4322 ;; `default': This causes (read-file-name) to return
|
|
4323 ;; the empty string if he user simply presses return.
|
|
4324 ;; Using nil here may result in a default directory
|
|
4325 ;; of the current buffer, which is not useful for
|
|
4326 ;; serial port.
|
|
4327 "")
|
|
4328 (read-from-minibuffer
|
|
4329 (if (stringp h) (format "Serial port (default %s): " h)
|
|
4330 "Serial port: ")
|
|
4331 nil nil nil '(file-name-history . 1) nil nil))))
|
|
4332 (if (or (null x) (and (stringp x) (zerop (length x))))
|
|
4333 (setq x h)
|
|
4334 (setq serial-name-history file-name-history))
|
|
4335 (when (or (null x) (and (stringp x) (zerop (length x))))
|
|
4336 (error "No serial port selected"))
|
|
4337 (when (and (not (serial-port-is-file-p))
|
|
4338 (not (string-match "\\\\" x)))
|
|
4339 (set 'x (concat "\\\\.\\" x)))
|
|
4340 x))
|
|
4341
|
|
4342 (defun serial-read-speed ()
|
|
4343 "Read a serial port speed (in bits per second) from the user.
|
|
4344 Try to be nice by providing useful defaults and history."
|
|
4345 (serial-supported-or-barf)
|
|
4346 (let* ((history serial-speed-history)
|
|
4347 (h (car history))
|
|
4348 (x (read-from-minibuffer
|
|
4349 (cond ((string= h serial-no-speed)
|
|
4350 "Speed (default nil = set by port): ")
|
|
4351 (h
|
|
4352 (format "Speed (default %s b/s): " h))
|
|
4353 (t
|
|
4354 (format "Speed (b/s): ")))
|
|
4355 nil nil nil '(history . 1) nil nil)))
|
|
4356 (when (or (null x) (and (stringp x) (zerop (length x))))
|
|
4357 (setq x h))
|
|
4358 (when (or (null x) (not (stringp x)) (zerop (length x)))
|
|
4359 (error "Invalid speed"))
|
|
4360 (if (string= x serial-no-speed)
|
|
4361 (setq x nil)
|
|
4362 (setq x (string-to-number x))
|
|
4363 (when (or (null x) (not (integerp x)) (<= x 0))
|
|
4364 (error "Invalid speed")))
|
|
4365 (setq serial-speed-history history)
|
|
4366 x))
|
|
4367
|
|
4368 ;;;###autoload
|
|
4369 (defun serial-term (port speed)
|
|
4370 "Start a terminal-emulator for a serial port in a new buffer.
|
|
4371 PORT is the path or name of the serial port. For example, this
|
|
4372 could be \"/dev/ttyS0\" on Unix. On Windows, this could be
|
|
4373 \"COM1\" or \"\\\\.\\COM10\".
|
|
4374 SPEED is the speed of the serial port in bits per second. 9600
|
|
4375 is a common value. SPEED can be nil, see
|
|
4376 `serial-process-configure' for details.
|
|
4377 The buffer is in Term mode; see `term-mode' for the commands to
|
|
4378 use in that buffer.
|
|
4379 \\<term-raw-map>Type \\[switch-to-buffer] to switch to another buffer."
|
|
4380 (interactive (list (serial-read-name) (serial-read-speed)))
|
|
4381 (serial-supported-or-barf)
|
|
4382 (let* ((process (make-serial-process
|
|
4383 :port port
|
|
4384 :speed speed
|
|
4385 :coding 'no-conversion
|
|
4386 :noquery t))
|
|
4387 (buffer (process-buffer process)))
|
|
4388 (save-excursion
|
|
4389 (set-buffer buffer)
|
|
4390 (term-mode)
|
|
4391 (term-char-mode)
|
|
4392 (goto-char (point-max))
|
|
4393 (set-marker (process-mark process) (point))
|
|
4394 (set-process-filter process 'term-emulate-terminal)
|
|
4395 (set-process-sentinel process 'term-sentinel))
|
|
4396 (switch-to-buffer buffer)
|
|
4397 buffer))
|
|
4398
|
|
4399 (defvar serial-mode-line-speed-menu nil)
|
|
4400 (defvar serial-mode-line-config-menu nil)
|
|
4401
|
|
4402 (defun serial-speed ()
|
|
4403 "Return the speed of the serial port of the current buffer's process.
|
|
4404 The return value may be nil for a special serial port."
|
|
4405 (process-contact (get-buffer-process (current-buffer)) :speed))
|
|
4406
|
|
4407 (defun serial-mode-line-speed-menu-1 (event)
|
|
4408 (interactive "e")
|
|
4409 (save-selected-window
|
|
4410 (select-window (posn-window (event-start event)))
|
|
4411 (serial-update-speed-menu)
|
|
4412 (let* ((selection (serial-mode-line-speed-menu event))
|
|
4413 (binding (and selection (lookup-key serial-mode-line-speed-menu
|
|
4414 (vector (car selection))))))
|
|
4415 (when binding (call-interactively binding)))))
|
|
4416
|
|
4417 (defun serial-mode-line-speed-menu (event)
|
|
4418 (x-popup-menu event serial-mode-line-speed-menu))
|
|
4419
|
|
4420 (defun serial-update-speed-menu ()
|
|
4421 (setq serial-mode-line-speed-menu (make-sparse-keymap "Speed (b/s)"))
|
|
4422 (define-key serial-mode-line-speed-menu [serial-mode-line-speed-menu-other]
|
|
4423 '(menu-item "Other..."
|
|
4424 (lambda (event) (interactive "e")
|
|
4425 (let ((speed (serial-read-speed)))
|
|
4426 (serial-process-configure :speed speed)
|
|
4427 (term-update-mode-line)
|
|
4428 (message "Speed set to %d b/s" speed)))))
|
|
4429 (dolist (str (serial-nice-speed-history))
|
|
4430 (let ((num (or (and (stringp str) (string-to-number str)) 0)))
|
|
4431 (define-key
|
|
4432 serial-mode-line-speed-menu
|
|
4433 (vector (make-symbol (format "serial-mode-line-speed-menu-%s" str)))
|
|
4434 `(menu-item
|
|
4435 ,str
|
|
4436 (lambda (event) (interactive "e")
|
|
4437 (serial-process-configure :speed ,num)
|
|
4438 (term-update-mode-line)
|
|
4439 (message "Speed set to %d b/s" ,num))
|
|
4440 :button (:toggle . (= (serial-speed) ,num)))))))
|
|
4441
|
|
4442 (defun serial-mode-line-config-menu-1 (event)
|
|
4443 (interactive "e")
|
|
4444 (save-selected-window
|
|
4445 (select-window (posn-window (event-start event)))
|
|
4446 (serial-update-config-menu)
|
|
4447 (let* ((selection (serial-mode-line-config-menu event))
|
|
4448 (binding (and selection (lookup-key serial-mode-line-config-menu
|
|
4449 (vector (car selection))))))
|
|
4450 (when binding (call-interactively binding)))))
|
|
4451
|
|
4452 (defun serial-mode-line-config-menu (event)
|
|
4453 (x-popup-menu event serial-mode-line-config-menu))
|
|
4454
|
|
4455 (defun serial-update-config-menu ()
|
|
4456 (setq serial-mode-line-config-menu (make-sparse-keymap "Configuration"))
|
|
4457 (let ((config (process-contact
|
|
4458 (get-buffer-process (current-buffer)) t))
|
|
4459 (y)
|
|
4460 (str))
|
|
4461 (dolist (y '((:flowcontrol hw "Hardware flowcontrol (RTS/CTS)")
|
|
4462 (:flowcontrol sw "Software flowcontrol (XON/XOFF)")
|
|
4463 (:flowcontrol nil "No flowcontrol")
|
|
4464 (:stopbits 2 "2 stopbits")
|
|
4465 (:stopbits 1 "1 stopbit")
|
|
4466 (:parity odd "Odd parity")
|
|
4467 (:parity even "Even parity")
|
|
4468 (:parity nil "No parity")
|
|
4469 (:bytesize 7 "7 bits per byte")
|
|
4470 (:bytesize 8 "8 bits per byte")))
|
|
4471 (define-key serial-mode-line-config-menu
|
|
4472 (vector (make-symbol (format "%s-%s" (nth 0 y) (nth 1 y))))
|
|
4473 `(menu-item
|
|
4474 ,(nth 2 y)
|
|
4475 (lambda (event) (interactive "e")
|
|
4476 (serial-process-configure ,(nth 0 y) ',(nth 1 y))
|
|
4477 (term-update-mode-line)
|
|
4478 (message "%s" ,(nth 2 y)))
|
|
4479 ;; Use :toggle instead of :radio because a non-standard port
|
|
4480 ;; configuration may not match any menu items.
|
|
4481 :button (:toggle . ,(equal (plist-get config (nth 0 y))
|
|
4482 (nth 1 y))))))))
|
|
4483
|
|
4484
|
9509
|
4485 ;;; Converting process modes to use term mode
|
|
4486 ;;; ===========================================================================
|
|
4487 ;;; Renaming variables
|
17283
|
4488 ;;; Most of the work is renaming variables and functions. These are the common
|
9509
|
4489 ;;; ones:
|
|
4490 ;;; Local variables:
|
|
4491 ;;; last-input-start term-last-input-start
|
|
4492 ;;; last-input-end term-last-input-end
|
|
4493 ;;; shell-prompt-pattern term-prompt-regexp
|
|
4494 ;;; shell-set-directory-error-hook <no equivalent>
|
|
4495 ;;; Miscellaneous:
|
|
4496 ;;; shell-set-directory <unnecessary>
|
|
4497 ;;; shell-mode-map term-mode-map
|
|
4498 ;;; Commands:
|
|
4499 ;;; shell-send-input term-send-input
|
|
4500 ;;; shell-send-eof term-delchar-or-maybe-eof
|
|
4501 ;;; kill-shell-input term-kill-input
|
|
4502 ;;; interrupt-shell-subjob term-interrupt-subjob
|
|
4503 ;;; stop-shell-subjob term-stop-subjob
|
|
4504 ;;; quit-shell-subjob term-quit-subjob
|
|
4505 ;;; kill-shell-subjob term-kill-subjob
|
|
4506 ;;; kill-output-from-shell term-kill-output
|
|
4507 ;;; show-output-from-shell term-show-output
|
|
4508 ;;; copy-last-shell-input Use term-previous-input/term-next-input
|
|
4509 ;;;
|
|
4510 ;;; SHELL-SET-DIRECTORY is gone, its functionality taken over by
|
|
4511 ;;; SHELL-DIRECTORY-TRACKER, the shell mode's term-input-filter-functions.
|
|
4512 ;;; Term mode does not provide functionality equivalent to
|
|
4513 ;;; shell-set-directory-error-hook; it is gone.
|
|
4514 ;;;
|
|
4515 ;;; term-last-input-start is provided for modes which want to munge
|
|
4516 ;;; the buffer after input is sent, perhaps because the inferior
|
|
4517 ;;; insists on echoing the input. The LAST-INPUT-START variable in
|
|
4518 ;;; the old shell package was used to implement a history mechanism,
|
|
4519 ;;; but you should think twice before using term-last-input-start
|
|
4520 ;;; for this; the input history ring often does the job better.
|
17283
|
4521 ;;;
|
9509
|
4522 ;;; If you are implementing some process-in-a-buffer mode, called foo-mode, do
|
|
4523 ;;; *not* create the term-mode local variables in your foo-mode function.
|
|
4524 ;;; This is not modular. Instead, call term-mode, and let *it* create the
|
17283
|
4525 ;;; necessary term-specific local variables. Then create the
|
9509
|
4526 ;;; foo-mode-specific local variables in foo-mode. Set the buffer's keymap to
|
|
4527 ;;; be foo-mode-map, and its mode to be foo-mode. Set the term-mode hooks
|
|
4528 ;;; (term-{prompt-regexp, input-filter, input-filter-functions,
|
|
4529 ;;; get-old-input) that need to be different from the defaults. Call
|
17283
|
4530 ;;; foo-mode-hook, and you're done. Don't run the term-mode hook yourself;
|
|
4531 ;;; term-mode will take care of it. The following example, from shell.el,
|
9509
|
4532 ;;; is typical:
|
17283
|
4533 ;;;
|
9509
|
4534 ;;; (defvar shell-mode-map '())
|
|
4535 ;;; (cond ((not shell-mode-map)
|
|
4536 ;;; (setq shell-mode-map (copy-keymap term-mode-map))
|
|
4537 ;;; (define-key shell-mode-map "\C-c\C-f" 'shell-forward-command)
|
|
4538 ;;; (define-key shell-mode-map "\C-c\C-b" 'shell-backward-command)
|
|
4539 ;;; (define-key shell-mode-map "\t" 'term-dynamic-complete)
|
|
4540 ;;; (define-key shell-mode-map "\M-?"
|
|
4541 ;;; 'term-dynamic-list-filename-completions)))
|
|
4542 ;;;
|
|
4543 ;;; (defun shell-mode ()
|
|
4544 ;;; (interactive)
|
|
4545 ;;; (term-mode)
|
|
4546 ;;; (setq term-prompt-regexp shell-prompt-pattern)
|
|
4547 ;;; (setq major-mode 'shell-mode)
|
|
4548 ;;; (setq mode-name "Shell")
|
|
4549 ;;; (use-local-map shell-mode-map)
|
|
4550 ;;; (make-local-variable 'shell-directory-stack)
|
|
4551 ;;; (setq shell-directory-stack nil)
|
|
4552 ;;; (add-hook 'term-input-filter-functions 'shell-directory-tracker)
|
62744
|
4553 ;;; (run-mode-hooks 'shell-mode-hook))
|
9509
|
4554 ;;;
|
|
4555 ;;;
|
|
4556 ;;; Completion for term-mode users
|
17283
|
4557 ;;;
|
9509
|
4558 ;;; For modes that use term-mode, term-dynamic-complete-functions is the
|
|
4559 ;;; hook to add completion functions to. Functions on this list should return
|
|
4560 ;;; non-nil if completion occurs (i.e., further completion should not occur).
|
|
4561 ;;; You could use term-dynamic-simple-complete to do the bulk of the
|
|
4562 ;;; completion job.
|
|
4563
|
|
4564 (provide 'term)
|
|
4565
|
93975
|
4566 ;; arch-tag: eee16bc8-2cd7-4147-9534-a5694752f716
|
9509
|
4567 ;;; term.el ends here
|