In addition to interpreting Windows paths in Cygwin a handler is added for interpreting MSYS paths in NT Emacs.
authorOleksandr Gavenko <gavenkoa@gmail.com>
Wed, 14 Dec 2022 00:58:57 +0200
changeset 1767 fd3589f24170
parent 1766 407c95f4887f
child 1768 b3cac2287547
In addition to interpreting Windows paths in Cygwin a handler is added for interpreting MSYS paths in NT Emacs.
.emacs-my
mylisp/cygpath.el
mylisp/cygwin-winpath.el
--- a/.emacs-my	Wed Dec 14 00:51:42 2022 +0200
+++ b/.emacs-my	Wed Dec 14 00:58:57 2022 +0200
@@ -580,8 +580,10 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 (message "Cygwin, MSYS")
 
-(when (and (eq system-type 'cygwin) (fboundp #'cygwin-winpath-activate))
-  (cygwin-winpath-activate))
+(when (and (eq system-type 'cygwin) (fboundp #'cygpath-nt-activate))
+  (cygpath-nt-activate))
+(when (and (eq system-type 'windows-nt) cygpath-msys-root (fboundp #'cygpath-msys-activate))
+  (cygpath-msys-activate))
 
 ;; Add some standard places to PATH if they are not set by login script.
 ;; Rearrange the order of paths so system's are first, user's are last.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mylisp/cygpath.el	Wed Dec 14 00:58:57 2022 +0200
