Emacs Helm: 使用关键字搜索、获取、执行任何东西

Helm 是一个emacs的软件包,定义了一个通用框架,交互式地、动态缩减式地使用关键字选择、获取、执行任何东西。比如:

  • 执行emacs 命令
  • 打开文件
  • 查看man文档
  • 执行grep操作
  • 执行apt命令
  • 相看imenu函数定义
  • 切换buffer

Helm软件包本身包含两部分,框架本身及应用。以上列表均为应用。基于框架,可以轻松创建新的应用。

基本原理

Helm的三个重要概念:candidate, narrowing, action.

Candidate

Candidate即候选值,是一个列表,保存所有可供选择的条目。对于打开文件的命令,candidate是所有的文件名称的列表。

Narrowing

Helm命令启动后,用户未输入任何关键字前,会将candidate中的所有条目显示出来,每行显示一个项,可通过‘C-n‘, ‘C-p‘上下移动光标选择当前条目。

如果candidate的数目较少,此时没必要输入关键字,通过上下移动光标选择就行了;但如果candidate数目较多,目标条目没有被显示在第一页,可输入关键字,对candidate的条目进行筛选,只有匹配到关键字的条目才会被显示出来。这就是narrowing。

值得一提的是,这个过程是动态的,即每输入一个字符,candidate的条目都会被重新筛选。有时只输入了一个字符,目标条目已经显示在第一页,则可停止输入,通过移动光标选择当前条目;有时输入了一个关键字,目标条目仍然没有出现,则可按空格,继续输入另一个关键字,进行更精确的筛选,直到目标条目出现为止。

输入的关键字越多,candidate的数目会越少,目标条目出现在第一页第一个条目位置的机率就越大,进而选择也就越方便。

Action

当一个candidate被选中后,按下Enter后,就会有一个action被执行。对于打开文件,其action对应到emacs命令就是‘find-file‘。可以为一个条目定义多个action,如对于文件条目action可以为打开文件、重命令文件、删除文件等。 通过TAB键从多个action中选择,如果直接按Enter会执行第一个action.

定义一个新的helm应用

基本例子

要定义一个新的helm命令,只需定义一个变量指定candidate及对应的action,然后将其作为参数传给helm就可以了,以下为一个例子。

(setq some-helm-source
      ‘((name . "HELM at the Emacs")
        (candidates . (1 2 3 4))
        (action . (lambda (candidate)
                    (message-box "%s" candidate)))))

(helm :sources ‘(some-helm-source))

其中定义candidate、action的变量叫做source, 是一个assoc list。candidates是一个list, action是一个函数,action函数被调用时,当前选择的candidate会被作为参数传入。

定义多个action

上面的例子中action的值为一个匿名函数,如果要定义多个action,则需要将action的值设置为一个list,list的元素是一个cons:(说明 . 函数)。如下所示,定义了两个action。

(setq some-helm-source
      ‘((name . "HELM at the Emacs")
        (candidates . (1 2 3 4))
        (action .
                (("Display" .  (lambda (candidate)
                                 (message-box "%s" candidate)))
                 ("None" . identify)
                 ))
        ))
(helm :sources ‘(some-helm-source))

将candidate的选择值与真实值分离

有时候需要通过不同的值选择candidate,此时可将candidates设置为cons (KEY . VALUE)的list。其中KEY将用于选择,VALUE将作为action函数的输入参数值。

(setq some-helm-source
      ‘((name . "HELM at the Emacs")
        (candidates . (("one" . 1) 2 ("three" . 3) 4))
        (action .
                (("Display" .  (lambda (candidate)
                                 (message-box "%s" candidate)))
                 ("None" . identify)
                 ))
        ))
(helm :sources ‘(some-helm-source))

动态candidate

有时candidates需要动态计算,或者静态计算量会很大,此时可将candidates设置为一个函数,这个函数将被用于计算所有candidates的值。

(defun random-candidates ()
  "Return a list of 4 random numbers from 0 to 10"
  (loop for i below 4 collect (random 10)))

(setq some-helm-source
      ‘((name . "HELM at the Emacs")
        (candidates . random-candidates)
        (action . (lambda (candidate)
                    (message "%s" candidate)))))

(helm :sources ‘(some-helm-source))

helm-org-headlines的定义

这个命令由helm默认提供,其定义如下:

