Added mode for recognition of Windows paths in Cygwin Emacs.
authorOleksandr Gavenko <gavenkoa@gmail.com>
Wed, 02 Jun 2021 00:34:11 +0300
changeset 1731 fec5d1fffe8c
parent 1730 795b3f2ecfbb
child 1732 c3279bad1cc3
Added mode for recognition of Windows paths in Cygwin Emacs.
.emacs-my
mylisp/cygwin-winpath.el
--- a/.emacs-my	Wed Jun 02 00:17:06 2021 +0300
+++ b/.emacs-my	Wed Jun 02 00:34:11 2021 +0300
@@ -552,6 +552,9 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 (message "Cygwin, MSYS")
 
+(when (and (eq system-type 'cygwin) (fboundp #'cygwin-winpath-activate))
+  (cygwin-winpath-activate))
+
 (defun follow-cygwin-symlink ()
   "Follow new-style (and also UCS-16) Cygwin symlinks."
   (save-excursion
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mylisp/cygwin-winpath.el	Wed Jun 02 00:34:11 2021 +0300
@@ -0,0 +1,52 @@
+
+(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)