fuzzy file matching in vim

posted by alexis reigel on december 13, 2013

Until recently I used command-t as the mechanism for opening files. It was always working great for me, and apart from the installation, which is a bit of a hassle because it’s written in ruby, I was very happy with it. There was only one feature missing: Word boundary matching by using uppercase characters.

I was playing with the thought of contributing that feature to command-t, but then Gary Bernhardt came along and put selecta out there:

A fuzzy text selector for files and anything else you need to select.

He even provides a simple script that provides fuzzy file matching in vim.

So… let’s extend that really nice and simple script with my desired word boundary matching, I thought. And I did exactly that.

What my extension does is this:

Uppercase characters in the query must match a word boundary. Word boundaries are pascal and camel cased words and the characters ‘/’, ‘\’, ‘_’, ‘-’, ‘.’ and whitespace. (“FooB” will match “foo/bar” and “fooBar” but not “foobar”)

For the use case of fuzzy file matching in vim the change allows to search very quickly for specific paths. If we want to search e.g. for a rails model named foo, we could enter “AMFoo”, which would match the path “app/models/foo.rb”, but not “app/controllers/myfoos_controller”. If we searched just for “amfoo”, the latter would be matched as well.

git bash prompt

posted by alexis reigel on july 05, 2013

Hi.

I tried many different bash git prompt solutions, all of which were either too complicated, too buggy or too ugly. So…

I didn’t want to invent too much myself, so I used the git prompt provided by git as a basis. This script does all the magic already, so the only thing left to do was to make it look nicer. This is the whole section in my .bash_profile:

# bash git prompt
GIT_PS1_SHOWDIRTYSTATE=true
GIT_PS1_SHOWUNTRACKEDFILES=true
GIT_PS1_SHOWUPSTREAM="verbose"

git_current_branch_name="\$(__git_ps1 '%s' | sed 's/ .\+//' | sed -e 's/[\\\\/&]/\\\\\\\\&/g')"
git_status_substitutes=(
    "s/$git_current_branch_name//;" # remove branch temporarily
    "s/u//;" # upstream
    "s/+\([0-9]\+\)/▴\1/;" # outgoing
    "s/-\([0-9]\+\)/▾\1/;" # incoming
    "s/%/?/;" # untracked
    "s/+/✓/;" # staged
    "s/*/✕/;" # unstaged
    "s/\(.\+\)/($git_current_branch_name\1)/;" # insert branch again
)
git_status_command="\$(__git_ps1 '%s'| sed \"${git_status_substitutes[@]}\")"

if [ "$color_prompt" = yes ]; then
PS1="${debian_chroot:+($debian_chroot)}\[\033[0;37m\] \w \[\033[34m\]$git_status_command\[\033[37m\]\$\[\033[00m\] "
else
PS1="${debian_chroot:+($debian_chroot)} \w $git_status_command\$ "
fi
unset git_status_substitutes git_status_command git_current_branch_name

And now, step by step:

GIT_PS1_SHOWDIRTYSTATE=true
GIT_PS1_SHOWUNTRACKEDFILES=true
GIT_PS1_SHOWUPSTREAM="verbose"
git_current_branch_name="\$(__git_ps1 '%s' | sed 's/ .\+//;s/(//')"
git_status_substitutes=(
    "s/$git_current_branch_name //;" # remove branch temporarily
    "s/u//;" # upstream
    "s/+\([0-9]\+\)/▴\1/;" # outgoing
    "s/-\([0-9]\+\)/▾\1/;" # incoming
    "s/%/?/;" # untracked
    "s/+/✓/;" # staged
    "s/*/✕/;" # unstaged
    "s/\(.\+\)/($git_current_branch_name \1)/;" # insert branch again
)
git_status_command="\$(__git_ps1 '%s'| sed \"${git_status_substitutes[@]}\")"
if [ "$color_prompt" = yes ]; then
    PS1="${debian_chroot:+($debian_chroot)}\[\033[0;37m\] \w \[\033[34m\]$git_status_command\[\033[37m\]\$\[\033[00m\] "
else
    PS1="${debian_chroot:+($debian_chroot)} \w $git_status_command\$ "
fi

The final output looks like this:

~/src/dotfiles (master ✕✓? ▴1▾5)$

The original output of __git_ps1 looks like this, which is much more cryptic:

~/src/dotfiles (master *+% u+1-5)$

The meaning of the symbols:

Unstaged changes
Staged changes
? Untracked files
▴1 One changeset ahead of remote
▾5 Five changesets behind remote
= No difference to remote

You can see the whole thing in action in my .bash_profile.

how to generate a webfont kit with open source tools

posted by alexis reigel on august 06, 2012

There are some web based services that convert fonts to a webfont package, the most popular of which is the fontsquirrel font-face generator. For our metaflop project I was looking for a service api that i could call from within our application. Since i didn’t find one I was attempting to build the whole webfont generation by collecting tools that could do the job.

Font types

To create a webfont kit that works on all browsers we need to generate several different font types:

Tool chain

The following tools are required to generate all the needed font types. I assume that you have your font as otf. If you have a ttf, just switch ttf with otf in the following statements:

The very simple FontForge script (ttf-svg.pe) looks like this:
Open($1)
Generate($1:r + ".ttf")
Generate($1:r + ".svg")
# outputs font.ttf, font.svg
$ fontforge -script ttf-svg.pe font.otf
# outputs font.woff
$ sfnt2woff font.otf
$ ttf2eot font.ttf > font.eot

CSS

The css declaration is based on Fontspring’s bulletproof @font-face syntax and is the same syntax as used by fontsquirrel.

@font-face {
    font-family: 'YourFont';
    src: url('YourFont.eot'); /* IE 9 Compatibility Mode */
    src: url('YourFont.eot?#iefix') format('embedded-opentype'), /* IE < 9 */
         url('YourFont.woff') format('woff'), /* Firefox >= 3.6, any other modern browser */
         url('YourFont.ttf') format('truetype'), /* Safari, Android, iOS */
         url('YourFont.svg#YourFont') format('svg'); /* Chrome < 4, Legacy iOS */
}

That’s it. Remember though that you should only convert fonts are legally eligible for web embedding.

reminder. git. awesome.

posted by alexis reigel on july 19, 2012

This is just a quick reminder of how awesome git actually is. The story is short:

My disk crashed and I lost a couple of local commits that I hadn’t pushed (to github) yet. Luckily, I deployed them to the staging server already (actually, this is a reminder of how awesome git and capistrano actually are). Because capistrano is awesome and deploys the git repo to the server, and git is awesome too, I could restore my local repo from the staging server:

local:  $ ssh staging_server
server: $ # some `cd` action
server: $ tar czf asdf.tgz www_folder
server: $ # ctrl + D
local:  $ cd /tmp
local:  $ scp user@staging_server:/tmp/asdf.tgz .
local:  $ tar xf asdf.tgz
local:  $ cd my_local_repo
local:  $ git pull /tmp/asdf dev

A simple git pull from the copied repo and I’m all set again.

How awesome is your dev stack?