Gashooの描く未来

クリエイターの生き方、働き方の選択肢を増やすことで社会における情緒的価値を増やす。

Gashooの目指すを一言で表すと「全てのクリエイターに生き方、働き方の選択肢を増やしていくこと」です。

僕らの創業メンバーの半数は芸術大学出身でそれぞれのバックグラウンドを持ちながら社会に飛び込みました。

様々な機会に恵まれ、チームとして動くことができ、様々な支援によって働く環境、自分たちのやりたいビジョンに向かって動いていけています。ここで改めて関係者各位に感謝申し上げます。 本当にありがとうございます。

なぜ僕らがクリエイターの生き方、働き方の選択肢(以下:クリエイターの選択肢)を増やして行くことになったのでしょうか?

クリエイティブから生まれる様々な人の情緒的価値の向上

僕たちがクリエイターの選択肢を増やす理由は一言で言うと社会全体の情緒的価値の向上にあります。 僕たちは価値において機能的価値と情緒的価値の二つが存在していると考えています。 機能的価値は例えばiphoneが便利だと思う動機、情緒的価値はiphoneを所有していることによる感情変化による情緒的価値などを考えています。

これは例え話ではありますが、冬のイルミネーションなどを見て綺麗と感じるかたが大半だと思います。

ではこの綺麗と感じる瞬間を作っているのは誰なのでしょうか?

様々な見解があると思いますが僕たちはクリエイターがデザインしそれらを人々が制作、構築し、この場所、空間を生み出したと考えています。 つまり、クリエイターが人々の情緒的価値の大半を構築していると考えています。

事象についてはそれだけに限る事はないですがつまり僕らの考えていることはクリエイターが社会的に最適化されて、なおかつ自身の働き方で活動できるようになれば日常的に生きている人々の「かっこいい」「綺麗」「かわいい」などといった感情から沸き起こる幸福度はあがっていくのではないかと考えています。 なぜ情緒的価値の向上をするのでしょうか?

僕たちは情緒的価値が向上すると人々は幸福を感じることができ人生が豊かになると考えています。

それはこの記事を執筆している松江がバックパックをして東南アジアを周遊していた時の話になりますが、バックパックをして気づいたことがありました。途上国地域の中の集落に訪問した時の話ですが、そこは僕たちが住んでいる日本では見た事のないような景色でした。

コンクリートジャングルで育った僕からすれば高床式倉庫のような家で暮らしている事が理解できなかったのです。 「こんなところで幸せに暮らすことなんてできない。」と思っていました。

僕の中でそれはかなりのカルチャーショックを受けました。

そこに住む人々は確かに笑いながら幸せそうに暮らしていたのです。

そこで気づいた点は、どんなに便利な社会であろうと心が貧しいと人は生きにくいのではないか。

逆説で行くと心が豊かであれば便利な社会じゃなくても生きやすいのではないか。 そこで情緒的価値の向上が浮かびました。 自身からの経験から生まれたことではありますが、帰国してからの考え方が変わったことによって全てのクリエイティブシーンにおいて感謝をするようになりました。

自分自身が生きていて「楽しい」「かっこいい」「綺麗」などといった感情が沸き起こるシーンは確かにクリエイターが創っていたのです。

大好きな映画、大好きな音楽、大好きな花火、大好きなイルミネーション、どんなに生活が便利になってもこの大好きなものが僕たちの生活の質を向上していると考えています。

だから僕たちはクリエイターの選択肢を増やす。

まとめると

クリエイターが活躍する→それを見た、感じた人たちが幸せを感じやすくなる。

クリエイターの選択肢を増やすことで社会全体における情緒的価値、幸福度の向上に繋がるからと僕たちは信じてクリエイターさんと共に世の中をもっと生きてて楽しい世の中にしたいと考えています。

僕たちが目指す未来はクリエイターと共に社会全体の情緒的価値の総量を増やすことです。

今後とも宜しくお願いします。

株式会社ガシュー CEO 松江翔輝

思考におけるクリエイティブとは

ソルトです。 最近いわゆる、「インターン」というものに結構顔を出しています。 そうですね、人によっては面白いのかと思います。

そこでよく言われる思考のフレームワークについて 自分の中で固まってきたので書こうかと思います。 結果から。

『クリティカル思考』
    ↓
『第一クリエイティブ思考』
    ↓ 
『ロジカル思考』
    ↓
『第二クリエイティブ思考』


