You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
566 lines
24 KiB
566 lines
24 KiB
2 years ago
|
;;; cygwin-mount.el --- Teach EMACS about cygwin styles and mount points.
|
||
|
|
||
|
;; Copyright (C) 1997 Michael Cook <mcook@xemacs.org>.
|
||
|
;; 2001 Klaus Berndl <berndl@sdm.de>
|
||
|
|
||
|
;; Author: Michael Cook <mcook@xemacs.org>
|
||
|
;; Keywords: files, mount, cygwin
|
||
|
|
||
|
;; This file is *NOT* (yet?) part of 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, Inc., 59 Temple Place - Suite 330,
|
||
|
;; Boston, MA 02111-1307, USA.
|
||
|
|
||
|
;; Additional info:
|
||
|
;; $Date: 2004-01-14 07:35:04 -0800 (Wed, 14 Jan 2004) $
|
||
|
;; Maintenance: Eric Hanchrow <offby1@blarg.net>
|
||
|
;; Additional code by: Stephane Rollandin <hepta@zogotounga.net>
|
||
|
;; Michael Mauger <mmaug@yahoo.com>
|
||
|
;; Keisuke Mori <ksk@ntts.com>
|
||
|
;; Drew Moseley (drewmoseley@mindspring.com)
|
||
|
;; James Ganong (jeg@bigseal.ucsc.edu)
|
||
|
;; Jeff Juliano <juliano@cs.unc.edu>
|
||
|
;; Klaus Berndl <berndl@sdm.de>
|
||
|
;; Nick Sieger <nsieger@bitstream.net>
|
||
|
;; Richard Y. Kim <ryk@dspwiz.com>
|
||
|
;; Karel Sprenger <karel.sprenger@compaq.com>
|
||
|
;;
|
||
|
;; When submitting patches, please try to also submit an automated
|
||
|
;; test that demonstrates the need for the patch -- i.e., one that
|
||
|
;; fails with the unpatched code, but passes with the patched code.
|
||
|
;; This will make is easier for the maintainer to decide if your patch
|
||
|
;; duplicates functionality from other patches. Patching `tests.el'
|
||
|
;; would be good.
|
||
|
;;; Availabilty
|
||
|
|
||
|
;; The latest version of cygwin-mount.el can always be found at
|
||
|
;; http://www.blarg.net/~offby1/cygwin-mount/
|
||
|
|
||
|
;; ----------------------------------------------------------------------
|
||
|
;;; Commentary
|
||
|
|
||
|
;; This package lets you use cygwin-style filenames like
|
||
|
;; "//D/any/path/to/file" or "/cygdrive/D/any/path/to/file" in exactly
|
||
|
;; the same manner as the normal Windows-style filenames like
|
||
|
;; "D:\any\path\to\file" or "D:/any/path/to/file". NOTE: "/cygdrive/"
|
||
|
;; is only an example for the cygdrive-prefix \(see
|
||
|
;; `cygwin-mount-cygdrive-prefix--internal'). cygwin-mount can handle
|
||
|
;; every cygdrive-prefix set by "mount --change-cygdrive-prefix"
|
||
|
;; (e.g. "/" is also a valid cygdrive-prefix). UNC paths work
|
||
|
;; too. Furthermore, this package lets you use all your cygwin mounts
|
||
|
;; in file operations. For example, you can use (e.g. find-file) for
|
||
|
;; a file named "/usr/bin/anyfile" if you have mounted the related
|
||
|
;; Windows-path to /usr/bin. Ange-ftp also works correctly.
|
||
|
|
||
|
;;; Installation:
|
||
|
|
||
|
;; Put in your .emacs or site-start.el file the following lines:
|
||
|
;; (require 'cygwin-mount)
|
||
|
;; (cygwin-mount-activate)
|
||
|
|
||
|
;;; Customization and using
|
||
|
|
||
|
;; + All customization is done in the customize-group `cygwin-mount'.
|
||
|
;; Do not set the user-options via `setq' but only via customize because
|
||
|
;; otherwise the package will not work correct!!
|
||
|
;; Important: Now the cygwin mountpoints are stored in the variable
|
||
|
;; `cygwin-mount-table--internal'. This variable must not be set by the user
|
||
|
;; but it is only set by customizing `cygwin-mount-table'!
|
||
|
;; + Activating: cygwin-mount-activate
|
||
|
;; + Deactivating: cygwin-mount-deactivate
|
||
|
|
||
|
;;; Compatibility
|
||
|
|
||
|
;; The cygwin-mount.el package is only tested with NTEmacs >= 20.6.1.
|
||
|
;; It has also been tested with the native port of XEmacs 21.1 but not
|
||
|
;; very intensive! The package has been tested with Cygwin 1.1.8 and
|
||
|
;; >= 1.3.1. It reportedly also works with at least some versions of
|
||
|
;; MinGW.
|
||
|
|
||
|
;; How it works:
|
||
|
;; basically we push some functions onto file-name-handler-alist.
|
||
|
;; They detect filenames expressed in cygwin style, and translate
|
||
|
;; those names into native Win32 style.
|
||
|
|
||
|
;;; Code:
|
||
|
|
||
|
(defconst cygwin-mount-version "1.4.8")
|
||
|
|
||
|
(defgroup cygwin-mount nil
|
||
|
"Proper handling of cygwin mounts and filenames."
|
||
|
:prefix "cygwin-"
|
||
|
:group 'files)
|
||
|
|
||
|
;; some constants
|
||
|
|
||
|
(defconst cygwin-mount-program "mount.exe")
|
||
|
(defconst cygwin-mount-uname-program "uname.exe")
|
||
|
(defconst cygwin-mount-buffername " *mount*")
|
||
|
|
||
|
;; internal variables. These variables are only set by calling
|
||
|
;; `cygwin-mount-activate' or by customizing `cygwin-mount-table'.
|
||
|
|
||
|
(defvar cygwin-mount-table--internal nil
|
||
|
"Do not set this variable directly but customize `cygwin-mount-table'!")
|
||
|
|
||
|
(defvar cygwin-mount-cygdrive-prefix--internal ""
|
||
|
"Prefix for the \"/cygdrive/X/\" style of cygwin.
|
||
|
A cygwin-user can change the \"/cygdrive\" to whatever he wants to access
|
||
|
files at MS-DOS drives. For example many people seem to like to have the
|
||
|
drives accessible as a directory so that c: == /c, which means the
|
||
|
cygdrive-prefix is \"/\" instead of \"/cygdrive\". This prefix must end
|
||
|
with a '/'! Do not set this variable because the value of this variable is
|
||
|
determined at activation-time of cygwin-mount \(see
|
||
|
`cygwin-mount-activate')")
|
||
|
|
||
|
;; user options
|
||
|
|
||
|
(defcustom cygwin-mount-cygwin-bin-directory nil
|
||
|
"*The directory where the cygwin binaries reside.
|
||
|
If nil then the cygwin-binary-directory must be into the PATH."
|
||
|
:group 'cygwin-mount
|
||
|
:type '(radio (const :tag "Cygwin is into PATH" :value nil)
|
||
|
(directory :tag "Cygwin-Binary-Dir" :value "")))
|
||
|
|
||
|
(defcustom cygwin-mount-build-mount-table-asynch nil
|
||
|
"*When non-nil, `cygwin-mount-table' is built at load-time.
|
||
|
If you change the value via customize you must deactivate and activate the
|
||
|
package again to take effect."
|
||
|
:group 'cygwin-mount
|
||
|
:type 'boolean)
|
||
|
|
||
|
(defcustom cygwin-mount-table t
|
||
|
"*Alist of custom cygwin mount points or t.
|
||
|
If t if all the current mount-points returned by the cygwin mount-program
|
||
|
should be used. If set to nil then there are no mount-points. An element of
|
||
|
the alist has the form \(<mounted windows-device> . <cygwin-directory>),
|
||
|
e.g. \(\"D:\\\\programs\\\\cygwin\\\\bin\" . \"/usr/bin/\") or
|
||
|
\(\"D:/programs/cygwin\" . \"/\")."
|
||
|
:group 'cygwin-mount
|
||
|
:set (function (lambda (symbol value)
|
||
|
(set symbol value)
|
||
|
(if (equal value t)
|
||
|
(cygwin-mount-build-table-internal)
|
||
|
(setq cygwin-mount-table--internal value))))
|
||
|
:initialize 'custom-initialize-default
|
||
|
:type '(radio (const :tag "Automatic"
|
||
|
:value t)
|
||
|
(repeat :tag "Custom mounts"
|
||
|
(cons (directory :tag "Mounted device")
|
||
|
(string :tag "Cygwin directory")))))
|
||
|
|
||
|
;; copied from executable.el because this library is not included in all
|
||
|
;; Emacsen by default.
|
||
|
(defvar cygwin-mount-executable-binary-suffixes
|
||
|
(if (memq system-type '(ms-dos windows-nt))
|
||
|
'(".exe" ".com" ".bat" ".cmd" ".btm" "")
|
||
|
'("")))
|
||
|
(defun cygwin-mount-executable-find (command)
|
||
|
"Search for COMMAND in `exec-path' and return the absolute file name.
|
||
|
Return nil if COMMAND is not found anywhere in `exec-path'."
|
||
|
(let ((list exec-path)
|
||
|
file)
|
||
|
(while list
|
||
|
(setq list
|
||
|
(if (and (setq file (expand-file-name command (car list)))
|
||
|
(let ((suffixes cygwin-mount-executable-binary-suffixes)
|
||
|
candidate)
|
||
|
(while suffixes
|
||
|
(setq candidate (concat file (car suffixes)))
|
||
|
(if (and (file-executable-p candidate)
|
||
|
(not (file-directory-p candidate)))
|
||
|
(setq suffixes nil)
|
||
|
(setq suffixes (cdr suffixes))
|
||
|
(setq candidate nil)))
|
||
|
(setq file candidate)))
|
||
|
nil
|
||
|
(setq file nil)
|
||
|
(cdr list))))
|
||
|
file))
|
||
|
|
||
|
;; functions
|
||
|
|
||
|
(defun cygwin-mount-get-full-progname (program)
|
||
|
"Return the full path of PROGRAM if possible or nil."
|
||
|
(let ((fullname
|
||
|
(if (and cygwin-mount-cygwin-bin-directory
|
||
|
(stringp cygwin-mount-cygwin-bin-directory)
|
||
|
(file-directory-p cygwin-mount-cygwin-bin-directory))
|
||
|
(concat (file-name-as-directory cygwin-mount-cygwin-bin-directory)
|
||
|
program)
|
||
|
(expand-file-name (or (cygwin-mount-executable-find program)
|
||
|
program)))))
|
||
|
(if (file-executable-p fullname)
|
||
|
fullname
|
||
|
nil)))
|
||
|
|
||
|
(defun cygwin-mount-get-cygdrive-prefix ()
|
||
|
"Return prefix used for the \"/cygdrive/X/\" style of cygwin.
|
||
|
This is done by calling \"mount --show-cygdrive-prefixes\".
|
||
|
The result is either \"/\" or \"/<string>/\"."
|
||
|
(let ((buf (get-buffer-create " *cygdrive*"))
|
||
|
(fullname (cygwin-mount-get-full-progname cygwin-mount-program)))
|
||
|
(if (null fullname)
|
||
|
(error "Cannot find program '%s'. Check `cygwin-mount-cygwin-bin-directory'"
|
||
|
cygwin-mount-program)
|
||
|
(with-current-buffer buf
|
||
|
(or
|
||
|
(progn
|
||
|
(erase-buffer)
|
||
|
(zerop (call-process fullname nil buf nil "--show-cygdrive-prefix")))
|
||
|
(progn
|
||
|
(erase-buffer)
|
||
|
(zerop (call-process fullname nil buf nil "--show-cygdrive-prefixes")))
|
||
|
(error "Cannot run %s" fullname))
|
||
|
(goto-char (point-min))
|
||
|
(prog1
|
||
|
(let ((regexp-prefix "\\(/[^ \t]*\\)[ \t]+")
|
||
|
cygdrive-prefix)
|
||
|
;; we search first for the user prefix and if there isn't any we
|
||
|
;; search for the system prefix.
|
||
|
(if (or (search-forward-regexp (concat regexp-prefix "user") nil t)
|
||
|
(search-forward-regexp (concat regexp-prefix "system") nil t))
|
||
|
(progn
|
||
|
(setq cygdrive-prefix (match-string 1))
|
||
|
(if (string= cygdrive-prefix "/")
|
||
|
cygdrive-prefix
|
||
|
(concat cygdrive-prefix "/")))
|
||
|
"/cygdrive/"))
|
||
|
(kill-buffer buf))))))
|
||
|
|
||
|
(defun trim-trailing-whitespace (str)
|
||
|
(string-match "^\\(.*\\S-\\)\\s-*$" str )
|
||
|
(replace-match "\\1" nil nil str))
|
||
|
|
||
|
(defun cygwin-mount-parse-one-line (line)
|
||
|
"Parse the output from one line of the Cygwin `mount' command;
|
||
|
return a pair containing the windows directory and the corresponding
|
||
|
Cygwin path."
|
||
|
|
||
|
;; can't use non-greedy regular expressions because versions of
|
||
|
;; Emacs older than 21.1 lack them.
|
||
|
(if (or (string-match "\\(.*\\) on \\(/.*\\) type .* (.*)" line)
|
||
|
(string-match "\\(.*\\)\\s-+\\(/.*\\)\\s-+\\(user\\|system\
|
||
|
\\|vfat\\)\\s-+\\(textmode\\|binmode\\)"
|
||
|
line))
|
||
|
(let ((win (match-string 1 line))
|
||
|
(cyg (match-string 2 line)))
|
||
|
(setq win (trim-trailing-whitespace win))
|
||
|
(setq cyg (trim-trailing-whitespace cyg))
|
||
|
(cons win cyg))
|
||
|
(error "Cannot parse output from `mount': %s" line)))
|
||
|
|
||
|
(defun cygwin-mount-parse-mount ()
|
||
|
"Parse buffer `cygwin-mount-buffername' and return alist of
|
||
|
mount-points, sorted with longest \"device\" names first. For the
|
||
|
format of this alist see `cygwin-mount-table'. Precondition of this
|
||
|
function is current buffer must be the buffer named
|
||
|
`cygwin-mount-buffername'."
|
||
|
(if (equal (current-buffer) (get-buffer cygwin-mount-buffername))
|
||
|
(let ((case-fold-search t)
|
||
|
mounts)
|
||
|
(goto-char (point-min))
|
||
|
(while (not (eobp))
|
||
|
(let* ((parsed (cygwin-mount-parse-one-line
|
||
|
(buffer-substring
|
||
|
(progn (beginning-of-line) (point))
|
||
|
(progn (end-of-line) (point)))))
|
||
|
(device (car parsed))
|
||
|
(direct (cdr parsed)))
|
||
|
(setq mounts (cons (cons (file-name-as-directory device)
|
||
|
(file-name-as-directory direct))
|
||
|
mounts))
|
||
|
(forward-line 1)))
|
||
|
|
||
|
;; now sort the alist so that the longest directories come first.
|
||
|
(setq mounts (sort mounts (function (lambda (pair1 pair2)
|
||
|
(> (length (cdr pair1))
|
||
|
(length (cdr pair2)))))) )
|
||
|
mounts)))
|
||
|
|
||
|
(defun cygwin-mount-sentinel (proc msg)
|
||
|
"Process sentinel for PROC with MSG."
|
||
|
(if (or (eq (process-status proc) 'exit)
|
||
|
(eq (process-status proc) 'signal))
|
||
|
(let ((buf (get-buffer-create cygwin-mount-buffername)))
|
||
|
(with-current-buffer buf
|
||
|
(setq cygwin-mount-table--internal (cygwin-mount-parse-mount)))
|
||
|
(kill-buffer buf)
|
||
|
(message "Build of mount table completed"))))
|
||
|
|
||
|
(defun cygwin-mount-build-table-internal ()
|
||
|
"Determine cygwin mount points.
|
||
|
This function sets `cygwin-mount-table--internal'
|
||
|
either synchronously or asynchronously \(see
|
||
|
`cygwin-mount-build-mount-table-asynch'). If asynchronously then the set is
|
||
|
really done by `cygwin-mount-sentinel'."
|
||
|
(let ((fullname (cygwin-mount-get-full-progname cygwin-mount-program)))
|
||
|
(if (null fullname)
|
||
|
(error "Cannot find program '%s'. Check `cygwin-mount-cygwin-bin-directory'"
|
||
|
cygwin-mount-program)
|
||
|
(if cygwin-mount-build-mount-table-asynch
|
||
|
;; asynchron building
|
||
|
(let ((proc (start-process "mount" cygwin-mount-buffername fullname)))
|
||
|
(set-process-sentinel proc 'cygwin-mount-sentinel)
|
||
|
;; 2013-10-21, TunaFish5 (EmacsWiki): Use `set-process-query-on-exit-flag'.
|
||
|
;; D. Adams: Use only if defined. Keep older code for older Emacs.
|
||
|
(if (fboundp 'set-process-query-on-exit-flag)
|
||
|
(set-process-query-on-exit-flag proc nil)
|
||
|
(process-kill-without-query proc)))
|
||
|
;; synchron building
|
||
|
(let ((buf (get-buffer-create cygwin-mount-buffername)))
|
||
|
(with-current-buffer buf
|
||
|
(erase-buffer)
|
||
|
(call-process fullname nil buf)
|
||
|
(prog1
|
||
|
(setq cygwin-mount-table--internal (cygwin-mount-parse-mount))
|
||
|
(kill-buffer buf))))))))
|
||
|
|
||
|
(defun cygwin-mount-name-hook-function (operation &rest args)
|
||
|
"Run OPERATION with ARGS."
|
||
|
(let ((fn (get operation 'cygwin-mount-name)))
|
||
|
(if fn (apply fn operation args)
|
||
|
(cygwin-mount-run-real-handler operation args))))
|
||
|
|
||
|
(defun cygwin-mount-map-drive-hook-function (operation &rest args)
|
||
|
"Run OPERATION with ARGS."
|
||
|
(let ((fn (get operation 'cygwin-mount-map-drive)))
|
||
|
(if fn (apply fn operation args)
|
||
|
(cygwin-mount-run-real-handler operation args))))
|
||
|
|
||
|
(defun cygwin-mount-run-real-handler (operation args)
|
||
|
"Run OPERATION with ARGS."
|
||
|
(let ((inhibit-file-name-handlers
|
||
|
(append '(cygwin-mount-name-hook-function
|
||
|
cygwin-mount-map-drive-hook-function)
|
||
|
(and (eq inhibit-file-name-operation operation)
|
||
|
inhibit-file-name-handlers)))
|
||
|
(inhibit-file-name-operation operation))
|
||
|
(apply operation args)))
|
||
|
|
||
|
|
||
|
(defun cygwin-mount-name-expand (operation name &rest args)
|
||
|
"Run OPERATION NAME with ARGS.
|
||
|
first ARG is either nil or a file name"
|
||
|
(when (and args (car args))
|
||
|
(setq args (copy-sequence args)) ; TODO: determine if this call is necessary
|
||
|
(setcar args (cygwin-mount-substitute-longest-mount-name (car args))))
|
||
|
(cygwin-mount-run-real-handler
|
||
|
operation
|
||
|
(cons (cygwin-mount-substitute-longest-mount-name name) args)))
|
||
|
|
||
|
(defun cygwin-mount-substitute-longest-mount-name (name)
|
||
|
"Substitute NAME with mount device or return NAME."
|
||
|
(and name
|
||
|
(save-match-data
|
||
|
(if (or (string-match "^//.+" name) (string-match "/\\[.+\\]" name))
|
||
|
;; Added by Klaus: if name beginns with "//" then it can never contain
|
||
|
;; a cygwin mount point! Therefore we must not check for contained
|
||
|
;; mount points because if / is mounted then this will always match
|
||
|
;; and we get an incorrect substitution for network devices like
|
||
|
;; //Host/path
|
||
|
name
|
||
|
(let ((mounts cygwin-mount-table--internal)
|
||
|
(len (length (file-name-as-directory name)))
|
||
|
match)
|
||
|
(while mounts
|
||
|
(let ((mount (file-name-as-directory (cdar mounts))))
|
||
|
(and (>= len (length mount))
|
||
|
(string= mount
|
||
|
(file-name-as-directory
|
||
|
(substring (file-name-as-directory name)
|
||
|
0 (length mount))))
|
||
|
(or (null match)
|
||
|
(> (length (cdar mounts)) (length (cdr match))))
|
||
|
(setq match (car mounts))))
|
||
|
(setq mounts (cdr mounts)))
|
||
|
(if match
|
||
|
(concat (file-name-as-directory (car match))
|
||
|
(if (>= (length (file-name-as-directory (cdr match))) len)
|
||
|
""
|
||
|
(substring name (length (file-name-as-directory (cdr match))))))
|
||
|
name))))))
|
||
|
|
||
|
;; Added by Klaus
|
||
|
(defconst cygwin-mount-cygwin-style1-regexp "^/[^:@]*$\\|^/|/[^/:]+\\(\\'\\|/\\)")
|
||
|
|
||
|
;; This appears to work with ancient versions of cygwin, on which the
|
||
|
;; cygwin path `//x' was shorthand for the Win32 path `x:'.
|
||
|
(defconst cygwin-mount-cygwin-style2-regexp "^//[A-Za-z]/")
|
||
|
|
||
|
;; will be set by `cygwin-mount-activate'.
|
||
|
(defvar cygwin-mount-cygwin-style3-regexp nil)
|
||
|
|
||
|
;; We cannot assume that NAME matched cygwin-mount-cygwin-style1-regexp,
|
||
|
;; cygwin-mount-cygwin-style2-regexp nor cygwin-mount-cygwin-style3-regexp,
|
||
|
;; because this function could be called with either argument to
|
||
|
;; `expand-file-name', but only one argument to `expand-file-name' may
|
||
|
;; have matched a regexp.
|
||
|
;; For example, `(expand-file-name ".." "/cygdrive/c/")' will trigger
|
||
|
;; `(cygwin-mount-convert-file-name "..")' and
|
||
|
;; `(cygwin-mount-convert-file-name "/cygdrive/c/")' to be called.
|
||
|
(defun cygwin-mount-convert-file-name ( name )
|
||
|
"Convert file NAME, to cygwin format.
|
||
|
`//x/' to `x:/' and `/cygdrive/x/' to `x:/'.
|
||
|
NOTE: \"/cygdrive/\" is only an example for the cygdrive-prefix \(see
|
||
|
`cygwin-mount-cygdrive-prefix--internal')."
|
||
|
(let ((cygdrive-prefix-len (length cygwin-mount-cygdrive-prefix--internal)))
|
||
|
(save-match-data
|
||
|
(cond ((string-match cygwin-mount-cygwin-style2-regexp name)
|
||
|
(concat (substring name 2 3) ":" (substring name 3)))
|
||
|
((string-match cygwin-mount-cygwin-style3-regexp name)
|
||
|
(concat (substring name cygdrive-prefix-len
|
||
|
(1+ cygdrive-prefix-len))
|
||
|
":" (substring name (1+ cygdrive-prefix-len) nil)))
|
||
|
(t name)))))
|
||
|
|
||
|
(defun cygwin-mount-map-drive (operation name &rest args)
|
||
|
"Run OPERATION on cygwin NAME with ARGS.
|
||
|
Map cygwin name to the dos-style \"[A-Za-z]:/\" and call
|
||
|
OPERATION with the mapped filename\(s). NAME must have the format looks like
|
||
|
\"^//[A-Za-z]/\" or \"/cygdrive/[A-Za-z]/\" here. Note that at least the first
|
||
|
element of ARGS could be a filename too \(then it must have the same syntax
|
||
|
like NAME!) which must be converted \(e.g. `expand-file-name' can be called
|
||
|
with two filenames).
|
||
|
NOTE: \"/cygdrive/\" is only an example for the cygdrive-prefix \(see
|
||
|
`cygwin-mount-cygdrive-prefix--internal')."
|
||
|
(cygwin-mount-run-real-handler
|
||
|
operation
|
||
|
(cons (cygwin-mount-convert-file-name name)
|
||
|
(if (stringp (car args))
|
||
|
(cons (cygwin-mount-convert-file-name (car args))
|
||
|
(cdr args))
|
||
|
args))))
|
||
|
|
||
|
;;; TODO -- see if we need to do stuff for Tramp that is similar to
|
||
|
;;; what we're about to do for ange-ftp. If so, perhaps we can use
|
||
|
;;; `advice' to clean up those forms below whose comments describe
|
||
|
;;; them as "real hacks".
|
||
|
|
||
|
;;; ange-ftp
|
||
|
(if (locate-library "ange-ftp")
|
||
|
(require 'ange-ftp))
|
||
|
|
||
|
;;; save the original function definition of ange-ftp-run-real-handler
|
||
|
(defconst cygwin-mount-original-ange-ftp-handler
|
||
|
(if (featurep 'ange-ftp)
|
||
|
(symbol-function 'ange-ftp-run-real-handler)
|
||
|
nil))
|
||
|
|
||
|
;;; This version of ange-ftp-run-real-handler also inhibits the
|
||
|
;;; cygwin file name expansion when we are doing ange-ftp expansion.
|
||
|
;;;
|
||
|
;;; This is a real hack. If the real definition of this function
|
||
|
;;; changes, we have to modify this function
|
||
|
(defun cygwin-mount-ange-ftp-run-real-handler (operation args)
|
||
|
"Run OPERATION with ARGS."
|
||
|
(let ((inhibit-file-name-handlers
|
||
|
(append '(ange-ftp-hook-function
|
||
|
ange-ftp-completion-hook-function
|
||
|
cygwin-mount-name-hook-function
|
||
|
cygwin-mount-map-drive-hook-function)
|
||
|
(and (eq inhibit-file-name-operation
|
||
|
operation)
|
||
|
inhibit-file-name-handlers)))
|
||
|
(inhibit-file-name-operation operation))
|
||
|
(apply operation args)))
|
||
|
|
||
|
;; Added by Klaus
|
||
|
(defvar cygwin-mount-activated nil)
|
||
|
(defun cygwin-mount-activate ()
|
||
|
"Activate cygwin-mount- and cygwin-style-handling."
|
||
|
(interactive)
|
||
|
(if (not (eq system-type 'windows-nt))
|
||
|
(message "cygwin-mount is only available for Emacs for NT!")
|
||
|
|
||
|
(unless cygwin-mount-activated
|
||
|
;; initialize the internal variables
|
||
|
|
||
|
(if (equal cygwin-mount-table t)
|
||
|
(cygwin-mount-build-table-internal)
|
||
|
(setq cygwin-mount-table--internal cygwin-mount-table))
|
||
|
(setq cygwin-mount-cygdrive-prefix--internal
|
||
|
(cygwin-mount-get-cygdrive-prefix))
|
||
|
(setq cygwin-mount-cygwin-style3-regexp
|
||
|
(concat "^" cygwin-mount-cygdrive-prefix--internal "[A-Za-z]/"))
|
||
|
|
||
|
;; add the cygwin-filehandlers
|
||
|
(or (assoc cygwin-mount-cygwin-style1-regexp file-name-handler-alist)
|
||
|
(setq file-name-handler-alist
|
||
|
(cons `(,cygwin-mount-cygwin-style1-regexp
|
||
|
. cygwin-mount-name-hook-function)
|
||
|
file-name-handler-alist)))
|
||
|
|
||
|
(or (assoc cygwin-mount-cygwin-style2-regexp file-name-handler-alist)
|
||
|
(setq file-name-handler-alist
|
||
|
(cons `(,cygwin-mount-cygwin-style2-regexp
|
||
|
. cygwin-mount-map-drive-hook-function)
|
||
|
file-name-handler-alist)))
|
||
|
(or (assoc cygwin-mount-cygwin-style3-regexp file-name-handler-alist)
|
||
|
(setq file-name-handler-alist
|
||
|
(cons `(,cygwin-mount-cygwin-style3-regexp
|
||
|
. cygwin-mount-map-drive-hook-function)
|
||
|
file-name-handler-alist)))
|
||
|
|
||
|
;; add cygwin-properties
|
||
|
(put 'substitute-in-file-name 'cygwin-mount-name
|
||
|
'cygwin-mount-name-expand)
|
||
|
(put 'expand-file-name 'cygwin-mount-name 'cygwin-mount-name-expand)
|
||
|
(put 'substitute-in-file-name
|
||
|
'cygwin-mount-map-drive 'cygwin-mount-map-drive)
|
||
|
(put 'expand-file-name 'cygwin-mount-map-drive
|
||
|
'cygwin-mount-map-drive)
|
||
|
;; rebind ange-ftp-run-real-handler to our version
|
||
|
(if (featurep 'ange-ftp)
|
||
|
(fset 'ange-ftp-run-real-handler 'cygwin-mount-ange-ftp-run-real-handler))
|
||
|
|
||
|
(setq cygwin-mount-activated t))))
|
||
|
|
||
|
;; Added by Klaus
|
||
|
(defun cygwin-mount-deactivate ()
|
||
|
"Deactivate cygwin-mount- and cygwin-style-handling."
|
||
|
(interactive)
|
||
|
(if (not (eq system-type 'windows-nt))
|
||
|
(message "cygwin-mount is only available for (X)Emacs for NT!")
|
||
|
(unless (not cygwin-mount-activated)
|
||
|
;; reset the internal variables
|
||
|
(setq cygwin-mount-table--internal nil)
|
||
|
|
||
|
(setq cygwin-mount-cygdrive-prefix--internal "")
|
||
|
|
||
|
;; remove the cygwin-filehandlers
|
||
|
(setq file-name-handler-alist
|
||
|
(delete (assoc cygwin-mount-cygwin-style1-regexp file-name-handler-alist)
|
||
|
file-name-handler-alist))
|
||
|
(setq file-name-handler-alist
|
||
|
(delete (assoc cygwin-mount-cygwin-style2-regexp file-name-handler-alist)
|
||
|
file-name-handler-alist))
|
||
|
(setq file-name-handler-alist
|
||
|
(delete (assoc cygwin-mount-cygwin-style3-regexp file-name-handler-alist)
|
||
|
file-name-handler-alist))
|
||
|
;; remove the cygwin properties
|
||
|
(put 'substitute-in-file-name 'cygwin-mount-name nil)
|
||
|
(put 'expand-file-name 'cygwin-mount-name nil)
|
||
|
(put 'substitute-in-file-name 'cygwin-mount-map-drive nil)
|
||
|
(put 'expand-file-name 'cygwin-mount-map-drive nil)
|
||
|
;; rebind ange-ftp-run-real-handler to its original definition.
|
||
|
(if (featurep 'ange-ftp)
|
||
|
(fset 'ange-ftp-run-real-handler cygwin-mount-original-ange-ftp-handler))
|
||
|
(setq cygwin-mount-activated nil))))
|
||
|
|
||
|
(provide 'cygwin-mount)
|
||
|
|
||
|
;;; cygwin-mount.el ends here
|