;; @(#) pushd.el -- defining default directories for Emacs ;; Copyright (C) 1997, Robert Harlander. All rights reserved. ;; This file is intended to be used with GNU Emacs. ;; 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 2, 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. ;; 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, 675 Mass Ave, Cambridge, MA 02139, USA. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ;; pushd.el ;; ;; ;; ;; Version 1.4 (Nov 6, 2001) ;; ;; ;; ;; written by rh ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ;; DESCRIPTION: ;; ;; The aim of this program is to make finding of files more convenient. ;; ;; If you are working mainly in a finite number of ;; ;; different directories, you may add these directories to pushd-list ;; ;; by typing M-x pd. This will prompt you for some path, which will ;; ;; then be added. The ordinary find-file will usually prompt you with ;; ;; the current buffers directory, and by typing , it will start ;; ;; 'dired' with this directory. pushd-find-file will also prompt you ;; ;; with the current buffers directory. But by typing , it will ;; ;; switch to the next entry in pushd-list. The same is true for ;; ;; pushd-insert-file and pushd-find-file-read-only. ;; ;; ;; ;; ;; ;; EXAMPLE: ;; ;; Your current default directory is /home/you/dir1/. Now you type M-x ;; ;; pd, which prompts you with /home/you/dir1/. Change this to ;; ;; /home/you/dir2/. Then . This adds /home/you/dir2/ to ;; ;; pushd-list and also changes the default directory to this path. ;; ;; You may repeat this for an arbitrary number of directories, ;; ;; /home/you/dir2/subdir1/, ... Typing M-x pushd-find-file afterwards ;; ;; again prompts you with the current default directory, but by typing ;; ;; , it spools through all directories previously added to ;; ;; pushd-list. That's great. ;; ;; ;; ;; ;; ;; INSTALLATION: ;; ;; copy this file to your load-path and add the following lines to your ;; ;; .emacs: ;; ;; ;; ;; (load "pushd") ;; ;; (global-set-key C-x C-f 'pushd-find-file) ;; ;; (global-set-key C-x C-i 'pushd-insert-file) ;; ;; (global-set-key C-x C-r 'pushd-find-file-read-only) ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ;; CHANGES: ;; ;; - Nov 06, 2001 (rh): some serious bug fixes: ;; ;; now the default-directory is not affected any longer by ;; ;; functions of pushd.el ;; ;; - Oct 29, 2001 (rh): pd-clean-pd-list added ;; ;; - Jun 29 (rh): print-pushd-list added ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; PLEASE DEFINE THE FOLLOWING VARIABLES: ;; ;; where do you put your Elisp-files? ;; (defvar pd-lisp-dir "~/.elisp/") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defvar pushd-list nil "List of frequently used directories. To be filled with M-x pd. See pushd.el for further information." ) (defvar pd-default-directory) (defvar pushd-always-ask nil) (defvar pushd-tmp-list) (defvar user-prompt) (defvar pushd-file) (defvar pd-buffer-file-name) (defvar pushd-next-dir) (defvar i) (defvar outlist) (defun pushd-find-file () "" (interactive) (setq pd-default-directory (expand-file-name default-directory)) (if (not (member pd-default-directory pushd-list)) (setq pushd-tmp-list (cons pd-default-directory pushd-list)) (setq pushd-tmp-list pushd-list)) (while (not (equal pd-default-directory (car pushd-tmp-list))) (progn (setq pushd-tmp-list (rotate pushd-tmp-list)))) (setq user-prompt "Find file: ") (setq pushd-next-dir (car pushd-tmp-list)) (setq pushd-file (read-file-name user-prompt pushd-next-dir)) (if (not buffer-file-name) (setq pd-buffer-file-name default-directory) (setq pd-buffer-file-name buffer-file-name)) (while (or (equal (expand-file-name pushd-file) (expand-file-name pd-buffer-file-name)) (equal (expand-file-name pushd-file) (expand-file-name pushd-next-dir))) (progn (setq pushd-tmp-list (rotate pushd-tmp-list)) (setq pushd-next-dir (car pushd-tmp-list)) (setq pushd-file (read-file-name user-prompt pushd-next-dir))) ) (find-file pushd-file) (setq def-dir (expand-file-name default-directory)) (if (and pushd-always-ask (not (member def-dir pushd-list)) (y-or-n-p (concat "Add " def-dir " to pd-list? "))) (setq pushd-list (cons (expand-file-name def-dir) pushd-list))) ) (defun pushd-find-file-read-only () "" (interactive) (setq pd-default-directory (expand-file-name default-directory)) (if (not (member pd-default-directory pushd-list)) (setq pushd-tmp-list (cons pd-default-directory pushd-list)) (setq pushd-tmp-list pushd-list)) (setq user-prompt "Find file read-only: ") (setq pushd-file (read-file-name user-prompt)) (if (not buffer-file-name) (setq pd-buffer-file-name default-directory) (setq pd-buffer-file-name buffer-file-name)) (while (or (equal (expand-file-name pushd-file) (expand-file-name pd-buffer-file-name)) (equal (expand-file-name pushd-file) (expand-file-name default-directory))) (progn (setq pushd-tmp-list (rotate pushd-tmp-list)) (setq pushd-next-dir (car pushd-tmp-list)) (setq pushd-file (read-file-name user-prompt pushd-next-dir))) ) (find-file-read-only pushd-file) ) (defun pushd-insert-file () "" (interactive) (setq pd-default-directory (expand-file-name default-directory)) (if (not (member pd-default-directory pushd-list)) (setq pushd-tmp-list (cons pd-default-directory pushd-list)) (setq pushd-tmp-list pushd-list)) (setq user-prompt "Insert file: ") (setq pushd-file (read-file-name user-prompt)) (if (not buffer-file-name) (setq pd-buffer-file-name default-directory)) (if buffer-file-name (setq pd-buffer-file-name buffer-file-name)) (while (or (equal (expand-file-name pushd-file) (expand-file-name pd-buffer-file-name)) (equal (expand-file-name pushd-file) (expand-file-name default-directory))) (progn (setq pushd-tmp-list (rotate pushd-tmp-list)) (setq pushd-next-dir (car pushd-tmp-list)) (setq pushd-file (read-file-name user-prompt pushd-next-dir))) ) (insert-file pushd-file) ) (defun print-pushd-list () "" (interactive) (with-output-to-temp-buffer "*Help*" (princ "\npushd-list is:\n\n") (print-elements-of-list pushd-list))) (defun pd-this-dir () "" (interactive) (if (not (member (expand-file-name default-directory) pushd-list)) (progn (pd default-directory) (pd-save-pushd-list) (message (concat "Added " (directory-file-name (abbreviate-file-name default-directory)) " to pushd-list.")) ) ) ) (defun popd-this-dir () "" (interactive) (popd default-directory) ) (defun pd (dir) (interactive "DAdd to pushd-list: ") (setq ldir (expand-file-name dir)) (if (not (file-directory-p ldir)) (message "%s" (print (concat dir " is not a directory."))) (if (eq (string-match "/$" ldir) nil) (setq ldir (concat ldir "/"))) (if (not (member ldir pushd-list)) (setq pushd-list (cons ldir pushd-list)) ) ) ) (defun popd (dir) "" (interactive "DRemove from pushd-list: ") (setq dir (expand-file-name dir)) (if (eq (string-match "/$" dir) nil) (setq dir (concat dir "/"))) (setq pushd-list (delete dir pushd-list)) (message "pushd-list is now: %s" (print pushd-list)) ) (defun pd-reset () "" (interactive) (setq pushd-list nil) ) (defun pd-save-pushd-list () "" (interactive) (find-file (concat pd-lisp-dir "#pd-list.el#")) (insert "(setq pushd-list \'\(") (if (< 0 (length pushd-list)) (progn (setq i 0) (while (< i (length pushd-list)) (insert-string (concat "\"" (car (nthcdr i pushd-list)) "\" ")) (setq i (+ i 1))) (backward-char 1))) (insert "\)\)\n") (write-file (concat pd-lisp-dir "pd-list.el")) (kill-this-buffer) ) (defun rotate (inlist) "" (setq outlist inlist) (setq outlist (reverse (cons (car inlist) (reverse (cdr outlist))))) ) (defun pd-clean-pd-list () "" (interactive) (print-pushd-list) (setq lenhome (length (expand-file-name "~"))) (setq tmplist pushd-list) (setq keeplist ()) (setq i 0) (while (< i (length pushd-list)) (if (not (y-or-n-p (concat "Delete ~" (substring (directory-file-name (car tmplist)) lenhome) " from pd-list? "))) (setq keeplist (cons (car tmplist) keeplist))) (setq i (+ i 1)) (setq tmplist (cdr tmplist))) (setq pushd-list keeplist) (print-pushd-list) ) (provide 'pushd)