diff lisp/efs/emacs-19.el @ 98:0d2f883870bc r20-1b1

Import from CVS: tag r20-1b1
author cvs
date Mon, 13 Aug 2007 09:13:56 +0200
parents 8fc7fe29b841
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lisp/efs/emacs-19.el	Mon Aug 13 09:13:56 2007 +0200
@@ -0,0 +1,484 @@
+;;;; Emacs 19 compatibility functions for use in Emacs 18.
+;;;; Based on: $Id: emacs-19.el,v 1.1 1997/02/11 05:05:14 steve Exp $
+;;;;
+;;;; Rewritten by sandy@ibm550.sissa.it after gnu emacs 19 was
+;;;; released to make it closer to V19.
+;;;; Last modified: Sun Jun 12 00:06:06 1994 by sandy on ibm550
+
+;;; This program 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 1, or (at your option)
+;;; any later version.
+;;;
+;;; This program 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.
+;;;
+;;; A copy of the GNU General Public License can be obtained from this
+;;; program's author (send electronic mail to roland@ai.mit.edu) or from
+;;; the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA
+;;; 02139, USA.
+
+;; These functions are used in dired.el, but are also of general
+;; interest, so you may want to add this to your .emacs:
+;; 
+;; (autoload 'make-directory "emacs-19" "Make a directory." t)
+;; (autoload 'delete-directory "emacs-19" "Remove a directory." t)
+;; (autoload 'member "emacs-19" "Like memq, but uses `equal' instead of `eq'.")
+;; (autoload 'compiled-function-p "emacs-19" "Emacs 18 doesn't have these.")
+
+(provide 'emacs-19)
+
+;;; Variables
+
+(defvar insert-directory-program "ls"
+  "Absolute or relative name of the `ls' program used by `insert-directory'.")
+
+(defvar bv-length) ; make the byte compiler a happy camper
+
+(defconst directory-abbrev-alist
+  nil
+  "*Alist of abbreviations for file directories.
+A list of elements of the form (FROM . TO), each meaning to replace
+FROM with TO when it appears in a directory name.  This replacement is
+done when setting up the default directory of a newly visited file.
+*Every* FROM string should start with `^'.
+
+Use this feature when you have directories which you normally refer to
+via absolute symbolic links.  Make TO the name of the link, and FROM
+the name it is linked to.")
+
+(defconst automount-dir-prefix "^/tmp_mnt/"
+  "Regexp to match the automounter prefix in a directory name.")
+
+(defvar abbreviated-home-dir nil
+  "The the user's homedir abbreviated according to `directory-abbrev-list'.")
+
+;;; Autoloads
+
+(autoload 'diff "diff" "Diff two files." t)
+(autoload 'diff-backup "diff" "Diff a file with its most recent backup.")
+
+;;; Functions which are subroutines in Emacs 19.
+
+;; Provide a non-working version of find-file-name-handler.
+;; If you want it to work, require 'fn-handler.
+
+(or (fboundp 'find-file-name-handler) (fset 'find-file-name-handler 'ignore))
+(or (boundp 'file-name-handler-alist) (defvar file-name-handler-alist nil))
+
+;; The name of buffer-flush-undo has changed in V19.
+(fset 'buffer-disable-undo 'buffer-flush-undo)
+
+(defun current-time ()
+  "Returns the number of seconds since midnight.
+A poor man's version of the the function `current-time' in emacs 19."
+  (let ((string (current-time-string)))
+    (list
+     0
+     (+ (* 3600 (string-to-int (substring string 11 13)))
+	(* 60 (string-to-int (substring string 14 16)))
+	(string-to-int (substring string 17 19)))
+     0)))
+
+;; call-process below may lose if filename starts with a `-', but I
+;; fear not all mkdir or rmdir implementations understand `--'.
+
+(defun delete-directory (fn)
+  "Delete a directory.
+This is a subr in Emacs 19."
+  (interactive 
+   (list (read-file-name "Delete directory: " nil nil 'confirm)))
+  (setq fn (expand-file-name fn))
+  (if (file-directory-p fn)
+      (call-process "rmdir" nil nil nil fn)
+    (error "Not a directory: %s" fn))
+  (if (file-exists-p fn)
+      (error "Could not remove directory %s" fn)))
+
+(defun make-directory (dir &optional parents)
+  "Create the directory DIR and any nonexistent parent dirs."
+  (interactive "FMake directory: \nP")
+  (if (not parents)
+      (make-directory-internal dir)
+    (let ((dir (directory-file-name (expand-file-name dir)))
+	  create-list)
+      (while (not (file-exists-p dir))
+	(setq create-list (cons dir create-list)	    
+	      dir (directory-file-name (file-name-directory dir))))
+      (while create-list
+	(make-directory-internal (car create-list))
+	(setq create-list (cdr create-list))))))
+
+(defun make-directory-internal (fn)
+  ;; This is a subroutine in emacs 19.
+  (let* ((fn (expand-file-name fn))
+	 (handler (find-file-name-handler fn 'make-directory-internal)))
+    (if handler
+	(funcall handler 'make-directory-internal fn)
+      (setq fn (directory-file-name fn))
+      (if (file-exists-p fn)
+	  (error "Cannot make directory %s: file already exists" fn)
+	(call-process "mkdir" nil nil nil fn))
+      (or (file-directory-p fn)
+	  (error "Could not make directory %s" fn)))))
+
+(defun kill-new (string)
+  "Save STRING as if killed in a buffer."
+  (setq kill-ring (cons string kill-ring))
+  (if (> (length kill-ring) kill-ring-max)
+      (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil))
+  (setq kill-ring-yank-pointer kill-ring))
+
+(defun insert-directory (file switches &optional wildcard full-directory-p)
+  "Insert directory listing for FILE, formatted according to SWITCHES.
+Leaves point after the inserted text.
+SWITCHES may be a string of options, or a list of strings.
+Optional third arg WILDCARD means treat FILE as shell wildcard.
+Optional fourth arg FULL-DIRECTORY-P means file is a directory and
+switches do not contain `d', so that a full listing is expected.
+
+This works by running a directory listing program
+whose name is in the variable `insert-directory-program'.
+If WILDCARD, it also runs the shell specified by `shell-file-name'."
+  ;; We need the directory in order to find the right handler.
+  (let ((handler (find-file-name-handler (expand-file-name file)
+					 'insert-directory)))
+    (if handler
+	(funcall handler 'insert-directory file switches
+		 wildcard full-directory-p)
+      (if (eq system-type 'vax-vms)
+	  (vms-read-directory file switches (current-buffer))
+	(if wildcard
+	    ;; Run ls in the directory of the file pattern we asked for.
+	    (let ((default-directory
+		    (if (file-name-absolute-p file)
+			(file-name-directory file)
+		      (file-name-directory (expand-file-name file))))
+		  (pattern (file-name-nondirectory file))
+		  (beg 0))
+	      ;; Quote some characters that have special meanings in shells;
+	      ;; but don't quote the wildcards--we want them to be special.
+	      ;; We also currently don't quote the quoting characters
+	      ;; in case people want to use them explicitly to quote
+	      ;; wildcard characters.
+	      (while (string-match "[ \t\n;<>&|()#$]" pattern beg)
+		(setq pattern
+		      (concat (substring pattern 0 (match-beginning 0))
+			      "\\"
+			      (substring pattern (match-beginning 0)))
+		      beg (1+ (match-end 0))))
+	      (call-process shell-file-name nil t nil
+			    "-c" (concat insert-directory-program
+					 " -d "
+					 (if (stringp switches)
+					     switches
+					   (mapconcat 'identity switches " "))
+					 " "
+					 pattern)))
+	  ;; SunOS 4.1.3, SVr4 and others need the "." to list the
+	  ;; directory if FILE is a symbolic link.
+	  (apply 'call-process
+		 insert-directory-program nil t nil
+		 (let (list)
+		   (if (listp switches)
+		       (setq list switches)
+		     (if (not (equal switches ""))
+			 (progn
+			   ;; Split the switches at any spaces
+			   ;; so we can pass separate options as separate args.
+			   (while (string-match " " switches)
+			     (setq list (cons (substring switches 0
+							 (match-beginning 0))
+					      list)
+				   switches (substring switches
+						       (match-end 0))))
+			   (setq list (cons switches list)))))
+		   (append list
+			   (list
+			    (if full-directory-p
+				(concat (file-name-as-directory file) ".")
+			      file))))))))))
+
+(defun file-local-copy (file)
+  "Copy the file FILE into a temporary file on this machine.
+Returns the name of the local copy, or nil, if FILE is directly
+accessible."
+  (let* ((file (expand-file-name file))
+	 (handler (find-file-name-handler file 'file-local-copy)))
+    ;; Does nothing, if no handler.
+    (if handler
+	(funcall handler 'file-local-copy file))))
+
+(defun file-truename (filename)
+  "Return the truename of FILENAME, which should be absolute.
+The truename of a file name is found by chasing symbolic links
+both at the level of the file and at the level of the directories
+containing it, until no links are left at any level."
+  (if (or (string= filename "~")
+	  (and (string= (substring filename 0 1) "~")
+	       (string-match "~[^/]*" filename)))
+      (progn
+	(setq filename (expand-file-name filename))
+	(if (string= filename "")
+	    (setq filename "/"))))
+  (let ((handler (find-file-name-handler filename 'file-truename)))
+    ;; For file name that has a special handler, call handler.
+    ;; This is so that ange-ftp can save time by doing a no-op.
+    (if handler
+	(funcall handler 'file-truename filename)
+      (let ((dir (file-name-directory filename))
+	    target dirfile file-name-handler-alist)
+	;; Get the truename of the directory.
+	(setq dirfile (directory-file-name dir))
+	;; If these are equal, we have the (or a) root directory.
+	(or (string= dir dirfile)
+	    (setq dir (file-name-as-directory (file-truename dirfile))))
+	(if (equal ".." (file-name-nondirectory filename))
+	    (directory-file-name (file-name-directory
+				  (directory-file-name dir)))
+	  (if (equal "." (file-name-nondirectory filename))
+	      (directory-file-name dir)
+	    ;; Put it back on the file name.
+	    (setq filename (concat dir (file-name-nondirectory filename)))
+	    ;; Is the file name the name of a link?
+	    (setq target (file-symlink-p filename))
+	    (if target
+		;; Yes => chase that link, then start all over
+		;; since the link may point to a directory name that uses links.
+		;; We can't safely use expand-file-name here
+		;; since target might look like foo/../bar where foo
+		;; is itself a link.  Instead, we handle . and .. above.
+		(if (file-name-absolute-p target)
+		    (file-truename target)
+		  (file-truename (concat dir target)))
+	      ;; No, we are done!
+	      filename)))))))
+
+(defun generate-new-buffer-name (name)
+  "Return a string which is the name of no existing buffer based on
+NAME. If there is no live buffer named NAME, return NAME. Otherwise,
+modify name by appending `<NUMBER>', incrementing NUMBER until an
+unused name is found. Return that name."
+  (if (get-buffer name)
+      (let ((num 2)
+	    attempt)
+	(while (progn
+		 (setq attempt (concat name "<" (int-to-string num) ">"))
+		 (get-buffer attempt))
+	  (setq num (1+ num)))
+	attempt)
+    name))
+
+(defun abbreviate-file-name (filename)
+  "Return a version of FILENAME shortened using `directory-abbrev-alist'.
+This also substitutes \"~\" for the user's home directory.
+Type \\[describe-variable] directory-abbrev-alist RET for more information."
+  ;; Get rid of the prefixes added by the automounter.
+  (if (and (string-match automount-dir-prefix filename)
+	   (file-exists-p (file-name-directory
+			   (substring filename (1- (match-end 0))))))
+      (setq filename (substring filename (1- (match-end 0)))))
+  (let ((tail directory-abbrev-alist))
+    ;; If any elt of directory-abbrev-alist matches this name,
+    ;; abbreviate accordingly.
+    (while tail
+      (if (string-match (car (car tail)) filename)
+	  (setq filename
+		(concat (cdr (car tail)) (substring filename (match-end 0)))))
+      (setq tail (cdr tail)))
+    ;; Compute and save the abbreviated homedir name.
+    ;; We defer computing this until the first time it's needed, to
+    ;; give time for directory-abbrev-alist to be set properly.
+    (or abbreviated-home-dir
+	(setq abbreviated-home-dir
+	      (let ((abbreviated-home-dir "$foo"))
+		(concat "^" (abbreviate-file-name (expand-file-name "~"))))))
+    ;; If FILENAME starts with the abbreviated homedir,
+    ;; make it start with `~' instead.
+    (if (string-match abbreviated-home-dir filename)
+	(setq filename
+	      (concat "~"
+		      ;; If abbreviated-home-dir ends with a slash,
+		      ;; don't remove the corresponding slash from
+		      ;; filename.  On MS-DOS and OS/2, you can have
+		      ;; home directories like "g:/", in which it is
+		      ;; important not to remove the slash.  And what
+		      ;; about poor root on Unix systems?
+		      (if (eq ?/ (aref abbreviated-home-dir
+				       (1- (length abbreviated-home-dir))))
+			  "/"
+			"")
+		      (substring filename (match-end 0)))))
+    filename))
+
+(defun file-newest-backup (filename)
+  "Return most recent backup file for FILENAME or nil if no backups exist."
+  (let* ((filename (expand-file-name filename))
+	 (file (file-name-nondirectory filename))
+	 (dir  (file-name-directory    filename))
+	 (comp (file-name-all-completions file dir))
+	 newest)
+    (while comp
+      (setq file (concat dir (car comp))
+	    comp (cdr comp))
+      (if (and (backup-file-name-p file)
+	       (or (null newest) (file-newer-than-file-p file newest)))
+	  (setq newest file)))
+    newest))
+
+;; This is used in various files.
+;; The usage of bv-length is not very clean,
+;; but I can't see a good alternative,
+;; so as of now I am leaving it alone.
+(defun backup-extract-version (fn)
+  "Given the name of a numeric backup file, return the backup number.
+Uses the free variable `bv-length', whose value should be
+the index in the name where the version number begins."
+  (if (and (string-match "[0-9]+~$" fn bv-length)
+	   (= (match-beginning 0) bv-length))
+      (string-to-int (substring fn bv-length -1))
+      0))
+
+;; The standard V18 version of this function doesn't support
+;; the arg KEEP-BACKUP-VERSION
+(defun file-name-sans-versions (name &optional keep-backup-version)
+  "Return FILENAME sans backup versions or strings.
+This is a separate procedure so your site-init or startup file can
+redefine it.
+If the optional argument KEEP-BACKUP-VERSION is non-nil,
+we do not remove backup version numbers, only true file version numbers."
+  (let ((handler (find-file-name-handler name 'file-name-sans-versions)))
+    (if handler
+	(funcall handler 'file-name-sans-versions name keep-backup-version)
+      (substring name 0
+		 (if (eq system-type 'vax-vms)
+		     ;; VMS version number is (a) semicolon, optional
+		     ;; sign, zero or more digits or (b) period, option
+		     ;; sign, zero or more digits, provided this is the
+		     ;; second period encountered outside of the
+		     ;; device/directory part of the file name.
+		     (or (string-match ";[-+]?[0-9]*\\'" name)
+			 (if (string-match "\\.[^]>:]*\\(\\.[-+]?[0-9]*\\)\\'"
+					   name)
+			     (match-beginning 1))
+			 (length name))
+		   (if keep-backup-version
+		       (length name)
+		     (or (string-match "\\.~[0-9]+~\\'" name)
+			 (string-match "~\\'" name)
+			 (length name))))))))
+
+(defun member (x y)
+  "Like memq, but uses `equal' for comparison.
+This is a subr in Emacs 19."
+  (while (and y (not (equal x (car y))))
+    (setq y (cdr y)))
+  y)
+
+(defun compiled-function-p (x)
+  "Emacs 18 doesn't have these."
+  nil)
+
+;; punt -- this will at least allow handlers to work for this.
+(defun set-visited-file-modtime (&optional time)
+  (error "set-visited-file-modtime not defined in emacs 18."))
+
+(defun add-hook (hook function &optional append)
+  "Add to the value of HOOK the function FUNCTION.
+FUNCTION is not added if already present.
+FUNCTION is added (if necessary) at the beginning of the hook list
+unless the optional argument APPEND is non-nil, in which case
+FUNCTION is added at the end.
+
+HOOK should be a symbol, and FUNCTION may be any valid function.  If
+HOOK is void, it is first set to nil.  If HOOK's value is a single
+function, it is changed to a list of functions."
+  (or (boundp hook) (set hook nil))
+  ;; If the hook value is a single function, turn it into a list.
+  (let ((old (symbol-value hook)))
+    (if (or (not (listp old)) (eq (car old) 'lambda))
+	(set hook (list old))))
+  (or (if (consp function)
+	  ;; Clever way to tell whether a given lambda-expression
+	  ;; is equal to anything in the hook.
+	  (let ((tail (assoc (cdr function) (symbol-value hook))))
+	    (equal function tail))
+	(memq function (symbol-value hook)))
+      (set hook 
+	   (if append
+	       (nconc (symbol-value hook) (list function))
+	     (cons function (symbol-value hook))))))
+
+;;; after-save.el (Now part of files.el in Gnu Emacs V19)
+
+;;; Copyright (C) 1990 Roland McGrath
+;;;
+
+(or (fboundp 'real-save-buffer)
+    (fset 'real-save-buffer (symbol-function 'save-buffer)))
+
+(defvar after-save-hook nil
+  "A function or list of functions to be run after saving the current buffer.")
+
+(defun save-buffer (&optional args)
+  "Save the current buffer, and then run `after-save-buffer-hook'.
+The hooks are only run if the buffer was actually written.
+For more documentation, do \\[describe-function] real-save-buffer RET."
+  (interactive "p")
+  (let ((modp (buffer-modified-p)))
+    (real-save-buffer args)
+    (if modp
+	(run-hooks 'after-save-hook))))
+
+;;; end of after-save
+
+;;;;
+;;;; Correcting for V18 bugs, and hacking around stupidities.
+;;;;
+
+;; The 18.57 version has a bug that causes C-x C-v RET (which usually
+;; re-visits the current buffer) to fail on dired buffers.
+;; Only the last statement was changed to avoid killing the current
+;; buffer.
+(defun find-alternate-file (filename)
+  "Find file FILENAME, select its buffer, kill previous buffer.
+If the current buffer now contains an empty file that you just visited
+\(presumably by mistake), use this command to visit the file you really want."
+  (interactive "FFind alternate file: ")
+  (and (buffer-modified-p)
+       (not buffer-read-only)
+       (not (yes-or-no-p (format "Buffer %s is modified; kill anyway? "
+				 (buffer-name))))
+       (error "Aborted"))
+  (let ((obuf (current-buffer))
+	(ofile buffer-file-name)
+	(oname (buffer-name)))
+    (rename-buffer " **lose**")
+    (setq buffer-file-name nil)
+    (unwind-protect
+	(progn
+	  (unlock-buffer)
+	  (find-file filename))
+      (cond ((eq obuf (current-buffer))
+	     (setq buffer-file-name ofile)
+	     (lock-buffer)
+	     (rename-buffer oname))))
+    (or (eq (current-buffer) obuf)
+	(kill-buffer obuf))))
+
+;; At least in Emacs 18.55 this defvar has been forgotten to be copied
+;; from lpr.el into loaddefs.el
+
+(defvar lpr-command (if (eq system-type 'usg-unix-v)
+			"lp" "lpr")
+  "Shell command for printing a file")
+
+
+;; buffer-disable-undo used to be called buffer-flush-undo in Emacs
+;; 18.55:
+(or (fboundp 'buffer-disable-undo)
+    (fset 'buffer-disable-undo 'buffer-flush-undo))
+
+;;; end of emacs-19.el