(setq helm-source-org-headline
      `((name . "Org Headline")
        (headline
         ,@(mapcar
            (lambda (num)
              (format "^\\*\\{%d\\} \\(.+?\\)\\([ \t]*:[[email protected]:]+:\\)?[ \t]*$"
                      num))
            (number-sequence 1 8)))
        (condition . (eq major-mode ‘org-mode))
        (migemo)
        (subexp . 1)
        (persistent-action . (lambda (elm)
                               (helm-action-line-goto elm)
                               (org-cycle)))
        (action-transformer
         . (lambda (actions candidate)
             ‘(("Go to line" . helm-action-line-goto)
               ("Refile to this headline" . helm-org-headline-refile)
               ("Insert link to this headline"
                . helm-org-headline-insert-link-to-headline))))))

(defun helm-org-headlines ()
  "Preconfigured helm to show org headlines."
  (interactive)
  (helm-other-buffer ‘helm-source-org-headline "*org headlines*"))
时间: 2024-10-03 14:02:10

Emacs Helm: 使用关键字搜索、获取、执行任何东西的相关文章

Jquery实现页面关键字搜索

<style type="text/css"> .highlight { background-color:yellow; } </style> <script type="text/javascript" src="../jquery.js"></script> <script type="text/javascript"> $(document).ready(fu

纯客户端页面关键字搜索高亮jQuery插件

一.效果抢鲜展示 此插件是我今天下午写的,为了直观地看到是个什么东东,先展示效果,您可以狠狠地点击这里:搜索页面文字jQuery插件Demo 下图为Demo页面的两个测试截图 – 测试页面HTML代码取自豆瓣网帮助页面: 下载 您可以狠狠地点击这里:jquery.textSearch-1.0.js 文件较小,功能简单,恕不打包~~ 二.功能简述 从上图也应该看出来了,就是对HTML页面上的文字内容进行高亮标记,这个可以用在内容搜索上.纯粹的客户端程序,与后台一点瓜葛都没有. 三.如何使用 使用方

《新浪微博自动评论软件&#183;设计与实现之关键字搜索篇》

任务:进行关键字搜索,对结果批量评论 通过GET请求来获取搜索页面,其url:http://s.weibo.com/weibo/keyword&Refer=STopic_box.其中keyword为搜索关键字. 利用Python的RegEx解析网页,获取每条微博的mid. 手动对一条微博发送评论,抓取其数据包,分析其中各个参数及其作用以便在程序中对其进行更改模拟,其中包括但不限于Cookie字段以及POST参数mid.content. 利用Python编写程序模拟3中的情况重新提交POST请求,

Oracle获取执行计划方法

获取执行计划的6种方法 1. explain plan for获取: 2. set autotrace on : 3. statistics_level=all; 4. 通过dbms_xplan.display_cursor输入sql_id参数直接获取 5. 10046 trace跟踪 6. awrsqrpt.sql 适用场合分析 1.如果某SQL执行非常长时间才会出结果,甚至慢到返回不了结果,这时候看执行计划就只能用方法1: 2.跟踪某条SQL最简单的方法是方法1,其次就是方法2,方法2要执行

JSON 之 SuperObject(16): 实例 - 解析 Google 关键字搜索排名

同上例类似, 通过 'http://clients1.google.cn/complete/search?&q=' + "关键字" 可以获取 Google 的关键字搜索排名. 我用 Delphi 为关键字得到的结果是: window.google.ac.h( ["Delphi",[ ["delphi 教程", "375,000 结果", "0"], ["delphi盒子", &q

XE3随笔18:实例 - 解析 Google 关键字搜索排名

同上例类似, 通过 'http://clients1.google.cn/complete/search?&q=' + "关键字" 可以获取 Google 的关键字搜索排名. 我用 Delphi 为关键字得到的结果是: window.google.ac.h( ["Delphi",[ ["delphi 教程", "375,000 结果", "0"], ["delphi盒子", &q

如何用圆形搜索获取中心点周围100米内全部关键点?如天安门附近所有的餐厅、加油站、宾馆、大厦等

摘要: 在LBS上有这样一个常用的功能,查找附近所有的关键点(POI点,比如标志性建筑物,餐厅,大厦,加油站等).相信大家对search已经非常熟悉了,可是search必须要传"关键字"参数,即使是多关键字搜索,也要把所有POI的tag都一一列举出来,才能搜索到结果.那么,有没有什么办法,可以不用关键字,就搜索到附近全部的POI呢? 答案是肯定的.我们一起来学习一下吧~ ----------------------------------------------------------

EXPLAIN 获取执行语句计划

可以通过 EXPLAIN 获取执行语句计划,从而优化语句. 会显示如下信息: 其中,id:select 语句的 ID:    select_type:查询的基本类型(例如,简单的查询,union 查询,衍生表查询,即 from 子句里的子查询):   table:输出的记录所在的 table:   type:join type,描述了查询的 连接类型(密切影响性能),有很多种类:   possible_keys:在表中可被使用的索引:   key:MySQL 选择使用的索引:

python中获取执行脚本路径方法

1.sys.path[0]:获取执行脚本目录绝对路径 #每次执行脚本时,python会将执行脚本目录加入PYTHONPATH环境变量中(sys.path获取) #!/usr/bin/python3 import os import sys print(sys.path) print(sys.path[0]) 执行结果: [[email protected] tmp]# ./py_test1/pytest24.py ['/tmp/py_test1', '/usr/local/lib/python3