Post Page Advertisement [Top]

configdynamicprojecthaskellworkspacexmonad

xmonadのワークスペースをお洒落に機能向上させる

あなたのxmonadのワークスペース名はどんな感じですか?「1」とか「2」とか「3」とか?


タイリングウィンドマネージャを触り始めた頃は、 ちょっと意味がわからないけれど暗号チックで簡素な表示がカッコよく感じていたかもしれません。 しかし、巷の他人のデスクトップのスクリーンショットを見ると、 「web」とか「code」と「music」なんてものも使われているのを見つけて、「あれもいいなぁ」なんて思ったんじゃないでしょうか? ただ、自分でも実際にワークスペース名に意味のある名前を付けてみると、 その名前の通りのワークスペースで、その名前通りの作業をするというのは、凄く面倒なことで、 よっぽど几帳面な人じゃない限り、すぐにワークスペース名はお飾りになってしまうことも少なくないと思います。 そうなんです、ほんとは、全部、昔の私のことなんですが、、、、


xmonadに限らずウィンドウマネージャには大体、 バーチャルデスクトップという複数のデスクトップを管理できる機能が付随しています。 しかし、皆さん結局、このバーチャルデスクトップをどんな風に使っていますか? 上記で述べたように、xmonadでは、バーチャルデスクトップである ワークスペースに事前に好きな名前を簡単につけれるので、 やはり、なんとなく、各ワークスペース毎に何らかの意味がある ウィンドウの整理を行おうと思いつつも、いつしかぐちゃぐちゃになっているかもしれません。


しかし、そんなバーチャルデスクトップの使い方として、 xmonadのユーザーは面白い発想をした人達がいたようです。 通常、プログラム等の開発を行う場合、 IDEを使うにしても、それ以外であったとしても、 あるディレクトリにその作業が纏められ「プロジェクト」等という 名前がつけられると思います。 そこで、この一般的な、「ある仕事は、ディレクトリ単位でひとまとまりになっているという状況」を「ワークスペース」に融合させる人が現れたのです。


もう少し具体的に言えば、 通常のデスクトップ作業のあり方として、 ある開発のプロジェクトがあれば、そのためのディレクトリがあり、 その場所で、それを開発するための環境、すなわち、エディタやIDEが起動された状態にするはずです。 そして、これらは「ある1つのワークスペース」で作業されるので、 そのあるワークスペースに移動すると、これらの準備を自動で行うようにするようにしてしまうのです。


これをやりたいことの数だけ事前に準備さえしておけば、 ワークスペースを移動するだけで、やりたいことが初められるようになります。


いわば、「ワークスペース駆動形ウィンドマネージャ」でしょうか。


この発想は、ワークスペースに次の属性を持たせることで実現できます。


  • ワークスペース名
  • ディレクトリ
  • スタートアッププログラム

ここで、xmonadは、そもそもプログラムであり発想さえあれば、 自分の好きなようにカスタマイズができます。 また、ワークスペース毎にスタートアップ処理や、ディレクトリ、 レイアウトを紐付けるためのモジュールも色々と揃っていている(徐々に揃った?)ので、 それらを利用して自分で処理さえ書けば、このような発想のデスクトップ環境を作るのも全然夢では無いのですが、 一方で当然、これらの環境をつくることはxmonad初心者には敷居が高い作業となります。


だからといって、全然諦める必要はありません。 実は、めちゃめちゃ凝ったカスタマイズまで目指さないならば、 ここで紹介する「XMonad.Actions.DynamicProjects」モジュールが提供する機能を使うだけで、 比較的簡単にワークスペースの紐づけ機能が使えるようになります。


ここに、このダイナミックプロジェクトの機能を使ったxmonad.hsの例を用意してみましたので、 一度、実際に試してみませんか? この中で利用している外部プログラムは以下のものなので、挑戦して見る場合には、 事前にインストールしておいて下さい。(もし、別のターミナルを使う場合については、 XConfig l型のterminal項目だけでなく、76行目辺りのspawn関数の引数も書き換えて下さい。)


  • kitty(ターミナル)
  • chromium(ブラウザ)
  • xmobar(ステータスバー)
  • dmenu(ランチャー)
  • IPAGothic(フォント)

