[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