Tech That!

The rantings of a mad computer scientist

Running Dungeon Keeper on Linux

After reading this great post on how in-app purchases are ruining the gaming industry, I felt an urge to play Dungeon Keeper again. Since I run Linux, however, playing games is not always such a trivial affair. WineHQ (unhelpfully) told me that Dungeon Keeper does not run very well under wine 1.5, but given that 1.5 was released early last year, I figued I’d give it another shot.

I headed over to Good Old Games who provide DRM-free versions of old games, and bought Dungeon Keeper Gold edition for just below $6. After downloading the installer, I ran it through wine, and lo’ and behold, the installer ran without problems. At the last screen, I pressed “Launch game”, and to my surprise the game also started without a hitch. No stuttering in video or audio. I started the single player campaign, and nothing seemed to be wrong at all. So much for old WineHQ entries.

Then I quit the game to see whether it would still work when I started it “normally”. I quickly discovered that there was no “normal” way to start the game. The game is run through DOSBox, and GOG have provided Windows shortcut files (.lnk) for launching the game with the appropriate options. Unfortunately, wine doesn’t let you launch .lnk files, and just running DOSBox gave me nothing more than a shell (which, to be fair, was to be expected). Time to start digging.

It turns out that .lnk are part binary, part text, and by catting the file, you do see what commands it would run when executed on Windows. I’ll save you the details, but you essentially need to pass DOSBox two configuration files provided by GOG: dosboxDK.conf and dosboxDK_single.conf. You also need to run this command from inside the DOSBOX/ directory! Being in the game’s root directory will not work, and the game won’t start.

Realizing that DOSBox is also supported natively on Linux, I started to wonder whether I could avoid wine alltogether.. Seems silly to start wine to start DOSBox to start the game if I don’t have to. So, I replaced wine DOSBox.exe with just dosbox, and everything worked just as well! In fact, it turns out that DOSBox has already been tested with Dungeon Keeper, so this shouldn’t have come as a surprise I suppose.

Finally, to clean up, I extracted the Dungeon Keeper icon files and created a Desktop Entry file so that I can now start the game directly from my launcher:Dungeon Keeper launcher

Hope this has been useful, now go and be evil!

Incremental plotting in gnuplot

If you have ever had to plot something, chances are you’ve come across gnuplot. It’s a very versatile plotting tool, and once you get used to the syntax and quirks, you quickly start using it from everything from throwaway data visualization to plots included in papers.

One use-case for gnuplot that there is currently no built-in support for, is handling incremental plotting where you have a data file that some other process is writing to, and you want your plot to update so that it always shows the latest data (or scale so it always shows all of it!). There are many ways of accomplishing this, most of which are based on having something like this in your plot file:

load "< while [ 1 ]; do echo 'replot'; sleep .1s; done"

load is telling gnuplot to continue reading commands from the following source, and the < at the beginning of the source string tells it that it should execute what succeeds it as a shell command. Without asking questions, gnuplot does so, causing it to enter an infinte loop. Each time the script outputs “replot”, gnuplot goes ahead and replots, but since the input source isn’t empty yet, it continues reading (blocking the application in the process). This certainly works, but it has the unfortunate side-effect of completely locking up the interface so you cannot interact with your data at all. Zooming and panning will simply not work. It is also somewhat inconvenient that script will never terminate, even when your data file is no longer being written to.

I therefore propose the following solution instead. First, you create a little bash script that generates your gnuplot script and puts it in a variable (let’s call it script). Then, at the end of your script, you add the following code:

script="plot 'data-file.dat'"

mkfifo $$.gnuplot-pipe
gnuplot -p <$$.gnuplot-pipe & pid=$! exec 3>$$.gnuplot-pipe
echo "$script" >&3

running=1
trap 'running=0' SIGINT
while [[ $running -eq 1 && $(lsof "$1" | wc -l) -gt 0 ]]; do
	echo "replot" >&3
	sleep .5s
done

