Skip to content

Commit 3355e62

Browse files
committed
Add local to remote directory aliases.
1 parent 82f8d49 commit 3355e62

File tree

1 file changed

+86
-35
lines changed

1 file changed

+86
-35
lines changed

pythonic.el

Lines changed: 86 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -32,60 +32,109 @@
3232
(require 's)
3333
(require 'f)
3434

35+
36+
;;; Connection predicates.
37+
38+
(defun pythonic-local-p ()
39+
"Determine local virtual environment."
40+
(not (pythonic-remote-p)))
41+
3542
(defun pythonic-remote-p ()
36-
"Determine remote or local virtual environment."
37-
(tramp-tramp-file-p default-directory))
43+
"Determine remote virtual environment."
44+
(tramp-tramp-file-p (pythonic-aliased-path default-directory)))
3845

3946
(defun pythonic-remote-docker-p ()
4047
"Determine docker remote virtual environment."
4148
(and (pythonic-remote-p)
42-
(s-starts-with-p "/docker:" (pythonic-remote-connection))))
49+
(s-equals-p (pythonic-remote-method) "docker")))
4350

4451
(defun pythonic-remote-vagrant-p ()
4552
"Determine vagrant remote virtual environment."
4653
(and (pythonic-remote-p)
4754
(s-equals-p (pythonic-remote-host) "localhost")
4855
(s-equals-p (pythonic-remote-user) "vagrant")))
4956

57+
58+
;;; Connection properties.
59+
60+
(defun pythonic-remote-method ()
61+
"Get tramp method of the connection to the remote python interpreter."
62+
(tramp-file-name-method (tramp-dissect-file-name (pythonic-aliased-path default-directory))))
63+
5064
(defun pythonic-remote-user ()
5165
"Get user of the connection to the remote python interpreter."
52-
(tramp-file-name-user (tramp-dissect-file-name (pythonic-remote-connection))))
66+
(tramp-file-name-user (tramp-dissect-file-name (pythonic-aliased-path default-directory))))
5367

5468
(defun pythonic-remote-host ()
5569
"Get host of the connection to the remote python interpreter."
56-
(replace-regexp-in-string
57-
"#.*\\'" ""
58-
(tramp-file-name-host (tramp-dissect-file-name (pythonic-remote-connection)))))
70+
(let ((hostname (tramp-file-name-host (tramp-dissect-file-name (pythonic-aliased-path default-directory)))))
71+
(replace-regexp-in-string "#.*\\'" "" hostname)))
5972

