記法を習得しないといけないですが、その結果次第では開発が便利になりそうですよ。 正規表現を使うとプログラミングコードを一気に置き換えることができます。graspはそれをさらに柔軟に、そしてJavaScriptに特化させたソフトウェアになります。 grepや置換ツールの代替に使ってみると面白いかも知れません。使い方がこれまでにない感じですが、使いこなせば強力なツールになる可能性を秘めています。 インストールは簡単で、npmコマンドでできます。

$ npm install -g grasp

続いてヘルプ

$ grasp --help
Usage: grasp [option]... [selector] [file]...

Search (or --replace) for selector in file(s) or standard input.
For more help '--help more', '--help --option-name', '--help syntax'
Example: grasp --context 2 'if.test bi[op="< "]' file.js file2.js

Miscellaneous:
  -h, --help                       display this help and exit '--help more' for more help info
  -v, --version                    print version information and exit
  -d, --debug                      output debug information
  -x, --extensions [String]        comma separated list of acceptable file extensions - default:
                                   js
  -r, --recursive                  recursively search directories

Replacement:
  -R, --replace replacement::String  replace each match with replacement, use `--help --replace`
                                     for more info
  -F, --replace-file file::String  replace each match with contents of file
  -t, --to Object | String         write replaced output to file(s), `--help --to` for more info
  -i, --in-place                   overwrite input files with replaced output

Selector interpretation:
  -s, --squery                     use squery - selector query - css style selectors
  -e, --equery                     use equery - example query - use code example with wildcards
  -f, --file file::String          obtain selector from file

Output control:
  -m, --max-count n::Int           stop after n matches
  -n, --line-number                print line number with output lines - default: true
  -b, --col-number                 print column number with output lines
  -H, --filename                   print the file name for each match (opposite: `--no-filename`)
  -o, --only-matching              show only the matching part of the line(s)
  -q, --quiet, --silent            suppress all normal output
  -W, --files-without-match        print only names of files containing no match
  -w, --files-with-matches         print only names of files containing matches
  -c, --count                      print only a count of matches per file
  -O, --color, --colour            use color to highlight matches - default: true
  -j, --json                       JSON output for matches

Context control:
  -B, --before-context n::Int      print n lines of leading context
  -A, --after-context n::Int       print n lines of trailing context
  -C, --context n::Int             print n lines of output context
  -NUM::Int                        same as --context NUM

Version 0.1.0
<http://graspjs.com/>

では実際に使ってみます。例えばサンプルとして次のようなコードがあったとします。

$ cat a.js
function g(x) {
  if (x && f(x)) { return [1, 2]; }
  doSomething();
  while(x < 2) {
    if (xs.length && ys.length) {
      return xs[x] + ys[x];
    }
    x++;
  }
  if (x == 3 && list[x]) {
    return list;
  }
}

まずif文を抽出します。Squeryという記法になります。

$ grasp 'if.test' a.js
2:  if (x && f(x)) { return [1, 2; }]
5:    if (xs.length && ys.length) {
10:  if (x == 3 && list[x]) {

続いてreturn 〜の部分を抽出。

$ grasp -e 'return __' a.js
2:  if (x && f(x)) { return [1, 2;] }
6:      return xs[x + ys[x];]
11:    return list;

さらにreturn ○○+○○という形の行を抽出。__で省略できる仕組みです。正規表現より分かりやすいかも知れませんね。

$ grasp -e 'return __+__' a.js
6:      return xs[x + ys[x];]

そして置換の仕組みも用意されています。ここの文法が今ひとつ理解できていないのですが、変数の判定を置き換えたり、関数で覆ったりするのも容易にできるようです。

$ grasp bi --replace '{{.r}}+{{.l}}' a.js
function g(x) {
  if (x && f(x)) { return [1, 2]; }
  doSomething();
  while(2+x) {
    if (xs.length && ys.length) {
      return ys[x]+xs[x];
    }
    x++;
  }
  if (3+x && list[x]) {
    return list;
  }
}

公式サイトにデモが用意されていますので、試してみてください。

graspはJavaScriptの構造を認識した上で置換や検索を行うソフトウェアになります。汎用的な正規表現に比べるとJavaScriptに特化している分、より細かな検索や置換ができるようになっています。構造を認識していることもあって例えば、

if(〜){f(x)}

と一行で書かれている場合と、

if(〜){
  f(x)
}

と三行で書かれている場合を正しく検索、置換できるということです。この辺りが正規表現とも相違点になるかも知れません。

graspはnode/JavaScript製、MIT Licenseのオープンソース・ソフトウェアです。

grasp - JavaScript structural search and replace gkz/grasp