From 04754d3612ea2f09440604c571814e0795511fa3 Mon Sep 17 00:00:00 2001 From: Fabián Ezequiel Gallina Date: Wed, 17 Apr 2013 19:23:13 -0300 Subject: * 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. --- lisp/progmodes/python.el | 48 ++++++++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 22 deletions(-) (limited to 'lisp/progmodes/python.el') 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." ;; Ensure point moves forward. (and (> beg-pos (point)) (goto-char beg-pos))))) -(defun python-nav--syntactically (fn poscompfn &optional pos) - "Move to point using FN ignoring non-code or paren context. -FN must take no arguments and could be used to set match-data. -POSCOMPFN is a two arguments function used to compare current and -previous point after it is moved using FN, this is normally a -less-than or greater-than comparison. Optional argument POS is -internally used in recursive calls and should not be explicitly -passed." - (let* ((newpos - (and (funcall fn) - (save-match-data - (and - (not (python-syntax-context-type)) - (point-marker))))) - (current-match-data (match-data))) - (cond ((or (and (not pos) newpos) - (and pos newpos (funcall poscompfn newpos pos))) - (set-match-data current-match-data) - (point-marker)) - ((and (not pos) (not newpos)) nil) - (t (python-nav--syntactically - fn poscompfn (point-marker)))))) +(defun python-nav--syntactically (fn poscompfn &optional contextfn) + "Move point using FN avoiding places with specific context. +FN must take no arguments. POSCOMPFN is a two arguments function +used to compare current and previous point after it is moved +using FN, this is normally a less-than or greater-than +comparison. Optional argument CONTEXTFN defaults to +`python-syntax-context-type' and is used for checking current +point context, it must return a non-nil value if this point must +be skipped." + (let ((contextfn (or contextfn 'python-syntax-context-type)) + (start-pos (point-marker)) + (prev-pos)) + (catch 'found + (while t + (let* ((newpos + (and (funcall fn) (point-marker))) + (context (funcall contextfn))) + (cond ((and (not context) newpos + (or (and (not prev-pos) newpos) + (and prev-pos newpos + (funcall poscompfn newpos prev-pos)))) + (throw 'found (point-marker))) + ((and newpos context) + (setq prev-pos (point))) + (t (when (not newpos) (goto-char start-pos)) + (throw 'found nil)))))))) (defun python-nav--forward-defun (arg) "Internal implementation of python-nav-{backward,forward}-defun. -- cgit v1.2.1