しばたテックブログ

PowerShellを中心に気分で書いている技術ブログです。

WMF 5.1の新機能をざっくり説明する - 3. コンソール機能強化 編

今回は

  1. 新シナリオと機能 編
  2. バグ修正 編

の続きです。

今回の対象範囲

WMF 5.1 のコンソール機能強化

についてわかる範囲で補足を入れていく感じにします。

VT100 のサポート

Windows 10 では、VT100 エスケープ シーケンスのサポートが追加されました。
PowerShell は、テーブルの幅を計算するとき、特定の VT100 書式指定エスケープ シーケンスを無視します。

について、VT100エスケープシーケンスはTH2(1511)から利用可能なのですがデフォルトで無効になっています。
来月のAnniversary Update(RS1)でデフォルト有効になる様です。

TH2でエスケープシーケンスを有効にするには以下のコードを実行します。

#
# Windows 10 TH2(1511)以降でのみ有効
#
# Win32 API定義をAdd-Typeする
Add-Type -MemberDefinition @"
[DllImport("kernel32.dll", SetLastError=true)]
public static extern bool SetConsoleMode(IntPtr hConsoleHandle, int mode);
[DllImport("kernel32.dll", SetLastError=true)]
public static extern IntPtr GetStdHandle(int handle);
[DllImport("kernel32.dll", SetLastError=true)]
public static extern bool GetConsoleMode(IntPtr handle, out int mode);
"@ -Namespace Win32 -Name NativeMethods
# コンソールモードを変更
$Handle = [Win32.NativeMethods]::GetStdHandle(-11) #  stdout
$Mode = 0
$Result = [Win32.NativeMethods]::GetConsoleMode($Handle, [ref]$Mode)
$Mode = $Mode -bor 4 # undocumented flag to enable ansi/vt100
$Result = [Win32.NativeMethods]::SetConsoleMode($Handle, $Mode)

この辺の話は、

stknohg.hatenablog.jp

でも触れているので参考にしてください。
尚、

VT100 エスケープ シーケンスは、Windows 10 Anniversary 更新以降でのみサポートされることに注意してください。
それより前のシステムではサポートされません。

とあるのでTH2では機能は使えどもサポートされない様です。

MSDNに記載されているサンプルを試してみると以下の様な感じになります。

if ($host.UI.SupportsVirtualTerminal)
{
    $esc = [char]0x1b
    "A yellow ${esc}[93mhello${esc}[0m"
}else{
    "A default hello"
}

WMF 5.0(通常)

f:id:stknohg:20160731013641p:plain

WMF 5.1

f:id:stknohg:20160731013648p:plain

WMF 5.0(エスケープシーケンス有効化)

f:id:stknohg:20160731013656p:plain

補足として、$host.UI.SupportsVirtualTerminalについてはWMF 5.1から利用可能なプロパティですので、WMF 5.0でエスケープシーケンスを有効にしても値を取得することはできません。

PSReadline での vi モードのサポート

これはWMF 5.1ではなくPSReadline 1.2の新機能になります。

WMF 5.0以前でもPSReadline 1.2にすればviモードを利用することができます。
WMF 5.1に搭載されるPSReadlineが1.2になるのでここに載っている感じでしょうか。

vi モードへの変更にはSet-PSReadlineOptionコマンドレットを使い以下の様にします。

# 変更するとき
Set-PSReadlineOption -EditMode Vi

元に戻すときはセッションを終了するか以下の様にします。

# 元に戻すとき
Set-PSReadlineOption -EditMode Windows

私はviちからがほとんどないので断言はできないのですが、初期状態が挿入モードだったり、モード変更にCtrl+[が使えなかったり*1と、「これ本当に使えるのか?」という使用感でした。
コンソール上の入力欄は基本1行なのでそこでviのモード変更というのは相性が悪い気がしています。

このあたりviに強い方の使用感を聞いてみたいですね。

対話型の入力を使用する stdin のリダイレクト

地味にうれしい改善です。

あまり知られていない機能ですが、PowerShellで対話型の入力を標準入力からリダイレクトするにはpowershell.exe -File -とする必要がありました。
使いどころを説明するのが難しいのですが、過去に、

stknohg.hatenablog.jp

のエントリで、OpenSSHのSSHdにログインした後にPowerShellを起動する際に使ったりしています。

この引数がWMF 5.1からは不要になるということです。

PSReadline は現在はリダイレクトされた stdin をサポートせず、リダイレクトされた stdin での組み込みコマンド ライン編集エクスペリエンスは非常に限られたものであることに注意してください (たとえば、方向キーは機能しません)。
PSReadline の将来のリリースではこの問題が対処されるはずです。

については、現状powershell.exe -File -をした場合はPSReadlineは使えないといった程度の認識でよいかと思います。

リンク

他の回のリンクはこちら。
その1その2その4

*1:こちらはキーバインドをカスタマイズすれば対処できそうですが..