ラベル Vim の投稿を表示しています。 すべての投稿を表示
ラベル Vim の投稿を表示しています。 すべての投稿を表示

Vim x C言語で書くプロジェクトの良さと(私的)つらみについて

この記事は Vim Advent Calendar 2016 の16日目の記事です。
15日目の前日は shinespark氏の「Vimでtreeっぽくディレクトリ構成を書きたい、そんなアナタの為のVim Plugin、できてます。」でした。


この前の新Mac騒動でCtrl+]を初めて知った@MNukazawaです。
しかし相変わらずESCを連打しています。


追記 > 投稿してから文字サイズがおかしいことに気づいたのですが、ざっくり対処しておきますので、多少おかしくても勘弁いただければと思います。

まえがき


家でも仕事でも、C言語を書くときは(C言語を書くときに限らず)Vimを使っています。
ライトVimmerにとって、Vimは最高ですが、完璧ではないです。
C言語での開発とVimとの相性は最高ですが、光のあるところには影もあり、以下に書いてあるアレコレのつらみに、私は今も苦しんでいます。

今回挙げた中には、受け入れていかなければならないものや、いかにも井の中の蛙っぽい悩みも含まれており、解決策やベストプラクティスが無いはずがないと思えるものもあります。
「プラグイン忌避を克服しろ」「Vimの基本コマンドくらい覚えろ」等々、厳しくツッコミを入れて頂けると、正直とても嬉しいです。


私は現在、Vecterion(べくてりおん)という名前のベクターグラフィック・エディタを書いています。
今回のVim記事も、VecterionをVimで書いているときの話をするので、Vecterionのスペックをざっくり挙げておきます。
* GUIアプリケーション(ベクターグラフィック・エディタ)
* C言語/GTK3で書いている。
* googletest使用
* GNUMake(生Makefile)でビルド
* 中規模アプリケーション(1人で開発。アプリケーション本体のヘッダとソースが50個ずつ有る)

リリースはまだしていませんが、昨日もリリースブロッカを一つ潰したので、来年のどこかでは...。
Vecterionについては、Vimに関わらない C言語 Advent Calendar 2016 の12日目の記事「Cで書く中規模GUIアプリケーションから得た知見(初稿) 」でざっくり書いたので、よければどうぞ。





つらみ達

# ディレクトリ構成

中規模アプリケーションは、ヘッダとソースが別パスになる。
=== Vecterionのヘッダ一覧 ==
:~/etaion_vge$ ls include/
et_canvas.h             et_error.h             et_snap.h          pv_bezier.h           pv_io.h
et_canvas_collection.h  et_etaion.h            et_snap_panel.h    pv_cairo.h            pv_render_context.h
et_color_panel.h        et_key_action.h        et_state.h         pv_color.h            pv_render_option.h
et_define.h             et_layer_view.h        et_stroke_panel.h  pv_element.h          pv_renderer.h
et_doc.h                et_mouse_action.h      et_thumbnail.h     pv_element_general.h  pv_rotate.h
et_doc_history.h        et_mouse_cursor.h      et_tool_id.h       pv_element_info.h     pv_stroke.h
et_doc_history_hive.h   et_mouse_util.h        et_tool_info.h     pv_error.h            pv_svg_info.h
et_doc_id.h             et_pointing_manager.h  et_tool_panel.h    pv_file_format.h      pv_type.h
et_doc_manager.h        et_position_panel.h    pv_anchor_point.h  pv_focus.h            pv_vg.h
et_doc_relation.h       et_renderer.h          pv_appearance.h    pv_general.h

===


ソースは source/ 以下にある。

* ヘッダとソースを別パスにすると、Vimでソースヘッダ間の移動が面倒になる

imでソースヘッダ間の移動で有名な 
`:sp %<.h`
 が効かなくなるため、移動が面倒。
