diff options
| author | Fabián Ezequiel Gallina | 2012-05-17 00:02:57 -0300 |
|---|---|---|
| committer | Fabián Ezequiel Gallina | 2012-05-17 00:02:57 -0300 |
| commit | 075a0f6194c052a2dfc7bd7b8d267f5188fa1923 (patch) | |
| tree | e06705586421edb945f3e88798b875e8a3fa047d | |
| parent | 3d6913c7d1737ffbe4163cf0f8a19c4d09f2dbc7 (diff) | |
| download | emacs-075a0f6194c052a2dfc7bd7b8d267f5188fa1923.tar.gz emacs-075a0f6194c052a2dfc7bd7b8d267f5188fa1923.zip | |
Enhanced shell and code autocompletion.
python-shell-completion-complete-at-point and
python-completion-complete-at-point now share common code.
Also lots of fixes related to the cleanup of shell output has been
made so completion code is really robust now.
| -rw-r--r-- | lisp/progmodes/python.el | 136 |
1 files changed, 54 insertions, 82 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index b9cbfdd3b4d..114b2ff1775 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el | |||
| @@ -1138,6 +1138,45 @@ It is specially designed to be added to the | |||
| 1138 | (define-key inferior-python-mode-map (kbd "<tab>") | 1138 | (define-key inferior-python-mode-map (kbd "<tab>") |
| 1139 | 'python-shell-completion-complete-or-indent))) | 1139 | 'python-shell-completion-complete-or-indent))) |
| 1140 | 1140 | ||
| 1141 | (defun python-shell-completion--get-completions (input process) | ||
| 1142 | "Retrieve available completions for INPUT using PROCESS." | ||
| 1143 | (with-current-buffer (process-buffer process) | ||
| 1144 | (let ((completions)) | ||
| 1145 | (python-shell-send-string | ||
| 1146 | (format python-shell-completion-strings-code input) | ||
| 1147 | process) | ||
| 1148 | (accept-process-output process) | ||
| 1149 | (when comint-last-output-start | ||
| 1150 | (setq completions | ||
| 1151 | (split-string | ||
| 1152 | (buffer-substring-no-properties | ||
| 1153 | comint-last-output-start | ||
| 1154 | (save-excursion | ||
| 1155 | (goto-char comint-last-output-start) | ||
| 1156 | (line-end-position))) | ||
| 1157 | ";\\|\"\\|'\\|(" t)) | ||
| 1158 | (comint-delete-output) | ||
| 1159 | completions)))) | ||
| 1160 | |||
| 1161 | (defun python-shell-completion--get-completion (input completions) | ||
| 1162 | "Get completion for INPUT using COMPLETIONS." | ||
| 1163 | (let ((completion (when completions | ||
| 1164 | (try-completion input completions)))) | ||
| 1165 | (cond ((eq completion t) | ||
| 1166 | input) | ||
| 1167 | ((null completion) | ||
| 1168 | (message "Can't find completion for \"%s\"" input) | ||
| 1169 | (ding) | ||
| 1170 | input) | ||
| 1171 | ((not (string= input completion)) | ||
| 1172 | completion) | ||
| 1173 | (t | ||
| 1174 | (message "Making completion list...") | ||
| 1175 | (with-output-to-temp-buffer "*Python Completions*" | ||
| 1176 | (display-completion-list | ||
| 1177 | (all-completions input completions))) | ||
| 1178 | input)))) | ||
| 1179 | |||
| 1141 | (defun python-shell-completion-complete-at-point () | 1180 | (defun python-shell-completion-complete-at-point () |
| 1142 | "Perform completion at point in inferior Python process." | 1181 | "Perform completion at point in inferior Python process." |
| 1143 | (interactive) | 1182 | (interactive) |
| @@ -1145,43 +1184,12 @@ It is specially designed to be added to the | |||
| 1145 | (when (and comint-last-prompt-overlay | 1184 | (when (and comint-last-prompt-overlay |
| 1146 | (> (point-marker) (overlay-end comint-last-prompt-overlay))) | 1185 | (> (point-marker) (overlay-end comint-last-prompt-overlay))) |
| 1147 | (let* ((process (get-buffer-process (current-buffer))) | 1186 | (let* ((process (get-buffer-process (current-buffer))) |
| 1148 | (input (comint-word (current-word))) | 1187 | (input (substring-no-properties |
| 1149 | (completions (when input | 1188 | (or (comint-word (current-word)) "") nil nil))) |
| 1150 | (delete-region (point-marker) | 1189 | (delete-char (- (length input))) |
| 1151 | (progn | 1190 | (insert |
| 1152 | (forward-char (- (length input))) | 1191 | (python-shell-completion--get-completion |
| 1153 | (point-marker))) | 1192 | input (python-shell-completion--get-completions input process))))))) |
| 1154 | (message (format python-shell-completion-strings-code input)) | ||
| 1155 | (python-shell-send-string | ||
| 1156 | (format python-shell-completion-strings-code input) | ||
| 1157 | process) | ||
| 1158 | (split-string | ||
| 1159 | (save-excursion | ||
| 1160 | (if (not comint-last-output-start) | ||
| 1161 | "" | ||
| 1162 | (goto-char comint-last-output-start) | ||
| 1163 | (buffer-substring-no-properties | ||
| 1164 | (point-marker) (line-end-position)))) | ||
| 1165 | ";\\|\"\\|'\\|(" t))) | ||
| 1166 | (completion (when completions (try-completion input completions)))) | ||
| 1167 | (when completions | ||
| 1168 | (save-excursion | ||
| 1169 | (forward-line -1) | ||
| 1170 | (kill-line 1))) | ||
| 1171 | (cond ((eq completion t) | ||
| 1172 | (when input (insert input))) | ||
| 1173 | ((null completion) | ||
| 1174 | (when input (insert input)) | ||
| 1175 | (message "Can't find completion for \"%s\"" input) | ||
| 1176 | (ding)) | ||
| 1177 | ((not (string= input completion)) | ||
| 1178 | (insert completion)) | ||
| 1179 | (t | ||
| 1180 | (message "Making completion list...") | ||
| 1181 | (when input (insert input)) | ||
| 1182 | (with-output-to-temp-buffer "*Python Completions*" | ||
| 1183 | (display-completion-list | ||
| 1184 | (all-completions input completions))))))))) | ||
| 1185 | 1193 | ||
| 1186 | (defun python-shell-completion-complete-or-indent () | 1194 | (defun python-shell-completion-complete-or-indent () |
| 1187 | "Complete or indent depending on the context. | 1195 | "Complete or indent depending on the context. |
| @@ -1292,51 +1300,15 @@ inferior python process is updated properly." | |||
| 1292 | (let ((process (python-shell-get-process))) | 1300 | (let ((process (python-shell-get-process))) |
| 1293 | (if (not process) | 1301 | (if (not process) |
| 1294 | (error "Completion needs an inferior Python process running") | 1302 | (error "Completion needs an inferior Python process running") |
| 1295 | (let* ((input (when (comint-word (current-word)) | 1303 | (with-syntax-table python-dotty-syntax-table |
| 1296 | (with-syntax-table python-dotty-syntax-table | 1304 | (let* ((input (substring-no-properties |
| 1297 | (buffer-substring (point-marker) | 1305 | (or (comint-word (current-word)) "") nil nil)) |
| 1298 | (save-excursion | 1306 | (completions (python-shell-completion--get-completions |
| 1299 | (forward-word -1) | 1307 | input process))) |
| 1300 | (point-marker)))))) | 1308 | (delete-char (- (length input))) |
| 1301 | (completions (when input | 1309 | (insert |
| 1302 | (delete-region (point-marker) | 1310 | (python-shell-completion--get-completion |
| 1303 | (progn | 1311 | input completions))))))) |
| 1304 | (forward-char (- (length input))) | ||
| 1305 | (point-marker))) | ||
| 1306 | (process-send-string | ||
| 1307 | process | ||
| 1308 | (format | ||
| 1309 | python-shell-completion-strings-code input)) | ||
| 1310 | (accept-process-output process) | ||
| 1311 | (with-current-buffer (process-buffer process) | ||
| 1312 | (save-excursion | ||
| 1313 | (re-search-backward comint-prompt-regexp | ||
| 1314 | comint-last-input-end t) | ||
| 1315 | (split-string | ||
| 1316 | (buffer-substring-no-properties | ||
| 1317 | (point-marker) comint-last-input-end) | ||
| 1318 | ";\\|\"\\|'\\|(" t))))) | ||
| 1319 | (completion (when completions | ||
| 1320 | (try-completion input completions)))) | ||
| 1321 | (with-current-buffer (process-buffer process) | ||
| 1322 | (save-excursion | ||
| 1323 | (forward-line -1) | ||
| 1324 | (kill-line 1))) | ||
| 1325 | (when completions | ||
| 1326 | (cond ((eq completion t) | ||
| 1327 | (insert input)) | ||
| 1328 | ((null completion) | ||
| 1329 | (insert input) | ||
| 1330 | (message "Can't find completion for \"%s\"" input) | ||
| 1331 | (ding)) | ||
| 1332 | ((not (string= input completion)) | ||
| 1333 | (insert completion)) | ||
| 1334 | (t | ||
| 1335 | (message "Making completion list...") | ||
| 1336 | (insert input) | ||
| 1337 | (with-output-to-temp-buffer "*Python Completions*" | ||
| 1338 | (display-completion-list | ||
| 1339 | (all-completions input completions)))))))))) | ||
| 1340 | 1312 | ||
| 1341 | (add-to-list 'debug-ignored-errors "^Completion needs an inferior Python process running.") | 1313 | (add-to-list 'debug-ignored-errors "^Completion needs an inferior Python process running.") |
| 1342 | 1314 | ||