swiper在搜索org文件时能不能只搜索页面可见内容(指的不是折叠)

估计很少有人会发现过这个问题,我也是今天才发现(其实早就该发现了,以前是感觉有问题但没有深究)。

一直在用ivy swiper, 我的 org文件中链接比较多 。在搜索时通常都只希望搜索链接上的文字,而不是搜索链接上的url等源代码,如同在浏览器里搜索,通常指的是搜索页面可见内容而不是搜索网页源码。

比如我的org文件中有一个删除按钮(根据文件标题自动生成),elisp源码是:[[elisp:(progn (erase-buffer)(url-insert-file-contents "http://[::1]/org.php?from=home&a=del&title=org文件加载时自动展开折叠效果测试")(save-buffer)(next-line 2)(org-end-of-line))][删除(不可恢复)]]

swiper搜索del这个词,效果是这样子的

图片

我的org文件的可见内容中并没有del这个词,搜索时把链接里的elisp源码也搜索了。

当org文件没多少链接时这样也不影响,但当org文件中链接比较多,elisp源码也比较多时,体验不太好。

使用emacs原生的搜索isearch时没有这个问题,搜索的就是页面可见内容,不会把不可见内容也搜索出来

你试试 search-invisible 这个变量能不能解决你的问题?

试了这两个变量(setq search-invisible nil) (setq isearch-invisible nil) 还是一样,没发现有变化

  1. 我认为不是很少人发现问题,而是大部分人都赞同这样的设计,至少不反对。

  2. 「页面可见内容」的「页面」是指从(window-start)(window-end) 之间内容吗?还是(point-min)(point-max)

    如果是前者,那么就是两项需求了:一、不匹配隐藏内容;二、限制搜索起/止范围。第二个需求我估计作者不会答应,感觉不符合更大众的需求。

    如果是后者,不改搜索范围,只修正 invisible 判断就比较容易了,例如 avy--visible-p 函数就符合需求。

    可以整理一下你的需求,跟作者探讨一下:GitHub - abo-abo/swiper: Ivy - a generic completion frontend for Emacs, Swiper - isearch with an overview, and more. Oh, man!

1 个赞

区域选中后再搜索

英文太差,用谷哥翻译把本文翻成了英文,去提了一个issues,emacs的原生搜索isearch搜索的就是页面可见内容,不是 (point-min)(point-max),这个设计感觉也挺好的,但不知道为什么不想用它

如果觉得没把握用英文描述清楚,用代码是不是更好一些?例如:

(with-temp-buffer
  ;;
  ;; 1. init buffer:
  ;; +------------------+
  ;; | [[foo][bar]]     |
  ;; |                  |
  ;; |                  |
  ;; ~                  ~
  ;; | [[quz][baz]]     |
  ;; +------------------+
  ;;
  (insert "[[foo][bar]]\n")
  (dotimes (_ (window-height))
    (insert "\n"))
  (insert "[[quz][baz]]\n")
  (setq-local org-hide-emphasis-markers t) ;; hide markers
  (org-mode)
  (font-lock-ensure)
  ;;
  ;; 2. test
  ;;
  (goto-char (point-min))
  (let (invisible-chars)
    (while (not (eobp))
      (unless (avy--visible-p (point))
        (push (char-after (point)) invisible-chars))
      (forward-char 1))
    (cl-assert
     (equal (mapconcat #'char-to-string (reverse invisible-chars) "")
            (concat "[[foo][]]"
                    "[[quz][]]")))
    t))
;; => t

对这段代码的意图,应该不会有理解上的歧义,而且可以 100% 重现。

感谢,把你的代码也加到issues里去了(虽然还不是很明白),试了一下用eww打开的页面,没有这个问题,swiper搜索的就是页面可见内容,不会搜索eww页面里隐藏的前端源码。我觉得org-mode应该也能做到这点。

emacs升级29.1,org-mode9.6.6,这个问题还是没找到改善办法,还更加严重了,现在不仅搜索链接里的内容,还会自动把链接展开,以前链接不会展开,就当作看不到就可以,现在链接自动展开,且不会在光标移开后自动隐藏,有些链接还特别长,完全显示出影响页面布局,相当碍眼,没法再当作看不到。

用isearch还稍微好些,swiper搜索体验下降很多 :joy: :joy: :joy:

我有个简单粗暴的想法, 直接把可见内容拷贝(这不难, 之前 chatgpt 就帮我写了一个可以 work 的, 就是读取 overlay 之类的)到 new buffer 中在这个 buffer 中搜索

有内置的 org-copy-visible

1 个赞

搜索magit buffer时也有这个问题。有时我只是想搜索文件名,但是swiper会搜索到文件里面的diff

isearch 不会吗?我刚试了下,好像isearch/consult都是一样的

(defun swiper--visible-p (pos)
  (let ((invisible (get-char-property pos 'invisible)))
    (or (null invisible)
        (eq t buffer-invisibility-spec)
        (null (assoc invisible buffer-invisibility-spec)))))

(defun swiper-visible (&optional initial-input)
  "Like `swiper' but only search for visible content."
  (interactive)
  (let ((ad-swiper--line
         (lambda (orig-fn)
           (cl-letf (((symbol-function 'buffer-substring)
                      (lambda (start end)
                        (let (visible-chars)
                          (save-excursion
                            (goto-char start)
                            (while (< (point) end)
                              (when (swiper--visible-p (point))
                                (push (char-after (point)) visible-chars))
                              (forward-char 1))
                            (mapconcat #'char-to-string (reverse visible-chars) ""))))))
             (funcall orig-fn)))))
    (advice-add 'swiper--line :around ad-swiper--line)
    (unwind-protect
        (swiper initial-input)
      (advice-remove 'swiper--line ad-swiper--line))))

(global-set-key (kbd "C-s") #'swiper-visible)

org-copy-visible 试了一下,会把链接的完整地址也复制下来,而我只需要链接的显示文字部分,就像在eww里搜索网页或list-packages里搜索包名一样 。@twlz0ne 的这段代码我试了一下,也没有效果。

有谁知道给org-mode报bug的步骤吗,问chatGPT告诉我到 //github.com/orgmode/org-mode/issues ,实际并没有这个地址

我那段代码效果是这样的:(建议你把「没效果」的图也发出来)

image image image

不得不说,一开始你的标题就让人看得云里雾里。

「页面可见内容」,一般理解就是窗口展示的可见内容,也就是不翻页就能看到的部分。

「指的不是折叠」,加上这句就更费解了。

看了上面的回帖,我推测你想要的是搜索链接 [[link][description]] 的 description,如果这也不是的话就真不知道你想要什么了。

Peek 2023-10-24 10-18

我在 emacs -Q 上没问题

org-copy-visible 的副作用是会影响 kill-ring,而且只适用于 org 文件,markdown 也有搜索折叠显示内容的需求。

我这个也不是解决方案,一开始我只是给楼上做个补充。 :joy:

image

奇怪,我这还是这样,上面是emacs -q后的配置,这个标题确实没起好,应该改成:swiper | isearch在org-mode中搜索时可否只搜索链接中的显示文字description,而不搜索链接的实际地址 ,辛苦管理员操作一下

@VagrantJoker org-copy-visible 刚才没测试好,这个确实可忽略掉链接的实际地址