クリティカル思考は、世の中から課題を見つける能力。 第一クリエイティブ思考は、主観を一切入れずに神の目から見て、理想の状態を具体的にイメージする能力。 ロジカル思考は、その目標までに相手を説得できる理詰めがどれだけ情報を元に構築できるかという能力。 第二クリエイティブ思考は、ロジカル思考によって考えられたものをどうアウトプットしていくかという能力。

この『第一クリエイティブ思考』って僕が呼んでるところ、 今の大学生世代はかなり苦手だと思います。 課題があったときにすぐ「AIを用いて〜」みたいな。 結局そんなことしても何が面白いの?と思ってしまうベンチャー企業ってたくさんあると思うんですよね。

じゃぁどういう人がみんなを ゾクゾク (ワクワクではない)させれるレベルの理想を提示できるのか。 結果論でしかないんですけど Work Hard, Play Hard を貫いている人はやっぱりぶっ飛んだ面白いことを思いついている印象がありますね。

「遊びの概念からクリエイティブは生まれる」 「遊びの延長線上にクリエイティブはある」 よく言われるようなことに着地するのかなと思います。

固定概念の枠を自分で認識した上で、 その境目を行き来して自分を自分自身で弄ぶ。 その先に本当に面白い理想が広がっているのではないでしょうか。

最後に自分が描いている理想の世界について箇条書きで書いてみます。

・40歳定年制度
・オール逆求人システムの採用
・染料導線と電磁誘導を組み合わせた、半永久的送電装置
・全消費財のIoT化と、自動郵送システム
・ヒトの雰囲気、波長の可視化によるマッチング装置
・5感すべてをジャックする広告

ほかなにかあるかな。。

Docker上でHanamiを動かす

GASHOO Inc. Advent Calendar 2017土曜日担当、23日目を飾ります、t-kusakabeです。 いよいよ僕の担当は最後です。頑張っていきます。

Hanamiをくじらの上で。

今回はGashooでも使われている、Docker上でHanamiを動かすということをしようと思います。 まだまだHanami & Dockerの記事がそんなにないので手順をまとめて見ました。 Docker。便利ですよね。

まずはDockerをinstall

Mac OSの方は以下のリンクからDLしてください。 Docker for Mac

Docker for MacだとDockerもdocker-composeもinstallできるので便利ですね。

まずはHanamiのスケルトンを作る

なにはともあれ hanami new です

hanami new hanami_on_docker

Hanamiのスケルトンが出来ました。

.
├── Dockerfile
├── Gemfile
├── README.md
├── Rakefile
├── apps
├── config
├── config.ru
├── db
├── lib
├── public
└── spec

Dockerfileを書く

ではDockerfileを書いていきます。 今回はRubyの2.4.2、ベースイメージにalpineを使おうと思います。

FROM ruby:2.4.2-alpine

ARG APP_ROOT=/home/hanami_on_docker
WORKDIR $APP_ROOT

RUN apk update && \
    apk add \
      build-base \
      curl-dev \
      libxml2-dev \
      libxslt-dev \
      linux-headers \
      mysql-dev \
      nodejs \
      ruby-dev \
      tzdata \
      yaml \
      yaml-dev

COPY . $APP_ROOT

RUN gem install bundler && \
    bundle install

/home以下にアプリケーションを置いてその中でgemをinstallします。 本的に必要になるライブラリだけ入れていますが、他にも必要なものがある場合は適宜追加してください。 (RMagickをつかっているのならImageMagickなど)

docker-compose.ymlを書く

次にdocker-compose.ymlを作成します。 DBにはMySQLを使おうと思います。

version: '3'
services:
  app:
    build: .
    container_name: "hanami_on_docker"
    ports:
      - "2300:2300"
    command: bundle exec hanami server --host 0.0.0.0
    volumes:
      - .:/home/gashoo_admin
    depends_on:
      - db
    tty: true
    stdin_open: true

  db:
    image: mysql:5.7
    container_name: "mysql"
    ports:
      - "3306:3306"
    volumes:
      - mysql-data:/var/lib/mysql
    environment:
      MYSQL_ALLOW_EMPTY_PASSWORD: "yes"

volumes:
  mysql-data:

buildしてみる

それではbuildしてみましょう。

docker-compose build
docker images

で、 hanamiondocker というコンテナが出来て入ればOKです。

コンテナを起動してみる

それでは最後にコンテナを起動してみましょう。

docker-compose up

localhost:2300 にアクセスしてHanamiのトップ画面が表示されて入れば成功です!

