TabSideBarの進捗旅 at 土善旅館

11月23日から26日にかけて三泊四日のVimmer7人で開発合宿を行った。

f:id:rbtnn:20171126234738j:plain

土善旅館での食事とか様子とかは他のVimmerのブログを見てもらうとして、私はやったことをつらつら書きます。

1日目

今回の目標は、WindowsにてTabSideBarの描写がおかしくなるのを修正するというのが一応目標だった。いつもはMacBookAirでもくもく会などに参加しているが、今回はSurfacePro4のWindowsでの参戦。

Windowsの描写まわりが壊滅状態 · Issue #3 · rbtnn/vim · GitHub

描写がおかしくなる現象は以下の通り。スクロールしようとすると、TabSideBar分のスクロール位置がずれる。

f:id:rbtnn:20171127000601g:plain

この現象はMacのTerminal上では発生せず、Windowsでのみ発生するのでずっとTabSideBarの進捗は滞っていた。 1日目はVimの描写回りがコーディングしてあるscreen.cとにらめっこしてあっけなく1日目が終了。この日はなにもわからず、進捗0%... orz

2日目

2日目もscreen.cとにらめっこし途方に暮れていた。2日目も終わろうとしていたころ(23時くらい?)、「scroll_region_set関数のリージョンってなんだ?」とふと思い、調べてみたところ、term.cに定義してあり、とある条件下の時だけ、このscroll_region_set関数で描写を行っているっぽい。で、この関数を調べてみたらTabSideBarの対応が全くされていなく、対応したら、あっさりWindowsでのTabSideBarの描写が直った。2日目が終了してもう個人的には進捗100%状態w。

f:id:rbtnn:20171127003151g:plain

3日目

3日目はコマンドラインでCtrl-dしてtabキーを押すとwildmenuの描写位置がおかしい問題。

コマンドラインでCtrl-dしてtabキーで表示がおかしい · Issue #6 · rbtnn/vim · GitHub

f:id:rbtnn:20171127004056p:plain

まぁこれは、コマンドラインでCtrl-dしてtabキーを押した時もTabSideBarの幅が考慮されたまま描写されていて、比較的簡単だった。wild_menu_showingという変数がwildmenuの表示状態を保持していて、wildmenuが表示中はTabSideBarの幅を0にしてあっけなく完了。

f:id:rbtnn:20171127004615p:plain

次にマウス対応。この時のTabSideBarは全くマウス対応してない状態。

マウス対応(%T) · Issue #4 · rbtnn/vim · GitHub

で、マウスのイベントはVimのどこで処理しているかと探しているとnormal.cのdo_mouse関数でかなりわかりやすいコードでtablineのマウスクリックイベントが処理されている。screen.cとはUI周りの座標計算ばっかなので全く読みやすくない! tablineのマウスクリックイベント処理をそのままパクって多分TabSideBarのマウスイベントも実装完了。3日目終了。 ただ、TabSideBarにおいて%T%Xはどうするか?という問題は残ったまま保留。

f:id:rbtnn:20171127005513g:plain

4日目

TabSideBarのテストを書くかーと思ったが、Vim本体のテスト実行するmakeのパラメータを忘れている。 なので、めんどくさいことはとりあえずVim scriptで書き書き....

GitHub - rbtnn/vim-runtest

runtest.vimを実行するだけのコマンドが定義してあるVimプラグインを作成して、

:RunTest test_alot.vim

ステーキを食べて4日目終了。

f:id:rbtnn:20171127010511j:plain

個人的には進捗が出た4日間でした。よかったよかった。

Raspberry Pi3 Model BとRaspberryPI用3.5inchタッチ液晶(LCD)のセットアップ

Raspberry Pi3 Model Bを購入したついでにタッチ液晶(LCD)も購入したのですが、 ちょっと設定に苦戦したのブログに残しておきます。

f:id:rbtnn:20170204235008j:plain

買ったもの

やり方

1) イメージダウンロード

