things i want to remember, things i want to share

Développeur Python et adepte Linux depuis 2005, Core développeur Kivy, passionné par beaucoup trop de choses.
Profil Github gpg signature bitcoin address

Switching to i3wm

written by tshirtman, on 2/17/14 12:15 AM.

I’ve been a wmii user for more or less 5 years, and until now although it was not much maintained anymore, i was unable to replace it with something else.

Last time i checked, neither awesome, i3, xmonad, or either of the few tiling WMs i tried, seemed to fulfill my needs, i wanted dynamic tagging of workspace, full keyboard navigation, and the same tag on all screen in a multiscreen setup (more on that later). So, although it had a few bugs, i decided that wmii was still the best thing out there.

Recently, hobbestigrou suggested me having a look at qtile, being in python, it would be easy to script and adapt to my use case.

I did look into it yesterday, and spent some time configure it for my use. In the end, i had most things working, although i wasn’t crazy about the window placement capabilities, and using the doc hadn’t been a thrilling experience.
The last standing point however was, the separate tag management per screen, but, at that point i was ready to give that a chance, considering i often pinned a window to all workspaces on the second screen (but not all the time).
So i decided to give a second chance to i3wm, considering it’s the spiritual successor of wmii, i may be more excited at the window placements.

And while it took me some time to wrap my head about the tree system of i3 (the split shortcut (Meta4+v) turned out to be quite important), i have to admit it solves all the limitation of wmii’s one, while avoiding the limitations of layout systems of other tiling managers.

Now, i3 doesn’t expose a dynamic tagging system out of the box, but it offers a nice cli api, and i found a blog post offering a good explanation on how to use it, i adapted it to make it slightly faster, but the idea stands.

I’m still a bit confined by the inability to share tags across screens, i gave myself a way to move a window/container from one screen, but it’s still a bit different. I won’t try to force i3 to see only one screen, as i did on my first try, because that caused all sorts of swampy issues, and it’s clearly not the way it’s meant to be used.

Other than that, it’s pleasing to see all the nice improvement of the window manager over its ancestor, it’s certainly way more pleasing to look at, and to configure.

Anyway, my configuration is now on github, for my own profit (easier to setup on multiple machines), and for the curiosity of others :).

Tip me if you like this :)

Keyboard Kata

written by tshirtman, on 2/12/14 2:08 AM.

So i spent most of the evening copying texts on dactylotest, most of the time barely reading them, while listening to tv, to work on my typing speed and regularity, and it paid a little, for the first time, i passed the 70WPM mark, and i hit 60WPM most of the time, which is a progress from the 50WPM i considered normal not long ago.


so yes, practice makes perfect…

Tip me if you like this :)

Using jinja2 outside of the web.

written by tshirtman, on 2/10/14 12:56 AM.

I may be the last person out there to do that, but i hadn’t actually gotten to that yet.

So here is the thing, sometime you want to produce a text file, with some complex structure, and string.format is not really up to the task, so you scratch your head and wonder what could be useful to… template an output.

Then a nice lib like jinja2 totally makes sense.

For my use case, i want to generate java source code, using info parsed from other java source code (thanks to the awesome plyj lib), so it’s easy to give the general form of the output file, and to pass the content after that.

{% if package %}package {{ package }};{% endif %}
import {{ module.package_declaration.name.value }}.*;
{{ imports }}\

public class {{ cls.name }}{{ suffix }} extends {{ cls.name }} {
    public interface I{{ cls.name }} {\
    {% for method in methods %}
    {{ method.return_type | get_type }} {{ method.name }}({{ method.parameters | render_params }});\
    {% endfor %}

    private I{{ cls.name }} implem = null;

