docker+clojure+lein+vim+dein+fireplaceがうまく動かない

clojure初見で開発環境をdockerで作ろうとしてうまく行かなかった記録。
わすれそうなので書いておく。
dockerfileは以下。

FROM clojure:lein-2.8.1
MAINTAINER xxx 

RUN apt-get update
RUN apt-get install -y sudo
RUN apt-get install -y vim-nox
RUN apt-get install -y zsh
RUN apt-get install -y emacs-nox

RUN apt-get install -y locales
RUN localedef -f UTF-8 -i ja_JP ja_JP.UTF-8
ENV LANG ja_JP.UTF-8
ENV LC_ALL ja_JP.UTF-8
ENV LANGUAGE ja_JP:ja

RUN echo "xxx ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/xxx

RUN groupadd -g 1000 wheel 
&& useradd -g wheel -G sudo -m -s /bin/bash xxx 
&& echo 'xxx:pass' | chpasswd 
&& echo 'root:pass' | chpasswd

ENV USER xxx
USER xxx
COPY .emacs /home/xxx/
COPY .vimrc /home/xxx/
COPY .zshrc /home/xxx/

RUN mkdir -p /home/xxx/study/clojure
RUN mkdir -p ~/.cache/dein 
&& cd ~/.cache/dein 
&& curl https://raw.githubusercontent.com/Shougo/dein.vim/master/bin/installer.sh > installer.sh 
&& sh ./installer.sh ~/.cache/dein
# RUN /bin/bash -c 'vim -c ":silent! call dein#install() | :q"'

bootやらdevtoolsやらビルドツールなのかタスクランナーなのか何やら色々あるがleinにしておいた。
ググった雰囲気的にleinが一番情報が多そうだったから。

ここで一つ目のつまづきポイント
毎回dein#installしてしまうのが嫌だったのでdocker build時点でinstallしておきたかったんだけど

RUN /bin/bash -c 'vim -c ":silent! call dein#install() | :q"'


がうまく動かない。
コンテナを落としてrunしなおすたびにinstallはうざい、、、けど時間ももったいないので諦めた。
とりあえずコメントにしといた。いつか動くといいな。

.vmrcはこんな感じ
Dokcerfileと同じディレクトリに入れておいてbuild時にコピーする。

if &compatible
  set nocompatible
endif

syntax enable
colorscheme desert
nnoremap ; :
set hlsearch
set number
set cursorline
set imdisable
" set antialias
set nobackup
set visualbell t_vb=
set wrapscan
set showmatch
set grepprg=internal
set clipboard=unnamed
set virtualedit=block
set ignorecase
set smartcase
set incsearch
set ambiwidth=double
set laststatus=2
set backspace=eol,indent,start
set wildmenu
set encoding=utf-8
set cindent
set tabstop=4
set shiftwidth=4
set showtabline=2
set list
set listchars=tab:>-,trail:-,extends:<,precedes:<

" sorry, Uganda
set shortmess+=I
inoremap <silent> jj <ESC>

nnoremap <C-c><C-c> :set hlsearch!<cr><ESC>

"dein Scripts-----------------------------
if &compatible
set nocompatible " Be iMproved
endif

" Required:
set runtimepath+=/home/xxx/.cache/dein/repos/github.com/Shougo/dein.vim

" Required:
if dein#load_state('/home/xxx/.cache/dein')
call dein#begin('/home/xxx/.cache/dein')

" Let dein manage dein
" Required:
call dein#add('/home/xxx/.cache/dein/repos/github.com/Shougo/dein.vim')

" Add or remove your plugins here:
call dein#add('tpope/vim-fireplace')

" Required:
call dein#end()
call dein#save_state()
endif

" Required:
filetype plugin indent on
syntax enable

" If you want to install not installed plugins on startup.
if dein#check_install()
call dein#install()
endif

"End dein Scripts-------------------------

なるべくプラグインは入れないで素のvimにしたいんだけどfireplaceの入れ方がわからなかったのでdeinに頼る。

dockerのbuildは以下。

docker build --force-rm=true -t  clojure.v01.2.8.1 .

この辺から怪しくなってくる
lein replする側のコンテナ起動が以下。

docker run --name repl -p 7777:7777 --rm -it -v /home/xxx/study/clojure/.m2:/home/xxx/.m2 -v /home/xxx/study/clojure:/home/xxx/study/clojure -w /home/xxx/study/clojure -u xxx clojure.v01.2.8.1 /bin/zsh

leinを動かした時に色々落ちてくる.m2をホスト側のディレクトリで持つようにする。
そうしないとこれも毎回落としてきて辛い。

で、起動したコンテナ内で以下でreplを実行

lein repl :start :host 0.0.0.0 :port 7777
or
lein repl :headless :host 0.0.0.0 :port 7777