以下がダイナミックプロジェクトを利用したxmonad.hsの例です。 実際に、あなたのxmonad.hsと入れ替えて、ダイナミックプロジェクトを体感してみましょう。



ダイナミックプロジェクト機能を体験しよう

さて、xmonad.hsを入れ替えたら、「m + q」して、設定を更新した後、 更に、xセッションを終了し、xmonadを立ち上げ直して下さい。 ステータスバーは、xmonad.hsの中から呼び出しているので、 それ以外のものを利用した場合には起動しないようにして下さい。


始まりのワークスペース

xmonadが起動したら、xmobarへのlogHook出力、即ち、通常、ワークスペース名が表示される部分を確認して下さい。 [home]とだけ書かれているでしょうか? そのhomeがワークスペース名です。


このhomeは、特に何かの役割を割り振っているわけではなく、 単なる始まりのワークスペースとしての位置づけです。 では、「Mod + Shift + Enter」でターミナルを開いて下さい。 開いたシェルのカレントディレクトリは、特定の仕事をしないので、ホームディレクトリに設定してあります。


プロンプトでワークスペースを移動

ここで、「Mod + g」してみましょう。


Mod + g

画面の中央に「Switch or Create Project」と書かれた プロンプトが出現したはずです。実は、ダイナミックプロジェクトでは、 このプロンプトにワークスペース名を文字で入力して、ワークスペースを移動します。 プロンプトの下段には、選択可能なワークスペース名が並んでいます。 また、ココでの入力は補完が効くので、文字を全て打ち込む必要はありません。



では、プロンプトに「config」と入力して、Enterキーで決定しましょう。 ワークスペースが切り替わりましたか? xmobarのlogHook出力を確認して下さい。 ワークスペース名にconfigが追加されるとともに、 カレントワークスペースがconfigであることを示す表示になっていると思います。


home [config] : Tall : ....


ワークスペースとカレントディレクトリの紐づけを確認


このデスクトップには、何もウィンドウが無いはずなので、 「Mod + Shift + Enter」をして、ターミナルを呼び出して下さい。 ターミナルが開いたら、シェルのカレントディレクトリを確認して下さい。 あなたは今~/.configにいるはずです。 この「config」ワークスペースは、 ローカルの一般的な設定が「~/.config」以下の各ディレクトリにあるということで、 その入り口に立つための設定です。 特定の作業を想定していないので、立ち上げるプログラムは設定していませんでした。


では、次に、今開いてるシェルを使って、 あなたのホームディレクトリに、codeという名前のディレクトリがあるかどうかを確認して下さい。 もし、なければ、~/codeディレクトリを作成します。


$ mkdir ~/code


ではまた、「Mod + g」してワークスペース移動プロンプトを呼び出します。 今度は「code」と入力して、移動して下さい。


ワークスペースとスタートアッププログラムの紐づけ

今度は、ワークスペースが切り替わると同時に、 ターミナルが起動されたはずです。 その中のシェルのカレントディレクトリを確認して下さい。 ~/codeになっていますか? また、xmobarのワークスペース表示でcodeワークスペースに居ることが確認できるはずです。 この「code」ワークスペースは、例で使う仮のプロジェクトディレクトリです。 「code」ワークスペースに移動するだけで、プロジェクトディレクトリがカレントディレクトリになるとともに、 自分の好きなプログラムを立ち上げることが出来るのです。


home [code] config : Tall : ....


では、別のプロジェクトを起動してみましょう。 ワークスペースを小難しいプログラミングや仕事の為だけに活用する必要はありません。 単純に、ウェブサーフィンしたいだけでもOK!と先でも述べました。 「web」ワークスペースへ移動しましょう。 ワークスペースに移動するだけで、ブラウザが立ち上がって待ってくれています。


