diff options
Diffstat (limited to 'lisp/progmodes/python.el')
| -rw-r--r-- | lisp/progmodes/python.el | 89 |
1 files changed, 59 insertions, 30 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index 98f37fc2ac4..7284e7a1ed9 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el | |||
| @@ -35,8 +35,9 @@ | |||
| 35 | ;; keeping it simple :) | 35 | ;; keeping it simple :) |
| 36 | 36 | ||
| 37 | ;; Implements Syntax highlighting, Indentation, Movement, Shell | 37 | ;; Implements Syntax highlighting, Indentation, Movement, Shell |
| 38 | ;; interaction, Shell completion, Pdb tracking, Symbol completion, | 38 | ;; interaction, Shell completion, Shell virtualenv support, Pdb |
| 39 | ;; Skeletons, FFAP, Code Check, Eldoc, imenu. | 39 | ;; tracking, Symbol completion, Skeletons, FFAP, Code Check, Eldoc, |
| 40 | ;; imenu. | ||
| 40 | 41 | ||
| 41 | ;; Syntax highlighting: Fontification of code is provided and supports | 42 | ;; Syntax highlighting: Fontification of code is provided and supports |
| 42 | ;; python's triple quoted strings properly. | 43 | ;; python's triple quoted strings properly. |
| @@ -84,12 +85,12 @@ | |||
| 84 | ;; pyreadline from http://ipython.scipy.org/moin/PyReadline/Intro and | 85 | ;; pyreadline from http://ipython.scipy.org/moin/PyReadline/Intro and |
| 85 | ;; you should be good to go. | 86 | ;; you should be good to go. |
| 86 | 87 | ||
| 87 | ;; The shell also contains support for virtualenvs and other special | 88 | ;; Shell virtualenv support: The shell also contains support for |
| 88 | ;; environment modification thanks to | 89 | ;; virtualenvs and other special environment modifications thanks to |
| 89 | ;; `python-shell-process-environment' and `python-shell-exec-path'. | 90 | ;; `python-shell-process-environment' and `python-shell-exec-path'. |
| 90 | ;; These two variables allows you to modify execution paths and | 91 | ;; These two variables allows you to modify execution paths and |
| 91 | ;; enviroment variables to make easy for you to setup virtualenv rules | 92 | ;; enviroment variables to make easy for you to setup virtualenv rules |
| 92 | ;; or behaviors modifications when running shells. Here is an example | 93 | ;; or behavior modifications when running shells. Here is an example |
| 93 | ;; of how to make shell processes to be run using the /path/to/env/ | 94 | ;; of how to make shell processes to be run using the /path/to/env/ |
| 94 | ;; virtualenv: | 95 | ;; virtualenv: |
| 95 | 96 | ||
| @@ -104,6 +105,15 @@ | |||
| 104 | ;; "VIRTUAL_ENV=/path/to/env/")) | 105 | ;; "VIRTUAL_ENV=/path/to/env/")) |
| 105 | ;; (python-shell-exec-path . ("/path/to/env/bin/")) | 106 | ;; (python-shell-exec-path . ("/path/to/env/bin/")) |
| 106 | 107 | ||
| 108 | ;; Since the above is cumbersome and can be programatically | ||
| 109 | ;; calculated, the variable `python-shell-virtualenv-path' is | ||
| 110 | ;; provided. When this variable is set with the path of the | ||
| 111 | ;; virtualenv to use, `process-environment' and `exec-path' get proper | ||
| 112 | ;; values in order to run shells inside the specified virtualenv. So | ||
| 113 | ;; the following will achieve the same as the previous example: | ||
| 114 | |||
| 115 | ;; (setq python-shell-virtualenv-path "/path/to/env/") | ||
| 116 | |||
| 107 | ;; Pdb tracking: when you execute a block of code that contains some | 117 | ;; Pdb tracking: when you execute a block of code that contains some |
| 108 | ;; call to pdb (or ipdb) it will prompt the block of code and will | 118 | ;; call to pdb (or ipdb) it will prompt the block of code and will |
| 109 | ;; follow the execution of pdb marking the current line with an arrow. | 119 | ;; follow the execution of pdb marking the current line with an arrow. |
| @@ -160,11 +170,6 @@ | |||
| 160 | 170 | ||
| 161 | ;;; TODO: | 171 | ;;; TODO: |
| 162 | 172 | ||
| 163 | ;; Ordered by priority: | ||
| 164 | |||
| 165 | ;; Give a better interface for virtualenv support in interactive | ||
| 166 | ;; shells | ||
| 167 | |||
| 168 | ;;; Code: | 173 | ;;; Code: |
| 169 | 174 | ||
| 170 | (require 'ansi-color) | 175 | (require 'ansi-color) |
| @@ -1085,6 +1090,16 @@ default `exec-path'." | |||
| 1085 | :group 'python | 1090 | :group 'python |
| 1086 | :safe 'listp) | 1091 | :safe 'listp) |
| 1087 | 1092 | ||
| 1093 | (defcustom python-shell-virtualenv-path nil | ||
| 1094 | "Path to virtualenv root. | ||
| 1095 | This variable, when set to a string, makes the values stored in | ||
| 1096 | `python-shell-process-environment' and `python-shell-exec-path' | ||
| 1097 | to be modified properly so shells are started with the specified | ||
| 1098 | virtualenv." | ||
| 1099 | :type 'string | ||
| 1100 | :group 'python | ||
| 1101 | :safe 'stringp) | ||
| 1102 | |||
| 1088 | (defcustom python-shell-setup-codes '(python-shell-completion-setup-code | 1103 | (defcustom python-shell-setup-codes '(python-shell-completion-setup-code |
| 1089 | python-ffap-setup-code | 1104 | python-ffap-setup-code |
| 1090 | python-eldoc-setup-code) | 1105 | python-eldoc-setup-code) |
| @@ -1141,12 +1156,42 @@ uniqueness for different types of configurations." | |||
| 1141 | (python-shell-parse-command) | 1156 | (python-shell-parse-command) |
| 1142 | (mapconcat #'symbol-value python-shell-setup-codes "") | 1157 | (mapconcat #'symbol-value python-shell-setup-codes "") |
| 1143 | (mapconcat #'indentity python-shell-process-environment "") | 1158 | (mapconcat #'indentity python-shell-process-environment "") |
| 1159 | (or python-shell-virtualenv-path "") | ||
| 1144 | (mapconcat #'indentity python-shell-exec-path ""))))) | 1160 | (mapconcat #'indentity python-shell-exec-path ""))))) |
| 1145 | 1161 | ||
| 1146 | (defun python-shell-parse-command () | 1162 | (defun python-shell-parse-command () |
| 1147 | "Calculate the string used to execute the inferior Python process." | 1163 | "Calculate the string used to execute the inferior Python process." |
| 1148 | (format "%s %s" python-shell-interpreter python-shell-interpreter-args)) | 1164 | (format "%s %s" python-shell-interpreter python-shell-interpreter-args)) |
| 1149 | 1165 | ||
| 1166 | (defun python-shell-calculate-process-enviroment () | ||
| 1167 | "Calculate process enviroment given `python-shell-virtualenv-path'." | ||
| 1168 | (let ((env (python-util-merge 'list python-shell-process-environment | ||
| 1169 | process-environment 'string=)) | ||
| 1170 | (virtualenv (if python-shell-virtualenv-path | ||
| 1171 | (directory-file-name python-shell-virtualenv-path) | ||
| 1172 | nil))) | ||
| 1173 | (if (not virtualenv) | ||
| 1174 | env | ||
| 1175 | (dolist (envvar env) | ||
| 1176 | (let* ((split (split-string envvar "=" t)) | ||
| 1177 | (name (nth 0 split)) | ||
| 1178 | (value (nth 1 split))) | ||
| 1179 | (when (not (string= name "PYTHONHOME")) | ||
| 1180 | (when (string= name "PATH") | ||
| 1181 | (setq value (format "%s/bin:%s" virtualenv value))) | ||
| 1182 | (setq env (cons (format "%s=%s" name value) env))))) | ||
| 1183 | (cons (format "VIRTUAL_ENV=%s" virtualenv) env)))) | ||
| 1184 | |||
| 1185 | (defun python-shell-calculate-exec-path () | ||
| 1186 | "Calculate exec path given `python-shell-virtualenv-path'." | ||
| 1187 | (let ((path (python-util-merge 'list python-shell-exec-path | ||
| 1188 | exec-path 'string=))) | ||
| 1189 | (if (not python-shell-virtualenv-path) | ||
| 1190 | path | ||
| 1191 | (cons (format "%s/bin" | ||
| 1192 | (directory-file-name python-shell-virtualenv-path)) | ||
| 1193 | path)))) | ||
| 1194 | |||
| 1150 | (defun python-comint-output-filter-function (output) | 1195 | (defun python-comint-output-filter-function (output) |
| 1151 | "Hook run after content is put into comint buffer. | 1196 | "Hook run after content is put into comint buffer. |
| 1152 | OUTPUT is a string with the contents of the buffer." | 1197 | OUTPUT is a string with the contents of the buffer." |
| @@ -1220,16 +1265,8 @@ run). | |||
| 1220 | (list nil (python-shell-parse-command)))) | 1265 | (list nil (python-shell-parse-command)))) |
| 1221 | (let* ((proc-name (python-shell-get-process-name dedicated)) | 1266 | (let* ((proc-name (python-shell-get-process-name dedicated)) |
| 1222 | (proc-buffer-name (format "*%s*" proc-name)) | 1267 | (proc-buffer-name (format "*%s*" proc-name)) |
| 1223 | (process-environment | 1268 | (process-environment (python-shell-calculate-process-enviroment)) |
| 1224 | (if python-shell-process-environment | 1269 | (exec-path (python-shell-calculate-exec-path))) |
| 1225 | (python-util-merge 'list python-shell-process-environment | ||
| 1226 | process-environment 'string=) | ||
| 1227 | process-environment)) | ||
| 1228 | (exec-path | ||
| 1229 | (if python-shell-exec-path | ||
| 1230 | (python-util-merge 'list python-shell-exec-path | ||
| 1231 | exec-path 'string=) | ||
| 1232 | exec-path))) | ||
| 1233 | (when (not (comint-check-proc proc-buffer-name)) | 1270 | (when (not (comint-check-proc proc-buffer-name)) |
| 1234 | (let ((cmdlist (split-string-and-unquote cmd))) | 1271 | (let ((cmdlist (split-string-and-unquote cmd))) |
| 1235 | (set-buffer | 1272 | (set-buffer |
| @@ -1258,16 +1295,8 @@ of commands.)" | |||
| 1258 | (let* ((cmd (python-shell-parse-command)) | 1295 | (let* ((cmd (python-shell-parse-command)) |
| 1259 | (proc-name (python-shell-internal-get-process-name)) | 1296 | (proc-name (python-shell-internal-get-process-name)) |
| 1260 | (proc-buffer-name (format "*%s*" proc-name)) | 1297 | (proc-buffer-name (format "*%s*" proc-name)) |
| 1261 | (process-environment | 1298 | (process-environment (python-shell-calculate-process-enviroment)) |
| 1262 | (if python-shell-process-environment | 1299 | (exec-path (python-shell-calculate-exec-path))) |
| 1263 | (python-util-merge 'list python-shell-process-environment | ||
| 1264 | process-environment 'string=) | ||
| 1265 | process-environment)) | ||
| 1266 | (exec-path | ||
| 1267 | (if python-shell-exec-path | ||
| 1268 | (python-util-merge 'list python-shell-exec-path | ||
| 1269 | exec-path 'string=) | ||
| 1270 | exec-path))) | ||
| 1271 | (when (not (comint-check-proc proc-buffer-name)) | 1300 | (when (not (comint-check-proc proc-buffer-name)) |
| 1272 | (let ((cmdlist (split-string-and-unquote cmd))) | 1301 | (let ((cmdlist (split-string-and-unquote cmd))) |
| 1273 | (set-buffer | 1302 | (set-buffer |