仕方なしにヘッダからソースへの移動は、目に付いた適当な関数を叩いて飛んでいる。
というか、ソースへのアクセスもとりあえずヘッダを開いてctagsでソースへ飛び、いつでもctagsのスタックでヘッダへ飛べるようにしておく、という運用をしている。

 * Vimに必須なctagsが絡むと、ディレクトリが深くなりタイプ量が増える

 ctagsは、tagsファイル生成と利用のために、vimのカレントディレクトリを、常にプロジェクトのソース先頭にしておかないと都合が悪い。
そうでなくても、ソースとヘッダの間を行き来することを考えると、Tab補完はあるものの、ディレクトリの分だけタイプ数が増えることを受け入れなければならない。

# 今どきな長めの名前で、インテリセンス無しで書く

 今どきの関数・変数名は、省略を避けるなど、なんとなく長い名前になりがち。
 長い名前をインテリセンス無しで書くのはつらい。
 (名前が長いこと自体は、自分が悪い気がしないでもないが。)
 Vimは最高のテキストエディタだが、最高のIDEであるとは限らない。

 ex. `>-------pv_anchor_point_set_handle(&dst_aps[2], PvAnchorPointIndex_HandlePrev, p1_handle_prev_dst);`

 インテリセンスのプラグインに決定打がない。ついでにVimプラグインはインストールがつらい。


# リファクタリング的な置換ができる命名

「リファクタリング」というほど格好良くなくても、開発していて名前を変えたくなることは多い。

 * Vimのリネームは1ファイル内のみ

プロジェクト内でファイルを跨いだ命名変更がしたいとき、Vimは無力。
 ヘッダ・ソース合わせて100ファイルを超えているので手作業は嫌。
 なので、
`sed -i 's/AA/BB/g' */*.[hc]`
を使っている。

 * sedでリネームしやすい名前を付けている(付けなければならない)

 つまり`sed`しやすい名前を付けなければならない。
 EtElement構造体のオブジェクトの変数は"element", "layer_element"などと名付ける。
リネームしずらいので、"elem"とか"e"とは付けない。
 (というか初期に一部のコードでそういった変数名を付けてしまったので、後で直さないと...)
 関数の引数を変更したいとき、引数に折り返しがあるとsedできなくてつらい。(これはIDEでも難しいだろうけれど)

ファイルの"path"(filepath)と被るのが怖くて、アンカーポイントで構成される線分"path"(ahchorpath)と名づけるのを避けて、変な名前を付けたりしていた。

# ctagsでstatic関数定義へ飛ぶとき

中規模以上のC言語プロジェクトでは、ファイルローカルなstatic関数を定義する。
そしてコーディングルールによったり、その他の都合で、ソースの先頭近くでファイルローカルstatic関数の定義をすることになる。
そしてVimを使うならば、ctagsで関数間をジャンプする。

 * ctagsは最初の候補としてstatic関数の宣言へ飛ぶが、私は定義を見たい

いつもCtrl+]とCtrl+Tを使っている。Vimのタグジャンプ自体はとても便利で多用するので、いつも常に:tsと打って候補一覧を見てから数字キーで飛び先を指定する、なんてことはしたくない。

 * そもそも開発中に関数を追加しながら毎度`:!ctags -R`するのがつらい。

コミット前のコードは、書きかけの関数が消えたり、名前が変わったりが頻繁に起こる。
`ctags -R`を何度か打つことになる。が、ディレクトリに複数のソースファイルを抱えたプロジェクトで、再帰的にソースを探索させるとctagsも2~3秒かかることもある。(いま以上に大きくなったらどうなるか不安)

# インデント整形(gg=G)にコーディング規約を合わせる

 * Vimはデフォルトでインデント整形できる機能が用意されているのがすばらしい

 しかし完璧ではないので、以下のような考慮すべき点がある。

## switch case{}とLinuxコーディング規約の衝突

Linuxコーディング規約よりインデントが1段深い。
8tabを使っていると8文字分の横幅を使われる。
他の開発者に触ってもらうなどを考えると、Vimのデフォルトから.vimrcで変えたくなかった。
一人で開発しているだけなら、そのうち慣れたので大きな問題でもない。