また、同じブラウザを使うにしても、任意のウェブサーフィンではなく、 特定の調べごとをするために特定のページ自体をワークスペースにしてしまうことも出来ます。 「applist」ワークスペースへ移動してみましょう。「web」とは別のワークスペースとして別のブラウザが待ってくれています。 これは、archlinuxユーザーならば有用なワークスペースになるかもしれません。


ワークスペース間の軽快な移動

ここまで、ワークスペースの移動はプロンプトを使っていましたが、 実は、もっと簡単に移動できます。「Mod + ←(カーソル左)」を押して下さい。 そして、「Mod + →(カーソル右)」も押してみましょう。


Mod + ←(カーソル左)

Mod + →(カーソル右)

xmobarのワークスペース表示を確認しながら、適当に、右に行ったり、左に行ったりして下さい。 どうです??簡単に移動できて、快適じゃないですか?


不必要なワークスペースを片付ける

ここで、「config」ワークスペースへ移動してください。 移動したら、開いているウィンドウをすべて終了し、デスクトップを空っぽにします。 ウィンドウに何もなくなったら、「code」ワークスペースへ移動して下さい。 そして、xmobarのワークスペース表示を確認しましょう。 そこに、「config」ワークスペースの表示が無くなっているはずです。


home applist [code] web: Tall : ....


このように、空っぽになったワークスペースは、xmobarのワークスペース欄には表示されなくなります。 表示されなくなると使えなくなるわけではなく、 ワークスペースの移動プロンプトを使えば、また、いつでも、「config」ワークスペースを利用することが出来ます。


表面上は、 「ワークスペースの作成は、Mod+gで呼び出すワークスペースの作成プロンプトで行い、 既存のワークスペース間は、Mod+左右カーソルで行き来でき、 ワークスペース内のウィンドウが全てなくなると、ワークスペースは消去される」 という風にワークスペースを扱えるようになります。


設定済みのワークスペースと任意のワークスペース

ワークスペース「config」や「code」は、そのワークスペースを開くと、 カレントディレクトリが変化しました。 また、ワークスペース「code」や「web」や「applist」では、ワークスペースを開くと、 設定してあるプログラムが起動しました。 これらは、予め、xmonad.hsの中で、定義していたものです。 以下の該当部分をみれば、詳しくはわからなくても、それっぽさが伝わると思います。



しかし実は、ワークスペースは初めから登録してあるものだけしか使えないわけではありません。 動的に好きなだけワークスペースを作ることが出来ます。 「Mod + g」で呼び出すワークスペース移動プロンプトに、 任意のワークスペース名を入力して見て下さい。 例えば、hogehogeです。または、fugafugaも作ってみましょう。 事前に登録していないワークスペースは、紐付けるディレクトリが、ホームディレクトリで、 紐付ける起動プログラムが無しとして、作成されます。 つまりは、単に何もしない普通のワークスペースとして作成されます。


一方、ただ単にワークスペースを新たに作っても、 他のワークスペースと同じで中身が無いと移動したらステータスバーの一覧から消えてしまいます。 ウロウロしていると、先に作ったhogehogefugafugaは、既に何処かへ行ってしまったかもしれません。 状況的に、空の新しいワークスペースを作るというのは、そもそも、「ワークスペース駆動形うんたらかんたら」には、馴染みません。 任意の新しいワークスペースを作るのは、実は、次の項目の時に重宝されるのです。


ウィンドウを別のワークスペースへ移動する

さて、タイリングウィンドウマネージャでは、 「ウィンドウをワークスペース間で移動する」という機能は、 わりとよく使う機能ではないでしょうか? 邪魔になった何かのウィンドウを別の場所に動かしたくなる時です。 そんなときには、移動させたいウィンドウにフォーカスを当てた状態で、 「Mod + Shift + g」を押して下さい。


Mod + Shift + g

「Send Window to Project」と書かれた、 ウィンドウ移動のプロンプトが出現します。


このプロンプトはワークスペース移動のプロンプト同じで、 2段目には、設定済みのワークスペース名が並んでおり、 また、それらの補完も効きます。 しかし、それ以外の単語を書き込むことで、 好きな名前のワークスペースを作成し、 そこへ今フォーカスしているウィンドウを送ることが出来るのです。 つまり、送り出そうとしている邪魔だと思っていたウィンドウに、 今、その場で自由にそれが入るにふさわしいワークスペースの名前を 付けてあげることが出来るのです。


