Posts Tagged ‘development

dot-emacs: smarter indentation with tabs and spaces

In XMMS2, the coding guidelines require you to use a mix of tabs and spaces to indent code: tabs indent blocks, while spaces are used to align multi-line statements. It’s all very natural really:

[tab][tab][tab]foo_function (arg1,
[tab][tab][tab]              arg2,
[tab][tab][tab]              arg3)

Unfortunately, if you use the default C indentation mode in emacs, what you get (when breaking like with C-j or RET TAB) is the following:

[tab][tab][tab]foo_function (arg1,
[tab][tab][tab][tab][tab]    arg2,
[tab][tab][tab][tab][tab]    arg3)

So you mean to tweak the code yourself to fix the tabs. Tedious, annoying. We know better!

I wrote a hook to fix this. The idea is to fix tabs when we’re in an argument list context. It can probably be further improved (please send patches!), but it’s quite useful already.

Just add the following to your .emacs file.

(defun xmms2-c-mode ()
  "C mode with adjusted defaults for use with the xmms2."
  (interactive)
  (c-mode)
  (c-set-style "K&R")
  (setq tab-width 4)
  (setq indent-tabs-mode t)
  (setq c-basic-offset 4)

  ; Align closing paren with opening paren
  (c-set-offset ‘arglist-close ‘c-lineup-arglist-intro-after-paren)

  (add-hook ‘c-special-indent-hook ’smart-tab-indent-hook))

(defun get-nonempty-context ()
  (let ((curr-context (car (c-guess-basic-syntax))))
    (if (or (eq (car curr-context) ‘arglist-intro)
            (eq (car curr-context) ‘arglist-cont)
            (eq (car curr-context) ‘arglist-cont-nonempty)
            (eq (car curr-context) ‘arglist-close))
        curr-context
      nil)))

(defun smart-tab-indent-hook ()
  "Fixes indentation to pad with spaces in arglists."
  (let ((nonempty-ctx (get-nonempty-context)))
    (if nonempty-ctx
        (let ((tabbed-columns (+ (point-at-bol)
                                 (/ (c-langelem-col nonempty-ctx t)
                                    tab-width)))
              (orig-column (current-column)))
          (tabify (point-at-bol) tabbed-columns)
          (untabify tabbed-columns (point-at-eol))
          ; editing tabs screws the pointer position
          (move-to-column orig-column)))))

Note: don’t forget the

c-set-offset

bit, else it won’t work properly for the last argument before the closing parenthesis. And avoid using

c-indent-new-comment-line

to break lines, it can fail with this hook; use

c-context-line-break

instead, it’s smarter anyway!

Git Tips #1: Get there now

Sometimes you’ve played around in the history of a branch, edited some stuff in older commits, perhaps reordered them. You’ve reset’d back a few commits, and now you want to get to the final state you were at initially (or whatever state you want to get to).

Say you’ve kept a branch called ‘

the-end-state

‘ with the working end state you wanted to get back to before you started messing around with the history. You don’t want to

merge

(merging two alternative histories of the same development wouldn’t make any sense), you don’t want to

rebase

(it’s about building a new history, not forwarding it on top of the old one). You just want a new commit to bring you to ‘

the-end-state

‘.

And you want to get there now!

The intuitive way to do this is the following:

$ git diff ..the-end-state > finish.patch
$ patch -p1 < finish.patch
$ git commit -a -s

But why three steps when you can do with just two, using

git read-tree

to import the tree from

the-end-state

branch into your index (

-m

to check for unmerged entries) and populate your work tree (

-u

):

$ git read-tree -m -u the-end-state
$ git commit -a -s

Thanks Junio for the tip on gitml!

XMMS2 GSoC 2008 wrap-up

I’m still waiting for nesciens’ conclusion notes about his very successful project, Collections 2.0, but he’s been busy with his starting university so it will take a few more days.

In the meantime, I wanted to write a wrap-up post about this year’s mildly successful Google Summer of Code with XMMS2. Out of 6 projects, we’ve had 3 successful projects and 3 failed ones. That’s a pretty high and disappointing failure rate to be honest. You always have to be prepared to face unplanned obstacles, but it got a bit out of hand this time.

It is especially frustrating as the projects were all pretty sexy or important, or both.

The long-awaited Generic IPC project seems to be one of those cursed projects that nobody manages to get done. We ran that project last year but it was not finished in time, so Leonid Evdokimov (darkk) took over this year, but he wasn’t able to complete it either.

We had been lucky to get an extra slot to run the S4 project, an experimental new backend for the medialib optimized (in structure, space and performance) for the specific semantics of our data (basically, short property strings attached to objects). Unfortunately, Tobias Bengtsson (ydo) got more busy than expected with his master thesis and a major hardware failure put an end to his hopes of completing S4.

The last failing project was probably the most original/experimental: cloudstream, or a smart blend of xmms2 local music playing and last.fm’s social & semantic information, allowing to play “local radios” of your tracks using a sexy graphical cloud interface. We were especially excited as it had come as a spontaneous suggestion by the student, Arpith Siromoney. Sadly, only little code was produced; we hope that the idea will live on and end up being implemented in one way or the other!

On the brighter side of things, the three other projects were a great success and we hope to include them in the -devel tree and the main release ASAP.

Daniel Chokola (puzzles) worked on getting Ning Shi (zeegeek)’s Service clients (which I mentored for GSoC ‘07) ready for merge. He reworked the concept a bit (operations involved, atomicity of registration, etc), gave the API a refresh and rebased the tree onto the latest -devel releases. From early on, it had also become clear that it would all be nicer with the result/value-split refactoring that had been discussed for some time. Nobody had time to hack it up so I did, and I worked closely with puzzles to update service clients to use the new code and giving him a hand cleaning up the server-side and IPC layer. It’s now a good showcase of the cool new

