Skip to content

Commit 5ec55b9

Browse files
committed
Use lexical binding in ess-r-mode.el
1 parent 4475e8c commit 5ec55b9

File tree

1 file changed

+140
-143
lines changed

1 file changed

+140
-143
lines changed

lisp/ess-r-mode.el

Lines changed: 140 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
;;; ess-r-mode.el --- R customization
1+
;;; ess-r-mode.el --- R customization -*- lexical-binding: t; -*-
22

33
;; Copyright (C) 1997-2020 Free Software Foundation, Inc.
44
;; Author: A.J. Rossini
@@ -83,18 +83,9 @@ access."
8383
;; TODO: Refactor so as to not rely on dynamic scoping. After that
8484
;; refactor, also remove the file-local-variable byte-compile-warnings
8585
;; (not lexical) at the bottom.
86-
(defvar block)
8786
(defvar containing-sexp)
8887
(defvar indent-point)
89-
(defvar infinite)
90-
(defvar last-newline)
91-
(defvar last-pos)
92-
(defvar offset)
93-
(defvar prefix-break)
9488
(defvar prev-containing-sexp)
95-
(defvar start-pos)
96-
(defvar style)
97-
(defvar type)
9889

9990
(define-obsolete-variable-alias 'ess-r-versions 'ess-r-runner-prefixes "ESS 19.04")
10091
(defcustom ess-r-runner-prefixes
@@ -1516,9 +1507,7 @@ load is successful, and nil otherwise."
15161507
(let ((loader (ess-file-content (expand-file-name "ESSR/LOADREMOTE" ess-etc-directory))))
15171508
(or (with-temp-message "Fetching and loading ESSR into the remote ..."
15181509
(ess-boolean-command (format loader essr-version)))
1519-
(let* ((errmsg (with-current-buffer " *ess-command-output*" (buffer-string)))
1520-
(src-dir (expand-file-name "ESSR/R" ess-etc-directory))
1521-
(files (directory-files src-dir t "\\.R\\'")))
1510+
(let ((errmsg (with-current-buffer " *ess-command-output*" (buffer-string))))
15221511
(message (format "Couldn't load or download ESSR.rds on the remote.\n Error: %s\n Injecting local copy of ESSR." errmsg))
15231512
nil))))
15241513

@@ -1895,10 +1884,12 @@ Returns nil if line starts inside a string, t if in a comment."
18951884
(ess-calculate-indent--args-open-delim))
18961885
;; Indent from attached name
18971886
((eq type 'prev-call)
1898-
(ess-calculate-indent--args-prev-call))
1887+
(ess-calculate-indent--args-prev-call block))
18991888
;; Indent from previous line indentation
19001889
((eq type 'prev-line)
1901-
(ess-calculate-indent--args-prev-line))
1890+
(let ((out (ess-calculate-indent--args-prev-line type block offset)))
1891+
(setq offset (pop out))
1892+
(pop out)))
19021893
(t
19031894
(error "Malformed offset")))))
19041895
(if max-col
@@ -1909,7 +1900,7 @@ Returns nil if line starts inside a string, t if in a comment."
19091900
(forward-char)
19101901
(current-column))
19111902

