IndentFinder vim plugin

This is a great little python script that finds out what indentation is used in your source files. The author also provides a vim plugin, which is a life saver for anyone working with others on software projects. It prevents the complete mess that is the result of team members using their own indentation settings on source code. It analyses the text file, and provides reliable hints what indentation settings (tabs vs spaces, number of spaces etc) were used by the author. There is another plugin for the same purpose, which is basically the vimscript port of IndentFinder, but this latter is extremely slow, especially on large files (it seems vimscript was not really meant for parsing thousands of lines every time you open a file).

What I did not really like about IndentFinder was the way it invokes the python interpreter (thus increasing startup time and leaving room for errors), even if python bindings are supported in vim.  One solution could have been simply to create a vim plugin from the python source, but then this would have meant increased maintenance efforts (copying changes from the python source to the vim plugin).  Another possibility was to generate the vim plugin via setup.py from the python source.

First I added a new method to the main class in indent_finder.py:

--- a/indent_finder.py
+++ b/indent_finder.py
@@ -125,16 +125,21 @@ class IndentFinder:
         self.clear()^M
         f = open( fname )^M
         l = f.readline()^M
         while( l ):^M
             self.analyse_line( l )^M
             l = f.readline()^M
         f.close()^M
 ^M
+    def parse_buffer( self, buf ):^M
+        self.clear()^M
+        for l in buf:^M
+            self.analyse_line(l)^M
+^M
     def clear( self ):^M
         self.lines = {}^M
         for i in range(2,9): self.lines['space%d' % i] = 0^M
         for i in range(2,9): self.lines['mixed%d' % i] = 0^M
         self.lines['tab'] = 0^M
 ^M
         self.nb_processed_lines = 0^M
         self.nb_indent_hint = 0^M

It just makes it possible to call the parser with a buffer instead of a file name: vim opens the file and reads its contents into memory, thus it’s easier to pass the buffer itself to IndentFinder.

The second part is modifying setup.py to build the plugin from a fixed header, the python source and a fixed trailer. It turned out distutils is flexible enough to do this easily: you can subset the build class and do your special stuff in it. Easy:

#!/usr/bin/env python

from distutils.core import setup
from distutils.command.build import build
import os
import indent_finder

HEADER = """if exists('indent_finder') || !has('python')
	finish
endif
let indent_finder=1

python << EOS
"""

TRAILER = """EOS

augroup indent
	au!
	au BufRead *.* :py import vim
	au BufRead *.* :py fi = IndentFinder()
	au BufRead *.* :py fi.parse_buffer(vim.current.buffer)
	au BufRead *.* :py vim.command(fi.vim_output())
augroup END
"""

These are our fixed header and trailer parts. We just make sure python is supported in vim, and make IndentFinder parse the opened buffer. The result from IndentFinder is an actual vim command that adjusts indentation settings.

class build_vimscript(build):
	vimscript = "indent_finder.vim"
	pyscript = "indent_finder.py"

	def run(self):
		build.run(self) # call superclass first

		if self.is_vimscript_outdated():
			self.update_vimscript()

	def is_vimscript_outdated(self):
		pyst = os.stat(self.pyscript)
		try:
			vimst = os.stat(self.vimscript)
		except OSError:
			return True
		else:
			if pyst.st_mtime > vimst.st_mtime:
				return True
		return False

	def update_vimscript(self):
		pyf = open(self.pyscript, "r")
		vimf = open(self.vimscript, "w")

		vimf.write(HEADER)
		for line in pyf:
			vimf.write(line)
		vimf.write(TRAILER)

		vimf.close()
		pyf.close()

Here we check that the vim plugin is older than the python source of IndentFinder. If it is, then the plugin is rebuilt. Calling the superclass in our run() method makes sure the other part of the build process is handled the usual way.

setup( 	name = "Indentation Finder",
		version = indent_finder.VERSION,
		description = "Finds of check the indentation used in programming source files",
		author = "Philippe Fremy",
		author_email = "phil at freehackers dot org",
		maintainer = "Philippe Fremy",
		maintainer_email = "phil at freehackers dot org",
		license = "BSD license",
		url="http://www.freehackers.org/Indent_Finder",
		py_modules = [ "indent_finder" ],
		cmdclass={"build": build_vimscript},
		)

Here we’ve just added a new parameter to setup cmdclass tells distutils to use our class for building the package.

And that’s it. The .vim plugin is built and can be copied to
~/.vim/plugin/.

Alienware Android phone release date

Alienware logo
Alienware, the manufacturer of high-performing and extraterrestrial looking game gears is rumored to release an Android-powered cell phone. The concept image below popped up in 2008.
Now, there are rumors a prototype of this phone might be presented on 14-17th February, 2011, at the Mobile World Congress in Barcelona, Spain. Whenever it will be (if ever – many say it remains a concept), we can’t wait. android grin
Alienware Android Cell Phone

Disable scanning in NetworkManager when connected

Nowadays virtually all Linux distributions use NetworkManager to manage available network interfaces.  It makes interfaces connect automatically, for instance wireless network cards associate automatically to the access point with the strongest signal; ethernet cards can be set up via DHCP or configured with static parameters.

However, the strategy for keeping wireless interfaces connected involves scanning all available channels periodically — typically every two minutes.  For some wireless drivers, such as ath5k and ath9k this might take quite a few seconds, which means network traffic will stall for this period.  Even worse, while the problem is known, it is not possible to disable this feature or override the frequency of scans.  Background scanning is supposed to solve this issue, but the ath5k driver in Ubuntu Lucid does not support it yet.