exec 3>&-
rm $$.gnuplot-pipe
wait $pid

This code uses a named pipe to feed data to gnuplot so that we can continue sending commands to gnuplot after launching it. We also use another little-known trick to prevent echo from closing the FIFO file once it has written to it. Because we launched gnuplot as a background process, we can now run our own while loop that sends replot messages to gnuplot without blocking the main plotting thread! We can also be somewhat smarter about this by only sending replot commands as long as the file is still held open (the lsof command helps us with this), and we can gracefully terminate if the user sends us a SIGINT (presses ^C). Finally, we close and remove the FIFO file, and wait for gnuplot to terminate. Shiny!

So, there you have it, incremental data plotting in gnuplot without blocking the interface.

Generating combinations for N-dimensional searches

Problems involving searches are very common in computer science, and they are often N-dimensional, meaning you are looking for a *combination* of values that yields some outcome. For example, you might be looking for all pairs of numbers whose sum is 50. This is trivial to express in most modern programming languages, and would usually be done with a nested for loop like this:

for (int a = 0; a < 50; a++)
  for (int b = 0; b < 50; b++)
    if (a+b == 50) printf("%d + %d == 50\n", a, b);

Say that you now wanted to find all triples of numbers that sum to 50. You might be tempted to add another nested for loop as such:

for (int a = 0; a < 50; a++)
  for (int b = 0; b < 50; b++)
    for (int c = 0; c < 50; c++)
      if (a+b+c == 50) printf("%d + %d + %d == 50\n", a, b, c);

While this is still legible, it should become apparent that this won’t scale very well as you add more dimensions. More importantly though, this approach also requires you to know in advance the number of numbers you want to add. If you were to build a program that let the user specify how many numbers she wanted to use, this simply wouldn’t work.

I had exactly this problem, and came up with a pretty neat solution. It has probably been done before elsewhere, but I figured I’d document it for future reference.

The following code lets you find all combinations of N variables with values between 0 and S. By multiplying the value with a fraction, you can also extend this to non-integral numbers.

int x, n, i;
int vars[N];
double ns = pow(S, N);

for (n = 0; n < ns; n++) {
  x = n;
  for (i = 0; i < N; i++) {
    vars[i] = x % S;
    x /= S;
  }
  /*
   * vars[0..S] now holds one of the
   * combinations of values for the
   * N variables
   */
}

We can use this to implement the example I gave above of letting the user specify the number of numbers to sum:

int N = /* get user's number */
int S = 50;
int x, n, i;
int *vars = calloc(N, sizeof(int));
double ns = pow(S, N);

for (n = 0; n < ns; n++) {
  int sum = 0;

  x = n;
  for (i = 0; i < N; i++) {
    vars[i] = x % S;
    x /= S;

    sum += vars[i];
  }

  if (sum == 50) {
    for (i = 0; i < N; i++) {
      if (i == 0)
        printf("%d", vars[i]);
      else
        printf(" + %d", vars[i]);
    }
    printf(" = 50\n");
  }
}

free(vars);

While it is certainly longer, it is also much more flexible. If the values of N and S are known at compile-time, we can also let the compiler unroll the loops completely for us to avoid the runtime termination checks!

Game Dev Tycoon on Linux

Yesterday Game Dev Tycoon went viral with its decision to punish pirates in an unusual, but quite ingenious way. Helping their popularity was probably the fact that the game is available for both Windows, Mac and Linux, and so users were downloading it like crazy! Unfortunately, the Linux version seems to be riddled with bugs at the moment, and for some users getting the game to run in the first place seems to be causing massive headaches.

I can’t help much with the in-game bugs (that I know the developers are hard at work on), but getting it to run on Linux turns out to be easier than expected. The only in-game bug I have a fix for is the one that makes the game hang when trying to move out of the garage – see the bottom of this post for the workaround.

