mylisp/cygpath.el
changeset 1767 fd3589f24170
parent 1731 fec5d1fffe8c
equal deleted inserted replaced
1766:407c95f4887f 1767:fd3589f24170
       
     1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
       
     2 ;; Handling MSYS paths in NT Emacs.
       
     3 
       
     4 (defvar cygpath-msys-root nil
       
     5   "Installation root for MSYS.")
       
     6 
       
     7 (defconst cygpath-msys-drive-regex "\\`/\\([a-z]\\)/"
       
     8   "Regex for identifying MSYS(2) drive-like paths.")
       
     9 (defconst cygpath-msys-root-dirs (list "bin" "clang32" "clang64" "clangarm64" "etc" "home" "mingw32" "mingw64" "opt" "srv" "tmp" "ucrt64" "usr" "var")
       
    10   "Root directories to be recognized as MSYS paths.")
       
    11 (defun cygpath-msys-root--regex ()
       
    12     "Build regex for matching MSYS root dirs."
       
    13     (format "\\`/%s" (regexp-opt cygpath-msys-root-dirs)))
       
    14 (defconst cygpath-msys-root--regex nil
       
    15     "Regex for matching MSYS root dirs. Automatically regenerated by
       
    16 the function `cygpath-msys-root--regex'.")
       
    17 
       
    18 (defun cygpath-msys-to-nt (msyspath)
       
    19   "Coverts MSYS style path to NT path."
       
    20   (cond
       
    21    ((string-match cygpath-msys-drive-regex msyspath)
       
    22     (concat (match-string 1 msyspath) ":\\" (string-replace "/" "\\" (substring msyspath (match-end 0)))))
       
    23    ((string-match cygpath-msys-root--regex msyspath)
       
    24     (concat cygpath-msys-root (string-replace "/" "\\" msyspath)))
       
    25    (t msyspath)))
       
    26 
       
    27 ;; (cygpath-msys-to-nt "/c/")
       
    28 ;; (cygpath-msys-to-nt "/c/Users")
       
    29 ;; (setq cygpath-msys-root--regex (cygpath-msys-root--regex))
       
    30 ;; (cygpath-msys-to-nt "/etc/fstab")
       
    31 
       
    32 (defun cygpath-msys--mapping-function (op msyspath &rest args)
       
    33   (let ((inhibit-file-name-handlers (cons #'cygpath-msys--mapping-function inhibit-file-name-handlers))
       
    34         (inhibit-file-name-operation op))
       
    35     (apply op (cygpath-msys-to-nt msyspath) args)))
       
    36 
       
    37 (defvar cygpath-msys-activated nil)
       
    38 
       
    39 (defun cygpath-msys--fail-if-not-nt ()
       
    40   (unless (eq system-type 'windows-nt)
       
    41     (error "`cygpath-msys' mode makes sense only in NT Emacs."))
       
    42   (unless cygpath-msys-root
       
    43     (error "`cygpath-msys-root' is not defined."))
       
    44   (unless (file-directory-p cygpath-msys-root)
       
    45     (error "`cygpath-msys-root' is a directory.")))
       
    46 
       
    47 ;;;###autoload
       
    48 (defun cygpath-msys-activate ()
       
    49   "Start interpret MSYS(2) paths inside NT Emacs."
       
    50   (interactive)
       
    51   (cygpath-msys--fail-if-not-nt)
       
    52   (unless cygpath-msys-activated
       
    53     (setq cygpath-msys-root--regex (cygpath-msys-root--regex))
       
    54     (mapc (lambda (regex)
       
    55             (add-to-list 'file-name-handler-alist (cons regex #'cygpath-msys--mapping-function)))
       
    56           (list cygpath-msys-drive-regex (cygpath-msys-root--regex)))
       
    57     (setq cygpath-msys-activated t)))
       
    58 
       
    59 ;;;###autoload
       
    60 (defun cygpath-msys-deactivate ()
       
    61   "Stop interpret MSYS(2) paths inside NT Emacs."
       
    62   (interactive)
       
    63   (cygpath-msys--fail-if-not-nt)
       
    64   (when cygpath-msys-activated
       
    65     (setf file-name-handler-alist (cl-delete #'cygpath-msys--mapping-function file-name-handler-alist :key #'cdr :test #'eq))
       
    66     (setq cygpath-msys-activated nil)))
       
    67 
       
    68 
       
    69 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
       
    70 ;; Handling Windows paths in Cygwin Emacs.
       
    71 
       
    72 (defvar cygpath-nt-cygdrive-prefix "/cygdrive"
       
    73   "For MSYS set to empty string!")
       
    74 
       
    75 (defconst cygpath-nt-regex-forward-slash "\\`\\([a-zA-Z]\\):/")
       
    76 (defconst cygpath-nt-regex-backward-slash "\\`\\([a-zA-Z]\\):\\\\")
       
    77 (defconst cygpath-nt-regex-list (list cygpath-nt-regex-forward-slash cygpath-nt-regex-backward-slash))
       
    78 
       
    79 (defun cygpath-nt-to-cygwin (winpath)
       
    80   (cond
       
    81    ((string-match cygpath-nt-regex-forward-slash winpath)
       
    82     (concat cygpath-nt-cygdrive-prefix "/" (downcase (match-string 1 winpath)) "/" (substring winpath (match-end 0))))
       
    83    ((string-match cygpath-nt-regex-backward-slash winpath)
       
    84     (concat cygpath-nt-cygdrive-prefix "/" (downcase (match-string 1 winpath)) "/" (replace-regexp-in-string "\\\\" "/" (substring winpath (match-end 0)))))
       
    85    (t winpath)))
       
    86 
       
    87 ;; (cygpath-nt-to-cygwin "c:/home/my.txt")
       
    88 ;; (cygpath-nt-to-cygwin "c:\\home\\my.txt")
       
    89 
       
    90 (defun cygpath-nt--mapping-function (op winname &rest args)
       
    91   (let ((inhibit-file-name-handlers (cons #'cygpath-nt--mapping-function inhibit-file-name-handlers))
       
    92         (inhibit-file-name-operation op))
       
    93     (apply op (cygpath-nt-to-cygwin winname) args)))
       
    94 
       
    95 (defvar cygpath-nt-activated nil)
       
    96 
       
    97 (defun cygpath-nt--fail-if-not-cygwin ()
       
    98   (unless (eq system-type 'cygwin)
       
    99     (error "Mode is suppose to work only inside Cygwin")))
       
   100 
       
   101 ;;;###autoload
       
   102 (defun cygpath-nt-activate ()
       
   103   "Start interpret Windows paths inside Cygwin Emacs."
       
   104   (interactive)
       
   105   (cygpath-nt--fail-if-not-cygwin)
       
   106   (unless cygpath-nt-activated
       
   107     (mapc (lambda (regex)
       
   108             (add-to-list 'file-name-handler-alist (cons regex #'cygpath-nt--mapping-function)))
       
   109           cygpath-nt-regex-list)
       
   110     (setq cygpath-nt-activated t)))
       
   111 
       
   112 ;;;###autoload
       
   113 (defun cygpath-nt-deactivate ()
       
   114   "Stop interpret Windows paths inside Cygwin Emacs."
       
   115   (interactive)
       
   116   (cygpath-nt--fail-if-not-cygwin)
       
   117   (when cygpath-nt-activated
       
   118     (mapc (lambda (regex)
       
   119             (setf file-name-handler-alist (cl-delete regex file-name-handler-alist :key #'car :test #'equal)))
       
   120           cygpath-nt-regex-list)
       
   121     (setq cygpath-nt-activated t)))
       
   122 
       
   123 
       
   124 (provide 'cygpath-msys)
       
   125 (provide 'cygpath-nt)
       
   126 
       
   127 (provide 'cygpath)