NoahOrblog

某・福島にある大学のコンピュータ理工学部の大学生のお話。

自作NeoVimプラグインの軌跡

Noahです。

この記事はVimAdventCalendar2018 16日目の記事です

qiita.com

先日Publishした他アドベントカレンダーの記事が「〜〜の軌跡」なので、それにあやかります。

本当はVimに最近パッチで入った開発中のテキストプロパティを触ってみた話を記事にしたかったのですが、少し時間がなかったので、自作のNeoVimプラグインについて少し話します。

NeoVimのRemotePlugin関係(主にGolang)のスライドや記事はたくさん書いているのでそちらもみていただけると嬉しいです。

noahorberg.hatenablog.com

noahorberg.hatenablog.com

noahorberg.hatenablog.com

noahorberg.hatenablog.com

www.slideshare.net

最近

NoahOrberg/diesirae.nvim

github.com

実装したのはかなり前なのですが、Aizu Online Judge をNeoVimから操作できるようにしたこのプラグインがローカルでテストを回せるようになりました

以前までは提出、結果取得をしなければならず、サーバー側で提出のログに残ってしまったのですが、予め用意されているテスト用のInput, Outputを取得して内部で回せます

その際に、実行するコマンドを自分で指定する必要があります。

READMEにも書いてあるのですが、

let g:diesirae_config = {
\  'commands': {
\    'py': {
\      'build_command': [], 
\      'exec_command': ['python3', '*source*']
\    },
\    'go': {
\      'build_command': ['go', 'build', '-o', '*bin*', '*source*'], 
\      'exec_command': ['*bin*']
\    }
\  }
\}

このように、ファイル拡張子をキーにして build_commanmd, exec_command の二種類を定義します。

*bin*, *source* はそれぞれバイナリとソースファイルのプレースホルダーです。

pythonのようなスクリプト言語には build_command に空の配列を指定し、 exec_command だけ定義します。

NoahOrberg/AYUNiS.nvim

github.com

AYUNiS.nvim では、Spotify.appを操作するためにAppleScriptを内部で利用しています。

そのため、AppleScriptスクリプトの場所を知るためにRuntimePathを内部で定義していて、以前は自分が GitHub - Shougo/dein.vim: Dark powered Vim/Neovim plugin manager を使っていたので、deinからRuntimePathを取得していたのですが、PlugなどもサブPCで使用していたので、プラギンマネージャに左右されないようにRuntimePathをVimscriptで注入できるようにしました。

少しだけ煩わしいですね。

lightline.vim などで以下のように設定するとtablineで現在の再生曲タイトルが見れるのでいい感じです。

ちなみにAppleScriptを使ってるのでMacでしか動かないです。

" use lightline (show in the tabline
let g:lightline = {
      \ 'component_function': {
      \   'ayunis': 'AYUNiSGetNowPlaying'
      \ },
      \ }
let g:lightline.tabline          = {
      \ 'left': [['ayunis', 'buffers']],
      \ 'right': [['close']]
      \ }

最後に

時間がなかったので、今まで開発したプラグインや記事たちの紹介になっちゃったけど、もっとちゃんとした記事を書きたかった...

ぼくのdotfilesの軌跡

Noahです。

この記事は Aizu Advent Calendar 8日目の記事です。

adventar.org

前の記事は id:culumn さんの記事です。自分はiOS開発を行う際によくStoryboardをつかうのですが、Xibも触ってみようという気持ちになりました。

culumn.hatenablog.com

次の記事は id:Nozomi_M さんです。楽しみです。

本題

ところで、早いもので自分ももう学部三年です。

AizuAdventCalendar、自分が学部1年のとき投稿したのはHaskellの遅延評価の話、学部2年のときにはNeoVim/go-clientの記事と書きましたが、来年は忙しくて振り返ってられないと思うのと、

今年は学部一年が結構居たので、あまり小難しい記事は書かずに、僕のdotfilesの軌跡を辿っていきたいと思います。

github.com

序盤、若干ポエム入るので読みたくない人はGoBack!

ぼくのdotfiles黎明期

黎明期っていうけど、最初にdotfilesを上げたのが2015/9/9らしい。

f:id:NoahOrberg:20181206182219p:plain

ちょうど自分が高校3年の秋ですね。僕はこの頃から会津大学の受験勉強を始めていました(推薦入試の3ヶ月くらい前でかなり遅い)

この頃は Qiitaやどこかからコピペしたreferenceすらない .vimrc をお遊びで入れていたくらいで、そもそもGitHubというツールがどのようにつかわれるものかを把握していませんでした。