## extern C{} (c++対応)

* extern C{}がVimの自動インデントで引っかかる。ヘッダ全体にインデントが一段かかってしまう。

 googletestでテストを書こうとするとこれに悩む。
 googletest側でextern C{}することで解決。
 CヘッダがC++に考慮するのが間違いと思うことにする。
 せいぜいC++テストコード内のinclude行だけの問題になる。




以上です。



あとがき

今更ですが、「つらみ」ってこういう使い方で良かったのでしょうかね?

もうそろそろ「ライトVimmerの世界 - 驚きのプラグイン無し生活 -」みたいな記事を書いたほうが良い気がしています。
それよりVimコマンドを覚えたほうが有意義そうですが。

水の中の魚は水のことを意識することがありません。Vimを使ってC言語でコードを書いていると、ctagsの有り難みをつい忘れてしまいがちです(Windows上のAtomでソースを開いたときに思い出す)。
それは必ずしも悪いことではないのだと思います。が、快適なVimコーディングも、使い続けていると細かいところでつらみが意識されるようになるのも、自然なことで、だからこそ先達たちは多用なVimプラグインを生み出してきたのかもしれません。


この記事は Vim Advent Calendar 2016 の16日目の記事でした。
17日目の明日はanekos氏の「Vim の下着の話」です。

Ubuntu14.04にJSLint.vim(またはJSHint.vim)を導入する


個人プロジェクトのために、JavaScript開発環境の構築をはじめました。
まずは、JavaScriptのコードチェックを行うjslint.vimを導入します。
jslint.vimによる強調表示

JSLintの導入は決定したものの、JSLintのWebサイト版を使うにはコードをコピペしなければなりませんし、コマンドライン版もコマンドを叩く一手間がかかります。
現代的なIDEのように、書いた直後から動的に構文チェックしてもらいたいところです。
そこでjslint.vimを導入することにしました。


jslint.vimの導入


jslint.vimを取得します。
git clone https://github.com/hallettj/jslint.vim.git

ブラウザ外部のJavaScript実行環境として、node.jsをインストールします。
sudo apt-get install nodejs -y

jslint.vimのインストールに必要となるrakeツールをインストールします。
sudo apt-get install rake -y

jslint.vimのリポジトリ内に移動して、rake installを実行します。
cd jslint.vim/
rake install

あとは適当な.jsファイルをvimで開くだけです。
jslimt.vimは、デフォルトで自動的にJSLintによるチェックが行われ、ヒントが表示されるようになっています。

 jshint.vimの導入

リポジトリは
https://github.com/wookiehangover/jshint.vim
を使用しました。
導入手順もgithubリポジトリのページに書いてある通りにします。
このリポジトリからjshint.vimを導入するには、Bundleを使うのが簡単です。


Bundleが導入されていない方は、以下の手順でBundleを導入します。

Vimに、Vundleを使ってBundleを導入します。
手順はVandleリポジトリのページに書かれています。

https://github.com/gmarik/Vundle.vim

Vundleのソースリポジトリを入手します。
git clone https://github.com/gmarik/vundle.git ~/.vim/bundle/vundle

Vandleリポジトリのページに書かれている設定を ~/.vimrc に書き込みます。

vimを立ち上げて、Vim中でコマンドを入力してプラグインをインストールします。
vim
:PluginInstall

Vundleは、インストール中にエラーが出ますが、とりあえず大丈夫かと思われます。
リポジトリ管理者の個人にとって使いやすい固定パスが書き込まれているだけで、別段害はないか、
あるいは単にこのコミットにだけ含まれていて、後日修正されるのでしょう。
Vundleのインストール進行表示
Vim内で、
:h vundle
にてヘルプが出ることを確認して、Vundleのインストール確認に代えます。


Bundleが導入されている環境で、jshintを導入するために、~/.vimrc に以下の行を書き足します。
Bundle "wookiehangover/jshint.vim"

