ivy 如何定义功能:使其位于文件夹时展开文件夹,位于文件时打开action list

默认的TAB绑定功能 ivy-partial-or-done ,会尝试补全,展开文件夹,直到位于文件时,打开该文件。

我希望最后位于文件时,不是打开该文件,而是打开该文件的action list(即调用ivy-dispatching-done),也就是说更接近 helm-ff-TAB 的行为:如果是文件夹,展开;如果是文件,打开action list。

我本来以为会有一个 file-directory-p 判断是文件,还是文件夹,然后条件执行,改改就好。然而,粗略看了下 ivy-partial-or-doneivy-alt-done 等函数,发现逻辑异常复杂 :joy:

请教各位朋友,有无现成实现方案?

  (defun maple/ivy-done()
    (interactive)
    (if (eq (ivy-state-collection ivy-last) #'read-file-name-internal)
        (let ((dir (ivy-expand-file-if-directory (ivy-state-current ivy-last))))
          (if (not dir)
              (call-interactively 'ivy-dispatching-done)
            (ivy--cd dir)
            (setq this-command 'ivy-cd)))
      (call-interactively 'ivy-partial-or-done)))

可以一次tab展开文件夹,ivy默认需要两次,如果是文件调用ivy-dispatching-done

感谢您的热心解答!在counsel-find-file下使用效果很好,不过现在有一个问题:

如果将 maple/ivy-done 直接绑定在 ivy-minibuffer-map 的TAB上,其他基于ivy的命令也会受到影响,比如 counsel-org-tag。

有无办法只为counsel-find-file绑定TAB键为maple/ivy-done?似乎ivy并不像helm,每个都有单独的keymap

渐渐感觉到ivy与helm的设计差异了。

helm会为不同的应用设计独立的keymap,因此相同的按键在不同的应用下,可以绑定到不同的按键:比如tab默认绑定到 helm-select-action ,打开可执行的动作列表。但是在helm-find-files中,tab可以另外绑定 到 helm-ff-TAB , 只在位于文件时,打开可执行的动作列表;如果位于文件夹,则展开文件夹。这样,功能之间不会互相干扰。

ivy似乎是为所有应用绑定相同的功能,因此单个功能的逻辑就会非常复杂,因为要判断各种情况,参见 ivy-partial-or-done

目前感觉就自定义设置而言,helm似乎更灵活?

如有偏误,恳请指正。