dotfiles/.vimrc at a1a4a1d449f7ff1219c114f53ebd62b5c0e09ddd · NoahOrberg/dotfiles · GitHub

僕自身、大学に入ってからチーム開発というものを触れたのでしかたがないですね。コミットメッセージも最初の頃はひどいものです。

f:id:NoahOrberg:20181206182858p:plain

ひどいコミットメッセージ

何がcorrectやねん。そもそも定期ってなんやねん定期って。

ぼくの最近の.zshrcのはなし

install script

最初は、上のようにどこから拾ってきたか知らない .vimrc を突っ込んでるだけでしたが、最近はMacBookProと並行して使うマシン(ThinkPad x230)が増えたり、インターンで使用するPCが支給されたりしたので、それらのためにセットアップスクリプトを組んだりしています。

#     __                     
#    / /_  ________ _      __
#   / __ \/ ___/ _ \ | /| / /
#  / /_/ / /  /  __/ |/ |/ / 
# /_.___/_/   \___/|__/|__/  
#                            
if `which brew > /dev/null 2>&1`; then
    echo "brew: already installed"
else
    if [ `uname` = "Darwin" ]; then
        echo "brew: installing..."
        /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
        echo "brew: done."
    elif [ `uname` = "Linux" ]; then
        echo "brew: unnecessary install"
    else
        echo "cannot detect OS"
    fi
fi

よくあるやつですね。Linuxにはbrewは不必要(apt-getなりpacmanなりをつかえばいい)なので、 unameDarwin, Linuxで識別してそれぞれを入れます。

愛用のfzfやzplugもこれで入れています。

widgets

zshは、widgetという機能を使うと、関数をキーにバインドでき、その機能を自分は割と気に入って使っています。以下のような関数をC-jなどホームポジションで実行できるように出来ます。

cd_ghq() {
    selected=`for dir in $(ls $GHQPATH/github.com);do for dir2 in $(ls $GHQPATH/github.com/${dir});do echo ${dir}${dir2}; done; done | fzf`
    [ "${selected}" = "" ] && return 0
    cd $GHQPATH/github.com/${selected}

    zle reset-prompt
    zle -R -c
}

zshプラグインで、anyframeというプラグインanyframe-widget-cd-ghq-repository というウィジェットがあるのですが、細かい挙動を操作したかったので自分で再実装しています。

fzfを割と愛用してて、それで任意のghqパス配下にあるディレクトリに移動できるので心強い

github.com

これ以外によく使うのは、gitのbranchのcheckoutですね。

checkout_gbranch() {
    # NOTE: サブディレクトリからでもcheckout可能にする
    #       プロジェクトルートにcdする制限付き(存在しないディレクトリに入ったりしないために
    tmpdir=`pwd`; branches=""
    while true ; do # NOTE: `$ git branch -a` を、cdしなくてもいい方法があればそちらのほうが良い
        if [ `pwd` = "/" ]; then;
            cd ${tmpdir} && return 0
        fi

        if [ -d .git ]; then;
            branches=`git branch -a`
            break
        else cd ../; fi
    done
    selected=`echo ${branches} | awk 'BEGIN{}{print $1}' | grep -v 'HEAD' | grep -v '\*' | awk 'BEGIN{idx=1;FS="/"}{if($1=="remotes" && $2=="origin"){idx=3};for(i=idx;i<NF;i++){printf "%s/", $i}; print $NF}' | sort | uniq | fzf`
    # NOTE: プロジェクトルートからしかできない安定版は以下(上がぶっ壊れたらつかう)
    # [ ! -d .git ] && return 0
    # selected=`git branch -a | awk 'BEGIN{}{print $1}' | grep -v 'HEAD' | grep -v '\*' | awk 'BEGIN{idx=1;FS="/"}{if($1=="remotes" && $2=="origin"){idx=3};for(i=idx;i<NF;i++){printf "%s/", $i}; print $NF}' | sort | uniq | fzf`
    [ "${selected}" = "" ] && return 0
    git checkout ${selected}

    zle reset-prompt
    zle -R -c
}

プロジェクトルートに戻るために .git/ が見つかるまでひたすら cd ../ してますね。改めて見ると、階層が浅いうちはいいんですけど深くなったらどうなるんでしょうねコレ。

めっちゃコメントがかいてありますが、実際には割といま手探りで、gitのcheckoutの都合上、checkout元のブランチには存在したディレクトリにいまいるとして、checkout先のブランチにはそのディレクトリがない、などの場合が起こると都合が悪いので、チェックアウトしたあとにプロジェクトルートに戻るか、それともこの実行自体をプロジェクトルートから行えるのみにするか、みたいな葛藤をしてますね。