1912-
(defun ess-calculate-indent--args-prev-call ()
1903+
(defun ess-calculate-indent--args-prev-call (block)
19131904
;; Handle brackets chains such as ][ (cf data.table)
19141905
(ess-climb-chained-delims)
19151906
;; Handle call chains
@@ -1927,7 +1918,7 @@ Returns nil if line starts inside a string, t if in a comment."
19271918
(+ (ess-offset 'block) (current-column))
19281919
(current-column)))
19291920

1930-
(defun ess-calculate-indent--args-prev-line ()
1921+
(defun ess-calculate-indent--args-prev-line (type block offset)
19311922
(ess-at-indent-point
19321923
(cond
19331924
;; Closing delimiters are actually not indented at
@@ -1936,13 +1927,13 @@ Returns nil if line starts inside a string, t if in a comment."
19361927
(ess-up-list -1)
19371928
(when (looking-at "{")
19381929
(ess-climb-block-prefix))
1939-
(current-indentation))
1930+
(list offset (current-indentation)))
19401931
;; Function blocks need special treatment
19411932
((and (eq type 'prev-line)
19421933
(eq block 'fun-decl))
19431934
(goto-char containing-sexp)
19441935
(ess-climb-block-prefix)
1945-
(current-indentation))
1936+
(list offset (current-indentation)))
19461937
;; Regular case
19471938
(t
19481939
;; Find next non-empty line to indent from
@@ -1958,15 +1949,16 @@ Returns nil if line starts inside a string, t if in a comment."
19581949
;; The following ensures that only the first line
19591950
;; counts. Otherwise consecutive statements would get
19601951
;; increasingly more indented.
1961-
(when (and block
1962-
containing-sexp
1963-
(not (eq block 'unbraced))
1964-
(save-excursion
1965-
(/= (line-number-at-pos)
1966-
(progn (goto-char containing-sexp)
1967-
(line-number-at-pos)))))
1968-
(setq offset 0))
1969-
(current-indentation)))))
1952+
(let ((offset (if (and block
1953+
containing-sexp
1954+
(not (eq block 'unbraced))
1955+
(save-excursion
1956+
(/= (line-number-at-pos)
1957+
(progn (goto-char containing-sexp)
1958+
(line-number-at-pos)))))
1959+
0
1960+
offset)))
1961+
(list offset (current-indentation)))))))
19701962

19711963
;; Indentation of arguments needs to keep track of how previous
19721964
;; arguments are indented. If one of those has a smaller indentation,
@@ -2213,118 +2205,128 @@ state.")
22132205
(setq ess-fill--style-level (1+ ess-fill--style-level))))))
22142206
ess-fill--style-level)
22152207