ダイナミックプロジェクトの機能を組み込む

この機能が気に入ったら、早速自分のxmonad.hsに組み込みたくなると思いますので、 そのTipsを幾つかノートしておきます。 まず、ダイナミックプロジェクト機能のモジュールのページは 「XMonad.Actions.DynamicProjects」 にあります。英語が苦手でも、データ型や関数のリファレンスがあるので、なんとなく眺めて見るだけでも何かのヒントになるかもしれません。 このモジュールの機能を利用するには、基本的に以下の事を行えばOKです。


  • 関連して必要となるモジュールのインポート
  • Project型データのリストを作成
  • xmonadに渡すXConfig l型データをdynamicProjects関数で加工
  • xmonadに渡すXConfig l型データで定義するworkspaces項目をhomeだけにする
  • ワークスペース移動用のキーバインドを再定義
  • プロンプトの見栄えの定義

各項目ごとにもう少し以下で補足していきます。


関連して必要となるモジュールのインポート

例示のxmonad.hsでインポートしている部分のうち、以下の3つがこの機能で必須になります。



以下にリファレンスのリンクを示します。



Project型データのリストを作成

Project型データをProject値コンストラクタに3つの引数を渡すことで作成します。(haskellのデータに付いて全く知らない方は、「haskellのお洒落なレコード構文について」も参考にしてみて下さい) 引数は、「ワークスペース名」、「ディレクトリ」、「スタートアッププログラム」です。 このデータをリストとして纏めておき、後に述べる、dynamicProjects関数の引数にします。 まずは、該当部分のコードを見てみましょう。



例を見て分かるとおり、Project値コンストラクタに渡す1つ目と2つめの引数は文字列であり、直感的に把握できると思います。 3つめは、少しhaskellの知識が必要となります。 ココにはMaybe a型という、データに「有るのか無いのか」という属性を付加したデータ型を使うことになっています。 あまり難しく考えず、次のようにやってみて下さい。


まず、なにもプログラムを起動しない場合はNothingとだけ書きます。


ターミナルプログラムを起動させたい場合の基本は、以下のようになります。 もし、haskellに全く興味がない場合は、二重引用符の中がシェルに渡すコマンド文字列になるので、そこを書き換えるだけでOKです。


(Just $ spawn "kitty")


基本構造は、 全体を括弧で囲みJustで初めます。 spawnは、引数に渡す文字列をシェルに渡して実行させるアクションを作る関数です。 ですから、ここには、通常シェルに渡す場合のように、オプションも同時渡すことが出来ます。 (この括弧や$キーの意味が全くわからない場合は、一度、「haskellの関数をおしゃれに把握する」も見てみて下さい。) 例示のapplistワークスペースの定義では83行目でこのスタートアップ定義をしていますが、対象URLとなる文字列をwhereで別に定義して、それを変数のように結合して、コマンドライン文字列を作成しています。


複数のアプリケーションを立ち上げる場合には、次のような形になります。 haskell的に言えば、3つめの引数は、XアクションのMaybe型で、!(Maybe (X ()))です。 アクションについては、「haskellのアクションと記号演算子 >>= をおしゃれに理解しよう」 を参照するとヒントになると思います。


-- 複数アプリケーション立ち上げ例
  -- for xmonad config
  , Project   
      "xmonad" 
      "~/.xmonad"
      (Just $ do spawn "chromium https://xmonad.org/documentation.html --new-window" 
                 spawn "kitty nvim ~/.xmonad/xmonad.hs" )


つまり、do構文を用いて、アクションを複数並列に定義することが出来ます。 haskellでは、インデントに意味が有るので、コピペをする場合、その点にも注意しましょう。


-- 複数アプリケーション立ち上げの雛形
   Project   
      "hogehoge" 
      "~/hogehoge"
      (Just $ do spawn "comand1" 
                 spawn "comand2" 
                 spawn "comand3" 
                 spawn "comand4"
                 .
                 .
                 .
                 )