6073
(defun pythonic-remote-port ()
6174
"Get port of the connection to the remote python interpreter."
62-
(let ((hostname (tramp-file-name-host (tramp-dissect-file-name (pythonic-remote-connection)))))
75+
(let ((hostname (tramp-file-name-host (tramp-dissect-file-name (pythonic-aliased-path default-directory)))))
6376
(when (s-contains-p "#" hostname)
6477
(string-to-number (replace-regexp-in-string "\\`.*#" "" hostname)))))
6578

66-
(defun pythonic-local-file-name (file)
67-
"Local FILE name with out tramp prefix."
68-
(if (tramp-tramp-file-p file)
69-
(tramp-file-name-localname (tramp-dissect-file-name file))
70-
file))
71-
72-
(defun pythonic-real-file-name (file)
73-
"Probably Remote FILE name with tramp prefix."
74-
(if (and (pythonic-remote-p)
75-
(not (tramp-tramp-file-p file)))
76-
(concat (pythonic-remote-connection) file)
77-
file))
78-
79-
(defun pythonic-real-directory-name (directory)
80-
"Generate `default-directory' FROM-DIRECTORY."
81-
(let ((default-directory (pythonic-real-file-name directory)))
82-
(f-full default-directory)))
83-
84-
(defun pythonic-remote-connection ()
85-
"Tramp connection string or nil."
86-
(when (pythonic-remote-p)
87-
(substring default-directory 0 (- (length default-directory)
88-
(length (pythonic-local-file-name default-directory))))))
79+
80+
;;; File names.
81+
82+
(defvar pythonic-directory-aliases nil)
83+
84+
(defun pythonic-aliased-path (path)
85+
"Get aliased PATH."
86+
(let ((alias-tuple (cl-find-if
87+
(lambda (it)
88+
(or (f-same-p (car it) path)
89+
(f-ancestor-of-p (car it) path)))
90+
pythonic-directory-aliases)))
91+
(if (null alias-tuple)
92+
path
93+
(concat (cadr alias-tuple)
94+
(substring path (length (car alias-tuple)))))))
95+
96+
(defun pythonic-unaliased-path (alias)
97+
"Get real path from ALIAS."
98+
(let ((alias-tuple (cl-find-if
99+
(lambda (it)
100+
(or (f-same-p (cadr it) alias)
101+
(f-ancestor-of-p (cadr it) alias)))
102+
pythonic-directory-aliases)))
103+
(if (null alias-tuple)
104+
alias
105+
(concat (car alias-tuple)
106+
(substring alias (length (cadr alias-tuple)))))))
107+
108+
(defun pythonic-python-readable-file-name (filename)
109+
"Emacs to Python FILENAME conversion.
110+
Take FILENAME from the perspective of the localhost and translate
111+
it to the FILENAME Python process can read. Python can be
112+
running locally or remotely. FILENAME can have local or tramp
113+
format. Result will have local format."
114+
(let ((alias (pythonic-aliased-path filename)))
115+
(if (tramp-tramp-file-p alias)
116+
(tramp-file-name-localname (tramp-dissect-file-name alias))
117+
alias)))
118+
119+
(defun pythonic-emacs-readable-file-name (filename)
120+
"Python to Emacs FILENAME conversion.
121+
Take FILENAME from the perspective of the python interpreter and
122+
translate it to the FILENAME Emacs `find-file' command can
123+
understand. Python can be running locally or remotely. FILENAME
124+
should have local format. Result can have local or tramp
125+
format."
126+
(when (tramp-tramp-file-p filename)
127+
(error "%s can not be tramp path" filename))
128+
(if (pythonic-remote-p)
129+
(let* ((directory (pythonic-aliased-path default-directory))
130+
(connection (substring directory 0
131+
(- (length directory)
132+
(length (tramp-file-name-localname (tramp-dissect-file-name directory)))))))
133+
(pythonic-unaliased-path (concat connection filename)))
134+
filename))
135+
136+
137+
;;; Processes.
89138

90139
(cl-defun pythonic-call-process (&key file buffer display args cwd)
91140
"Pythonic wrapper around `call-process'.
@@ -94,7 +143,7 @@ FILE is the input file. BUFFER is the output destination. DISPLAY
94143
specifies to redisplay BUFFER on new output. ARGS is the list of
95144
arguments passed to `call-process'. CWD will be working directory
96145
for running process."
97-
(let ((default-directory (pythonic-real-directory-name (or cwd "~"))))
146+
(let ((default-directory (pythonic-aliased-path (or cwd default-directory))))
98147
(python-shell-with-environment
99148
(apply 'process-file python-shell-interpreter file buffer display args))))
100149

@@ -108,7 +157,7 @@ process. FILTER must be a symbol of process filter function if
108157
necessary. SENTINEL must be a symbol of process sentinel
109158
function if necessary. QUERY-ON-EXIT will be corresponding
110159
process flag."
111-
(let ((default-directory (pythonic-real-directory-name (or cwd "~"))))
160+
(let ((default-directory (pythonic-aliased-path (or cwd default-directory))))
112161
(python-shell-with-environment
113162
(let ((process (apply 'start-file-process process buffer python-shell-interpreter args)))
114163
(when filter
@@ -118,12 +167,14 @@ process flag."
118167
(set-process-query-on-exit-flag process query-on-exit)
119168
process))))
120169

170+
171+
;;; Commands.
172+
121173
;;;###autoload
122174
(defun pythonic-activate (virtualenv)
123175
"Activate python VIRTUALENV."
124176
(interactive "DEnv: ")
125-
(setq python-shell-virtualenv-root
126-
(pythonic-local-file-name (pythonic-real-directory-name virtualenv))))
177+
(setq python-shell-virtualenv-root (pythonic-python-readable-file-name virtualenv)))
127178

128179
;;;###autoload
129180
(defun pythonic-deactivate ()

0 commit comments

Comments
 (0)