Show
Ignore:
Timestamp:
07/16/06 08:36:52 (2 years ago)
Author:
miyoshi
Message:

Sync up with Emacs CVS HEAD.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/lisp/dirtrack.el

    r4037 r4111  
    3030;; 
    3131;; This is yet another attempt at a directory-tracking package for 
    32 ;; Emacs shell-mode. However, this package makes one strong assumption: 
     32;; Emacs shell-mode. However, this package makes one strong assumption: 
    3333;; that you can customize your shell's prompt to contain the 
    34 ;; current working directory. Most shells do support this, including 
     34;; current working directory. Most shells do support this, including 
    3535;; almost every type of Bourne and C shell on Unix, the native shells on 
    3636;; Windows95 (COMMAND.COM) and Windows NT (CMD.EXE), and most 3rd party 
    37 ;; Windows shells. If you cannot do this, or do not wish to, this package 
     37;; Windows shells. If you cannot do this, or do not wish to, this package 
    3838;; will be useless to you. 
    3939;; 
     
    4646;; Note that directory tracking is done by matching regular expressions, 
    4747;; therefore it is *VERY IMPORTANT* for your prompt to be easily 
    48 ;; distinguishable from other output. If your prompt regexp is too general, 
     48;; distinguishable from other output. If your prompt regexp is too general, 
    4949;; you will see error messages from the dirtrack filter as it attempts to cd 
    5050;; to non-existent directories. 
    5151;; 
    52 ;; 2) Set the variable `dirtrack-list' to an appropriate value. This 
     52;; 2) Set the variable `dirtrack-list' to an appropriate value. This 
    5353;; should be a list of two elements: the first is a regular expression 
    5454;; which matches your prompt up to and including the pathname part. 
    5555;; The second is a number which tells which regular expression group to 
    56 ;; match to extract only the pathname. If you use a multi-line prompt, 
    57 ;; add 't' as a third element. Note that some of the functions in 
     56;; match to extract only the pathname. If you use a multi-line prompt, 
     57;; add 't' as a third element. Note that some of the functions in 
    5858;; 'comint.el' assume a single-line prompt (eg, comint-bol). 
    5959;; 
    60 ;; Determining this information may take some experimentation. Setting 
     60;; Determining this information may take some experimentation. Setting 
    6161;; the variable `dirtrack-debug' may help; it causes the directory-tracking 
    62 ;; filter to log messages to the buffer `dirtrack-debug-buffer'. You can easily 
     62;; filter to log messages to the buffer `dirtrack-debug-buffer'. You can easily 
    6363;; toggle this setting with the `dirtrack-debug-toggle' function. 
    6464;; 
     
    6666;; 
    6767;; (add-hook 'shell-mode-hook 
    68 ;;   (function (lambda () 
    69 ;;            (setq comint-preoutput-filter-functions 
    70 ;;                  (append (list 'dirtrack) 
    71 ;;                          comint-preoutput-filter-functions))))) 
     68;;   (lambda () (add-hook 'comint-preoutput-filter-functions 'dirtrack nil t))) 
    7269;; 
    7370;; You may wish to turn ordinary shell tracking off by calling 
     
    108105;;   If you do this, and the shell prompt contains a ~, Emacs will interpret 
    109106;;   this relative to the user which owns the Emacs process, not the user 
    110 ;;   who owns the shell buffer. This may cause dirtrack to behave strangely 
     107;;   who owns the shell buffer. This may cause dirtrack to behave strangely 
    111108;;   (typically it reports that it is unable to cd to a directory 
    112109;;   with a ~ in it). 
     
    114111;;   The same behavior can occur if you use dirtrack with remote filesystems 
    115112;;   (using telnet, rlogin, etc) as Emacs will be checking the local 
    116 ;;   filesystem, not the remote one. This problem is not specific to dirtrack, 
     113;;   filesystem, not the remote one. This problem is not specific to dirtrack, 
    117114;;   but also affects file completion, etc. 
    118115 
     
    133130 
    134131(defcustom dirtrack-list (list "^emacs \\([a-zA-Z]:.*\\)>" 1) 
    135   "*List for directory tracking. 
     132  "List for directory tracking. 
    136133First item is a regexp that describes where to find the path in a prompt. 
    137134Second is a number, the regexp group to match.  Optional third item is 
     
    141138  :type  '(sexp (regexp  :tag "Prompt Expression") 
    142139                (integer :tag "Regexp Group") 
    143                 (boolean :tag "Multiline Prompt") 
    144                 ) 
    145   ) 
     140                (boolean :tag "Multiline Prompt"))) 
    146141 
    147142(make-variable-buffer-local 'dirtrack-list) 
    148143 
    149144(defcustom dirtrack-debug nil 
    150   "*If non-nil, the function `dirtrack' will report debugging info." 
    151   :group 'dirtrack 
    152   :type  'boolean 
    153   ) 
     145  "If non-nil, the function `dirtrack' will report debugging info." 
     146  :group 'dirtrack 
     147  :type  'boolean) 
    154148 
    155149(defcustom dirtrack-debug-buffer "*Directory Tracking Log*" 
    156150  "Buffer to write directory tracking debug information." 
    157151  :group 'dirtrack 
    158   :type  'string 
    159   ) 
     152  :type  'string) 
    160153 
    161154(defcustom dirtrackp t 
    162   "*If non-nil, directory tracking via `dirtrack' is enabled." 
    163   :group 'dirtrack 
    164   :type  'boolean 
    165   ) 
     155  "If non-nil, directory tracking via `dirtrack' is enabled." 
     156  :group 'dirtrack 
     157  :type  'boolean) 
    166158 
    167159(make-variable-buffer-local 'dirtrackp) 
     
    170162  (if (memq system-type (list 'ms-dos 'windows-nt 'cygwin)) 
    171163      'dirtrack-windows-directory-function 
    172     'dirtrack-default-directory-function) 
    173   "*Function to apply to the prompt directory for comparison purposes." 
    174   :group 'dirtrack 
    175   :type  'function 
    176   ) 
     164    'file-name-as-directory) 
     165  "Function to apply to the prompt directory for comparison purposes." 
     166  :group 'dirtrack 
     167  :type  'function) 
    177168 
    178169(defcustom dirtrack-canonicalize-function 
    179170  (if (memq system-type (list 'ms-dos 'windows-nt 'cygwin)) 
    180171      'downcase 'identity) 
    181   "*Function to apply to the default directory for comparison purposes." 
    182   :group 'dirtrack 
    183   :type  'function 
    184   ) 
     172  "Function to apply to the default directory for comparison purposes." 
     173  :group 'dirtrack 
     174  :type  'function) 
    185175 
    186176(defcustom dirtrack-directory-change-hook nil 
    187177  "Hook that is called when a directory change is made." 
    188178  :group 'dirtrack 
    189   :type 'hook 
    190   ) 
     179  :type 'hook) 
    191180 
    192181 
     
    195184;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
    196185 
    197 (defun dirtrack-default-directory-function (dir) 
    198   "Return a canonical directory for comparison purposes. 
    199 Such a directory ends with a forward slash." 
    200   (let ((directory dir)) 
    201     (if (not (char-equal ?/ (string-to-char (substring directory -1)))) 
    202         (concat directory "/") 
    203       directory))) 
    204186 
    205187(defun dirtrack-windows-directory-function (dir) 
     
    207189Such a directory is all lowercase, has forward-slashes as delimiters, 
    208190and ends with a forward slash." 
    209   (let ((directory dir)) 
    210     (setq directory (downcase (dirtrack-replace-slash directory t))) 
    211     (if (not (char-equal ?/ (string-to-char (substring directory -1)))) 
    212         (concat directory "/") 
    213       directory))) 
     191  (file-name-as-directory (downcase (subst-char-in-string ?\\ ?/ dir)))) 
    214192 
    215193(defun dirtrack-cygwin-directory-function (dir) 
     
    219197    dir)) 
    220198 
    221 (defconst dirtrack-forward-slash  (regexp-quote "/")) 
    222 (defconst dirtrack-backward-slash (regexp-quote "\\")) 
    223  
    224 (defun dirtrack-replace-slash (string &optional opposite) 
    225   "Replace forward slashes with backwards ones. 
    226 If additional argument is non-nil, replace backwards slashes with 
    227 forward ones." 
    228   (let ((orig     (if opposite 
    229                       dirtrack-backward-slash 
    230                     dirtrack-forward-slash)) 
    231         (replace  (if opposite 
    232                       dirtrack-forward-slash 
    233                     dirtrack-backward-slash)) 
    234         (newstring string) 
    235         ) 
    236     (while (string-match orig newstring) 
    237       (setq newstring (replace-match replace nil t newstring))) 
    238   newstring)) 
    239  
    240199;; Copied from shell.el 
    241200(defun dirtrack-toggle () 
    242201  "Enable or disable Dirtrack directory tracking in a shell buffer." 
    243202  (interactive) 
    244   (setq dirtrackp (not dirtrackp)) 
     203  (if (setq dirtrackp (not dirtrackp)) 
     204      (add-hook 'comint-preoutput-filter-functions 'dirtrack nil t) 
     205    (remove-hook 'comint-preoutput-filter-functions 'dirtrack t)) 
    245206  (message "Directory tracking %s" (if dirtrackp "ON" "OFF"))) 
    246207 
     
    274235 
    275236You can enable directory tracking by adding this function to 
    276 `comint-output-filter-functions'. 
    277 
    278   (if (null dirtrackp) 
     237`comint-output-filter-functions'." 
     238  (if (or (null dirtrackp) 
     239          ;; No output? 
     240          (eq (point) (point-min))) 
    279241      nil 
    280242    (let (prompt-path 
    281           matched 
    282243          (current-dir default-directory) 
    283244          (dirtrack-regexp    (nth 0 dirtrack-list)) 
    284245          (match-num          (nth 1 dirtrack-list)) 
    285           (multi-line         (nth 2 dirtrack-list)) 
    286           ) 
    287       ;; No output? 
    288       (if (eq (point) (point-min)) 
    289           nil 
    290         (save-excursion 
    291           (setq matched (string-match dirtrack-regexp input))) 
    292           ;; No match 
    293           (if (null matched) 
    294               (and dirtrack-debug 
    295                    (dirtrack-debug-message 
    296                     (format 
    297                      "Input `%s' failed to match regexp: %s" 
    298                     input dirtrack-regexp))) 
    299             (setq prompt-path 
    300                   (substring input 
    301                    (match-beginning match-num) (match-end match-num))) 
    302             ;; Empty string 
    303             (if (not (> (length prompt-path) 0)) 
    304                 (and dirtrack-debug 
    305                      (dirtrack-debug-message "Match is empty string")) 
    306               ;; Transform prompts into canonical forms 
    307               (setq prompt-path (funcall dirtrack-directory-function 
    308                                          prompt-path)) 
    309               (setq current-dir (funcall dirtrack-canonicalize-function 
    310                                          current-dir)) 
    311               (and dirtrack-debug 
    312                    (dirtrack-debug-message 
    313                     (format 
    314                      "Prompt is %s\nCurrent directory is %s" 
    315                      prompt-path current-dir))) 
    316               ;; Compare them 
    317               (if (or (string= current-dir prompt-path) 
    318                       (string= current-dir 
    319                                (abbreviate-file-name prompt-path))) 
    320                   (and dirtrack-debug 
    321                        (dirtrack-debug-message 
    322                         (format "Not changing directory"))) 
    323                 ;; It's possible that Emacs will think the directory 
    324                 ;; won't exist (eg, rlogin buffers) 
    325                 (if (file-accessible-directory-p prompt-path) 
    326                     ;; Change directory 
    327                     (and (shell-process-cd prompt-path) 
    328                          (run-hooks 'dirtrack-directory-change-hook) 
    329                          dirtrack-debug 
    330                          (dirtrack-debug-message 
    331                           (format "Changing directory to %s" prompt-path))) 
    332                   (error "Directory %s does not exist" prompt-path))) 
    333               ))))) 
     246          ;; Currently unimplemented, it seems.  --Stef 
     247          (multi-line         (nth 2 dirtrack-list))) 
     248      (save-excursion 
     249        ;; No match 
     250        (if (null (string-match dirtrack-regexp input)) 
     251            (and dirtrack-debug 
     252                 (dirtrack-debug-message 
     253                  (format 
     254                   "Input `%s' failed to match `dirtrack-regexp'" input))) 
     255          (setq prompt-path (match-string match-num input)) 
     256          ;; Empty string 
     257          (if (not (> (length prompt-path) 0)) 
     258              (and dirtrack-debug 
     259                   (dirtrack-debug-message "Match is empty string")) 
     260            ;; Transform prompts into canonical forms 
     261            (setq prompt-path (funcall dirtrack-directory-function 
     262                                       prompt-path)) 
     263            (setq current-dir (funcall dirtrack-canonicalize-function 
     264                                       current-dir)) 
     265            (and dirtrack-debug 
     266                 (dirtrack-debug-message 
     267                  (format 
     268                   "Prompt is %s\nCurrent directory is %s" 
     269                   prompt-path current-dir))) 
     270            ;; Compare them 
     271            (if (or (string= current-dir prompt-path) 
     272                    (string= current-dir 
     273                             (abbreviate-file-name prompt-path))) 
     274                (and dirtrack-debug 
     275                     (dirtrack-debug-message 
     276                      (format "Not changing directory"))) 
     277              ;; It's possible that Emacs will think the directory 
     278              ;; won't exist (eg, rlogin buffers) 
     279              (if (file-accessible-directory-p prompt-path) 
     280                  ;; Change directory 
     281                  (and (shell-process-cd prompt-path) 
     282                       (run-hooks 'dirtrack-directory-change-hook) 
     283                       dirtrack-debug 
     284                       (dirtrack-debug-message 
     285                        (format "Changing directory to %s" prompt-path))) 
     286                (error "Directory %s does not exist" prompt-path))) 
     287            ))))) 
    334288  input) 
    335289 
    336290(provide 'dirtrack) 
    337291 
    338 ;;; arch-tag: 168de071-be88-4937-aff6-2aba9f328d5a 
     292;; arch-tag: 168de071-be88-4937-aff6-2aba9f328d5a 
    339293;;; dirtrack.el ends here