indent-region with hideshowvis-symbols changes code
If I have hideshowvis-symbols enabled, and the regions are hidden and showing the yellow rectangle on the right, if I select a region (say, the whole buffer) and then press TAB (for indent-for-tab-command ) the code is changed, with parts of it removed (parentheses or even complete expressions).
This is code to show the problem:
- Start
emacs -Qand evaluate this code:
(add-hook 'prog-mode-hook 'hs-minor-mode)
(add-to-list 'load-path "wherever-hideshowsivis-is")
(require 'hideshowvis)
(add-hook 'emacs-lisp-mode-hook 'hideshowvis-enable)
;; the next line is the culprit
(add-hook 'emacs-lisp-mode-hook 'hideshowvis-symbols)
Now, in that same emacs, open a file like, for example, this one:
(defun a ()
(setq b 93))
(defun a2 ()
(setq b 93
))
Now, in the file hs-hide-all. It will show this:
Then, mark the whole buffer and press TAB (or M-x indent-region). And notice the modeline shows the buffer has been changed (indent-region could do that, but it should not have changed anything in this buffer)
In fact, this is how the code looks if we hs-show-all:
In the first block, (setq b 93) has been erased and in the second block one closing parenthesis has been erased.
If we do not enable hideshow-symbols none of this happens, as far as I can tell.
EDIT: a simple, though brutal and ugly, way of dealing with this for now is advicing indent-region:
(advice-add 'indent-region :before (lambda (&rest args) (hs-show-all)))
I do not know if there is a better way.
I can reproduce this. It also happens when I only use the example code from hideshow.el:
(defun hideshowvis-display-code-line-counts (ov)
(when (eq 'code (overlay-get ov 'hs))
(overlay-put ov 'display
(format "... / %d"
(count-lines (overlay-start ov)
(overlay-end ov))))))
Maybe the advice would be the easiest fix but I'm not sure what other functions might be affected
Thanks for confirming. So far I haven't seen other affected functions, but will post here if I see others.
I think I found a fix.
With this I don't see the issue happening anymore. Could you try and see if this works for you?
(defun hideshowvis-display-code-line-counts (ov)
(when (eq 'code (overlay-get ov 'hs))
(let* ((marker-string "*fringe-dummy*")
(marker-length (length marker-string))
(display-string (format "%d lines" (count-lines (overlay-start ov) (overlay-end ov))))
)
(overlay-put ov 'help-echo "Hiddent text. C-c,= to show")
(put-text-property 0 marker-length 'display
(list 'left-fringe 'hideshowvis-hidden-marker 'hideshowvis-hidden-fringe-face)
marker-string)
(overlay-put ov 'before-string marker-string)
(put-text-property 0 (length display-string) 'face 'hideshowvis-hidden-region-face display-string)
(overlay-put ov 'after-string display-string))))
What happened was that current-column gets confused when I set a 'display property in the overlay. In indent-line-to delete-region then deletes the wrong part of the buffer. All I've changed now is to use 'after-string instead of 'display for the overlay property
Thanks!
I've just quickly tested, and it seems to work OK.
In fact, for the full details: I've added the change (the replacement of 'display by 'after-string) in the function definition of my modified hideshowvis-display-code-line-counts, that I modified to display the yellow box on the right of also for comments (coded added in branch https://github.com/rdiaz02/hideshowvis/tree/fixes-8-hsvis-changes-code, commit https://github.com/rdiaz02/hideshowvis/commit/e570aa8b6b3df20f661a07159f35620edd6ed371).
This is the code I use (and I've removed the advice-add in my config). I'll let you know if I see the issue.