    public void setImplem(I{{ cls.name }} implem) {
    this.implem = implem;

    {% for method in methods %}
    {{ method.return_type | get_type }} {{ method.name }}({{ method.parameters | render_params }}) {
    if (this.implem)
        return this.implem.{{ method.name }}({{ method.parameters | render_params_values }});
    }{% endfor %}

One problem i had, though, was when it turned out it would be convenient to use custom filters inside my template, it took me some time to find the relevant documentation about how to register functions as filters in this situation (since people usually use jinja2 in a framework, they document how to do so using the environment used by this framework).

So the answer was not to use jinja2.Template directly, but to build an environment before.

env = jinja2.Environment()

then to setup my filters in this environment:

env.filters['render_params'] = render_params
env.filters['render_params_values'] = render_params_values
env.filters['get_type'] = get_type

and to use env.template_from_string(template_string) to create a Template object from my string.

Tip me if you like this :)

Worthiness of effort

written by tshirtman, on 2/9/14 1:08 AM.

If it’s worth to be done, it’s worth to be done well. If you aren’t struggling, it’s not worth doing it.

Tip me if you like this :)

flappy bird is a stupid game.

written by tshirtman, on 2/7/14 1:54 AM.

No, seriously.

Difficulty is flat, once you got past a pole, you know you can get past any pole, if you got past a dozen, you know you can theoretically go “all the way” (and there is no difference between theory and practice, in theory), so it’s just a matter of being consistent, the challenge is just to avoid losing focus, or stressing (because you are getting near of your high-score), but each pole is just as easy as the first one in the game.

So getting past pole 1 is enough to “beat the game”, of course, then you’ll set other arbitrary limits, trying to push further and further, but it’s just a matter of how lucky you are at avoiding accidents. I decided to put the limit at 50, and got to it today, so that’s it for me, and i’ll resume more interesting activities :P (it was already to high a limit, but i think it’s enough to consider i didn’t “beat the game” by accident).

Tip me if you like this :)

Magnet: a widget to easily make your interface more lively

written by tshirtman, on 2/6/14 12:38 AM.

Kivy has a very nice Animation class, that allows you to move move widgets around (or other things), by updating any numeric property to a target value, just by setting a time and a transition function. Still, when you are building a complex interface, it can still be a bit cumbersome to manually trigger animations for all the elements, and to keep track of them.

After being frustrated about this issue for some time, i tried my luck some time ago, at doing a nicer, “90% use cases” interface, and the Magnet garden widget was born.

Its usage is simple, you simply use it to wrap your target widget, and give it rules about how to transition when the magnet is moved. As the magnet is moved or resized by the usual kivy logic, instead of making the wrapped widget immediately follow such constraints, it’ll create and keep track of animations to achieve a smooth transition to the new values for you.

As any garden “flower”, to install it, you need to install and use the garden project.

python setup.py install

(either in a virtualenv or system-wide)

then do:

garden install magnet

you can now import it a kivy application:

from kivy.garden.magnet import Magnet

Garden Magnet video

Tip me if you like this :)

git, show stash list after checkout.

written by tshirtman, on 2/4/14 12:13 AM.

Sometime you start doing something in your codebase, and then you have to go do something else on another branch, so you stash them, later you come back, and you may not remember you started, them, and you forget to check your stash list.

Git has a very general solution for these kind of things: hooks

hooks are actions that you can “hook” (heh!) to events, it’s common to use the pre-commit hook to check for various errors before validating it, or to update refs after a fetch. Here, we want to display the list of stashes done on the current branch, after you checkout it.