docker run時に-pで指定している7777はここ由来。
leinがreplにつなぐ用に開けるポートの指定をしている。(たぶん)

でこれに繋ぐ方のコンテナ起動は以下。

docker run --link repl:repl --rm -it -v /home/xxx/study/clojure/.m2:/home/xxx/.m2 -v /home/xxx/study/clojure:/home/xxx/study/clojure -w /home/xxx/study/clojure -u xxx clojure.v01.2.8.1 /bin/zsh

—linkでreplを動かしたコンテナの名前を指定。
コンテナ起動後にenvを叩くとlinkで指定したコンテナのipやらポートが見える。

[xxx/ ~/study/clojure/ #docker-clojure#]% env
PATH=・・・
REPL_PORT=tcp://172.17.0.3:7777
REPL_PORT_7777_TCP=tcp://172.17.0.3:7777
REPL_PORT_7777_TCP_ADDR=172.17.0.3
REPL_PORT_7777_TCP_PORT=7777
REPL_PORT_7777_TCP_PROTO=tcp

こんな感じ。

ふむふむ、とか思いつつ、lein repl :connectで繋いでみるとうまく行くっぽい。

[xxx/ ~/study/clojure/test/hello-world/ #docker-clojure#]% lein repl :connect 172.17.0.3:7777
Connecting to nREPL at 172.17.0.3:7777
REPL-y 0.3.7, nREPL 0.2.12
Clojure 1.8.0
OpenJDK 64-Bit Server VM 1.8.0_171-8u171-b11-1~deb9u1-b11
    Docs: (doc function-name-here)
          (find-doc "part-of-name-here")
  Source: (source function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
    Exit: Control+D or (exit) or (quit)
 Results: Stored in vars *1, *2, *3, an exception in *e

hello-world.core=> 

これってイケてるんだよね?
ではvimから・・・
vimで作ったプロジェクトのソースを開く>vimノーマルモードでcpp

function 26_printop[1]..26_opfunc[35]..fireplace#client[2]..fireplace#platform[9]..fireplace#register_port_file[9]..fireplace#nrepl_connection#open[13]..fireplace#nrepl#for
[3]..43_nrepl_process[1]..43_nrepl_message[3]..43_nrepl_call[3]..42_nrepl_transport_call[2]..42_nrepl_transport_dispatch の処理中にエラーが検出されました:
行    6:
E605: 例外が捕捉されませんでした: nREPL: [Errno 111] Connection refused^@

怒られる。
接続先がわからないから明示的につなげばいいのかな、とか思って
:FirePleceConnectを叩いてみる

FirePlaceConnect nrepl
//172.17.0.3:7777

すると

scope connection to: ~study/clojure/test/hello-world

とか出てくる。
うまくいったのか、と思いきやその後、cppするとやっぱり同じエラー。
もう今日はここまでにする。

例外か戻り値か

それを例外として(パニック)扱うべきか回復可能だから戻り値とするかなんか状況によるよな。

エディタなら存在しないファイル開こうとしてそれがなくてももっかい別のファイル指定してもらえばいい。

でもさ、webアプリでサーバ側のconfigファイルなかったら異常事態だからさっさとパニック起こして死ぬべきだよな。

例外もgoみたいな戻り値も両極端だよな。
メソッド名が
doXXX
なら戻り値で返して
doXXX!
なら例外投げる
みたいなのがいい気がする。

!は破壊的なメソッドに取られてるので他のがいいんだけど!が一番しっくりくるんだよなあ

vimとscala

.vimrcに以下

:command! RunScalaRepl execute ":VimShellInteractive scala-2.11"

vmap <silent> ,s :VimShellSendString<cr>

:RunScalaReplで右にscalaインタプリタ、右にコード書くとこが出る。

右に書く。

vでビジュアルモードに入って評価したいコードを選択。で,sすると左に送って評価してくれる。

こりゃいいかも。

 

vim

VimShellがいいのかConqueがいいのかわからないから両方入れとく

 

NeoBundleLazy 'http://conque.googlecode.com/svn/trunk/', { 'autoload' : { 'commands' : ['ConqueTerm', 'ConqueTermSplit', 'ConqueTermTab', 'ConqueTermVSplit'] } }

nnoremap <silent> ,bash :<C-u>ConqueTermSplit bash<CR>

だけ.vimrcに書いといた。

,bashで開く。

 

Elixir初見

http://yohshiy.blog.fc2.com/blog-entry-235.html
ここ読んだ程度。

うーむ。
静的型スキー(ただし型推論ありに限る)なのでスルーかなあ。
マクロはlispで懲りてるのもあるし、lispの方がいいじゃん、というのもある。

んー。どっかお金持ちの会社がlisp持ち上げてくれんかなー。