結局前者のほうが都合がいいので、後者はコメントにして残してる状態です。GitHubでコードを管理するとき、わりとみなさん良いコードだけ残そうとしますけど、葛藤したコードとかも残しておくほうがあとから見返せますし個人的にはいいと思います。

fzfを使うと、dockerの操作も簡単にできますのでおすすめです。ここに書くと行数が長くなるので書きません。

dlogs: dotfiles/.zshrc at 6777317032fd9b3e173a9f7fde4e2a7b8e5dcd3a · NoahOrberg/dotfiles · GitHub

dsh: dotfiles/.zshrc at 6777317032fd9b3e173a9f7fde4e2a7b8e5dcd3a · NoahOrberg/dotfiles · GitHub

dshは個人的によく使います。作業する際にコンテナの中に入って操作するときが多いので。

コマンド

あとは gg コマンドですね。chrome-cliを使って、今開いているタブのgitリポジトリghqで取ってくるようにしています。

gg() {
    # NOTE: NEEDs chrome-cli
    #       $ brew install chrome-cli
    ghq get $(chrome-cli info | sed -n 's/Url: https:\/\/github.com\/\(.*\)/git@github.com:\1/p')
    cd $GHQPATH/$(echo $_ | sed -e 's/git\@github.com:\(.*\)/github.com\/\1/')
}

ブラウジングしてて、ふとクローンしたいと思ったときにべんりです。

あまり賢くないので正規表現でごまかしつつスクリプトを組み立てています。

ぼくの最近の.config/nvim/init.vimのはなし

init.vimはNeoVimの設定ファイルです。

ちなみに自分は最近あまり編集をしてません(最近はほぼほぼzshの設定をしている)

自分はよくタイポをするのですが、それの修正のために

iabbrev TOOD TODO
iabbrev srting string
iabbrev strign string
iabbrev strnig string
iabbrev nit int
iabbrev pubric public
iabbrev Pritln Println
iabbrev Prit Print
iabbrev pritn print
iabbrev singup signup
iabbrev singin signin

こんなかんじで、iabbrev に定義をしておいて自動でタイポを直すようにしています。これはべんり。最近知った。

あとは、inccommandですね。

set incsearch
set inccommand=split

これを入れると、nvim側で置換をするときにプレビューしながら置換コマンドをかけます。これは便利。下のgifでは単純な置換のみですが、正規表現は結構難しいので割とアドです。

ぼくの最近の.config/karabinerのはなし

最近はThinkpad KeyboardをBluetoothでつなげてよく使いますが、このキーボード、ミドルボタンが少し癖があります。

Chromeなどウェブブラウザで特に顕著なのですが、スクロールのために押すと、カーソル以下のリンクが別タブで開く謎の挙動をします。

なので、それの修正をkarabinerでするスクリプトや、WindowsキーボードとMacのキーボードの配置の違いである、AltとCommandの逆転なども仕込んでいます。

これらは以下の記事から持ってきたコードなので特に書きません

ref. http://k3174r0.hateblo.jp/entry/2017/12/05/202046

ぼくの最近の.tmux.confのはなし

自分の開発において、tmuxはなくてはならないもので、自分の開発時間中、彼はずっと支えてくれています。

tmuxの見た目に関しては、vimプラグインでカラースキーマにいい感じに合わせてくれるプラグインがあるのでそれを使っています。

github.com

これはべんり。最近、tenderからspacemacs風のカラースキーマに変更したのですが、やっぱり良い。

まとめ

以上、ぼくの最近のdotfiles事情をまとめてみました。俗に言われるシェル芸とか、あまり大したことはしてないです。

「エディタはIDEで十分じゃい!」

vim(ないしはnvim)なんかつかわない!」

「tmuxよりscreenでしょ!w」

とかいうひとでも、普段シェルやターミナル環境は少なくとも使うだろうと思いますし、JetBrainsのIDEでも、~/.ideavimrc を置くことでIdeaVimの設定を行うことができます。

みなさんもこれを期に自分だけのdotfilesを極めてみてはどうでしょうか。いいdotfilesやtipsがあれば紹介していただけるとぼくも嬉しいです。

はてなインターンで最高の夏を過ごして来た

f:id:NoahOrberg:20180907142720j:plain

実はしれっと、はてなインターン2018に参加してきました!!!

developer.hatenastaff.com

応募まで

応募が始まった瞬間、エントリーシートを記入しました。(14:00 からだったのですが、その前から待機していました。)

