aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/progmodes/python.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/progmodes/python.el')
-rw-r--r--lisp/progmodes/python.el52
1 files changed, 52 insertions, 0 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 81440cfcfc9..594681594b0 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -2386,9 +2386,54 @@ backward to previous statement."
2386 (python-nav-beginning-of-statement) 2386 (python-nav-beginning-of-statement)
2387 (setq arg (1+ arg)))) 2387 (setq arg (1+ arg))))
2388 2388
2389(defvar python-nav-cache nil
2390 "Cache to hold the results of navigation functions.")
2391
2392(defvar python-nav-cache-tick 0
2393 "`buffer-chars-modified-tick' when registering the navigation cache.")
2394
2395(defun python-nav-cache-get (kind)
2396 "Get value from the navigation cache.
2397If the current buffer is not modified, the navigation cache is searched
2398using KIND and the current line number as a key."
2399 (and (= (buffer-chars-modified-tick) python-nav-cache-tick)
2400 (cdr (assoc (cons kind (line-number-at-pos nil t)) python-nav-cache))))
2401
2402(defun python-nav-cache-set (kind current target)
2403 "Add a key-value pair to the navigation cache.
2404Invalidate the navigation cache if the current buffer has been modified.
2405Then add a key-value pair to the navigation cache. The key consists of
2406KIND and CURRENT line number, and the value is TARGET position."
2407 (let ((tick (buffer-chars-modified-tick)))
2408 (when (/= tick python-nav-cache-tick)
2409 (setq-local python-nav-cache nil
2410 python-nav-cache-tick tick))
2411 (push (cons (cons kind current) target) python-nav-cache)
2412 target))
2413
2414(defun python-nav-with-cache (kind func)
2415 "Cached version of the navigation FUNC.
2416If a value is obtained from the navigation cache using KIND, it will
2417navigate there and return the position. Otherwise, use FUNC to navigate
2418and cache the result."
2419 (let ((target (python-nav-cache-get kind)))
2420 (if target
2421 (progn
2422 (goto-char target)
2423 (point-marker))
2424 (let ((current (line-number-at-pos nil t)))
2425 (python-nav-cache-set kind current (funcall func))))))
2426
2389(defun python-nav-beginning-of-block () 2427(defun python-nav-beginning-of-block ()
2390 "Move to start of current block." 2428 "Move to start of current block."
2391 (interactive "^") 2429 (interactive "^")
2430 (python-nav-with-cache
2431 'beginning-of-block #'python-nav--beginning-of-block))
2432
2433(defun python-nav--beginning-of-block ()
2434 "Move to start of current block.
2435This is an internal implementation of `python-nav-beginning-of-block'
2436without the navigation cache."
2392 (let ((starting-pos (point))) 2437 (let ((starting-pos (point)))
2393 ;; Go to first line beginning a statement 2438 ;; Go to first line beginning a statement
2394 (while (and (not (bobp)) 2439 (while (and (not (bobp))
@@ -2413,6 +2458,13 @@ backward to previous statement."
2413(defun python-nav-end-of-block () 2458(defun python-nav-end-of-block ()
2414 "Move to end of current block." 2459 "Move to end of current block."
2415 (interactive "^") 2460 (interactive "^")
2461 (python-nav-with-cache
2462 'end-of-block #'python-nav--end-of-block))
2463
2464(defun python-nav--end-of-block ()
2465 "Move to end of current block.
2466This is an internal implementation of `python-nav-end-of-block' without
2467the navigation cache."
2416 (when (python-nav-beginning-of-block) 2468 (when (python-nav-beginning-of-block)
2417 (let ((block-indentation (current-indentation))) 2469 (let ((block-indentation (current-indentation)))
2418 (python-nav-end-of-statement) 2470 (python-nav-end-of-statement)