読者です 読者をやめる 読者になる 読者になる

fnwiyaBlog

EmacsとかLispとか可視化とか

youtubeをfzf/pecoでフィルタリングしながらコマンドラインで再生

コマンドラインに引きこもりたいけど音楽も聴きたかったので聴きたい曲をpecoって選べるようにしてみました。

再生用のツールをインストール

brew install youtube-dl mplayer

聴きたい曲候補を~/favoriteSongs.tsvに
一行目:検索する際のタイトル
二行目:URL
として用意します。

zshの設定(fzfの部分をpecoにしても動きます)

    function fzf-youtube () {
        local title=$(cat ~/favoriteSongs.tsv | cut -f1 | fzf)
        if [ -n "$title" ]; then
            url=$(grep ${title} ~/favoriteSongs.tsv | cut -f2)
            BUFFER="youtube-dl '${url}' -o - | mplayer - -novideo"
            zle accept-line
        fi
        zle clear-screen
    }
    zle -N fzf-youtube fzf-youtube
    bindkey '^x^v' fzf-youtube

これでC-x C-vを叩けばfzfでフィルタリングができ、
選択した曲が流れ始めます。

自分のplaylistから取ってこれたらもっと便利な気がする。

Hatena Engineer Seminar #7 @ Tokyoに行ってきた

Hatena Engineer Seminar #7 @ Tokyoに行ってきました。
はてな東京オフィスでしたが表参道近くのおしゃれな雰囲気漂う素敵なオフィスでした。

まとめとしては

  • 採用で自走できる人を採る。採用に妥協しなければあとは性善説で自由を与えれば大丈夫
  • はてなでも35歳定年説あるかも、、、という話は意外だった
  • 技術選定はコミュニティを重視する。自社のエンジニアをコミュニティに送り込めるか。情報を発信することで情報が集まってくる。
  • エンジニア->マネージャーという一方向キャリアパスだけでなく、再度マネージャー->エンジニアというジョブローテーションもいいよね。
  • 新しいポジションの仕事は自分で定義していい。
  • 個人の技術力の向上と組織の成長が結びついてることが学びのモチベーションとなる。うまくいってる感が大事
  • サービス、組織に対するオーナーシップ。指示は噛み砕きすぎずやんわり伝える。楽しくないなら楽しくしよう。

以下メモ。

はてなで一人前のエンジニアになる方法

@hakobe932
チーフエンジニア

はてなにおけるエンジニア制度

  • アプリケーションエンジニア
    • Serviceチームに所属してアプリケーションを開発
  • ウェブオペレーションエンジニア
    • Serviceを支えるインフラ =>領域はグラデーションでかぶってる
  • チーム横断の組織: 技術グループ
    • シニアエンジニア
    • チームエンジニア

キャリア

  • 専門性
  • 技術グループ
  • チーム運用・企画力=>ディレクター

kakobe932の場合

  • インターン
  • 新卒
    • 技術研修なし(今はある)
  • 2~3年目: チームを渡り歩いて修行
    • チーム移動がしやすい
    • 互いに学び合う文化: 社内勉強会
  • 4~6年目:
  • チーフエンジニア

一人前のエンジニアになれる組織

  • 学び続けられる
    • 環境
    • メンバー
  • 基礎を大事にする
    • 寿命の長い基礎技術を
    • 10年後も使える知識を。フレームワークだけでなく思想や理論
  • 技術の成果を原動力に
    • 成功体験(うまくいっている感)
    • 技術の向上が利益につながる
  • モチベーションを大事にする
    • モチベーションは有限
    • 個々人のモチベーションをみる

Q&A

  • シニアエンジニアの成長支援とは?
    • 1on1

エンジニアがはてなでマネージャーをやるということ

@Songmu
チーフエンジニア&mackerelマネージャー

