平衡点


2014/10/07

_ マルチバイト文字列の幅を 2 としてカウントする

ログインシェルは zsh ですが, あまりカスタマイズしていない佐々木ですこんばんは. 業務で Windows で作成されたらしき日本語の暗号化 zip ファイルを受け取ってじたばたすることが, 最近になって(ようやく?)無視できないくらい増えてきて嫌気がさしています. 外部にファイルを添付して送信する場合に暗号化した zip ファイルにして送信するって文化は誰が勧めたんでしょうね. 心底無駄なんでやめて欲しいです.

本題

zshRPROMT で今いるディレクトリを表示させています. 右端に表示させたいので

# source: sh
  # 変数の文字列計算用関数
  function count_prompt_chars (){
      print -n -P -- "$1" | sed -e $'s/\e\[[0-9;]*m//g' | wc -m | sed -e 's/ //g'
  }
  # precmd のプロンプト更新用関数
  function update_prompt (){
      ## プロンプト: 1段目左
      local ps_user="%(!,%B%F{magenta}%n%b,%n)"
      local ps_host="%m"
      [[ -n ${SSH_CONNECTION} ]] && ps_host="%F{yellow}%m%f"
      local prompt_1st_left="[$ps_user@$ps_host$chroot_info]"
      ## プロンプト: 1段目右
      local prompt_1st_right="[%F{white}%(5~,%-2~/.../%1~,%~)%f]"
      ## 1段目行の残り文字列の計算
      local left_length=$(count_prompt_chars $prompt_1st_left)
      local right_length=$(count_prompt_chars $prompt_1st_right)
      local bar_rest_length=$[ COLUMNS - left_length - right_length -1 ]
      ## 1段目に水平線を引く
      local prompt_1st_hr=${(l:${bar_rest_length}::-:)}
      ## PROMPT の設定
      # @see Zshをかわいくする.zshrcの設定
      # URL: http://qiita.com/kubosho_/items/c200680c26e509a4f41c
      # 横幅等を調整.
      local ps_status="[%j]%(?.%B%F{green}.%B%F{blue})%(?!(*'-')%b!(*;-;%)%b)%f "
      local ps_mark="%(!,%B%F{magenta}#%f%b,%%)"
      PROMPT="$prompt_1st_left$prompt_1st_hr$prompt_1st_right-"$'\n'"$ps_status$ps_mark "
      PROMPT2='|%j]> '
      SPROMPT="[%j]%B%F{red}%{$suggest%}(*'~'%)?<%b %U%r%u is correct? [n,y,a,e]:%f "
      # 右プロンプト
      RPROMPT="$ps_vcs_info"
  }
  precmd_functions+=update_prompt

なんて.

Terminal 01

ですが, zip を展開して日本語のディレクトリなんかができてしまうと...

Terminal 02

原因は wc -c なのですが, これを例えば wc -m なんてすると, 文字数のカウントは正しくなりますが, 表示自体はズレます. なので, ASCII では 1, それ以外では 2 を返すようにしたくなりました.

sed なんかでじたばたしていた訳ですが...

なるほど. 勉強になります.

というわけで

# source: sh
  function count_prompt_chars (){
      # @see https://twitter.com/satoh_fumiyasu/status/519386124020482049
      print -n -P -- "$1" | sed -e $'s/\e\[[0-9;]*m//g' | sed -e 's/[^\x01-\x7e]/aa/g' | wc -m | sed -e 's/ //g'
  }

としてみました. これで幸せ.

Terminal 03

という現実逃避ネタでした.

(追記) 早速ツッコミ頂きました.

おっしゃる通りです..._| ̄|○


連絡先など
最近の日記
  • 2024/10/09
    • 1. Mastodon でのメール通知, というか Exim4 と Apparmor
  • 2024/06/19
    • 1. WSL2 での gpg-agent, ssh-agent
  • 2024/06/18
    • 1. WSL で Windows 側のフォントを利用する
  • 2024/06/17
    • 1. WSLとWindowsの時刻同期
  • 2024/06/12
    • 1. wsl2 で systemd
    • 2. wslg の設定
一覧
2006|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|02|03|04|08|09|10|11|12|
2013|01|02|03|04|05|06|08|09|10|11|12|
2014|01|02|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|09|10|
2016|02|03|
2017|01|02|03|05|06|07|09|11|12|
2018|03|06|07|10|11|12|
2019|01|02|03|04|05|07|10|12|
2020|01|02|03|04|05|08|09|10|11|12|
2021|01|02|03|05|06|07|08|09|11|12|
2022|01|02|03|04|05|06|08|10|11|12|
2023|02|03|04|06|08|09|11|12|
2024|01|02|03|04|05|06|10|
Back to Top ▲