aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFabián Ezequiel Gallina2013-04-17 19:23:13 -0300
committerFabián Ezequiel Gallina2013-04-17 19:23:13 -0300
commit04754d3612ea2f09440604c571814e0795511fa3 (patch)
tree20fe20127a95831eb06c2313f3c2cca2abddc1a0
parentdd8791e96feb4915c895a4879deee67e672e0a7f (diff)
downloademacs-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/ChangeLog5
-rw-r--r--lisp/progmodes/python.el48
-rw-r--r--test/ChangeLog6
-rw-r--r--test/automated/python-tests.el108
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 @@
12013-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
12013-04-17 Stefan Monnier <monnier@iro.umontreal.ca> 62013-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.
1197FN must take no arguments and could be used to set match-data. 1197FN must take no arguments. POSCOMPFN is a two arguments function
1198POSCOMPFN is a two arguments function used to compare current and 1198used to compare current and previous point after it is moved
1199previous point after it is moved using FN, this is normally a 1199using FN, this is normally a less-than or greater-than
1200less-than or greater-than comparison. Optional argument POS is 1200comparison. Optional argument CONTEXTFN defaults to
1201internally used in recursive calls and should not be explicitly 1201`python-syntax-context-type' and is used for checking current
1202passed." 1202point context, it must return a non-nil value if this point must
1203 (let* ((newpos 1203be 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 @@
12013-04-17 Fabián Ezequiel Gallina <fgallina@gnu.org> 12013-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
72013-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 "
724def 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
767class 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 "
822def 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 "
854class 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 "