Monday, December 30, 2013

Zsh History Search

Compared to Fish, currently I like Zsh a little bit more. But one of the unforgettable feature of Fish is its auto-suggestion based on history.
It made command line input so fluent.

Zsh has a feature similar to that called predict. You could configure by placing the following codes in your ~/zshrc.
You could press <Ctrl-Z> to toggle predict on and off.

autoload predict-on
predict-toggle() {
  ((predict_on=1-predict_on)) && predict-on || predict-off
}
zle -N predict-toggle
bindkey '^P'   predict-toggle
zstyle ':predict' toggle true
zstyle ':predict' verbose true

But compared to Fish’s auto-suggestion, I feel that the predict feature is less useful.
The difference show up when you simply type ls<Enter>.

  • In Fish, only ls will be executed.
  • In Zsh, if predict was turned on, ls -la will be executed, which is sometimes not what we want.

So for a more convenient way of accessing command line history, I prefer Zsh’s vi mode and history-search-backward.
You could press <Ctrl-J> and <Ctrl-K> to search history forward and backward.

# vi mode
setopt vi

# bind k and j for history search in vi mode
bindkey -M viins '^k' history-search-backward
bindkey -M viins '^j' history-search-forward
bindkey -M vicmd '^k' history-search-backward
bindkey -M vicmd '^j' history-search-forward

YCM with Clang on Windows

YCM, short for YouCompleteMe, is a fast, as-you-type, fuzzy-search code completion engine for Vim. If built with Clang (v3.2+) support, then it can provide
petty code completion for C/C++ code. On linux, we can get or build Clang easily, but on Windows, it not only hard to build, but also not works well.

Listed below are the steps to compile clang on Windows using MinGW64 and make it work with YCM. Pleas note that the Clang built using this methods can only work as parser, instead of a compiler.
That is to say, you can only use it with YCM to provide code completion, and you won’t be able to use it to compile your code. The reason is that the executable file generated by the Clang we build will crash.

1. Download and install MinGW64

Mingw-w64 is a project that provides support to both 64 bit (x64) and 32 bit (x86) GCC on windows.
You could download the MinGW-w64 package using the link below. You could refer to the reason why we use this particular version on Qt.org.

2. Download and install MSYS.

MSYS is a collection of GNU utilities on Windows.

3. Install SVN

Please download and install SVN. Please make sure svn.exe is on on PATH

4. Get LLVM and Clang code

In a MSYS terminal, execute the following commands to get the Clang’s source code. In my case, it is r192871.

cd ~
svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm

cd ~/llvm/tools
svn co http://llvm.org/svn/llvm-project/cfe/trunk clang

cd ~/llvm/projects
svn co http://llvm.org/svn/llvm-project/compiler-rt/trunk compiler-rt

5. Modify Clang’s code to let Clang know about our include path.

vi ~/llvm/tools/clang/lib/Frontend/InitHeaderSearch.cpp

Find the following method.

void InitHeaderSearch::AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple, const HeaderSearchOptions &HSOpts) {

Within the method, find the following line.

case llvm::Triple::MinGW32:

Add the following lines to right below that position.

// mingw-build C++ include paths
AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "i686-w64-mingw32", "4.8.0");

6. Build LLVM & Clang

In the MSYS terminal, execute the following commands to build Clang.

cd ~
mkdir build
cd build
export CC=gcc
export CXX=g++
../llvm/configure --disable-docs --enable-optimized --disable-assertions --enable-targets=x86,x86_64 --prefix=/mingw
make
make install

7. Install Vim and YCM.

8. Build YCM core

# cd <your YCM folder>
mkdir build && cd build
cmake -G "Unix Makefiles" -DPATH_TO_LLVM_ROOT=/mingw -DTEMP=/mingw/bin/clang.dll . ../cpp
make ycm_core
cp ycm/ycm_core.pyd ../python/ycm_core.dll

That’s it. Enjoy YCM on Windows.

For more information, please refer to the following links.

Setup Pip and Virtualenv

In case we need to run python programs that depends on different versions of same libs, we need to create isolated python environment to avoid those libs interfere with each other. There are two tools can help us achieve that, pip and virtualenv.

1. Install pip

Pip is a package manager used to install and manage python packages. On ubuntu (13.04), you could install it via the following command. You could also download it from here.

sudo apt-get install pip

Note: Depending on your python versions, you may want to install pip or pip-3.x package.

2. Install virtualenv

Virtualenv is the tool to create isolated python environments. On ubuntu you could use apt sources to install virtualenv, or you could always use pip to install it.

sudo pip install virtualenv

3. Create a virtual environment

Once you have the tools installed, you could create a virtual environment using the following command.

virtualenv myenv

4. Use a virtual environment

To use the virtualenv, you could activate it by executing the following command. Basically speaking, it prepend the virtualenv/bin to your $PATH environment variable.

cd myenv
. bin/activate

5. Leave a virtual environment

The following command will revert the changes made by the activate script.

deactivate

Setup Pelican

