mylisp/cygwin-winpath.el
author Oleksandr Gavenko <gavenkoa@gmail.com>
Wed, 02 Jun 2021 00:34:11 +0300
changeset 1731 fec5d1fffe8c
permissions -rw-r--r--
Added mode for recognition of Windows paths in Cygwin Emacs.


(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)