ripgrep(rg)の検索結果をCotEditorで開いてタグジャンプ

2月 19th, 2019
[`evernote` not found]
Facebook にシェア

(2019年2月19日修正:macOS Mojaveでは外部のOSAXライブラリをサポートしなくなったため、satimageのライブラリを使わないように変更。正規表現のルーチンは、sed – Can’t figure out how to implement REGEX with AppleScript – Stack Overflowに掲載されていたものを使わせてもらった)

指定した文字列を含むテキストファイルを、特定のフォルダ内から検索。テキストエディタで検索結果を開き、該当ファイルの該当行を一発で開けるようにしてみました。
テキスト検索ツールとしてはripgrep、テキストエディタはCotEditor(macOS用)を使っています。

事前準備

ripgrepのインストール

Homebrewをすでに使っているなら、ターミナルから

brew install ripgrep

と入力するだけ。

テキストエディタCotEditorのインストール

CotEditorは、Mac App Storeからインストールできる。

ターミナルからCotEditorを起動できるようにする

CotEditorには「cot」というコマンドラインツールが用意されている。ターミナルから

ln -s /Applications/CotEditor.app/Contents/SharedSupport/bin/cot /usr/local/bin/cot

と入力してシンボリックリンクを作成する。

CotEditor用のスクリプトをインストール

下記のスクリプトを、macOS搭載の「AppleScriptエディタ」で入力して適当なファイル名を付け、CotEditorのスクリプトフォルダ(“~/Library/Application Scripts/com.coteditor.CotEditor”)に保存。私は「tagjump.@~j.scpt」という名前を付けた。

(※”@~”と付いているのは、command+option+jというショートカットキーでこのスクリプトを呼び出せるようにするため。詳しくはCotEditorのヘルプを参照)


use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
tell application "CotEditor"
	if exists front document then
		tell front document
			
			-- get selection's positional data
			set {locLength, selectionLength} to range of selection
			set {locLines, selectionLines} to line range of selection
			set looseSelect to 0
			-- whole lines select
			if (selectionLines is greater than or equal to looseSelect as number) then
				set line range of selection to {locLines, selectionLines}
				set {locLength, selectionLength} to range of selection
			end if
			
			-- ignore last line break
			if contents of selection ends with "
" then set range of selection to {locLength, selectionLength - 1}
			set theSelection to contents of selection
		end tell
	end if
end tell

set regex to "^(/.+):([0-9]+):(.*)"
set aRes to re_match from theSelection against regex given replacement:"/usr/local/bin/cot $1 -l $2"
if aRes is not equal to {} then
	delay 0.2
	do shell script aRes
end if

on re_match against pattern from str given replacement:fmt
	set regex to current application's NSRegularExpression's ¬
		regularExpressionWithPattern:pattern ¬
			options:(current application's ¬
			NSRegularExpressionCaseInsensitive) ¬
			|error|:(missing value)
	
	(regex's stringByReplacingMatchesInString:str ¬
		options:0 range:{0, length of str} ¬
		withTemplate:fmt) ¬
		as text
end re_match

使い方

ターミナルからripgrepで検索を実行

ターミルから

rg -n -e 検索したいパターン 検索対象フォルダのフルパス | cot

と入力する。
フルパスを手入力するのは面倒くさいけど、Finderから対象フォルダをターミナルにドラッグ&ドロップすると簡単に入力できる。

検索結果がCotEditorで開かれる。

Ripgrep coteditor 1

CotEditor上からスクリプトを実行

開きたいファイル名のところにカーソルを移動し、スクリプトメニューから「tagjump.@~j.scpt」を実行(この場合は、command+option+jキーで実行できる)

該当ファイルの該当行がCotEditorで開かれる。

(2018/01/03追記)フルパスを書くのが面倒なら、例えば下記のようなシェルスクリプト(rgcot.sh)を書いておいて、「rgcot.sh 検索パターン」のように実行すると便利。この例では、カレントディレクトリ以下から検索パターンを検索し、結果をCotEditorで開く。

#!/bin/sh
abs_path=$(cd . && pwd)
rg -n -e $1 "$abs_path" | cot -n

Leave a Reply

Comments links could be nofollow free.