[Pelican] is a static site generator, written in Python. It allows you write your content in Markdown and reStructuredText. It uses
Here are the steps to setup a hello world [Pelican].

1. Install pip and virtualenv

It is highly recommended to use a virtualenv to create isolated python environment and use pip to manage your packages.
You could refer to my post [Setup Pip and Virtualenv] for instructions to install them.

2. Create a virtual environment

Once you installed virtualenv, you could activate your virtual environment by executing the following command.

virtualenv pelican
cd pelican
. bin/activate

About the last line, if you are using Fish shell, you may need to use . bin/activate.fish instead.

3. Install required packages

pip install pelican markdown

4. Create pelican configuration file

There is a quick start program pelican-quickstart than can help you create a pelican configuration file quickly.
The program will ask you several questions to gather the information needed.

> Where do you want to create your new web site? [.] 
> What will be the title of this web site? Hello World Blog
> Who will be the author of this web site? Your Name
> What will be the default language of this web site? [en] 
> Do you want to specify a URL prefix? e.g., http://example.com   (Y/n) Y
> What is your URL prefix? (see above example; no trailing slash) http://hello-world-blog.com
> Do you want to enable article pagination? (Y/n) Y
> How many articles per page do you want? [10] 8
> Do you want to generate a Fabfile/Makefile to automate generation and publishing? (Y/n) Y
> Do you want an auto-reload & simpleHTTP script to assist with theme and site development? (Y/n) Y
> Do you want to upload your website using FTP? (y/N)
> Do you want to upload your website using SSH? (y/N)
> Do you want to upload your website using Dropbox? (y/N)
> Do you want to upload your website using S3? (y/N)
> Do you want to upload your website using Rackspace Cloud Files? (y/N)

5. Draft the first post

Create a markdown file in content folder.

mkdir content
vim content/the-first-post.md

And paste the following content into it.

Title: Hello World
Date: 2013-10-25
Category: Misc

# Hello World

6. Generate HTML files

After the following command succeeded, HTML files will be generated in output folder.

pelican content -s pelicanconf.py -o output

7. Preview the blog

You could start a local HTTP server by running the following command,
and then you can preview your site at http://localhost:8000

cd output && python -m SimpleHTTPServer

Make Python 3.x Default Python on Ubuntu

If you installed both python version 2.x and 3.x on system, you could add the following line to your ~/.bashrc or ~/.zshrc to make python 3.x the default python.

alias python='python3'

If you want to make pip-3.x and virtualenv-3.x your default ones, you may also add the following lines.

alias pip='pip-3.3'
alias virtualenv='virtualenv-3.3'

Floating Point Binary Representation in C++

Interested in how a float point number is stored in memory? The following C++ code can print it out.

#include <iostream>
#include <bitset>

using namespace std;

int main() {
    float f = 3.14159;
    bitset<32> bs(*(int*)&f);
    cout << bs << endl;
}

The output is 01000000010010010000111111010000.

Apache Thrift

Apache Thrift is a framework for scalable cross-language services development. Compared to SOAP-based and JSON-based web services, Thrift uses its own interface definition language and binary format in communication.

Here are the steps to setup thrift and use it to build a hello world web service.

1. Get Thrift source code.

git clone https://git-wip-us.apache.org/repos/asf/thrift.git thrift
cd thrift

2. Install required tools and libraries.

sudo apt-get install libboost-dev libboost-test-dev libboost-program-options-dev libevent-dev automake libtool flex bison pkg-config g++ libssl-dev

3. Build and install Thrift

./bootstrap.sh
./configure
make
make install

4. Define a simple service interface

# helloworld.thrift
service Foo {
    string bar();
}

5. Generate boilerplate codes

thrift --gen cpp helloworld.thrift
thrift --gen py helloworld.thrift

6. Implement the server in C++.

In gen-cpp folder, edit the file Foo_server.skeleton.cpp, which is an auto-generated skeleton file for server implementation.

class FooHandler : virtual public FooIf {
 public:
  void bar(std::string& _return) {
      _return = "Hello World";
  }
};

In gen-cpp folder, create a CMakeLists.txt file with the following content.

cmake_minimum_required (VERSION 2.6)
project (server)
link_libraries(libthrift.so)
aux_source_directory(. sources)
add_executable(server ${sources})

Then run the following commands.

cmake. && make

7. Implement the client in Python.

In gen-py folder, create a client.py with the following content.

import sys
from thrift.transport import TTransport
from thrift.transport import TSocket
from thrift.protocol import TBinaryProtocol
from helloworld import Foo
from helloworld.ttypes import *

socket = TSocket.TSocket('localhost', 9090)
transport = TTransport.TBufferedTransport(socket)
protocol = TBinaryProtocol.TBinaryProtocol(transport)
client = Foo.Client(protocol)
transport.open()
print(client.bar())
transport.close()

9. Start server.

cd gen-cpp
server &

10. Start client.

cd gen-py
python client.py

And the text Hello World should be printed out.

Keep Both Python 2 and Python 3 on Windows

Here is notes to keep both Python 2 and Python 3 working on Windows.

New in Python 3.3

