clip.exeで日本語をコピーすると文字化けするようになった
状況
今日(2023-03-12)terminalを使ったら、clip.exeでコピーした日本語が文字化けするようになってしまった https://gyazo.com/2b5bf23b089b2146c450feb88d4ec9ac
正常だった他の日本語コメントも巻き込んでしまう
原因 (根本ではない)
ならなぜ今まで文字化けしなかったのか……takker.icon
| clip.exeでファイルの中身をコピーしても、少しも文字化けしなかった
今確認したら、文字化けするようになってしまっていた
takker.iconのシステムが、昨日から突然echoもneovimもShift JISではなくUTF-8を使うようになったとか?
そんなことある?
しかもそれだと今までShift JISメインでシステムが動いていたということになるが、ますますあり得ない
neovimがこれをUTF-8と認識してしまうため、文字化けを起こしていた
解決策
方針
標準入力をShift JISに変換してから渡す
iconvでもよかったかも。install不要なので #22ではコピーコマンドを別のファイルにwrapして呼び出していた sh -cで直接コマンドを書きたかったが、なぜかclipboard: error: -sc: 1: Syntax error: Unterminated quoted stringが出てしまうため断念した これの原因が空白区切りだとわかったので、手動で空白の区切り方を設定できるリスト渡しに変更した
code:clip-fix.vim
if system('uname -a | grep microsoft') != ''
let g:clipboard = {
\ 'name': 'WslClipboard',
\ 'copy': {
\ },
\ 'paste': {
\ '+': 'powershell.exe -c Console::OutputEncoding = Text.Encoding::UTF8;Console::Out.Write($(Get-Clipboard -Raw).tostring().replace("\`r", "")', \ '*': 'powershell.exe -c Console::OutputEncoding = Text.Encoding::UTF8;Console::Out.Write($(Get-Clipboard -Raw).tostring().replace("\`r", "")', \ },
\ 'cache_enabled': 0,
\ }
endif
懸念
Shift JISのファイルを編集しようとしたとき、逆の問題が起こりそうだ
貼り付け時にUTF-8をShift JISと解釈してしまう
わかっていないこと
突然文字コード変換が必要になった理由
根本原因がわからないのが怖いtakker.icon
2023-09-14 07:59:44 WSL2のupdateが原因のようだ 状況整理
↓が文字化けする
$ echo "日本語" | clip.exe
https://gyazo.com/54235ae9c143d8f4303c9807e2e807bd
対処
✅SJISに変換してから渡す
https://gyazo.com/e31641f6a2e81bc0f63819ff03d5e960
これを出力したときには気づいていなかったが、コピーした文字列はShift JISになっている
from
単一sessionでしか有効にならないみたい
https://gyazo.com/9ebbd7064e164086ec85ad8e7bd65220
powershell.exe -c "$OutputEncoding = [Text.Encoding]::Default;Read-Host | clip.exe"ならどうだろう?
意味なかった
https://gyazo.com/848681c69039e019efef2095ad49c45f
echo "日本語" | powershell.exe -c "[Console]::InputEncoding = [Text.Encoding]::UTF8;\$OutputEncoding = [Text.Encoding]::Default;Read-Host | clip.exe"でなんとかなるか試してみたが、微妙に壊れた文字になってしまう
https://gyazo.com/d10539f173f751e33ad733c02fe07eef
2023-03-13 10:51:33 今調べたら、Read-Host | Set-Clipboardではまったくコピペできていなかった
昨日はたまたまclipboardに似たような文字列が入ってたせいで、実行できたと勘違いしていただけだった
copy
paste
powershell.exe -c [Console]::Out.Write($(Get-Clipboard -Raw).tostring().replace("\`r", ""))を実行すると、Shift JISで出力されてしまう
neovimだとこれが解釈できずに文字化けを起こす
fish shell上だと自動で文字コードを判別してくれるせいか、文字化けせず表示される
多分この親切な挙動のせいで、文字コードが変わっているかどうかわからず混乱した面が少なからずあったと思うtakker.icon
この機能はmanで初めて知った
先にmanを読むべきだったかな
powershell.exe -c "Get-Clipboard" | nkf -gもShift JISと判定された
コピー方法はclip.exeでもwindows上でのコピーでもSet-Clipboardでも同じ
neovim内で'+': 'sh copy.sh'にしてコピーした日本語まじりのテキストをスクボやメモ帳に貼り付けたら、文字化けしてなかった
つまりコピーではなく、貼り付け処理の問題だということ
$ powershell.exe -c Console::OutputEncoding = Text.Encoding::UTF8;Console::Out.Write($(Get-Clipboard -Raw).tostring().replace("\`r", "") これで解決
解決策
sh copy.shでコピー
powershell.exe -c [Console]::OutputEncoding = [Text.Encoding]::UTF8;[Console]::Out.Write($(Get-Clipboard -Raw).tostring().replace("\`r", "")で貼り付ける
確認事項
neovim内での日本語まじりの(複数)行のコピペ
yとdとpを使った
いくつかの異なる文字列で試した
windowsのメモ帳とneovim間でコピペ
以下、調査時の混乱を含むメモ
調査
WSL2経由でclip.exeをつかっているのが原因だろうか?
15:20:37 外部から貼り付けしたときも文字化けしてた。原因はこれだけじゃない
code:log
$OutputEncoding
IsSingleByte : True
BodyName : us-ascii
EncodingName : US-ASCII
HeaderName : us-ascii
WebName : us-ascii
WindowsCodePage : 1252
IsBrowserDisplay : False
IsBrowserSave : False
IsMailNewsDisplay : True
IsMailNewsSave : True
EncoderFallback : System.Text.EncoderReplacementFallback
DecoderFallback : System.Text.DecoderReplacementFallback
IsReadOnly : True
CodePage : 20127
わからないこと
対策
powershellの設定を変えても変化なし
どうすりゃええねんtakker.icon
この現象が起きた理由
なんにもしてないはずだが……takker.icon
sudo apt upgradeで何らかのアプリの設定が変わったとか?
対策
❌
コマンド上は変換に成功した
vimの設定でパイプを使う方法がわからない
code:vim
if system('uname -a | grep microsoft') != ''
let g:clipboard = {
\ 'name': 'WslClipboard',
\ 'copy': {
\ '+': 'nkf -sc | clip.exe',
\ '*': 'nkf -sc | clip.exe',
\ },
\ 'paste': {
\ '+': 'powershell.exe -c Console::Out.Write($(Get-Clipboard -Raw).tostring().replace("`r", ""))', \ '*': 'powershell.exe -c Console::Out.Write($(Get-Clipboard -Raw).tostring().replace("`r", ""))', \ },
\ 'cache_enabled': 0,
\ }
endif
配列を指定すればいいだけっぽい?
教えてもらった情報から、次の変更を施したらコピーできるようになった
code:diff
- \ '+': 'clip.exe',
- \ '*': 'clip.exe',
+ \ '+': 'powershell.exe -c Read-Host | Set-Clipboard',
+ \ '*': 'powershell.exe -c Read-Host | Set-Clipboard',
欠点
漢字が文字化けする
まだ文字コードがおかしいみたい
https://gyazo.com/d535f6c853c719e98191ebafb680b7de
遅い
改行がコピーされない
$ powershell.exe -c "Set-Clipboard(\"てすと`n てsつp\");Console::Out.Write(\$(Get-Clipboard -Raw).tostring())" https://gyazo.com/86d792501865445d78f8c69afec86985
$ cmd.exe /C "set /p inputText= && echo %inputText% | clip"
結果
警告で止まってしまい、コピーできない
shell上ではコピーはできている
https://gyazo.com/94f2884a2cfe178e632f872d800dbf70
警告の中身
code:err
'\\wsl.localhost\Ubuntu\home\takker\git\dotfiles\nvim\userautoload\init'
上記の現在のディレクトリで CMD.EXE を開始しました。
UNC パスはサポートされません。Windows ディレクトリを既定で使用します。
対策を考える
警告を抑制する
微妙に関係なさそう
消し方は不明
警告の原因を消す
https://gyazo.com/0f2750aa52c0bb0868f418b9e159bff6
関係ないかも
WSLの文字コード周りがあやしいかも
一番関係ありそう
https://code2svg.vercel.app/svg/L37-49/https://raw.githubusercontent.com/neovim/neovim/v0.8.3/runtime/autoload/provider/clipboard.vim#.svg https://github.com/neovim/neovim/blob/v0.8.3/runtime/autoload/provider/clipboard.vim#L37-L49
渡せない理由は書かれていない
References
お世話になりすぎて頭が上がらないtakker.icon*3
/nishio/nishio.iconさん
頭を冷やすよう促された(雑解釈)
ありがとうございますtakker.icon
referencesではないけどまあいいや