これまでの経歴

  • 情報系大学で中国語->営業->SI->カヤック->はてな

    心がけていること

  • はてなは一回落ちてる
  • エンジニアのディレクター(まだ少ない)
    • ディレクターはえらかった<-偉くなりたくない。。。
    • Mackerelだから引き受けた。オーナーシップ。仕事は断らない。
  • 自戒
    • 人間は愚かである(スタンフォード監獄実験)
    • マネージャーは偉くない
    • 「マネージャーは南ちゃんだ」
  • マネージャー像
  • オーナーシップ中心マネージメント
    • ×やらされてる感
    • オープン、フラット、遊びを持たせる
    • ブレークダウンしすぎない。やんわりと伝える。
    • 属人化が課題
  • 規則だから守る=>自分から規律を作る
  • マネジャーは評価する人ではなくて成果を代わりにアピールしてくれる人
  • ディレクター<->エンジニアをローテーションしていく。仕組み化していきたい。
  • 我慢しているは自分への言い訳。どうやったら楽しくなるか。

    Q&A

  • メンバーが良くない方向に進んだらどうする?
    • 早めに方向修正する

ウェブオペレーションエンジニアになるまでの思い出

@y_uuki

ウェブオペレーションは技芸であり科学ではない

ぼくがセールスエンジニアというキャリアを選んだ理由(わけ)

@a-know http://www.slideshare.net/aknow3373/ss-69866334

結論

  • エンジニアとしてもっと成長したかった
    • まわりのエンジニア
    • 質問に答える
    • アウトプット
  • 初めてやることは自分で定義していい

パネルディスカッション

@kiyosick

組織の成長/個人の成長

  • 朝会
  • 2週間に1回会議デーがある(5時間会議)。あとは開発
  • 毎日(金曜以外)リリースする。botが教えてくれる。
    • 夜、金曜はリリースしない。定時で帰る。
  • リモートの働き方
    • テレビ会議のSystemが整備されている
    • いけるなら直接会う
    • 京都側にサブディレクターを置いた
    • 雑談大事
  • エンジニアがマネジメントってどう?
    • 35歳定年説はあるかもしれない。。。(あんまりいない)
    • ジョブローテーションをやっていきたい。
  • はてなのエンジニア文化
    • アウトプット。ブログ
    • 技術が好き
    • ランチタイムに勉強会
    • 新しい技術はなかなか導入しづらい(プロダクトの息が長い)。コミュニティが大切。
    • コミュニティに人を送り込めるか。情報を発信して情報を集める。
  • エンジニアの育て方
    • チーム開発は型があるのでそこから
    • 中途の人のギャップははじめは苦労してるっぽい。方法論よりはチームに馴染むことが大切
    • ペアプロ
    • 採用基準で担保してはてな特有の部分を教える
    • 社内の知見はドキュメントに。一般的なことは自分で調べられる人を採る。

今いるディレクトリをまるごと削除する

試しにクローンしてきたレポジトリを削除したいときなどに、
pecoなどを用いて該当のレポジトリに移動してそのまま削除したいときがあったので。

function rmself () {
    p=$(pwd)
    cd ../
    rm -rf $p
}

こちらをzshの設定に書いておけばrmselfで今いるディレクトリがごっそり消せます。

選挙啓発系団体の目的

実は学生時代選挙啓発を行う団体に所属しておりまして、
その関係で先日インタビューを受ける機会があり改めて感じることがあったのでメモ。

選挙啓発団体の存在意義は?

大事なときにみんなが話を聞いてくれるような意識のフックを作ること。
日常的にみんなが政治の話をしてるのってそれはそれで変で、
そういうのは選挙啓発団体のメンバーみたいな人たちが好きなだけやったら良いのかなと。
大切なのはいざ選挙となったときにみんなが情報を受け取れるチャネルを整備して、
情報を受け取れば考えようと思えるような状態であってもらうこと。

とりあえず選挙に行くみたいな人が増えると変な人が当選してしまうのでは?

そうなったらそうなったでいいのでは?
間違ったら次に正しい道に修正する力があるのが民主主義のはず。
自分の選んだ政治家が間違っていたと気づけば次はもっと考えて投票するようになる。(絶望して投票にいかなくなる可能性ももちろんある) 逆に今変な人が当選してないわけではない気が。。。

