感谢这篇文章 https://www.evanlovely.com/utilities/alfred/snippets/ 给了我基本的框架
我想让 DailyNotes 支持笔记搜索,但是不希望把搜索功能耦合到 DailyNotes 代码中。使用第三方搜索工具是最好的,比如 grep
命令其实就很够用了。为了能够调用 grep
命令,并能方便地显示搜索结果,使用 Alfred 是个不错的主意。之前折腾了几次,没有成功,昨晚突然又想尝试下,终于找到了方法。其实,方法就藏在 Alfred 的文档中,只不过没心思细看。
Alfred 中调用脚本处理数据并输出结果的工作原理为:
s
是命令。{query}
指的是查询参数,例如下图中 s 是激活命令,Snowflake 就是查询参数。<items>
结构。例如:export dir="$1/"
echo "<items>"
if [ "$2" ]
then
export QUERY="$2"
find "$1" -maxdepth 1 -type f -exec grep -i -l "$2" {} + | sort -r | xargs -I {} \
sh -c 'echo "<item arg=\"$1\" type=\"file\" uid=\"$1\"><title>$(echo "${1/$dir/}")</title><subtitle>$(grep -i "${QUERY}" "$1" | head -n 1)</subtitle><icon type=\"fileicon\">$1</icon></item>"' -- {}
else
# No argument provided, list all
echo '<item arg="$dir/PeopleSoft.md" type="file" uid="$dir/PeopleSoft.md"><title>PeopleSoft.md</title><subtitle><![CDATA[人是最重要的!]]></subtitle><icon type="fileicon">$dir/PeopleSoft.md</icon></item>'
fi
echo "</items>"
这里的处理关键就是构造 <items>
,里面的每一个 <item>
就是显示在 Alfred 结果中的一个条目。例如下图中,就包含了 4 个 <item>
:
上面的脚本有个细节:里面有个逻辑判断 if [ "$2" ]
,这是因为当我们输入 s
后,Alfred 就会被立即激活,并且立即开始以空参数的方式调用脚本,此时建议用一个轻量的 <item>
响应一下查询即可,否则可能会导致响应很慢。
为了避免每输入一个字符就触发一次脚本,可以双击 Script Filter,然后编辑触发行为(Run Behavior),触发下一个脚本时杀掉上一个脚本,等待输入完成后再触发脚本等。这么做,响应速度回差一些,但是够用。
假设我实现了一个搜索引擎,那么我可以用脚本调用搜索引擎获得结果,然后把结果组织成 <items>
,最后在 Alfred 中对接一个 Open URL 的工作流即可。