Mac版SpacemacsのPowerlineが正しく描画されない問題
この問題についてだがissueが上がっており既知の問題ではあるものの, あの長大なQ&Aの深奥に書かれているためここに残す.
(というか何故既知なのに公式のPrerequisitesが更新されないんだろうか)
emacs-mac-portをbrewで導入し,後は公式の通りspacemacsをgit cloneするプロセスを踏めば良い.
brew tap railwaycat/emacsmacport brew install emacs-mac --with-gnutls --with-imagemagick --with-spacemacs-icon
before:
というわけでspacemacs使い始めたのだけど例に有るような綺麗な描画じゃないのは何が悪いんだろうか pic.twitter.com/BvISyGoUwb
— じょんどろ (@_Nnwww) 2016年5月30日
after:
emacsmacportに適用したらすっかり良くなったよ(しかしlatexモードとかで漢字が所謂中華フォントになってしまうのだが pic.twitter.com/DMDrixY4xs
— じょんどろ (@_Nnwww) 2016年6月15日
最近はspacemacsを常用している. 一時期evil + emacsを試していた自分としては非常に理想的な環境であり, かれこれ5年程(neo)vimを使っていたもののすっかり乗り換えてしまった. レイヤについて調べたらまとめて記事にしたい…と考えている.
merilnの補完パッケージ初期化スクリプト
merilnは便利だがプロジェクト毎に一々書くのもだるい。 そう思って前に調べたら調度良いタイミングでそういうスクリプトを書いてくれている人が居た。
このgistのスクリプトはopam内のパッケージ全てを入れてしまうので、コメントにて他の方が手を加えてくれた指定版を用いると良い。 埋もれてしまうには勿体無いので、分散としてここでも言及しておく。
#!/bin/sh # Add PKG's: ocamlfind list \ | awk '{ print "PKG "$1 }' # See https://github.com/the-lambda-church/merlin/wiki/Letting-merlin-locate-go-to-stuff-in-.opam find ~/.opam -name '*.cmt' -print0 \ | xargs -0 -I{} dirname '{}' \ | sort -u \ | awk '{ print "S "$0"\nB "$0 }' # e.g.) merlin-init.sh | grep batteries > .merlin
私の環境では以下のようになる。
PKG batteries S /Users/nnwww/.opam/4.02.3/build/batteries.2.4.0/_build B /Users/nnwww/.opam/4.02.3/build/batteries.2.4.0/_build S /Users/nnwww/.opam/4.02.3/build/batteries.2.4.0/_build/build B /Users/nnwww/.opam/4.02.3/build/batteries.2.4.0/_build/build S /Users/nnwww/.opam/4.02.3/build/batteries.2.4.0/_build/src B /Users/nnwww/.opam/4.02.3/build/batteries.2.4.0/_build/src
単純な方法なのでこれでcoreを指定するとppx_core等も対象に入れてしまうが、実用には十分だろう。
ズンドコOCaml
元ネタと流れ
流行りには乗れ。
コード (ppx_deriving.show)
type zundoko = ZUN | DOKO [@@deriving show] let rec sing cnt gen = match gen () with | DOKO -> if cnt = 4 then print_endline "KIYOSHI!" else sing 0 gen | ZUN -> sing (cnt + 1) gen let () = sing 0 (fun () -> let zd = if Random.bool () then ZUN else DOKO in print_endline @@ show_zundoko zd; zd)
初めはすごいHな言語の例を受けて「batteriesのLazyListとパターンマッチで数字なんて出てこない!イケイケ!モダン!ヒュー!抱いて!」となる予定だったが汚物が建立したので潔くカウントした。 メモリも無駄にせずリストに有り勝ちな無駄O(n)走査も無くforとifの塊よか簡潔…と思いたい。 文字列で済ませば依存性も無くなるしより短くもなるけれど網羅性を担保せずしてな~にがパターンマッチじゃと実家のキャットに言われたので。
コード(ppx_deriving.show, Batteries.LazyList)
5つのまとまりで考えて良いことを忘れていたので修正した所マシになったため追記。
open Batteries.Legacy open Batteries.LazyList type zundoko = ZUN | DOKO [@@deriving show] let rec sing l = match take 5 l |> to_list with | ZUN :: ZUN :: ZUN :: ZUN :: DOKO :: [] -> print_endline "KIYOSHI!" | _ -> print_newline (); sing @@ drop 5 l let () = sing @@ from (fun () -> let zd = if Random.bool () then ZUN else DOKO in print_endline @@ show_zundoko zd; zd)
LazyListは文字通り遅延リストで、fromに遅延評価時のthunkを渡して生成できる。このthunkでコンソールに出力すれば良い。 あとはリストを5ずつ見て所定の配列になるまで捨てていくだけ。
BatteriesはString.println stdout ~
というコードを提供し、標準ライブラリのprint_
系を隠してしまう。
細々し過ぎているという気持ちも分からなくもないが、今回は使いたいのでLegacy
で引っ張りだしている。
先程と比べ、コードの状態を追わなくても一目瞭然になったのはより「らしいコード」と言えるかもしれない。
広告
速い短い型安全。
改行位置の自由度が高いシンタックスや、言語仕様が複雑じゃない所もポイントです。
正格評価かつ最適化が支配的でないため、計算量の見通しが容易で自身による最適化がコードに反映され易いのも直感的で良し。 (これは受け売り半分ですが…
可能な限り副作用を抑え安全を指向しながらも、冗長になってしまう所は副作用で殴ってしまえるのも1つの力でしょう。
OCamlはいいぞ。
関数型云々とOCamlに入門したので。
本記事はTUT Advent Calender 2015 22日目のために書かれました。 前日はid:NU_Panさんです。 nu-pan.hatenablog.com
昨年が技術記事割合多めだったような気がしてたんですけど傾向変わってて何だか本記事浮いてしまっている…(´・_・`)
導入
私が所属しているプログラミングサークルでは長期休業期間手前等、大学の日程の折り目に合わせライトニングトーク"TUTLT"を行っており、特に今回はサークル外の方(なまる〜ん)も参加するなど良い傾向が見られたなぁと思います。
(AdCと同じで技術ネタ強制ではないのでサークル外の方もっと参加しても良いんだよ?)
この流れもあり、AdCではLTで行った言語に依らない関数型プログラミング入門のスライドにOCaml入門を追加し、
前後編として公開することに決めました。
動機
此度は学内の方への布教と学外の方からの被マサカリが主目的です。こういうのは初心者のうちに言語化してマサカリ受けとけってじっちゃんが言ってました。 おかしな所、説明不足な所についてよろしくお願いします。
スライド
前編の関数型プログラミング入門はP.47まで、P.48からが後編のOCamlを用いた入門となっています。
本記事にも埋め込んでみたものの、特に後半は密度が上がるため、
全画面もしくはSlideShareからダウンロードして閲覧することをお勧めします。 (ダウンロードすると元画質で見ることができます)
www.slideshare.net
環境構築編
OCamlに興味を持っていただけましたか?
貴方がEmacserなら検索すれば色々な記事がヒットしますし、特にOcamlアイドルことid:no_maddojpさんの記事がお勧めです。
貴方がVimmerなら環境構築の一助として弊記事をどうぞ
学び
Q.) ぶっちゃけ後半見難くない?
A.) そうなんすよ…(´・_・`)
途中までスライドで作っていたためそのままOCaml入門もスライドで制作したのですが、
スライド上で可読性を失わない実例を探したり、分かりやすい説明方法に苦心したり、
その割に出来が微妙だったりと利点が全く無いですね。 ソースの解説はブログなりの記事形式で書きましょう…
次
明日23日目は最優秀発表賞ことけーさんによる記事です。
書き上がったようです、お疲れ様でした(´・_・`)
人によっては忙しさ最高潮の時期だと思われますが、皆さん良きクリスマス&お年を!
私は今からこたつみかんたこ焼き映画三昧の正月が楽しみです( ・`ω・´)
OCaml on Vim with Homebrew
動機
私は元々Vimを使っていたが、OCamlはEmacsで書くのが安牌だとされている。(現在ではSpacemacsが最も簡単に入門できる環境だろう) そこでEmacsに乗り換えてみると、此方は此方で快適であるものの、同様にエディタを軽々と乗り換えられる人はそう多くないだろうとも思った。 丁度「OCamlに入門したんだから今の内に振り返りの記事を書こう」と考えていたので、その布石としてOS X上でVimを使う際の環境構築について書くことにした。 Emacs側についてはもっと詳細な説明を書かかれている方がいらっしゃるのでそちらを参照してもらいたい。
前提
みんな HomebrewとNeoBundleの入ったVimは持ったな!! 行くぞォ!!
シェル上での設定
言語専属パッケージマネージャがOCamlにも有るので入れる。各種操作でコケる事の殆ど無い良い子。
brew install opam opam init --comp 4.03.0
ここまででopamが何か言っているようならそちらに従って下さい。
インストールが完了したようなら~/.ocamlinit
に#topfind
が有ること、~/.zshenv
ないし~/.zshrc
(お好みのシェルの設定に置き換えてください)に. ~/.opam/opam-init/init.zsh > /dev/null 2> /dev/null || true
があることを確認して下さい。
次に後に紹介するmerlinのための設定を行います。シェルの設定に以下の環境変数を追加してexec $SHELL -l
してください。
export OCAMLPARAM="_,bin-annot=1" export OPAMKEEPBUILDDIR=1
1つ目の変数はOCamlのコンパイラに渡すデフォルトのオプションです。ここでbin-annotを1にしておきます。これにより生成されるcmtファイルにはコンパイルしたソースの型付き構文木情報が含まれており、merlinはこれを利用することで:MerlinLocate
(IDEにお馴染みのGoto Definition機能)を実現しています。
2つ目の変数はopamでインストールしたパッケージのソースを残すオプションで、buildディレクトリ下にビルド済みのソースがプロジェクト丸ごと保存されるようになります。1つ目のオプションと組み合わせることでcmtが生成されている筈なので、そのプロジェクトのディレクトリに移動してソースを開けばすぐにソースブラウジングができるようになります。
OCamlは基本的にmlファイル(実装のファイル)に対応したmliファイル(mlの実装のうち、露出する関数のシグネチャを記すファイル、大体ocamlbuild ソース名.inferred.mli
で自動生成してから弄る)にその関数のドキュメント付けを行う文化があります。特に後述するライブラリのcore等はweb上のドキュメントよりもmliのドキュメントの方が圧倒的なので、ソースを読む癖を徹底付ける必要があります。そのためこの2つのオプションは結構重要です。詳細は以下を参照して下さい。
Letting merlin locate go to stuff in .opam · the-lambda-church/merlin Wiki · GitHub
続いて色々インストールしていきます。
opam install ocamlfind ocamlbuild utop merlin ocp-indent core -y
順番に、ライブラリの依存関係やパスを解決するツール、ビルドツール、REPL、補完プラグイン、インデントプラグイン、JaneStreet製の標準ライブラリ強化版です。ちょっと語弊が有るかもしれませんが許してください。
なお、今回はRealWorldOCamlを読むための設定を兼ねているのでcoreを導入していますが、如何せんビッグなライブラリなので、バイナリが大きくなることが気になるなら扱いやすいサイズのライブラリが良いと思われます。次点で有名なGitHub - ocaml-batteries-team/batteries-included: Batteries Included projectはOCaml 4.02.3と共に最近AtCoderに入りました。OCamlは実行コンパイル共に関数型プログラミング言語では高速とされる部類なので競プロにも良い筈です。 (最近はBatteriesの方がいいなと思っています)
Vimの設定
ここから先程入れたプラグインを呼び出す設定をしていきます。 お使いのVimのパッケージマネージャでsyntasticとocp-indent-vimを入れて下さい。 (まだ試してないんですけどwatchdogs.vimでも設定すればOCaml用のチェック走らせられそうですね、保存時以外の非同期チェックが良い方はそちらを試して僕に是非教えて下さい)
NeoBundle 'Shougo/neocomplete.vim' NeoBundle 'scrooloose/syntastic' NeoBundle 'def-lkb/ocp-indent-vim'
Neocompleteの設定に関してはVim界隈で沢山の言及があるので説明は不要かと思われます。githubの設定例のコピペで全く問題なく動作するでしょう。ただし後述するmerlinのようなvim側のパッケージマネージャで管理しないvimscriptの読み込みをNeoBundleLazyなどで遅延読み込みするのはお勧めしません。私の経験談でしかありませんが、結構簡単に動かなくなります。
私のsyntasticの設定です。特に重要なのは上2パラグラフで、symbolや色の設定はお好みでどうぞ。
set statusline+=%#warningmsg# set statusline+=%{SyntasticStatuslineFlag()} set statusline+=%* let g:syntastic_always_populate_loc_list = 1 let g:syntastic_auto_loc_list = 0 let g:syntastic_check_on_open = 0 let g:syntastic_check_on_wq = 0 hi SyntasticErrorSign ctermfg=160 hi SyntasticWarningSign ctermfg=220
そして一番この記事で重要そうなのがここ。
let g:opamshare = substitute(system('opam config var share'),'\n$','','''') execute "set rtp+=" . g:opamshare . "/merlin/vim" let g:syntastic_ocaml_checkers = ['merlin'] if !exists('g:neocomplete#force_omni_input_patterns') let g:neocomplete#force_omni_input_patterns = {} endif let g:neocomplete#force_omni_input_patterns.ocaml = '[^. *\t]\.\w*\|\h\w*|#'
opamはコンパイラのバージョン毎にディレクトリを分けており、それに付随するパッケージ達もディレクトリ毎に分かれています。ユーザーが意図的にディレクトリを分けることも可能であるため、
などなど利点が多いのですが、エディタ側の設定では工夫が必要になります。
opamは現在フォーカスしているコンパイラ(これはopam switch <コンパイラのバージョン>
で切り替えます)の情報を提供するコマンドがあるので、それを使って各パッケージに同梱されたVimのプラグインファイルへのパスをVim本体が読み込むランタイムパスに追加する必要が有るという訳です。merlin自体のパスを通したらsyntasticにmerlinを設定しておいて下さい。ocp-indentについては先程入れたVim側のプラグインがよしなにしてくれるので特に何も記述する必要はありませんが、細かなインデントの変更を行いたい場合だけ公式ドキュメントを見ながら.ocp/ocp-indent.conf
を設定して下さい。ocp-indent.confの記入例はこちら
ちなみにこのスクリプトのsystem関数はopamが無いとエラーを吐くので、ポータブルなvimrcを望む方はopamの所在を確認しておきましょう。(if executable('opam')
などなど
最後に自動補完の設定となります。補完自体はmerlinにお任せしたいので、Neocompleteのg:neocomplete#force_omni_input_patterns
に補完を呼び出す際の正規表現を渡します。
良い方法ないかなーと思って探していた所、merlinのVimプラグインのhelpファイルの最も奥底にneocomplcache時代の設定が眠っていたので正規表現だけ拝借しました。本当に神様仏様暗黒美夢王様です。
(2015 11/15追記)
そういえば忘れてましたけどデフォルトのままだとインデント周りでocp-indent-vimが支配的に成れていないようなので、~/.vim/ftplugin/ocaml.vim
に、
set shiftwidth=2 set tabstop=2 set softtabstop=2
のように追記しておいて下さい(あくまで貴方のocp-indent.conf
に合わせてお願いします、これは私の例です)、この場合であればfiletypeがocamlの時だけインデントがスペース2個分になります、expandtab
するか否かはお好みでどうぞ。
ftplugin/ocaml.vim
はmerlinでも使用しているようで、ここにプラグインの遅延読み込み設定などを入れるとエラーになりやすいので気をつけて下さい。(経験談
merlinのための設定
.merlin
ファイルを貴方が作業するディレクトリ下に配置することでどのソースやパッケージを補完するのかを設定することが出来ます。
coreだけ入れてくれれば良いよという場合はPKG core
をカレントディレクトリの.merlin
内に書いて下さい。
詳しくはこの辺を参考にすると良いと思われます。
vim使用時のmerlinの諸機能(式の型評価やコードサーフィン機能)や、補完の詳細なコンフィグは以下のmerlin自体のwikiを見て下さい(実質必読
すると…
vimでOCamlの設定してたんだけどCoreの補完が激しい pic.twitter.com/GpSRpLJdmx
— じょんどろ (@_Nnwww) November 6, 2015
(ここから2文字も打てば殆ど絞られるので作業に支障は無いです)
(追記:) 実際に沢山のパスを記述するのは面倒なものです。こちらもお勧めしておきます。
学ぶ
Real World OCamlが無料で公開されており、難しくない英語ですし、他の和書と比べ新しめで踏み込んだ内容だと思います。(まだ2章のパース関連までしか読めてないのですが…)
日本語なら…
OCamlについて踏み込む訳では有りませんが、関数型言語を用いたプログラミングの基礎としては、
http://www.saiensu.co.jp/?page=book_details&ISBN=ISBN978-4-7819-1160-1&YEAR=2007
を読むのが良いと思われます(少なくともweb上の小難しい表現で得意になっている記事よりは余程平易で為に成ります)
言語化を兼ねて関数型プログラミング & OCaml雰囲気ざっくり入門を書いてみました、専門書と比べあまりにも貧相ですが御参考までにどうぞ。
ocp-index, OCamlSpot, merlin, 或いは gtags
これらはmliとmlの間を移動したり、呼び出しから実装へ跳んだりする機能を持つプラグインです。規模が大きくなったり本腰を入れたコードリーディングには欠かせない存在だと思います。 私の場合試しにocp-indexを入れてみたんですが思った挙動をしないのでそれ以外を入れることを検討中です… unite-gtagsのようなgtagsとの連携はまだ導入していませんが、最近merlinを使っています。機能の詳細は先程挙げたmerlinのwikiを見て欲しいのですが
- top levelのモジュール名を指定してml, mliへジャンプする機能
- 式の型を表示する機能(更にその式の外側or内側の式を評価する機能)
- カーソルを置いた関数の定義へジャンプする機能
があるので非常に便利です。またOCamlのシンタックスに併せた移動機能MerlinJumpが追加されたようですね。
Jump command · the-lambda-church/merlin Wiki · GitHub
これにアウトラインを走査する機能があれば最高なのでgtagsとかも試してみたいですね!
tmux 2.1 on OSX マウススクロール出来ない件
マウス周りの設定が大きく変わったようですね こういう時は取り敢えずgithubを見て、
set-option -g mouse on bind -n WheelUpPane if-shell -F -t = "#{mouse_any_flag}" "send-keys -M" "if -Ft= '#{pane_in_mode}' 'send-keys -M' 'select-pane -t=; copy-mode -e; send-keys -M'" bind -n WheelDownPane select-pane -t= \; send-keys -M
以上です。スクロール量が足りない方は
bind -t vi-copy WheelUpPane halfpage-up bind -t vi-copy WheelDownPane halfpage-down
を更に加えて下さい。あ、これまでのmouse系は勿論消してくださいね。
YosemiteにおけるFlashlight起動, そして夜狐アンビエント降臨篇
tl;dr
動いたけどtwitterのプラグインに問題が有るので対応を…されるんだろうか…(´・_・`)
と思ってたら製作者様から反応頂き無事修正出来ることを確認しました!(2016/01/03 更新)
本文
macにはSpotlightなる機能があるよね、あ、まず此処でmac以外の方は解散です。んでこれはOS全体を検索してくれる+ちょっとした機能のランチャなんですね、環境設定の所から検索するリソース設定できて、一々マウスを動かさなくてもショートカット1つでmac上のあらゆる場所からアプリケーションを呼び出せたり辞書検索できたりして便利なんですけど、これもっと機能追加したら便利なランチャになるんでね?というのがflashlightです。 www.danshihack.com
丁度夏季長期休暇も終わり、「心機一転まずは環境の見直しでもするかー」という感じでmacをいじくり回していた私はこれに目が止まり折角なので入れてみようと思ったら動かない。 そして長い戦いが始まったのです(体感3時間)
はい面倒な話は抜きにして解決策ですね、まずこちら
Steps to make Flashlight work on 10.10.4 (doesn't work for El Capitan) · GitHub
日本人で反応している方もいらっしゃいました
成程これを使えばいいんですね!
…
動かない…
(動いた方はここで解散です、お疲れ様でした)
というか貼られているapple scriptなるもの、'Identifier' can't follow this 'Identifier'とか言って全く動作しないんだけど?
とはいえいくらググっても(そういえば英語ではgooglingと言うらしいですね、最近知りました)コレ以外の有効な方法は見当たらないし… でも何となく諦め付かないし…とグダグタ格闘した末「動いたthx!」という賞賛のコメントを恨めしくスクロールしていくと…
For anyone getting syntax error: 'Identifier' can't follow this 'Identifier', even after closing Flashlight, restart your mac, close Flashlight again, then run the script. Tested on 10.10.5!
ええ、いつもどおりの灯台下暗し、解決策は真下に有りました、というかこんな方法コメントした方はどうやって見つけたんだ。本当に感謝しか無い…
とはいえこのコメントからは真意を掴みきれず、この後30分以上は閉じては再起動、スクリプトを実行しては〜を繰り返していたと記憶しています。結果はこうです。
- まず先ほどの解決策の通りにスクリプトを書いてアプリケーションの形式で保存する
- ここでIdentifierが云々と言って動かなくても取り敢えず保存
- システム環境設定の「ユーザとグループ」を開く
- ログイン項目の実行するアプリに先程保存したスクリプトとflashlightを登録
- flashlightの隠すにチェックを入れる(flashlightの画面が起動時に邪魔なので
- flashlightをdisableに
- PCを再起動、ログアウトでもおk
- ログインしたらflashlightを再びenable→disable
- スクリプト実行
- なぜか動く
「途中のログイン実行登録後からでも良くね?」
はい、そうだと思います。取り敢えず自分が動いた例の詳細を上げたので、大事なのはやはりeven after closing Flashlight, restart your mac, close Flashlight again, then run the scriptでしょう。flashlightがdisableの状態で次回もログイン実行されるようになればOKです。
あらゆる状態からショートカット1つでツイートしたかった
これで各種webサービスからロック、シャットダウンといった操作までワンショートカットでアクセスできるようになり、快適度が増しました、しかし一番の見所はflashlight用のtwitterクライアントが有ることです。
これは正に思考の標準出力をtwitterにリダイレクトするが如き神クライアントでありまして、メール読んだりググったりシェルをいじっている最中にもワンショートカットでツイートできてしまう代物なのです。 しかしこれには現状問題点が有ります。Mac OS X のNFD問題です…つまりこの夜狐アンビエントを介したツイートは他のOSから見ると濁点が分離して見えてしまうということですね…(´・_・`) 何卒作者様対応をお願いします…
製作者様から反応を頂きました (2016/01/03 更新)
https://t.co/ZXU0kKl8Gw
夜狐アンビエント使ってくれてる人おる…!
これまだ使ってるかな。使ってたら直そうかな
— のっぺ (@noppefoxwolf) 2016, 1月 2
うおああああああああああああああああああああああああああああああああ使いますうううううううううううううううううううううううううううううううううううううう
— じょんどろ (@_Nnwww) 2016, 1月 2
@_Nnwww なおすうううう!!!!!
— のっぺ (@noppefoxwolf) 2016, 1月 2
@_nnwww 動きませんでした…
NightFoxAmbient.bundle/plugin.pyの100行目付近をこんな感じにしたら動くかもです。
環境が無いのでちょっと試せないですが… pic.twitter.com/gUTpWSZcKw
— のっぺ (@noppefoxwolf) 2016, 1月 2
@noppefoxwolf 随分遅れましたすいません、元々unicode文字列だったので画像100行目のdecodeを取り除いたコードで動作確認できました(androidから確認したのみですが…
— じょんどろ (@_Nnwww) 2016, 1月 2
という流れで解決することが出来ました。思わぬお年玉です、有難う御座いました!!
少し補足すると、書き換えるスクリプトは~/Library/FlashlightPlugins/NightFoxAmbient.bundle/plugin.py
の100行目付近で、以下がコピペ用となります。
関数norm_unistr
は新規に追加し、元のmessage = message.encode('utf8')
からmessage = norm_unistr("NFC", message, "utf8")
へ変更して下さい。
from unicodedata import normalize def norm_unistr(form, string, encoding): s = normalize(form, string) return s.encode(encoding) def run(message): import os, pipes, json from requests_oauthlib import OAuth1Session from applescript import asrun, asquote # message = message.encode('utf8') message = norm_unistr("NFC", message, "utf8")
これが恐らくOSX Yosemiteにおける最速のツイートツールです、TLが見れないのですが寧ろTLを追う作業効率低下を避けつつ呟く事ができるのでメリットと言えるでしょう。
実はブログ始めに「始めました」だけだとアレだなぁと思い書いた記事だったのですが…これからは純な技術ネタ以外も投稿していきたいと思います。