なんでそんな意識高いことするんですか?

根っこにあるのは自分や自分の子供のためという利己的な発想。
このままでは割りを食うのは確実でかといって自分一人ではどうにもできないので仲間を増やさないといけない。
べつにクーデターを起こしたいわけではないが、
正しいバランスを目指したい。

これからやっていきたいことは?

エンジニアと政治に関わってきた身としてその2つをうまくミックスさせていきたい。
具体的には政策の効果測定・可視化、情報へのアクセシビリティの向上など。
セキュリティ政策も急務なはずなのでまずはスキルアップ

仕事が楽しくて夢中なときだからこそ自分の価値観を再確認できたいい機会でした。 べつに二者択一ではないと思うので相乗効果で頑張っていきます。

node学園祭2016行ってきた

大きなConference系は久しぶり。
node界隈というかJS界隈は幅が広くて動きが活発でとても聴き応えがあった。
一番印象的だったので@t_wada氏のpower-assertへの依存をなくした話。
ロックインをなくしてtool化していく姿勢は本当に尊敬します。
サイボウズのKAIZENNはちょうど悩んでいたろころでぴったりだし、
気になっていたサーバサイドレンダリング、web-assemby周りも知れた、
何より最前線を走っている方々の熱量を感じられたのが良かったです。(after partyも豪華だった)

発表者・運営の方々に感謝です。
来年はLT立ちたいな。

以下メモ

Building Interactive npm Command Line Modules

@Irina Shestak

  • CLIのコマンドのオプションの意味わからなくないですか?という問題提起
  • CLIAppとは? プログラムと対話する
  • optionいっぱいよりinteractiveにするとUser friendly
  • https://github.com/yargs/yargs/ が引数の処理におすすめ
  • ↑default設定、ロングオプション、ショートオプション等の設定が楽
  • .help()でdescriptionがでる
  • catコマンド(猫の飼える数の表示)実装してみたよ(15分ぐらいでできたらしい)

Debugging Node.js Performance Issues in Production

@Thomas Watson

  • パフォーマンスモニタリング
  • 本番のパフォーマンス測定は難しい。影響を与えたくない。
  • premature optimization = 早すぎる最適化はよくない。
  • console.time('hoge'); hoge(); console.timeEnd('hone');で測定できる。
  • 遅くなる(Stop The World)原因:
    • single thread
    • CPU intensive code
    • Slow I/O
    • Event Loop saturation
    • Running out of memory
    • Garbage Collection
  • CPU Intensive Code
    • Sync I/O fs.*Sync
    • JSON parse
    • RegExp
    • Crypto
    • Templates

サイボウズの開発を支えるKAIZEN文化

@Teppei Sato http://www.slideshare.net/teppeis/kaizen-68803503

  • VP of Engineering
  • 技術的負債との戦い
    • あとで時間のあるときにやろう!=>そんな時こない
    • KAIZENN DAY(丸一日KAIZENNする日)。呼び方も変える
    • 1日で終わらない。非エンジニアの共感。割り込み業務 => 改善合宿(関係者に発表)
    • チーム横断なもの => 改善会議(スーパリセットしちゃお) http://pepabo-ceo.jugem.jp/?eid=40
  • 新規技術
  • リモートワーク
    • 採用戦略
    • QoL => ウルトラワーク(総労働時間の10%は好きなところで働いてよい制度)
    • 最初はつらさもあった(つながらない問題) => 全員がリモートワーカー。全員練習する CiscoのSystem
    • 質問責任と説明責任
    • すべての情報はオンラインに
    • 分報(ピープル)
  • 理想の共有/共感

The Seif Project

@Douglas Crockford

  • Upgrade Web => seif project
  • https://github.com/paypal/seifnode
  • https://github.com/paypal/seif-protocol
  • Full duplexなプロトコル
  • Seif resource management
  • Seif Apps
    • HTML-free Javascript-based application delivery build on NodeJS and Qt
    • Logic: Node, Display: Qtをjson-channnelでつなぐ。
  • Trust Management
  • Seif Helper App
  • Transion Plan
    • 一つのブラウザに組み込むよう説得する(Mozilla?MS?)
    • secureなサイトにユーザーにそのブラウザを使うようにしてもらう
    • penguinの原理でほかもついてくるようになる
    • 他のブラウザも対応するようになる
    • 既存のものと並行するとは思うが、新しいものはseifで作られるようになる