Game Dev Tycoon is built using node-webkit, which essentially lets the developers build the game using web tech, while still being able to provide a binary to users. The way node-webkit packages applications is that the source code and resources are put in a zip file, and this zip file can then be passed as an argument to the nw binary, which will extract it and run the code using node and webkit (as the name implies). To make installation for end-users “easier”, the node-webkit documentation suggests that a binary is generated like this:

cat /usr/bin/nw app.nw > app && chmod +x app

which allows a user to simply run ./app. The problem with this is that this means the user is locked in to using the nw binary as compiled on the developer’s computer, which turns out to be a 32-bit Ubuntu system. This isn’t great for 64-bit users and users on bleeding-edge distributions like Arch Linux, who then have to install all sorts of legacy libraries (lib32-gconf) and ugly symlink hacks (libudev.so.0 -> libudev.so.1) to make it run.

So, how can we do better? Well, the node-webkit documentation does say

In general, it’s recommended to offer a .nw for download, and optionally “merged” versions for the platforms where this makes things simpler.

but the developers didn’t do this. Is all lost? No. As it turns out, the unzip program is quite smart, and can extract zip files even if they’re appended onto another file! This means we can simply run

tar xzvf game-dev-tycoon.tar.gz && unzip gamedevtycoon

And all the source files of the game will be made available to us in the current directory! Now, all we have to do is install/compile node-webkit ourselves (so no 32/64-bit problems and up-to-date libraries) and run

nw ./

and the game will run as advertised with no more hassle or hacks. Yay!

I notified the developers that the code could be extracted in this way, and the reply I got was

Yes, we are aware of this.
If people don’t abuse this, there isn’t an issue.

Finally some game developers who understand the name of the game!

For those of you running Arch Linux, I’ve written a PKGBUILD which does a cleaned-up version of this and made it available in the¬†AUR and on GitHub.

Update: many Linux users are reporting an issue with not being able to move out of the garage (the loading bar just runs forever). The fix has been posted by several people on the GDT forums, and it is simply due to Linux having case-sensitive filenames. The workaround is simply to run

mv images/superb/level2Desk.png images/superb/level2desk.png

after running unzip, and everything should be working smoothly.

Why don’t people ask questions?

You probably know me. Or someone like me. The guy who always raises his hand in class or who has a question or comment regarding whatever idea is being discussed. You might find people like me annoying. I’ve never understood why there seems to be so few of us though. Ever since I was a kid, I’ve wanted to question things; to figure out why or how. Unfortunately, it seems most people don’t. Or rather, it seems as though people are afraid of asking questions. Whether it is from fear of showing that they don’t know or from not wanting to take up other people’s time or something else entirely, I’ve never been able to understand. I do know, however, that it disturbs me.

There are many quotes on questions, like “better to ask and be thought a fool for five minutes than to remain a fool forever” and the likes, but to me, there is something deeper than that. Asking questions often reveals a lot more information than just the answer to the question, almost regardless of the situation. At university, questions can not only reveal errors in the material, but they can spawn discussions on aspects of the topic that suddenly makes it so much clearer why things have to be the way they are. If you strive to understand, questions tend to give a deeper understanding of what’s going on than trying to fill the gaps yourself.

Questions are important in the professional world as well, whether to make clients think properly through the problem they are presenting you with so you don’t go solving the wrong problem or to your peers to come up with the best solution to a problem. I’ve lost count of the number of times a solution has been accepted simply because no-one asked questions at the time it was proposed, only for it to later turn out that it was a terrible solution, and several people in the group saw that it was. This is not because the person with the original idea was an idiot, but rather because there was no feedback process. Without questions, without questioning, ideas are never refined. They need critique and thought, things that are incurred by asking questions.

Indeed, even in personal relationships, questions are important. Asking others questions about themselves serves both to show them that you care, but also for you to learn more about that person. And not only whatever the answer to the question is; you often learn a great deal more about a person simply from digging a little bit. One question often turns into a deeper conversation. Even asking others questions about yourself can be hugely rewarding; what better way of getting a better understanding of how people perceive you than to ask? Many might find this difficult because they are afraid of what they might learn, but if you truly want to improve yourself as a person, then asking is the best way of finding out where you should start.

