How to use Vital.Async.Promise

Couple months ago, on the new year’s day 2018-01-01, Dog a.k.a. linda_pp or rhysd created a vital.vim module Async.Promise.

INTRODUCTION Vital.Async.Promise-introduction

Vital.Async.Promise is a library to represent the eventual completion or
failure of an asynchronous operation. APIs are aligned to ES6 Promise. If you
already know them, you can start to use this library easily.

Instead of callbacks, Promise provides:

  • a guarantee that all operations are asynchronous. Functions given to .then()
    method or .catch() method is executed on next tick (or later) using
  • chaining asynchronous operations. Chained operation’s order is sequentially
    run and the order is guaranteed.
  • persistent error handling using .catch() method. Please be careful of
    floating Promise. All Promise should have .catch() call not to squash an
  • flow control such as awaiting all Promise objects completed or selecting
    the fastest one of Promises objects.

If you know the detail of APIs, documents for ES6 Promise at Mozilla Developer
Network and ECMA-262 specs would be great.

Mozilla Developer Network:


As the introduction mentioned, it is an ES6 Promise compatible interface for Vim scripts. You can use it as a fully controllable abstract layer on lowest layer Vim functions job_start/timer_start or vimproc.vim for your plugin developments.

Trivial example: echo message after a while

Let’s implement something like this without blocking Vim.

sleep 5 " This is blocking. We don't want to use `:sleep`
echo 'it has been 5 seconds'

Back then we don’t have timer_start Vim script function, we had to register events such as CursorHold or CursorHoldI to check what time is it and compare with a base you prepared.

Now we have Vim native function timer_start(), so let’s use it first without vital.

function! s:my_echo(timer_id) abort
echo 'it has been 5 seconds'

echo timer_start(5000, function('s:my_echo'))

It works. When you evaluate them your Vim won’t block you; you can do anything. And after 5 seconds you get the message shown.

You can shorten that with using Vim8 lambda. The below and the above are conceptually same.