Why to Standardize your READMEs

@Richard Littauer

  • READMEはドキュメントより先に見る
  • npmには35万のパッケージがある

Vue.js 2.0 サーバサイドレンダリング

@Kazuya Kawaguchi https://speakerdeck.com/kazupon/vue-dot-js-2-dot-0-server-side-rendering

  • プログレッシブフレームワーク
  • コンパイル template => AST
  • VirtualDOM
    • diff算出コストがかかる => 二段階処理 = 静的なノードの検出 + 静的なノードツリーの検出
    • snabbdomベース
  • サーバーサイドレンダリング
    • レンダラ
      • renderToStream
    • ハイドレーション(水分補給)=>状態補給
    • コンテキスト
    • バンドリング
  • 参照透過性をたもったレンダリングを実装しましょう

React + Reduxを使った大規模商用サービスの開発

@Naohiro Yoshida

  • SSRしたあとはSPAとして動作pushStateをもちいたpjaxなアプリ
  • redux middleware: サーバーとクライアントの差分を吸収する
  • 失敗しないように注意するポイント
    • transition
      • onEnterではreplaceStateを使う。pushStateだめ
      • mountしてから分析ログを飛ばす
      • data fetchしてからRouterContexrのrenderをする
      • iPhone画面スワイプ問題(safariは回避策あり。chromeは無理)
    • webpack
      • 変更箇所意外のhashを変えずにブラウザキャッシュを最大限活用
      • めったに行かない画面のjsはgetComponentで動的に
    • partial renderingでもGoogle botに認識される。Fetch as Google

Introducing Now and Next.js

@nkzawa

The Evolution of Electron

@Cheng Zhao

  • Atomを作ったのがきっかけ
  • node-webkittは複数ウィンドウに対応していなかったのでforkしてatom-shellとして書き直し
  • node-webkitがまともに動かないとAtomが作れない」「じゃあ作者を雇おう」=> チェン=サンがgithubに雇われる
  • コントリビューターを惹き付けるために
    • issues, PRにはすぐに反応することが重要 -開発へのハードルを下げる

JavaScript による並列処理:共有メモリとロック

@Noritada Shimizu https://speakerdeck.com/chikoski/20161113-nodefest

  • Mozillaエヴァンジェリスト
  • メインスレッドという一つの時間軸の上で動いている
  • workerを使うとマルチスレッドが実現できる
  • メッセージ間のデータのやりとりではobjがコピーされる
  • ArrayBufferならポインタを移すだけなので効率的 => SharedArrayBifferならさらに共有可能
  • 食事する哲学者問題 => Atomics.wait
  • unityはHTMLを吐ける。
  • 1.5倍ぐらい早くなる?

WebAssemblyに欠けている大事なもの

@Yoshiki Shibukawa

  • C/C++: 言語自体はとても良くなっている
  • pkgマネージャーがない...rustはいいぞ
  • CMakeがデファクト
  • webassemblyはUIに絞っただけのほうがいいかもしれない

From Library to Tool - power-assert as a General Purpose Assertion Enhancement Tool

@Takuto Wada

  • Testing framework should evoleve slowly.
  • testコードはtestできない。書き直しは綱渡り
  • easy to write VS. easy to learn to write
  • No API is the best API
  • require('power-assert')ではなくrequire('assert')で動くようにした。power-assertに依存しない。From Library to Tool
  • assertはtestだけのためのものではない。契約プログラミングなど。unassertでproductionでもいける

How Do We Get Along With Static Types

@FUJI Goro https://speakerdeck.com/gfx/how-do-we-get-along-with-static-types

  • JSの資産を使うのが難しい
  • 型定義ファイルが無いとダメ
  • .d.tsを書けばできる。けどそれで生産性は上がってる?