まず、Raspberry Piの公式ページからRaspbianのイメージをダウンロードします。 ここで気をつけたいのがNOOBSじゃなくてRaspbianのイメージを使うことです。 現時点(2017年2月4日)では、NOOBSだとタッチ液晶(LCD)のパッチの相性が悪くてうまく動かず、Raspbianだとうまく動きました。

f:id:rbtnn:20170205001031p:plain

ダウンロードしたファイル(2017-01-11-raspbian-jessie.zip)を解凍します。ダウンロードページに書いてある通り7ZipThe Unarchiverで解凍するのが楽でした。


2) SDカードに書き込み

SDカードをフォーマットし、ddコマンドでイメージを書き込みます。

f:id:rbtnn:20170205003544p:plain

※ dfコマンドでは「/dev/disk2s2」になっていますが、ddコマンドで書き込むときは「/dev/rdisk2」にします(先頭にrを付け、末尾のs2を取り除く)。


3) Raspberry Pi起動

USBキーボード、USBマウス、SDカード、有線LANケーブル、HDMIケーブルをRaspberry Piに繋ぎ、最後にMicro-USBケーブルを繋ぎます。 SDカードに正しくイメージが書き込まれていれば、Micro-USBケーブルを繋ぐだけで勝手に起動してくれます。 LANが有線であれば特に設定を行うことなく、インターネットに接続できるはずです。

f:id:rbtnn:20170205005715j:plain


4) LCDのパッチを当てる

Raspberry Pi上でTerminalを起動し、以下のコマンドを順に実行します。

$ sudo raspi-config
$ wget http://www.waveshare.com/w/upload/4/4b/LCD-show-161112.tar.gz
$ tar zxf LCD-show-161112.tar.gz
$ cd ./LCD-show
$ ./LCD35-show

sudo raspi-configの際は、

  1. 「Expand Filesystem」を選択
  2. 「Boot Option」を選択して「Desktop Autologin」を選択

を行います。

そして、Raspberry Piにタッチ液晶を接続し、再起動して完了です。

f:id:rbtnn:20170204235024j:plain

ちなみに、3.5inchのタッチ液晶に対してLCD32-showを実行してしまうと再起動後Raspberry Piの起動が失敗します。 LCD??-showのコマンドはくれぐれも間違わないように!

参考にしたもの

Vimconf 2016に参加した。

Vimconf2016に参加してきました。 本編は午後からなんだけど、一応スタッフということもあって午前中から会場入りした。

http://vimconf.vim-jp.org/2016/

http://vim-jp.org/blog/2016/10/31/announce-vimconf2016-before-event.html

発表者の各内容は公式サイトにあるので省きますが、参加して思ったことなどをいくつか。

  • vim-mode-plus for Atom editor」はt9mdさんのVimに対する理解度がやばかった。この発表、「テキストオブジェクト」や 「モーション」などのVim専門用語がバンバン使って話されていて、「これ理解して聴いている人、この中の何割くらいだ?」って思うほど濃かった。
  • koronさんは「Vimの日本語ドキュメント」について発表していたけど、backspacefm vim-sideの次のネタなんじゃ?って思っていながら聴いていたw。次のbackspacefm vim-side #3も同じネタ話すんかな?日本語入力だったけ?

http://backspace.fm/

  • Go関連の話が多かった。
  • koronさん提供のVimリストバンド。 f:id:rbtnn:20161106180641j:plain

  • 技術イベントでおなじみの寿司🍣 とピザ🍕。今回は綺麗に食べきれた。ジュースは1.5Lのが8本前後余ったけど。 f:id:rbtnn:20161106180638j:plain

  • 私作成の名札。前年度と比べるとちょっと品質向上した。 f:id:rbtnn:20161106180634j:plain

  • 発表者のスライドの文字サイズが小さい問題。Vimconf2015のujmさんのスライドの文字サイズくらいがよさそう、今後の参考にしたい。

docs.google.com

  • セキココと会場のイスレイアウトの相性の悪さ。
  • カメラ提供、vikkeさんありがとうございました。
  • b4b4r07さんのアイコンと実際の本人とのギャップ。
  • AP回復アイテム(座布団とか)が必要。

以上、お疲れ様でした。

ファイルに保存されたマクロを動的にロードする方法(Excel VBA)