Vimを起動し、 以下のコマンドにてjshintを導入します。
:so ~/.vimrc
:BundleInstall

ただし、このままでは"node コマンドが無い(意訳)"というエラーが出るので、
sudo apt-get install nodejs-legacy -y
を導入して対応します。

Vimで適当な.jsファイルを開けば、自動的に構文チェックが行われます。

jshint.vimによる強調表示

 雑感

jslint.vim/jshint.vim はフォークされたバージョンがいくつかあるようです。選ぶだけでも一苦労。
導入方法も、対象のリポジトリや解説しているブログによって異なるため、ちょっと迷います。
jslint.vimのリポジトリは https://github.com/basyura/jslint.vim を使ったほうがよいという意見をあちこちで見かけましたが、今回はとりあえず本家版を使うようにしました。


jslintとjshintの違いとして、ソースの中ほどに書かれた文字列連結への警告表示が、jshintでは表示されたのですが、jslintでは表示されていませんでした。
警告の方針が違うのか、あるいはjslintはソース中に警告箇所を発見すると、そこから下のチェックを行わないのかもしれません。
(あるいは、リポジトリごとの設定の違いによるものかもしれません。)
とりあえず、このあたりはこれから使ってみればわかるものかと思います。

jslint.vimもjshint.vimも、デフォルトのシンタックスカラーでは、文字列が警告に塗りつぶされて読めなくなるようです。

JSLintを導入することにした理由は、以前にCoders at Work プログラミングの技をめぐる探求で、製作者であるダグラス・クロックフォード氏へのインタビューを読んでいたからです。

とはいえJSLint から JSHint をフォークした理由(翻訳)という議論もあるようですので、開発中に無理がでるようなら、チェックが現実的で緩いとされるJSHintに切り替えようと思っています。

閑話休題。


次は、VimにJavaScriptのシンタックスハイライトを導入する予定です。

English digest of the my blog posts 2013 dec to oct

I writen blog to software topics. Main theme is ubuntu and other.
Write japanese.
This page is English digest.
2013/12~10

POST from the fancyBox Form

 and Sample source.

fancyBox dialog sample message form


Ubuntu setting Suspend shortcut key

Release auto setting script. it in github. in add_shortcut.sh.

Shortcut key setting menu gui.


Ubuntu snap to impossible capture screen shots (configure timer shot)

Release auto setting script. it in github.in add_shortcut.sh.
Impossible screen shots is :
Canceling PrintScreen key apps. (example: calender widget)
Disappear window view because of send keys. (example: Menu bar).

Impossible shot (Ubuntu calender widget)


Ubuntu version shift 13.10 to 12.04

I shift to Ubuntu older version.
Failure to can't move user data.
Use of the package for newer Ubuntu.( not better technique)

This is danger technique. Example :  Ubuntu is broken.
Target package or there dependencies (search to depend package to use synaptic package manager).
Ubuntu packages page( or google search)
Keyword [ package_name ubuntu_version Ubuntu packages ] etc.
Download and install to .deb package.

Failure Liferea open browser and resolution setting


Liferea setting menu select browse

Failure Compress Big Zip file Error

Big zip archive (2GB over) Ubuntu 12.04, thereupon unpacking error for windows7.
Use of the zip archiving library package for newer Ubuntu.( not better technique)
Ubuntu12.04 "zip" package is 3.0-4.
Shift to zip 3.0-7(from Ubuntu 13.04) package


Package Dependencies


Pixel 7aを買ったので自分が購入前に読みたかったレビューを自分で書いてみる

カメラ性能がどうとかスペック比較がどうとか、そういう一変通りな評価ブログ記事ははっきり役に立たないので、本当のスマホ端末の評価ブログ記事というものはこう書くのだという記事を自分で書いた。 スマホ端末レビュー記事で一番大事なのはちゃんと筆者の自分語りがされていること。なぜならスマホ...