xmmsv_t

API!

The first project I mentored was nycli, also referred to as “the new korving CLI”, a new CLI client for XMMS2 in C that I had started to take over from my previous C++ client, nyello. I had run out of time to work on nycli but Igor Ribeiro de Assis (greafine) did a great job taking over the code, improving it and completing all the missing features and adding some of his own: commands to interact with the playlist, collections and server actions, support for subcommands, file path globbing, interactive status command, and the super cool aliases!

The second student I mentored, Erik Massop (nesciens), hacked heaps of new features into Collections (my GSoC ‘06 project): new operators (incl. Order, Limit, generic comparison, Token, etc.), server-side source preferences, support for medialists (ordered collections), new query mechanisms allowing aggregates, functions on values and more complex results, conversion of all values to strings, optimized prefix matching, etc. Here come Collections 2.0!

As an organization, we acknowledge our failure at choosing students able to complete their projects in full and in time. We had a much better success ratio in the previous editions, so I guess this year is a combination of bad luck and small defects on the part of mentors and students.

Next year, I’d like us to improve communication between mentor and student, and also between the GSoC participants and the XMMS2 community. Status updates on the planet, clearer project descriptions, better linking throughout the wiki, etc. I’d also like to focus on working on a stricter list of objectives, roadmap and deadlines with the student, to help us keep track of progress more formally. I think we already had a pretty good selection process, but that might be improved too.

Nevertheless, I’m very happy with the students I mentored (nesciens, greafine, and puzzles unofficially): they all showed dedication and genuine interest in their projects, they were very open to criticism but also ready to provide arguments and new ideas to make solutions more elegant.

I look forward to seeing the GSoC code merged in official releases; it has sometimes taken longer than we would have liked in the past, but nycli and service clients should make it to your Git tree in the near future. Collections 2.0 still need review and tests, but the possibilities are already quite exciting!

Congratulations to all the successful students, thanks to Google for sponsoring this program, and let’s make it even more successful next year!

Get the Git slides

Git is the coolest content versioning system since the birth of bits, and I gave two talks/courses recently: the first at the BarCamp in Lausanne (edition 2), and the second for the local LUG, AKA the GULL.

I’ve uploaded the PDF of the slides in English and in French, and in case anyone is interested in reusing them, the sources are available (warning: evil Keynote format; I was in a rush, won’t happen again) under the Creative Commons Attribution-Share Alike 2.5 License: sources in English, and in French.

Git logoAnd to follow up to the topic of Git, go and read this interesting article about using the Index to do partial commits and this short note about using git-rebase –interactive to rewrite history (not History, yet).

PS: I’m quite sure I’m scaring the shit out of my non-tech geek readers, sorry. Stay around though, I will try to split this blog in two (life stuff, bytes stuff) in the future, and I have a few entries about Japan cooking up…

Regarding those slow XMMS2 queries…

The screaming groupies disturb my concentration, so I will reluctantly take a few minutes to silence the general hysteria. The secret is no more: we have über-optimized queries in XMMS2!

All thanks go to nesciens, who dived in the optimization documentation of SQLite to fix some stupid bottlenecks of my query generator. The two most important elements are the use of

COLLATION NOCASE

for case-insensitive comparison (instead of using

LOWER(value)

, which disabled indexing), and the creation of better indices on the Media table (including collated indices).

Let’s get some numbers out!

Quick note: in addition to a pair of [key, value] indices (one with BINARY collation and one with NOCASE), he added a pair of [id, key, value] indices. I couldn’t highlight any effect on performance of the latter two, but I left them in for those tests. (Hint: more tests and insight are welcome!)

I ran a series of benchmarks with different search patterns. The execution time has been averaged over 100 executions ran with the command

time for i in $(seq 100); do $CMD > /dev/null; done

. I compared the performance of execution in two versions of XMMS2:

  • default DrKosmos (git hash: f171d33ca13e1715d3b167e8fa958a724eb032ce)
  • optimized DrKosmos (git hash: 94661d22a7437b48c9cb5d4b1cd6483350d0a9a4, nesciens-sqloptims in my tree)

The queries used were the following (all matched songs):

Q1) artist:Air album:”Moon Safari”
Q2) artist:AIR
Q3) artist:Air album:”Moon*”
Q4) artist~Air

read the rest of this entry »

MP3Tunes contest: XMMS2 support?

MP3Tunes may or may not be an Evil (as in Axis of ~) service, but it just announced a developer contest to encourage people to implement its API and create new interfaces (on the desktop, mobile phone, TV, toilet seat, whatever).

The contest page on the official website isn’t quite as verbose as one would have hoped, though, and the link to the rules points to a missing webpage. Some more intel is however available in a blog post on Michael Robertson’s blog. Yes, Michael MP3.Com/Linspire Robertson, who is also Michael MP3Tunes Robertson, obviously.

The deal: you have until November 5th, 2007, to submit an interface to MP3Tunes in one of the ten predefined categories (Desktop Player, Game Console, WebUI, PDA, etc). The winner in each category will receive a cosy $1000. I haven’t determined whether it’s a public vote, a closed jury, or some other semi-random algorithm involving car-driving girafes.

I haven’t yet checked what the API offers, either, but I sure wonder whether we could hack something together with XMMS2. If it could be hooked into the daemon, and apart from the obvious ever satisfying benefit of being neat and fun, it might allow using any of our interfaces (AKA clients) to play music from MP3Tunes.
read the rest of this entry »