以下のコードでファイルに保存されたマクロを動的にロード出来ます。 ちょっとめんどくさいのは、デフォルト設定のExcelでは「プログラミングによる Visual Basic プロジェクトへのアクセスは信頼性に欠けます」の実行時エラーになってしまい、実行できません。 なので、「マクロの設定」の「VBA プロジェクトオブジェクトモデルへのアクセスを信頼する」をチェックしないといけません。

f:id:rbtnn:20161002013544p:plain

ThisWorkbookシート

Option Explicit

' ---------------------------------------------
' ファイルに保存されたマクロを動的にロードする。
' ---------------------------------------------

Private Sub Workbook_Open()
    Call ClearModules
    Call ImportModule(ThisWorkbook.Path & "\ModMain.bas")
End Sub

Private Sub Workbook_Close()
    Call ClearModules
End Sub

Private Sub ImportModule(ByVal strFilePath As String)
    Dim objFS As Object
    Set objFS = CreateObject("Scripting.FileSystemObject")
    If objFS.FileExists(strFilePath) Then
        ThisWorkbook.VBProject.VBComponents.Import strFilePath
    Else
        Call MsgBox("モジュールが存在しません。" & vbCrLf & strFilePath)
    End If
    Set objFS = Nothing
End Sub

Private Sub ClearModules()
    Dim varComponent As Variant
    For Each varComponent In ThisWorkbook.VBProject.VBComponents
        If varComponent.Type = 1 Then
            ThisWorkbook.VBProject.VBComponents.Remove varComponent
        End If
    Next
End Sub

' 【Excel】実行エラー「プログラミングによる Visual Basic プロジェクトへのアクセスは信頼性に欠けます」の対策
' http://saku-saku-pc.com/excel/プログラミングによるアクセス/

Microsoft Visual Studio 14.0でVimをビルドする。

今までMacBook AirのTerminal上でvimをビルドするか、もしくはWindowsMinGWでビルドしていました。 今回、Microsoft Visual Studio 14.0でビルドをしてみました。 で、ビルドしてみたけど結構はまりどころがあったのでここに適当にまとめます。

まず、最終的にできた私のビルドスクリプトを載せておきます。

vimbuild.bat

@echo off

set PATH=%SystemRoot%
set PATH=%PATH%;%SystemRoot%\System32
set PATH=%PATH%;%SystemRoot%\System32\Wbem
set PATH=%PATH%;C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin

set INCLUDE=
set LIBPATH=

call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\vcvars32.bat"

set OPT1= IME=yes MBYTE=yes ICONV=yes CSCOPE=yes NETBEANS=no
set OPT2= PLATFORM=x86 SDK_INCLUDE_DIR="C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Include" XPM=no

pushd .\vim\src
nmake -f Make_mvc.mak %OPT1% %OPT2% GUI=no clean
nmake -f Make_mvc.mak %OPT1% %OPT2% GUI=yes clean
nmake -f Make_mvc.mak %OPT1% %OPT2% GUI=no
nmake -f Make_mvc.mak %OPT1% %OPT2% GUI=yes
popd

はまりどころ

Microsoft Visual Studio 14.0でVimをビルドする上で注意した方がいいオプションが以下になります。

INCLUDE, LIBPATH

これは直接的にはVimに関係ないけど、vcvars32.batINCLUDELIBPATHにどんどん値を追加していくようになっていて、 vcvars32.batを20回くらい呼ぶと限界を超え、以下のエラーになります。

入力行が長すぎます。
コマンドの構文が誤っています。

なので、vcvars32.batを呼ぶ前に初期化しておくとよいです。

set INCLUDE=
set LIBPATH=

call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\vcvars32.bat"

PLATFORM

私のビルド環境がPLATFORM=MCDだったのですが、Make_mvc.makはMCDのプラットフォームに対応してないっぽいので 以下のエラーになってしまいました。

Microsoft(R) Program Maintenance Utility Version 14.00.23918.0
Copyright (C) Microsoft Corporation.  All rights reserved.

Make_mvc.mak(228) : fatal error U1050: *** ERROR Unknown target platform "MCD". Make aborted.
Stop.

