conor@goose.UUCP (Conor Rafferty) (12/04/87)
Expires:
References:
Sender:
Followup-To:
Distribution:
A new version of gnumacs just came up for me with a minimum of bother.
To express my gratitude :) I have collected a few little hacks I use
to make interaction with subshells more convenient. Particularly subshells
containing dbx. The first hack, called shell-repeat, takes an expression like
print pt[nd[0:2]->pt]->cord
and turns it into
print pt[nd[0]->pt]->cord; print pt[nd[1]->pt]->cord; print pt[nd[2]->pt]->cord
Vi lovers have said it's almost enough to convert them :-)
The second hack is called just-like-csh and does what you would expect.
!! repeats the previous command
!a repeats the previous command starting with an a
!?abc repeats the previous command containing abc
just-like-csh relies on shell and telnet windows copying user input
lines into a buffer called *history*. That requires a minor change
in both shell.el and telnet.el.
------------------------------Changes to shell.el------------------------------
*** /u2/conor/bin/shell.el Thu Dec 3 22:30:14 1987
--- /u2/conor/src/emacs/lisp/shell.el Fri Aug 14 14:55:08 1987
***************
*** 216,228 ****
(goto-char last-input-start)
(shell-set-directory))
(error (funcall shell-set-directory-error-hook)))
! (let ((process (get-buffer-process (current-buffer))) command-copy) ;csr{
(process-send-region process last-input-start last-input-end)
! (set-marker (process-mark process) (point))
! (setq command-copy (buffer-substring last-input-start last-input-end))
! (set-buffer (get-buffer-create "*history*"))
! (end-of-buffer)
! (insert command-copy))) ;csr}
;;; If this code changes (shell-send-input and shell-set-directory),
;;; the customization tutorial in
;;; info/customizing-tutorial must also change, since it explains this
--- 216,225 ----
(goto-char last-input-start)
(shell-set-directory))
(error (funcall shell-set-directory-error-hook)))
! (let ((process (get-buffer-process (current-buffer))))
(process-send-region process last-input-start last-input-end)
! (set-marker (process-mark process) (point))))
!
;;; If this code changes (shell-send-input and shell-set-directory),
;;; the customization tutorial in
;;; info/customizing-tutorial must also change, since it explains this
------------------------------Changes to telnet.el------------------------------
*** /u2/conor/bin/telnet.el Thu Dec 3 22:31:00 1987
--- /u2/conor/src/emacs/lisp/telnet.el Tue Sep 1 10:28:14 1987
***************
*** 24,31 ****
;;to eval current expression. Also to try to send escape keys correctly.
;;essentially we'll want the rubout-handler off.
- (provide 'telnet)
-
(defvar telnet-new-line "\r")
(defvar telnet-mode-map nil)
(defvar telnet-prompt-pattern "^[^#$%>]*[#$%>] *")
--- 24,29 ----
***************
*** 97,106 ****
(t (setq telnet-count (1+ telnet-count)))))))
(defun telnet-filter (proc string)
- (let ((move-point-p)) ;csr to avoid underfoot movement
(save-excursion
(set-buffer (process-buffer proc))
- (if (eq (point) (point-max)) (setq move-point-p t)) ;csr
(goto-char (point-max))
(let ((now (point)))
(insert string)
--- 95,102 ----
***************
*** 112,122 ****
(marker-position last-input-start)
telnet-remote-echoes)
(delete-region last-input-start last-input-end)))
! (if (and ;csr
! move-point-p ;csr
! (eq (process-buffer proc)
! (current-buffer)))
! (goto-char (point-max)))))
(defun delete-char-or-send-eof (arg killp)
"At end of buffer, send eof to subshell. Otherwise delete character."
--- 108,116 ----
(marker-position last-input-start)
telnet-remote-echoes)
(delete-region last-input-start last-input-end)))
! (if (eq (process-buffer proc)
! (current-buffer))
! (goto-char (point-max))))
(defun delete-char-or-send-eof (arg killp)
"At end of buffer, send eof to subshell. Otherwise delete character."
***************
*** 150,164 ****
(move-marker last-input-end (point))))
(save-excursion
(goto-char last-input-start)
! (shell-set-directory)
! (let ((process (get-buffer-process (current-buffer))) copy-command) ;csr{
(send-region process last-input-start last-input-end)
(if (not copied) (send-string process telnet-new-line))
! (set-marker (process-mark process) (point))
! (setq copy-command (buffer-substring last-input-start last-input-end))
! (set-buffer (get-buffer-create "*history*"))
! (goto-char (point-max))
! (insert copy-command "\n"))))) ;csr}
(defun telnet (arg)
"Open a network login connection to host named HOST (a string).
--- 144,153 ----
(move-marker last-input-end (point))))
(save-excursion
(goto-char last-input-start)
! (let ((process (get-buffer-process (current-buffer))))
(send-region process last-input-start last-input-end)
(if (not copied) (send-string process telnet-new-line))
! (set-marker (process-mark process) (point))))))
(defun telnet (arg)
"Open a network login connection to host named HOST (a string).
------------------------------shell-util.el------------------------------
; load this explicitly
(require 'shell)
(require 'telnet)
(require 'blisp)
;----------
;Extra history stuff
;----------
(defvar last-shell nil "shell buffer to copy input to")
(defvar history-map nil "map inside history buffer")
;define the history buffer
(save-excursion
(set-buffer (get-buffer-create "*history*"))
(if (not history-map) (setq history-map (make-sparse-keymap)))
(define-key history-map "\C-m" 'copy-history-to-shell)
(use-local-map history-map)
)
;how you go back to shells
(defun copy-history-to-shell ()
(interactive)
(let ((line (buffer-line)))
(or last-shell (error "no last shell defined?!"))
(switch-to-window last-shell)
(goto-char (point-max))
(insert line)))
;define how you get there from shells
(define-key shell-mode-map "\e!" 'switch-to-history)
(define-key shell-mode-map "!" 'just-like-csh)
(define-key telnet-mode-map "\e!" 'switch-to-history)
(define-key telnet-mode-map "!" 'just-like-csh)
(defun switch-to-history ()
(interactive)
(setq last-shell (current-buffer))
(switch-to-buffer "*history*"))
(defun just-like-csh ()
(interactive)
(setq last-shell (current-buffer))
(let ((s (read-string "Repeat: ")))
(set-buffer "*history*")
(save-excursion
(goto-char (point-max))
(cond
((or (zerop (length s)) (equal (aref s 0) ?!))
(re-search-backward "^."))
((equal (aref s 0) ??)
(search-backward (substring s 1)))
(t
(re-search-backward (concat "^" (regexp-quote s)))))
(copy-history-to-shell))))
;----------
;random
;----------
(define-key shell-mode-map "\C-x9" 'shell-repeat)
(define-key telnet-mode-map "\C-x9" 'shell-repeat)
(defun shell-repeat ()
"Expands arithmetic loops. ``p pt[nd[0:2]->pt]'' becomes
``p pt[nd[0]->pt]->cord;p pt[nd[1]->pt]->cord;p pt[nd[2]->pt]->cord;''
This makes unprogrammable debuggers like dbx a little more tolerable."
(interactive)
(let (start-user end-user line count lo hi lsp last-insert)
(if (not (eobp))
(message "Only works at end of buffer")
(setq start-user (process-mark (get-buffer-process (current-buffer))))
(goto-char start-user)
;Someday, add , in the expansion
(re-search-forward "\\([0-9]+\\):\\([0-9]+\\)")
(setq lo (buffer-substring (match-beginning 1) (match-end 1)))
(setq hi (buffer-substring (match-beginning 2) (match-end 2)))
(setq lo (string-to-int lo))
(setq hi (string-to-int hi))
(if (< hi lo) (error "first number must be less than second"))
(end-of-line)
(setq end-user (point))
(setq line (buffer-substring start-user end-user))
(kill-region start-user end-user)
;Get exciting screen action because replace-regexp calls push-mark
(setq count lo)
(setq lsp start-user)
(while (<= count hi)
(goto-char (point-max));
(setq last-insert (point))
; Hack to avoid sending > 200 chars per line to send-region
(if (> (- last-insert lsp) 200) (progn (insert "\n") (setq lsp last-insert)))
(insert line)
(goto-char last-insert)
(replace-regexp "[0-9]+:[0-9]+" (int-to-string count))
(goto-char (point-max))
(insert ";")
(setq count (+ count 1)))
(set-buffer "*history*")
(end-of-buffer)
(insert line "\n"))))
------------------------------blisp.el------------------------------
; some basic lisp functions
; I repeat again and again.
(provide 'blisp)
(defun lose-buffer (&optional bufname)
"Do what bury-buffer only promises to do"
(interactive)
(if (not bufname)
(setq bufname (current-buffer)))
(bury-buffer bufname)
(switch-to-buffer (other-buffer (current-buffer))))
(defun switch-to-window (name)
"select the window of the named BUFFER. If none, get one."
(let* ((bbb (if (bufferp name) name (get-buffer name)))
(www (get-buffer-window bbb)))
(if www
(progn
(select-window www)
(set-buffer bbb)) ; looks but isn't redundant
(switch-to-buffer bbb))))
(defun buffer-line ()
(save-excursion
(buffer-substring (progn (beginning-of-line) (point))
(progn (end-of-line) (point)))))