xmonad
Table of Contents
css change
Chrome のローカルオーバーライド機能を使ってWebサイトのファイルをローカルのファイルに置き換える
で、CSSファイルを見ると複数の色が定義されてる。どれが *.htmlのどれに対 応してる? htmlファイルを開くと、細密充填の機械が読むだけー式。さあ どうする? そんな時は、ブラウザーのインスペクターだな。
リンク色は、#9E358F となってた。Chromeが親切だった。
a { text-decoration: none; } a[href]:link { color: #9E358F; } a[href]:visited {color: #6F5F9C; } a[href]:hover { text-decoration:underline; }
各ブラウザごとのデフォルトのスタイルシート が、最強の奴だよって指定す るのかな。
p{color:red !important;}
こんなのを設定するのかな。
hlintと言う家庭教師
前回やったサーチ・アプリを診断してもらったら、次のアドバイスをされた。 家庭教師だな。
sakae@deb:/tmp/t/app$ hlint Main.hs Main.hs:10:14-48: Suggestion: Move brackets to avoid $ Found: 1 + (foldl max 0 $ map length seld) Perhaps: 1 + foldl max 0 (map length seld) 1 hint
ちょいと悔しいので、無駄を省く算段をしたい。文字列リストの長さリストを作成。 そいつに対して最大値というか最長の長さを求める。都合2回、リストをスキャ ンしてる。えいやで、関数合成。
let mlon = 1 + foldl (max . length) 0 seld
んが、
/tmp/t/app/Main.hs:9:31-36: error: • Couldn't match type ‘Int’ with ‘[Char]’ Expected: [Char] -> [Char] Actual: [Char] -> Int • In the second argument of ‘(.)’, namely ‘length’ In the first argument of ‘foldl’, namely ‘(max . length)’ In the second argument of ‘(+)’, namely ‘foldl (max . length) 0 seld’ | 9 | let mlon = 1 + foldl (max . length) 0 seld -- longst word length + 1 | ^^^^^^
更に、mlonを参照してる後続行でもエラーとなってて、盛大な事この上ない。 やる気を削ぐ仕組みになってるんだな。
λ> :t (max . length) (max . length) :: Foldable t => t a -> Int -> Int
冷静に、合成した関数の型を確認。2引数を要求してるよ。と言う事は、合成 できないって事。やるなら、自前で関数を作れ。
let mlon = 1 + foldl (\b a -> max b $ length a) 0 seld -- longst word length + 1
関数を書く時は、foldlの型を出しておいて、単に型引数を割り当てていくの が楽だ。きっと幼稚園児でも出来るだろう。
let mlon = 1 + foldl (\b -> max b . length) 0 seld -- longst word length + 1
これは、格好つけたがりの中坊みたいだな。やり過ぎ注意。
Bug発見
上記の変更をテストしておきましょ。変更したら直にテストって誰かが吠えて いたな。鉄は熱いうちに打てってのは、とっても大事な事。
λ> :main "" "-----1----12" "---123--1234" "-12345-----a" "----aa---aaa" "--aaaa-----b" "----bb---bbb" "--bbba---abc"
ちょいと指が早合点して、文字列の入力をすっとばしてしまった。これでも答 が出てくるのね。まあ、実際のアプリでコマンドラインからNULL文字列を渡す のは難しいだろうから、隠しコマンドだな。
ひるがえって、想定外の事が起ったらどうなるか、アインシュタイン宜しく、 思考実験する。
たとえば、文字列の流さは、端末の桁数より短かいって、無意識に仮定してた。 この仮定が破られる事があったら、どうなる?
splitAt 0 xs を根底で使用してる、インチキsplitは停止しなくなるだろう。 その結果は、暴走という事になるはず。
実際に実験すると、永遠に、"" が表示された。そりゃそうだ、再帰が終了し ないからね。じゃ、これをどう防ぐ?
split :: Int -> Int -> [[Char]] -> [[Char]] split z 0 _ = [] :
システムコール宜しく、イリーガルな入力に対しては、即実行終了にしてしま うのがよさそう。更に予防的な観点から、zも同様な対策を施すのがよさそ うだ。まあ、これらが負数の場合はとかがあるけどね。
ls
本物のlsでは、端末の桁数より、長いファイル名が有った時、それをどう、扱っ ている? プチ調べてみる。勿論、調べ物はOpenBSDね。久しぶりの登 場だ。まずは、挙動確認って事で、端末の桁数を30桁に制限。
vbox$ ./a.out Makefile ls.c utf8.c a.out ls.h util.c cmp.c main.c extern.h print.c
それから、長いファイル名のものを混ぜ込み。
vbox$ ./a.out Makefile a.out abcdefghijklmnopqrstuvwxyz0123456789 cmp.c :
1ファイル/1行モードに移行した。
ソースの中心は、ls.c
/* Terminal defaults to -Cq, non-terminal defaults to -1. */ if (isatty(STDOUT_FILENO)) { f_column = f_nonprint = 1; } else { f_singlecol = 1; } termwidth = 0; if ((p = getenv("COLUMNS")) != NULL) termwidth = strtonum(p, 1, INT_MAX, NULL); if (termwidth == 0 && ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) == 0 && win.ws_col > 0) termwidth = win.ws_col; if (termwidth == 0) termwidth = 80;
端末かどうかの判定とか、桁数の導出をしてる。そして、えいやでgdb君。
#0 printcol (dp=0xcf7f7734) at print.c:172 #1 0x16fed6d8 in display (p=0x722d0580, list=0x722d0a80) at ls.c:576 #2 0x16fecb1f in traverse (argc=1, argv=0x36fea20c <ls_main.dotav>, options=25) at ls.c:397 #3 0x16fec870 in ls_main (argc=0, argv=0xcf7f78b8) at ls.c:335 #4 0x16fed7a6 in main (argc=1, argv=0xcf7f78b4) at main.c:12
コードを追跡してみると、 fts_read
で、ファイルの情報を収集。lsの各種
表示に必要な情報にdisplay()を使ってまとめあげる(ex. dp->maxlenは最大ファ
イル名長)。
compute_columns()
内で、どう表示するか決定。
colwidth = dp->maxlen; colwidth += 1; mywidth = termwidth + 1; /* no extra space for last column */ if (mywidth < 2 * colwidth) { printscol(dp); return (0); } *pnum = mywidth / colwidth; return (mywidth / *pnum); /* spread out if possible */
printscol()が使われるのは、長いファイル名が検出された場合だ。短いファ イルの時は、printcol()だ。まぎらわしい名前付けって思うのは、漢な人だか らかな。たったの1文字違いですからね。printsolocolとか、ソロを強調して ほしかったぞ。s はソロと解釈したけど、シングルとも言えるな。
ボーと生きていると、増殖する「ChatGPTもどき」にご用心 チェック・ポイ ントが注意喚起 こういうのに引っかかるぞ。今や人を集める、水飲み場ですから。 boss@company.comとboss@cornpany.comの違いをサッと見分けられるか?
void printcol(DISPLAY *); void printacol(DISPLAY *); void printlong(DISPLAY *); void printscol(DISPLAY *); void printstream(DISPLAY *);
まぎらわしい名前の一覧(って、恨みでもあるんか)。せめて print_xxx
と
かできなかったんでしょうかね? これらの関数は、高階関数として利用され
てるよ。どれを選ぶかは、膨大なオプションの組み合わせによる。
ls opt paths = traverse printfcn paths where printfcn = case opt of (-l) = printlong (-x) = printacol : _ = printcol
超いいかげんな、lsコマンドのhaskell風構造表記。lsコマンドの解説で、 本を書いてしまった人がいるからなあ。こんな絵を出すとブッ飛ばされます。
guard 戦法
上で出てきた、splitをより安全にする為に、ガード戦法を取り入れてみる。 パターンマッチ方式じゃ、ピンポイントのチェックしか出来ないからね。
ちゃんとしておけば、hoogleにも登録できる、逸品になるぞ。 まあ、system callみたいに、引数は全部チェックするという厳格さの適用だ けどね。
split :: Int -> Int -> [[Char]] -> [[Char]] split z n xs | z <= 0 = error "Must be positive" | n <= 0 = error "Uum ... negative" | xs == [] = [] | otherwise = aa : split z n ts where (hs, ts) = splitAt n xs aa = foldr (\s t -> pad z s ++ t) "" hs
最初エラーメッセージを同一にしてたんだけど、それじゃMSみたいだから、変 更してみた。ウーム、マンダムって昭和のおじさんしか知らないCMから、頂い てしまった。
xmonad
タイル型ウィンドウマネージャという新たな世界観に衝撃を受けた!XmonadをつかってワクワクCUI生活
ArchLinuxにXorgを最小限インストールしておしゃれにxmonadする
The following NEW packages will be installed: ghc libbsd-dev libffi-dev libghc-data-default-class-dev libghc-data-default-class-doc libghc-data-default-dev libghc-data-default-doc libghc-data-default-instances-containers-dev libghc-data-default-instances-dlist-dev libghc-data-default-instances-old-locale-dev libghc-dlist-dev libghc-extensible-exceptions-dev libghc-old-locale-dev libghc-old-time-dev libghc-random-dev libghc-random-doc libghc-semigroups-dev libghc-setlocale-dev libghc-utf8-string-dev libghc-utf8-string-doc libghc-x11-dev libghc-x11-doc libghc-x11-xft-dev libghc-x11-xft-doc libghc-xmonad-contrib-dev libghc-xmonad-contrib-doc libghc-xmonad-dev libghc-xmonad-doc libmd-dev xmonad 0 upgraded, 30 newly installed, 0 to remove and 0 not upgraded. Need to get 82.8 MB of archives. After this operation, 773 MB of additional disk space will be used.
ghcが新規に入るのか。混ぜるな危険を承知の上で導入する。既存のものと 交雑して、おかしな事にならない様に祈りを捧げておこう。
sakae@deb:~$ /usr/bin/ghc --version The Glorious Glasgow Haskell Compilation System, version 8.8.4 sakae@deb:~$ ghci --version The Glorious Glasgow Haskell Compilation System, version 9.2.7
とりあえず、下記の設定でstartxする。単にicewmを止めてxmonadにしただけ。
sakae@deb:~$ cat .xinitrc xrdb ~/.Xresources setxkbmap -option ctrl:swapcaps xterm -r -g 80x39 & xmonad #icewm #ctwm
icewmに比べて起動が速い。起動すると、赤枠の全面xtermが表れた。 xtermの追加は、Alt + Shift + Enter, フォーカスのあるアプリを終了させるには Alt + Shift + c、Alt + Shift + qで、xmonadを終了できる。今日は3個のキー バインドを覚えましたからね。
おっと、それだけじゃ実用にならないので、 Alt + p で、ランチャーがでてくる。Alt + number(1-9) で、仮想画面の指定 も覚えておこう。
これ以上の操作は、 ウィンドウ操作の基本 を参照だな。
sakae@deb:/usr/share/doc$ ls -d libghc* libghc-data-default-class-dev/ libghc-semigroups-dev/ libghc-data-default-class-doc/ libghc-setlocale-dev/ libghc-data-default-dev/ libghc-utf8-string-dev/ libghc-data-default-doc/ libghc-utf8-string-doc/ libghc-data-default-instances-containers-dev/ libghc-x11-dev/ libghc-data-default-instances-dlist-dev/ libghc-x11-doc/ libghc-data-default-instances-old-locale-dev/ libghc-x11-xft-dev/ libghc-dlist-dev/ libghc-x11-xft-doc/ libghc-extensible-exceptions-dev/ libghc-xmonad-contrib-dev/ libghc-old-locale-dev/ libghc-xmonad-contrib-doc/ libghc-old-time-dev/ libghc-xmonad-dev/ libghc-random-dev/ libghc-xmonad-doc/ libghc-random-doc/
ここに、肌色でリンクを表示するhtml類が集合してる、よく見ておけ。
A dynamically tiling X11 window manager that is written and configured in Haskell.
がxmondの正体なんだけど、怖くて近付けない 人は、luaで作成されたのも有るよ。
カスタマイズ
修飾キーが Altって emacsと競合するなあ。これは是非、Windowsキーに変更 したいぞ。xtermのバックグラウンド色を黒にしておきたい。どうする?
設定ファイルは、~/.xmonad/xmonad.hs とな。
Xmonad for FreeBSD 同窓会の雰囲気。キーの説明があって助かった。
import XMonad main = xmonad defaultConfig { modMask = mod4Mask -- Use Super(Win key) instead of Alt , terminal = "xterm -r" }
古いghcを使うように、一時的にPATHの先頭に/usr/binを指定。そうしておい て、Alt-q で、更新。これでいいはずなんだけど、エラーだよ。最初は、 import Xmondが見付からないなんて、とぼけた事をほざいていたけど、数度実行した。 そうしたら、 エラーログが、こんなになって、どうやら成功した。
sakae@deb:~/.xmonad$ cat xmonad.errors xmonad.hs:3:15: warning: [-Wdeprecations] In the use of ‘defaultConfig’ (imported from XMonad, but defined in XMonad.Config): Deprecated: "Use def (from Data.Default, and re-exported by XMonad and XMonad.Config) instead." | 3 | main = xmonad defaultConfig | ^^^^^^^^^^^^^
xmonad –recompile でもいいのか。文句を言われつつも、狙った機能が実現 できたから、良しとしよう。残骸は下記の様であった。
sakae@deb:~/.xmonad$ ls -l total 3300 -rw-r--r-- 1 sakae sakae 307 May 20 07:36 xmonad.errors -rw-r--r-- 1 sakae sakae 2922 May 20 07:36 xmonad.hi -rw-r--r-- 1 sakae sakae 142 May 20 07:27 xmonad.hs -rwxr-xr-x 1 sakae sakae 3355344 May 20 07:36 xmonad-i386-linux* -rw-r--r-- 1 sakae sakae 5524 May 20 07:36 xmonad.o
まて、残骸なんて失礼な事を言うな。mainが有るなら、それはアプリだ。新ら しい設定が反映された奴だ。きっと、アーなってるに違いない。
質問があります
まずは、軽く確認。
sakae@deb:~/.xmonad$ ls -l xmonad-i386-linux /usr/bin/xmonad -rwxr-xr-x 1 root root 2244896 Aug 15 2020 /usr/bin/xmonad* -rwxr-xr-x 1 sakae sakae 3355344 May 20 07:36 xmonad-i386-linux*
startxする前後で、プロセスがどうなってるか確認。冒頭の+記号は、スター ト後に生えたもの。
- 989 pts/2 R+ 0:00 ps awx + 990 tty1 S+ 0:00 /bin/sh /usr/bin/startx + 1012 tty1 S+ 0:00 xinit /home/sakae/.xinitrc -- /etc/X11/xin + 1013 tty1 Sl 0:00 /usr/lib/xorg/Xorg -nolisten tcp :0 vt1 -k + 1027 tty1 S 0:00 sh /home/sakae/.xinitrc + 1035 tty1 S 0:00 xterm -r -g 80x39 + 1036 tty1 S 0:00 /home/sakae/.xmonad/xmonad-i386-linux + 1038 pts/3 Ss+ 0:00 bash + 1043 pts/2 R+ 0:00 ps awx
手に取るようにXの起動の仕組みが見えますなあ。オイラーが startxで起動。
.xinitrcが読みこまれてXorgが動きだす。.xinitrcをシェルスクリプトとして実
行。xtermが起動してから、ウィンドウ・マネージャである
xmonad-i386-linx
が起動。xtermの中でbashが動きだして完了。
注意としては、.xinitrc中には、xmonadとしか記述してない点。こいつは、 /usr/bin/xmonadのはず。ゆえに、一度こいつが起動して、この中で、新しい 設定のxmonad-i386-linuxを見付けて、そいつに移譲してるんだな。
なんで、こんな面倒な仕組みになってる? 変更点だけを記述した設定ファイ ルを用意して、それを取り込んでもよかったはず。
それは美意識の問題だろう。オイラーがサンプルで作成したアプリはシングル バイナリーにした。理由は、余計なものはいらないって事だった。ただのテキ ストファイルだと、間違って変更しちゃう可能性がある。それに文法まちがい も予想される。一度コンパイルしたものだと、これらを払拭できる。多分そん な事では、なかろうか。
興味深いメッセージが出てきたなあ。
sakae@deb:~$ xmonad -version XMonad is recompiling and replacing itself another XMonad process because the current process is called "xmonad" but the compiled configuration should be called "xmonad-i386-linux" XMonad will use ghc to recompile, because "/home/sakae/.xmonad/build" does not exist. XMonad skipping recompile because it is not forced (e.g. via --recompile), and n either xmonad.hs nor any *.hs / *.lhs / *.hsc files in lib/ have been changed. xmonad-i386-linux: user error (unrecognized flags:["-version"])
pre check
太い括弧(ex. <a href="..">hoge</a>みたいな奴)に飽きてきたので、正統な 括弧で行きます。んで、下調べ。
sakae@deb:~$ t scheme husk-scheme husk-scheme-libs micro-recursion-schemes monadic-recursion-schemes purescheme-wai-routing-core recursion-schemes recursion-schemes-ext recursion-schemes-ix sugar-scheme sakae@deb:~$ t lisp atto-lisp clisparkline haskelisp helisp hsc3-lisp lispparser megalisp
48Hr
haskellの本家に資料があがっていた。オイラーだと、とても48時間ではおさ まらなくて、いろいろな疑問をクリアーしながら進むであろうから、72時間は かかるだろう。
NHKの名物番組にあったよな。72時間なんとかって奴で、色々な人生を見せて くれる奴が。ああ、街録なんて番組もあったな。
micro scheme
こちらは、日本人による日本人の為の貴重な資源です。つつしんで拝読いたし ます。
golang project
GoでWebAssembly――Go標準のWebAssemblyサポートを体験する
アンテナは高い程よい は、常識です。ワッチしておかないとね。 特に、プロジェクトの作成方法で、右往左往するのよ。
rust,haskell,golangぐらいを抑えておけば十分だろうけど。
いつか、比較表を作りたいな。いや、きっと既に誰かが、やっているだろう。
おっと、Juliaを忘れちゃいけないよーー(と、リンダ風、謎)。奥深い所にscheleが潜んでいるか らね。最近、 実践Julia入門 なんて本が出たみたい。