沒穿方服

索引

顯示╱隱藏內文
顯示具有 command 標籤的文章。 顯示所有文章
顯示具有 command 標籤的文章。 顯示所有文章

之前 keitheis 提到比 ack 更快的 Ag (the_silver_searcher),已經成為我 search 的首選了。

ack > grep 我不以為然,但 ag 用起來就真的時髦又開心。 也不是因為快,就是指令符合懶惰需求,且沒有一些不解意圖的設計。


從 source 安裝比較實用

真正感到 stable 也是最近的事而已,所以正式 release 前,就直接 builing from source 吧,地雷可能比較少。

(version 0.14pre) 近期漂亮開發進展:

  1. #98 Files with non-english characters are trait as binary files
    修正特定檔案——例如中文較多的 html——誤判為 binary file 而被略過的問題。
  2. #110 Remove a leading "./" before printing by AndrewRadev
    移除輸出前頭的 ./ 顯示,較接近 ack/grep 行為。
  3. #90 Make colors configurable
    輸出色彩(path、line-number、match 部分)終於可以設定了。

我的設定

因為 Ag 還不支援設定檔,所以設定就是 .zshrc 裡的 alias 爾。
輸出調成類似 grep 的樣子。 再來個 agjs alias 專門搜專案中未壓縮的 JavaScript。

() {
  local common='noglob ag --nobreak --nogroup --noheading --smart-case --depth=27'
  local colors='--color-path 35 --color-line-number 32 --color-match "1;31"'
  alias ag=$common' '$colors
  alias agjs=$common' '$colors' -G public/javascripts/.*-(debug|src).js'
}

擷圖:

ag 輸出的樣子

ack 簡單易用

本來覺得有 grep 幹嘛還要 ack,用了才知身為懶惰、無力調校 grep 的人,ack 裝備上去效率立刻提升,這 cheap 的感覺相當過癮。