なので、私は対応しているPLATFORM=x86にして対処してみました。

PLATFORM=x86

SDK_INCLUDE_DIR

ビルドにはWin32.makを必要らしく、SDK_INCLUDE_DIRを設定していないと以下のエラーになってしまいます。

Microsoft(R) Program Maintenance Utility Version 14.00.23918.0
Copyright (C) Microsoft Corporation.  All rights reserved.

Make_mvc.mak(254) : fatal error U1052: ファイル 'Win32.mak' が見つかりません。
Stop.

なので、SDK_INCLUDE_DIRWin32.makがあるフォルダを指定します。

SDK_INCLUDE_DIR="C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Include"

XPM

Vimはpre-compiledなXPMがレポジトリに含まれていて、それがLIBC.libにリンクしているみたいです。

最近のMicrosoft Visual StudioはLIBC.libを含んでいないため、以下のようなエラーが出てしまいます。

link /RELEASE /nologo /subsystem:windows /LTCG:STATUS -out:gvim.exe .\ObjGi386\blowfish.obj  .\ObjGi386\buffer.obj
.\ObjGi386\charset.obj  .\ObjGi386\crypt.obj  .\ObjGi386\crypt_zip.obj  .\ObjGi386\diff.obj  .\ObjGi386\digraph.obj
.\ObjGi386\edit.obj  .\ObjGi386\eval.obj  .\ObjGi386\ex_cmds.obj  .\ObjGi386\ex_cmds2.obj  .\ObjGi386\ex_docmd.obj
.\ObjGi386\ex_eval.obj  .\ObjGi386\ex_getln.obj  .\ObjGi386\fileio.obj  .\ObjGi386\fold.obj  .\ObjGi386\getchar.obj
.\ObjGi386\hardcopy.obj  .\ObjGi386\hashtab.obj  .\ObjGi386\json.obj  .\ObjGi386\main.obj  .\ObjGi386\mark.obj
.\ObjGi386\mbyte.obj  .\ObjGi386\memfile.obj  .\ObjGi386\memline.obj  .\ObjGi386\menu.obj  .\ObjGi386\message.obj
.\ObjGi386\misc1.obj  .\ObjGi386\misc2.obj  .\ObjGi386\move.obj  .\ObjGi386\normal.obj  .\ObjGi386\ops.obj  .\ObjGi386\option.obj
.\ObjGi386\os_mswin.obj  .\ObjGi386\winclip.obj  .\ObjGi386\os_win32.obj  .\ObjGi386\pathdef.obj  .\ObjGi386\popupmnu.obj
.\ObjGi386\quickfix.obj  .\ObjGi386\regexp.obj  .\ObjGi386\screen.obj  .\ObjGi386\search.obj  .\ObjGi386\sha256.obj
.\ObjGi386\spell.obj  .\ObjGi386\syntax.obj  .\ObjGi386\tag.obj  .\ObjGi386\term.obj  .\ObjGi386\ui.obj  .\ObjGi386\undo.obj
.\ObjGi386\window.obj  .\ObjGi386\vim.res .\ObjGi386\gui.obj  .\ObjGi386\gui_beval.obj  .\ObjGi386\gui_w32.obj  .\ObjGi386\os_w32exe.obj
.\ObjGi386/if_cscope.obj  .\ObjGi386/channel.obj  .\ObjGi386/xpm_w32.obj .\ObjGi386\version.obj oldnames.lib kernel32.lib advapi32.lib
shell32.lib gdi32.lib  comdlg32.lib ole32.lib uuid.lib /machine:i386 gdi32.lib version.lib   winspool.lib comctl32.lib advapi32.lib
shell32.lib  /machine:i386  libcmt.lib  user32.lib          WSock32.lib xpm\x86\lib\libXpm.lib /PDB:gvim.pdb -debug
LINK : fatal error LNK1104: ファイル 'LIBC.lib' を開くことができません。
NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\link.EXE"' : リターン コード '0x450'
Stop.

なので、XPM=noにして対処しました。

環境

vimrc読書会のためのプラグインを書いた。

