やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

日付テキストを貼り付けるホットキーを作る(zenity, xsel, xdotool, date + OpenBox)

 書式を選択するUI付き。シェルスクリプトで実装した。

手順

  1. 計画
  2. インストール
  3. スクリプト作成
  4. OpenBoxホットキー設定
  5. 使ってみる

1. 計画

 ホットキーで日付テキストを貼り付ける。

HotKey キーの覚え方
Ctrl+M, D Macro.Date

 クリップボードを介してテキストエディタなどのUIに日付テキストを貼り付ける。

f:id:ytyaru:20190314201114p:plain

f:id:ytyaru:20190314201126p:plain

 日付の書式は色々あるのでUIで選択できるようにしたい。

 使用するコマンドは以下。

  • zenity
  • xsel
  • xdotool
  • date

2. インストール

sudo apt install -y xsel
sudo apt install -y xdotool
sudo apt install -y zenity

 zenityは標準で入っている。他はインストールする必要がある。

3. スクリプト作成

${HOME}/root/sys/workflow/script/sh/runnable/called/openbox/paste_date.sh

#!/bin/bash
Run() {
    # 現在のクリップボードをセカンダリに退避する
    xsel -bo | xsel -si

 . "${HOME}/root/sys/workflow/script/sh/definalble/datetime/define.sh"
    local Now=$(date "+%s")
    local Text=$(zenity --list --hide-header --multiple --separator "\n" --height 250 --title "日付テキストのコピー" --text "コピーしたい書式を選んでください。" --column "日付" \
     "$(date "${DateFormats["Now"]}" -d "@${Now}")" \
     "$(date "${DateFormats["ISO8601"]}" -d "@${Now}")" \
     "$(date -u "${DateFormats["ISO8601_UTC"]}" -d "@${Now}")" \
     "$(date "${DateFormats["TimeStamp"]}")" \
     "$(date "${DateFormats["Japanese"]}" -d "@${Now}")" \
     "$(date "${DateFormats["Wareki"]}" -d "@${Now}")")
    # 日付テキストをプライマリとクリップボードに保存する
    echo "$Text" | xsel -pi
    echo "$Text" | xsel -bi
    # Ctrl+Vキーイベントでクリップボードをペーストする
    xdotool key ctrl+v

    # 退避したクリップボードを復元する
    xsel -so | xsel -bi
}
Run

 もしCtrl+Vでペーストできなければxsel -poで日付テキストを取り出せる。たとえばターミナルアプリlxterminalCtrl+Shift+Vでないとペーストできない。
 LinuxでもWindowsでいうWM_SETTEXTができれば良かったのに。

${HOME}/root/sys/workflow/script/sh/definalble/datetime/define.sh

#!/bin/bash
#-----------------------------------------------------------------------------
# 日付の書式を定義する。(dateコマンドで使用する)
#-----------------------------------------------------------------------------
# 日付書式の定義
declare -A DateFormats;
DateFormats=(
    ["Now"]="+%Y-%m-%d %H:%M:%S"
    ["ISO8601"]="+%Y-%m-%dT%H:%M:%S%z"
    ["ISO8601_UTC"]="+%Y-%m-%dT%H:%M:%SZ"
    ["TimeStamp"]="+%Y%m%d%H%M%S%N"
    ["Japanese"]="+%Y年%-m月%-d日(%a) %-H時%-M分%-S秒"
    ["Wareki"]="+%EY%-m月%-d日(%a) %-H時%-M分%-S秒"
)
# 日付の妥当性チェック
# $1: 日付書式
# $2: 日付文字列
Validate() {
    local OPT_UTC=""
    # 日付書式の最後が"Z"ならUTC時刻で判定する
    [ "Z" == "${1: -1}" ] && local OPT_UTC="-u"
    [ "$(date $OPT_UTC "${1}" -d "${2}" 2> /dev/null)" == "${2}" ] && echo "Valid" || echo "Invalid"
}
# 指定した日付文字列に該当する日付書式名を取得する
# $1: 日付文字列
GetFormatName() {
    for key in ${!DateFormats[@]}; do
        [ "Valid" = $(Validate "${DateFormats[$key]}" "${1}") ] && { echo "$key"; exit 0; }
    done
}

4. OpenBoxホットキー設定する

${HOME}/.config/openbox/lxde-pi-rc.xml

<openbox_config>
  ...
  <keyboard>
    ...
    <keybind key="C-m">
      <keybind key="d">
        <action name="Execute">
          <command>//home/pi/root/sys/workflow/script/sh/runnable/called/openbox/paste_date.sh</command>
        </action>
      </keybind>
    </keybind>

 上記ファイルを保存したら反映するため以下コマンドを実行する。

$ openbox --reconfigure

5. 使ってみる

  1. 任意テキストエディタを起動する
  2. 1をアクティブウインドウにしたままCtrl+M, D キーを押下する
    f:id:ytyaru:20190314201056p:plain
  3. 日付選択ダイアログが表示される
    f:id:ytyaru:20190314201106p:plain
  4. キーでフォーカス遷移し、Enterキーで決定する
    f:id:ytyaru:20190314201114p:plain
  5. 1に4で選択した日付テキストがペーストされることを確認する(成功!)
    f:id:ytyaru:20190314201126p:plain

 複数選択するときの操作に難がある。Ctrl+Aで全選択したりCtrl+Shift+Ctrl+Clickで複数選択してからEnterキーを押下してもひとつしか選択されない。TabOKボタンにフォーカスしてからEnterキー押下することで複数選択される。この挙動はzenity --list --multipleのバグか仕様と思われる。使いづらい。

対象環境

  • Raspbierry pi 3 Model B+
  • Raspbian stretch 9.0 2018-11-13
  • bash 4.4.12
    • zenity 3.28.1
    • xsel 1.2.0
    • xdotool 3.20160805.1
$ uname -a
Linux raspberrypi 4.14.98-v7+ #1200 SMP Tue Feb 12 20:27:48 GMT 2019 armv7l GNU/Linux