So, given all the benefits asking questions have, why are there so few people like me? Why is it that there’s “that one person always raising his hand” or that “that one person always questioning people’s ideas”? Why is it that during lectures, I’m the only one who asks questions nearly every time? Why is it that such a low fraction of people account for such a large fraction of the questions? I refuse to believe that other people aren’t curious or have doubts about things. My deepest fear is that people just don’t care. That they don’t care how a particular project turns out or whether they get a complete understanding of whatever is being taught in a lecture. They just want to get by. This is a terrible, terrible attitude, one that inhibits innovation and exploration. Come on people, raise your hands and speak your mind! Develop. Learn. Explore. Question. Care! Or go do something else.

Coding is boring, engineering isn’t

I’ve always considered myself a programmer, a coder. I came up with ideas, or other people did, and I wrote the code needed to make them work. Only recently have I realized that not only is programmer not sufficient to describe what I do, it is not even what I want to be doing.

This realization started to dawn on me after reading a (quite interesting) article by Patrick McKenzie I was referred to by a friend. I can highly recommend having a read through if you haven’t seen it already. The article goes into some depth about what working with software development entails, and, amongst other things, points out that what we do as developers is far more than just writing code. In fact, most of the hard work we do has little to do with code. Anyone can code. Being able to write code does not mean you can develop good software. In fact, if all you can do is write code you should definitely not be creating software!

What I’ve come to realize is that not only is coding not what I do most of, nor the most important skill I have, but coding is my least favorite part of the development process. Writing code is boring. Figuring out what the client wants is interesting (albeit frustrating at times). Determining how to create the best experience for the users is interesting. Coming up with a good technical design for you application, database and APIs is interesting. Writing for-loops, ifs, variable assignments and functions is not. The implementation, while important – without the code you have nothing but an idea – is simply not interesting. Nor is it challenging. It is just something that has to be done to complete the design you have in your head.

Now, I’m not saying there is not an art to programming? Far from it. What I am saying is that the art of programming lies in the thinking you do before writing the code, not in the writing itself. To be a good developer, you need to be more than just a programmer, you need to be an engineer – you have to discuss, plan, predict, design, evaluate and re-design; you have to think. Engineering is about solving problems, thinking deeply about every aspect of a system and figuring out the best way of doing things. That is the part of development I love, and the part I consider art.

Handling swipe and click with JavaScript

So, you’ve got a list with overflow:hidden, and you want to make it scrollable with touch?
And perhaps you don’t want to include a library such as iScroll, you just want simple scrolling with as little code as possible.
Perhaps you even stumbled across the fairly simple solution proposed by Chris Barr on his blog, so you start using it (replacing all .pageY with .pageX for horizontal scrolling), and your content scrolls like never before!

You then try to click one of your elements. And nothing happens. You try, and try, and try to no avail. Then you give up, throw your hands in the air, yell “I knew it wasn’t that easy”, and use iScroll.

Before I hand you the solution on a (somewhat) silver platter, let me tell you what’s causing the problem. Notice the “event.preventDefault();” Chris has in his event handlers? These are what break your onclick handler (or href), since they tell the browser not to do whatever it would normally have done when, say, a touch is initated on a clickable element. Unfortunately, they also have to be there, otherwise your phone would, helpful as it is, try to scroll the entire page.

So, how do we solve this? Well, it’s quite simple really. Think about it. What is a click? It’s a tap. And what’s a tap? It’s a touch motion that does not include any movement.

Without further ado, the solution can be found in this gist

The only additions to Chris’ code is that we monitor whether touchmove has been triggered since the last call to touchstart. If it hasn’t then it was a click.
What you decide to put inside the if in touchend is what you’d normally but in your onclick handler. If you’re using jQuery, you would typically use $(e.target).closest(‘a’) or something similar to get the element that the onclick event would normally have triggered on.