これはVim script Advent Calendar 2015の6日目の記事です。

vimrc読書会

毎週土曜日の23時からLingr vim-jpというページでVimの.vimrcをみんなで読むという活動をしています。詳しくは以下のページを参照してください。

http://vim-jp.org/reading-vimrc/

vim-next-reading-vimrc

この集まりに参加しているとその.vimrcをダウンロードしてきてVimで開くという単純作業がめんどうになってきました。 なので、Vimで対象の.vimrcを自動でダウンロードして開いてくれるVimコマンドがあったら便利だなと思ったので作ってみました。

github.com

dart:core Stringの関数について

dart:core Stringの関数について

ここに書いてある関数について適当に日本語化&例を載せてまとめます。

https://api.dartlang.org/1.13.0/dart-core/String-class.html

まとめるほどでもないけど、単純にどんな言語でも文字列操作大事だし、まぁ単純にアウトプットしたいだけです。 あと、Iterableをリストと表記したりかなり雑です。

コンストラクタ

String.fromCharCode(int charCode) factory

数値から文字列を生成する。

main(){
  var c = new String.fromCharCode(0x41);
  print(c);
  // A
}

String.fromCharCodes(Iterable<int> charCodes, [int start = 0, int end]) factory

数値のリストから文字列を生成する。このリストの始まりと終わりを指定することも可能。

main(){
  var ns = [0x41, 0x42, 0x43, 0x44];
  print(new String.fromCharCodes(ns));
  // ABCD
  print(new String.fromCharCodes(ns, 1));
  // BCD
  print(new String.fromCharCodes(ns, 1, 2));
  // B
}

String.fromEnvironment(String name, {String defaultValue}) factory

pub build時に--defineで定義した値を取得する。

main(){
  // `pub build --define releasemode=true`の場合

  print(const String.fromEnvironment('releasemode'));
  // true
}

プロパティ

codeUnits -> List<int> read-only

文字列からUTF-16のコードの変更不可なリストを返す。

main(){
  var xs = 'hi'.codeUnits;
  print(xs);
  // [104, 105]

  // エラー!
  // xs[0] = 0x41;
}

hashCode -> int read-only

文字列のハッシュ値を返す。

main(){
  var hash = 'hi'.hashCode;
  print(hash);
  // 793667904
}

isEmpty -> bool read-only

空文字列ならtrueを返す。

main(){
  print('hoge'.isEmpty);
  // false
  print(''.isEmpty);
  // true
  print('   '.isEmpty);
  // false
}

isNotEmpty -> bool read-only

空文字列でないならtrueを返す。

main(){
  print('hoge'.isNotEmpty);
  // true
  print(''.isNotEmpty);
  // false
  print('   '.isNotEmpty);
  // true
}

length -> int read-only

文字列の長さを返す。

main(){
  print('hoge'.length);
  // 4
  print(''.length);
  // 0
}

runes -> Runes read-only

文字列のUnicodeコードのイテレータを返す。

main(){
  print('hoge'.runes);
  // (104, 111, 103, 101)

  for(var c in 'hoge'.runes){
    print(c);
  }
  // 104
  // 111
  // 103
  // 101
}

runtimeType -> Type read-only, inherited

型名を返す。

class A{}
main(){
  var a = new A();
  print(a.runtimeType);
  // A
  print('hoge'.runtimeType);
  // String
}

オペレータ

operator *(int times) -> String

文字列をtimes回繰り返した文字列を返す。

main(){
  print('abc' * 2);
  // abcabc
}

operator +(String other) -> String

文字列同士を結合する。

main(){
  print('abc' + 'def');
  // abcdef
}

operator ==(Object other) -> bool

文字列が同じであるか判定する。

main(){
  var a = 'abc';
  var b = 'abc';
  var c = 'def';
  print(a == b);
  // true
  print(a == c);
  // false
  print(b == c);
  // false
}

operator [](int index) -> String

文字列のindex番目の文字を取得する。(0オリジン)

main(){
  var str = 'abc';
  print(str[0]);
  // a
  print(str[2]);
  // c
}

メソッド

あとで書く。