|
|
1.1 ! root 1: ;; File input and output commands for Emacs ! 2: ;; Copyright (C) 1985, 1986, 1987, 1990 Free Software Foundation, Inc. ! 3: ! 4: ;; This file is part of GNU Emacs. ! 5: ! 6: ;; GNU Emacs is free software; you can redistribute it and/or modify ! 7: ;; it under the terms of the GNU General Public License as published by ! 8: ;; the Free Software Foundation; either version 1, or (at your option) ! 9: ;; any later version. ! 10: ! 11: ;; GNU Emacs is distributed in the hope that it will be useful, ! 12: ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ! 13: ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 14: ;; GNU General Public License for more details. ! 15: ! 16: ;; You should have received a copy of the GNU General Public License ! 17: ;; along with GNU Emacs; see the file COPYING. If not, write to ! 18: ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. ! 19: ! 20: ! 21: (defconst delete-auto-save-files t ! 22: "*Non-nil means delete a buffer's auto-save file ! 23: when the buffer is saved for real.") ! 24: ! 25: ;(make-variable-buffer-local 'buffer-backed-up) ! 26: ;(defvar buffer-backed-up nil ! 27: ; "Non-nil if this buffer's file has been backed up. ! 28: ;Backing up is done before the first time the file is saved.") ! 29: ! 30: ;;; Turn off backup files on VMS since it has version numbers. ! 31: (defconst make-backup-files (not (eq system-type 'vax-vms)) ! 32: "*Create a backup of each file when it is saved for the first time. ! 33: This can be done by renaming the file or by copying. ! 34: ! 35: Renaming means that Emacs renames the existing file so that it is a ! 36: backup file, then writes the buffer into a new file. Any other names ! 37: that the old file had will now refer to the backup file. ! 38: The new file is owned by you and its group is defaulted. ! 39: ! 40: Copying means that Emacs copies the existing file into the backup file, ! 41: then writes the buffer on top of the existing file. Any other names ! 42: that the old file had will now refer to the new (edited) file. ! 43: The file's owner and group are unchanged. ! 44: ! 45: The choice of renaming or copying is controlled by the variables ! 46: backup-by-copying, backup-by-copying-when-linked and ! 47: backup-by-copying-when-mismatch.") ! 48: ! 49: (defconst backup-by-copying nil ! 50: "*Non-nil means always use copying to create backup files. ! 51: See documentation of variable make-backup-files.") ! 52: ! 53: (defconst backup-by-copying-when-linked nil ! 54: "*Non-nil means use copying to create backups for files with multiple names. ! 55: This causes the alternate names to refer to the latest version as edited. ! 56: This variable is relevant only if backup-by-copying is nil.") ! 57: ! 58: (defconst backup-by-copying-when-mismatch nil ! 59: "*Non-nil means create backups by copying if this preserves owner or group. ! 60: Renaming may still be used (subject to control of other variables) ! 61: when it would not result in changing the owner or group of the file; ! 62: that is, for files which are owned by you and whose group matches ! 63: the default for a new file created there by you. ! 64: This variable is relevant only if backup-by-copying is nil.") ! 65: ! 66: (defconst buffer-offer-save nil ! 67: "*Non-nil in a buffer means offer to save the buffer on exit ! 68: even if the buffer is not visiting a file. Automatically local in ! 69: all buffers.") ! 70: (make-variable-buffer-local 'buffer-offer-save) ! 71: ! 72: (defconst file-precious-flag nil ! 73: "*Non-nil means protect against I/O errors while saving files. ! 74: Some modes set this non-nil in particular buffers.") ! 75: ! 76: (defvar version-control nil ! 77: "*Control use of version numbers for backup files. ! 78: t means make numeric backup versions unconditionally. ! 79: nil means make them for files that have some already. ! 80: never means do not make them.") ! 81: ! 82: (defvar dired-kept-versions 2 ! 83: "*When cleaning directory, number of versions to keep.") ! 84: ! 85: (defvar trim-versions-without-asking nil ! 86: "*If true, deletes excess backup versions silently. ! 87: Otherwise asks confirmation.") ! 88: ! 89: (defvar kept-old-versions 2 ! 90: "*Number of oldest versions to keep when a new numbered backup is made.") ! 91: ! 92: (defvar kept-new-versions 2 ! 93: "*Number of newest versions to keep when a new numbered backup is made. ! 94: Includes the new backup. Must be > 0") ! 95: ! 96: (defconst require-final-newline nil ! 97: "*t says silently put a newline at the end whenever a file is saved. ! 98: Non-nil but not t says ask user whether to add a newline in each such case. ! 99: nil means don't add newlines.") ! 100: ! 101: (defconst auto-save-default t ! 102: "*t says by default do auto-saving of every file-visiting buffer.") ! 103: ! 104: (defconst auto-save-visited-file-name nil ! 105: "*t says auto-save a buffer in the file it is visiting, when practical. ! 106: Normally auto-save files are written under other names.") ! 107: ! 108: (defconst save-abbrevs nil ! 109: "*Non-nil means save word abbrevs too when files are saved. ! 110: Loading an abbrev file sets this to t.") ! 111: ! 112: (defconst find-file-run-dired t ! 113: "*Non-nil says run dired if find-file is given the name of a directory.") ! 114: ! 115: (defvar find-file-not-found-hooks nil ! 116: "List of functions to be called for find-file on nonexistent file. ! 117: These functions are called as soon as the error is detected. ! 118: buffer-file-name is already set up. ! 119: The functions are called in the order given, ! 120: until one of them returns non-nil.") ! 121: ! 122: (defvar find-file-hooks nil ! 123: "List of functions to be called after a buffer is loaded from a file. ! 124: The buffer's local variables (if any) will have been processed before the ! 125: functions are called.") ! 126: ! 127: (defvar write-file-hooks nil ! 128: "List of functions to be called before writing out a buffer to a file. ! 129: If one of them returns non-nil, the file is considered already written ! 130: and the rest are not called.") ! 131: ! 132: (defconst inhibit-local-variables nil ! 133: "*Non-nil means query before obeying a file's local-variables list. ! 134: This applies when the local-variables list is scanned automatically ! 135: after you find a file. If you explicitly request such a scan with ! 136: \\[normal-mode], there is no query, regardless of this variable.") ! 137: ! 138: (defconst ignore-local-eval nil ! 139: "*Non-nil means ignore the \"variable\" `eval' in a file's local variables. ! 140: This applies when the local-variables list is scanned automatically ! 141: after you find a file. If you explicitly request such a scan with ! 142: \\[normal-mode], there is no query, regardless of this variable.") ! 143: ! 144: ;; Avoid losing in versions where CLASH_DETECTION is disabled. ! 145: (or (fboundp 'lock-buffer) ! 146: (fset 'lock-buffer 'ignore)) ! 147: (or (fboundp 'unlock-buffer) ! 148: (fset 'unlock-buffer 'ignore)) ! 149: ! 150: (defun pwd () ! 151: "Show the current default directory." ! 152: (interactive nil) ! 153: (message "Directory %s" default-directory)) ! 154: ! 155: (defun cd (dir) ! 156: "Make DIR become the current buffer's default directory." ! 157: (interactive "DChange default directory: ") ! 158: (setq dir (expand-file-name dir)) ! 159: (if (not (eq system-type 'vax-vms)) ! 160: (setq dir (file-name-as-directory dir))) ! 161: (if (not (file-directory-p dir)) ! 162: (error "%s is not a directory" dir) ! 163: (setq default-directory dir)) ! 164: (pwd)) ! 165: ! 166: (defun load-file (file) ! 167: "Load the file FILE of Lisp code." ! 168: (interactive "fLoad file: ") ! 169: (load (expand-file-name file) nil nil t)) ! 170: ! 171: (defun load-library (library) ! 172: "Load the library named LIBRARY. ! 173: This is an interface to the function `load'." ! 174: (interactive "sLoad library: ") ! 175: (load library)) ! 176: ! 177: (defun switch-to-buffer-other-window (buffer) ! 178: "Select buffer BUFFER in another window." ! 179: (interactive "BSwitch to buffer in other window: ") ! 180: (let ((pop-up-windows t)) ! 181: (pop-to-buffer buffer t))) ! 182: ! 183: (defun find-file (filename) ! 184: "Edit file FILENAME. ! 185: Switch to a buffer visiting file FILENAME, ! 186: creating one if none already exists." ! 187: (interactive "FFind file: ") ! 188: (switch-to-buffer (find-file-noselect filename))) ! 189: ! 190: (defun find-file-other-window (filename) ! 191: "Edit file FILENAME, in another window. ! 192: May create a new window, or reuse an existing one; ! 193: see the function display-buffer." ! 194: (interactive "FFind file in other window: ") ! 195: (switch-to-buffer-other-window (find-file-noselect filename))) ! 196: ! 197: (defun find-file-read-only (filename) ! 198: "Edit file FILENAME but don't save without confirmation. ! 199: Like find-file but marks buffer as read-only." ! 200: (interactive "fFind file read-only: ") ! 201: (find-file filename) ! 202: (setq buffer-read-only t)) ! 203: ! 204: (defun find-alternate-file (filename) ! 205: "Find file FILENAME, select its buffer, kill previous buffer. ! 206: If the current buffer now contains an empty file that you just visited ! 207: \(presumably by mistake), use this command to visit the file you really want." ! 208: (interactive "FFind alternate file: ") ! 209: (and (buffer-modified-p) ! 210: ;;; (not buffer-read-only) ! 211: (not (yes-or-no-p (format "Buffer %s is modified; kill anyway? " ! 212: (buffer-name)))) ! 213: (error "Aborted")) ! 214: (let ((obuf (current-buffer)) ! 215: (ofile buffer-file-name) ! 216: (oname (buffer-name))) ! 217: (rename-buffer " **lose**") ! 218: (setq buffer-file-name nil) ! 219: (unwind-protect ! 220: (progn ! 221: (unlock-buffer) ! 222: (find-file filename)) ! 223: (cond ((eq obuf (current-buffer)) ! 224: (setq buffer-file-name ofile) ! 225: (lock-buffer) ! 226: (rename-buffer oname)))) ! 227: (or (eq obuf (current-buffer)) ! 228: (kill-buffer obuf)))) ! 229: ! 230: (defun create-file-buffer (filename) ! 231: "Create a suitably named buffer for visiting FILENAME, and return it. ! 232: FILENAME (sans directory) is used unchanged if that name is free; ! 233: otherwise a string <2> or <3> or ... is appended to get an unused name." ! 234: (let ((lastname (file-name-nondirectory filename))) ! 235: (if (string= lastname "") ! 236: (setq lastname filename)) ! 237: (generate-new-buffer lastname))) ! 238: ! 239: (defconst automount-dir-prefix "^/tmp_mnt/" ! 240: "Regexp to match the automounter prefix in a directory name.") ! 241: ! 242: (defun find-file-noselect (filename &optional nowarn) ! 243: "Read file FILENAME into a buffer and return the buffer. ! 244: If a buffer exists visiting FILENAME, return that one, ! 245: but verify that the file has not changed since visited or saved. ! 246: The buffer is not selected, just returned to the caller." ! 247: (setq filename (expand-file-name filename)) ! 248: ;; Get rid of the prefixes added by the automounter. ! 249: (if (and (string-match automount-dir-prefix filename) ! 250: (file-exists-p (file-name-directory ! 251: (substring filename (1- (match-end 0)))))) ! 252: (setq filename (substring filename (1- (match-end 0))))) ! 253: (if (file-directory-p filename) ! 254: (if find-file-run-dired ! 255: (dired-noselect filename) ! 256: (error "%s is a directory." filename)) ! 257: (let ((buf (get-file-buffer filename)) ! 258: error) ! 259: (if buf ! 260: (or nowarn ! 261: (verify-visited-file-modtime buf) ! 262: (cond ((not (file-exists-p filename)) ! 263: (error "File %s no longer exists!" filename)) ! 264: ((yes-or-no-p ! 265: (if (buffer-modified-p buf) ! 266: "File has changed since last visited or saved. Flush your changes? " ! 267: "File has changed since last visited or saved. Read from disk? ")) ! 268: (save-excursion ! 269: (set-buffer buf) ! 270: (revert-buffer t t))))) ! 271: (save-excursion ! 272: (setq buf (create-file-buffer filename)) ! 273: (set-buffer buf) ! 274: (erase-buffer) ! 275: (condition-case () ! 276: (insert-file-contents filename t) ! 277: (file-error ! 278: (setq error t) ! 279: ;; Run find-file-not-found-hooks until one returns non-nil. ! 280: (let ((hooks find-file-not-found-hooks)) ! 281: (while (and hooks ! 282: (not (funcall (car hooks)))) ! 283: (setq hooks (cdr hooks)))))) ! 284: (setq default-directory (file-name-directory filename)) ! 285: (after-find-file error (not nowarn)))) ! 286: buf))) ! 287: ! 288: (defun after-find-file (&optional error warn) ! 289: "Called after finding a file and by the default revert function. ! 290: Sets buffer mode, parses local variables. ! 291: Optional args ERROR and WARN: ERROR non-nil means there was an ! 292: error in reading the file. WARN non-nil means warn if there ! 293: exists an auto-save file more recent than the visited file. ! 294: Finishes by calling the functions in find-file-hooks." ! 295: (setq buffer-read-only (not (file-writable-p buffer-file-name))) ! 296: (if noninteractive ! 297: nil ! 298: (let* (not-serious ! 299: (msg ! 300: (cond ((not buffer-read-only) ! 301: (if (and warn ! 302: (file-newer-than-file-p (make-auto-save-file-name) ! 303: buffer-file-name)) ! 304: "Auto save file is newer; consider M-x recover-file" ! 305: (setq not-serious t) ! 306: (if error "(New file)" nil))) ! 307: ((not error) ! 308: (setq not-serious t) ! 309: "File is write protected") ! 310: ((file-attributes buffer-file-name) ! 311: "File exists, but is read-protected.") ! 312: ((file-attributes (directory-file-name default-directory)) ! 313: "File not found and directory write-protected") ! 314: (t ! 315: "File not found and directory doesn't exist")))) ! 316: (if msg ! 317: (progn ! 318: (message msg) ! 319: (or not-serious (sit-for 1 t))))) ! 320: (if auto-save-default ! 321: (auto-save-mode t))) ! 322: (normal-mode t) ! 323: (mapcar 'funcall find-file-hooks)) ! 324: ! 325: (defun normal-mode (&optional find-file) ! 326: "Choose the major mode for this buffer automatically. ! 327: Also sets up any specified local variables of the file. ! 328: Uses the visited file name, the -*- line, and the local variables spec. ! 329: ! 330: This function is called automatically from `find-file'. In that case, ! 331: if `inhibit-local-variables' is non-`nil' we require confirmation before ! 332: processing a local variables spec. If you run `normal-mode' explicitly, ! 333: confirmation is never required." ! 334: (interactive) ! 335: (or find-file (funcall (or default-major-mode 'fundamental-mode))) ! 336: (condition-case err ! 337: (set-auto-mode) ! 338: (error (message "File mode specification error: %s" ! 339: (prin1-to-string err)))) ! 340: (condition-case err ! 341: (hack-local-variables (not find-file)) ! 342: (error (message "File local-variables error: %s" ! 343: (prin1-to-string err))))) ! 344: ! 345: ;(defvar auto-mode-alist ...) now in loaddefs.el ! 346: (defun set-auto-mode () ! 347: "Select major mode appropriate for current buffer. ! 348: May base decision on visited file name (See variable auto-mode-list) ! 349: or on buffer contents (-*- line or local variables spec), but does not look ! 350: for the \"mode:\" local variable. For that, use hack-local-variables." ! 351: ;; Look for -*-MODENAME-*- or -*- ... mode: MODENAME; ... -*- ! 352: (let (beg end mode) ! 353: (save-excursion ! 354: (goto-char (point-min)) ! 355: (skip-chars-forward " \t\n") ! 356: (if (and (search-forward "-*-" (save-excursion (end-of-line) (point)) t) ! 357: (progn ! 358: (skip-chars-forward " \t") ! 359: (setq beg (point)) ! 360: (search-forward "-*-" (save-excursion (end-of-line) (point)) t)) ! 361: (progn ! 362: (forward-char -3) ! 363: (skip-chars-backward " \t") ! 364: (setq end (point)) ! 365: (goto-char beg) ! 366: (if (search-forward ":" end t) ! 367: (progn ! 368: (goto-char beg) ! 369: (if (let ((case-fold-search t)) ! 370: (search-forward "mode:" end t)) ! 371: (progn ! 372: (skip-chars-forward " \t") ! 373: (setq beg (point)) ! 374: (if (search-forward ";" end t) ! 375: (forward-char -1) ! 376: (goto-char end)) ! 377: (skip-chars-backward " \t") ! 378: (setq mode (buffer-substring beg (point)))))) ! 379: (setq mode (buffer-substring beg end))))) ! 380: (funcall (intern (concat (downcase mode) "-mode"))) ! 381: (let ((alist auto-mode-alist) ! 382: (name buffer-file-name)) ! 383: (let ((case-fold-search (eq system-type 'vax-vms))) ! 384: ;; Remove backup-suffixes from file name. ! 385: (setq name (file-name-sans-versions name)) ! 386: ;; Find first matching alist entry. ! 387: (while (and (not mode) alist) ! 388: (if (string-match (car (car alist)) name) ! 389: (setq mode (cdr (car alist)))) ! 390: (setq alist (cdr alist)))) ! 391: (if mode (funcall mode))))))) ! 392: ! 393: (defun hack-local-variables (&optional force) ! 394: "Parse, and bind or evaluate as appropriate, any local variables ! 395: for current buffer." ! 396: ;; Look for "Local variables:" line in last page. ! 397: (save-excursion ! 398: (goto-char (point-max)) ! 399: (search-backward "\n\^L" (max (- (point-max) 3000) (point-min)) 'move) ! 400: (if (let ((case-fold-search t)) ! 401: (and (search-forward "Local Variables:" nil t) ! 402: (or (not inhibit-local-variables) ! 403: force ! 404: (save-window-excursion ! 405: (switch-to-buffer (current-buffer)) ! 406: (save-excursion ! 407: (beginning-of-line) ! 408: (set-window-start (selected-window) (point))) ! 409: (y-or-n-p (format "Set local variables as specified at end of %s? " ! 410: (file-name-nondirectory buffer-file-name))))))) ! 411: (let ((continue t) ! 412: prefix prefixlen suffix beg) ! 413: ;; The prefix is what comes before "local variables:" in its line. ! 414: ;; The suffix is what comes after "local variables:" in its line. ! 415: (skip-chars-forward " \t") ! 416: (or (eolp) ! 417: (setq suffix (buffer-substring (point) ! 418: (progn (end-of-line) (point))))) ! 419: (goto-char (match-beginning 0)) ! 420: (or (bolp) ! 421: (setq prefix ! 422: (buffer-substring (point) ! 423: (progn (beginning-of-line) (point))))) ! 424: (if prefix (setq prefixlen (length prefix) ! 425: prefix (regexp-quote prefix))) ! 426: (if suffix (setq suffix (concat (regexp-quote suffix) "$"))) ! 427: (while continue ! 428: ;; Look at next local variable spec. ! 429: (if selective-display (re-search-forward "[\n\C-m]") ! 430: (forward-line 1)) ! 431: ;; Skip the prefix, if any. ! 432: (if prefix ! 433: (if (looking-at prefix) ! 434: (forward-char prefixlen) ! 435: (error "Local variables entry is missing the prefix"))) ! 436: ;; Find the variable name; strip whitespace. ! 437: (skip-chars-forward " \t") ! 438: (setq beg (point)) ! 439: (skip-chars-forward "^:\n") ! 440: (if (eolp) (error "Missing colon in local variables entry")) ! 441: (skip-chars-backward " \t") ! 442: (let* ((str (buffer-substring beg (point))) ! 443: (var (read str)) ! 444: val) ! 445: ;; Setting variable named "end" means end of list. ! 446: (if (string-equal (downcase str) "end") ! 447: (setq continue nil) ! 448: ;; Otherwise read the variable value. ! 449: (skip-chars-forward "^:") ! 450: (forward-char 1) ! 451: (setq val (read (current-buffer))) ! 452: (skip-chars-backward "\n") ! 453: (skip-chars-forward " \t") ! 454: (or (if suffix (looking-at suffix) (eolp)) ! 455: (error "Local variables entry is terminated incorrectly")) ! 456: ;; Set the variable. "Variables" mode and eval are funny. ! 457: (cond ((eq var 'mode) ! 458: (funcall (intern (concat (downcase (symbol-name val)) ! 459: "-mode")))) ! 460: ((eq var 'force) nil) ! 461: ((eq var 'ignore-local-eval) ! 462: nil) ! 463: ((eq var 'eval) ! 464: (if (or (and ignore-local-eval (not force)) ! 465: (string= (user-login-name) "root")) ! 466: (message "Ignoring `eval:' in file's local variables") ! 467: (eval val))) ! 468: (t (make-local-variable var) ! 469: (set var val)))))))))) ! 470: ! 471: (defun set-visited-file-name (filename) ! 472: "Change name of file visited in current buffer to FILENAME. ! 473: The next time the buffer is saved it will go in the newly specified file. ! 474: nil or empty string as argument means make buffer not be visiting any file. ! 475: Remember to delete the initial contents of the minibuffer ! 476: if you wish to pass an empty string as the argument." ! 477: (interactive "FSet visited file name: ") ! 478: (if filename ! 479: (setq filename ! 480: (if (string-equal filename "") ! 481: nil ! 482: (expand-file-name filename)))) ! 483: (or (equal filename buffer-file-name) ! 484: (null filename) ! 485: (progn ! 486: (lock-buffer filename) ! 487: (unlock-buffer))) ! 488: (if filename ! 489: (let ((new-name (file-name-nondirectory filename))) ! 490: (if (string= new-name "") ! 491: (error "Empty file name")) ! 492: (if (file-directory-p filename) ! 493: (error "File %s is a directory" filename)) ! 494: (if (eq system-type 'vax-vms) ! 495: (setq new-name (downcase new-name))) ! 496: (setq buffer-file-name filename) ! 497: (setq default-directory (file-name-directory buffer-file-name)) ! 498: (or (get-buffer new-name) (rename-buffer new-name))) ! 499: (setq buffer-file-name nil)) ! 500: (setq buffer-backed-up nil) ! 501: (clear-visited-file-modtime) ! 502: ;; So that C-x C-w after ftp-find-file ! 503: ;; writes an ordinary local file in the ordinary way. ! 504: (kill-local-variable 'write-file-hooks) ! 505: ;; So that revert works normally after theat C-x C-w. ! 506: (kill-local-variable 'revert-buffer-function) ! 507: ;; Rename the auto-save file to go with the new visited name. ! 508: ;; If auto-save was not already on, turn it on if appropriate. ! 509: (if buffer-auto-save-file-name ! 510: (rename-auto-save-file) ! 511: (auto-save-mode (and buffer-file-name auto-save-default))) ! 512: (if buffer-file-name ! 513: (set-buffer-modified-p t))) ! 514: ! 515: (defun write-file (filename) ! 516: "Write current buffer into file FILENAME. ! 517: Makes buffer visit that file, and marks it not modified." ! 518: (interactive "FWrite file: ") ! 519: (or (null filename) (string-equal filename "") ! 520: (set-visited-file-name filename)) ! 521: (set-buffer-modified-p t) ! 522: (save-buffer)) ! 523: ! 524: (defun backup-buffer () ! 525: "Make a backup of the disk file visited by the current buffer, if appropriate. ! 526: This is normally done before saving the buffer the first time. ! 527: If the value is non-nil, it is the result of `file-modes' on the original file; ! 528: this means that the caller, after saving the buffer, should change the modes ! 529: of the new file to agree with the old modes." ! 530: (and make-backup-files ! 531: (not buffer-backed-up) ! 532: (file-exists-p buffer-file-name) ! 533: (memq (aref (elt (file-attributes buffer-file-name) 8) 0) ! 534: '(?- ?l)) ! 535: (or (< (length buffer-file-name) 5) ! 536: (not (string-equal "/tmp/" (substring buffer-file-name 0 5)))) ! 537: (condition-case () ! 538: (let* ((backup-info (find-backup-file-name buffer-file-name)) ! 539: (backupname (car backup-info)) ! 540: (targets (cdr backup-info)) ! 541: setmodes) ! 542: ; (if (file-directory-p buffer-file-name) ! 543: ; (error "Cannot save buffer in directory %s" buffer-file-name)) ! 544: (condition-case () ! 545: (if (or file-precious-flag ! 546: (file-symlink-p buffer-file-name) ! 547: backup-by-copying ! 548: (and backup-by-copying-when-linked ! 549: (> (file-nlinks buffer-file-name) 1)) ! 550: (and backup-by-copying-when-mismatch ! 551: (let ((attr (file-attributes buffer-file-name))) ! 552: (or (nth 9 attr) ! 553: (/= (nth 2 attr) (user-uid)))))) ! 554: (copy-file buffer-file-name backupname t t) ! 555: (condition-case () ! 556: (delete-file backupname) ! 557: (file-error nil)) ! 558: (rename-file buffer-file-name backupname t) ! 559: (setq setmodes (file-modes backupname))) ! 560: (file-error ! 561: ;; If trouble writing the backup, write it in ~. ! 562: (setq backupname (expand-file-name "~/%backup%~")) ! 563: (message "Cannot write backup file; backing up in ~/%%backup%%~") ! 564: (sleep-for 1) ! 565: (condition-case () ! 566: (delete-file backupname) ! 567: (file-error nil)) ! 568: (copy-file buffer-file-name backupname t t))) ! 569: (setq buffer-backed-up t) ! 570: (if (and targets ! 571: (or trim-versions-without-asking ! 572: (y-or-n-p (format "Delete excess backup versions of %s? " ! 573: buffer-file-name)))) ! 574: (while targets ! 575: (condition-case () ! 576: (delete-file (car targets)) ! 577: (file-error nil)) ! 578: (setq targets (cdr targets)))) ! 579: setmodes) ! 580: (file-error nil)))) ! 581: ! 582: (defun file-name-sans-versions (name) ! 583: "Return FILENAME sans backup versions or strings. ! 584: This is a separate procedure so your site-init or startup file can ! 585: redefine it." ! 586: (substring name 0 ! 587: (if (eq system-type 'vax-vms) ! 588: (or (string-match ";[0-9]*\\'" name) ! 589: (and (string-match "\\." name (string-match "[]>]" name)) ! 590: (string-match "\\.[0-9]*\\'" name (match-end 0)))) ! 591: (string-match "\\(\\.~[0-9]+\\)?~\\'" name)))) ! 592: ! 593: (defun make-backup-file-name (file) ! 594: "Create the non-numeric backup file name for FILE. ! 595: This is a separate function so you can redefine it for customization." ! 596: (concat file "~")) ! 597: ! 598: (defun backup-file-name-p (file) ! 599: "Return non-nil if FILE is a backup file name (numeric or not). ! 600: This is a separate function so you can redefine it for customization. ! 601: You may need to redefine file-name-sans-versions as well." ! 602: (string-match "~$" file)) ! 603: ! 604: ;; I believe there is no need to alter this behavior for VMS; ! 605: ;; since backup files are not made on VMS, it should not get called. ! 606: (defun find-backup-file-name (fn) ! 607: "Find a file name for a backup file, and suggestions for deletions. ! 608: Value is a list whose car is the name for the backup file ! 609: and whose cdr is a list of old versions to consider deleting now." ! 610: (if (eq version-control 'never) ! 611: (list (make-backup-file-name fn)) ! 612: (let* ((base-versions (concat (file-name-nondirectory fn) ".~")) ! 613: (bv-length (length base-versions)) ! 614: (possibilities (file-name-all-completions ! 615: base-versions ! 616: (file-name-directory fn))) ! 617: (versions (sort (mapcar 'backup-extract-version possibilities) ! 618: '<)) ! 619: (high-water-mark (apply 'max (cons 0 versions))) ! 620: (deserve-versions-p ! 621: (or version-control ! 622: (> high-water-mark 0))) ! 623: (number-to-delete (- (length versions) ! 624: ;; -1 compensates for the backup ! 625: ;; we are about to make. ! 626: kept-old-versions kept-new-versions -1))) ! 627: (if (not deserve-versions-p) ! 628: (list (make-backup-file-name fn)) ! 629: (cons (concat fn ".~" (int-to-string (1+ high-water-mark)) "~") ! 630: (if (and (> number-to-delete 0) ! 631: ;; Delete nothing if there is overflow ! 632: ;; in the number of versions to keep. ! 633: (>= (+ kept-new-versions kept-old-versions -1) 0)) ! 634: (mapcar (function (lambda (n) ! 635: (concat fn ".~" ! 636: (int-to-string n) "~"))) ! 637: (let ((v (nthcdr kept-old-versions versions))) ! 638: (rplacd (nthcdr (1- number-to-delete) v) ()) ! 639: v)))))))) ! 640: ! 641: (defun backup-extract-version (fn) ! 642: (if (and (string-match "[0-9]+~$" fn bv-length) ! 643: (= (match-beginning 0) bv-length)) ! 644: (string-to-int (substring fn bv-length -1)) ! 645: 0)) ! 646: ! 647: (defun file-nlinks (filename) ! 648: "Return number of names file FILENAME has." ! 649: (car (cdr (file-attributes filename)))) ! 650: ! 651: (defun save-buffer (&optional args) ! 652: "Save current buffer in visited file if modified. Versions described below. ! 653: ! 654: By default, makes the previous version into a backup file ! 655: if previously requested or if this is the first save. ! 656: With 1 or 3 \\[universal-argument]'s, marks this version ! 657: to become a backup when the next save is done. ! 658: With 2 or 3 \\[universal-argument]'s, ! 659: unconditionally makes the previous version into a backup file. ! 660: With argument of 0, never makes the previous version into a backup file. ! 661: ! 662: If a file's name is FOO, the names of its numbered backup versions are ! 663: FOO.~i~ for various integers i. A non-numbered backup file is called FOO~. ! 664: Numeric backups (rather than FOO~) will be made if value of ! 665: `version-control' is not the atom `never' and either there are already ! 666: numeric versions of the file being backed up, or `version-control' is ! 667: non-nil. ! 668: We don't want excessive versions piling up, so there are variables ! 669: `kept-old-versions', which tells Emacs how many oldest versions to keep, ! 670: and `kept-new-versions', which tells how many newest versions to keep. ! 671: Defaults are 2 old versions and 2 new. ! 672: `dired-kept-versions' controls dired's clean-directory (.) command. ! 673: If `trim-versions-without-asking' is nil, system will query user ! 674: before trimming versions. Otherwise it does it silently." ! 675: (interactive "p") ! 676: (let ((modp (buffer-modified-p)) ! 677: (large (> (buffer-size) 50000)) ! 678: (make-backup-files (and make-backup-files (not (eq args 0))))) ! 679: (and modp (memq args '(16 64)) (setq buffer-backed-up nil)) ! 680: (if (and modp large) (message "Saving file %s..." (buffer-file-name))) ! 681: (basic-save-buffer) ! 682: (and modp (memq args '(4 64)) (setq buffer-backed-up nil)))) ! 683: ! 684: (defun delete-auto-save-file-if-necessary () ! 685: "Delete the auto-save filename for the current buffer (if it has one) ! 686: if variable delete-auto-save-files is non-nil." ! 687: (and buffer-auto-save-file-name delete-auto-save-files ! 688: (not (string= buffer-file-name buffer-auto-save-file-name)) ! 689: (progn ! 690: (condition-case () ! 691: (delete-file buffer-auto-save-file-name) ! 692: (file-error nil)) ! 693: (set-buffer-auto-saved)))) ! 694: ! 695: (defun basic-save-buffer () ! 696: "Save the current buffer in its visited file, if it has been modified." ! 697: (interactive) ! 698: (if (buffer-modified-p) ! 699: (let (setmodes tempsetmodes) ! 700: (or buffer-file-name ! 701: (progn ! 702: (setq buffer-file-name ! 703: (expand-file-name (read-file-name "File to save in: ") nil) ! 704: default-directory (file-name-directory buffer-file-name)) ! 705: (auto-save-mode auto-save-default))) ! 706: (if (not (file-writable-p buffer-file-name)) ! 707: (if (yes-or-no-p ! 708: (format "File %s is write-protected; try to save anyway? " ! 709: (file-name-nondirectory buffer-file-name))) ! 710: (setq tempsetmodes t) ! 711: (error ! 712: "Attempt to save to a file which you aren't allowed to write"))) ! 713: (or (verify-visited-file-modtime (current-buffer)) ! 714: (not (file-exists-p buffer-file-name)) ! 715: (yes-or-no-p ! 716: "Disk file has changed since visited or saved. Save anyway? ") ! 717: (error "Save not confirmed")) ! 718: (or buffer-backed-up ! 719: (setq setmodes (backup-buffer))) ! 720: (save-restriction ! 721: (widen) ! 722: (and (> (point-max) 1) ! 723: (/= (char-after (1- (point-max))) ?\n) ! 724: (or (eq require-final-newline t) ! 725: (and require-final-newline ! 726: (yes-or-no-p ! 727: (format "Buffer %s does not end in newline. Add one? " ! 728: (buffer-name))))) ! 729: (save-excursion ! 730: (goto-char (point-max)) ! 731: (insert ?\n))) ! 732: (let ((hooks write-file-hooks) ! 733: (done nil)) ! 734: (while (and hooks ! 735: (not (setq done (funcall (car hooks))))) ! 736: (setq hooks (cdr hooks))) ! 737: ;; If a hook returned t, file is already "written". ! 738: (cond (done (setq setmodes nil)) ! 739: ((not done) ! 740: (if file-precious-flag ! 741: ;; If file is precious, rename it away before ! 742: ;; overwriting it. ! 743: (let ((rename t) nodelete ! 744: (file (concat buffer-file-name "#"))) ! 745: (condition-case () ! 746: (progn (rename-file buffer-file-name file t) ! 747: (setq setmodes (file-modes file))) ! 748: (file-error (setq rename nil nodelete t))) ! 749: (unwind-protect ! 750: (progn (clear-visited-file-modtime) ! 751: (write-region (point-min) (point-max) ! 752: buffer-file-name nil t) ! 753: (setq rename nil)) ! 754: ;; If rename is still t, writing failed. ! 755: ;; So rename the old file back to original name, ! 756: (if rename ! 757: (progn ! 758: (rename-file file buffer-file-name t) ! 759: (clear-visited-file-modtime)) ! 760: ;; Otherwise we don't need the original file, ! 761: ;; so flush it. Unless we already lost it. ! 762: (or nodelete ! 763: (condition-case () ! 764: (delete-file file) ! 765: (error nil)))))) ! 766: ;; If file not writable, see if we can make it writable ! 767: ;; temporarily while we write it. ! 768: ;; But no need to do so if we have just backed it up ! 769: ;; (setmodes is set) because that says we're superseding. ! 770: ;; Systems with version numbers need not do this. ! 771: (if (eq system-type 'vax-vms) ! 772: (setq setmodes nil tempsetmodes nil)) ! 773: (cond ((and tempsetmodes (not setmodes)) ! 774: ;; Change the mode back, after writing. ! 775: (setq setmodes (file-modes buffer-file-name)) ! 776: (set-file-modes buffer-file-name 511))) ! 777: (write-region (point-min) (point-max) ! 778: buffer-file-name nil t))))) ! 779: (if setmodes ! 780: (condition-case () ! 781: (set-file-modes buffer-file-name setmodes) ! 782: (error nil)))) ! 783: (delete-auto-save-file-if-necessary)) ! 784: (message "(No changes need to be saved)"))) ! 785: ! 786: (defun save-some-buffers (&optional arg exiting) ! 787: "Save some modified file-visiting buffers. Asks user about each one. ! 788: Optional argument (the prefix) non-nil means save all with no questions. ! 789: Optional second argument EXITING means ask about certain non-file buffers ! 790: as well as about file buffers." ! 791: (interactive "P") ! 792: (let (considered (list (buffer-list))) ! 793: (while list ! 794: (let ((buffer (car list))) ! 795: (and (buffer-modified-p buffer) ! 796: (save-excursion ! 797: (set-buffer buffer) ! 798: (and ! 799: (or buffer-file-name ! 800: (and exiting buffer-offer-save (> (buffer-size) 0))) ! 801: (setq considered t) ! 802: (or arg ! 803: (y-or-n-p (if buffer-file-name ! 804: (format "Save file %s? " ! 805: buffer-file-name) ! 806: (format "Save buffer %s? " (buffer-name))))) ! 807: (condition-case () ! 808: (save-buffer) ! 809: (error nil)))))) ! 810: (setq list (cdr list))) ! 811: (and save-abbrevs abbrevs-changed ! 812: (progn ! 813: (setq considered t) ! 814: (if (or arg ! 815: (y-or-n-p (format "Save abbrevs in %s? " abbrev-file-name))) ! 816: (write-abbrev-file nil)) ! 817: ;; Don't keep bothering user if he says no. ! 818: (setq abbrevs-changed nil))) ! 819: (if considered ! 820: (message "") ! 821: (message "(No files need saving)")))) ! 822: ! 823: (defun not-modified () ! 824: "Mark current buffer as unmodified, not needing to be saved." ! 825: (interactive) ! 826: (message "Modification-flag cleared") ! 827: (set-buffer-modified-p nil)) ! 828: ! 829: (defun toggle-read-only () ! 830: "Change whether this buffer is visiting its file read-only." ! 831: (interactive) ! 832: (setq buffer-read-only (not buffer-read-only)) ! 833: ;; Force mode-line redisplay ! 834: (set-buffer-modified-p (buffer-modified-p))) ! 835: ! 836: (defun insert-file (filename) ! 837: "Insert contents of file FILENAME into buffer after point. ! 838: Set mark after the inserted text." ! 839: (interactive "fInsert file: ") ! 840: (let ((tem (insert-file-contents filename))) ! 841: (push-mark (+ (point) (car (cdr tem)))))) ! 842: ! 843: (defun append-to-file (start end filename) ! 844: "Append the contents of the region to the end of file FILENAME. ! 845: When called from a function, expects three arguments, ! 846: START, END and FILENAME. START and END are buffer positions ! 847: saying what text to write." ! 848: (interactive "r\nFAppend to file: ") ! 849: (write-region start end filename t)) ! 850: ! 851: (defvar revert-buffer-function nil ! 852: "Function to use to revert this buffer, or nil to do the default.") ! 853: ! 854: (defun revert-buffer (&optional arg noconfirm) ! 855: "Replace the buffer text with the text of the visited file on disk. ! 856: This undoes all changes since the file was visited or saved. ! 857: If latest auto-save file is more recent than the visited file, ! 858: asks user whether to use that instead. ! 859: First argument (optional) non-nil means don't offer to use auto-save file. ! 860: This is the prefix arg when called interactively. ! 861: ! 862: Second argument (optional) non-nil means don't ask for confirmation at all. ! 863: ! 864: If revert-buffer-function's value is non-nil, it is called to do the work." ! 865: (interactive "P") ! 866: (if revert-buffer-function ! 867: (funcall revert-buffer-function arg noconfirm) ! 868: (let* ((opoint (point)) ! 869: (auto-save-p (and (null arg) (recent-auto-save-p) ! 870: buffer-auto-save-file-name ! 871: (file-readable-p buffer-auto-save-file-name) ! 872: (y-or-n-p ! 873: "Buffer has been auto-saved recently. Revert from auto-save file? "))) ! 874: (file-name (if auto-save-p ! 875: buffer-auto-save-file-name ! 876: buffer-file-name))) ! 877: (cond ((null file-name) ! 878: (error "Buffer does not seem to be associated with any file")) ! 879: ((not (file-exists-p file-name)) ! 880: (error "File %s no longer exists!" file-name)) ! 881: ((or noconfirm ! 882: (yes-or-no-p (format "Revert buffer from file %s? " ! 883: file-name))) ! 884: ;; If file was backed up but has changed since, ! 885: ;; we shd make another backup. ! 886: (and (not auto-save-p) ! 887: (not (verify-visited-file-modtime (current-buffer))) ! 888: (setq buffer-backed-up nil)) ! 889: ;; Discard all the undo information. ! 890: (or (eq buffer-undo-list t) ! 891: (setq buffer-undo-list nil)) ! 892: (let ((buffer-read-only nil) ! 893: ;; Don't record undo info for the revert itself. ! 894: ;; Doing so chews up too much storage. ! 895: (buffer-undo-list t)) ! 896: ;; Bind buffer-file-name to nil ! 897: ;; so that we don't try to lock the file. ! 898: (let ((buffer-file-name nil)) ! 899: (or auto-save-p ! 900: (unlock-buffer)) ! 901: (erase-buffer)) ! 902: (insert-file-contents file-name (not auto-save-p))) ! 903: (goto-char (min opoint (point-max))) ! 904: (after-find-file nil) ! 905: t))))) ! 906: ! 907: (defun recover-file (file) ! 908: "Visit file FILE, but get contents from its last auto-save file." ! 909: (interactive "FRecover file: ") ! 910: (setq file (expand-file-name file)) ! 911: (if (auto-save-file-name-p file) (error "%s is an auto-save file" file)) ! 912: (let ((file-name (let ((buffer-file-name file)) ! 913: (make-auto-save-file-name)))) ! 914: (cond ((not (file-newer-than-file-p file-name file)) ! 915: (error "Auto-save file %s not current" file-name)) ! 916: ((save-window-excursion ! 917: (if (not (eq system-type 'vax-vms)) ! 918: (with-output-to-temp-buffer "*Directory*" ! 919: (buffer-flush-undo standard-output) ! 920: (call-process "ls" nil standard-output nil ! 921: "-l" file file-name))) ! 922: (yes-or-no-p (format "Recover auto save file %s? " file-name))) ! 923: (switch-to-buffer (find-file-noselect file t)) ! 924: (let ((buffer-read-only nil)) ! 925: (erase-buffer) ! 926: (insert-file-contents file-name nil)) ! 927: (after-find-file nil)) ! 928: (t (error "Recover-file cancelled.")))) ! 929: (setq buffer-auto-save-file-name nil) ! 930: (message "Auto-save off in this buffer till you do M-x auto-save-mode.")) ! 931: ! 932: (defun kill-some-buffers () ! 933: "For each buffer, ask whether to kill it." ! 934: (interactive) ! 935: (let ((list (buffer-list))) ! 936: (while list ! 937: (let* ((buffer (car list)) ! 938: (name (buffer-name buffer))) ! 939: (and (not (string-equal name "")) ! 940: (/= (aref name 0) ? ) ! 941: (yes-or-no-p ! 942: (format "Buffer %s %s. Kill? " ! 943: name ! 944: (if (buffer-modified-p buffer) ! 945: "HAS BEEN EDITED" "is unmodified"))) ! 946: (kill-buffer buffer))) ! 947: (setq list (cdr list))))) ! 948: ! 949: (defun auto-save-mode (arg) ! 950: "Toggle auto-saving of contents of current buffer. ! 951: With arg, turn auto-saving on if arg is positive, else off." ! 952: (interactive "P") ! 953: (setq buffer-auto-save-file-name ! 954: (and (if (null arg) ! 955: (not buffer-auto-save-file-name) ! 956: (or (eq arg t) (listp arg) (and (integerp arg) (> arg 0)))) ! 957: (if (and buffer-file-name auto-save-visited-file-name ! 958: (not buffer-read-only)) ! 959: buffer-file-name ! 960: (make-auto-save-file-name)))) ! 961: (if (interactive-p) ! 962: (message "Auto-save %s (in this buffer)" ! 963: (if buffer-auto-save-file-name "on" "off"))) ! 964: buffer-auto-save-file-name) ! 965: ! 966: (defun rename-auto-save-file () ! 967: "Adjust current buffer's auto save file name for current conditions. ! 968: Also rename any existing auto save file." ! 969: (let ((osave buffer-auto-save-file-name)) ! 970: (setq buffer-auto-save-file-name ! 971: (make-auto-save-file-name)) ! 972: (if (and osave buffer-auto-save-file-name ! 973: (not (string= buffer-auto-save-file-name buffer-file-name)) ! 974: (not (string= buffer-auto-save-file-name osave)) ! 975: (file-exists-p osave)) ! 976: (rename-file osave buffer-auto-save-file-name t)))) ! 977: ! 978: (defun make-auto-save-file-name () ! 979: "Return file name to use for auto-saves of current buffer. ! 980: Does not consider auto-save-visited-file-name; that is checked ! 981: before calling this function. ! 982: You can redefine this for customization. ! 983: See also auto-save-file-name-p." ! 984: (if buffer-file-name ! 985: (concat (file-name-directory buffer-file-name) ! 986: "#" ! 987: (file-name-nondirectory buffer-file-name) ! 988: "#") ! 989: (expand-file-name (concat "#%" (buffer-name) "#")))) ! 990: ! 991: (defun auto-save-file-name-p (filename) ! 992: "Return non-nil if FILENAME can be yielded by make-auto-save-file-name. ! 993: FILENAME should lack slashes. ! 994: You can redefine this for customization." ! 995: (string-match "^#.*#$" filename)) ! 996: ! 997: (defconst list-directory-brief-switches "-CF" ! 998: "*Switches for list-directory to pass to `ls' for brief listing,") ! 999: (defconst list-directory-verbose-switches "-l" ! 1000: "*Switches for list-directory to pass to `ls' for verbose listing,") ! 1001: ! 1002: (defun list-directory (dirname &optional verbose) ! 1003: "Display a list of files in or matching DIRNAME, a la `ls'. ! 1004: DIRNAME is globbed by the shell if necessary. ! 1005: Prefix arg (second arg if noninteractive) means supply -l switch to `ls'. ! 1006: Actions controlled by variables list-directory-brief-switches ! 1007: and list-directory-verbose-switches." ! 1008: (interactive (let ((pfx current-prefix-arg)) ! 1009: (list (read-file-name (if pfx "List directory (verbose): " ! 1010: "List directory (brief): ") ! 1011: nil default-directory nil) ! 1012: pfx))) ! 1013: (let ((switches (if verbose list-directory-verbose-switches ! 1014: list-directory-brief-switches)) ! 1015: full-dir-p) ! 1016: (or dirname (setq dirname default-directory)) ! 1017: (if (file-directory-p dirname) ! 1018: (progn ! 1019: (setq full-dir-p t) ! 1020: (or (string-match "/$" dirname) ! 1021: (setq dirname (concat dirname "/"))))) ! 1022: (setq dirname (expand-file-name dirname)) ! 1023: (with-output-to-temp-buffer "*Directory*" ! 1024: (buffer-flush-undo standard-output) ! 1025: (princ "Directory ") ! 1026: (princ dirname) ! 1027: (terpri) ! 1028: (if full-dir-p ! 1029: (call-process "ls" nil standard-output nil ! 1030: switches dirname) ! 1031: (let ((default-directory (file-name-directory dirname))) ! 1032: (call-process shell-file-name nil standard-output nil ! 1033: "-c" (concat "exec ls " ! 1034: switches " " ! 1035: (file-name-nondirectory dirname)))))))) ! 1036: ! 1037: (defun save-buffers-kill-emacs (&optional arg) ! 1038: "Offer to save each buffer, then kill this Emacs fork. ! 1039: With prefix arg, silently save all file-visiting buffers, then kill." ! 1040: (interactive "P") ! 1041: (save-some-buffers arg t) ! 1042: (and (or (not (memq t (mapcar (function ! 1043: (lambda (buf) (and (buffer-file-name buf) ! 1044: (buffer-modified-p buf)))) ! 1045: (buffer-list)))) ! 1046: (yes-or-no-p "Modified buffers exist; exit anyway? ")) ! 1047: (or (not (fboundp 'process-list)) ! 1048: ;; process-list is not defined on VMS. ! 1049: (let ((processes (process-list)) ! 1050: active) ! 1051: (while processes ! 1052: (and (memq (process-status (car processes)) '(run stop open)) ! 1053: (let ((val (process-kill-without-query (car processes)))) ! 1054: (process-kill-without-query (car processes) val) ! 1055: val) ! 1056: (setq active t)) ! 1057: (setq processes (cdr processes))) ! 1058: (or (not active) ! 1059: (yes-or-no-p "Active processes exist; kill them and exit anyway? ")))) ! 1060: (kill-emacs))) ! 1061: ! 1062: (define-key ctl-x-map "\C-f" 'find-file) ! 1063: (define-key ctl-x-map "\C-q" 'toggle-read-only) ! 1064: (define-key ctl-x-map "\C-r" 'find-file-read-only) ! 1065: (define-key ctl-x-map "\C-v" 'find-alternate-file) ! 1066: (define-key ctl-x-map "\C-s" 'save-buffer) ! 1067: (define-key ctl-x-map "s" 'save-some-buffers) ! 1068: (define-key ctl-x-map "\C-w" 'write-file) ! 1069: (define-key ctl-x-map "i" 'insert-file) ! 1070: (define-key esc-map "~" 'not-modified) ! 1071: (define-key ctl-x-map "\C-d" 'list-directory) ! 1072: (define-key ctl-x-map "\C-c" 'save-buffers-kill-emacs) ! 1073: ! 1074: (defvar ctl-x-4-map (make-keymap) ! 1075: "Keymap for subcommands of C-x 4") ! 1076: (fset 'ctl-x-4-prefix ctl-x-4-map) ! 1077: (define-key ctl-x-map "4" 'ctl-x-4-prefix) ! 1078: (define-key ctl-x-4-map "f" 'find-file-other-window) ! 1079: (define-key ctl-x-4-map "\C-f" 'find-file-other-window) ! 1080: (define-key ctl-x-4-map "b" 'switch-to-buffer-other-window)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.