読者です 読者をやめる 読者になる 読者になる

PowerShell の入力補完にGoogleサジェストの結果を表示する

↑ みたいな事って出来るのかな、となんとなく調べてみたところ、どうやら TabExpansion++ というモジュールを使うと簡単に出来そう!
という事で、ちょっと試してみました。

f:id:pierre3:20150625215746p:plain

TabExpansion++

github.com

PowerShellのTab補完、インテリセンスをより賢く、便利にするモジュールで、
コンテキストに応じた入力候補を動的に生成してくれるようです。

さらには、入力候補の生成処理を自作して組み込むことが出来るとのことで、今回はこの機能を使ってGoogleサジェストの結果をインテリセンスに表示させてみたいと思います。

インストール

iex (new-object System.Net.WebClient).DownloadString('https://raw.github.com/lzybkr/TabExpansionPlusPlus/master/Install.ps1')

でダウンロードして、Install.ps1 を実行するか、PsGet がインストールされていれば以下でインストールできます。

Install-Module -ModuleUrl https://github.com/lzybkr/TabExpansionPlusPlus/zipball/master/ -ModuleName TabExpansion++ -Type ZIP

後は、プロファイルに Import-Module TabExpansion++ を追加しておけば準備完了です。

Search-Google コマンドレット

まずは、Google でWeb検索するコマンドレットを作成します。
パラメータ($SearchWords)に検索ワードを渡すと、検索クエリ付のURLを生成してブラウザに投げるだけの簡単なものです。

Search-Google -$SearchWords あ のように入力して、[Tab]または[Ctrl]+[Space]を押すと、
Googleサジェストから取得した入力候補が表示されるようになればOKです。

入力候補を動的に生成する関数の定義

以下の要件を満たした関数を定義するだけで、自作の入力補完処理が使用できるようになります。
(すごい!)

  • 関数に ArgumentCompleter 属性を付ける。

    • ここで、入力補完のターゲットとしたいコマンドとそのパラメータ名を指定します。
    • コマンドは配列で複数指定することが可能です。
  • 入力パラメータは以下の様に定義する。

    • param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
    • $wordToComplete に補完対象となる入力中の文字列が入ってきます。
  • System.Management.Automation.CompletionResult クラスのオブジェクトを出力する

    • New-ComoletionResult コマンドを使用して生成します。引数には順に以下を渡します。
      • CompletionText:補完結果の文字列
      • ToolTip: ツールチップに表示される文字列(省略可。省略時は第1引数と同じになる)
      • ListItemText: 入力候補一覧に表示される文字列(省略可。省略時は第1引数と同じになる)
      • CompletionResultType : 入力候補の種別 (一覧の左側に表示するアイコンを指定できる)(省略可。規定値'ParameterValue')
      • NoQuotes : 文字列の中の変数を展開するか否かを指定?(違うかも)(省略可。規定値False)

では、実際に関数を作ってみましょう。
SearchWoerdsパラメータの一部として入力された文字列をGoogleサジェストに投げて、帰ってきた結果から CompletionResult を生成して出力します。

(2015/12/5 追記) PowerShell v5.0からは、Register-ArgumentCompleter コマンドレットで処理を登録できるようになりました。こちらを使用したサンプルコードを追記します。(以下2番目のコード)

後は、これを記述したスクリプトファイルを 以下の何れかに配置しておくだけでOKです。

  • $env:PSModulePath に定義されているPath の1階層下のフォルダ
  • 任意のフォルダに置いて、そのパスを $env:PSArgumentCompleterPath に設定する

実行結果

"powershell" と入力して[Ctrl]+[Space]

f:id:pierre3:20150627002308p:plain

"powershell" と入力して[Tab]

f:id:pierre3:20150625220854p:plain

まとめ

思った以上に簡単に実現できてしまって驚きです。

他にも工夫次第でいろいろ便利なものが出来そうな予感がします。

TabExpansion++ が提供する入力補完も相当数あるようですので、自作しなくても十分かもしれませんが。