aboutsummaryrefslogtreecommitdiff
path: root/duet.el
diff options
context:
space:
mode:
Diffstat (limited to 'duet.el')
-rw-r--r--duet.el42
1 files changed, 42 insertions, 0 deletions
diff --git a/duet.el b/duet.el
index 364a7c4..9ab858b 100644
--- a/duet.el
+++ b/duet.el
@@ -33,11 +33,53 @@
;;; Code:
+(require 'tramp)
+
(defgroup duet nil
"Dual-pane file commander over dirvish/dired."
:group 'files
:prefix "duet-")
+;;; Path classification
+
+(defun duet--classify-path (path)
+ "Classify PATH into a plist describing its locality and components.
+
+The returned plist has these keys:
+
+ :locality `local' or `remote'
+ :method TRAMP method (e.g. \"ssh\"), or nil when local
+ :user remote user, or nil
+ :host remote host (the final hop for a multi-hop path), or nil
+ :port remote port as a string, or nil
+ :localname the path on the target filesystem
+ :hop the leading-hops string for a multi-hop path, or nil
+
+TRAMP performs the dissection, so any path `file-remote-p' recognizes is
+remote and everything else is local. A local PATH has its name expanded
+\(so a leading ~ resolves to the home directory); a remote localname is kept
+verbatim because a ~ there is the remote home, not this machine's.
+
+Classification is total: a TRAMP-looking string TRAMP does not accept as a
+remote name (an incomplete \"/ssh:host\") is treated as a local path rather
+than signaling. Validating raw TRAMP input is the connection reader's job."
+ (if (file-remote-p path)
+ (let ((v (tramp-dissect-file-name path)))
+ (list :locality 'remote
+ :method (tramp-file-name-method v)
+ :user (tramp-file-name-user v)
+ :host (tramp-file-name-host v)
+ :port (tramp-file-name-port v)
+ :localname (tramp-file-name-localname v)
+ :hop (tramp-file-name-hop v)))
+ (list :locality 'local
+ :method nil
+ :user nil
+ :host nil
+ :port nil
+ :localname (expand-file-name path)
+ :hop nil)))
+
;;;###autoload
(defun duet ()
"Launch the DUET dual-pane file commander."