[ESS] hs-show/hide-block and functions with definition over several lines
Ramon Diaz-Uriarte
rd|@z02 @end|ng |rom gm@||@com
Sat Dec 23 14:50:00 CET 2023
Dear All,
I am having trouble using hide-show functions hs-show-block and hs-hide-block, when the R function definition extends over several lines; in this case, if I am at, say, the function name, hs-hide-block does nothing.
It is possible to define new functions that search for the next "{", but then that breaks using other code that calls hs-show/hide-block (such as a nice wrapper in https://karthinks.com/software/simple-folding-with-hideshow/).
I've found a way of (at least apparently) solving the issue. But it involves advice-add. Code that shows the problem and the solution is below.
My solution seems way too convoluted and fragile (elisp ignorance?) for what I understand is a common issue, so I think I must be missing something. Any suggestions?
Thanks,
######################################################################
[This is the code in file "test.R"]
f1 <- function(a, b
c, d,
e) {
x <- 1
f2 <- function(u) {
u + 2
}
f2(a + b + c + d + e)
}
######################################################################
### Start emacs -Q and execute the following:
(require 'package)
(package-initialize)
;; https://emacs.stackexchange.com/a/29740
(use-package ess
:init (require 'ess-site))
;; https://stat.ethz.ch/pipermail/ess-help/2009-April/005217.html
(setq hs-special-modes-alist
'((ess-mode "{" "}" "#" nil nil)
))
(add-hook 'prog-mode-hook 'hs-minor-mode)
;; Open test.R
(find-file "test.R")
;; Use "M-x hs-hide-block" in examples below (to have everything shown
;; again, "M-x hs-show-all")
;; - point anywhere in first line before "(" and hs-hide-block:
;; nothing happens
;; - point in "a", or "b", on the first line o point in "c" or ")" :
;; argument list is hidden, not the function
;; - point in space between ")" and "{" on second line:
;; hs-hide-block does nothing
;; - point in "{", second line: hs-hide-block hiddes the function
;; These do what I want
(defun hs-hide-block-R (&optional end)
"hs-hide-block, jumping to opening brace"
(interactive "P")
(save-excursion
(search-forward "{")
(hs-hide-block)))
(defun hs-show-block-R (&optional end)
"hs-hide-block, jumping to opening brace"
(interactive "P")
(save-excursion
(search-forward "{")
(hs-show-block)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; advice hs-show/hide-block so the above logic applies
;; only when in ess-r-mode
(defun move-to-left-of-non-whitespace ()
"Move point to the left of the first non-whitespace character if
all characters to the right are whitespace."
(interactive)
(if (looking-at "[[:space:]\n]*$")
(progn
(skip-chars-backward "[:space:]")
(when (not (bolp)) (forward-char -1))))
)
(defun my-advice-for-hs-hide-block (hs-hide-block &rest args)
"In R code, find next ?{ before calling hs-hide-block.
In case we are after a ?{ but everything to the right is whitespace,
move to the ?{ first."
(if (eq major-mode 'ess-r-mode)
(save-excursion
(move-to-left-of-non-whitespace)
(search-forward "{")
(apply hs-hide-block args))
(apply hs-hide-block args)
))
(defun my-advice-for-hs-show-block (hs-show-block &rest args)
"In R code, find next ?{ before calling hs-show-block.
In case we are after a ?{ but everything to the right is whitespace,
move to the ?{ first."
(if (eq major-mode 'ess-r-mode)
(save-excursion
(move-to-left-of-non-whitespace)
(search-forward "{")
(apply hs-show-block args))
(apply hs-show-block args)
))
(advice-add 'hs-hide-block :around #'my-advice-for-hs-hide-block)
(advice-add 'hs-show-block :around #'my-advice-for-hs-show-block)
;; If we run again the examples above, hs-hide/show-block hide/show
;; the blocks.
;; With the above, we can use Karthink's functions in
;; https://karthinks.com/software/simple-folding-with-hideshow/
;; And also works with hideshowvis: https://github.com/sheijk/hideshowvis
;; mentioned in Vitalie's
;; https://stat.ethz.ch/pipermail/ess-help/2009-April/005217.html
--
Ramon Diaz-Uriarte
Department of Biochemistry, Lab B-31
Facultad de Medicina
Universidad Autónoma de Madrid
Arzobispo Morcillo, 4
28029 Madrid
Spain
Phone: +34-91-497-2412
Email: rdiaz02 using gmail.com
r.diaz using uam.es
ramon.diaz using iib.uam.es
https://ligarto.org/rdiaz
More information about the ESS-help
mailing list