在Bash裡,命令行按Ctrl+R可以搜尋執行過的命令,Nyagos也實作了相同功能,也能用history列出命令歷史,再用 !命令索引編號 就能重覆執行指定索引位置的命令,但現在已經2025年了,當然要用選擇的方式來快速執行。

Nyagos提供了 nyagos.box() 可以將陣列形成選單供使用者選擇,歷史選單的熱鍵是Alt+R(應該是和Ctrl+R相應),下面這行就能產生命令歷史選單:

local result = nyagos.box(share.__dump_history())

▼ 按Alt+R,按上下鍵移動,按Enter取回命令

gh|700

雖然Alt+R選單帶來一些便利,但它並沒有漸進式過濾的功能,不如改與 fzf 整合,不僅可以過濾、更美觀,也有更多功能。

為了fzf整合,用Lua寫了一個Alias hf和熱鍵 Ctrl+W

fzf 可由fzf GitHub下載,awk.exe則由Gow (Gnu On Windows)下載。

1. Alias hf

  • 用 Alias hf 以倒序方式顯示出命令的索引號、執行時間供選用,選單出現後可以再輸入過濾字串,也可以用 hf 過濾字串 在執行時先行輸入過濾字串。
  • fzf裡用上下鍵移動到要重覆執行的命令再按Enter即能將該命令帶回命令行

gh|700

nyagos.alias.hf = function(args)
  local _sQuery = ""
  if args[1] then _sQuery = args[1] end
  local _sResult = ""
  local _sCmd = 'history | fzf --cycle --tac --layout=reverse '
  if string.len(_sQuery) > 0 then _sCmd = _sCmd .. '--query=' .. _sQuery end
  _sCmd = _sCmd .. ' | awk "{match($0, /\\] (.*) \\(/, arr); print arr[1]}" '
  _sResult = nyagos.eval(_sCmd)
  if (_sResult ~= "") then
    print('Exec: ' .. _sResult .. '\n')
    nyagos.setnextline(_sResult)  -- v4.4.19 available
  end
end
  • history 將命令歷史傳給 fzf 供選擇,按Enter後將游標位置整列傳給 awk 解析,取出 ] 右方內容,再用byagos.setnextline()將命令寫回命令行
  • byagos.setnextline() 是尚未釋出的 v4.4.19 才提供的功能,可由最新Build區 取得測試檔

2. 熱鍵 Ctrl+W

與 hf 大致相同,只是改成按鍵操作。Alias可透過 args 取得傳入參數,按鍵則使用 this:lastword() 取得命令行內容,因此可以用 .docxCtrl+W的方式使用過濾字串。

nyagos.key.C_w = function(this)
  local _sQuery = this:lastword()
  local _sCmd = 'history | fzf --cycle --tac --layout=reverse '
  if string.len(_sQuery) > 0 then 
    _sCmd = _sCmd .. '--query=' .. _sQuery 
  end
  _sCmd = _sCmd .. ' | awk "{match($0, /\\] (.*) \\(/, arr); print arr[1]}"'

  local _sResult = ""
  _sResult = nyagos.eval(_sCmd)
  if (_sResult ~= "") then
    print('Exec: ' .. _sResult .. '\n')
    return _sResult
  end
end

3. 💡 相關鏈接

✅ 解說文章(繁體中文): https://jdev.tw/blog/9154/

Explanation article(English)

解説記事(日本語)

bmatzelle/gow: Unix command line utilities installer for Windows.

junegunn/fzf: :cherry_blossom: A command-line fuzzy finder

##