first, we need to take the current branch.

 branch=$(git branch | grep "^\*"|sed -s s/'* '//)

then, we get the list of stash, and filter it on this branch:

 git stash list | grep "WIP on $branch"

put that in .git/hooks/post-checkout of your repository, and make it executable.

 chmod +x .git/hooks/post-checkout

But now, you have to do that in all your git repositories, but then there is this nice trick that allow you to easily use that hook in all your repositories, with just an unintrusive git init each time.

edit 2014-03-13: adding the exit 0 at the end of the script, because it prevented rebase. the code is now:

#!/usr/bin/env sh
branch=$(git branch | grep "^\*"|sed -s s/'* '//)
git stash list | grep "WIP on $branch"
exit 0
Tip me if you like this :)

back from FOSDEM

written by tshirtman, on 2/2/14 8:24 PM.

So i’m back from fosdem, and there has been an obvious pause on the daily blogpost thing, not only the days where quite full, but internet access was not, because i don’t have tethering in belgium, and wifi works when it wants.

The hotel wifi locked access had some dns bug, by the way, redirection to
www.hotspot.local wasn’t working, although dig gave its correct ip, editing /etc/host’ was the easy solution, so i did that.

So, there was a lot of interesting conferences, and as usual, you just can’t see them all, and there are people to see too, so i’ll definitly watch some of
them later using online recordings.

In the Python track, which i gave quite some attention too on sunday, async solutions was probably the most popular theme, with talks about pypy and SMT, asyncio, offset (python port of go’s goroutine), etc. I’ll definitly have to
give some more time to this, trying to port kivy’s eventloop to asyncio may be
a good (and potentially useful) exercise in this direction.

I managed to get a seat in the javascript track for the Cute presentation, as
i had a recent second look at AngularJS and it’s self-evidently a very complex framework, having an understandable version, even if less performant, looks like a very good idea. I guess i’ll have to learn some more on the JS
fundamental before though, as i understand its scope and object model much less than Python’s.

Aside of that i managed to have some time with Mathieu Virbel to talk about exciting new features in PyOBJus and the best syntax for them, and to think about the kivy organisation, which still require some work.

Of course, i met a lot of other friends, and had very nice discussions, so it
was a good experience, although i had overlooked the basic consequences of
being abroad (that is, that my second brain is impaired by lack of permanent network access).

Tip me if you like this :)

I'm going to FOSDEM

written by tshirtman, on 1/31/14 1:34 AM.

Yep, totally short-notice, i know!

I’ll be in Bruxelles this week end for one of the biggest FOSS event in Europe, ping me if you want to meet me! (tshirtman in all the relevant networks ;)).

Oddly, it’s the first way i manage to go to the event, thanks to my company for being pretty open about sponsoring employees to go to such events, i’ll try to make the most of it!

Have a nice weekend! :).

Tip me if you like this :)

Short meetings

written by tshirtman, on 1/30/14 1:13 AM.

There is something to do meetings near the end of the day, you really get down to take decisions very fast, nobody wants to delay things, things that would have been planned for a two hours session can really be achieved in a matter of minutes.

Most meetings should be hard-constrained to 30 minutes, doing more should be considered a waste of the company’s money.

Tip me if you like this :)


#FIXME 3G absurd ad_sense alterway aléatoire android animation anonymity atheism bach backlog bash bitcoins blog blogging boldness book books boulot bricolage bépo C canvas captcha captures carte SD censure christianity chroot CI CLI cli cloudwatt code colors comfort zone command line community company life conferences contest copwatch copwatchnord-idf core-devs cours ct705 culture deb debian debug deformation dehors dessin dev distribute distribution docker débutant déploiement développement ebooks eeepad eeepc effect ego empty en escher event firefly flappy bird flask fosdem foss fr fun game garden gdb geek culture git github goals graphics grrr gödel hack hackathon hacked hacking health hooks i3 images IMAP inspirational install isync java jenkins jeu jeu video jinja2 jni keyboard keynav kivy kv lame learning lib libre life linux lol macosx magnet mail mailing-list mails maths mbsync meetings memory leak mesh meta mint mirroir MIT module motivational mouse museomix mutt nexus7 no-mouse notmuch nottoomuch offlineimap onycroit opencourseware osc packaging paris passphrase password patch pentacatyl people perte de données ping pip planning plugin positioning pr procrastination programmation progress project projet property proudhon proxy psf publisher/consumer pull-down pygame pyjnius pypi python pythonar qtile raid rapsberry pi reading recorder references release religion responsive review reviews réseau réseaux sociaux résurection salon screenshots script self service shows shutil shyness sizing solib sortie sousous!!! spam spritz stash status systeme système templating terminal texture texture coordinates Thomas Paine thread thème tiling time time management. tip tips tools transformer tutorial tv twitter typematrix typing ubuntu ubuntu-fr ultimate-smash-friends unity update upload images useless usf utils value VDM video vie/mort vim virtualenv visite widget windows wm wmii work workflow workflow. zine études