Enjoy!

Update 2012-04-26: Changed the code to delay handling the click in case the user just paused while swiping.

Ice Cream Sandwich: Death by paper cuts

I’m a big fan of Android. I have written a few apps, have two phones running it, and I happily recommend it to friends. There is one problem though; the Android experience is riddled with paper cuts. Seemingly minor annoyances that all together make for a frustrating user experience. Google attempted to mitigate some of these in Ice Cream Sandwich, but they somehow managed to introduce a slew of new ones.

In June 2010, Mozilla started the Paper Cuts project. This aimed to fix a lot of the minor quirks that annoyed people working with Firefox all day. I believe it’s about time Google does the same with Android. We don’t need another full overhaul, we just want a more polished experience. So, without further ado, my Android paper cuts:

  • There is no way of hiding applications from the application launcher without uninstalling or disabling them. I don’t use Places, but I still want Google Maps…
  • And why can’t the search bar on top of the homescreen be hidden? Personally, I have never used it. Not a single time. Why should it occupy an entire row on my homescreen?
  • Enabling and disabling auto rotate requires a swipe, three taps and multiple presses of the back button to accomplish. Get real. At least automatically enable rotate when watching video… There are so many ways this could be done: Long click back button, in the power menu, in the notification drop-down. Please give us a shortcut.
  • The whole point of having soft buttons is that they are context aware. This does not just mean hide in fullscreen and rotate. Why is the back button visible when there is no back action? Why is the home button there if I’m already on the homescreen? Couldn’t these provide shortcuts for more useful features in these instances?
  • Why oh why does long click on the soft buttons not have any effect? They are always present, why not utilize them? Toggle auto-rotate for instance… Long press the recent applications button could switch to the latest open application to make switching between two applications very easy.
  • In general, getting to anything takes too many taps. Try setting an alarm. Open app drawer, click clock, click set alarm, click add alarm. Isn’t this common enough that four clicks is a bit too much?
  • The menu button. Or the action overflow. Call it what you’d like. Make it consistent. Why does it appear in three different places? Actually, I don’t want to know why. I just want it to be consistent.
  • Android Market is too slow. It should not take over a second to load, even with a very slow internet connection. Cache the previous content and show that immediately, then update it when fresh information comes in. Usually, we go to the market for a specific action, like opening My Apps. It shouldn’t be necessary to wait for, or even load, the frontpage… We need to see a quick reaction to our inputs.
  • And can someone please fix the millisecond delays that are present for almost every single action? It’s just enough to be noticed, which is not a good thing. This is especially noticeable when using the soft buttons, since they are so often used. I don’t care what is causing it. I’ve read all the blog posts on applications doing too much work on the GUI thread or the fact that user interaction events are prioritized as high as on iOS. I don’t care. It has to be fixed.
    • I have a suspicion that the reason many of these actions feel slow is the little animations that have been placed everywhere in ICS. Closing an app with the back button should not take close to a second – even with animations.

These minor things, and many more like them, taint the Android experience and make it inferior to what it could, and should, be.

Please Google, sit down with a group of your users and have them play around with an Android phone. Note down what bothers them even the slightest, and fix what you can. This will do more for users than any redesign. Make Android feel polished.

Linux homedir dotfiles

Most first-time Linux users come from a world where every program has a settings dialog in which to configure the program; indeed some have never opened those dialogs at all. In Linux, however, many applications still use configuration files located in your home directory. These are often prefixed with a period (.bashrc, .xinit, etc), and referred to as dotfiles for this reason. The reason behind the dot-prefix is that in Linux, files with filenames starting with a period are hidden in most listings by default. Since you don’t want to see all your config files every time you try to find something in your home directory, it makes sense to make them hidden. (If you don’t believe me, open a command prompt and run “ls -la” to see all the dotfiles as well)

So, let’s have a the dotfiles you will most likely want to change. Note that these are primarily for command-line applications, but since you’re using Linux, you will more than likely come in contact with the command line sooner or later.