RuntimeJS Playground

@Jacob Groundwater

http://runtimejs.org/ - OS等はすっ飛ばして直接ハードウェアを操作する。

haskellでバブルソート・マージソート・クイックソート

Haskellでソート3種実装してみました。
クイックソートのシンプルさが際立ちます。
これがパターンマッチの力。

バブルソート

bswap [x] = [x]
bswap (x:xs)
    | x > y     = y:x:ys
    | otherwise = x:y:ys
    where
        (y:ys) = bswap xs

bsort [] = []
bsort xs = y : bsort ys
    where
        (y:ys) = bswap xs

main = do
    print $ bsort [4, 3, 1, 5, 2, 7, 3]

マージソート

merge xs [] = xs
merge [] ys = ys
merge (x:xs) (y:ys)
    | x < y     = x : merge xs (y:ys)
    | otherwise = y : merge (x:xs) ys

msort []  = []
msort [x] = [x]
msort xs  = merge (msort (take h xs)) (msort (drop h xs))
    where
        h = (length xs) `div` 2

main = do
    print $ msort bsort [4, 3, 1, 5, 2, 7, 3]

クイックソート

qsort []     = []
qsort (n:xs) = qsort lt ++ [n] ++ qsort gteq
    where
        lt   = [x | x <- xs, x <  n]
        gteq = [x | x <- xs, x >= n]

main = do
    print $ qsort [4, 3, 1, 5, 2, 7, 3]

タイル型ウィンドウマネージャxmonad

現在ウィンドウマネージャにxmonadを使用しています。

メリットとしては

マウスによるウィンドウの操作やパネルの重なりも設定によっては可能なのでかなり柔軟性は高いです。
万人にはおすすめできませんが、
ubuntuの余計なアニメーションや装飾に嫌気が差した方などにはおすすめです。

設定ファイルはこちら

dotfiles/xmonad.hs at master · fnwiya/dotfiles · GitHub