Out of any other options, I decided to disable scanning in the source code and recompile NetworkManager.  It is quite trivial; as a first step, just fetch the source package:

% apt-get source network-manager

This will fetch and unpack the source tree of the network-manager package.

Update: you can install the build dependencies of network-manager via (thanks Andreas for the tip):

% apt-get build-dep network-manager

Save this patch, step into the network-manager folder, and apply the diff:

% curl -O http://nilvec.com/downloads/network-manager_disable-scan-if-connected.patch

% cd network-manager-0.8

% patch -p1 < ../network-manager_disable-scan-if-connected.patch

Update: to make sure Ubuntu won’t reinstall the original package you can bump the version of network-manager via (debchange is in the devscripts package):

% debchange -i

Just bump the version, or extend the version string with an extra part e.g. if you had 0.8-0ubuntu3, make it 0.8-0ubuntu3-disablescanning0.

% fakeroot dpkg-buildpackage

This patches and builds NetworkManager with scanning disabled while connected to an active access point.

% cd .. && sudo dpkg -i network-manager_0.8-0ubuntu3_i386.deb

There you go.  You should restart the network-manager service (or reboot your machine), and everything should work as supposed — no network stalls or lost packets due to wireless scans.

Building cyanogenmod from source

Cyanogenmod 5.0.7 stable has just been released for the Dream, Magic, Nexus One and Droid phones.  This is a great alternative to get Android 2.1 Eclair, especially to G1 (aka Dream) owners, who are still stuck with Android 1.6 — that is likely not going to change, due to the way the flash storage of the Dream is partitioned, not leaving enough room for a full 2.1 software update.

For the brave, it is also possible to build a Cyanogen ROM from source.  However, I haven’t been able to find any complete guide how to do that, so here’s one quick recap how it can be done.

It’s recommended to use Linux for the build process.  Ubuntu 8.04 or later will do.  You need the following packages:

sudo apt-get install git-core gnupg sun-java5-jdk flex bison gperf libsdl-dev libesd0-dev libwxgtk2.6-dev build-essential zip curl libncurses5-dev zlib1g-dev
This is for a 32-bit installation, on a 64-bit system they may have different names or you may have to install the 32-bit version from certain packages.  Ubuntu 9.10 and later doesn’t include Java5 from Sun anymore, but the Jaunty repositories can be used — just add the following lines to /etc/apt/sources.list:
deb http://us.archive.ubuntu.com/ubuntu/ jaunty multiverse
deb http://us.archive.ubuntu.com/ubuntu/ jaunty-updates multiverse
You also need the repo tool to fetch and manage Android source repositories:
curl http://android.git.kernel.org/repo > ~/bin/repo
chmod 755 ~/bin/repo
Once all the tools above are installed you can grab the Cyanogen Eclair repository:
mkdir cm
cd cm
repo init -u git://github.com/cyanogen/android.git -b eclair-ds
repo sync
This will clone all git repositories needed for the build.  It takes some time, so relax and have a coffee or two…  You can also use this time to install the Android SDK if you haven’t done so before, since you will need adb to access your phone.  Make sure the tools folder from the unpacked SDK is in your PATH.
Once you have the repositories you’ve got to extract the proprietary HTC files from your device.  Hook your phone up to your PC via USB.  Make sure your computer can see it:
% adb devices
List of devices attached
HT851N000044    device
Then you can go ahead and fetch the files:
cd vendor/htc/dream_sapphire
./extract_files.sh
If you don’t have your phone at hand you can also download an official HTC firmware and get the necessary files from it.  Go to htc.com and get signed-dream_devphone_userdebug-img-150275.zip.  You can use unyaffs to unpack system.img after you uncompressed the zip file, and then you can copy all necessary files from the folder it was extracted into.
Then go back to your build root, set up the build environment and choose your build target:
cd ../../..
source build/envsetup.sh
lunch
If you use zsh envsetup.sh may fail, but you can simply
unsetopt NOMATCH
in your shell and you’re good to go.  You can build everything with a simple
m
If you only need the OTA-format update zip use:
TARGET_NO_RADIOIMAGE=true make otapackage
One drawback of this process is that it produces an image that barely fits onto the G1 even after repartitioning it with the Danger SPL — there won’t be enough space left for Google applications like Gmail, Market and Talk.  I haven’t been able to find any clue how “official” Cyanogenmod images are built so that it remains slim enough to make Google’s applications also fit onto the phone — the xbin folder contains a squashfs image that spares some megabytes, but it is not enough in itself.  If you install this image you have just built, the Google applications won’t fit.  Perhaps the key is some build option which optimizes for size — if you figure it out, let me know.
Happy hacking!

The ultimate Android smiley list

:-) (smiling android) android-smile

;-) (winking android) Android wink

:-( (sad android) Android sad

:’-( (crying android) Android cry

B-) (cool android) Android cool

:-* (kissing android) Android kiss

:-P (android tongue) Android tongue

:O (angry android) Android angry

O:-) (android angel) Android angel

:-O (gasping android) gasping android

:-[ (blushing android) blushing Android

:-$ (money android) money android

:-! (scared android) scared android

:-/ (android erm) android erm

:-D (android grin) android grin

o_O (confused android) confused android

:-X (android wub) android wub