Ack 的好

  1. 打的字比 grep 少:
    grep foobar **/*.rb -ri --exclude-dir=.git 會變成
    ack foobar --ruby

對我來說沒別的了,有興趣請見官網 Why ack

快速完成設定

  • 我選擇裝 standalone 版本,就是單純一支 perl script,不管什麼環境都長一樣。
    依官網 ack: InstallationInstall the ack executable 敘述,curl 一下就裝好了。
  • ~/.ackrc
    基本上是顯示格式、色彩的調整; 進階一點是設定檔案 type,譬如設了 --type-set=log=.log 就可以下 ack foobar --log,只搜尋 *.log
    我的設定:
    --smart-case
    --no-heading
    --no-group
    
    --color-filename=magenta
    --color-lineno=green
    --color-match=bold\ red
    
    --type-set=log=.log
    --all-types
  • 目錄 .ackrc
    Ack 只吃一個全域 .ackrc,但要作到對「特定目錄」設定也是可能的,比如在 .zshrc 設定:
    alias ack='noglob ack $([ -f ./.ackrc ] && tr "\n" " " < ./.ackrc) '
    之後若在 rails app/ 目錄想忽略 vendor/ doc/ test/ 等,就在 app 目錄放個 .ackrc 把它們排除即可:
    --ignore-dir=vendor
    --ignore-dir=doc
    --ignore-dir=test
    --ignore-dir=tmp
    --ignore-dir=public/cache

Ack 的鳥

  • 預設排除 *.min.js

    Pull Request #142,看似體貼,其實難以接受,為什麼不能由 config 拿掉這個規則。

  • 無法指定排除檔案

    grep 的 --exclude 系列選項在 ack 不存在,無法簡易排除名為 *-src.js 的檔案。
    只能等待 ack 2.0 改進了。

zsh 還未正式支援 cap (Capistrano) 自動完成,不過以下專案有實作:

  • zsh-users/zsh-completions
    準官方的 _cap function,能補全命令列參數和 tasks。 不過沒做快取,使用上有延遲感。
  • oh-my-zsh
    只能補 tasks,且不包含 task 的說明。
    有快取,會在 Rails 目錄下存一個 .cap_tasks~ 暫存檔,當 config/deploy.rb 變動時更新。
    問題是比較過時,至少要等 Pull Request #367 後才支援 Capistrano 2.0。

我不用 oh-my-zsh,所以我想你們也不會。

好掌握的擴充方式是自己 mkdir 放自己的補全方數,譬如放 ~/.zsh/completions/,就要配合 .zshrc 這麼寫(在 compinit 之前):

# user completion plugins
if [[ -d ~/.zsh/completions ]]; then
  fpath=(~/.zsh/completions $fpath)
fi

我選擇 oh-my-zsh 的 task 補全(不顯示說明,比較簡短)和快取(但換成擺到 tmp/ 裡),加上 zsh-completions 的選項補全。 組成的 ~/.zsh/completions/_capistrano 內容在 zsh _capistrano completeion function — Gist

有時會發現 command line 輸出怪異單引號,例如某些機器上
rm all humans
輸出 `all' 和 `humans',最左邊的符號是 backtick(`)而不是引號,難道是某種內行人的黑話?

查了一些資料,原來是錯誤的歷史用法。

簡短說明

書寫引號原本是以「」和「」為一對,不過早期電腦只支援垂直的「'」, 於是許多輸出設備把

  • 重音符號`」顯示為「
  • 單引號 「'」顯示為「

這樣輸入「``I can't''」就能顯示為「‘‘I can’t’’」—— 顯示正確,但是資料錯誤。

直到 Unicode (1991) 制定各種型式的引號,才算可以處理這個需求。
既然這個月我們還在用 Big-5 的系統報稅,看到這種引號似乎也不必太驚訝。

週末讀到 par 這個小巧指令,用於文字段落(paragraph)的格式化,例如在 Vim 裡面用 :'<,'>!par 把選取區內特定格式的段落重排。

看看 Descripton 裡的範例 Par 1.52 - paragraph reformatter 便能大概瞭解其用途。
有趣的是說明文件 par.doc,以我水平實在難懂,好像不屬這世界的寫法;如做智力測驗題目的兒時記憶,讓我半夜對著螢幕靜靜傻笑。

以上樂趣分享,以下簡易筆記(私用性質,請小心誤導


par 轉換大略過程 (how it works)

  1. Text

  2. 根據換行字元拆成 lines

                    line
    Text     =>     line
                    line
                      ⋮
  3. 將 lines 分為幾組 segment

    會找出 protected line(開頭字元符合 protected 字,具體哪些字可另外設定)或 blank line(僅含空白、Tab 等字的行)——這兩種行將直接輸出而不會轉換;而剩下來一段段的 lines 就是 segment。
    line (protected)
    line                        segment 1
    line                        segment 1
    line                 =>     segment 1 (3 lines)
    line (blank)
    line                        segment 2
    line                        segment 2 (n lines)
      ⋮                               ⋮
  4. 將 segment 內容(lines)分為幾組 block

    會找出 bodiless line(內容不是真的本文,例如 /*** ... ****/)和 superfluous line(冗行:整行空白、或既 bodiless 且中間重複字元全為空白)。
    bodiless line - 根據選項(repeat)調整輸出方式,
    superfluous line - 根據選項(expel)可能不輸出。
    segment line                         (只有一行應該不算 block?但仍會在後續步驟處理)
    segment line (bodiless)               
    segment line                 =>       block 1
    segment line                          block 1
    segment line (superfluous)
    segment line                          block 2
          ⋮
  5. 將 block 分為幾組 IP (Input paragraph)

    若選項(div)沒開,一個 block 就是一個 IP
  6. 對每個 IP 中的 lines,拿掉 <prefix>, <suffix>,剩下的字重排

    /* PREFIX WORD, WORD SUFFIX */
    /* PREFIX WORD SUFFIX */
    /* PREFIX WORD. WORD WORD SUFFIX */
                  ↓
    WORD, WORD
    WORD
    WORD. WORD WORD
                  ↓
    WORD, WORD WORD 
    WORD. WORD WORD
  7. 把 <prefix>, <suffix> 插回去

實際上根據選項,過程中各種細節都會影響輸出,不過這邊就沒研究了。


par 使用小抄 (how-to-use-it)

此為上課順手記,不是實戰用的。

par 59f         f (fit) 盡可能保持原寬度(59 字)
par 59l         l (last) 盡可能讓最後一行與其它行同寬
par 59t0        t0 (touch 0) 輸出寬固定為 59
par 59j         j (just) text justified
par 59h3        h (hang) 分開前 3 行與之後行的 prefix, suffix 計算
par 59p         p (prefix) 保證每行的前 59 字和 Input 相同
par 59d         d (div) 每行依照 comprelen+1 個字是否為空格,切割為不同 IP
par 59r         r (repeat, r 不給參數則為 3) 變更 bodiless line 定義,repeat 字元 3 次以上也算為 bodiless(原本只有空白才算)
                r 不為 0 時,會使 repeat 字元最多調整到 59
par 59e         e (expel) 不輸出 superfluous line
par 59q         q (quote) 於不同級的引用插入 vacant line
par 59i         i (invis) 不輸出 quote 插入的 vacant line
par 59g         g (guess) 判斷相連的 curious word, capitalized word 如何連接(例:Dr. Jon 分行時被當作一個字)
par 59gc        c (cap) 所有的詞皆視為 capitalized word
par Q+:+ q      將 "+ " 也視為引用字元(加入 PARQUOTE)再執行 q