デザイナーがTutorial: Intro To Reactを和訳しながらやってみたで( `・∀・´)ノ来年モヨロシク

f:id:gashoo:20171221033831p:plain

こちら、GASHOO Inc. Advent Calendar 2017の記事です。

Reactを学習することになった経緯💢

弊社代表「デザイナーもReact触れなアカンで!(σ・∀・)σゲッツ!!」

ぼく「はあ( ゚∀゚)」

この記事を書こうと思った理由🖊

  • モダンなフロントエンドの開発トレンドを知らねばならん
  • とりあえず入門で勧められたReact Tutorial、日本語版が見つからない。(同じ理由で挫折した人がいるはず)
  • 意外とやってみたら楽しい

というわけで、まともに触れませんが、挑戦していきながらReactの門を叩こうと思います。

謝罪🙇

Reduxは時間の都合で間に合わんかったんじゃ。。。

ぼくのJsレベル

  • jQueryは結構さわってた
  • 生のJsもちょくちょく書いてた(document.querySelector('hoge')ですねわかります)
  • ES6、ちょっとだけ分かる
  • 設計とかはさっぱり

実施環境

Mac OS X El Capitan (10.11.5)

Node.js V7.0.0

npm 3.10.8

ローカルマシン内にcreate-react-appをインストールし、 localhost:3000 で進捗を確認していきます。

和訳だけ見たいねん💢 という方

こちら

インストール&下準備

    $ npm install -g create-react-app
    $ create-react-app my-app //my-appっていう名前でReactアプリケーションを作成
    $ cd my-app
    $ rm -f src/*
    $ touch src/index.css src/index.js // src以下にindex.cssとindex.jsをつくる

以下、章に対応して考えていたことをまとめていきます。

最初の状態

GameがBoardをrenderして、BoardがSquareをrenderしているので、

なんとなく、Game > Board > Squareなのね、という解釈です。

Propsを通じてデータを渡す

突然 props とかstate とか出てくるけど違いが分からんので調べます。

Stateは「Componentが持っている状態」の事を、
Propsは「 親Componentから渡された値」を指します。
こちらを参考にしました
https://qiita.com/ryo_t/items/d1f080f77bdeff4fa2f4

状態を引き上げる

この章ではここが重要っぽい。

複数の子からのデータを集約する場合や、2つの子コンポーネントが互いに通信する場合は、親コンポーネントに存在するように状態を上位に移動します。 親は、親コンポーネントを介して子に状態を戻すことができるので、子コンポーネントは常に互いに、親と同期します。

で、component間はprivateとなってSquareコンポーネントから、Boardコンポーネントへアクセスすることができないので、■をクリックしたときの関数をSquare側へ渡そう、というみたいです。

親であるBoardクラスから状態が飛んでくる予定なので、

  • Squareの render で this.state.value を this.props.value に置き換えます
  • Squareの render で This.setState() を this.props.value に置き換えます
  • 状態を持たないのでSquareからコンストラクタ定義を削除してください

こうなるようです。


そして以下の行、

四角をクリックしてみてください。handleClickをまだ定義していないので、エラーが発生します。これをBoardクラスに追加します。

ここで、

handleClick(i) {
    const squares = this.state.squares.slice();
    squares[i] = 'X';
    this.setState({squares: squares});
}

おお、なんじゃこれとなります。

this.state.squaresの配列をコピーして、squaresという新しい変数に代入。これをBoardコンポーネントのコンストラクタにいる this.state = { squares: ~~ }にセットするっぽいです。ややこしい。

Functional Components

この時点でSquareコンポーネントはコンストラクタ関数も内部的な処理も持っていないので、renderを返すだけの関数でOKよね、って話みたいです。

ターンを作る

そんなにつまづかなかったので割愛

勝者の定義

calculateWinner関数が一瞬「?」となるが、ようするに勝ちパターンである[0, 1, 2], [3, 4, 5]に一致するかを判定してるっぽいです。

ここまでで一応完成。次はターンを行き来する機能を作っていきます。

履歴の保存

上位のレベルのGameコンポーネントが移動リストの表示を担当するようにします。(強制)

Boardコンポーネントに書いていた内容をGameコンポーネントにお引っ越し。同じようにコンストラクタを定義して、下記のタスクを終わらせます。

  • Boardでコンストラクタを削除します
  • Boradの renderSquare で this.state.squares[i] を this.props.squares[i] に置き換えます
  • Boardの renderSquare で this.handleClick(i) を this.props.onClick(i) に置き換えます

これで、Gameコンポーネント → Boardコンポーネント → Square関数という風になります。

で、handleClickメソッドをGameコンポーネントに移すときには、historyという状態にconcatを使ってどこどこゲームの状態のオブジェクトが入っていく感じですね。はじめの

このようなオブジェクトを状態に格納するとしましょう

    history = [
      {
        squares: [
          null, null, null,
          null, null, null,
          null, null, null,
        ]
      },
      {
        squares: [
          null, null, null,
          null, 'X', null,
          null, null, null,
        ]
      },
      // ...
    ]

こんな感じで入っていくわけですね。

Keys

keyというプロパティが、Reactが内部で色々するために勝手にできるので、適切なkeyを設定しましょうね、ってことらしい。適切なkeyってのは、重複しないユニークな値を設定してねってことらしいです。

紆余曲折あって完成

言われるがままコードを書いていたが、とりあえず完成。

とりあえず、このチュートリアルで理解できたことは、

  • 親と子の関係を持つコンポーネントという単位で構成していく
  • propsは親から子へ値を渡す時、stateはコンポーネントの状態を表す
  • 子から親へはアクセスできないので、親 → 子へのデータ渡しの形を基本にする

本当に基本的なことしか理解していないので、来年はもっと環境周りを含め、色々理解していきたいですね。

アドベントカレンダー、初めて書いてみた感想

  • いつもぼんやり考えていることを、人に伝わるように書くのは難しい
  • 定期的に続けることが一番難しい
  • たった4回の更新だけど、すっぽかさずにできたから良かった
  • 文体がCVRに影響するのか個人的に観察してたけど、あんまりないっぽい。大事なのは見出しと画像 (ちなみに、絵文字の多用はCVRに関係はなく、趣味である)
  • はてなブログ、もうちょいアクセス解析ガッツリしたい感
  • markdown記法がノールックで結構書けるようになった
  • Gashooのアピールになったのだろうか、来年はもうちょい統一感のあるテーマで書きたい
  • デザイナーなのに、デザインについて書いたのは1回だけ(いいよね)
  • 自分は文章を書くのはあまり嫌いではないようだ

そんな感じで、白石の2017年アドベントカレンダー、お先に終了とさせていただきます!ありがとうございました。🙇

Gashooのアドベントカレンダーはまだまだ続くので、お楽しみください。🙇🙇🙇

余談

過去の白石の2017アドベントカレンダー

gashoo.hatenablog.com

gashoo.hatenablog.com

gashoo.hatenablog.com

GASHOO Inc. Advent Calendar 2017

adventar.org

この処理どう書いたらいいのか 迷ったねんけど...

f:id:gashoo:20171201153719j:plain


はじめに

Gashoo inc. Engineer の しゅん(@shunn_93) | Twitterです~


GASHOO Inc. Advent Calendar 2017年12月20日 を飾ります。

前回引き続き 自身の1年の振り返りとともに

コード的に どうあるべきか... スタイルガイド的に... となったときの お話です。

コーディング規約が しっかり ない時期だと よく起こる話だと 思うので, それらの対処法 を お伝えできればなと思います。



2017年10月 ~ 12月


10月   基礎的なことでは 詰まらなくなる
       あるシステムを作って欲しいという内容の設計などを考える
       周りの人からweb教えて などを言われるようになる
       エンジニアリングにおいて, できるの定義が 少しだけ明確化する

基礎部分のところで ほとんど詰まらなくなってきて,
どうあるべきか などの会話が 少しずつ できるようになる。
これが, また難しいですね。。。

また, 周りの知人から webに関する質問などが 僕の元へくるようになる。


11月   Gashoo の デザインリニューアル
    新しい機能のリリース
       react,  hanami など に手を出そうとする
       docker とはなんぞや となる
       DDDの教本を開いては 眠くなる

デザインリニューアルと 共に 新しい機能のリリースを行いました
やること多すぎて, 自分がなにやっているのか わからなくなるレベル笑

リリースするタイミングも, 障害対応したりと, なかなか 気が休まらなかった。

その後すぐに, 次どう進めていくのか, どこを修正かけていくのか, などを話し合い、
他の技術を導入検討したので, それらの勉強を始めようとした。


12月   今ココ
       体重は変わっていないが去年より 太った気がする






どう書くのがベストプラクティスなのか迷ったとき



パターン 1

def hoge
  if Time.find_by(params[:xxxx]).present?
    @drink = Drink.create(params[:xoxo])
  end
end



パターン 2

def foo
  @drink = Drink.create(params[:xoxo]) if time_present
end

private

  def time_present
    Time.find_by(params[:xxxx]).present?
  end



メソッド hoge と foo どちらも 同じ処理をしているのだが
どちらの方が 可読性があり、わかりやすいのか.....
そういった話になったことがある。

その際に どちらの パターンを採用する方がいいのか。



Ruby on Rails Style Guide には

1行は 80文字以下に統一を推奨としている。

パターン 2の長い1行の部分でも 50文字となっているので、それは 満たしている...orz

どちらの方が 読みやすいのだろうと 考えた。。。

パターン 1 は if で条件を書いて インデントしている。
パターン 2 は インデントせずに 後置if で ワンライナー(1行)で 書いている。



ここで 例に上がったのは,

私生活での会話...w

パターン 1 は

もし, 暇なんやったら, 飲み物を作って欲しい。

と 言っているイメージで,

パターン 2 は

飲み物を作って欲しい。もし, 暇なんやったら

と 言っているイメージ。

言い方であったり, 言いやすい方を 言うと思うのですが、 どちらも 同じ意味です...

パターン 1 は 相手が 暇だという前提で 言っている感じで, もう行ってきて~ と 言っている感じになりそうで...


パターン 2 は 倒置法を用いて, ほんまに 暇なんやったら、行ってきて欲しい, と 言っているニュアンスになりそうだなと...w



結論 どの方法がいいのか

考えた結果,

基本的に コードは 上から 順に読むので, パターン 1 を採用し,
尚且つ , より処理の可読性を上げるために, private method を作成し
method名から 条件を 連想できるように しました。



採用したパターン

def bar
  if hima_time_exists?
    @drink = Drink.create(params[:xoxo])
  end
end

private

  def hima_time_exists?
    Time.find_by(params[:xxxx]).present?
  end

こういう書き方にすることにより、

まず はじめに if文が 目に入り, どういう条件なのか確認する。
hima_time_exists(存在する)? と書いているので、
メソッド名だけで どういう条件なのか わかることができる。

暇な時間は存在する??という条件だ ということが メソッド名から 連想することができたら

もし, 暇なら 飲み物を 作る(買ってくると認識でも可 笑) ってことが,
barメソッドだけで確認することが 可能になる。

これがもし パターン 1 の方法を 採用していたら、
Timeってなんだっけ... params[:xxxx]って どういう情報が入っていて...
結局, どういう状態だったら、Drink.createするのだったけ....orz となる可能性が 高い....

僕は これが 一番読みやすく, わかりやすいと 思ったので, 上記を採用しました。
こういう方法の方がいいよ など ベストプラクティスな 意見がありましたら、コメントなどで 連絡してもらえると🙇


まとめ

  • メソッド名の命名など 他の人の意見を聞いてみる
    • しっかりとしたコーディング規約が あればそれに従う
    • 自分がそうだと思っていても, 連想させるモノが 違うときがあるので
  • 未来の自分を想像する
  • 可読性を上げて 読んで シンプルに なにをしているか わかるようにする

追記

  • 僕自身 リーダブルコードなどを 再度 じっくり読みます🙇

余談

前回の古川のアドベントカレンダー
仕様, 設計が 甘くて 禿げた - GASHOO BLOG



過去のGASHOO Inc. アドベントカレンダーの記事はこちら
adventar.org

ガシューと代表の松江翔輝自身を振り返る

こんちゃっす。 誕生日で調子乗ってたらアドカレさぼってしまいました。

17日に出す予定だった記事ですが本日、重なっての更新となります!

今回は今年の振り返りを諸々Twitterでのツイート内容より振り返っていこうかなと思います。

今年は1日から働いてました。 何をしていたかは覚えてないです。

2016年にGashooをβverとしてテストリリースして、そのデータを元に再設計し、サービスを開発しはじめていた頃だと思います。

僕が大切にしている事の1つです。 社会全体が許し合えるような環境があると人間は優しく生きられるのではないかと思いました。

西野さんが絵本をネットで無料公開したことにより賛否両論がありました。

今も本当にそう思っって生きています。 中学時代に受けていたテストで「あいつのせいだ。なんて批判しなかったですよね。」

このくらいの頃から出会う人の幅が広がって知見や視野が広がり始めた。

2月8日にクリエイター学生に対して選択肢を広げつ活動の一環で「Gashoo seeds」を立ち上げた。 現在は活動が水面下になっているが様々な形で学生も社会人も関係なくクリエイティブに生きている人たちの選択肢をこれからもどんどん広げていきます。

この時くらいに事務所の数を増やした。 そして高校生が事務所に遊びにきてくれた。 彼女は現在大学生で勉学に励んでいる。先日、ご飯も行ってきたが一年で思考が凄まじく変化していて若さとは最強の武器だと再認識しました。

弊社チーフデザインオフィサーの白石による技術講座。 来年はこういった教育活動も積極的に行っていきたい。

CRAZYの大阪支社二周年イベントにお伺いさせていただいた時のツイート

Gashooの目指している世界観。 今も変わらずこういう形をどういった手段で表現するのは株式会社ガシューに集まる人によって変わっていくだろう。チームメンバー募集しています。

大学院に入学した。

自分に保険をかけた生き方をしているといつかは自分を見失うぜ。っていう話。

この時、しれっとサービス開始してた。 まだまだ改良の余地がある中でのスタートダッシュをした。 それはユーザーコミュニケーションから生まれるサービス開発を行うためであると考えていたからです。

忘れてた。

柴犬の養殖場ってあるんですよ。

後にクリエイター異種格闘技戦というコンペ企画になった。

この気持ちは今でもいっしょ。

今は亡き、スコア機能 近々これに代わる機能を実装します。

コンペ開催した。 様々なデータが集まって何を解決していくべきなのか明確になった。

大学院で講義をさせていただいた。 いい刺激になった。

クライアントワークにおける難しい課題点 ヒアリング能力であったりとデザイナーには求められる技術が多岐にわたる。

そういうときもある。

こんな感じのことちょいちょい言ってる気がする。

クリエイター学生、社会人関わらず色んな人にあいたいです。

僕は大事だと思います。

友達のホテルオープンレセプションにも行ったり。

こんなのも作った。

思想が見え隠れする。

こんなスタンスです!

いい出会いに感謝

嬉しいです。いつもありがとうございます!

これいいですよ

クリエイターファースト

Gashooのデザイン一新しました。

周りに恵まれまくってると最上級に感じた時のツイート

Gashooの存在意義として僕達が伝えたい事です。

大阪芸術大学教授とのコラボプロジェクト こういった形でもいいから様々な形で情報発信を行う。

僕がいつも尊敬している人たちはだいたいこんな感じ。 歳が関係なくこういう人。

そして東京オフィスの立ち上げ、関西と関東の両軸でどんどんクリエイターの働き方、生き方の選択肢を広げられるように活動していきます。

これもまた生き方論の話ですね。

感謝は大事だと思います。言葉にする事はもっと大事かなと。

先日誕生日でした! ありがとうございました!!!

ていう感じでTwitterの投稿を一年振り返ってみました。

基本的にツイートしている内容は自分の生き方、思想からGashooでどういう活動をしているのかなどをつぶやいていました。

来年からは活動範囲が一気に広がるので更に面白い事ができそうです。

Railsをvimで書いてみよう!

GASHOO Inc. Advent Calendar 2017土曜日担当、19日目を飾ります、t-kusakabeです。 先週の土曜日は多忙のため記事をあげることが出来ずリスケして今です、頑張ります。

Railsvim

皆さん大好き宗教戦争です。 普段はエディタは何をお使いでしょうか? 弊社ではatomsublime textを使っている人がいる中僕だけvimでコードを書いています。(VSCodeがいないのは珍しいのかな?)(IDE臨機応変に使ってるよ!) よく「vimは勉強コストが高い」や「vimrc書くのが面倒」という理由からvimを避けている人を見かけます。 ただ僕はvimmer同士が集まったときに必ず繰り広げられる「自分が使っているvimの便利なプラグイン自慢」みたいなものに全く参加できません。 というくらい僕が使っているものはしれています。 ただコードを書くのには十分過ぎるので以外とvimの導入コストって高くないと感じいます。 今回はgashooのコードをvimで書けるようにしてみようと思います。 (gashooのコードを公開するわけじゃないよ)

構成

通常一つの.vimrcにいろいろ書いていくと思いますが僕は以下の様にディレクトリを分けています。

├── .vimrc
└── .vim
  ├── bundle
  ├── colors
  └── userautoload

なにはともあれ.vimrc

.vimrcには各種設定ファイルを読み紅葉にします。 (カラースキームだけ面倒くかったのでそのままです...mm)

runtime! userautoload/*.vim

" colorscheme
colorscheme antares

大きく二つに分ける

基本的に触るファイルはuserautoload以下のファイルです。

userautoload
├── basic.vim
├── neobudle.vim
└── statusline.vim

プラグインを使うのならneobundle.vim、使わないのならbasic.vimに書いていきます。

まずはプラグインなしから

" setting
set number
set title
set expandtab
set autoindent
set tabstop=2
set shiftwidth=2
set ignorecase
set smartcase
set wrapscan
set cursorline
set scrolloff=10
set confirm
set hidden
set nobackup
set noswapfile
set hlsearch
set incsearch
set ignorecase
set nowrapscan
set mouse=a
set wildmenu wildmode=list:longest,full
set fenc=utf-8
set laststatus=2
set ruler
set showcmd
set list
set listchars=trail:.
set clipboard+=unnamed
set clipboard=unnamedplus
set clipboard+=autoselect
set wildmenu
set history=1000
set backspace=indent,eol,start
syntax on
set syntax=markdown
set incsearch

autocmd QuickFixCmdPost *grep* cwindow

" escを
C>

" sキー封印
nnoremap s <Nop>

" window移動
nnoremap sj <C-w>j
nnoremap sk <C-w>k
nnoremap sl <C-w>l
nnoremap sh <C-w>h

" 論理移動
nnoremap j gj
nnoremap k gk
nnoremap gj j
nnoremap gk k

" window分割 shortcut key
nnoremap ss :<C-u>sp<CR>
nnoremap sv :<C-u>vs<CR>

" 新規tab shortcut key
nnoremap st :<C-u>tabnew<CR>

" 画面を閉じる
nnoremap sq :<C-u>q<CR>

" 検索結果を画面中央に
nmap n nzz
nmap N Nzz
nmap * *zz
nmap # #zz

" 強制保存
cnoremap w!! w !sudo tee > /dev/null %<CR> :e!<CR>

" htmlの閉じタグ補完
augroup MyXML
autocmd!
autocmd Filetype xml inoremap <buffer> </ </<C-x><C-o>
autocmd Filetype html inoremap <buffer> </ </<C-x><C-o>
autocmd Filetype eruby inoremap <buffer> </ </<C-x><C-o>
augroup END

" clipboardからのペースト時のインデント崩れの防止
if &term =~ "xterm"
let &t_SI .= "\e[?2004h"
let &t_EI .= "\e[?2004l"
let &pastetoggle = "\e[201~"

function XTermPasteBegin(ret)
set paste
return a:ret
endfunction

inoremap <special> <expr> <Esc>[200~ XTermPasteBegin("")
endif

Gashooのインデントはソフトタブ2つなためそれに合わせいます(ほんとは自分が好きなだけで変える必要がある時はちゃんとeditorconfig使ってます) また新型MBPに対応するためESCを押さなくて良い様に 'j' を2回押すとコマンドモードに切り替わるようにしています。 これが以外と便利で普段タイピングをするときに 'j' を2回連続で押すことは全くと言っていいほどないので入力は困らないです。 またESCを押すときにホームポジションが崩れてしまうのも防げるのでわりとお気に入りです。(実際はタッチバーなしを買った)

vimで分割

sをprefixにしています。 - s + s -> 水平分割 - s + v -> 垂直分割

  • s + (j k, h, l) -> ペインの移動

  • s + t -> 新規タブの作成

  • s + q -> 画面を閉じる

これだけでも他のエディタと似た様なことが出来るかと思います。

そしてプラグイン

昔ながらのneoBundleを使っています(モダンにして行きたいけど不便はないので移行する気があまり起きない。。。)

if has('vim_starting')
  set nocompatible

  " Required:
  set runtimepath+=~/.vim/bundle/neobundle.vim/
endif

" Required:
call neobundle#begin(expand('~/.vim/bundle/'))

" Let NeoBundle manage NeoBundle
" Required:
NeoBundleFetch 'Shougo/neobundle.vim'

" editorconfig
NeoBundle 'editorconfig/editorconfig-vim'

" vimのwindowサイズ調整
NeoBundle 'simeji/winresizer'
let g:winresizer_start_key = '<C-T>'

" vim上でgitの差分
NeoBundle 'airblade/vim-gitgutter'
" stauts line
NeoBundle 'itchyny/lightline.vim'

" NERDTreeを設定
NeoBundle 'scrooloose/nerdtree'
nnoremap <silent><C-e> :NERDTreeToggle<CR>
autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTree") && b:NERDTree.isTabTree()) | q | endif
map <C-l> gt
map <C-h> gT

" Unite.vim導入
NeoBundle 'Shougo/unite.vim'
" Unite.vim setting
" prefix keyの設定
nmap <Space> [unite]
" insertモードで起動
let g:unite_enable_start_insert=1
" 大文字小文字を区別しない
let g:unite_enable_ignore_case=1
let g:unite_enable_smart_case=1
" キーマップ
"スペースキーとaキーでカレントディレクトリを表示
nnoremap <silent> [unite]a :<C-u>UniteWithBufferDir -buffer-name=files file<CR>
"スペースキーとfキーでバッファと最近開いたファイル一覧を表示
nnoremap <silent> [unite]f :<C-u>Unite<Space>buffer file_mru<CR>
"新規ファイル作成
noremap :uff :<C-u>UniteWithBufferDir file file/new -buffer-name=file<CR>
" ESCキーを2回押すと終了する
au FileType unite nnoremap <silent> <buffer> <ESC><ESC> :q<CR>
au FileType unite inoremap <silent> <buffer> <ESC><ESC> <ESC>:q<CR>

" 括弧を自動で入れる
NeoBundle 'Townk/vim-autoclose'

" vim上でファイル名検索
NeoBundle "ctrlpvim/ctrlp.vim"
NeoBundle 'tacahiroy/ctrlp-funky'
let g:ctrlp_show_hidden = 0

" ファイル名検索にagを使う
NeoBundle 'rking/ag.vim'
if executable('ag')
  let g:ctrlp_use_caching=0
  let g:ctrlp_user_command='ag %s -i --hidden -g ""'
endif

" ag.vim
NeoBundle 'rking/ag.vim'

" plantuml
NeoBundle "aklt/plantuml-syntax"
let g:plantuml_executable_script = "~/.dotfile/plantuml"

" Railsのプラグイン
NeoBundle 'tpope/vim-rails'
" slimのsyntax
NeoBundle 'slim-template/vim-slim'

" Ruby向けにendを自動挿入してくれる
NeoBundle 'tpope/vim-endwise'

" カラースキーム
NeoBundle 'vim-scripts/twilight'

" なんかタグ強調してくれるやつ
NeoBundle 'valloric/matchtagalways'

" Reactのsyntax
NeoBundle 'pangloss/vim-javascript'
NeoBundle 'mxw/vim-jsx'

" Vueのsyntax
NeoBundle 'Shougo/context_filetype.vim'
NeoBundle 'osyo-manga/vim-precious'

autocmd BufNewFile,BufRead *.vue set filetype=html

" emmet-vim
NeoBundle 'mattn/emmet-vim'

" coffee-scriptのsyntax
NeoBundle 'kchmck/vim-coffee-script'

call neobundle#end()

" Required:
filetype plugin indent on

" If there are uninstalled bundles found on startup,
" this will conveniently prompt you to install them.
NeoBundleCheck

基本的にはSyntax系が多いです。 一部抜粋して。

  • airblade/vim-gitgutter -> vim上でgitの差分が見れる
  • scrooloose/nerdtree -> ディレクトリ構造を表示(ctrl + e)
  • Shougo/unite.vim -> pathを指定してファイルを開く(space + a)
  • ctrlpvim/ctrlp.vim -> ファイル名を指定して開く(上記はpathを辿らないといけないのに対してこちらは名前で開く(インクリメンタルサーチ)が出来る)

これだけ結構IDE的なことが出来ます。 ただIDEお得意の関数ジャンプがvimでは結構大変です。(ctagsとか使えばできる) これはサーチャー系を使って代替しています。

  • Highwaty
  • Platinum Searcher
  • The Silver Searcher

定義元に飛ぶだけより、どこで使われているのかなども把握出来るのでこちらの方が便利と言い聞かせています。 関数だけでなく単語なども検索出来るので便利ですね(cmd + shift + f相当)

ステータスライン

個人的にvimで大切なのは自分で設定をすることだと思っています。 よくvimrcくれと言われるのですが、自分で設定しないと何ができるのかわからなかったりするので結局vimを使わなくなったりします。 また自分で設定することで愛着も持てる気がします。 ということでステータスラインに関しては是非自分で設定してみてくださいw lightlineが良い感じになる気がします。 僕はステータスラインに未保存かどうか、現状のモード、書式、文字コード、行数、列数などを表示させています。 またrubocopなどのlintツールの結果を表示させたりしています。(これほんと便利)

まとめ

いかがでしたでしょうか。 僕は普段vim + tmux + zshを使って開発をしているのですが、vimだけでも十分便利に使えると思います。 「プログラマが知るべき97のこと」でも取り上げられていますが、IDEしか使ったことのない人は是非これを機にvimに挑戦していただけると幸いです。 エディタもバージョン管理も全て真っ黒な画面で行うのでちょっと知的になった気もしますねw