Start from Python 3.3, there is a py.exe installed to %SystemRoot% directory, which is helpful when multiple versions of Python installed.
  • py -2 and py starts Python 2.x
  • py -3 starts Python 3.x

Use shebang in Python scripts

In favor of py.exe, shebang in Python scripts can be recognized on Windows.
  • #! python 3 for Python 3.x
  • #! python 2 for Python 2.x

Installation order matters

If you install python3 first and then Python 2, the setup program of Python 2 will overwrite the .py file association, such that a Python 3 script with shebang #!python 3 will be executed by Python 2. So the better order is install Python 2 first and then Python 3.

Don’t need to add python to PATH

If both Python 2 and Python 3 executables are on PATH, then there will be confusion. Instead of add Python to PATH and call python your-script.py, the following command also work your-script.py.

Friday, October 18, 2013

Octopress Setup

As the first post of this blog, I’d like to start with how to setup the blog system - Jekyll, a blog aware static site generator, and Octopress, a framework based on it.

Steps

1. Install Git

sudo apt-get install git

2. Install Ruby

At the time of writing, Octopress requires Ruby 1.9.3+.
sudo apt-get install ruby

3. Get Octopress and its dependencies

git clone git://github.com/imathis/octopress.git octopress
cd octopress
gem install bundler
bundle install
On Ubuntu 13.10, the following error occurred at bundle install.
Using rake (0.9.2.2) 
Installing RedCloth (4.2.9) with native extensions 
Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.
...
The following line fix it for me.
    sudo apt-get install ruby1.9.1-dev

4. Install default theme

The following command will install the default Octopress theme.
    rake install

5. Config you blog

The configuration is quite easy, edit octopress/_config.yml and change some values.
Basically for a Hello World blog, you could just change the following lines.
    url: http://yourdomain.name
    title: Your Blog's Title

6. Write a post

The following command will create a new markdown file in source/_post folder.
It’s file name will be like 2013-10-18-hello-world.markdown. Add some test content and
then you are almost ready to see your new blog.
    rake new_post["Hello World"]

7. Generate and preview

Run the following command and visit http://localhost:4000 and enjoy your new blog system.
    rake genreate
    rake preview

Flash Stock ROM to HTC One V

Once I unlocked and rooted my HTC One V mobile phone. After while a weired problem occured. Google Map can’t access network while all other apps can. I tried all kind of tweaks but all failed until I flashed HTC’s stock ROM to it and finally fixed it. Here are the steps to do that in case it can help some one who met with the same problem.

Preparation

Before you can start with flashing, the following preparation work need to be done.

0. !!! Backup your data !!!

Copy all your important data out of the phone.

1. Find your the main version the software on your phone

You can find the number at Settings -> About -> Software information -> Software number.
In my case, the number is 2.24.708.1.

2. Find and download the right RUU for your main version

Normally the following two sites may help. If you can’t find a RUU that matches your main version, then you probably need someone else’s Nandroid Backup to restore your phone.
http://forum.xda-developers.com/
http://www.htcdev.com/DevCenter/downloads/
NOTE: If you downloaded a RUU, please CHECK IT’S DIGITAL SIGNATURE, for security reason.
In my case the RUU file is RUU_PRIMO_U_ICS_40A_hTC_Asia_HK_2.24.708.1_Radio_20.76.30.0835U_3831.19.00.120_release_276653_signed.exe

3. Extract required images from the RUU.

We need boot_signed.img and recovery_signed.img image files. We can extract theme from the RUU by following the steps below.
  • Run the RUU program, but don’t click any button.
  • Go to your %temp% folder, search for a file named rom.zip, which is usually several hundreds of mega bytes in size.
  • Open the rom.zip using 7-zip, and extract the two files out.
  • Exit the running RUU program.

4. Install HTC drivers

The simplest way to install HTC drivers is install HTC Sync Manager software.

5. Get Fastboot executables

To find fastboot.exe, install Android SDK and look in \android-sdk-windows\tools.
Note: fastboot.exe may be unavailable in the latest Windows Android Tools release. You can extract it from a previous release available here: android-sdk_r13-windows.zip You could find fastboot.exe in Android SDK.

Flashing ROM

To flash stock ROM, please follow the steps below.

1. Think again, since it can potentially BRICK YOUR PHONE.

2. Make sure your phone is over half changed.

3. On the Settings -> Developer options screen of your phone, enable USB debugging.

4. Restart your phone with the “Volume Down” button hold down to boot to boot loader screen.

5. Use “Volume Up/Down” buttons to focus the “Fast boot” menu item and press the “Power” button.

6. Connect your phone to your PC via USB, make sure you can see “Fastboot USB” on your phone’s screen.

7. Run the following command on your PC to test if your phone has been detected.

fastboot devices

8. Run the following commands on your PC to flash the boot and recovery images.

fastboot flash boot boot_signed.img
fastboot flash recovery recovery_signed.img

9. Relock the bootloader

fastboot oem lock

10. Run the RUU program and follow the steps.

That’s it. If all the steps succeeds, you phone’s software should be then fresh new.