;;; rlogin.el --- remote login interface
+;; Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+
;; Author: Noah Friedman
;; Maintainer: Noah Friedman <friedman@prep.ai.mit.edu>
;; Keywords: unix, comm
-;; Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
-;;
-;; This program is free software; you can redistribute it and/or modify
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.
-;;
-;; This program is distributed in the hope that it will be useful,
+
+;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
-;;
+
;; You should have received a copy of the GNU General Public License
-;; along with this program; if not, write to: The Free Software Foundation,
-;; Inc.; 675 Massachusetts Avenue.; Cambridge, MA 02139, USA.
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
-;; $Id$
+;; $Id: rlogin.el,v 1.34 1996/06/20 17:30:41 friedman Exp friedman $
;;; Commentary:
"*Hooks to run after setting current buffer to rlogin-mode.")
(defvar rlogin-process-connection-type nil
- "*If non-`nil', use a pty for the local rlogin process.
-If `nil', use a pipe (if pipes are supported on the local system).
+ "*If non-`nil', use a pty for the local rlogin process.
+If `nil', use a pipe (if pipes are supported on the local system).
Generally it is better not to waste ptys on systems which have a static
number of them. On the other hand, some implementations of `rlogin' assume
;; Initialize rlogin mode map.
(defvar rlogin-mode-map '())
-(cond
+(cond
((null rlogin-mode-map)
(setq rlogin-mode-map (if (consp shell-mode-map)
(cons 'keymap shell-mode-map)
(define-key rlogin-mode-map "\C-i" 'rlogin-tab-or-complete)))
\f
+;;;###autoload (add-hook 'same-window-regexps "^\\*rlogin-.*\\*\\(\\|<[0-9]+>\\)")
+
+(defvar rlogin-history nil)
+
;;;###autoload
-(defun rlogin (input-args &optional prefix)
- "Open a network login connection to HOST via the `rlogin' program.
+(defun rlogin (input-args &optional buffer)
+ "Open a network login connection via `rlogin' with args INPUT-ARGS.
+INPUT-ARGS should start with a host name; it may also contain
+other arguments for `rlogin'.
+
Input is sent line-at-a-time to the remote connection.
-Communication with the remote host is recorded in a buffer *rlogin-HOST*
-\(or *rlogin-USER@HOST* if the remote username differs\).
-If a prefix argument is given and the buffer *rlogin-HOST* already exists,
+Communication with the remote host is recorded in a buffer `*rlogin-HOST*'
+\(or `*rlogin-USER@HOST*' if the remote username differs\).
+If a prefix argument is given and the buffer `*rlogin-HOST*' already exists,
a new buffer with a different connection will be made.
+When called from a program, if the optional second argument BUFFER is
+a string or buffer, it specifies the buffer to use.
+
The variable `rlogin-program' contains the name of the actual program to
-run. It can be a relative or absolute path.
+run. It can be a relative or absolute path.
The variable `rlogin-explicit-args' is a list of arguments to give to
the rlogin when starting. They are added after any arguments given in
function `rlogin-directory-tracking-mode' rather than simply setting the
variable."
(interactive (list
- (read-from-minibuffer "rlogin arguments (hostname first): ")
+ (read-from-minibuffer "rlogin arguments (hostname first): "
+ nil nil nil 'rlogin-history)
current-prefix-arg))
(let* ((process-connection-type rlogin-process-connection-type)
(format "*rlogin-%s@%s*" user host)))
proc)
+ (cond ((null buffer))
+ ((stringp buffer)
+ (setq buffer-name buffer))
+ ((bufferp buffer)
+ (setq buffer-name (buffer-name buffer)))
+ ((numberp buffer)
+ (setq buffer-name (format "%s<%d>" buffer-name buffer)))
+ (t
+ (setq buffer-name (generate-new-buffer-name buffer-name))))
+
+ (setq buffer (get-buffer-create buffer-name))
+ (pop-to-buffer buffer-name)
+
(cond
- ((and (null prefix)
- (comint-check-proc buffer-name))
- (switch-to-buffer buffer-name))
- ;; This next case is done all in the predicate (including side effects
- ;; like switch-to-buffer) to avoid extra string consing via multiple
- ;; concats.
- ((and (numberp prefix)
- (let ((bufname (concat buffer-name "<" prefix ">")))
- (and (comint-check-proc bufname)
- (switch-to-buffer bufname)))))
+ ((comint-check-proc buffer-name))
(t
- (cond
- ((numberp prefix)
- (setq buffer-name (concat buffer-name "<" prefix ">")))
- (t
- (setq buffer-name (generate-new-buffer-name buffer-name))))
- (switch-to-buffer buffer-name)
- (comint-exec (current-buffer) buffer-name rlogin-program nil args)
- (setq proc (get-process buffer-name))
+ (comint-exec buffer buffer-name rlogin-program nil args)
+ (setq proc (get-buffer-process buffer))
;; Set process-mark to point-max in case there is text in the
;; buffer from a previous exited process.
(set-marker (process-mark proc) (point-max))
- (rlogin-mode)
-
+
;; comint-output-filter-functions is just like a hook, except that the
;; functions in that list are passed arguments. add-hook serves well
;; enough for modifying it.
+ ;; comint-output-filter-functions should already have a
+ ;; permanent-local property, at least in emacs 19.27 or later.
+ (if (fboundp 'make-local-hook)
+ (make-local-hook 'comint-output-filter-functions)
+ (make-local-variable 'comint-output-filter-functions))
(add-hook 'comint-output-filter-functions 'rlogin-carriage-filter)
+ (rlogin-mode)
+
(make-local-variable 'rlogin-host)
(setq rlogin-host host)
- (make-local-variable 'rlogin-user)
- (setq rlogin-user user)
-
- (cond
- ((eq rlogin-directory-tracking-mode t)
- ;; Do this here, rather than calling the tracking mode function, to
- ;; avoid a gratuitous resync check; the default should be the
- ;; user's home directory, be it local or remote.
- (setq comint-file-name-prefix
- (concat "/" rlogin-user "@" rlogin-host ":"))
- (cd-absolute comint-file-name-prefix))
- ((null rlogin-directory-tracking-mode))
- (t
- (cd-absolute (concat comint-file-name-prefix "~/"))))))))
+ (make-local-variable 'rlogin-remote-user)
+ (setq rlogin-remote-user user)
+
+ (condition-case ()
+ (cond ((eq rlogin-directory-tracking-mode t)
+ ;; Do this here, rather than calling the tracking mode
+ ;; function, to avoid a gratuitous resync check; the default
+ ;; should be the user's home directory, be it local or remote.
+ (setq comint-file-name-prefix
+ (concat "/" rlogin-remote-user "@" rlogin-host ":"))
+ (cd-absolute comint-file-name-prefix))
+ ((null rlogin-directory-tracking-mode))
+ (t
+ (cd-absolute (concat comint-file-name-prefix "~/"))))
+ (error nil))))))
(defun rlogin-mode ()
- "Set major-mode for rlogin sessions.
+ "Set major-mode for rlogin sessions.
If `rlogin-mode-hook' is set, run it."
(interactive)
(kill-all-local-variables)
If called with a negative prefix argument, disable directory tracking
entirely.
-If called with a positive, numeric prefix argument, e.g.
+If called with a positive, numeric prefix argument, e.g.
``\\[universal-argument] 1 M-x rlogin-directory-tracking-mode\'',
then do directory tracking but assume the remote filesystem is the same as
the local system. This only works in general if the remote machine and the
((or (null prefix)
(consp prefix))
(setq rlogin-directory-tracking-mode t)
- (setq shell-dirtrack-p t)
- (setq comint-file-name-prefix
- (concat "/" rlogin-user "@" rlogin-host ":")))
+ (setq shell-dirtrackp t)
+ (setq comint-file-name-prefix
+ (concat "/" rlogin-remote-user "@" rlogin-host ":")))
((< prefix 0)
(setq rlogin-directory-tracking-mode nil)
- (setq shell-dirtrack-p nil))
+ (setq shell-dirtrackp nil))
(t
(setq rlogin-directory-tracking-mode 'local)
(setq comint-file-name-prefix "")
- (setq shell-dirtrack-p t)))
- (cond
- (shell-dirtrack-p
+ (setq shell-dirtrackp t)))
+ (cond
+ (shell-dirtrackp
(let* ((proc (get-buffer-process (current-buffer)))
(proc-mark (process-mark proc))
(current-input (buffer-substring proc-mark (point-max)))
(store-match-data (match-data))
(nreverse list)))
-(defun rlogin-carriage-filter (&rest ignored)
- ;; When this function is called, the buffer will already have been
- ;; narrowed to the region containing the most recently-inserted text.
- ;; (See `comint-output-filter' in comint.el.)
- (let ((point-marker (point-marker)))
- (goto-char (point-min))
- (while (search-forward "\C-m" (point-max) t)
+(defun rlogin-carriage-filter (string)
+ (let* ((point-marker (point-marker))
+ (end (process-mark (get-buffer-process (current-buffer))))
+ (beg (or (and (boundp 'comint-last-output-start)
+ comint-last-output-start)
+ (- end (length string)))))
+ (goto-char beg)
+ (while (search-forward "\C-m" end t)
(delete-char -1))
(goto-char point-marker)))
(defun rlogin-delchar-or-send-Ctrl-D (arg)
"\
-Delete ARG characters forward, or send a C-d to process if at end of buffer."
- (interactive "p")
+Delete ARG characters forward, or send a C-d to process if at end of buffer."
+ (interactive "p")
(if (eobp)
(rlogin-send-Ctrl-D)
(delete-char arg)))
(defun rlogin-tab-or-complete ()
- "Complete file name if doing directory tracking, or just send TAB."
+ "Complete file name if doing directory tracking, or just insert TAB."
(interactive)
(if rlogin-directory-tracking-mode
(comint-dynamic-complete)
- (send-string nil "\C-i")))
+ (insert "\C-i")))
;;; rlogin.el ends here