annotate lisp/eshell/esh-util.el @ 91817:f0b22bbb77fb

;;; smtpmail.el --- simple SMTP protocol (RFC 821) for sending mail ;; Copyright (C) 1995, 1996, 2001, 2002, 2003, 2004, 2005, ;; 2006, 2007, 2008 Free Software Foundation, Inc. ;; Author: Tomoji Kagatani <kagatani@rbc.ncl.omron.co.jp> ;; Maintainer: Simon Josefsson <simon@josefsson.org> ;; w32 Maintainer: Brian D. Carlstrom <bdc@ai.mit.edu> ;; ESMTP support: Simon Leinen <simon@switch.ch> ;; Hacked by Mike Taylor, 11th October 1999 to add support for ;; automatically appending a domain to RCPT TO: addresses. ;; AUTH=LOGIN support: Stephen Cranefield <scranefield@infoscience.otago.ac.nz> ;; Keywords: mail ;; 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 3, or (at your option) ;; any later version. ;; 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 GNU Emacs; see the file COPYING. If not, write to the ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, ;; Boston, MA 02110-1301, USA. ;;; Commentary: ;; Send Mail to smtp host from smtpmail temp buffer. ;; Please add these lines in your .emacs(_emacs) or use customize. ;; ;;(setq send-mail-function 'smtpmail-send-it) ; if you use `mail' ;;(setq message-send-mail-function 'smtpmail-send-it) ; if you use message/Gnus ;;(setq smtpmail-default-smtp-server "YOUR SMTP HOST") ;;(setq smtpmail-local-domain "YOUR DOMAIN NAME") ;;(setq smtpmail-sendto-domain "YOUR DOMAIN NAME") ;;(setq smtpmail-debug-info t) ; only to debug problems ;;(setq smtpmail-auth-credentials ; or use ~/.authinfo ;; '(("YOUR SMTP HOST" 25 "username" "password"))) ;;(setq smtpmail-starttls-credentials ;; '(("YOUR SMTP HOST" 25 "~/.my_smtp_tls.key" "~/.my_smtp_tls.cert"))) ;; Where the 25 equals the value of `smtpmail-smtp-service', it can be an ;; integer or a string, just as long as they match (eq). ;; To queue mail, set smtpmail-queue-mail to t and use ;; smtpmail-send-queued-mail to send. ;; Modified by Stephen Cranefield <scranefield@infoscience.otago.ac.nz>, ;; 22/6/99, to support SMTP Authentication by the AUTH=LOGIN mechanism. ;; See http://help.netscape.com/products/server/messaging/3x/info/smtpauth.html ;; Rewritten by Simon Josefsson to use same credential variable as AUTH ;; support below. ;; Modified by Simon Josefsson <jas@pdc.kth.se>, 22/2/99, to support SMTP ;; Authentication by the AUTH mechanism. ;; See http://www.ietf.org/rfc/rfc2554.txt ;; Modified by Simon Josefsson <simon@josefsson.org>, 2000-10-07, to support ;; STARTTLS. Requires external program ;; ftp://ftp.opaopa.org/pub/elisp/starttls-*.tar.gz. ;; See http://www.ietf.org/rfc/rfc2246.txt, http://www.ietf.org/rfc/rfc2487.txt ;;; Code: (require 'sendmail) (autoload 'starttls-open-stream "starttls") (autoload 'starttls-negotiate "starttls") (autoload 'mail-strip-quoted-names "mail-utils") (autoload 'message-make-date "message") (autoload 'message-make-message-id "message") (autoload 'rfc2104-hash "rfc2104") (autoload 'netrc-parse "netrc") (autoload 'netrc-machine "netrc") (autoload 'netrc-get "netrc") ;;; (defgroup smtpmail nil "SMTP protocol for sending mail." :group 'mail) (defcustom smtpmail-default-smtp-server nil "*Specify default SMTP server. This only has effect if you specify it before loading the smtpmail library." :type '(choice (const nil) string) :group 'smtpmail) (defcustom smtpmail-smtp-server (or (getenv "SMTPSERVER") smtpmail-default-smtp-server) "*The name of the host running SMTP server." :type '(choice (const nil) string) :group 'smtpmail) (defcustom smtpmail-smtp-service 25 "*SMTP service port number. The default value would be \"smtp\" or 25." :type '(choice (integer :tag "Port") (string :tag "Service")) :group 'smtpmail) (defcustom smtpmail-local-domain nil "*Local domain name without a host name. If the function `system-name' returns the full internet address, don't define this value." :type '(choice (const nil) string) :group 'smtpmail) (defcustom smtpmail-sendto-domain nil "*Local domain name without a host name. This is appended (with an @-sign) to any specified recipients which do not include an @-sign, so that each RCPT TO address is fully qualified. \(Some configurations of sendmail require this.) Don't bother to set this unless you have get an error like: Sending failed; SMTP protocol error when sending mail, and the *trace of SMTP session to <somewhere>* buffer includes an exchange like: RCPT TO: <someone> 501 <someone>: recipient address must contain a domain " :type '(choice (const nil) string) :group 'smtpmail) (defcustom smtpmail-debug-info nil "Whether to print info in buffer *trace of SMTP session to <somewhere>*. See also `smtpmail-debug-verb' which determines if the SMTP protocol should be verbose as well." :type 'boolean :group 'smtpmail) (defcustom smtpmail-debug-verb nil "Whether this library sends the SMTP VERB command or not. The commands enables verbose information from the SMTP server." :type 'boolean :group 'smtpmail) (defcustom smtpmail-code-conv-from nil ;; *junet* "*smtpmail code convert from this code to *internal*..for tiny-mime.." :type 'boolean :group 'smtpmail) (defcustom smtpmail-queue-mail nil "*If set, mail is queued; otherwise it is sent immediately. If queued, it is stored in the directory `smtpmail-queue-dir' and sent with `smtpmail-send-queued-mail'." :type 'boolean :group 'smtpmail) (defcustom smtpmail-queue-dir "~/Mail/queued-mail/" "*Directory where `smtpmail.el' stores queued mail." :type 'directory :group 'smtpmail) (defcustom smtpmail-auth-credentials "~/.authinfo" "Specify username and password for servers, directly or via .netrc file. This variable can either be a filename pointing to a file in netrc(5) format, or list of four-element lists that contain, in order, `servername' (a string), `port' (an integer), `user' (a string) and `password' (a string, or nil to query the user when needed). If you need to enter a `realm' too, add it to the user string, so that it looks like `user@realm'." :type '(choice file (repeat (list (string :tag "Server") (integer :tag "Port") (string :tag "Username") (choice (const :tag "Query when needed" nil) (string :tag "Password"))))) :version "22.1" :group 'smtpmail) (defcustom smtpmail-starttls-credentials '(("" 25 "" "")) "Specify STARTTLS keys and certificates for servers. This is a list of four-element list with `servername' (a string), `port' (an integer), `key' (a filename) and `certificate' (a filename). If you do not have a certificate/key pair, leave the `key' and `certificate' fields as `nil'. A key/certificate pair is only needed if you want to use X.509 client authenticated connections." :type '(repeat (list (string :tag "Server") (integer :tag "Port") (file :tag "Key") (file :tag "Certificate"))) :version "21.1" :group 'smtpmail) (defcustom smtpmail-warn-about-unknown-extensions nil "*If set, print warnings about unknown SMTP extensions. This is mainly useful for development purposes, to learn about new SMTP extensions that might be useful to support." :type 'boolean :version "21.1" :group 'smtpmail) (defvar smtpmail-queue-index-file "index" "File name of queued mail index. This is relative to `smtpmail-queue-dir'.") (defvar smtpmail-address-buffer) (defvar smtpmail-recipient-address-list) (defvar smtpmail-queue-counter 0) ;; Buffer-local variable. (defvar smtpmail-read-point) (defvar smtpmail-queue-index (concat smtpmail-queue-dir smtpmail-queue-index-file)) (defconst smtpmail-auth-supported '(cram-md5 plain login) "List of supported SMTP AUTH mechanisms.") ;;; ;;; ;;; (defvar smtpmail-mail-address nil "Value to use for envelope-from address for mail from ambient buffer.") ;;;###autoload (defun smtpmail-send-it () (let ((errbuf (if mail-interactive (generate-new-buffer " smtpmail errors") 0)) (tembuf (generate-new-buffer " smtpmail temp")) (case-fold-search nil) delimline (mailbuf (current-buffer)) ;; Examine this variable now, so that ;; local binding in the mail buffer will take effect. (smtpmail-mail-address (or (and mail-specify-envelope-from (mail-envelope-from)) user-mail-address)) (smtpmail-code-conv-from (if enable-multibyte-characters (let ((sendmail-coding-system smtpmail-code-conv-from)) (select-message-coding-system))))) (unwind-protect (save-excursion (set-buffer tembuf) (erase-buffer) ;; Use the same buffer-file-coding-system as in the mail ;; buffer, otherwise any write-region invocations (e.g., in ;; mail-do-fcc below) will annoy with asking for a suitable ;; encoding. (set-buffer-file-coding-system smtpmail-code-conv-from nil t) (insert-buffer-substring mailbuf) (goto-char (point-max)) ;; require one newline at the end. (or (= (preceding-char) ?\n) (insert ?\n)) ;; Change header-delimiter to be what sendmail expects. (mail-sendmail-undelimit-header) (setq delimline (point-marker)) ;; (sendmail-synch-aliases) (if mail-aliases (expand-mail-aliases (point-min) delimline)) (goto-char (point-min)) ;; ignore any blank lines in the header (while (and (re-search-forward "\n\n\n*" delimline t) (< (point) delimline)) (replace-match "\n")) (let ((case-fold-search t)) ;; We used to process Resent-... headers here, ;; but it was not done properly, and the job ;; is done correctly in smtpmail-deduce-address-list. ;; Don't send out a blank subject line (goto-char (point-min)) (if (re-search-forward "^Subject:\\([ \t]*\n\\)+\\b" delimline t) (replace-match "") ;; This one matches a Subject just before the header delimiter. (if (and (re-search-forward "^Subject:\\([ \t]*\n\\)+" delimline t) (= (match-end 0) delimline)) (replace-match ""))) ;; Put the "From:" field in unless for some odd reason ;; they put one in themselves. (goto-char (point-min)) (if (not (re-search-forward "^From:" delimline t)) (let* ((login smtpmail-mail-address) (fullname (user-full-name))) (cond ((eq mail-from-style 'angles) (insert "From: " fullname) (let ((fullname-start (+ (point-min) 6)) (fullname-end (point-marker))) (goto-char fullname-start) ;; Look for a character that cannot appear unquoted ;; according to RFC 822. (if (re-search-forward "[^- !#-'*+/-9=?A-Z^-~]" fullname-end 1) (progn ;; Quote fullname, escaping specials. (goto-char fullname-start) (insert "\"") (while (re-search-forward "[\"\\]" fullname-end 1) (replace-match "\\\\\\&" t)) (insert "\"")))) (insert " <" login ">\n")) ((eq mail-from-style 'parens) (insert "From: " login " (") (let ((fullname-start (point))) (insert fullname) (let ((fullname-end (point-marker))) (goto-char fullname-start) ;; RFC 822 says \ and nonmatching parentheses ;; must be escaped in comments. ;; Escape every instance of ()\ ... (while (re-search-forward "[()\\]" fullname-end 1) (replace-match "\\\\\\&" t)) ;; ... then undo escaping of matching parentheses, ;; including matching nested parentheses. (goto-char fullname-start) (while (re-search-forward "\\(\\=\\|[^\\]\\(\\\\\\\\\\)*\\)\\\\(\\(\\([^\\]\\|\\\\\\\\\\)*\\)\\\\)" fullname-end 1) (replace-match "\\1(\\3)" t) (goto-char fullname-start)))) (insert ")\n")) ((null mail-from-style) (insert "From: " login "\n"))))) ;; Insert a `Message-Id:' field if there isn't one yet. (goto-char (point-min)) (unless (re-search-forward "^Message-Id:" delimline t) (insert "Message-Id: " (message-make-message-id) "\n")) ;; Insert a `Date:' field if there isn't one yet. (goto-char (point-min)) (unless (re-search-forward "^Date:" delimline t) (insert "Date: " (message-make-date) "\n")) ;; Possibly add a MIME header for the current coding system (let (charset) (goto-char (point-min)) (and (eq mail-send-nonascii 'mime) (not (re-search-forward "^MIME-version:" delimline t)) (progn (skip-chars-forward "\0-\177") (/= (point) (point-max))) smtpmail-code-conv-from (setq charset (coding-system-get smtpmail-code-conv-from 'mime-charset)) (goto-char delimline) (insert "MIME-version: 1.0\n" "Content-type: text/plain; charset=" (symbol-name charset) "\nContent-Transfer-Encoding: 8bit\n"))) ;; Insert an extra newline if we need it to work around ;; Sun's bug that swallows newlines. (goto-char (1+ delimline)) (if (eval mail-mailer-swallows-blank-line) (newline)) ;; Find and handle any FCC fields. (goto-char (point-min)) (if (re-search-forward "^FCC:" delimline t) ;; Force mail-do-fcc to use the encoding of the mail ;; buffer to encode outgoing messages on FCC files. (let ((coding-system-for-write smtpmail-code-conv-from)) (mail-do-fcc delimline))) (if mail-interactive (with-current-buffer errbuf (erase-buffer)))) ;; ;; ;; (setq smtpmail-address-buffer (generate-new-buffer "*smtp-mail*")) (setq smtpmail-recipient-address-list (smtpmail-deduce-address-list tembuf (point-min) delimline)) (kill-buffer smtpmail-address-buffer) (smtpmail-do-bcc delimline) ; Send or queue (if (not smtpmail-queue-mail) (if (not (null smtpmail-recipient-address-list)) (if (not (smtpmail-via-smtp smtpmail-recipient-address-list tembuf)) (error "Sending failed; SMTP protocol error")) (error "Sending failed; no recipients")) (let* ((file-data (expand-file-name (format "%s_%i" (format-time-string "%Y-%m-%d_%H:%M:%S") (setq smtpmail-queue-counter (1+ smtpmail-queue-counter))) smtpmail-queue-dir)) (file-data (convert-standard-filename file-data)) (file-elisp (concat file-data ".el")) (buffer-data (create-file-buffer file-data)) (buffer-elisp (create-file-buffer file-elisp)) (buffer-scratch "*queue-mail*")) (unless (file-exists-p smtpmail-queue-dir) (make-directory smtpmail-queue-dir t)) (with-current-buffer buffer-data (erase-buffer) (set-buffer-file-coding-system smtpmail-code-conv-from nil t) (insert-buffer-substring tembuf) (write-file file-data) (set-buffer buffer-elisp) (erase-buffer) (insert (concat "(setq smtpmail-recipient-address-list '" (prin1-to-string smtpmail-recipient-address-list) ")\n")) (write-file file-elisp) (set-buffer (generate-new-buffer buffer-scratch)) (insert (concat file-data "\n")) (append-to-file (point-min) (point-max) smtpmail-queue-index) ) (kill-buffer buffer-scratch) (kill-buffer buffer-data) (kill-buffer buffer-elisp)))) (kill-buffer tembuf) (if (bufferp errbuf) (kill-buffer errbuf))))) ;;;###autoload (defun smtpmail-send-queued-mail () "Send mail that was queued as a result of setting `smtpmail-queue-mail'." (interactive) (with-temp-buffer ;;; Get index, get first mail, send it, update index, get second ;;; mail, send it, etc... (let ((file-msg "")) (insert-file-contents smtpmail-queue-index) (goto-char (point-min)) (while (not (eobp)) (setq file-msg (buffer-substring (point) (line-end-position))) (load file-msg) ;; Insert the message literally: it is already encoded as per ;; the MIME headers, and code conversions might guess the ;; encoding wrongly. (with-temp-buffer (let ((coding-system-for-read 'no-conversion)) (insert-file-contents file-msg)) (let ((smtpmail-mail-address (or (and mail-specify-envelope-from (mail-envelope-from)) user-mail-address))) (if (not (null smtpmail-recipient-address-list)) (if (not (smtpmail-via-smtp smtpmail-recipient-address-list (current-buffer))) (error "Sending failed; SMTP protocol error")) (error "Sending failed; no recipients")))) (delete-file file-msg) (delete-file (concat file-msg ".el")) (delete-region (point-at-bol) (point-at-bol 2))) (write-region (point-min) (point-max) smtpmail-queue-index)))) ;(defun smtpmail-via-smtp (host,port,sender,destination,smtpmail-text-buffer) (defun smtpmail-fqdn () (if smtpmail-local-domain (concat (system-name) "." smtpmail-local-domain) (system-name))) (defsubst smtpmail-cred-server (cred) (nth 0 cred)) (defsubst smtpmail-cred-port (cred) (nth 1 cred)) (defsubst smtpmail-cred-key (cred) (nth 2 cred)) (defsubst smtpmail-cred-user (cred) (nth 2 cred)) (defsubst smtpmail-cred-cert (cred) (nth 3 cred)) (defsubst smtpmail-cred-passwd (cred) (nth 3 cred)) (defun smtpmail-find-credentials (cred server port) (catch 'done (let ((l cred) el) (while (setq el (pop l)) (when (and (equal server (smtpmail-cred-server el)) (equal port (smtpmail-cred-port el))) (throw 'done el)))))) (defun smtpmail-maybe-append-domain (recipient) (if (or (not smtpmail-sendto-domain) (string-match "@" recipient)) recipient (concat recipient "@" smtpmail-sendto-domain))) (defun smtpmail-intersection (list1 list2) (let ((result nil)) (dolist (el2 list2) (when (memq el2 list1) (push el2 result))) (nreverse result))) (defvar starttls-extra-args) (defvar starttls-extra-arguments) (defun smtpmail-open-stream (process-buffer host port) (let ((cred (smtpmail-find-credentials smtpmail-starttls-credentials host port))) (if (null (and cred (condition-case () (with-no-warnings (require 'starttls) (call-process (if starttls-use-gnutls starttls-gnutls-program starttls-program))) (error nil)))) ;; The normal case. (open-network-stream "SMTP" process-buffer host port) (let* ((cred-key (smtpmail-cred-key cred)) (cred-cert (smtpmail-cred-cert cred)) (starttls-extra-args (append starttls-extra-args (when (and (stringp cred-key) (stringp cred-cert) (file-regular-p (setq cred-key (expand-file-name cred-key))) (file-regular-p (setq cred-cert (expand-file-name cred-cert)))) (list "--key-file" cred-key "--cert-file" cred-cert)))) (starttls-extra-arguments (append starttls-extra-arguments (when (and (stringp cred-key) (stringp cred-cert) (file-regular-p (setq cred-key (expand-file-name cred-key))) (file-regular-p (setq cred-cert (expand-file-name cred-cert)))) (list "--x509keyfile" cred-key "--x509certfile" cred-cert))))) (starttls-open-stream "SMTP" process-buffer host port))))) (defun smtpmail-try-auth-methods (process supported-extensions host port) (let* ((mechs (cdr-safe (assoc 'auth supported-extensions))) (mech (car (smtpmail-intersection smtpmail-auth-supported mechs))) (cred (if (stringp smtpmail-auth-credentials) (let* ((netrc (netrc-parse smtpmail-auth-credentials)) (port-name (format "%s" (or port "smtp"))) (hostentry (netrc-machine netrc host port-name port-name))) (when hostentry (list host port (netrc-get hostentry "login") (netrc-get hostentry "password")))) (smtpmail-find-credentials smtpmail-auth-credentials host port))) (passwd (when cred (or (smtpmail-cred-passwd cred) (read-passwd (format "SMTP password for %s:%s: " (smtpmail-cred-server cred) (smtpmail-cred-port cred)))))) ret) (when (and cred mech) (cond ((eq mech 'cram-md5) (smtpmail-send-command process (upcase (format "AUTH %s" mech))) (if (or (null (car (setq ret (smtpmail-read-response process)))) (not (integerp (car ret))) (>= (car ret) 400)) (throw 'done nil)) (when (eq (car ret) 334) (let* ((challenge (substring (cadr ret) 4)) (decoded (base64-decode-string challenge)) (hash (rfc2104-hash 'md5 64 16 passwd decoded)) (response (concat (smtpmail-cred-user cred) " " hash)) ;; Osamu Yamane <yamane@green.ocn.ne.jp>: ;; SMTP auth fails because the SMTP server identifies ;; only the first part of the string (delimited by ;; new line characters) as a response from the ;; client, and the rest as distinct commands. ;; In my case, the response string is 80 characters ;; long. Without the no-line-break option for ;; base64-encode-sting, only the first 76 characters ;; are taken as a response to the server, and the ;; authentication fails. (encoded (base64-encode-string response t))) (smtpmail-send-command process (format "%s" encoded)) (if (or (null (car (setq ret (smtpmail-read-response process)))) (not (integerp (car ret))) (>= (car ret) 400)) (throw 'done nil))))) ((eq mech 'login) (smtpmail-send-command process "AUTH LOGIN") (if (or (null (car (setq ret (smtpmail-read-response process)))) (not (integerp (car ret))) (>= (car ret) 400)) (throw 'done nil)) (smtpmail-send-command process (base64-encode-string (smtpmail-cred-user cred) t)) (if (or (null (car (setq ret (smtpmail-read-response process)))) (not (integerp (car ret))) (>= (car ret) 400)) (throw 'done nil)) (smtpmail-send-command process (base64-encode-string passwd t)) (if (or (null (car (setq ret (smtpmail-read-response process)))) (not (integerp (car ret))) (>= (car ret) 400)) (throw 'done nil))) ((eq mech 'plain) ;; We used to send an empty initial request, and wait for an ;; empty response, and then send the password, but this ;; violate a SHOULD in RFC 2222 paragraph 5.1. Note that this ;; is not sent if the server did not advertise AUTH PLAIN in ;; the EHLO response. See RFC 2554 for more info. (smtpmail-send-command process (concat "AUTH PLAIN " (base64-encode-string (concat "\0" (smtpmail-cred-user cred) "\0" passwd) t))) (if (or (null (car (setq ret (smtpmail-read-response process)))) (not (integerp (car ret))) (not (equal (car ret) 235))) (throw 'done nil))) (t (error "Mechanism %s not implemented" mech))) ;; Remember the password. (when (and (not (stringp smtpmail-auth-credentials)) (null (smtpmail-cred-passwd cred))) (setcar (cdr (cdr (cdr cred))) passwd))))) (defun smtpmail-via-smtp (recipient smtpmail-text-buffer) (let ((process nil) (host (or smtpmail-smtp-server (error "`smtpmail-smtp-server' not defined"))) (port smtpmail-smtp-service) ;; smtpmail-mail-address should be set to the appropriate ;; buffer-local value by the caller, but in case not: (envelope-from (or smtpmail-mail-address (and mail-specify-envelope-from (mail-envelope-from)) user-mail-address)) response-code greeting process-buffer (supported-extensions '())) (unwind-protect (catch 'done ;; get or create the trace buffer (setq process-buffer (get-buffer-create (format "*trace of SMTP session to %s*" host))) ;; clear the trace buffer of old output (with-current-buffer process-buffer (setq buffer-undo-list t) (erase-buffer)) ;; open the connection to the server (setq process (smtpmail-open-stream process-buffer host port)) (and (null process) (throw 'done nil)) ;; set the send-filter (set-process-filter process 'smtpmail-process-filter) (with-current-buffer process-buffer (set-buffer-process-coding-system 'raw-text-unix 'raw-text-unix) (make-local-variable 'smtpmail-read-point) (setq smtpmail-read-point (point-min)) (if (or (null (car (setq greeting (smtpmail-read-response process)))) (not (integerp (car greeting))) (>= (car greeting) 400)) (throw 'done nil) ) (let ((do-ehlo t) (do-starttls t)) (while do-ehlo ;; EHLO (smtpmail-send-command process (format "EHLO %s" (smtpmail-fqdn))) (if (or (null (car (setq response-code (smtpmail-read-response process)))) (not (integerp (car response-code))) (>= (car response-code) 400)) (progn ;; HELO (smtpmail-send-command process (format "HELO %s" (smtpmail-fqdn))) (if (or (null (car (setq response-code (smtpmail-read-response process)))) (not (integerp (car response-code))) (>= (car response-code) 400)) (throw 'done nil))) (dolist (line (cdr (cdr response-code))) (let ((name (with-case-table ascii-case-table (mapcar (lambda (s) (intern (downcase s))) (split-string (substring line 4) "[ ]"))))) (and (eq (length name) 1) (setq name (car name))) (and name (cond ((memq (if (consp name) (car name) name) '(verb xvrb 8bitmime onex xone expn size dsn etrn enhancedstatuscodes help xusr auth=login auth starttls)) (setq supported-extensions (cons name supported-extensions))) (smtpmail-warn-about-unknown-extensions (message "Unknown extension %s" name))))))) (if (and do-starttls (smtpmail-find-credentials smtpmail-starttls-credentials host port) (member 'starttls supported-extensions) (numberp (process-id process))) (progn (smtpmail-send-command process (format "STARTTLS")) (if (or (null (car (setq response-code (smtpmail-read-response process)))) (not (integerp (car response-code))) (>= (car response-code) 400)) (throw 'done nil)) (starttls-negotiate process) (setq do-starttls nil)) (setq do-ehlo nil)))) (smtpmail-try-auth-methods process supported-extensions host port) (if (or (member 'onex supported-extensions) (member 'xone supported-extensions)) (progn (smtpmail-send-command process (format "ONEX")) (if (or (null (car (setq response-code (smtpmail-read-response process)))) (not (integerp (car response-code))) (>= (car response-code) 400)) (throw 'done nil)))) (if (and smtpmail-debug-verb (or (member 'verb supported-extensions) (member 'xvrb supported-extensions))) (progn (smtpmail-send-command process (format "VERB")) (if (or (null (car (setq response-code (smtpmail-read-response process)))) (not (integerp (car response-code))) (>= (car response-code) 400)) (throw 'done nil)))) (if (member 'xusr supported-extensions) (progn (smtpmail-send-command process (format "XUSR")) (if (or (null (car (setq response-code (smtpmail-read-response process)))) (not (integerp (car response-code))) (>= (car response-code) 400)) (throw 'done nil)))) ;; MAIL FROM:<sender> (let ((size-part (if (or (member 'size supported-extensions) (assoc 'size supported-extensions)) (format " SIZE=%d" (with-current-buffer smtpmail-text-buffer ;; size estimate: (+ (- (point-max) (point-min)) ;; Add one byte for each change-of-line ;; because of CR-LF representation: (count-lines (point-min) (point-max))))) "")) (body-part (if (member '8bitmime supported-extensions) ;; FIXME: ;; Code should be added here that transforms ;; the contents of the message buffer into ;; something the receiving SMTP can handle. ;; For a receiver that supports 8BITMIME, this ;; may mean converting BINARY to BASE64, or ;; adding Content-Transfer-Encoding and the ;; other MIME headers. The code should also ;; return an indication of what encoding the ;; message buffer is now, i.e. ASCII or ;; 8BITMIME. (if nil " BODY=8BITMIME" "") ""))) ; (smtpmail-send-command process (format "MAIL FROM:%s@%s" (user-login-name) (smtpmail-fqdn))) (smtpmail-send-command process (format "MAIL FROM:<%s>%s%s" envelope-from size-part body-part)) (if (or (null (car (setq response-code (smtpmail-read-response process)))) (not (integerp (car response-code))) (>= (car response-code) 400)) (throw 'done nil) )) ;; RCPT TO:<recipient> (let ((n 0)) (while (not (null (nth n recipient))) (smtpmail-send-command process (format "RCPT TO:<%s>" (smtpmail-maybe-append-domain (nth n recipient)))) (setq n (1+ n)) (setq response-code (smtpmail-read-response process)) (if (or (null (car response-code)) (not (integerp (car response-code))) (>= (car response-code) 400)) (throw 'done nil) ) )) ;; DATA (smtpmail-send-command process "DATA") (if (or (null (car (setq response-code (smtpmail-read-response process)))) (not (integerp (car response-code))) (>= (car response-code) 400)) (throw 'done nil) ) ;; Mail contents (smtpmail-send-data process smtpmail-text-buffer) ;;DATA end "." (smtpmail-send-command process ".") (if (or (null (car (setq response-code (smtpmail-read-response process)))) (not (integerp (car response-code))) (>= (car response-code) 400)) (throw 'done nil) ) ;;QUIT ; (smtpmail-send-command process "QUIT") ; (and (null (car (smtpmail-read-response process))) ; (throw 'done nil)) t )) (if process (with-current-buffer (process-buffer process) (smtpmail-send-command process "QUIT") (smtpmail-read-response process) ; (if (or (null (car (setq response-code (smtpmail-read-response process)))) ; (not (integerp (car response-code))) ; (>= (car response-code) 400)) ; (throw 'done nil) ; ) (delete-process process) (unless smtpmail-debug-info (kill-buffer process-buffer))))))) (defun smtpmail-process-filter (process output) (with-current-buffer (process-buffer process) (goto-char (point-max)) (insert output))) (defun smtpmail-read-response (process) (let ((case-fold-search nil) (response-strings nil) (response-continue t) (return-value '(nil ())) match-end) (catch 'done (while response-continue (goto-char smtpmail-read-point) (while (not (search-forward "\r\n" nil t)) (unless (memq (process-status process) '(open run)) (throw 'done nil)) (accept-process-output process) (goto-char smtpmail-read-point)) (setq match-end (point)) (setq response-strings (cons (buffer-substring smtpmail-read-point (- match-end 2)) response-strings)) (goto-char smtpmail-read-point) (if (looking-at "[0-9]+ ") (let ((begin (match-beginning 0)) (end (match-end 0))) (if smtpmail-debug-info (message "%s" (car response-strings))) (setq smtpmail-read-point match-end) ;; ignore lines that start with "0" (if (looking-at "0[0-9]+ ") nil (setq response-continue nil) (setq return-value (cons (string-to-number (buffer-substring begin end)) (nreverse response-strings))))) (if (looking-at "[0-9]+-") (progn (if smtpmail-debug-info (message "%s" (car response-strings))) (setq smtpmail-read-point match-end) (setq response-continue t)) (progn (setq smtpmail-read-point match-end) (setq response-continue nil) (setq return-value (cons nil (nreverse response-strings))))))) (setq smtpmail-read-point match-end)) return-value)) (defun smtpmail-send-command (process command) (goto-char (point-max)) (if (= (aref command 0) ?P) (insert "PASS <omitted>\r\n") (insert command "\r\n")) (setq smtpmail-read-point (point)) (process-send-string process command) (process-send-string process "\r\n")) (defun smtpmail-send-data-1 (process data) (goto-char (point-max)) (if (and (multibyte-string-p data) smtpmail-code-conv-from) (setq data (string-as-multibyte (encode-coding-string data smtpmail-code-conv-from)))) (if smtpmail-debug-info (insert data "\r\n")) (setq smtpmail-read-point (point)) ;; Escape "." at start of a line (if (eq (string-to-char data) ?.) (process-send-string process ".")) (process-send-string process data) (process-send-string process "\r\n") ) (defun smtpmail-send-data (process buffer) (let ((data-continue t) sending-data) (with-current-buffer buffer (goto-char (point-min))) (while data-continue (with-current-buffer buffer (setq sending-data (buffer-substring (point-at-bol) (point-at-eol))) (end-of-line 2) (setq data-continue (not (eobp)))) (smtpmail-send-data-1 process sending-data)))) (defun smtpmail-deduce-address-list (smtpmail-text-buffer header-start header-end) "Get address list suitable for smtp RCPT TO: <address>." (unwind-protect (with-current-buffer smtpmail-address-buffer (erase-buffer) (let ((case-fold-search t) (simple-address-list "") this-line this-line-end addr-regexp) (insert-buffer-substring smtpmail-text-buffer header-start header-end) (goto-char (point-min)) ;; RESENT-* fields should stop processing of regular fields. (save-excursion (setq addr-regexp (if (re-search-forward "^Resent-\\(to\\|cc\\|bcc\\):" header-end t) "^Resent-\\(to\\|cc\\|bcc\\):" "^\\(To:\\|Cc:\\|Bcc:\\)"))) (while (re-search-forward addr-regexp header-end t) (replace-match "") (setq this-line (match-beginning 0)) (forward-line 1) ;; get any continuation lines (while (and (looking-at "^[ \t]+") (< (point) header-end)) (forward-line 1)) (setq this-line-end (point-marker)) (setq simple-address-list (concat simple-address-list " " (mail-strip-quoted-names (buffer-substring this-line this-line-end)))) ) (erase-buffer) (insert " " simple-address-list "\n") (subst-char-in-region (point-min) (point-max) 10 ? t);; newline --> blank (subst-char-in-region (point-min) (point-max) ?, ? t);; comma --> blank (subst-char-in-region (point-min) (point-max) 9 ? t);; tab --> blank (goto-char (point-min)) ;; tidyness in case hook is not robust when it looks at this (while (re-search-forward "[ \t]+" header-end t) (replace-match " ")) (goto-char (point-min)) (let (recipient-address-list) (while (re-search-forward " \\([^ ]+\\) " (point-max) t) (backward-char 1) (setq recipient-address-list (cons (buffer-substring (match-beginning 1) (match-end 1)) recipient-address-list)) ) (setq smtpmail-recipient-address-list recipient-address-list)) ) ) ) ) (defun smtpmail-do-bcc (header-end) "Delete [Resent-]BCC: and their continuation lines from the header area. There may be multiple BCC: lines, and each may have arbitrarily many continuation lines." (let ((case-fold-search t)) (save-excursion (goto-char (point-min)) ;; iterate over all BCC: lines (while (re-search-forward "^\\(RESENT-\\)?BCC:" header-end t) (delete-region (match-beginning 0) (progn (forward-line 1) (point))) ;; get rid of any continuation lines (while (and (looking-at "^[ \t].*\n") (< (point) header-end)) (replace-match "")))))) (provide 'smtpmail) ;;; arch-tag: a76992df-6d71-43b7-9e72-4bacc6c05466 ;;; smtpmail.el ends here
author Bastien Guerry <bzg@altern.org>
date Wed, 13 Feb 2008 20:58:26 +0000
parents 107ccd98fa12
children 606f2d163a64 1e3a407766b9
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
38414
67b464da13ec Some fixes to follow coding conventions.
Pavel Janík <Pavel@Janik.cz>
parents: 37664
diff changeset
1 ;;; esh-util.el --- general utilities
29870
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
2
64701
34bd8e434dd7 Update years in copyright notice; nfc.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents: 64085
diff changeset
3 ;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004,
79707
48c4bb2b7d11 Add 2008 to copyright years.
Glenn Morris <rgm@gnu.org>
parents: 78220
diff changeset
4 ;; 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
29870
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
5
32526
8e57189d61b4 Add author information.
Gerd Moellmann <gerd@gnu.org>
parents: 32470
diff changeset
6 ;; Author: John Wiegley <johnw@gnu.org>
8e57189d61b4 Add author information.
Gerd Moellmann <gerd@gnu.org>
parents: 32470
diff changeset
7
29870
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
8 ;; This file is part of GNU Emacs.
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
9
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
10 ;; GNU Emacs is free software; you can redistribute it and/or modify
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
11 ;; it under the terms of the GNU General Public License as published by
78220
a1e8300d3c55 Switch license to GPLv3 or later.
Glenn Morris <rgm@gnu.org>
parents: 75346
diff changeset
12 ;; the Free Software Foundation; either version 3, or (at your option)
29870
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
13 ;; any later version.
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
14
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
15 ;; GNU Emacs is distributed in the hope that it will be useful,
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
18 ;; GNU General Public License for more details.
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
19
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
20 ;; You should have received a copy of the GNU General Public License
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
21 ;; along with GNU Emacs; see the file COPYING. If not, write to the
64085
18a818a2ee7c Update FSF's address.
Lute Kamstra <lute@gnu.org>
parents: 62915
diff changeset
22 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18a818a2ee7c Update FSF's address.
Lute Kamstra <lute@gnu.org>
parents: 62915
diff changeset
23 ;; Boston, MA 02110-1301, USA.
29870
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
24
87082
7a4a3f1c72ee Require individual files if needed when compiling, rather than
Glenn Morris <rgm@gnu.org>
parents: 86533
diff changeset
25 ;;; Commentary:
29870
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
26
87082
7a4a3f1c72ee Require individual files if needed when compiling, rather than
Glenn Morris <rgm@gnu.org>
parents: 86533
diff changeset
27 ;;; Code:
29870
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
28
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
29 (defgroup eshell-util nil
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
30 "This is general utility code, meant for use by Eshell itself."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
31 :tag "General utilities"
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
32 :group 'eshell)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
33
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
34 ;;; User Variables:
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
35
33020
e21feeab77fb See ChangeLog
John Wiegley <johnw@newartisans.com>
parents: 32526
diff changeset
36 (defcustom eshell-stringify-t t
e21feeab77fb See ChangeLog
John Wiegley <johnw@newartisans.com>
parents: 32526
diff changeset
37 "*If non-nil, the string representation of t is 't'.
e21feeab77fb See ChangeLog
John Wiegley <johnw@newartisans.com>
parents: 32526
diff changeset
38 If nil, t will be represented only in the exit code of the function,
e21feeab77fb See ChangeLog
John Wiegley <johnw@newartisans.com>
parents: 32526
diff changeset
39 and not printed as a string. This causes Lisp functions to behave
e21feeab77fb See ChangeLog
John Wiegley <johnw@newartisans.com>
parents: 32526
diff changeset
40 similarly to external commands, as far as successful result output."
e21feeab77fb See ChangeLog
John Wiegley <johnw@newartisans.com>
parents: 32526
diff changeset
41 :type 'boolean
e21feeab77fb See ChangeLog
John Wiegley <johnw@newartisans.com>
parents: 32526
diff changeset
42 :group 'eshell-util)
e21feeab77fb See ChangeLog
John Wiegley <johnw@newartisans.com>
parents: 32526
diff changeset
43
29870
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
44 (defcustom eshell-group-file "/etc/group"
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
45 "*If non-nil, the name of the group file on your system."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
46 :type '(choice (const :tag "No group file" nil) file)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
47 :group 'eshell-util)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
48
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
49 (defcustom eshell-passwd-file "/etc/passwd"
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
50 "*If non-nil, the name of the passwd file on your system."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
51 :type '(choice (const :tag "No passwd file" nil) file)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
52 :group 'eshell-util)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
53
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
54 (defcustom eshell-hosts-file "/etc/hosts"
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
55 "*The name of the /etc/hosts file."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
56 :type '(choice (const :tag "No hosts file" nil) file)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
57 :group 'eshell-util)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
58
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
59 (defcustom eshell-handle-errors t
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
60 "*If non-nil, Eshell will handle errors itself.
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
61 Setting this to nil is offered as an aid to debugging only."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
62 :type 'boolean
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
63 :group 'eshell-util)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
64
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
65 (defcustom eshell-private-file-modes 384 ; umask 177
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
66 "*The file-modes value to use for creating \"private\" files."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
67 :type 'integer
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
68 :group 'eshell-util)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
69
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
70 (defcustom eshell-private-directory-modes 448 ; umask 077
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
71 "*The file-modes value to use for creating \"private\" directories."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
72 :type 'integer
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
73 :group 'eshell-util)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
74
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
75 (defcustom eshell-tar-regexp
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
76 "\\.t\\(ar\\(\\.\\(gz\\|bz2\\|Z\\)\\)?\\|gz\\|a[zZ]\\|z2\\)\\'"
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
77 "*Regular expression used to match tar file names."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
78 :type 'regexp
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
79 :group 'eshell-util)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
80
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
81 (defcustom eshell-convert-numeric-arguments t
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
82 "*If non-nil, converting arguments of numeric form to Lisp numbers.
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
83 Numeric form is tested using the regular expression
37664
74b3a3b5aa87 (eshell-convert-numeric-arguments): Annotated the documentation string
John Wiegley <johnw@newartisans.com>
parents: 37659
diff changeset
84 `eshell-number-regexp'.
74b3a3b5aa87 (eshell-convert-numeric-arguments): Annotated the documentation string
John Wiegley <johnw@newartisans.com>
parents: 37659
diff changeset
85
74b3a3b5aa87 (eshell-convert-numeric-arguments): Annotated the documentation string
John Wiegley <johnw@newartisans.com>
parents: 37659
diff changeset
86 NOTE: If you find that numeric conversions are intefering with the
74b3a3b5aa87 (eshell-convert-numeric-arguments): Annotated the documentation string
John Wiegley <johnw@newartisans.com>
parents: 37659
diff changeset
87 specification of filenames (for example, in calling `find-file', or
74b3a3b5aa87 (eshell-convert-numeric-arguments): Annotated the documentation string
John Wiegley <johnw@newartisans.com>
parents: 37659
diff changeset
88 some other Lisp function that deals with files, not numbers), add the
74b3a3b5aa87 (eshell-convert-numeric-arguments): Annotated the documentation string
John Wiegley <johnw@newartisans.com>
parents: 37659
diff changeset
89 following in your .emacs file:
74b3a3b5aa87 (eshell-convert-numeric-arguments): Annotated the documentation string
John Wiegley <johnw@newartisans.com>
parents: 37659
diff changeset
90
74b3a3b5aa87 (eshell-convert-numeric-arguments): Annotated the documentation string
John Wiegley <johnw@newartisans.com>
parents: 37659
diff changeset
91 (put 'find-file 'eshell-no-numeric-conversions t)
74b3a3b5aa87 (eshell-convert-numeric-arguments): Annotated the documentation string
John Wiegley <johnw@newartisans.com>
parents: 37659
diff changeset
92
74b3a3b5aa87 (eshell-convert-numeric-arguments): Annotated the documentation string
John Wiegley <johnw@newartisans.com>
parents: 37659
diff changeset
93 Any function with the property `eshell-no-numeric-conversions' set to
74b3a3b5aa87 (eshell-convert-numeric-arguments): Annotated the documentation string
John Wiegley <johnw@newartisans.com>
parents: 37659
diff changeset
94 a non-nil value, will be passed strings, not numbers, even when an
74b3a3b5aa87 (eshell-convert-numeric-arguments): Annotated the documentation string
John Wiegley <johnw@newartisans.com>
parents: 37659
diff changeset
95 argument matches `eshell-number-regexp'."
29870
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
96 :type 'boolean
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
97 :group 'eshell-util)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
98
37659
7dc0e015c205 (eshell-number-regexp): Now that number conversions only happen for
John Wiegley <johnw@newartisans.com>
parents: 35588
diff changeset
99 (defcustom eshell-number-regexp "-?\\([0-9]*\\.\\)?[0-9]+\\(e[-0-9.]+\\)?"
29870
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
100 "*Regular expression used to match numeric arguments.
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
101 If `eshell-convert-numeric-arguments' is non-nil, and an argument
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
102 matches this regexp, it will be converted to a Lisp number, using the
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
103 function `string-to-number'."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
104 :type 'regexp
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
105 :group 'eshell-util)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
106
32446
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
107 (defcustom eshell-ange-ls-uids nil
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
108 "*List of user/host/id strings, used to determine remote ownership."
35588
31904bdf4350 See ChangeLog
John Wiegley <johnw@newartisans.com>
parents: 35209
diff changeset
109 :type '(repeat (cons :tag "Host for User/UID map"
31904bdf4350 See ChangeLog
John Wiegley <johnw@newartisans.com>
parents: 35209
diff changeset
110 (string :tag "Hostname")
31904bdf4350 See ChangeLog
John Wiegley <johnw@newartisans.com>
parents: 35209
diff changeset
111 (repeat (cons :tag "User/UID List"
31904bdf4350 See ChangeLog
John Wiegley <johnw@newartisans.com>
parents: 35209
diff changeset
112 (string :tag "Username")
31904bdf4350 See ChangeLog
John Wiegley <johnw@newartisans.com>
parents: 35209
diff changeset
113 (repeat :tag "UIDs" string)))))
32446
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
114 :group 'eshell-util)
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
115
29870
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
116 ;;; Internal Variables:
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
117
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
118 (defvar eshell-group-names nil
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
119 "A cache to hold the names of groups.")
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
120
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
121 (defvar eshell-group-timestamp nil
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
122 "A timestamp of when the group file was read.")
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
123
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
124 (defvar eshell-user-names nil
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
125 "A cache to hold the names of users.")
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
126
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
127 (defvar eshell-user-timestamp nil
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
128 "A timestamp of when the user file was read.")
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
129
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
130 (defvar eshell-host-names nil
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
131 "A cache the names of frequently accessed hosts.")
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
132
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
133 (defvar eshell-host-timestamp nil
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
134 "A timestamp of when the hosts file was read.")
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
135
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
136 ;;; Functions:
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
137
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
138 (defsubst eshell-under-windows-p ()
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
139 "Return non-nil if we are running under MS-DOS/Windows."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
140 (memq system-type '(ms-dos windows-nt)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
141
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
142 (defmacro eshell-condition-case (tag form &rest handlers)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
143 "Like `condition-case', but only if `eshell-pass-through-errors' is nil."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
144 (if eshell-handle-errors
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
145 `(condition-case ,tag
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
146 ,form
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
147 ,@handlers)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
148 form))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
149
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
150 (put 'eshell-condition-case 'lisp-indent-function 2)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
151
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
152 (defmacro eshell-deftest (module name label &rest forms)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
153 (if (and (fboundp 'cl-compiling-file) (cl-compiling-file))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
154 nil
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
155 (let ((fsym (intern (concat "eshell-test--" (symbol-name name)))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
156 `(eval-when-compile
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
157 (ignore
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
158 (defun ,fsym () ,label
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
159 (eshell-run-test (quote ,module) (quote ,fsym) ,label
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
160 (quote (progn ,@forms)))))))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
161
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
162 (put 'eshell-deftest 'lisp-indent-function 2)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
163
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
164 (defun eshell-find-delimiter
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
165 (open close &optional bound reverse-p backslash-p)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
166 "From point, find the CLOSE delimiter corresponding to OPEN.
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
167 The matching is bounded by BOUND.
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
168 If REVERSE-P is non-nil, process the region backwards.
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
169 If BACKSLASH-P is non-nil, and OPEN and CLOSE are the same character,
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
170 then quoting is done by a backslash, rather than a doubled delimiter."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
171 (save-excursion
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
172 (let ((depth 1)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
173 (bound (or bound (point-max))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
174 (if (if reverse-p
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
175 (eq (char-before) close)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
176 (eq (char-after) open))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
177 (forward-char (if reverse-p -1 1)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
178 (while (and (> depth 0)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
179 (funcall (if reverse-p '> '<) (point) bound))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
180 (let ((c (if reverse-p (char-before) (char-after))) nc)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
181 (cond ((and (not reverse-p)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
182 (or (not (eq open close))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
183 backslash-p)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
184 (eq c ?\\)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
185 (setq nc (char-after (1+ (point))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
186 (or (eq nc open) (eq nc close)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
187 (forward-char 1))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
188 ((and reverse-p
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
189 (or (not (eq open close))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
190 backslash-p)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
191 (or (eq c open) (eq c close))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
192 (eq (char-before (1- (point)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
193 ?\\))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
194 (forward-char -1))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
195 ((eq open close)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
196 (if (eq c open)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
197 (if (and (not backslash-p)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
198 (eq (if reverse-p
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
199 (char-before (1- (point)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
200 (char-after (1+ (point)))) open))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
201 (forward-char (if reverse-p -1 1))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
202 (setq depth (1- depth)))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
203 ((= c open)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
204 (setq depth (+ depth (if reverse-p -1 1))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
205 ((= c close)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
206 (setq depth (+ depth (if reverse-p 1 -1))))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
207 (forward-char (if reverse-p -1 1)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
208 (if (= depth 0)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
209 (if reverse-p (point) (1- (point)))))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
210
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
211 (defun eshell-convert (string)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
212 "Convert STRING into a more native looking Lisp object."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
213 (if (not (stringp string))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
214 string
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
215 (let ((len (length string)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
216 (if (= len 0)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
217 string
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
218 (if (eq (aref string (1- len)) ?\n)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
219 (setq string (substring string 0 (1- len))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
220 (if (string-match "\n" string)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
221 (split-string string "\n")
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
222 (if (and eshell-convert-numeric-arguments
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
223 (string-match
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
224 (concat "\\`\\s-*" eshell-number-regexp
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
225 "\\s-*\\'") string))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
226 (string-to-number string)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
227 string))))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
228
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
229 (defun eshell-sublist (l &optional n m)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
230 "Return from LIST the N to M elements.
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
231 If N or M is nil, it means the end of the list."
45736
fa968fe464d3 (eshell-copy-list): Function deleted.
Richard M. Stallman <rms@gnu.org>
parents: 38414
diff changeset
232 (let* ((a (copy-sequence l))
29870
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
233 result)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
234 (if (and m (consp (nthcdr m a)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
235 (setcdr (nthcdr m a) nil))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
236 (if n
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
237 (setq a (nthcdr n a))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
238 (setq n (1- (length a))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
239 a (last a)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
240 a))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
241
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
242 (defun eshell-split-path (path)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
243 "Split a path into multiple subparts."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
244 (let ((len (length path))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
245 (i 0) (li 0)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
246 parts)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
247 (if (and (eshell-under-windows-p)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
248 (> len 2)
62915
b89e30bcd2bb Changed all uses of `directory-sep-char' to ?/, and all uses of
John Wiegley <johnw@newartisans.com>
parents: 52401
diff changeset
249 (eq (aref path 0) ?/)
b89e30bcd2bb Changed all uses of `directory-sep-char' to ?/, and all uses of
John Wiegley <johnw@newartisans.com>
parents: 52401
diff changeset
250 (eq (aref path 1) ?/))
29870
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
251 (setq i 2))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
252 (while (< i len)
62915
b89e30bcd2bb Changed all uses of `directory-sep-char' to ?/, and all uses of
John Wiegley <johnw@newartisans.com>
parents: 52401
diff changeset
253 (if (and (eq (aref path i) ?/)
29870
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
254 (not (get-text-property i 'escaped path)))
62915
b89e30bcd2bb Changed all uses of `directory-sep-char' to ?/, and all uses of
John Wiegley <johnw@newartisans.com>
parents: 52401
diff changeset
255 (setq parts (cons (if (= li i) "/"
29870
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
256 (substring path li (1+ i))) parts)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
257 li (1+ i)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
258 (setq i (1+ i)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
259 (if (< li i)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
260 (setq parts (cons (substring path li i) parts)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
261 (if (and (eshell-under-windows-p)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
262 (string-match "\\`[A-Za-z]:\\'" (car (last parts))))
62915
b89e30bcd2bb Changed all uses of `directory-sep-char' to ?/, and all uses of
John Wiegley <johnw@newartisans.com>
parents: 52401
diff changeset
263 (setcar (last parts) (concat (car (last parts)) "/")))
29870
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
264 (nreverse parts)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
265
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
266 (defun eshell-to-flat-string (value)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
267 "Make value a string. If separated by newlines change them to spaces."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
268 (let ((text (eshell-stringify value)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
269 (if (string-match "\n+\\'" text)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
270 (setq text (replace-match "" t t text)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
271 (while (string-match "\n+" text)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
272 (setq text (replace-match " " t t text)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
273 text))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
274
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
275 (defmacro eshell-for (for-var for-list &rest forms)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
276 "Iterate through a list"
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
277 `(let ((list-iter ,for-list))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
278 (while list-iter
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
279 (let ((,for-var (car list-iter)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
280 ,@forms)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
281 (setq list-iter (cdr list-iter)))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
282
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
283 (put 'eshell-for 'lisp-indent-function 2)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
284
31241
3099993cba0f See ChangeLog
John Wiegley <johnw@newartisans.com>
parents: 31240
diff changeset
285 (defun eshell-flatten-list (args)
29870
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
286 "Flatten any lists within ARGS, so that there are no sublists."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
287 (let ((new-list (list t)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
288 (eshell-for a args
65168
b93526432c17 *** empty log message ***
John Wiegley <johnw@newartisans.com>
parents: 65164
diff changeset
289 (if (and (listp a)
29870
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
290 (listp (cdr a)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
291 (nconc new-list (eshell-flatten-list a))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
292 (nconc new-list (list a))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
293 (cdr new-list)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
294
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
295 (defun eshell-uniqify-list (l)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
296 "Remove occurring multiples in L. You probably want to sort first."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
297 (let ((m l))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
298 (while m
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
299 (while (and (cdr m)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
300 (string= (car m)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
301 (cadr m)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
302 (setcdr m (cddr m)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
303 (setq m (cdr m))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
304 l)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
305
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
306 (defun eshell-stringify (object)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
307 "Convert OBJECT into a string value."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
308 (cond
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
309 ((stringp object) object)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
310 ((and (listp object)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
311 (not (eq object nil)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
312 (let ((string (pp-to-string object)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
313 (substring string 0 (1- (length string)))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
314 ((numberp object)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
315 (number-to-string object))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
316 (t
33020
e21feeab77fb See ChangeLog
John Wiegley <johnw@newartisans.com>
parents: 32526
diff changeset
317 (unless (and (eq object t)
e21feeab77fb See ChangeLog
John Wiegley <johnw@newartisans.com>
parents: 32526
diff changeset
318 (not eshell-stringify-t))
e21feeab77fb See ChangeLog
John Wiegley <johnw@newartisans.com>
parents: 32526
diff changeset
319 (pp-to-string object)))))
29870
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
320
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
321 (defsubst eshell-stringify-list (args)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
322 "Convert each element of ARGS into a string value."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
323 (mapcar 'eshell-stringify args))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
324
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
325 (defsubst eshell-flatten-and-stringify (&rest args)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
326 "Flatten and stringify all of the ARGS into a single string."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
327 (mapconcat 'eshell-stringify (eshell-flatten-list args) " "))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
328
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
329 ;; the next two are from GNUS, and really should be made part of Emacs
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
330 ;; some day
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
331 (defsubst eshell-time-less-p (t1 t2)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
332 "Say whether time T1 is less than time T2."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
333 (or (< (car t1) (car t2))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
334 (and (= (car t1) (car t2))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
335 (< (nth 1 t1) (nth 1 t2)))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
336
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
337 (defsubst eshell-time-to-seconds (time)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
338 "Convert TIME to a floating point number."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
339 (+ (* (car time) 65536.0)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
340 (cadr time)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
341 (/ (or (car (cdr (cdr time))) 0) 1000000.0)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
342
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
343 (defsubst eshell-directory-files (regexp &optional directory)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
344 "Return a list of files in the given DIRECTORY matching REGEXP."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
345 (directory-files (or directory default-directory)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
346 directory regexp))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
347
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
348 (defun eshell-regexp-arg (prompt)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
349 "Return list of regexp and prefix arg using PROMPT."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
350 (let* (;; Don't clobber this.
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
351 (last-command last-command)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
352 (regexp (read-from-minibuffer prompt nil nil nil
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
353 'minibuffer-history-search-history)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
354 (list (if (string-equal regexp "")
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
355 (setcar minibuffer-history-search-history
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
356 (nth 1 minibuffer-history-search-history))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
357 regexp)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
358 (prefix-numeric-value current-prefix-arg))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
359
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
360 (defun eshell-printable-size (filesize &optional human-readable
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
361 block-size use-colors)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
362 "Return a printable FILESIZE."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
363 (let ((size (float (or filesize 0))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
364 (if human-readable
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
365 (if (< size human-readable)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
366 (if (= (round size) 0)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
367 "0"
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
368 (if block-size
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
369 "1.0k"
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
370 (format "%.0f" size)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
371 (setq size (/ size human-readable))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
372 (if (< size human-readable)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
373 (if (<= size 9.94)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
374 (format "%.1fk" size)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
375 (format "%.0fk" size))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
376 (setq size (/ size human-readable))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
377 (if (< size human-readable)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
378 (let ((str (if (<= size 9.94)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
379 (format "%.1fM" size)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
380 (format "%.0fM" size))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
381 (if use-colors
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
382 (put-text-property 0 (length str)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
383 'face 'bold str))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
384 str)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
385 (setq size (/ size human-readable))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
386 (if (< size human-readable)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
387 (let ((str (if (<= size 9.94)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
388 (format "%.1fG" size)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
389 (format "%.0fG" size))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
390 (if use-colors
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
391 (put-text-property 0 (length str)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
392 'face 'bold-italic str))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
393 str)))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
394 (if block-size
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
395 (setq size (/ size block-size)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
396 (format "%.0f" size))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
397
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
398 (defun eshell-winnow-list (entries exclude &optional predicates)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
399 "Pare down the ENTRIES list using the EXCLUDE regexp, and PREDICATES.
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
400 The original list is not affected. If the result is only one element
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
401 long, it will be returned itself, rather than returning a one-element
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
402 list."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
403 (let ((flist (list t))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
404 valid p listified)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
405 (unless (listp entries)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
406 (setq entries (list entries)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
407 listified t))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
408 (eshell-for entry entries
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
409 (unless (and exclude (string-match exclude entry))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
410 (setq p predicates valid (null p))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
411 (while p
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
412 (if (funcall (car p) entry)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
413 (setq valid t)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
414 (setq p nil valid nil))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
415 (setq p (cdr p)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
416 (when valid
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
417 (nconc flist (list entry)))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
418 (if listified
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
419 (cadr flist)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
420 (cdr flist))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
421
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
422 (defsubst eshell-redisplay ()
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
423 "Allow Emacs to redisplay buffers."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
424 ;; for some strange reason, Emacs 21 is prone to trigger an
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
425 ;; "args out of range" error in `sit-for', if this function
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
426 ;; runs while point is in the minibuffer and the users attempt
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
427 ;; to use completion. Don't ask me.
87082
7a4a3f1c72ee Require individual files if needed when compiling, rather than
Glenn Morris <rgm@gnu.org>
parents: 86533
diff changeset
428 (condition-case nil
7a4a3f1c72ee Require individual files if needed when compiling, rather than
Glenn Morris <rgm@gnu.org>
parents: 86533
diff changeset
429 (sit-for 0 0)
7a4a3f1c72ee Require individual files if needed when compiling, rather than
Glenn Morris <rgm@gnu.org>
parents: 86533
diff changeset
430 (error nil)))
29870
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
431
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
432 (defun eshell-read-passwd-file (file)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
433 "Return an alist correlating gids to group names in FILE."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
434 (let (names)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
435 (when (file-readable-p file)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
436 (with-temp-buffer
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
437 (insert-file-contents file)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
438 (goto-char (point-min))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
439 (while (not (eobp))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
440 (let* ((fields
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
441 (split-string (buffer-substring
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
442 (point) (progn (end-of-line)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
443 (point))) ":")))
31240
10b1c85c0bbe See ChangeLog
John Wiegley <johnw@newartisans.com>
parents: 29934
diff changeset
444 (if (and (and fields (nth 0 fields) (nth 2 fields))
62915
b89e30bcd2bb Changed all uses of `directory-sep-char' to ?/, and all uses of
John Wiegley <johnw@newartisans.com>
parents: 52401
diff changeset
445 (not (assq (string-to-number (nth 2 fields)) names)))
b89e30bcd2bb Changed all uses of `directory-sep-char' to ?/, and all uses of
John Wiegley <johnw@newartisans.com>
parents: 52401
diff changeset
446 (setq names (cons (cons (string-to-number (nth 2 fields))
29870
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
447 (nth 0 fields))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
448 names))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
449 (forward-line))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
450 names))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
451
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
452 (defun eshell-read-passwd (file result-var timestamp-var)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
453 "Read the contents of /etc/passwd for user names."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
454 (if (or (not (symbol-value result-var))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
455 (not (symbol-value timestamp-var))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
456 (eshell-time-less-p
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
457 (symbol-value timestamp-var)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
458 (nth 5 (file-attributes file))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
459 (progn
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
460 (set result-var (eshell-read-passwd-file file))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
461 (set timestamp-var (current-time))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
462 (symbol-value result-var))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
463
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
464 (defun eshell-read-group-names ()
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
465 "Read the contents of /etc/group for group names."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
466 (if eshell-group-file
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
467 (eshell-read-passwd eshell-group-file 'eshell-group-names
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
468 'eshell-group-timestamp)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
469
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
470 (defsubst eshell-group-id (name)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
471 "Return the user id for user NAME."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
472 (car (rassoc name (eshell-read-group-names))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
473
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
474 (defsubst eshell-group-name (gid)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
475 "Return the group name for the given GID."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
476 (cdr (assoc gid (eshell-read-group-names))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
477
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
478 (defun eshell-read-user-names ()
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
479 "Read the contents of /etc/passwd for user names."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
480 (if eshell-passwd-file
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
481 (eshell-read-passwd eshell-passwd-file 'eshell-user-names
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
482 'eshell-user-timestamp)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
483
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
484 (defsubst eshell-user-id (name)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
485 "Return the user id for user NAME."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
486 (car (rassoc name (eshell-read-user-names))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
487
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
488 (defalias 'eshell-user-name 'user-login-name)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
489
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
490 (defun eshell-read-hosts-file (filename)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
491 "Read in the hosts from the /etc/hosts file."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
492 (let (hosts)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
493 (with-temp-buffer
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
494 (insert-file-contents eshell-hosts-file)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
495 (goto-char (point-min))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
496 (while (re-search-forward
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
497 "^\\(\\S-+\\)\\s-+\\(\\S-+\\)\\(\\s-*\\(\\S-+\\)\\)?" nil t)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
498 (if (match-string 1)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
499 (add-to-list 'hosts (match-string 1)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
500 (if (match-string 2)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
501 (add-to-list 'hosts (match-string 2)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
502 (if (match-string 4)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
503 (add-to-list 'hosts (match-string 4)))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
504 (sort hosts 'string-lessp)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
505
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
506 (defun eshell-read-hosts (file result-var timestamp-var)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
507 "Read the contents of /etc/passwd for user names."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
508 (if (or (not (symbol-value result-var))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
509 (not (symbol-value timestamp-var))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
510 (eshell-time-less-p
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
511 (symbol-value timestamp-var)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
512 (nth 5 (file-attributes file))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
513 (progn
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
514 (set result-var (eshell-read-hosts-file file))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
515 (set timestamp-var (current-time))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
516 (symbol-value result-var))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
517
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
518 (defun eshell-read-host-names ()
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
519 "Read the contents of /etc/hosts for host names."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
520 (if eshell-hosts-file
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
521 (eshell-read-hosts eshell-hosts-file 'eshell-host-names
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
522 'eshell-host-timestamp)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
523
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
524 (unless (fboundp 'line-end-position)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
525 (defsubst line-end-position (&optional N)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
526 (save-excursion (end-of-line N) (point))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
527
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
528 (unless (fboundp 'line-beginning-position)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
529 (defsubst line-beginning-position (&optional N)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
530 (save-excursion (beginning-of-line N) (point))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
531
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
532 (unless (fboundp 'subst-char-in-string)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
533 (defun subst-char-in-string (fromchar tochar string &optional inplace)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
534 "Replace FROMCHAR with TOCHAR in STRING each time it occurs.
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
535 Unless optional argument INPLACE is non-nil, return a new string."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
536 (let ((i (length string))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
537 (newstr (if inplace string (copy-sequence string))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
538 (while (> i 0)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
539 (setq i (1- i))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
540 (if (eq (aref newstr i) fromchar)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
541 (aset newstr i tochar)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
542 newstr)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
543
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
544 (defsubst eshell-copy-environment ()
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
545 "Return an unrelated copy of `process-environment'."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
546 (mapcar 'concat process-environment))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
547
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
548 (defun eshell-subgroups (groupsym)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
549 "Return all of the subgroups of GROUPSYM."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
550 (let ((subgroups (get groupsym 'custom-group))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
551 (subg (list t)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
552 (while subgroups
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
553 (if (eq (cadr (car subgroups)) 'custom-group)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
554 (nconc subg (list (caar subgroups))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
555 (setq subgroups (cdr subgroups)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
556 (cdr subg)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
557
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
558 (defmacro eshell-with-file-modes (modes &rest forms)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
559 "Evaluate, with file-modes set to MODES, the given FORMS."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
560 `(let ((modes (default-file-modes)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
561 (set-default-file-modes ,modes)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
562 (unwind-protect
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
563 (progn ,@forms)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
564 (set-default-file-modes modes))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
565
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
566 (defmacro eshell-with-private-file-modes (&rest forms)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
567 "Evaluate FORMS with private file modes set."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
568 `(eshell-with-file-modes ,eshell-private-file-modes ,@forms))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
569
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
570 (defsubst eshell-make-private-directory (dir &optional parents)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
571 "Make DIR with file-modes set to `eshell-private-directory-modes'."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
572 (eshell-with-file-modes eshell-private-directory-modes
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
573 (make-directory dir parents)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
574
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
575 (defsubst eshell-substring (string sublen)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
576 "Return the beginning of STRING, up to SUBLEN bytes."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
577 (if string
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
578 (if (> (length string) sublen)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
579 (substring string 0 sublen)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
580 string)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
581
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
582 (unless (fboundp 'directory-files-and-attributes)
47963
39dffdbc6892 (directory-files-and-attributes): Copy docstring from Emacs 21. Arg DIR renamed
Juanma Barranquero <lekktu@gmail.com>
parents: 46852
diff changeset
583 (defun directory-files-and-attributes (directory &optional full match nosort)
39dffdbc6892 (directory-files-and-attributes): Copy docstring from Emacs 21. Arg DIR renamed
Juanma Barranquero <lekktu@gmail.com>
parents: 46852
diff changeset
584 "Return a list of names of files and their attributes in DIRECTORY.
39dffdbc6892 (directory-files-and-attributes): Copy docstring from Emacs 21. Arg DIR renamed
Juanma Barranquero <lekktu@gmail.com>
parents: 46852
diff changeset
585 There are three optional arguments:
39dffdbc6892 (directory-files-and-attributes): Copy docstring from Emacs 21. Arg DIR renamed
Juanma Barranquero <lekktu@gmail.com>
parents: 46852
diff changeset
586 If FULL is non-nil, return absolute file names. Otherwise return names
39dffdbc6892 (directory-files-and-attributes): Copy docstring from Emacs 21. Arg DIR renamed
Juanma Barranquero <lekktu@gmail.com>
parents: 46852
diff changeset
587 that are relative to the specified directory.
39dffdbc6892 (directory-files-and-attributes): Copy docstring from Emacs 21. Arg DIR renamed
Juanma Barranquero <lekktu@gmail.com>
parents: 46852
diff changeset
588 If MATCH is non-nil, mention only file names that match the regexp MATCH.
39dffdbc6892 (directory-files-and-attributes): Copy docstring from Emacs 21. Arg DIR renamed
Juanma Barranquero <lekktu@gmail.com>
parents: 46852
diff changeset
589 If NOSORT is non-nil, the list is not sorted--its order is unpredictable.
39dffdbc6892 (directory-files-and-attributes): Copy docstring from Emacs 21. Arg DIR renamed
Juanma Barranquero <lekktu@gmail.com>
parents: 46852
diff changeset
590 NOSORT is useful if you plan to sort the result yourself."
39dffdbc6892 (directory-files-and-attributes): Copy docstring from Emacs 21. Arg DIR renamed
Juanma Barranquero <lekktu@gmail.com>
parents: 46852
diff changeset
591 (let ((directory (expand-file-name directory)) ange-cache)
29870
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
592 (mapcar
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
593 (function
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
594 (lambda (file)
47963
39dffdbc6892 (directory-files-and-attributes): Copy docstring from Emacs 21. Arg DIR renamed
Juanma Barranquero <lekktu@gmail.com>
parents: 46852
diff changeset
595 (cons file (eshell-file-attributes (expand-file-name file directory)))))
39dffdbc6892 (directory-files-and-attributes): Copy docstring from Emacs 21. Arg DIR renamed
Juanma Barranquero <lekktu@gmail.com>
parents: 46852
diff changeset
596 (directory-files directory full match nosort)))))
29870
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
597
32446
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
598 (eval-when-compile
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
599 (defvar ange-cache))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
600
29870
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
601 (defun eshell-directory-files-and-attributes (dir &optional full match nosort)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
602 "Make sure to use the handler for `directory-file-and-attributes'."
32446
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
603 (let* ((dir (expand-file-name dir))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
604 (dfh (find-file-name-handler dir 'directory-files)))
29870
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
605 (if (not dfh)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
606 (directory-files-and-attributes dir full match nosort)
32446
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
607 (let ((files (funcall dfh 'directory-files dir full match nosort))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
608 (fah (find-file-name-handler dir 'file-attributes)))
29870
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
609 (mapcar
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
610 (function
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
611 (lambda (file)
32446
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
612 (cons file (if fah
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
613 (eshell-file-attributes
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
614 (expand-file-name file dir))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
615 (file-attributes (expand-file-name file dir))))))
29870
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
616 files)))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
617
32446
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
618 (defun eshell-current-ange-uids ()
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
619 (if (string-match "/\\([^@]+\\)@\\([^:]+\\):" default-directory)
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
620 (let* ((host (match-string 2 default-directory))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
621 (user (match-string 1 default-directory))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
622 (host-users (assoc host eshell-ange-ls-uids)))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
623 (when host-users
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
624 (setq host-users (cdr host-users))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
625 (cdr (assoc user host-users))))))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
626
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
627 ;; Add an autoload for parse-time-string
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
628 (if (and (not (fboundp 'parse-time-string))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
629 (locate-library "parse-time"))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
630 (autoload 'parse-time-string "parse-time"))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
631
32470
b338a85bdffc Added a missing `require' form.
John Wiegley <johnw@newartisans.com>
parents: 32446
diff changeset
632 (eval-when-compile
86533
59b6ce989ba4 (top-level): Use require rather than load for ange-ftp.
Glenn Morris <rgm@gnu.org>
parents: 86202
diff changeset
633 (require 'ange-ftp nil t))
32470
b338a85bdffc Added a missing `require' form.
John Wiegley <johnw@newartisans.com>
parents: 32446
diff changeset
634
32446
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
635 (defun eshell-parse-ange-ls (dir)
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
636 (let (entry)
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
637 (with-temp-buffer
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
638 (insert (ange-ftp-ls dir "-la" nil))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
639 (goto-char (point-min))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
640 (if (looking-at "^total [0-9]+$")
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
641 (forward-line 1))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
642 ;; Some systems put in a blank line here.
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
643 (if (eolp) (forward-line 1))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
644 (while (looking-at
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
645 `,(concat "\\([dlscb-][rwxst-]+\\)"
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
646 "\\s-*" "\\([0-9]+\\)" "\\s-+"
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
647 "\\(\\S-+\\)" "\\s-+"
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
648 "\\(\\S-+\\)" "\\s-+"
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
649 "\\([0-9]+\\)" "\\s-+" "\\(.*\\)"))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
650 (let* ((perms (match-string 1))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
651 (links (string-to-number (match-string 2)))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
652 (user (match-string 3))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
653 (group (match-string 4))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
654 (size (string-to-number (match-string 5)))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
655 (mtime
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
656 (if (fboundp 'parse-time-string)
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
657 (let ((moment (parse-time-string
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
658 (match-string 6))))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
659 (if (nth 0 moment)
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
660 (setcar (nthcdr 5 moment)
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
661 (nth 5 (decode-time (current-time))))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
662 (setcar (nthcdr 0 moment) 0)
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
663 (setcar (nthcdr 1 moment) 0)
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
664 (setcar (nthcdr 2 moment) 0))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
665 (apply 'encode-time moment))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
666 (ange-ftp-file-modtime (expand-file-name name dir))))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
667 (name (ange-ftp-parse-filename))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
668 symlink)
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
669 (if (string-match "\\(.+\\) -> \\(.+\\)" name)
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
670 (setq symlink (match-string 2 name)
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
671 name (match-string 1 name)))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
672 (setq entry
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
673 (cons
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
674 (cons name
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
675 (list (if (eq (aref perms 0) ?d)
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
676 t
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
677 symlink)
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
678 links user group
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
679 nil mtime nil
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
680 size perms nil nil)) entry)))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
681 (forward-line)))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
682 entry))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
683
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
684 (defun eshell-file-attributes (file)
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
685 "Return the attributes of FILE, playing tricks if it's over ange-ftp."
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
686 (let* ((file (expand-file-name file))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
687 (handler (find-file-name-handler file 'file-attributes))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
688 entry)
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
689 (if (not handler)
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
690 (file-attributes file)
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
691 (if (eq (find-file-name-handler (file-name-directory file)
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
692 'directory-files)
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
693 'ange-ftp-hook-function)
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
694 (let ((base (file-name-nondirectory file))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
695 (dir (file-name-directory file)))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
696 (if (boundp 'ange-cache)
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
697 (setq entry (cdr (assoc base (cdr (assoc dir ange-cache))))))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
698 (unless entry
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
699 (setq entry (eshell-parse-ange-ls dir))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
700 (if (boundp 'ange-cache)
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
701 (setq ange-cache
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
702 (cons (cons dir entry)
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
703 ange-cache)))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
704 (if entry
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
705 (let ((fentry (assoc base (cdr entry))))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
706 (if fentry
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
707 (setq entry (cdr fentry))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
708 (setq entry nil)))))))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
709 (or entry (funcall handler 'file-attributes file)))))
aab90b31807c Added better remote directory support to Eshell, as well as a few bug
John Wiegley <johnw@newartisans.com>
parents: 31241
diff changeset
710
45741
b2a7c08cddcf (eshell-copy-tree): Make it an alias for copy-tree.
Richard M. Stallman <rms@gnu.org>
parents: 45736
diff changeset
711 (defalias 'eshell-copy-tree 'copy-tree)
29870
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
712
31240
10b1c85c0bbe See ChangeLog
John Wiegley <johnw@newartisans.com>
parents: 29934
diff changeset
713 (defsubst eshell-processp (proc)
10b1c85c0bbe See ChangeLog
John Wiegley <johnw@newartisans.com>
parents: 29934
diff changeset
714 "If the `processp' function does not exist, PROC is not a process."
10b1c85c0bbe See ChangeLog
John Wiegley <johnw@newartisans.com>
parents: 29934
diff changeset
715 (and (fboundp 'processp) (processp proc)))
10b1c85c0bbe See ChangeLog
John Wiegley <johnw@newartisans.com>
parents: 29934
diff changeset
716
29870
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
717 ; (defun eshell-copy-file
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
718 ; (file newname &optional ok-if-already-exists keep-date)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
719 ; "Copy FILE to NEWNAME. See docs for `copy-file'."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
720 ; (let (copied)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
721 ; (if (string-match "\\`\\([^:]+\\):\\(.*\\)" file)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
722 ; (let ((front (match-string 1 file))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
723 ; (back (match-string 2 file))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
724 ; buffer)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
725 ; (if (and front (string-match eshell-tar-regexp front)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
726 ; (setq buffer (find-file-noselect front)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
727 ; (with-current-buffer buffer
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
728 ; (goto-char (point-min))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
729 ; (if (re-search-forward (concat " " (regexp-quote back)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
730 ; "$") nil t)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
731 ; (progn
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
732 ; (tar-copy (if (file-directory-p newname)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
733 ; (expand-file-name
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
734 ; (file-name-nondirectory back) newname)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
735 ; newname))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
736 ; (setq copied t))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
737 ; (error "%s not found in tar file %s" back front))))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
738 ; (unless copied
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
739 ; (copy-file file newname ok-if-already-exists keep-date))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
740
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
741 ; (defun eshell-file-attributes (filename)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
742 ; "Return a list of attributes of file FILENAME.
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
743 ; See the documentation for `file-attributes'."
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
744 ; (let (result)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
745 ; (when (string-match "\\`\\([^:]+\\):\\(.*\\)\\'" filename)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
746 ; (let ((front (match-string 1 filename))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
747 ; (back (match-string 2 filename))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
748 ; buffer)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
749 ; (when (and front (string-match eshell-tar-regexp front)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
750 ; (setq buffer (find-file-noselect front)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
751 ; (with-current-buffer buffer
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
752 ; (goto-char (point-min))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
753 ; (when (re-search-forward (concat " " (regexp-quote back)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
754 ; "\\s-*$") nil t)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
755 ; (let* ((descrip (tar-current-descriptor))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
756 ; (tokens (tar-desc-tokens descrip)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
757 ; (setq result
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
758 ; (list
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
759 ; (cond
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
760 ; ((eq (tar-header-link-type tokens) 5)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
761 ; t)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
762 ; ((eq (tar-header-link-type tokens) t)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
763 ; (tar-header-link-name tokens)))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
764 ; 1
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
765 ; (tar-header-uid tokens)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
766 ; (tar-header-gid tokens)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
767 ; (tar-header-date tokens)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
768 ; (tar-header-date tokens)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
769 ; (tar-header-date tokens)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
770 ; (tar-header-size tokens)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
771 ; (concat
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
772 ; (cond
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
773 ; ((eq (tar-header-link-type tokens) 5) "d")
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
774 ; ((eq (tar-header-link-type tokens) t) "l")
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
775 ; (t "-"))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
776 ; (tar-grind-file-mode (tar-header-mode tokens)
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
777 ; (make-string 9 ? ) 0))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
778 ; nil nil nil))))))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
779 ; (or result
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
780 ; (file-attributes filename))))
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
781
87082
7a4a3f1c72ee Require individual files if needed when compiling, rather than
Glenn Morris <rgm@gnu.org>
parents: 86533
diff changeset
782 (provide 'esh-util)
29870
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
783
52401
695cf19ef79e Add arch taglines
Miles Bader <miles@gnu.org>
parents: 47963
diff changeset
784 ;;; arch-tag: 70159778-5c7a-480a-bae4-3ad332fca19d
29870
ccc03e321fdf *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
785 ;;; esh-util.el ends here