1 ;(autoload 'python-mode "python-mode" "Python Mode." t)
2 ;(add-to-list 'auto-mode-alist '("\\.py\\'" . python-mode))
3 ;(add-to-list 'interpreter-mode-alist '("python" . python-mode))
4 ;(require 'python-mode)
8 (global-unset-key "\C-xpn")
13 (autoload 'pymacs-apply "pymacs")
14 (autoload 'pymacs-call "pymacs")
15 (autoload 'pymacs-eval "pymacs" nil t)
16 (autoload 'pymacs-exec "pymacs" nil t)
17 (autoload 'pymacs-load "pymacs" nil t)
18 ;;(eval-after-load "pymacs"
19 ;; '(add-to-list 'pymacs-load-path YOUR-PYMACS-DIRECTORY"))
20 (pymacs-load "ropemacs" "rope-")
21 (setq ropemacs-enable-autoimport t)
23 ;; M-/ rope-code-assist
24 ;; C-c g rope-goto-definition
25 ;; C-c d rope-show-doc
26 ;; C-c f rope-find-occurrences
27 ;; M-? rope-lucky-assist
29 (define-key ropemacs-local-keymap "\M-/" 'hippie-expand)
31 (defun write-file-py-cleanup-imports ()
34 (py-cleanup-imports t)
38 (defun python-init-auto-cleanup-imports-on-save ()
39 (add-hook 'write-contents-functions 'write-file-py-cleanup-imports nil t))
41 (defun my-flymake-error-at-point ()
43 (flymake-ler-text (car (nth 0 (flymake-find-err-info flymake-err-info
44 (locate-current-line-number)))))
45 (error (error "no flymake error at point"))))
47 (defun my-flymake-show-error ()
49 (message (my-flymake-error-at-point)))
51 (defun my-pyflymake-add-import-from-error ()
53 (let ((err (my-flymake-error-at-point)))
54 (if (string-match "undefined name '\\(.*\\)'" err)
55 (py-add-import (match-string 1 err))
56 (error "no missing symbol at point"))))
58 (defun py-add-import (import)
59 (interactive "sModule to import: ")
60 (save-window-excursion
62 (goto-char (car (py-imports-region)))
63 (insert "import " import "\n")
64 (py-cleanup-imports t)
67 (defun my-flymake-check-and-wait ()
68 (if (boundp flymake-is-running)
70 (while flymake-is-running (sit-for .1))
71 (flymake-start-syntax-check)
72 (while flymake-is-running (sit-for .1)))))
74 (defun my-flymake-goto-next-error ()
76 (my-flymake-check-and-wait)
77 (flymake-goto-next-error)
78 (my-flymake-show-error))
80 (defun my-flymake-goto-prev-error ()
82 (my-flymake-check-and-wait)
83 (flymake-goto-prev-error)
84 (my-flymake-show-error))
86 (defun py-find-file (errormark filename defaultdir)
87 (let ((fullname (expand-file-name filename defaultdir)))
88 (or (and (not (file-exists-p fullname))
89 (let* ((name (loop for name = fullname then (directory-file-name
90 (file-name-directory name))
91 if (file-exists-p name) return name))
92 (fmt (and name (with-temp-buffer
93 (insert-file-contents name nil 0 1024 t) (archive-find-type))))
94 (tail (and fmt (substring fullname (1+ (length name))))))
96 (with-current-buffer (find-file-noselect name)
97 (goto-char (point-min))
98 (re-search-forward (concat " " (regexp-quote tail) "$"))
99 (save-window-excursion
101 (current-buffer))))))
102 (compilation-find-file errormark filename defaultdir))))
106 (defun py-eshell-goto-error (&optional back)
108 (display-buffer "*eshell*" t)
109 (let (here end start dir file line errmk example)
110 (with-current-buffer "*eshell*"
112 ;; Find and validate last traceback
113 (goto-char (point-max))
114 (re-search-backward "^\\(.*\\)Traceback \\|^Failed example:")
116 (if (looking-at "Failed example:")
120 (if (or (not (and (boundp 'py-eshell-last-error)
121 (boundp 'py-eshell-last-point)))
122 (null py-eshell-last-error)
123 (null py-eshell-last-point)
124 (null py-eshell-last-dir)
125 (not (= py-eshell-last-error (point))))
127 (set (make-local-variable 'py-eshell-last-error) (point))
128 (set (make-local-variable 'py-eshell-prefix) (or (match-string 1) ""))
129 (if (string-match "Original $" py-eshell-prefix)
130 (setq py-eshell-prefix (substring py-eshell-prefix 0 (match-beginning 0))))
133 (while (and (< (forward-line 1) 1) (looking-at (concat py-eshell-prefix " ")))))
134 (set (make-local-variable 'py-eshell-last-point) (point))
135 (set (make-local-variable 'py-eshell-last-dir) default-directory)
137 (and (< (forward-line 1) 1)
138 (not (if (looking-at ".*Leaving directory ")
140 (goto-char (match-end 0))
141 (skip-chars-forward "'\"`")
142 (let ((dir (current-word)))
143 (and dir (setq py-eshell-last-dir
144 (file-name-as-directory dir)))))))))))
145 (goto-char py-eshell-last-point)
147 ;; Nove to next / prev frame in traceback
150 (while (and (looking-at (concat py-eshell-prefix " "))
151 (< (forward-line 1) 1)
152 (not (looking-at (concat py-eshell-prefix " File ")))))
154 (while (and (looking-at (concat py-eshell-prefix " "))
155 (< (forward-line 1) 1)
156 (not (looking-at (concat py-eshell-prefix " File ")))))
158 (while (and (> (forward-line -1) -1)
159 (not (looking-at (concat py-eshell-prefix (if example "File " " File "))))
160 (> (point) py-eshell-last-error)))
161 (setq end py-eshell-last-point start (point)))
163 ;; Parse information and set overlay
164 (if (save-excursion (goto-char start) (setq errmk (point-marker))
165 (looking-at (concat py-eshell-prefix (if example "File " " File "))))
166 (let ((default-directory py-eshell-last-dir))
167 (set (make-local-variable 'py-eshell-last-point) start)
168 (if (and (boundp 'py-eshell-overlay) py-eshell-overlay)
169 (move-overlay py-eshell-overlay start end)
170 (set (make-local-variable 'py-eshell-overlay) (make-overlay start end))
171 (overlay-put py-eshell-overlay 'face 'highlight))
174 (forward-char (+ (length py-eshell-prefix) 7))
175 (skip-chars-forward "\"")
176 (setq file (current-word))
177 (search-forward " line ")
178 (skip-chars-forward " ")
179 (setq line (string-to-number
180 (buffer-substring-no-properties
181 (point) (progn (skip-chars-forward "0-9") (point)))))
182 (setq dir default-directory))
184 (error "File not found")))
185 (py-eshell-error-reset)
186 (error "No further traceback line"))))
188 ;; move to error locus
189 (if (and file line errmk)
190 (with-current-buffer (py-find-file errmk file dir)
191 (compilation-goto-locus errmk (save-excursion (goto-line line) (point-marker)) nil)))))
193 (defun py-eshell-error-reset ()
196 (set-buffer "*eshell*")
197 (if (and (boundp 'py-eshell-overlay) py-eshell-overlay)
198 (delete-overlay py-eshell-overlay))
199 (set (make-local-variable 'py-eshell-last-error) nil)
200 (set (make-local-variable 'py-eshell-last-point) nil)
201 (set (make-local-variable 'py-eshell-last-dir) nil)
202 (set (make-local-variable 'py-eshell-prefix) nil)
203 (set (make-local-variable 'py-eshell-overlay) nil)))
205 (global-set-key "\C-xP" 'py-eshell-goto-error)
206 (global-set-key "\C-x\C-p" 'python-shell)
208 (add-hook 'python-mode-hook 'python-init-auto-cleanup-imports-on-save)
210 (defun py-setup-hook ()
211 ;(set-variable 'py-indent-offset 4)
212 ;(set-variable 'py-smart-indentation nil)
213 (set-variable 'indent-tabs-mode nil)
214 ;(define-key py-mode-map (kbd "RET") 'newline-and-indent)
215 ;(define-key py-mode-map [tab] 'yas/expand)
216 ;(setq yas/after-exit-snippet-hook 'indent-according-to-mode)
217 ;(smart-operator-mode-on)
218 (define-key python-mode-map "\C-ci" 'my-pyflymake-add-import-from-error)
219 (define-key python-mode-map "\C-ce" 'my-flymake-show-error)
220 (define-key python-mode-map "\C-cn" 'my-flymake-goto-next-error)
221 (define-key python-mode-map "\C-cp" 'my-flymake-goto-prev-error)
222 (define-key python-mode-map "\C-cI" 'py-cleanup-imports)
225 (add-hook 'python-mode-hook 'py-setup-hook)
227 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
232 ;;; all with AutoComplete.el
233 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
235 (defun prefix-list-elements (list prefix)
238 (dolist (element list value)
239 (setq value (cons (format "%s%s" prefix element) value))))))
240 (defvar ac-source-rope
243 (prefix-list-elements (rope-completions) ac-target))))
245 (defun ac-python-find ()
246 "Python `ac-find-function'."
248 (let ((symbol (car-safe (bounds-of-thing-at-point 'symbol))))
250 (if (string= "." (buffer-substring (- (point) 1) (point)))
254 (defun ac-python-candidate ()
255 "Python `ac-candidates-function'"
257 (dolist (source ac-sources)
259 (setq source (symbol-value source)))
260 (let* ((ac-limit (or (cdr-safe (assq 'limit source)) ac-limit))
261 (requires (cdr-safe (assq 'requires source)))
263 (if (or (null requires)
264 (>= (length ac-target) requires))
267 (mapcar (lambda (candidate)
268 (propertize candidate 'source source))
269 (funcall (cdr (assq 'candidates source)))))))
270 (if (and (> ac-limit 1)
271 (> (length cand) ac-limit))
272 (setcdr (nthcdr (1- ac-limit) cand) nil))
273 (setq candidates (append candidates cand))))
274 (delete-dups candidates)))
275 (add-hook 'python-mode-hook
277 (auto-complete-mode 1)
278 (set (make-local-variable 'ac-sources)
279 (append ac-sources '(ac-source-rope) '(ac-source-yasnippet)))
280 (set (make-local-variable 'ac-find-function) 'ac-python-find)
281 (set (make-local-variable 'ac-candidate-function) 'ac-python-candidate)
282 (set (make-local-variable 'ac-auto-start) nil)))
283 ;;Ryan's python specific tab completion
284 (defun ryan-python-tab ()
286 ; 1) Do a yasnippet expansion
287 ; 2) Do a Rope code completion
290 (if (eql (ac-start) 0)
291 (indent-for-tab-command)))
292 (defadvice ac-start (before advice-turn-on-auto-start activate)
293 (set (make-local-variable 'ac-auto-start) t))
294 (defadvice ac-cleanup (after advice-turn-off-auto-start activate)
295 (set (make-local-variable 'ac-auto-start) nil))
297 ;(define-key py-mode-map "\t" 'ryan-python-tab)
298 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
299 ;;; End Auto Completion
300 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
301 ;; Auto Syntax Error Hightlight
302 (when (load "flymake" t)
303 (defun flymake-pyflakes-init ()
304 (let* ((temp-file (flymake-init-create-temp-buffer-copy
305 'flymake-create-temp-inplace))
306 (local-file (file-relative-name
308 (file-name-directory buffer-file-name))))
309 (message "flymake init pyflakes %s" local-file)
310 (list "pyflakes" (list local-file))))
311 (add-to-list 'flymake-allowed-file-name-masks
312 '("\\.py\\'" flymake-pyflakes-init)))
314 (defun safer-flymake-find-file-hook ()
315 "Don't barf if we can't open this flymake file"
316 (let ((flymake-filename
317 (flymake-create-temp-inplace (buffer-file-name) "flymake")))
318 (if (file-writable-p flymake-filename)
319 (flymake-find-file-hook)
322 "Couldn't enable flymake; permission denied on %s" flymake-filename)))))
323 (add-hook 'find-file-hook 'safer-flymake-find-file-hook)
325 (defun py-skip-few-lines (&optional count)
326 (if (null count) (setq count 3))
329 (and (or (when (eolp) (setq count 0) (incf blanks) t)
330 (when (> count 0) (decf count) t))
331 (< (forward-line 1) 1)))
334 (defun py-imports-region ()
336 (goto-char (point-min))
337 (while (and (re-search-forward "^\\(import\\s-+\\|from\\s-+\\)" nil t)
338 (looking-at "__future__")))
341 (while (and (py-skip-few-lines)
342 (looking-at "import\\s-+\\|from\\s-+"))
344 (if (not (looking-at "\\(import\\s-+\\|from\\s-+\\)"))
346 (while (looking-at "\\(import\\s-+\\|from\\s-+\\)")
348 (cons beg (point)))))
350 (defun py-cleanup-imports (&optional nowait)
353 (if (region-active-p)
354 (setq beg (region-beginning)
356 (setq reg (py-imports-region))
357 (if (= (car reg) (cdr reg))
358 (error "No imports found"))
359 (setq beg (car reg) end (cdr reg)))
360 (sort-lines t beg end)
362 (let ((end-marker (make-marker))
365 (set-marker end-marker end)
366 (while (< (point) end-marker)
367 (let ((is-import (looking-at "import\\s-+"))
368 (eol-marker (save-excursion (end-of-line) (point-marker)))
370 (if (and doing-imports (not is-import))
374 (sort-lines nil beg (point))
376 (setq doing-imports nil)))
377 (setq prefix (if is-import "import "
378 (buffer-substring-no-properties
379 (point) (re-search-forward "\\s-+import\\s-+" eol-marker t))))
380 (while (search-forward "," eol-marker t)
382 (delete-horizontal-space)
383 (insert "\n" prefix))
385 (sort-lines nil b (point))
386 (if (and (not nowait) (boundp flymake-is-running))
388 (my-flymake-check-and-wait)
390 (while (< (point) end-marker)
391 (if (and (loop for ov in (overlays-at (point))
392 thereis (flymake-overlay-p ov))
393 (not (save-excursion (search-forward "unused"
394 (save-excursion (end-of-line) (point))
396 (delete-region (point)
397 (progn (forward-line 1) (point)))
398 (forward-line 1))))))))
400 (defun flyspell-py-progmode-verify ()
401 "Replacement for standard flyspell-generic-progmode-verify which
402 checks for C/C++ preproc directives. Additionally, anything after ^L
403 is ignored (Those are the file local variables and local words)."
404 (let ((f (get-text-property (point) 'face)))
405 (and (memq f flyspell-prog-text-faces)
409 (not (let ((l (max (point-min) (- (point-max) 4096))))
411 (save-excursion (search-backward "
\f" l t)))))
412 (not (let* ((pos (python-in-string/comment))
413 (c (and pos (char-after pos))))
414 (and pos (not (save-excursion
417 (looking-at (concat "^\\s-*[uUrR]?" (regexp-quote (make-string 3 c))))))))))))
419 (defun flyspell-py-mode ()
420 "Turn on `flyspell-mode` for comments and multi-line strings"
422 (setq flyspell-generic-check-word-p 'flyspell-py-progmode-verify)
425 (provide 'init_python)