提出するものは、自分のポートフォリオと簡単な技術課題(ROT13の実装。任意の言語を選択可能)だったので、実装してシュッと提出したのを覚えています(30分位で提出した記憶)

応募に至った動機としては、以前のバイト先が同じで、大学の先輩である id:upamune さんと id:ktr_0731 さんが一昨年、昨年のはてなインターン生(2人ともmackerelチーム)で、話を伺っていたので自分もmackerelチームにインターンで参加したいな、と思っていました。

応募から選考に受かるまで

個人的にはてなインターンが第一で行きたいところで、(もしはてなインターンに落ちたときの万が一のために)それ以外にも複数のインターンの選考を受けていました。

選考のフローとしては、書類選考の後に面談を一回行って、それから合格のメールを数日後にいただきました

前半過程

前半過程では、去年まではPerl, Scalaでしたが、 Webサービス開発の上流から下流までを網羅した充実の講義プログラムを用意 という通り、今年はGolangでのサーバーサイド、React.jsでのフロントエンド、GraphQLを用いたWebサービスの実装、AWS機械学習、インフラなどといった講義が行われ、濃い二週間でした。

GraphQL実装、すごく楽しかった。

普段書いているGolangはもちろん、個人的に普段書かないフロントエンドについてや、触れたことのない機械学習などの技術にそれこそ上から下まで触ることができて最高だった。

後半過程

希望通り、mackerelチームに配属され、 id:albacore (通称メテオ)と最初はペアプロしてました。

Scalaを基本的には使い、外部APIを生やしたらmackerel-client-go にPR投げるなどを主にやりました。

数日でそれぞれ別タスクをやることにしましたが、 id:albacore の実装が尋常じゃないほど早く、自分が1機能作ってる間に彼は3機能くらい手を付けていたのでやばかった。(語彙力)

ちなみにmackerelチームは配属準備の2週目の金曜日、その次週の月曜日(本来はこれが初日)に外部向けのRoleAPIを実装してインターン最速リリースをすることができました。

mackerel.io

mackerel.io

インターン生活