-------------------------------------------------------------------------------
--                  __  ____  __                       _                     --
--                  \ \/ /  \/  | ___  _ __   __ _  __| |                    --
--                   \  /| |\/| |/ _ \| '_ \ / _` |/ _` |                    --
--                   /  \| |  | | (_) | | | | (_| | (_| |                    --
--                  /_/\_\_|  |_|\___/|_| |_|\__,_|\__,_|                    --
--                                                                           --
-------------------------------------------------------------------------------
-- Import modules                                                           {{{
-------------------------------------------------------------------------------

import System.IO                       -- for xmobar
import qualified Data.Map as M
import Control.Monad (liftM2)          -- myManageHookShift

import XMonad
import qualified XMonad.StackSet as W

import XMonad.Actions.CycleWS
import XMonad.Actions.FloatKeys
import XMonad.Actions.WindowGo
import qualified XMonad.Actions.FlexibleResize as Flex -- flexible resize

import XMonad.Hooks.DynamicLog         -- for xmobar
import XMonad.Hooks.EwmhDesktops
import XMonad.Hooks.ManageDocks        -- avoid xmobar area
import XMonad.Hooks.ManageHelpers

import XMonad.Layout
import XMonad.Layout.Gaps
import XMonad.Layout.NoBorders         -- In Full mode, border is no use
import XMonad.Layout.PerWorkspace      -- Configure layouts on a per-workspace
import XMonad.Layout.ResizableTile     -- Resizable Horizontal border
import XMonad.Layout.Simplest
import XMonad.Layout.SimplestFloat
import XMonad.Layout.Spacing           -- this makes smart space around windows
import XMonad.Layout.ToggleLayouts     -- Full window at any time
import XMonad.Layout.MultiToggle
import XMonad.Layout.MultiToggle.Instances
import XMonad.Layout.Fullscreen (fullscreenFull)
import XMonad.Layout.Named
import XMonad.Layout.MouseResizableTile

import XMonad.Util.EZConfig            -- removeKeys, additionalKeys
import XMonad.Util.Run
import XMonad.Util.Run(spawnPipe)      -- spawnPipe, hPutStrLn
import XMonad.Util.SpawnOnce
import XMonad.Util.WorkspaceCompare

import XMonad.Config.Desktop (desktopLayoutModifiers)

--------------------------------------------------------------------------- }}}
-- vars                                                                     {{{
-------------------------------------------------------------------------------

modm = mod4Mask  -- Super
myWorkspaces = ["1", "2", "3", "4", "5", "6"]
myFloatWorkspace = "3"
myTerminal   = "gnome-terminal"
--myTerminal   = "urxvt"

-- Color Setting
colorBlue      = "#77A0D4"
colorGreen     = "#519CA5"
colorRed       = "#E15F67"
colorGray      = "#6E7E93"
colorWhite     = "#FDFDFE"
colorNormalbg  = "#333134"
colorfg        = "#D0CDD9"

-- Border width
borderwidth = 1

-- Border color
mynormalBorderColor  = colorGray
myfocusedBorderColor = colorRed

-- gapwidth
gapwidth  = 3
gwU = 0
gwD = 0
gwL = 0
gwR = 0

--------------------------------------------------------------------------- }}}
-- main                                                                     {{{
-------------------------------------------------------------------------------

main = do
    wsbar <- spawnPipe myWsBar
    xmonad $ ewmh defaultConfig
       {
         modMask            = modm
       , terminal           = myTerminal
       , workspaces         = myWorkspaces
       , borderWidth        = borderwidth
       , normalBorderColor  = mynormalBorderColor
       , focusedBorderColor = myfocusedBorderColor
       , mouseBindings      = myMouseBindings
       , startupHook        = myStartupHook
       , manageHook         = myManageHookShift <+>
                              myManageHookFloat <+>
                              manageDocks
       , layoutHook         = avoidStruts $ (
                                toggleLayouts (noBorders Full)
                                -- $ onWorkspace myFloatWorkspace simplestFloat
                                $ myLayout
                              )
       , logHook            = myLogHook wsbar
       }

       -------------------------------------------------------------------- }}}
       -- Keymap:                                                           {{{
       ------------------------------------------------------------------------
       -- xprop | grep WM_CLASS

        `additionalKeys`
        [
          ((modm, xK_e), runOrRaise "emacs" (className =? "Emacs"))
        , ((modm, xK_s), runOrRaise "gnome-terminal" (className =? "Gnome-terminal"))
        , ((modm, xK_c), runOrRaise "google-chrome" (className =? "google-chrome"))
        , ((modm, xK_t), runOrRaise "thg" (className =? "thg"))
        , ((modm,  xK_f),  sendMessage (XMonad.Layout.MultiToggle.Toggle FULL))
        ]
        `additionalKeysP`
        [
        -- ("M-l", moveTo Next NonEmptyWS)
        -- , ("M-h", moveTo Prev NonEmptyWS)
        -- , ("M-S-h", shiftTo Prev EmptyWS)
        ]
--------------------------------------------------------------------------- }}}
-- myMousebindings:          Bind mouse                                     {{{
-------------------------------------------------------------------------------
myMouseBindings (XConfig {XMonad.modMask = modMask}) = M.fromList $
    [ ((modMask, button1), (\w -> focus w >> mouseMoveWindow w >> windows W.shiftMaster)) -- set the window to floating mode and move by dragging
    , ((modMask, button2), (\w -> focus w >> windows W.shiftMaster)) -- raise the window to the top of the stack
    , ((modMask, button3), (\w -> focus w >> Flex.mouseResizeWindow w)) -- set the window to floating mode and resize by dragging
    ]
--------------------------------------------------------------------------- }}}
-- myLayout:          Handle Window behaveior                               {{{
-------------------------------------------------------------------------------

myLayout = spacing gapwidth $ gaps [(U, gwU),(D, gwD),(L, gwL),(R, gwR)]
  $ (ResizableTall 1 (1/55) (1/2) [])
  -- ||| mouseResizableTile { draggerType = FixedDragger { gapWidth = 0, draggerWidth = 2 }}
  ||| Simplest

--------------------------------------------------------------------------- }}}
-- myStartupHook:     Start up applications                                 {{{
-------------------------------------------------------------------------------

myStartupHook = do
        spawnOnce "gnome-settings-daemon"
        spawnOnce "gnome-volume-control-applet"
        spawnOnce "unity-settings-daemon"
        spawnOnce "xscreensaver -no-splash"
        spawnOnce "$HOME/.dropbox-dist/dropboxd"
        spawnOnce "stalonetray"
        spawnOnce "xmodmap $HOME/.Xmodmap"

--------------------------------------------------------------------------- }}}
-- myManageHookShift: some window must created there                        {{{
-------------------------------------------------------------------------------

myManageHookShift = composeAll
            -- if you want to know className, type "$ xprop|grep CLASS" on shell
            [ className =? "Thg"           --> mydoShift "5"
            , className =? "Emacs"         --> mydoShift "2"
            ]
             where mydoShift = doF . liftM2 (.) W.greedyView W.shift

--------------------------------------------------------------------------- }}}
-- myManageHookFloat: new window will created in Float mode                 {{{
-------------------------------------------------------------------------------

myManageHookFloat = composeAll
    [ className =? "Gimp"             --> doFloat
    , className =? "Shutter"          --> doFloat
    , className =? "Nautilus"         --> doFloat
    , isFullscreen                    --> doFullFloat
    ]

--------------------------------------------------------------------------- }}}
-- myLogHook:         loghock settings                                      {{{
-------------------------------------------------------------------------------

myLogHook h = dynamicLogWithPP $ wsPP {
  ppOutput = hPutStrLn h
  }

--------------------------------------------------------------------------- }}}
-- myWsBar:           xmobar setting                                        {{{
-------------------------------------------------------------------------------

myWsBar = "xmobar $HOME/.xmonad/xmobar.hs"

wsPP = xmobarPP { ppOrder           = \(ws:l:t:_)  -> [ws,t]
                , ppCurrent         = xmobarColor colorGreen colorNormalbg . \s -> "●"
                , ppUrgent          = xmobarColor colorfg    colorNormalbg . \s -> "●"
                , ppVisible         = xmobarColor colorGreen colorNormalbg . \s -> "⦿"
                , ppHidden          = xmobarColor colorfg    colorNormalbg . \s -> "●"
                , ppHiddenNoWindows = xmobarColor colorfg    colorNormalbg . \s -> "○"
                , ppTitle           = xmobarColor colorGreen colorNormalbg
                , ppOutput          = putStrLn
                , ppWsSep           = " "
                , ppSep             = "  "
                }

--------------------------------------------------------------------------- }}}

dotfiles/xmobar.hs at master · fnwiya/dotfiles · GitHub

Config {
         font = "xft:Sans-9:bold"
       , bgColor = "#333134"
       , fgColor = "#D0CDD9"
       , border = NoBorder
       , borderColor = "#D0CDD9"
       , position = TopW L 100
       , lowerOnStart = False
       , commands = [
                      Run Cpu [
                        "-L","3"
                        ,"-H","50"
                        ,"--normal","green"
                        ,"--high","red"
                        ] 10
                    , Run Memory [
                        "-t","Mem: <usedratio>%"
                        ] 10
                    , Run Swap [
                        ] 10
                    , Run Date "%a %b %_d %Y %H:%M:%S" "date" 10
                    , Run Battery [
                        "-t", " <acstatus> "
                        ,"-L", "20"
                        ,"-H","80"
                        ,"--low","#f44336"
                        ,"--normal","#ffffff"
                        ,"--",
                          "-o","<left>%(<timeleft>)"
                          ,"-O","Charging<left>%"
                          ,"-i","<left>%"
                        ] 50
                    , Run StdinReader
                    ]
       , sepChar = "%"
       , alignSep = "}{"
       , template = "%cpu% | %memory% | %swap% } %StdinReader% { %battery% | %date% "
       }