はじめに
$ i3-msg workspace next
で「次」のワークスペースに移動することは出来るけれども、「隣」のワークスペースに移動する方法が見つからなかったのでスクリプトを作りました。その備忘録です。
例えば、今開かれているワークスペースが['1','3','mail']
のとき、'1'
の「次」の'3'
ではなく、'1'
の「隣」の'2'
に移動するようにします。
move_ws.py --direction right
で右隣に移動、left
で左隣に移動します。--move
を指定するとフォーカスしているウィンドウごと移動します。
これをi3wmのキーバインドに設定して使っています。
スクリプト全体の流れ
def main():
args = get_args()
move = args.move
direction = args.direction
ws_list = get_wslist()
cur_ws = get_cur_ws()
new_ws = get_new_ws(cur_ws, ws_list, direction)
cmd = ''
if move:
cmd += f'i3-msg move container to workspace {new_ws} && '
cmd += f'i3-msg workspace {new_ws}'
proc = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE)
スクリプトの全体の流れは以下のとおりです。
- 0.引数の処理
- 1.ワークスペース名のリストを取得
- 2.現在のワークスペース名を取得
- 3.移動先のワークスペース名を取得
- 4.コマンドの実行
0.引数の処理
def get_args():
parser = argparse.ArgumentParser('ワークスペース移動')
parser.add_argument('-d','--direction',choices=['left','right'], required=True)
parser.add_argument('-m','--move',action='store_true')
return parser.parse_args()
argparse
でコマンドライン引数を処理します。
1.ワークスペース名のリストを取得
def get_wslist():
base_wslist = ['1', '2', '3', '4', '5', '6', '7', '8', '9']
cmd = 'i3-msg -t get_workspaces'
active_wsjson = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE).stdout
active_wslist = [d.get('name') for d in json.loads(active_wsjson)]
active_wslist = [n for n in active_wslist if not n in base_wslist]
ws_list = base_wslist + active_wslist
return ws_list
基本のワークスペース名を「1」から「9」として置きます。
現在開かれているワークスペースのjsonデータを取得し、ワークスペース名だけ取り出してリストにします。
重複したものを除外して、リストを統合します。
例えば、今開かれているワークスペースが[1','3','mail']
だとしたら、
出力結果は['1', '2', '3', '4', '5', '6', '7', '8', '9','mail']
になります。
2.現在のワークスペース名を取得
def get_cur_ws():
cmd = 'i3-msg -t get_workspaces'
active_wsjson = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE).stdout
cur_ws = [d.get('name') for d in json.loads(active_wsjson) if d.get('focused') == True][0]
return cur_ws
現在開いているワークスペースのjsonデータから、'focused'
がTrue
であるワークスペース名を取得します。
3.移動先のワークスペース名を取得
def get_new_ws(cur_ws, ws_list, direction):
ws_index = ws_list.index(cur_ws)
if direction == 'right':
ws_index += 1
else:
ws_index -= 1
if ws_index > len(ws_list)-1:
ws_index = 0
elif ws_index < 0:
ws_index = len(ws_list)-1
new_ws = ws_list[ws_index]
return new_ws
現在のワークスペースがリストの何番目なのかを取得して、その隣の位置番号を求めます。
位置番号がリストから外れた場合は、ループするように処理します。
4.コマンドの実行
cmd = ''
if move:
cmd += f'i3-msg move container to workspace {new_ws} && '
cmd += f'i3-msg workspace {new_ws}'
proc = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE)
取得した移動先のワークスペース名に移動するコマンドを実行します。
move
が指定されているときは、ウィンドウごと移動するようにします。