他のインターン生も、みんな同じ志をもっているので、結構仲は良かった(例年より仲が良かったらしい。

夜は id:albacore と共に id:E_ntyo の部屋に押しかけたこともあった。

あと、はてなインターンは本当にお金を使いません。朝はホテルの朝食(券が貰えるが朝に弱く実は一度も使っていない)、昼はまかない、夜は社員の方がご飯に連れてってくれます

あと、素敵なステッカーももらえます。

まとめ

はてなインターン、最高の夏!!!!!!

実はこの記事はインターン後に伝統の三嶋亭に諸用で行けなかったので、みんなと東京ですき焼きを食べながら書いて公開しています。(本当です。)

普段の技術バイトなどで触る一部の業務だけでなく、前半の講義パートでWeb開発の大枠を掴み、後半で実践のできるはてなインターンは、是非大学の後輩にも行って多くを学んで来て欲しいと思いました。

あわせて読みたい他のインターン生の記事

id:E_ntyo キャラが濃い。1日目に遅刻したことをかなり後悔していた。はてなでわっしょい。 e-ntyo.hatenablog.com

id:albacore 通称メテオ氏。技術的にも〇〇的にもヤバかった。mackerelチーム優勝出来なかったのは心残り。 blog.meteors.me

id:gazimum がじまむ。一番の常識人だった気がする。実は同じ地元だったのと、彼が次に行くインターン先に id:culumn がいることも衝撃。 tomoyaf.hatenablog.com

id:YaaMaa 服部の人。 ずっとこれの言語Rubyなの、服部の色意識してかと気になってたけど最終日に違うことが判明してよかった yaamaa-memo.hatenablog.com

id:turtar_fms かめの人。一般人かと思ったら意外とやばかった。 いいんちょと一緒にいるイメージが多い(後半過程より)。 turtar-fms.hatenablog.com

id:mizdra キングドラのひと。一番熱意があって最高。 彼のプレゼンが一番見たかった。

www.mizdra.net

id:guni1192 ツッコミ担当。彼の鋭いツッコミが、僕は好きです。インフラの知識ありまくりで凄かった。

記事が増えたら貼るよ!お楽しみに

学生版ヒダッカソン サーバーサイド編 に参加してきた

Noahです。

結構前の話なのですが、サイバーエージェント主催の学生版ヒダッカソン -サーバーサイド編- に参加してきました。

www.cyberagent.co.jp

所感

2日に渡って開催され、初日はサイバーエージェントの社員さん方のLT、メインとなる2日目はISUCONのようなパフォーマンスチューニングをしてスコアを計測し、そのスコアの高さを競うものでした。

前日のLTでは、パフォーマンスチューニングする際にボトルネックを見つける方法など、翌日に活かせられる内容ばかりでした。

2日目では実際にパフォーマンスチューニングをしていくわけですが、MySQLにINDEXを貼ると途端にパフォーマンスが上がり、その他細かい変更などをすると午前中には1, 2位まで浮上しました。

が、午後になるとこれ以上のボトルネックを見つける方法がわからずに右往左往してしまい、そのうちにも徐々にランキングは下がっていき、N+1の箇所を発見するも解消まではできず。

ついに終了1時間くらい前にメンターの方からDBに負荷のかかっているボトルネックの探し方(mysqldumpslowなどを利用し、スロークエリを探し出す方法)や、原因がわかったらその問題に対してよくやる解消方法などを教わり、最終的には5位でヒダッカソンを終了することができました。

終わってみて

パフォーマンスの向上に計測は不可欠であり、基本的なことである 推測するな、計測せよ ということがとても大事だということがわかりました。

コードを読む、というよりは(今回の構成では)主にMySQLに負荷がかかっていたので、そちらを計測し、ボトルネックをみつけ、修正する、という単純ですが難しいことをやってのけるには、やはり日頃から経験を積むしかないとも思いました。

終わってからの社員さんからの解説では、並列化テクニックや、GolangならではのDBコネクションなどの内部処理にも着目されており、とても勉強になった2日間でした

2日目の夜の懇親会には諸用により参加ができなかったのがとても心残り…

Vimプラグインのキーバインド

Noahです。

TL;DR

map、これからはinit.vimとかで設定していこう

具体的な話

今までファイル内の文字列を探すとき、ptをCLIでよく使ってたんですけど、

Vimから似たような感じで検索できるctrlsfというプラグインがあって最近はこっちをよく使っています。

github.com

このctrlsfの単語での検索を、

function! InteractiveCtrlSFCmd() abort
  let s = input("plz input word: ")
  if (s != "") 
    execute ":CtrlSF " . s
  endif
endfunction

こんな感じに関数を書いて、 <SPACE>sf に割り当てたら、何故か期待通りに動作しない。原因調査すると、

github.com

こんな感じにplugin側でキーマップしているのが原因だった。(しかも自分の作ったプラグイン

まとめ

ちゃんと考えて、バッティングしないようにしよう(戒め

アルバイトをやめた

同じとこでアルバイトしてた友人が上げていたので上げる

都内にあるベンチャー企業のサーバーサイドエンジニアとして1年程度アルバイトしてましたが、5/19付でやめました。

やめた理由とか言ってもアレなので、良かったところを書きますが、個人的には色々な人との関係が築け、多くの学びがあったのが一番良かった。

自分はそこで1年程度働きました。最初はTwitter経由でそこの支社長からDMが飛んできて、トントン拍子に契約まで行ったのですが、そもそも仕事で使うGolangすら書いたことなかったし、フロントかサーバーサイドをどっちでもいいよと言われてサーバーサイドを選んだけど、その時は課外授業でやって興味を持ったという理由だった。(よくそんな自分を雇ってくれたと感謝しかない)

そんな自分でも先輩方にコードレビューしてもらったり、大学が夏季休業中はオフィスである趣きのある日本家屋でフルタイムで勤務する中、社の先輩や社員の方とペアプロをしたりしつつ自分自身成長することができたことがとても良かった点。

あとはアルバイト先の先輩たちと(目的は多々あれど)小名浜まで行ったり、慰安旅行で京都に行ったり、他にも貴重な経験があってとにかく最高の経験でした。

正直、この環境が無ければ今の自分はなかったと思うし、先輩方や社員の方に感謝してもしきれない。


ちなみに今度は(また別の)東京にあるベンチャーで(また)サーバーサイドとしてリモートワークする予定なのでがんばるぞー💪

MacでSpotifyをNeoVimから操作できるようにしてみた

Noah です。

最近、Spotifyを契約したのですがこれがまたとても良い。

www.spotify.com

プレミアム3ヶ月100円に釣られました。はい。

で、

SpotifyをNeoVimから操作できるようなプラグインを書いてみました。

Mac かつ Shougoさんのプラギンマネージャ、dein.vim の環境下でしか現状は動きませんが、最近Linuxマシンを手に入れたのでそっちも対応させたい 💪💪💪

github.com

(わりと最近書いたつもりだったけど最終コミット2ヶ月くらい前やん…)

ちなみに名前はBiSHのアユニ・Dさんから取りました