.bashrc

This file contains all the configuration options for your shell (the application that handles everything that happens in your terminal window).

Below is my current .bashrc file:

# Check for an interactive session
[ -z "$PS1" ] && return

# Color aliases
alias ls='ls --color=auto'
alias grep='grep --color=auto'

# Common aliases
alias more='less'

# Convenience aliases
alias svim='sudo vim'
alias srm='sudo rm'

# Prompt
PS1='[\u@\h \W]\$ '

# Tab completion for sudo
# Disabled because it also autocompletes filenames...
#complete -cf sudo

# Sets the editor to use
export EDITOR='vim'

# Add local bins to path
export PATH="$PATH:/usr/local/bin"

# Other aliases
# make
alias ,='make'
# git
alias .='git pull'
alias ..='git push'
# file handlers
alias o='xdg-open'
# update commands
alias yu='yaourt -Syu --aur'
alias pu='sudo powerpill -Syu'
alias yi='yaourt -S'
# online tools
alias t='tweet'

Note that you should change this to suit your preferences. If you don’t use git, then remove the git aliases or change them to something else you find useful!

.xinitrc

The .xinitrc file is a small, but important, file which controls what happens when you log in and start your X session (The “startx” command). If you’re running a graphical login manager such as GDM, KDM or SLiM, then these will execute startx for you, thus still invoking .xinitrc.
Since I’m running XFCE, my .xinitrc contains “exec startxfce4″.
The “ssh-agent” part runs the entire window manager under a single SSH agent daemon, allowing me to only enter the password for my private keys once in a single session.

exec ssh-agent startxfce4

.Xresources

The .Xresources file configures the visual aspects of all X applications (most notably xterm and xscreensaver).
Note that a lot of these settings will not change anything if you are using another terminal editor such as gnome-terminal or Konsole.
In my .Xresources file below (which is heavily inspired by the Arch Linux Wiki page on the subject), I define a “better” color theme, terminal settings such as font and how my xscreensaver should look. Feel free to experiment these and come up with the perfect settings for your tastes!

One important thing to note is that I am setting xterm to use the Inconsolata font – a very good monospaced terminal font. It is probably available for your Linux distro through the packaging system (Look for ttf-inconsolata)

! terminal colors ------------------------------------------------------------

! tangoesque scheme
*background: #111111
*foreground: #babdb6
! Black (not tango) + DarkGrey
*color0:  #000000
*color8:  #555753
! DarkRed + Red
*color1:  #ff6565
*color9:  #ff8d8d
! DarkGreen + Green
*color2:  #93d44f
*color10: #c8e7a8
! DarkYellow + Yellow
*color3:  #eab93d
*color11: #ffc123
! DarkBlue + Blue
*color4:  #204a87
*color12: #3465a4
! DarkMangenta + Mangenta
*color5:  #ce5c00
*color13: #f57900
!DarkCyan + Cyan (both not tango)
*color6:  #89b6e2
*color14: #46a4ff
! LightGrey + White
*color7:  #cccccc
*color15: #ffffff

! xterm ----------------------------------------------------------------------

xterm*geometry:           100x25
xterm*faceName:           inconsolata:pixelsize=15
!xterm*font:             -*-dina-medium-r-*-*-16-*-*-*-*-*-*-*
xterm*dynamicColors:      true
xterm*utf8:               1
xterm*eightBitInput:      true
xterm*saveLines:          512
xterm*scrollTtyKeypress:  true
xterm*scrollTtyOutput:    false
xterm*jumpScroll:         true
xterm*multiScroll:        true
xterm*toolBar:            false