2216-
(defun ess-fill-args (&optional style)
2217-
(let ((start-pos (point-min))
2218-
(bounds (ess-args-bounds 'marker))
2219-
;; Set undo boundaries manually
2220-
(undo-inhibit-record-point t)
2221-
last-pos last-newline prefix-break
2222-
infinite)
2223-
(when (not bounds)
2224-
(error "Could not find function bounds"))
2225-
(setq style (or style (ess-fill-style 'calls bounds)))
2226-
(if (= style 0)
2227-
(progn
2228-
(delete-region (car bounds) (marker-position (cadr bounds)))
2229-
(insert ess-fill--orig-state)
2230-
;; Restore the point manually. (save-excursion) wouldn't
2231-
;; work here because we delete the text rather than just
2232-
;; modifying it.
2233-
(goto-char ess-fill--orig-pos)
2234-
(message "Back to original formatting"))
2235-
(when ess-blink-refilling
2236-
(ess-blink-region (nth 2 bounds)
2237-
(1+ (marker-position (cadr bounds)))))
2238-
(undo-boundary)
2239-
(save-excursion
2240-
(ess-fill--unroll-lines bounds t)
2241-
(cond
2242-
;; Some styles start with first argument on a newline
2243-
((and (memq style '(2 4))
2244-
ess-fill-calls-newlines
2245-
(not (looking-at "[ \t]*#")))
2246-
(newline-and-indent))
2247-
;; Third level, start a newline after N arguments
2248-
((and (= style 3)
2249-
(not (looking-at "[ \t]*#")))
2250-
(let ((i (if (numberp current-prefix-arg)
2251-
current-prefix-arg
2252-
1)))
2253-
(while (and (> i 0)
2254-
(ess-jump-arg)
2255-
(ess-jump-char ","))
2256-
(setq i (1- i))))
2257-
(newline-and-indent)))
2258-
(ess-fill-args--roll-lines)
2259-
;; Reindent surrounding context
2260-
(ess-indent-call (car bounds)))
2261-
;; Signal marker for garbage collection
2262-
(set-marker (cadr bounds) nil)
2263-
(undo-boundary))))
2264-
2265-
(defun ess-fill-args--roll-lines ()
2266-
(while (and (not (looking-at "[])]"))
2267-
(/= (point) (or last-pos 1))
2268-
(not infinite))
2269-
(setq prefix-break nil)
2270-
;; Record start-pos as future breaking point to avoid breaking
2271-
;; at `=' sign
2272-
(while (looking-at "[ \t]*[\n#]")
2273-
(forward-line)
2274-
(back-to-indentation))
2275-
(setq start-pos (point))
2276-
(while (and (< (current-column) fill-column)
2277-
(not (looking-at "[])]"))
2278-
(/= (point) (or last-pos 1))
2279-
;; Break after one pass if prefix is active
2280-
(not prefix-break))
2281-
(when (memq style '(2 3))
2282-
(setq prefix-break t))
2283-
(ess-jump-token ",")
2284-
(setq last-pos (point))
2285-
;; Jump expression and any continuations. Reindent all lines
2286-
;; that were jumped over
2287-
(let ((cur-line (line-number-at-pos))
2288-
end-line)
2289-
(cond ((ess-jump-arg)
2290-
(setq last-newline nil))
2291-
((ess-token-after= ",")
2292-
(setq last-newline nil)
2293-
(setq last-pos (1- (point)))))
2208+
(let (_)
2209+
;; FIXME: Transform these dynamic bindings to a state object
2210+
(defvar ess--infinite)
2211+
(defvar ess--prefix-break)
2212+
(defvar ess--start-pos)
2213+
(defvar ess--last-pos)
2214+
(defvar ess--last-newline)
2215+
2216+
(declare-function ess-fill-args--roll-lines "ess-r-mode")
2217+
2218+
(defun ess-fill-args (&optional style)
2219+
(let ((ess--start-pos (point-min))
2220+
(bounds (ess-args-bounds 'marker))
2221+
;; Set undo boundaries manually
2222+
(undo-inhibit-record-point t)
2223+
ess--last-pos ess--last-newline ess--prefix-break
2224+
ess--infinite)
2225+
(when (not bounds)
2226+
(error "Could not find function bounds"))
2227+
(setq style (or style (ess-fill-style 'calls bounds)))
2228+
(if (= style 0)
2229+
(progn
2230+
(delete-region (car bounds) (marker-position (cadr bounds)))
2231+
(insert ess-fill--orig-state)
2232+
;; Restore the point manually. (save-excursion) wouldn't
2233+
;; work here because we delete the text rather than just
2234+
;; modifying it.
2235+
(goto-char ess-fill--orig-pos)
2236+
(message "Back to original formatting"))
2237+
(when ess-blink-refilling
2238+
(ess-blink-region (nth 2 bounds)
2239+
(1+ (marker-position (cadr bounds)))))
2240+
(undo-boundary)
22942241
(save-excursion
2295-
(when (< cur-line (line-number-at-pos))
2296-
(setq end-line (line-number-at-pos))
2297-
(ess-goto-line (1+ cur-line))
2298-
(while (and (<= (line-number-at-pos) end-line)
2299-
(/= (point) (point-max)))
2300-
(funcall indent-line-function)
2301-
(forward-line))))))
2302-
(when (or (>= (current-column) fill-column)
2303-
prefix-break
2304-
;; Ensures closing delim on a newline
2305-
(and (= style 4)
2306-
(looking-at "[ \t]*[])]")
2307-
(setq last-pos (point))))
2308-
(if (and last-pos (/= last-pos start-pos))
2309-
(goto-char last-pos)
2310-
(ess-jump-char ","))
2311-
(cond ((looking-at "[ \t]*[#\n]")
2312-
(forward-line)
2313-
(funcall indent-line-function)
2314-
(setq last-newline nil))
2315-
;; With levels 2 and 3, closing delim goes on a newline
2316-
((looking-at "[ \t]*[])]")
2317-
(when (and (memq style '(2 3 4))
2318-
ess-fill-calls-newlines
2319-
(not last-newline))
2242+
(ess-fill--unroll-lines bounds t)
2243+
(cond
2244+
;; Some styles start with first argument on a newline
2245+
((and (memq style '(2 4))
2246+
ess-fill-calls-newlines
2247+
(not (looking-at "[ \t]*#")))
2248+
(newline-and-indent))
2249+
;; Third level, start a newline after N arguments
2250+
((and (= style 3)
2251+
(not (looking-at "[ \t]*#")))
2252+
(let ((i (if (numberp current-prefix-arg)
2253+
current-prefix-arg
2254+
1)))
2255+
(while (and (> i 0)
2256+
(ess-jump-arg)
2257+
(ess-jump-char ","))
2258+
(setq i (1- i))))
2259+
(newline-and-indent)))
2260+
(ess-fill-args--roll-lines style)
2261+
;; Reindent surrounding context
2262+
(ess-indent-call (car bounds)))
2263+
;; Signal marker for garbage collection
2264+
(set-marker (cadr bounds) nil)
2265+
(undo-boundary))))
2266+
2267+
(defun ess-fill-args--roll-lines (style)
2268+
(while (and (not (looking-at "[])]"))
2269+
(/= (point) (or ess--last-pos 1))
2270+
(not ess--infinite))
2271+
(setq ess--prefix-break nil)
2272+
;; Record ess--start-pos as future breaking point to avoid breaking
2273+
;; at `=' sign
2274+
(while (looking-at "[ \t]*[\n#]")
2275+
(forward-line)
2276+
(back-to-indentation))
2277+
(setq ess--start-pos (point))
2278+
(while (and (< (current-column) fill-column)
2279+
(not (looking-at "[])]"))
2280+
(/= (point) (or ess--last-pos 1))
2281+
;; Break after one pass if prefix is active
2282+
(not ess--prefix-break))
2283+
(when (memq style '(2 3))
2284+
(setq ess--prefix-break t))
2285+
(ess-jump-token ",")
2286+
(setq ess--last-pos (point))
2287+
;; Jump expression and any continuations. Reindent all lines
2288+
;; that were jumped over
2289+
(let ((cur-line (line-number-at-pos))
2290+
end-line)
2291+
(cond ((ess-jump-arg)
2292+
(setq ess--last-newline nil))
2293+
((ess-token-after= ",")
2294+
(setq ess--last-newline nil)
2295+
(setq ess--last-pos (1- (point)))))
2296+
(save-excursion
2297+
(when (< cur-line (line-number-at-pos))
2298+
(setq end-line (line-number-at-pos))
2299+
(ess-goto-line (1+ cur-line))
2300+
(while (and (<= (line-number-at-pos) end-line)
2301+
(/= (point) (point-max)))
2302+
(funcall indent-line-function)
2303+
(forward-line))))))
2304+
(when (or (>= (current-column) fill-column)
2305+
ess--prefix-break
2306+
;; Ensures closing delim on a newline
2307+
(and (= style 4)
2308+
(looking-at "[ \t]*[])]")
2309+
(setq ess--last-pos (point))))
2310+
(if (and ess--last-pos (/= ess--last-pos ess--start-pos))
2311+
(goto-char ess--last-pos)
2312+
(ess-jump-char ","))
2313+
(cond ((looking-at "[ \t]*[#\n]")
2314+
(forward-line)
2315+
(funcall indent-line-function)
2316+
(setq ess--last-newline nil))
2317+
;; With levels 2 and 3, closing delim goes on a newline
2318+
((looking-at "[ \t]*[])]")
2319+
(when (and (memq style '(2 3 4))
2320+
ess-fill-calls-newlines
2321+
(not ess--last-newline))
2322+
(newline-and-indent)
2323+
;; Prevent indenting infinitely
2324+
(setq ess--last-newline t)))
2325+
((not ess--last-newline)
23202326
(newline-and-indent)
2321-
;; Prevent indenting infinitely
2322-
(setq last-newline t)))
2323-
((not last-newline)
2324-
(newline-and-indent)
2325-
(setq last-newline t))
2326-
(t
2327-
(setq infinite t))))))
2327+
(setq ess--last-newline t))
2328+
(t
2329+
(setq ess--infinite t)))))))
23282330

23292331
(defun ess-fill-continuations (&optional style)
23302332
(let ((bounds (ess-continuations-bounds 'marker))
@@ -2895,9 +2897,4 @@ given field. Options should be separated by value of
28952897

28962898
(provide 'ess-r-mode)
28972899

2898-
;;; Local variables:
2899-
;;; mode: emacs-lisp
2900-
;;; byte-compile-warnings: (not lexical)
2901-
;;; End:
2902-
29032900
;;; ess-r-mode.el ends here

0 commit comments

Comments
 (0)