@@ -0,0 +1,127 @@
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Handling MSYS paths in NT Emacs.
+
+(defvar cygpath-msys-root nil
+  "Installation root for MSYS.")
+
+(defconst cygpath-msys-drive-regex "\\`/\\([a-z]\\)/"
+  "Regex for identifying MSYS(2) drive-like paths.")
+(defconst cygpath-msys-root-dirs (list "bin" "clang32" "clang64" "clangarm64" "etc" "home" "mingw32" "mingw64" "opt" "srv" "tmp" "ucrt64" "usr" "var")
+  "Root directories to be recognized as MSYS paths.")
+(defun cygpath-msys-root--regex ()
+    "Build regex for matching MSYS root dirs."
+    (format "\\`/%s" (regexp-opt cygpath-msys-root-dirs)))
+(defconst cygpath-msys-root--regex nil
+    "Regex for matching MSYS root dirs. Automatically regenerated by
+the function `cygpath-msys-root--regex'.")
+
+(defun cygpath-msys-to-nt (msyspath)
+  "Coverts MSYS style path to NT path."
+  (cond
+   ((string-match cygpath-msys-drive-regex msyspath)
+    (concat (match-string 1 msyspath) ":\\" (string-replace "/" "\\" (substring msyspath (match-end 0)))))
+   ((string-match cygpath-msys-root--regex msyspath)
+    (concat cygpath-msys-root (string-replace "/" "\\" msyspath)))
+   (t msyspath)))
+
+;; (cygpath-msys-to-nt "/c/")
+;; (cygpath-msys-to-nt "/c/Users")
+;; (setq cygpath-msys-root--regex (cygpath-msys-root--regex))
+;; (cygpath-msys-to-nt "/etc/fstab")
+
+(defun cygpath-msys--mapping-function (op msyspath &rest args)
+  (let ((inhibit-file-name-handlers (cons #'cygpath-msys--mapping-function inhibit-file-name-handlers))
+        (inhibit-file-name-operation op))
+    (apply op (cygpath-msys-to-nt msyspath) args)))
+
+(defvar cygpath-msys-activated nil)
+
+(defun cygpath-msys--fail-if-not-nt ()
+  (unless (eq system-type 'windows-nt)
+    (error "`cygpath-msys' mode makes sense only in NT Emacs."))
+  (unless cygpath-msys-root
+    (error "`cygpath-msys-root' is not defined."))
+  (unless (file-directory-p cygpath-msys-root)
+    (error "`cygpath-msys-root' is a directory.")))
+
+;;;###autoload
+(defun cygpath-msys-activate ()
+  "Start interpret MSYS(2) paths inside NT Emacs."
+  (interactive)
+  (cygpath-msys--fail-if-not-nt)
+  (unless cygpath-msys-activated
+    (setq cygpath-msys-root--regex (cygpath-msys-root--regex))
+    (mapc (lambda (regex)
+            (add-to-list 'file-name-handler-alist (cons regex #'cygpath-msys--mapping-function)))
+          (list cygpath-msys-drive-regex (cygpath-msys-root--regex)))
+    (setq cygpath-msys-activated t)))
+
+;;;###autoload
+(defun cygpath-msys-deactivate ()
+  "Stop interpret MSYS(2) paths inside NT Emacs."
+  (interactive)
+  (cygpath-msys--fail-if-not-nt)
+  (when cygpath-msys-activated
+    (setf file-name-handler-alist (cl-delete #'cygpath-msys--mapping-function file-name-handler-alist :key #'cdr :test #'eq))
+    (setq cygpath-msys-activated nil)))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Handling Windows paths in Cygwin Emacs.
+
+(defvar cygpath-nt-cygdrive-prefix "/cygdrive"
+  "For MSYS set to empty string!")
+
+(defconst cygpath-nt-regex-forward-slash "\\`\\([a-zA-Z]\\):/")
+(defconst cygpath-nt-regex-backward-slash "\\`\\([a-zA-Z]\\):\\\\")
+(defconst cygpath-nt-regex-list (list cygpath-nt-regex-forward-slash cygpath-nt-regex-backward-slash))
+
+(defun cygpath-nt-to-cygwin (winpath)
+  (cond
+   ((string-match cygpath-nt-regex-forward-slash winpath)
+    (concat cygpath-nt-cygdrive-prefix "/" (downcase (match-string 1 winpath)) "/" (substring winpath (match-end 0))))
+   ((string-match cygpath-nt-regex-backward-slash winpath)
+    (concat cygpath-nt-cygdrive-prefix "/" (downcase (match-string 1 winpath)) "/" (replace-regexp-in-string "\\\\" "/" (substring winpath (match-end 0)))))
+   (t winpath)))
+
+;; (cygpath-nt-to-cygwin "c:/home/my.txt")
+;; (cygpath-nt-to-cygwin "c:\\home\\my.txt")
+
+(defun cygpath-nt--mapping-function (op winname &rest args)
+  (let ((inhibit-file-name-handlers (cons #'cygpath-nt--mapping-function inhibit-file-name-handlers))
+        (inhibit-file-name-operation op))
+    (apply op (cygpath-nt-to-cygwin winname) args)))
+
+(defvar cygpath-nt-activated nil)
+
+(defun cygpath-nt--fail-if-not-cygwin ()
+  (unless (eq system-type 'cygwin)
+    (error "Mode is suppose to work only inside Cygwin")))
+
+;;;###autoload
+(defun cygpath-nt-activate ()
+  "Start interpret Windows paths inside Cygwin Emacs."
+  (interactive)
+  (cygpath-nt--fail-if-not-cygwin)
+  (unless cygpath-nt-activated
+    (mapc (lambda (regex)
+            (add-to-list 'file-name-handler-alist (cons regex #'cygpath-nt--mapping-function)))
+          cygpath-nt-regex-list)
+    (setq cygpath-nt-activated t)))
+
+;;;###autoload
+(defun cygpath-nt-deactivate ()
+  "Stop interpret Windows paths inside Cygwin Emacs."
+  (interactive)
+  (cygpath-nt--fail-if-not-cygwin)
+  (when cygpath-nt-activated
+    (mapc (lambda (regex)
+            (setf file-name-handler-alist (cl-delete regex file-name-handler-alist :key #'car :test #'equal)))
+          cygpath-nt-regex-list)
+    (setq cygpath-nt-activated t)))
+
+
+(provide 'cygpath-msys)
+(provide 'cygpath-nt)
+
+(provide 'cygpath)
--- a/mylisp/cygwin-winpath.el	Wed Dec 14 00:51:42 2022 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-
-(defvar cygwin-winpath-cygdrive-prefix "/cygdrive")
-
-(defconst cygwin-winpath-regex-forward-slash "\\`\\([a-zA-Z]\\):/")
-(defconst cygwin-winpath-regex-backward-slash "\\`\\([a-zA-Z]\\):\\\\")
-(defconst cygwin-winpath-regex-list (list cygwin-winpath-regex-forward-slash cygwin-winpath-regex-backward-slash))
-
-(defun cygwin-winpath-cygwin-file-name (winpath)
-  (cond
-   ((string-match cygwin-winpath-regex-forward-slash winpath)
-    (concat cygwin-winpath-cygdrive-prefix "/" (downcase (match-string 1 winpath)) "/" (substring winpath (match-end 0))))
-   ((string-match cygwin-winpath-regex-backward-slash winpath)
-    (concat cygwin-winpath-cygdrive-prefix "/" (downcase (match-string 1 winpath)) "/" (replace-regexp-in-string "\\\\" "/" (substring winpath (match-end 0)))))
-   (t winpath)))
-
-;; (cygwin-winpath-cygwin-file-name "c:/home/my.txt")
-;; (cygwin-winpath-cygwin-file-name "c:\\home\\my.txt")
-
-(defun cygwin-winpath--mapping-function (op winname &rest args)
-  (let ((inhibit-file-name-handlers (cons #'cygwin-winpath--mapping-function inhibit-file-name-handlers))
-        (inhibit-file-name-operation op))
-    (apply op (cygwin-winpath-cygwin-file-name winname) args)))
-
-(defvar cygwin-winpath-activated nil)
-
-(defun cygwin-winpath--fail-if-not-cygwin ()
-  (unless (eq system-type 'cygwin)
-    (error "Mode is suppose to work only inside Cygwin")))
-
-;;;###autoload
-(defun cygwin-winpath-activate ()
-  "Start interpret Windows paths inside Cygwin Emacs."
-  (interactive)
-  (cygwin-winpath--fail-if-not-cygwin)
-  (unless cygwin-winpath-activated
-    (mapc (lambda (regex)
-            (add-to-list 'file-name-handler-alist (cons regex #'cygwin-winpath--mapping-function)))
-          cygwin-winpath-regex-list)
-    (setq cygwin-winpath-activated t)))
-
-;;;###autoload
-(defun cygwin-winpath-deactivate ()
-  "Stop interpret Windows paths inside Cygwin Emacs."
-  (interactive)
-  (cygwin-winpath--fail-if-not-cygwin)
-  (when cygwin-winpath-activated
-    (mapc (lambda (regex)
-            (setf file-name-handler-alist (cl-delete regex file-name-handler-alist :key #'car :test #'equal)))
-          cygwin-winpath-regex-list)
-    (setq cygwin-winpath-activated t)))
-
-(provide 'cygwin-winpath)