! xscreensaver ---------------------------------------------------------------
!font settings
xscreensaver.Dialog.headingFont:        -*-dina-bold-r-*-*-12-*-*-*-*-*-*-*
xscreensaver.Dialog.bodyFont:           -*-dina-medium-r-*-*-12-*-*-*-*-*-*-*
xscreensaver.Dialog.labelFont:          -*-dina-medium-r-*-*-12-*-*-*-*-*-*-*
xscreensaver.Dialog.unameFont:          -*-dina-medium-r-*-*-12-*-*-*-*-*-*-*
xscreensaver.Dialog.buttonFont:         -*-dina-bold-r-*-*-12-*-*-*-*-*-*-*
xscreensaver.Dialog.dateFont:           -*-dina-medium-r-*-*-12-*-*-*-*-*-*-*
xscreensaver.passwd.passwdFont:         -*-dina-bold-r-*-*-12-*-*-*-*-*-*-*
!general dialog box (affects main hostname, username, password text)
xscreensaver.Dialog.foreground:         #ffffff
xscreensaver.Dialog.background:         #111111
xscreensaver.Dialog.topShadowColor:     #111111
xscreensaver.Dialog.bottomShadowColor:  #111111
xscreensaver.Dialog.Button.foreground:  #666666
xscreensaver.Dialog.Button.background:  #ffffff
!username/password input box and date text colour
xscreensaver.Dialog.text.foreground:    #666666
xscreensaver.Dialog.text.background:    #ffffff
xscreensaver.Dialog.internalBorderWidth:24
xscreensaver.Dialog.borderWidth:        20
xscreensaver.Dialog.shadowThickness:    2
!timeout bar (background is actually determined by Dialog.text.background)
xscreensaver.passwd.thermometer.foreground:  #ff0000
xscreensaver.passwd.thermometer.background:  #000000
xscreensaver.passwd.thermometer.width:       8
!datestamp format--see the strftime(3) manual page for details
xscreensaver.dateFormat:    %I:%M%P %a %b %d, %Y

.vimrc

If you want to do any kind of advanced text editing (programming, etc), you’ll want a proper editor. And vim is definitely a suitable option when configured properly.
My .vimrc below is largely inspired by Steve Losh’s “Coming Home to Vim“, though it does contain some of my own preferences as well.
With regards to Vim, there are a couple of plugins I recommend you download. The script below only contains a couple of them: ZenCoding and CloseTag, but have a read of the above article and find your own combination.

 " Get indentation
set autoindent

set guioptions-=T " Remove toolbar
set vb t_vb= " No more beeps
set backspace=2 " Backspace over newlines

" GUI fixes
set ruler " Where am I?
set ttyfast
set laststatus=2

" Relative line numbers
set relativenumber

" Permanent undo
set undofile

" Autocomplete
set wildmenu
set wildmode=list:longest

" Fix tabs
set shiftwidth=4
set softtabstop=4
set tabstop=4
set expandtab

" Get syntax
syntax on

" Style vim
colors clouds

" Keymaps
let mapleader = ","
nnoremap <tab> %
vnoremap <tab> %
inoremap <F1> <ESC>
vnoremap <F1> <ESC>
vnoremap <F1> <ESC>
inoremap jj <ESC>

" Good-bye arrow keys... =(
nnoremap <up> <nop>
nnoremap <down> <nop>
nnoremap <left> <nop>
nnoremap <right> <nop>
inoremap <up> <nop>
inoremap <down> <nop>
inoremap <left> <nop>
inoremap <right> <nop>
nnoremap j gj
nnoremap k gk

" Proper search
nnoremap / /\v
vnoremap / /\v
set ignorecase
set smartcase
set gdefault

" Script plugins
au Filetype html,xml,xsl,php source ~/.vim/scripts/closetag.vim
au Filetype html,xml,css,php source ~/.vim/scripts/zencoding.vim

" Filetype indenting
filetype indent on

" Load indentation rules and plugins
" according to the detected filetype.
if has("autocmd")
  filetype plugin indent on
endif

" Settings
set nocompatible
set modelines=0
set encoding=utf-8
set scrolloff=3
set showmode
set showcmd
set hidden

set showcmd       " Show (partial) command in status line.
set mouse=a       " Enable mouse usage (all modes) in terminals