xmonadに渡すXConfig l型データをdynamicProjects関数で加工、及び、workspaceの定義

dynamicProjects関数は、1つ目に、Projectデータのリスト、即ちココでは、 先に定義して定義しているprojectsをとり、 2つめの引数にXConfig l型データ。即ち、通常、xmonadに渡す設定データを取ります。 そして、dynamicProjects関数は、渡されたXConfig l型データにdyanamicProject用の加工を施した 新たなXConfig l型データを作成して返してくれます。 ですから、これをxmonadの引数として与えればOKです。


ここでついでに、XConfig l型データのworkspace項目を["home"]と定義しておきます。(40行目)


さて、実は、xmonadにXConfig l型データを渡す付近は、一番、xmonad初心者を悩ませる部分です。



例示の様に、do構文が使われている場合には、 基本的にxmonadの後ろに色々あるものは、全て、dynamicProjects関数とおなじ様に、 XConfig l型データを引数にとって、加工された別のXConfig l型データを返す関数の式が並び、 それらが入れ子になっているだけです。 「haskellの関数をおしゃれに把握する」を参考に、 何が関数で何が引数なのかを整理すれば、道が見えてきます。 コピペでなく自分のxmonad.hsに組み込む際の参考にして下さい。


ワークスペース移動用のキーバインドを再定義

キーバインドの定義は、それに対応するアクションを設定するだけです。 キーバインドの事が全くわからない場合は、「xmonadでお洒落にキーのカスタマイズ」も参考にして下さい。



自分のxmonad.hsに組み込む場合、それぞれのワークスペース移動用キーバインドが既に設定されているかもしれません。 特に、デフォルトのワークスペース名が1から9くらいの数字で構成されているような場合、「xmonadでお洒落にキーのカスタマイズ」で紹介している以下のような部分が有るとおもいますが、それは消してしまって結構です。


--ワークスペース移動用のキーバーインド
[(“M-” ++ m ++ show k , windows $ f i)
  | (i,k) <- zip (XMonad.workspaces conf) ([1..5] :: [Int])
  , (f,m) <- [(W.view, “”),(W.shift, “S-”)]
]


プロンプトの見栄えの定義

先のキーバインドの定義部分の116,117行目はswitchProjectPrompt関数等を呼び出して、 移動用のプロンプトを出現させるためのアクションを作っています。 これら関数は、そのプロンプトの見栄えを定義したデータを引数としてとります。 例示では、promptAetheticであり、これは次のように定義しています。



この見栄えの設定データはXPConfig型データで、 「XMonad.Prompt」 の中に定義が有ります、デフォルトデータをレコード構文で書き換えれば自分の好きなように色やフォントを変えることは簡単に出来ますし、 このデータを2つ別々の色で作っておけば、ワークスペース移動プロンプトと、ウィンドウ移動プロンプトが色だけで簡単に見分けられるようにすることも簡単に出来ます。


落ちろ!!

どうでしょうか?ワークスペース駆動の感覚は?


実は、ワークスペースが出現したり消えたりしているのは、見た目だけの話なので、 有る条件下では挙動がおかしくなることも有ります。 また、「home」だけは、ウィンドウがあってもなくても、いつでも、表示させていたいとか、 他の機能である、スクラッチパッドと同時に使う時、NSPという特別なワークスペースの扱いについて制御したいとか、 ワークスペースの数が増えてきたら、ワークスペースの見た目の並びを変えて、移動しやすくしたいとか、 使っているうちに欲張りな欲求が増えてくるはずです。 しかしそれらの問題は、haskellマスターになれば、適当にhaskellのコードを組むことで解決されるようです。 僕もそんなふうにいつかなりたい!!


こんなに楽しいxmonadなのに、ほんとにユーザーが少なそうなのがめちゃめちゃ不満です。 ひとりでも多くの人がこの「沼」に落ちていくように、僕はxmonadノートを書き続けようと思います。


0 件のコメント:

コメントを投稿

Bottom Ad [Post Page]