MacOS ユーザが WSL ではない Windows の開発環境を整えるメモ
最近メインの開発マシンを MacOS から Windows (+ WSL2) に乗り換えた。普段の開発では WSL2 を使ってるし、WSL2 は Linux なので、WSL2 上での開発環境構築にはほとんど苦労しないのだけど、 WSL2 を使わない Windows 上でも開発することが出てきたたので、その時の開発環境を整える(2020年7月時点)作業、のメモ 📝。
なので ここでは WSL2 については基本触れない。
一行まとめ
Scoop 最高
パッケージマネージャ
A command-line installer for Windows
MS謹製の winget はまだ insider preview だし、chocolatey は管理者権限を標準では要求する
scoop はユーザ権限でインストールできる。~/scoop/ が作られ、その下にアプリが入る
$ scoop install git vim neovim nvs ruby wget curl
など、メジャーなものからそうでないものまで、様々なパッケージがある。
アンオフィシャルなレポジトリも追加できるよ
PowerShell(PS), cmd.exe 両方で使える
scoop 便利すぎて、なぜ今まで使っていなかったのか感がある。
sudo したいのじゃ
$ scoop install sudo
で PS , cmd.exe 上で sudo が使えるようになる
管理者権限が必要なことは、これで $ sudo command で実行できる
いい感じのターミナル使いたい
cmder を使う
Windows Terminal もあるけど、cmder (ComEmu) は以前も使っていたので、使い慣れてる cmder でまずは構築してみる
$ scoop install cmder
で入る。なんでもできるな scoop …
インストール後は PS 上で cmder とうつと立ち上がる。
cmder の標準の起動シェルを PowerShell にしておく
Ctrl-Tab と Ctrl-W と Ctrl-T を覚えておけばとりあえず使える。
PS の外観を整える
知識がないので何も考えず oh-my-posh と posh-git を入れる
oh-my-posh は名前の通り oh-my-zsh の Powershell 的な立ち位置、oh-my-zsh ほど多機能ではないけど
PS の起動時に設定を追加する
cmder だと ~/scoop/apps/cmder/current/config に user_profile.ps1 があって、PS の起動時に読み込まれる。
.bashrc のようなものなので、ここに設定を追加する
$ nvim ~/scoop/apps/cmder/current/config/user_profile.ps1
素vimだとまだ文字エンコーディングの設定をしてないので文字化けが起きる。nvim (neovim) だとおきなかった
普通に powershell 上で簡単に vim が叩ける嬉しさよ
Windows で Path を通すという、めんどくさい作業が無くなっただけでもかなり嬉しい。
vscode が入っていれば、code ./user_profle.ps1 とかでも OK
code:powershell
Import-Module posh-git
Import-Module oh-my-posh
Set-Theme Paradox
font を追加する
$ scoop bucket add nerd-fonts
$ sudo scoop install Meslo-NF
これで Meslo フォントが使えるように。cmder の設定でフォントを変えておく。
Meslo LG L
GitHub のソースコードをいい感じに clone して利用したい
つまり、ghq + fzf (か peco)が使いたい
まずは ghq と fzf を入れる。
$ scoop install go
$ go get github.com/x-motemen/ghq
$ scoop install fzf
github から clone できるようにする
普通に ~/.ssh に鍵を置く
ssh-agent はなんと Windows 標準の物が使える、のでサービスとして起動時に立ち上げるようにしておく
ただ、git コマンド利用時の ssh は別のものを使ってるようなので、env で windows の OpenSSH を指定する
code:ps1
$env:GIT_SSH = "C:\WINDOWS\System32\OpenSSH\ssh.exe"
ただ、こんどは warn が出る…
code:git
$ git push
warning: agent returned different signature type ssh-rsa (expected rsa-sha2-512)
そのため Microsoft 謹製の最新の Win32-OpenSSH を入れる
$ scoop install win32-openssh
Run 'sudo C:\Users\hotch\scoop\apps\win32-openssh\current\install-sshd.ps1' to install sshd and ssh-agent as a service.
とのことなので、↑を実行して ssh-agent をサービスに追加する
結局、GIT_SSH の path は scoop 以下となった…。
code:ps1
$env:GIT_SSH = "$env:USERPROFILE\scoop\apps\win32-openssh\current\ssh.exe"
再度サービスからOpenSSH Authentication Agentの自動起動を入れておく。
これで問題なく git push & ssh-agent 周りが上手く行った
ghq の設定で ~/src にダウンロードされるようにしておく
$ git config --global ghq.root ~/src
うまくいった
ghq + fzf
$ cd "$(ghq root)\$(ghq list | fzf)"
を実行。うまくいく。
これを bash でいうところの alias 登録がしたい
cmder が立ち上げる Powershell の場合、$env:USERPROFILE\scoop\apps\cmder\current\config\user_profile.ps1 に function として登録すれば良いらしい。
code:ps1
function gf {
cd "$(ghq root)\$(ghq list | fzf)"
}
source ~/.bashrc みたいなのは . $env:USERPROFILE\scoop\apps\cmder\current\config\user_profile.ps1でいける。
これで gf で ghq のリストを表示して fzf で選択、ができるように
続いてキーボードショートカット(zsh でいう bindkey)で gf を起動したい
zsh では C-] を割り当てていた
PSReadline のドキュメントを読んでいたらできそうだった
code:ps1
$shortcut_gf = @{
Key = 'Ctrl+]'
BriefDescription = 'ghq + fzf'
LongDescription = 'ghq + fzf'
ScriptBlock = {
gf
}
}
Set-PSReadLineKeyHandler @shortcut_gf
うまく動いた!これでC-] で gf が起動するぞ!
あと zsh では alias ghg='ghq get --shallow' を割り当ててる(大体最新のソースコードを見たいときが多いから shallow で取得する)ので、それも試しに作ってみる。
code:ps1
function ghg {
ghq get --shallow $args
}
$args で引数を渡せるぽい
$ ghg rails/rails
-> うまくいった
このへんで oh-my-posh のフォント周りの設定がうまく行ってないことに気づく。
ググってたら以下のブログに辿り着く
めちゃ良いですね↑の記事、といわけで今後は記事も参考にしつつ環境を整える。
PowerShell Core (pwsh.exe) を入れる
今まで使っていたのは最新の PowerShell では無いことに気づく。
~v5系(PowerShell, powershell.exe)と、v6系~(PS Core, pwsh.exe)に分かれる。
たしかに、Windows 標準の PowerShell を立ち上げると、👇の表示が出ていたな…。
$ scoop install pwsh
$ scoop witch pwsh
~\scoop\apps\pwsh\current\pwsh.exe
上の pwsh.exe を cmder で立ち上がるようにセットする。
code:ps1
pwsh -ExecutionPolicy Bypass -NoLogo -NoProfile -NoExit -Command "Invoke-Expression 'Import-Module ''%ConEmuDir%\..\profile.ps1'''"
PowerShell が PS Core に変わったため、もう一度 oh-my-posh 等を入れ直しておく
$ Install-Module oh-my-posh -Scope CurrentUser
$ Install-Module posh-git -Scope CurrentUser
PSReadLine は beta を入れておく (oh-my-posh の README.md より)
$ Install-Module -Name PSReadLine -AllowPrerelease -Scope CurrentUser -Force -SkipPublisherCheck
vscode でも pswh.exe を使う場合は vscode の settings.json で、👇のような設定をしておく。
code:json
"terminal.integrated.shell.windows": "${env:USERPROFILE}\\scoop\\apps\\pwsh\\current\\pwsh.exe",
Powerline 対応フォントを入れる
上の方で書いている font は Powerline にうまく対応していなかった
やった、Powerline まわりのフォントがうまく出るようになったぞ!
PowerShell のキーバインドを Linux (Emacs?) ぽくする
標準だと Ctrl-a が行頭じゃなくて、選択になったりする。
Set-PSReadLineOption -EditMode Emacs
を user_profile.ps1 にセット
Ctrl-a などの動きがそれっぽくなったぞ
PSReadLine のキーバインド
ls とか cat とか、Linux とは挙動が違うから、Coreutils の物を使いたい
ls などが PowerShell 上で実行でいるものの実態は PowerShell コマンドの Alias
Get-Alias ls とかすると、実態は Get-ChildItem なのである
code:ps1
Get-ALias ls
CommandType Name Version Source
----------- ---- ------- ------
Alias ls -> Get-ChildItem
を参考に。
Rust で書かれたプラットフォーム非依存の uutils/coreutils がある
scoop install uutils-coreutils
uutils ls -alh
俺が求めていた ls はこれだ!
uutils のコマンドを全部 alias しちゃおう。
適当に生成するぞ。
code:ruby
# Force でセットしてある alias。上書きすると不味そうなのでこれらは alias を上書きしない
ignore_commands = %w(sleep tee sort)
commands = %w(
arch, base32, base64, basename, cat, cksum, comm, cp, cut, date, df, dircolors, dirname,
echo, env, expand, expr, factor, false, fmt, fold, hashsum, head, hostname, join, link, ln,
ls, md5sum, mkdir, mktemp, more, mv, nl, nproc, od, paste, printenv, printf, ptx, pwd,
readlink, realpath, relpath, rm, rmdir, seq, sha1sum, sha224sum, sha256sum, sha3-224sum,
sha3-256sum, sha3-384sum, sha3-512sum, sha384sum, sha3sum, sha512sum, shake128sum,
shake256sum, shred, shuf, sleep, sort, split, sum, sync, tac, tail, tee, test, touch, tr,
true, truncate, tsort, unexpand, uniq, wc, whoami, yes
).map {|s| s.sub(',', '') }
commands.each do |cmd|
unless ignore_commands.include?(cmd)
puts "if (Test-Path alias:#{cmd}) { Remove-Item alias:#{cmd} }"
end
end
user_profile.ps1 に↑のを入れると量が多くなるので、同じディレクトリに uutils-alias.ps1 作る
user_profile.ps1 からは、それを . で import し読み込ませる
code:ps1
. $env:USERPROFILE\scoop\apps\cmder\current\config\uutils-alias.ps1
やったー Coreutils のコマンド群が使い慣れたものになったぞ!
gow というものもあるらしい
Gow - The lightweight alternative to Cygwin
windows 環境で coreutils / GNU find 等々を使えるようになるもの
Cygwin 懐かしい…
$ scoop install gow
coreutils に入っていない、例えば awk などを使いたくなったので
他にも便利なものを入れる
find の代替
fd で(Rust製)
scoop install fd
オプションが find とは結構異なるので find の alias にはしない
grep の代替
ripgrep で(Rust製)
$ scoop install ripgrep
$ Set-Alias grep rg
Linux/Mac では ag (The Silver Searcher) 使っていたけど、ag と同じで rg foobar とか雑に高速検索できるの良いな。
引数を伴わない場合、 function での定義ではなく、Set-Alias の alias で問題ないぽい
コマンドの代替、Rust や Go で書かれたプラットフォーム非依存のいい感じのツールを見つけることができる、良い世の中だ。
Node.js の実行環境の管理に nvs を入れる
Node.js のインストール~バージョン切り替えには、最近はどのプラットフォームでも動く nvs (Node Version Switcher) を使っている。
$ scoop install nvs
$ nvs add lts # 今なら Node v12
$ nvs link lts # 標準の node コマンドには LTS を使う
nvs はもちろん .node-version での、ディレクトリごとの node 切り替えなどにも対応してる
$ nvs auto on
これで cd したら、PS 上でも自動でディレクトリの .node-version に応じてバージョンが切り替わる
が、素のPSだとうまく auto で切り替わるが、cmder から立ち上げてるPSだとうまく行かないな…
$ npm install -g yarn
いくつかのプロジェクトで使ってみてた感じ、問題なく動いてる
expo 使った React-Native 開発もいける
ただ、手元プロジェクトのいくつかのソフトウェアテストの実行速度(CPUコア分の、並列12プロセス実行)は、WSL2 上の node に比べ Windows の node では、Windows の node のほうが7割ぐらいの速度しか出ない
サンプルが偏ってる可能性も
あれ、こんなに遅かったっけ?という時がある
npm i / yarn install がやたら遅いぞ…
Java (OpenJDK) を入れる
$ scoop bucket add java
$ scoop install openjdk9 openjdk14
入れてないけど oracle の jdk もあるみたい
切り替えは scoop reset でやるらしい
s$ coop which java
openjdk14 を指す
$ scoop reset openjdk9
$ scoop which java
openjdk9 の java を指す
scoop reset での java 切り替え、結構時間がかかったので、jenv 使ったほうが良い気もする
jenv は Windows 版は現在ないのか…
→その後、マシン再起動後に scoop reset で切り替えたら4秒ぐらい。これぐらいなら実用的な切替速度だ。
Ruby と Rubygems
rbenv も rvm も Windows では使えない…?
とりあえず scoop の bucket versions の仕組みを使って ruby のバージョンを切り替えてみる
$ scoop bucket add versions
$ scoop search ruby
ruby19,24,25,26 と ruby (2.7 = 今の最新) が表示されるように
$ scoop install ruby24 ruby
$ scoop reset ruby24 # 2.4
$ scoop reset ruby # 2.7
やっぱり scope reset での切り替えは、結構時間がかかるなぁ。symlink (junction) に時間がかかるのか、環境変数周りで時間がかかるのか、他の原因なのか。
Rails を入れるよ
$ gem install rails
$ rails new ~/tmp/rails-project
rails コマンドがない!(path が通っている場所に置かれていない)
$ scoop shich rails
で表示されない
ridk install で RubyInstaller2 経由で MSYS2 をインストールしろ、のことなので実行する
MSYS2 と、MSYS2 and MINGW development toolchain (buildに必要) を入れる
もう一度 gem install rails
$ scoop which rails
C:\Users\hotch\scoop\apps\ruby\current\gems\bin\rails.bat
今度はちゃんとパスが通ってそうなところに入ってる
$ rails new ~/tmp/rails-project
$ bundle exec rails s # -> 立ち上がってる
Android-SDK を入れる
$ scoop search android
すると、extras な bucket にあるようだ
$ scoop bucket add extras
$ scoop install android-sdk
adb 等々使えるようになった。
android-sdk 自体は ~/scoop/apps/android-sdk に入っている
$env:ANDROID_HOME もセットされた
等、環境変数のセットも行ってくれるみたい。便利だ。
Android-Studio を入れる
$ scoop install android-studio
この辺のいい感じにインストーラーがあるものは scoop から入れなくて良いかもしれない。
というか、Android-Studio は scoop でない、普通のインストーラー経由で入れていたので、ANDROID_HOME の path が別々の SDK を指したりしてややこしくなってきたので、scoop の方を消す。
$ scoop uninstall android-sdk
$ scoop uninstall android-studio
消しやすいのも良い。
Docker を使う
Windows (ホストOS)でも、 WSL2 でも同じ Docker を使えて便利
試しに mysql 動かす
$ docker pull mysql:latest
$ docker run --name mysql-test -e MYSQL_ROOT_PASSWORD=test-password -d -p 3306:3306 mysql
こいつに Windows の mysql.exe から接続してみる
$ scoot install mysql
今回は mysqld.exe は使わないので、サービス関係の設定はしない
$ mysql -uroot -ptest-password
接続できた
docker stop する
せっかくなんで fzf で ps -q のリスト出して選択して stop できるかどうかを試す
$ docker stop $(docker ps -q | fzf)
おお、普通にインタラクティブに選択して stop できた、やるじゃん PowerShell
$() でちゃんと展開できるのね。
code:ps1
❯ cd $(dirname $(scoop which docker))
❯ pwd
C:\Program Files\Docker\Docker\resources\bin
PS 上での glob が、思った挙動にならない( Linxu のシェル上とは異なる) ことがあることに気づく
PS での実行結果。python, ruby は scoop で入れた最新版、node は nvs で設定してる LTS (Node v12)
code:python
python -c "import sys; print(sys.argv)" *
code:node
node -e 'console.log(process.argv)' *
[
'C:\\Users\\hotch\\scoop\\apps\\nvs\\current\\nodejs\\default\\node.exe',
'*'
]
code:ruby
ruby -e 'p ARGV' *
["3D Objects", "ansel", "AppData", "Application Data", ... (略)
ruby のみが思った感じに glob 展開されて、node, python 共に glob が展開されていない
node の process.argv では glob が展開されておらず、'*' が渡ってきている、なるほど…
node の cli で実装されたライブラリのコードでは、windows なら * を node 側の glob ライブラリでパースしてる実装が書いてあって、そのため違和感なく glob が展開されている(ように使える)ものもあるようだ。
このへんで PS に慣れてきたので、cmder から Windows Terminal に乗り換えてみる
Ctrl-, で vscode が開いて JSON の編集で設定をいじれる。
JSON Scheme に対応してる(設定の上部に定義されてる)、key の補完や値のヒントが表示されて便利だ
MSオフィシャルの日本語ドキュメントあり
外観設定は色んな人が書いてあるので省く。
Font を Powerline 対応のものにする、ほかは好みで。
PS は cmder と使っているものと同等の設定にしたい。
code:json
"list": [
{
"guid": "{574e775e-4f2a-5b96-ac1e-a2962a402336}",
"hidden": false,
"name": "pwsh",
"commandline": "pwsh -ExecutionPolicy Bypass -NoLogo -NoProfile -NoExit -Command \"Invoke-Expression 'Import-Module ''%ConEmuDir%\\..\\profile.ps1'''\"",
"source": "Windows.Terminal.PowershellCore"
},
commandline の設定で、引数を指定できる
Import-Module で cmder で使っている profile.ps1 を指定することで、好きなプロファイルを読み込める、なるほど。
keybind の設定
Win の paste で使う ctrl+v は vim と思いっきりコンフリクトするので alt+v にする
copy も alt+c にしちゃう
tmux ではタブ関連を C-t なにかのキー]なのでそうしたいが、そういうキー定義はできないぽい
ので、altと組み合わせて大体のキーを定義してしまう。
あとで困ったら考えよう。
これで alt+t,n,p,数字 でいい感じでタブ移動できるようになった
code:json
"keybindings": [
{ "command": "nextTab", "keys": "alt+n" },
{ "command": "find", "keys": "alt+f" },
{ "command": "closeTab", "keys": "alt+w" },
{ "command": "newTab" "keybindings": [ "keys": "alt+t" },
{ "command": { "action": "copy", "singleLine": false }, "keys": "alt+c" },
{ "command": "paste", "keys": "alt+v" },
{ "command": { "action": "switchToTab", "index": 0 }, "keys": "alt+1" },
{ "command": { "action": "switchToTab", "index": 1 }, "keys": "alt+2" },
{ "command": { "action": "switchToTab", "index": 2 }, "keys": "alt+3" },
{ "command": { "action": "switchToTab", "index": 3 }, "keys": "alt+4" },
{ "command": { "action": "switchToTab", "index": 4 }, "keys": "alt+5" },
{ "command": { "action": "switchToTab", "index": 5 }, "keys": "alt+6" },
{ "command": { "action": "switchToTab", "index": 6 }, "keys": "alt+7" },
{ "command": { "action": "switchToTab", "index": 7 }, "keys": "alt+8" },
{ "command": { "action": "switchToTab", "index": 8 }, "keys": "alt+9" },
{ "command": "find", "keys": "alt+f" }
]
ペイン分割系は tmux でも使ってなかったので設定しない
Windows Terminal 以外にもいろんな Terminal あった
いろいろまとまっている
けど、今は Windows Terminal あるし、長いものに巻かれてみる
/dev/null 的なもの
PS で /dev/null 的なのは $null らしい
$ echo 'a' > $null
$ ruby -e "STDERR.puts 'error'" 2>&1 > $null
想定した感じで動くじゃん、と思いきや変な挙動に気づく
code:ps1
❯ ruby -e "STDERR.puts 'error'"
error
❯ echo $?
True
❯ ruby -e "STDERR.puts 'error'" 2>&1 > $null
❯ echo $?
False
なんで標準エラー出力に流したときはステータスが成功で、標準エラー出力を $null にリダイレクトで流したときは $? が失敗なんだ???
$? でなくて $LastExitCode をチェックすべし、とのことらしい
これはPSのスクリプト書いてるとハマりそう
cd のヒストリーに fzf で移動したい
そろそろディレクトリ移動が増えてきたので cd の訪れたディレクトリのヒストリーに fzf でインタラクティブに選択しながら移動したいのじゃよ
PS 版の z があるらしい
$ Install-Module ZLocation -Scope CurrentUser
user_profile.ps1 に Import-Module を追加
Import-Module ZLocation
なお、oh-my-posh のあとに追加する
これで cd したら ZLocation のヒストリーに貯まるように
z コマンドで見れる
$ z | awk '{ print $2} ' | fzf | cd
思った感じに fzf で以前訪れたディレクトリに移動できるようになった
gf のように C-; で立ち上がるようにキーバインドに追加しておく
code:ps1
function zfzf {
z | awk '{ print $2} ' | fzf | cd
}
$shortcut_zfzf = @{
Key = 'Ctrl+;'
ScriptBlock = {
zfzf
}
}
Set-PSReadLineKeyHandler @shortcut_zfzf
これで C-; でディレクトリヒストリー検索 & 移動ができるようになったぞ!
PowerShell の設定(user_profile.ps1)のバックアップ・他のWindowsでも共有したい
いままで $env:USERPROFILE\scoop\apps\cmder\current\config\user_profile.ps1に設定を書いてきたけど、2点問題がある
1. pwsh.exe ごとに引数で指定する必要がある。 例えば vscode がつかう pwsh.exe にも、適切な引数を与えてやらなくてはならない
2. 設定を他のマシンでも使えるように同期したい
git や Dropbox で設定ファイルを管理したい、ちなみに自分は勝手に同期される Dropbox 派
Windows なら OneDrive があるから、今回は OneDrive で共有してみる
~/OneDrive/development/powershell/user_profile.ps1 へと移動
こいつを読み込むようにする
$ Add-Content -Value "rn. $env:USERPROFILE\OneDrive\development\powershell\user_profile.ps1rn" -Encoding utf8 -Path $Profile.CurrentUserCurrentHost
で、どの PS (pwsh.exe) も起動時に $env:USERPROFILE\Dropbox\development\powershell\user_profile.ps1 を読み込むようになった。
ので、以前セットした、pwsh.exe の起動時の引数から user_profile.ps1 を読む系のオプションは取り除いた。
なお $Profile.CurrentUserCurrentHost の実態は
$ echo $Profile.CurrentUserCurrentHost
C:\Users\hotch\OneDrive\Documents\PowerShell\Microsoft.PowerShell_profile.ps1
編集するときは
$ code $Profile.CurrentUserCurrentHost
設定を反映したいときは
$ . $Profile.CurrentUserCurrentHost
でできる。$Profile は $profile でも $PROfile でも良いらしい。ignorecase なのか。
参考になる++
これでやりたいことができる感じになった
いい感じの ls を探す旅
uutilsのlsがwindowsだと --color が使えない
コードを見ると unix のみな実装ぽい?
ls に --color をつけないと、こんなにファイルの視認性が悪くなるのかと驚く
gow の ls.exe を使ってみる
→日本語文字化け解消せず
ruby を使うために入れた、msys64 付属の ls.exe が PS 上でも使え、一番表示がきちんとしている
ただ、env:LANG の設定が必要
uutils の ls の function を消して、msys の ls.exe があれば、それを使うようにした
code:ps1
$env:LANG = 'ja_JP.UTF-8'
if (Test-Path alias:ls) { Remove-Item alias:ls }
if (Test-Path "C:\msys64\usr\bin\ls.exe") {
if (Test-Path function:ls) { Remove-Item function:ls }
function ls() { C:\msys64\usr\bin\ls.exe --color $args }
}
いい感じになった (PowerShell の画面です)
https://gyazo.com/9f19bf6293b407ba5d5a02844df62cc5
git で clone したレポジトリの symlink がうまく動いていない
Windows では通常ユーザは標準だと symlink が作れないらしい
$ uutils ln -s a b
↑権限がなくてエラーとなる
の通りで、一つは core.symlinks=true オプションを付ける
code:.gitconfig
symlinks = true
もう一つは、ユーザに symlink 作成の権限を付ける
$ gpedit.msc
でシンボリックリンク作成の権限を、開発者ユーザに許可する
ここでWIndowsには「開発者モード」がある、ということに気づく
マジカ、コレ有効ならグループポリシーで開発者ユーザにする必要ない、と気づく
ただ、symlink を作りたいだけで、他の影響範囲がわからない開発者モードをオンにするより、一部だけ開放したほうが安全だなぁ。
git clone で symlink を含むレポジトリを落とす
一旦ログアウト&ログインをする。
$ uutils ln -s a b
こんどはうまく symlink が作成できた
こちらも問題なく symlink が機能してる
oh-my-posh ってなにやってるの?
雰囲気で使ってる
PS の見た目がそれっぽくなるなぁ、で使ってた
素の PS と比較する
$ pwsh -NoProfile
で、Profile (profile.ps1 とか) を読み込まずに起動する
tab で引数補完候補が出る
oh-my-posh の場合
code:ps1
Path Depth File ErrorAction OutVariable
LiteralPath Force Hidden WarningAction OutBuffer
Filter Name ReadOnly InformationAction PipelineVariable
Include Attributes System ErrorVariable
Exclude FollowSymlink Verbose WarningVariable
Recurse Directory Debug InformationVariable
OutVariable ov OutBuffer ob
bash の autocomplete ぽい動き
素の場合
code:ps1
Get-ChildItem -Path
一番最初にマッチしたのが補完される
PS のヘルプ引数 -? から表示されるものから補完するっぽい
なので、PowerShell ではないもの ( coreutils コマンドだったり ripgrep だったり) はいい感じの補完がされずファイルベースの補完となる
oh-my-posh のソースコードを読んで見る
VSCode + Powershell Ext 使ってると、補完だったり参照だったりサクサク見れるね
読むとほとんどテーマ関係のことしかしてない
マシン名、VCS(git)関係の情報取得、現在のパスの取得、等々を helper 関数で実装して、それを Set-Prompt で呼び出す
Theme 関係作成のための実装
あれ、tab での補完はどうやってるんだ?
oh-my-posh は tab 補完とは関係ない
PSReadline の Tab キーの割当によって、bash ぽい AutoComplete に変更できる
$ Get-PSReadLineKeyHandler -Key Tab
が素PSだと TabCompleteNext
bash ぽい補完してると Complete
に割り当てられてる
どこで Set-PSReadlineKeyHandler -Key Tab -Function Complete を実行してるんだろう
$Profile.* なファイルには書かれていない
自分でも書いていない
うーん、謎。
あ、分かった。
$ Set-PSReadLineOption -EditMode Emacs
の設定だ。EditMode が Emacs だと Tab キーを Complete に変更してる。
結局の所、oh-my-posh は今の所、「外観の変更(Set-Prompt の変更)」のみをしてくれるぽい。
PS-Readline の Tab 補完ってなにがあるの
実装されてる関数は、Complete, MenuComplete, TabCompleteNext, TabCompletePrevious のようだ
MenuComplete も試してみた
$ Set-PSReadLineKeyHandler -Key Tab -Function MenuComplete
うーん、Complete のほうが好きな挙動だな
PSFzf
おー。fzf の PS helper 集だ
$ Install-Module PSFzf -Scope CurrentUser
これで Invoke-Fuzzy* が使えるようになった
Invoke-FuzzyZLocation, Invoke FuzzyKillProcess あたり便利そう
起動ショートカット
Ctrl-t, Alt-c が上書きされる、って書いてあるけどされない
自分で Import-Module すると使えるけど、Alt-c は paste に使ってるから上書きされたくないから Import しなくていいや
alias
Enable-PsFzfAliases を呼び出さないと定義されない気がする
WindowsTerminal.exe で Ctrl-C すると一部プロセスが Terminal ごと終了する
結構辛い。なんだろう
長い時間起動してるプロセスだとそういうことがおきるっぽい
以下を WindowsTerminal の設定で pwsh を起動するようにして解決。
code:json
{
"guid": "{574e775e-4f2a-5b96-ac1e-a2962a402336}",
"hidden": false,
"name": "pwsh",
// Ctrl-C で端末が終了することがあるので
// source をコメントアウトして、commandline をフルパスで記述
// "source": "Windows.Terminal.PowershellCore"
"commandline": "%USERPROFILE%\\scoop\\apps\\pwsh\\current\\pwsh.exe",
"startingDirectory": "%USERPROFILE%"
},