web-mode
有一个内置的web-mode-fold-or-unfold
函数,但这个函数有一个问题,当存在fold时,使用indent-region
会得到错误的缩进,想要得到正确的缩进,必须先 unfold
, 比如
<div> <div class="col-xs-3 col-sm-3" id="sidebar" role="navigation"> <button class="btn btn-primary">Submit</button> <br /> <span> <button class="btn btn-primary">Submit</button> <br /> </span> <span> <button class="btn btn-primary">Submit</button> <br /> </span> </div> </div> <button class="btn btn-primary">Submit</button> <br /> <a href="">as</a>
当把div#sidebar使用web-mode-fold-or-unfold
折叠起来, 然后使用
(defun maple/indent-buffer () "Format buffer with `indent-region`." (interactive) (save-excursion (indent-region (point-min) (point-max) nil)))
展开后就会变成
<!-- sidebar --> <div> <div class="col-xs-3 col-sm-3" id="sidebar" role="navigation"> <button class="btn btn-primary">Submit</button> <br /> <span> <button class="btn btn-primary">Submit</button> <br /> </span> <span> <button class="btn btn-primary">Submit</button> <br /> </span> </div> </div> <button class="btn btn-primary">Submit</button> <br /> <a href="">as</a>
这与期望的效果不符(不知道是不是只有我碰到,还是这可能是一个bug), 我去看了一下web-mode-fold-or-unfold
的实现, 它使用的是
(put-text-property beg-inside end-inside 'invisible t)
来隐藏折叠部分, 我不太清楚为什么使用put-text-property会使indent-region缩进有问题,有知道的可以告知一下,但我平时在其他项目中都是使用 hs-toggle-hiding
来折叠代码, hs-toggle-hiding
能很好的与indent-region
配合
由于web-mode-fold-or-unfold
这个函数太长,不想占用我自己的配置, 所以魔改了一下
(fset 'maple/put-text-property (symbol-function 'put-text-property)) (defun maple/web-mode-put-text(p q prop value) (if (and (eq prop 'invisible) value) (hs-make-overlay p q 'code) (maple/put-text-property p q prop value))) (defun maple/web-mode-fold-or-unfold() (interactive) (cl-letf (((symbol-function 'put-text-property) 'maple/web-mode-put-text)) (web-mode-fold-or-unfold)))
把put-text-property
临时修改成hs-make-overlay
,这样web-mode折叠后就能正确地使用maple/indent-buffer
了