echo timer_start(5000, {_ ->
\ execute('echo "it has been 5 seconds"', '')

Let’s use Vital.Async.Promise this time.

let s:P = vital#vital#import('Async.Promise')

call{resolve -> timer_start(5000, resolve)})
\ execute('echo "it has been 5 seconds"', '')

They look quite similar so far.

Let’s continue into a little bit more complicated example.

Example: fault tolerant chained operations with job_start/channel

Coming soon…


Talked at RubyKaigi 2017

I gave a lightning talk at RubyKaigi 2017 as How to develop CRuby easily with Vim.

My talk and its slides

I was so nervous there.

A RubyKaigi staff personally took that videos of me presenting. I’ll replace them with RubyKaigi official videos on youtube once it’s available.

I used Google Slides and showtime.vim for projector to use, and focused mostly on live demo with GVim on my Gentoo Linux.

The final page has some links for the tools I used there.

FYI I collected tweets with #rubykaigi hashtag during my talk.
(Mostly in Japanese)

Additional notes for my talk

  • The 2 games I played at the beginning
    • mario.vim, made by rbtnn with his own game_engine.vim
      • It generates the stage randomly, so you can play forever.
      • I personally play puyo.vim occasionally for fun sometimes.
    • vim-game-code-break
      • Block-breaking game, but the blocks are made with text in the current buffer.
      • (I was too nervous to set this up properly. Audiences couldn’t see the buffer text..)
  • is a handy config for CRuby development
    • Note that it needs you to set its own filetype=cruby instead of filetype=c
    • Follow the README for that
    • This allows syntax completions (e.g. RUBY_DATA_FUNC, NUM2SSIZET, StringValuePtr) based on its syntax keywords
    • These keywords are manually added by mrkn.
  • Jump from Ruby code to CRuby implementation (like ctags for Ruby to Ruby and C to C)
    • Many ways are possible but no clean nice ways available yet
    • Maybe a good idea just to use regexp with ctags or something like that
    • I myself want the ujihisa/cruby-defs.vim mentioned in the slides so I may make it later
  • quicklearn.vim to see RubyVM::ISeq on the fly
    • I think I have written an article for that in 2012
    • I found it (Japanese)
    • The main focus of this Vim plugin was to visualize assembly code from C, and YARV ISeq was just a byproduct at the time.
      • e.g. gcc32, gcc32 with optimization, gcc64, gcc64 with optimization, llvm ir, and llvm ir with optimization
    • Good thing is that you can use quicklearn.vim effectively to learn what the final keynote by vlad was that. It mentioned about optimization in the internal representation layer.
  • I was happy that @shioyama mentioned that my talk was good!


I was moved by the fact that llvm opt could optimize my slow inefficient fib function written in brainf**k that compiled to llvm ir by my compiler to an immediate value. It must be beyond awesome when it works with one of the complex languages such as Ruby

a thing that I couldn’t make it during 5 min lightning talk

I fast-forwarded at the end of lightning talk but I didn’t have enough time advertising Fablic, inc where I currently work at.

Personal notes

I have given talks at RubyKaigi twice and RubyConf once in the past. I have experienced a quick and not-really-prepared lightning talk at RubyConf 2009 as well, but not at the very serious and time-restricted RubyKaigi; it was the first time for me. I was so nervous.

The RubyKaigi 2017 this year was really amazing. It didn’t only have great talks, but also helped me seeing lots of friends I haven’t seen for long time. Great also for meeting somebody new.

Thanks again to the organizers of RubyKaigi 2017 including Akira Matsuda, all the staffs and sponsors, and speakers. You are awesome.
I can say with confident that RubyKaigi 2017 was a great success.

Next steps for myself

  • VimConf 2017 in Nov
  • RubyConf 2017 in Nov

Heading to RubyKaigi 2017

I’ll be attending RubyKaigi 2017 on 2017-09-18 to 2017-09-20 in Hiroshima, Japan. See you there!

My short lightning talk: I’ll upload slides later.

Oedo RubyKaigi 06

I went to Oedo RubyKaigi 06 on 2017-03-20 in Tokyo and gave a talk about random stuff.

My talk


“Random topics, but overly high dense”

Since I came to Japan, I tried doing everything opposite to what I’ve done, so instead of organizing things and cutting unnecessary noise out, I included everything, and kept unorganized.

Topics included

  • Ruby m17n
  • Ruby continuation (code example demo below)
  • Vim quickrun
  • The implementation of quickrun
  • How Vim spawns a process and interact with it
  • How to achieve cuncurrency in Vim script
  • Vim script
  • vim + ruby (if_ruby)
  • continuation can SEGV
  • Vim = OS
  • Vim 8 job
  • quickrun with job
  • vital.vim
  • Conventional difference how rubyists document and how vimmers document
  • reading implementations
  • music score and cooking recipe
  • Cooking for Geeks
  • The Art of Fermentation
  • Sourdough, Mead, and Sauerkraut
  • Illegal to name Engineer in BC
  • FRIL
  • Fablic, inc
  • Japan

The continuation simple example

loop version:

5.times do |i|
 puts "Current i is #{i}"
puts :done

This outputs this

Current i is 0
Current i is 1
Current i is 2
Current i is 3
Current i is 4

The other version with continuation:

require 'continuation'
cont = nil
i = callcc {|c| cont = c; 0 }
puts "Current i is #{i}"
cont.(i + 1) if i < 4
puts :done















IMG_7795 IMG_7796 IMG_7797 IMG_7798

I prefer longer ones, but I don’t have a plate that can hold.


  • 500g flour (roughly 250g whole grain wheat flour, and 250g white all-purpose wheat flour)
  • 400g water
  • 6 ~ 10g salt
  • 6 ~ 10g sugar
  • 4 ~ 6g dry yeast
  • more flour for sprinkling to avoid sticking

Steps (total ≤20min labour)

  • Mix all but flour (water, salt, sugar, and dry yeast) together in a big bowl
  • Put flour and mix.
    • It may be tough at first. Leave some time and try again; it should be easier
  • Put a cover and leave like for 8 hours
    • I usually do above steps at night, and do below at the next morning
  • Form it
    • Sprinkle enough flour both to the top of the bowl and the plate to bake, otherwise you will have hard time removing the baked bread out later.
  • Preheat oven to 470F
    • It’s pretty hot!
    • I preheat after forming the dough, so that dough have enough time to rest.
  • Sprinkle water and make some coupe
    • I usually use scissors to cut
    • Water is to make the dough moisture. Don’t put too much to make them wet
  • Insert into oven, reduce the heat to 450F, and wait for 25min
    • Don’t undercook or overcook
    • If you can see some edges have tiny black line, that’s the time
    • Undercooked baguettes make it hard to slice and eat, particularly the skin. This may sound opposite, but that was true for me.
  • Take the bread out, and leave for 30min to cool down
    • It’s still cooking inside
    • It’s also extremely hard to slice when it’s too moisture
  • Slice
    • Use breadknife. Don’t press. Google how to slice bread


  • Baking breads, particularly baguettes, needs the oven to be somewhat moisture. Also the oven needs to be hot even after opening the door to put the doughs in. One solution is to put stones and small bowl with water in advance. But I think that they don’t have to be pure objects that achieve the breads’ requirements, but they can be something that give us additional benefit. Last time I put chicken thighs with some herbs. Since I put chicken in advance, they should have kept high temperature when I re-open the door to put doughs in, and also chicken should have generated some vapour that moisturize the oven room. The baguettes I got were good, and also I got the chicken to be roasted for free.
  • Buy a big bag of yeast, and keep it in freezer. If it’s inconvenient for you to use, take some batch out into an empty jar or anything.
  • They taste amazing. Considering the fact that it’s easy for me to make and it costs very low, I think this is really practical recipe that I can keep doing.
  • I keep the brown baked sprinkled flour into ziploc. They can be used for making white sauce with butter.
  • I form dough directly on the plate to bake. One less object to clean.
  • I’m calling this recipe as my bread making version 2. I have published version 1 article in Japanese in the past, but this current version is better and easier.
    • Currently experimenting making version 3 which won’t use dry yeast but uses sourdough starter.

Natural Scrolling + Left Handed Mouse Buttons

Things described below are done on my Gentoo Linux on 2015-08-15. However they should apply any X11 Systems such as Debian, Ubuntu, or Arch Linux as well, because none of them are depending on Gentoo specific tools.

Problem: Natural scrolling

This should be easy. Both xfce4 and gnome have config to reverse scroll direction. However, they don’t always reverse only on some GUI apps (such as evince pdf viewer)

xmodmap seems to solve this issue, but it does not.

xmodmap has another issue that if you unplug/plug USB mouse you have to apply xmodmap again.

Let’s find a solution which doesn’t depend on xmodmap, and which also works for any apps including evince.

Also I want to swap left click and right click.

Solution: /etc/X11/xorg.conf.d

Add /etc/X11/xorg.conf.d/99-ujihisa.conf

Section "InputClass"
        Identifier "natural scrolling for mouse"
        MatchDriver "evdev"
        Option "ButtonMapping" "3 2 1 5 4"

Section "InputClass"
        Identifier "natural scrolling for touchpad"
        MatchDriver "synaptics"
        Option      "VertScrollDelta"          "-111"
        Option      "HorizScrollDelta"         "-111"

After spending couple days I figured out that the above config works.

Notes for the process finding that solution

  • Tried to modify files under /usr/share/X11/xorg.conf.d/ which at-home-modifier (i.e. x11-drivers/xf86-input-evdev) also uses
  • Specifying wrong value (e.g. Driver "mouse") is very dangerous. It can disable any user inputs, and you may have to shutdown computer by holding the power button.
  • If you give wrong value the config can be silently ignored. /var/log/Xorg.0.log can be helpful for debugging
  • man xorg.conf.d, man synaptics, and man evdev are helpful
  • You may have seen ZAxisMapping for inverting scroll. Forget about it. It won’t work


When your Apple Bluetooth Keyboard disconnects immediately after connection

  • Gentoo Linux

Try bluetoothctl -a, instead of just bluetoothctl.

$ bluetoothctl
scan on
scan off (once you find your device)
pair {the id}
{input the pin from the keyboard}

If it still doesn’t work

modprobe applesmc

Nomiku roast beef

Cooked cross rib beef at 55C for 8 hours with using nomiku, then grilled the surface on a pan.




  • I have tried 57C and 58C with beef round (labelled as “for roast beef”) for like 8 hours. The red part was awesome but the white sinewy part was still tough.
  • Beef cross rib for roast beef was on sale at a supermarket nearby which was $11/kg. I bought 1+kg one.

Result: the red part was awesome even after it got cold on the next day. The white part was also great and it wasn’t tough at all.


Releasing Clojure applications with GPLv3

I’m not a lawyer or a software licensing specialist but just a programmer. Don’t use this blog article as your final decision of doing anything, but check original text both in GPL and EPL.

Speaking of software licenses, I personally prefer GPL, and I also like to always use the latest version as much as possible, so I always try to use “GPLv3 or any later version” in my freesoftware products.

GPLv3 logo from

I made a template for lein new to put GPLv3 license info in auto-generated project.clj instead of its default, EPL, since I spent so much time replacing the part every time when I make a new Clojure project. It’s released on here and the repository is on github:

When tweeted that I was planning to make the package on Twitter, @technomancy, the author of Leiningen, mentioned to me about the license compatibility.


So I researched about the licenses’ compatibility. According to GNU, GPLv3 and EPL aren’t compatible (i.e. if you make a GPLv3 project that depends on a EPL package, nobody can redistribute it with the dependency statically linked together,) but you can add an exception clause under section 7 to allow specific dependencies to re-distribute together.

I added COPYING and LICENSE files in the template to let you write the clause in your project. Enjoy!

How to use vimrepress

Assuming you already have neobundle installed, and you are using Gentoo Linux.


  1. make sure youf vim has python USE flag
  2. emerge dev-python/markdown
  3. make ~/.vimpressrc with referring the github repo
  4. install vimrepress

    if has('python')
      NeoBundle 'iyf/vimrepress'
  5. :BlogNew to create a new buffer for start writing a blog post in markdown

  6. :BlogSave publish to post the data and release it

You can also refer the list of blog post to edit by :BlogList

Added on 2015-04-25: this failed with error now and I can no longer use this for some reason.