In addition to interpreting Windows paths in Cygwin a handler is added for interpreting MSYS paths in NT Emacs.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 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)