diff options
| author | Fabián Ezequiel Gallina | 2013-04-17 19:23:13 -0300 |
|---|---|---|
| committer | Fabián Ezequiel Gallina | 2013-04-17 19:23:13 -0300 |
| commit | 04754d3612ea2f09440604c571814e0795511fa3 (patch) | |
| tree | 20fe20127a95831eb06c2313f3c2cca2abddc1a0 | |
| parent | dd8791e96feb4915c895a4879deee67e672e0a7f (diff) | |
| download | emacs-04754d3612ea2f09440604c571814e0795511fa3.tar.gz emacs-04754d3612ea2f09440604c571814e0795511fa3.zip | |
* lisp/progmodes/python.el (python-nav--syntactically): Fix cornercases
and do not care about match data.
* test/automated/python-tests.el (python-nav-backward-defun-2)
(python-nav-backward-defun-3, python-nav-forward-defun-2)
(python-nav-forward-defun-3): New tests.
| -rw-r--r-- | lisp/ChangeLog | 5 | ||||
| -rw-r--r-- | lisp/progmodes/python.el | 48 | ||||
| -rw-r--r-- | test/ChangeLog | 6 | ||||
| -rw-r--r-- | test/automated/python-tests.el | 108 |
4 files changed, 145 insertions, 22 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 4ace42afa09..fdb9ac2acab 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,8 @@ | |||
| 1 | 2013-04-17 Fabián Ezequiel Gallina <fgallina@gnu.org> | ||
| 2 | |||
| 3 | * progmodes/python.el (python-nav--syntactically): Fix cornercases | ||
| 4 | and do not care about match data. | ||
| 5 | |||
| 1 | 2013-04-17 Stefan Monnier <monnier@iro.umontreal.ca> | 6 | 2013-04-17 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 7 | ||
| 3 | * emacs-lisp/lisp.el (lisp-completion-at-point): Provide specialized | 8 | * emacs-lisp/lisp.el (lisp-completion-at-point): Provide specialized |
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index 1d7cf02ca5a..53aff94ae0e 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el | |||
| @@ -1192,28 +1192,32 @@ Returns nil if point is not in a def or class." | |||
| 1192 | ;; Ensure point moves forward. | 1192 | ;; Ensure point moves forward. |
| 1193 | (and (> beg-pos (point)) (goto-char beg-pos))))) | 1193 | (and (> beg-pos (point)) (goto-char beg-pos))))) |
| 1194 | 1194 | ||
| 1195 | (defun python-nav--syntactically (fn poscompfn &optional pos) | 1195 | (defun python-nav--syntactically (fn poscompfn &optional contextfn) |
| 1196 | "Move to point using FN ignoring non-code or paren context. | 1196 | "Move point using FN avoiding places with specific context. |
| 1197 | FN must take no arguments and could be used to set match-data. | 1197 | FN must take no arguments. POSCOMPFN is a two arguments function |
| 1198 | POSCOMPFN is a two arguments function used to compare current and | 1198 | used to compare current and previous point after it is moved |
| 1199 | previous point after it is moved using FN, this is normally a | 1199 | using FN, this is normally a less-than or greater-than |
| 1200 | less-than or greater-than comparison. Optional argument POS is | 1200 | comparison. Optional argument CONTEXTFN defaults to |
| 1201 | internally used in recursive calls and should not be explicitly | 1201 | `python-syntax-context-type' and is used for checking current |
| 1202 | passed." | 1202 | point context, it must return a non-nil value if this point must |
| 1203 | (let* ((newpos | 1203 | be skipped." |
| 1204 | (and (funcall fn) | 1204 | (let ((contextfn (or contextfn 'python-syntax-context-type)) |
| 1205 | (save-match-data | 1205 | (start-pos (point-marker)) |
| 1206 | (and | 1206 | (prev-pos)) |
| 1207 | (not (python-syntax-context-type)) | 1207 | (catch 'found |
| 1208 | (point-marker))))) | 1208 | (while t |
| 1209 | (current-match-data (match-data))) | 1209 | (let* ((newpos |
| 1210 | (cond ((or (and (not pos) newpos) | 1210 | (and (funcall fn) (point-marker))) |
| 1211 | (and pos newpos (funcall poscompfn newpos pos))) | 1211 | (context (funcall contextfn))) |
| 1212 | (set-match-data current-match-data) | 1212 | (cond ((and (not context) newpos |
| 1213 | (point-marker)) | 1213 | (or (and (not prev-pos) newpos) |
| 1214 | ((and (not pos) (not newpos)) nil) | 1214 | (and prev-pos newpos |
| 1215 | (t (python-nav--syntactically | 1215 | (funcall poscompfn newpos prev-pos)))) |
| 1216 | fn poscompfn (point-marker)))))) | 1216 | (throw 'found (point-marker))) |
| 1217 | ((and newpos context) | ||
| 1218 | (setq prev-pos (point))) | ||
| 1219 | (t (when (not newpos) (goto-char start-pos)) | ||
| 1220 | (throw 'found nil)))))))) | ||
| 1217 | 1221 | ||
| 1218 | (defun python-nav--forward-defun (arg) | 1222 | (defun python-nav--forward-defun (arg) |
| 1219 | "Internal implementation of python-nav-{backward,forward}-defun. | 1223 | "Internal implementation of python-nav-{backward,forward}-defun. |
diff --git a/test/ChangeLog b/test/ChangeLog index 7c25ad1a804..c8cb8ee3b54 100644 --- a/test/ChangeLog +++ b/test/ChangeLog | |||
| @@ -1,5 +1,11 @@ | |||
| 1 | 2013-04-17 Fabián Ezequiel Gallina <fgallina@gnu.org> | 1 | 2013-04-17 Fabián Ezequiel Gallina <fgallina@gnu.org> |
| 2 | 2 | ||
| 3 | * automated/python-tests.el (python-nav-backward-defun-2) | ||
| 4 | (python-nav-backward-defun-3, python-nav-forward-defun-2) | ||
| 5 | (python-nav-forward-defun-3): New tests. | ||
| 6 | |||
| 7 | 2013-04-17 Fabián Ezequiel Gallina <fgallina@gnu.org> | ||
| 8 | |||
| 3 | * automated/python-tests.el (python-nav-backward-defun-1) | 9 | * automated/python-tests.el (python-nav-backward-defun-1) |
| 4 | (python-nav-forward-defun-1): New tests. | 10 | (python-nav-forward-defun-1): New tests. |
| 5 | 11 | ||
diff --git a/test/automated/python-tests.el b/test/automated/python-tests.el index a7c7aab6464..15089e6b393 100644 --- a/test/automated/python-tests.el +++ b/test/automated/python-tests.el | |||
| @@ -718,6 +718,60 @@ class A(object): # A | |||
| 718 | (python-tests-look-at "class A(object): # A" -1))) | 718 | (python-tests-look-at "class A(object): # A" -1))) |
| 719 | (should (not (python-nav-backward-defun))))) | 719 | (should (not (python-nav-backward-defun))))) |
| 720 | 720 | ||
| 721 | (ert-deftest python-nav-backward-defun-2 () | ||
| 722 | (python-tests-with-temp-buffer | ||
| 723 | " | ||
| 724 | def decoratorFunctionWithArguments(arg1, arg2, arg3): | ||
| 725 | '''print decorated function call data to stdout. | ||
| 726 | |||
| 727 | Usage: | ||
| 728 | |||
| 729 | @decoratorFunctionWithArguments('arg1', 'arg2') | ||
| 730 | def func(a, b, c=True): | ||
| 731 | pass | ||
| 732 | ''' | ||
| 733 | |||
| 734 | def wwrap(f): | ||
| 735 | print 'Inside wwrap()' | ||
| 736 | def wrapped_f(*args): | ||
| 737 | print 'Inside wrapped_f()' | ||
| 738 | print 'Decorator arguments:', arg1, arg2, arg3 | ||
| 739 | f(*args) | ||
| 740 | print 'After f(*args)' | ||
| 741 | return wrapped_f | ||
| 742 | return wwrap | ||
| 743 | " | ||
| 744 | (goto-char (point-max)) | ||
| 745 | (should (= (save-excursion (python-nav-backward-defun)) | ||
| 746 | (python-tests-look-at " def wrapped_f(*args):" -1))) | ||
| 747 | (should (= (save-excursion (python-nav-backward-defun)) | ||
| 748 | (python-tests-look-at " def wwrap(f):" -1))) | ||
| 749 | (should (= (save-excursion (python-nav-backward-defun)) | ||
| 750 | (python-tests-look-at "def decoratorFunctionWithArguments(arg1, arg2, arg3):" -1))) | ||
| 751 | (should (not (python-nav-backward-defun))))) | ||
| 752 | |||
| 753 | (ert-deftest python-nav-backward-defun-3 () | ||
| 754 | (python-tests-with-temp-buffer | ||
| 755 | " | ||
| 756 | ''' | ||
| 757 | def u(self): | ||
| 758 | pass | ||
| 759 | |||
| 760 | def v(self): | ||
| 761 | pass | ||
| 762 | |||
| 763 | def w(self): | ||
| 764 | pass | ||
| 765 | ''' | ||
| 766 | |||
| 767 | class A(object): | ||
| 768 | pass | ||
| 769 | " | ||
| 770 | (goto-char (point-min)) | ||
| 771 | (let ((point (python-tests-look-at "class A(object):"))) | ||
| 772 | (should (not (python-nav-backward-defun))) | ||
| 773 | (should (= point (point)))))) | ||
| 774 | |||
| 721 | (ert-deftest python-nav-forward-defun-1 () | 775 | (ert-deftest python-nav-forward-defun-1 () |
| 722 | (python-tests-with-temp-buffer | 776 | (python-tests-with-temp-buffer |
| 723 | " | 777 | " |
| @@ -762,6 +816,60 @@ class A(object): # A | |||
| 762 | (python-tests-look-at "(self): # c"))) | 816 | (python-tests-look-at "(self): # c"))) |
| 763 | (should (not (python-nav-forward-defun))))) | 817 | (should (not (python-nav-forward-defun))))) |
| 764 | 818 | ||
| 819 | (ert-deftest python-nav-forward-defun-2 () | ||
| 820 | (python-tests-with-temp-buffer | ||
| 821 | " | ||
| 822 | def decoratorFunctionWithArguments(arg1, arg2, arg3): | ||
| 823 | '''print decorated function call data to stdout. | ||
| 824 | |||
| 825 | Usage: | ||
| 826 | |||
| 827 | @decoratorFunctionWithArguments('arg1', 'arg2') | ||
| 828 | def func(a, b, c=True): | ||
| 829 | pass | ||
| 830 | ''' | ||
| 831 | |||
| 832 | def wwrap(f): | ||
| 833 | print 'Inside wwrap()' | ||
| 834 | def wrapped_f(*args): | ||
| 835 | print 'Inside wrapped_f()' | ||
| 836 | print 'Decorator arguments:', arg1, arg2, arg3 | ||
| 837 | f(*args) | ||
| 838 | print 'After f(*args)' | ||
| 839 | return wrapped_f | ||
| 840 | return wwrap | ||
| 841 | " | ||
| 842 | (goto-char (point-min)) | ||
| 843 | (should (= (save-excursion (python-nav-forward-defun)) | ||
| 844 | (python-tests-look-at "(arg1, arg2, arg3):"))) | ||
| 845 | (should (= (save-excursion (python-nav-forward-defun)) | ||
| 846 | (python-tests-look-at "(f):"))) | ||
| 847 | (should (= (save-excursion (python-nav-forward-defun)) | ||
| 848 | (python-tests-look-at "(*args):"))) | ||
| 849 | (should (not (python-nav-forward-defun))))) | ||
| 850 | |||
| 851 | (ert-deftest python-nav-forward-defun-3 () | ||
| 852 | (python-tests-with-temp-buffer | ||
| 853 | " | ||
| 854 | class A(object): | ||
| 855 | pass | ||
| 856 | |||
| 857 | ''' | ||
| 858 | def u(self): | ||
| 859 | pass | ||
| 860 | |||
| 861 | def v(self): | ||
| 862 | pass | ||
| 863 | |||
| 864 | def w(self): | ||
| 865 | pass | ||
| 866 | ''' | ||
| 867 | " | ||
| 868 | (goto-char (point-min)) | ||
| 869 | (let ((point (python-tests-look-at "(object):"))) | ||
| 870 | (should (not (python-nav-forward-defun))) | ||
| 871 | (should (= point (point)))))) | ||
| 872 | |||
| 765 | (ert-deftest python-nav-beginning-of-statement-1 () | 873 | (ert-deftest python-nav-beginning-of-statement-1 () |
| 766 | (python-tests-with-temp-buffer | 874 | (python-tests-with-temp-buffer |
| 767 | " | 875 | " |