Sublime Text: “ImportError: No module named sublimeplugin” i.e. bad plugin documentation

TLDR: Sublime Text’s plugin Examples page is out of date as of 30th May 2014. Look at “How to Create a Sublime Text 2 Plugin” for proper guidance.

For the popularity that Sublime Text gets, it seems that their plugin documentation has been left by the wayside

Their Plugin Examples page is out of date showing an example for SublimeText 1. I found that out when creating the plugin only to see the following error message in the Sublime Text console (Ctrl+~ in Windows)

ImportError: No module named sublimeplugin

Searching for this error I landed on this forum post which the link to “How to Create a Sublime Text 2 Plugin” from Tuts+ which seems to work.

There seems to be a change from camelCase to snake_case for functions thus all the instructions on the plugin page are incorrect.

Links API References: choose appropriate link for Sublime Text version

Quickstart to Android Flashing Custom ROMs

Bootloader Android

I know I was a bit confused when initially rooting and installing custom ROMs on my Android device and while I don’t consider myself an expert there are a few terms that could use a quick definition to know your way around custom ROM installations.

Device Modes/States

When you start your device you can boot into 1 of 3 modes

  • Bootloader: a mode that can boot into Recovery or start the regular boot process (into Android) and also shows some details of your device. ROMs can be flashed in the bootloader but it is not the typical case
  • Recovery: a mode to flash ROMs (stock / custom)
  • Regular system boot: boots into the operating system while would typically be Android

Communication Tools

These tools can be used to communicate and even transfer files with your device

  • adb: when in recovery mode / standard Android
  • fastboot : when in bootloader

Unlocking the Bootloader


Boot loaders can be locked which prevents custom ROMS from being flashed. Unlocking the bootloader can be done with the following commands (this was done on a Nexus 7 2013, other devices may need other commands)

  1. Reboot into the bootloader
    adb reboot bootloader
  2. Unlock the bootloader
    fastboot oem unlock

Bootloader unlockBootloader unlock icon

Once the bootloader is unlocked you can install a custom ROM. While I believe it is possible to install custom ROMs without a custom recovery program, the typical way to install a ROM is with one. I’ve used ClockWorkMod Recovery and Team Win Recovery Project (TWRP) but there are others other there. Just make sure you install the right one for your device.

Flashing a Custom ROM

Custom Recovery TWRP

  1. Install a custom recovery
  2. Install it on your device
  3. Download your custom ROM
  4. Reboot your device into recovery
    adb reboot recovery
  5. Follow the on screen instructions to install the ROM
    1. Typically you have to wipe your device (dalvik cache, system and personal data)
    2. Install the custom ROM from a zip file
  6. Reboot into your new ROM

Custom ROMS

  • Custom builds/implementation of Android with some famous ones such as CyanogenMod and ParanoidAndroid (currently I’m using OmniROM)
  • Stock ROMs are the original ROM that came with the device
  • Custom ROMs typically will not have the Google services and usually need to be manually installed. Typically packaged / called gapps
  • Some problem with custom ROMs is usually hardware support: some things may not work as well as they do on stock ROMs. Thus custom ROMs that are based on stock ROMs will probably have better hardware support compared to generic custom ROMs


Other Terms

  • “Unlocked”: this can mean several things
    • Unlocked from a carrier: it can us SIM cards from any carrier
    • Unlocked bootloader: it can load custom ROMs

Things I’m still unsure of

  • If the bootloader needs to be unlocked in order to flash a custom recovery
  • “Secure boot”: shown on the boot loader but doesn’t affect flashing a custom ROM


Android adb Goodness

Thanks to the Ubuntu Touch install page I found out that you can do a full Android backup of apps and data.


adb backup -apk -shared -all

That will create a backup.ab file on your computer which can get huge


adb restore backup.ab

Restoration can be done even on a different ROM and it even maintains settings apps which require you to log in.

Full details of adb backup are as follows and you could selectively backup important app data and such.

adb backup [-f <file>] [-apk|-noapk] [-obb|-noobb] [-shared|-noshared] [-all] [-system|-nosystem] [<packages...>]
 - write an archive of the device's data to <file>.
 If no -f option is supplied then the data is written
 to "backup.ab" in the current directory.
 (-apk|-noapk enable/disable backup of the .apks themselves
 in the archive; the default is noapk.)
 (-obb|-noobb enable/disable backup of any installed apk expansion
 (aka .obb) files associated with each application; the default
 is noobb.)
 (-shared|-noshared enable/disable backup of the device's
 shared storage / SD card contents; the default is noshared.)
 (-all means to back up all installed applications)
 (-system|-nosystem toggles whether -all automatically includes
 system applications; the default is to include system apps)
 (<packages...> is the list of applications to be backed up. If
 the -all or -shared flags are passed, then the package
 list is optional. Applications explicitly given on the
 command line will be included even if -nosystem would
 ordinarily cause them to be omitted.)

Another great adb command is screen recording which I believe is only in Android 4.4 (KitKat) and above

adb shell screenrecord /sdcard/test.mp4

Ctrl+C to stop recording the video

If you have multiple devices connected, use -s deviceID to spec

adb devices
# List of devices attached
# 00bb1122 device
# 0022334455 device
adb -s 0063686250152c5a shell

Masjid Mana?


Stumbled upon OpenBrunei’s Map of Mosques in Brunei-Muara and thought I would do a simple geolocation web app. Still needs much work but very usable ATM for those who require it. Don’t have an app icon yet but you can add it to your home screen on iOS, Android and I believe Windows Phone too.

“Intro to Dart” @ Dart Flight School, Brunei 2014

On the 15th of February the Google Developer Group (GDG) Brunei held a Dart Flight School at DST’s Signature Store.

Dart is a new language that learns from Javascript and adds features that are missing in Javascript such as classes and optional static typing. It aims to provide a better developer workflow and efficiency, better performance vs Javascript and can compile to Javascript in order to be deployed anywhere.

I prerecorded an “Intro to Dart” video just in case as with all things, technology can be troublesome at times =)  There is also a 4 hour long Hangouts on Air recording of the entire event

Intro to Dart slide deck

Dart Flight School

The code labs served as a way to learn Dart and it is even deployable on Heroku. We also covered a bit of Angular JS with a work in progress AngularJS intro project on GitHub.

All in all, Dart seems compelling that it is more performant compared to Javascript, can be compiled to Javascript so you reap the development benefit while still maintaining deployability via Javascript, having a single language for both client and server and adding ‘modern’ features added to Javascript make it easier to develop in. Certainly an alternative to Javascript+Node and perhaps something to use in a future project.

ITLT: Computer Product Pages

So in the previous ITLT post: “Ultrabook & the latest Intel HD Graphics“, I realised how horrendous laptop product pages can be: hard to find the latest models and sometimes even harder to find their specifications at a glance.

In the order of best to worst that I saw are

  1. Apple: basically 2 different skews of notebooks each has 1 page for all specs and extra text with configuration options. Shows full specs and starting prices (MBAs /MBPs)
    Apple - Airs
  2. Apple - Airs specsSony: 1 page showing the 4 different types/segments of notebooks showing screen sizes and start prices. No filtering but the 4 different segments are unique enough that they don’t really need filtering. Each segment shows different models in that segment with processor, screen size & resolution, price. Comparison between models available non obvious page.
    SonySony - detailsSony - current models
  3. Lenovo: results show main specifications (CPU, Graphics, RAM, storage, screen size & resolution, OS, price) items list shows main specifications and has nice sidebar filtering but no filtering on screen resolution. Does not show possible upgrades. No comparison
  4. Dell: 86 results in total but good filtering: checkboxes that work and filterable by 4th gen processor. Results list show OS, Storage, RAM, price.
    Dell - ComparisonDell - Listing
  5. HP: the main page separates devices into “Home” and “Work” which I don’t really like. Results show (screen size and possibly price). Filtering by size shows a checkbox list but it works like an option dropdown – you can select only one. There is no filtering based on processor, so results could be showing you old laptops. Comparison of up to 3 devices to see further specs. 40 devices in total.
    HP - FilterHP - Listing
  6. Asus: Nice sidebar filtering options but dismal details of results listing: only shows screen size. Processor filtering does not show 4th gen processors (only 3rd gen and below). UX 301 LA is named as “Ultrabook” but filtering by “Ultrabook” thinness hides it. Can compare models (max 5) to see more specs. 51 results in the “thin and light” category (176 in all categories) – lots of older models.
  7. Samsung: Results show only screen size. No filtering and shows a lot of older models. Same model of different colour listed as a separate item – meaning there are duplicates. Viewing all shows all 187 results (lots of old models).

It’s sad to see how manufacturers are giving consumers a hard time just looking to find a laptop. It’s even sadder to see some manufacturers showing old models in their listings (Asus and Samsung). Kudos to Sony for simplifying their range to 4 distinct types of laptops but Apple takes the cake due to their minimal yet sufficient product line up and having information rich specification pages.

Quickstart: Git


  • A distributed revision control system
  • Doesn’t require a central server to work
  • Download at:
  • Command line tutorial below, execute code blocks in sequence
  • Lines starting with # are command line outputs or notes
  • Available on GitHub CornerGeeks/test-git


git config --global "John Doe"
git config --global
git config --list

# Doe
# -- other config

git config

# John Doe
  • and is what is recorded in commit logs


Go to a folder in command line and initialise it as a git repository

git init

# # Initialized empty Git repository in /Users/user/test_git/.git/

See current status and branch

git status

# # On branch master
# #
# # Initial commit
# #
# nothing to commit (create/copy files and use "git add" to track)    

Will show current branch and status of files in the folder

Save (Commit) files into the Repo

  • Create a file & add it to the staging area
    touch README
    git add README
  • See current status
    git status
    # # On branch master
    # #
    # # Initial commit
    # #
    # # Changes to be committed:
    # #   (use "git rm --cached <file>..." to unstage)
    # #
    # #    new file:   a
    # #
  • Commit the file
    git commit -m "Added README (C1)"
    # [master (root-commit) 93ecaa8] Added README (C1)
    #  1 file changed, 0 insertions(+), 0 deletions(-)
    #  create mode 100644 README
  • Can also commit with “git commit” then type in the editor and save

Status of Files

  1. Untracked: Will not be saved / commited into the repo (“git add filename” to stage”)
  2. Staged: To be saved into the repo (“git commit” to save into repo and make it unmodified)
  3. Unmodified: Previously committed. Currently has no changes
  4. Modified: Previously committed. Content has changed. Stage file (“git add filename”) in order to commit new version to repo
  • Cannot commit empty folders into git

Staging Files

  • A file needs to be staged before it can be committed
  • A staged file will stage the file at that point in time
    git status
      # # On branch master
      # nothing to commit, working directory clean 
    echo "line 1" >> README
    git status      
      # # On branch master
      # # Changes not staged for commit:
      # #   (use "git add <file>..." to update what will be committed)
      # #   (use "git checkout -- <file>..." to discard changes in working directory)
      # #
      # #    modified:   README
      # #
      # no changes added to commit (use "git add" and/or "git commit -a")
    git add README
    echo "line 2" >> README
    git commit -m "commits only line 1 (C2)"
       # [master 58001d6] commits only line 1 (C2)
       #  1 file changed, 1 insertion(+)      
    git status
      # # On branch master
      # # Changes not staged for commit:
      # #   (use "git add <file>..." to update what will be committed)
      # #   (use "git checkout -- <file>..." to discard changes in working directory)
      # #
      # #    modified:   README
      # #
      # no changes added to commit (use "git add" and/or "git commit -a")      
    git commit -am "auto stage tracked files and commit (C3)"
       # [master cbf5a24] auto stage tracked files and commit (C3)
       #  1 file changed, 1 insertion(+)

Viewing previous commit logs

git log
git log -2
git log --pretty=oneline
git log --pretty="format:%h: %s (%an)"

See previous commit states

-Checkout the state of the repo at any commit

# git checkout previousCommitHashShownInGitLog

git log --pretty=oneline

  # cbf5a24f41bb8a2f70527f5a96cea4fca411910b auto stage tracked files and commit (C3)
  # 58001d6d9c474a6e5b102cf53a1948b0f5fd213d commits only line 1 (C2)
  # 93ecaa8c1238b872827781f6136401e4b9e3849b Added README (C1)


  # line 1
  # line 2

git checkout 25555caa7589363b20b3e1b34bd7ba979c13ff57

  # line 1

git checkout master

  # line 1
  # line 2
  • Think of commits as chain of events linked to the previous commit
    C1 - C2 - C3 <-- master <-- head
  • master is the default branch and points to the last commit in the branch
  • HEAD points to you current location in the commit chain (changes when you checkout)
  • Checking out will move the head pointer and shows the state of the files at the point in time
  • “git checkout master” will point the HEAD back to master which is the latest commit
  • Note: All version of files are stored locally so you can git checkout without any network

Ignoring Files

  • Specify in .gitignore folder
    touch ignore_this_file
    git status
      # # On branch master
      # # Untracked files:
      # #   (use "git add <file>..." to include in what will be committed)
      # #
      # #    ignore_this_file
      # nothing added to commit but untracked files present (use "git add" to track)
    echo "ignore_this_file" >> .gitignore
    git status
      # # On branch master
      # # Untracked files:
      # #   (use "git add <file>..." to include in what will be committed)
      # #
      # #    .gitignore


  • When working on a new feature, create a feature branch, work on it and then merge it into the master branch

View Branches

git branch
    # * master

    # C1 - C2 - C3 <-- master <-- head

Create New Branch

git branch new_feature
    # C1 - C2 - C3 <-- master <-- head
    #           ^
    #           '---- new_feature

git branch
    # * master
    #   new_feature

Switch to new branch

git checkout new_feature
    # Switched to branch 'new_feature'

    # C1 - C2 - C3 <-- master
    #           ^
    #           '---- new_feature <-- head

git branch
    #   master
    # * new_feature

echo "new feature" >> README

git commit -am "new feature added (C4)"          

   # C1 - C2 - C3 <-- master
   #           |
   #           '---- C4 <-- new_feature <-- head

Merging Branches

  • Merge changes from new_feature into master
    git checkout master
      # C1 - C2 - C3 <-- master <-- head
      #           |
      #           '- C4 <-- new_feature
    git merge new_feature master
      # Updating e7578b4..13107de
      # Fast-forward
      #  README | 1 +
      #  1 file changed, 1 insertion(+)
      # C1 - C2 - C3 
      #           |
      #           '- C4 <-- new_feature 
      #               ^
      #               '---- master <-- head
  • As master has not been changed, the master pointer just “fast forwards”

Delete Branch after use

git branch -d new_feature

    # C1 - C2 - C3
    #           |
    #           '- C4
    #               ^
    #               '---- master <-- head

Merge Conflicts

  • Happens when conflicting changes happen between merges
      C1 - C2 - C3 - C4 <-- master
  • Create new branch and switch to it (shortcut)
    git checkout -b merge_conflict
    echo "merge_conflict_branch" > README
    git commit -am "one line README in merge_conflict (C5)"
      # C1 - C2 - C3 - C4 <-- master
      #                |
      #                C5 <-- merge_conflict  <-- head
    git checkout master
    echo "master add new line" >> README
    git commit -am "yet another line (C6)"
      # C1 - C2 - C3 - C4 - C6 <-- master  <-- head
      #                |
      #                C5 <-- merge_conflict
    git merge merge_conflict master
      # Auto-merging README
      # CONFLICT (content): Merge conflict in README
      # Automatic merge failed; fix conflicts and then commit the result.
  • Will now need to edit the README file manually to resolve conflicts
     cat README
       # <<<<<<< HEAD
       #  line 1
       #  line 2
       #  new feature
       #  master add new line
       #  =======
       #  merge_conflict_branch
       #  >>>>>>> merge_conflict
  • New file shows the changes between the branches.
  • Delete and clean the <<<<<<, =======, >>>>>> and text in between.
    • “<<<<<<<” : start of your current branch’s file
    • “=======” : end of your current branch’s file & start of the difference from other (merged) branch changes
    • “>>>>>>>” : end of other branch changesgit commit -am “merged merge_conflict with master (C7)”
       # C1 - C2 - C3 - C4 - C6 -C7 <-- master  <-- head
       #                |
       #                C5 <-- merge_conflict

Show changes

  • Changes that haven’t been staged
    echo "diff me" >> README
    git diff
      # diff --git a/README b/README
      # index 4b7c1e3..f6a1b72 100644
      # --- a/README
      # +++ b/README
      # @@ -4,3 +4,4 @@ new feature
      #  master add new line
      #  merge_conflict_branch
      # +diff me
  • Changes that have been staged
    echo "diff me again" >> README    
    git diff --cached    
    git add README
    git diff --cached
      # diff --git a/README b/README
      # index 4b7c1e3..fbe856c 100644
      # --- a/README
      # +++ b/README
      # @@ -4,3 +4,5 @@ new feature
      #  master add new line
      #  merge_conflict_branch
      # +diff me
      # +diff me again

Unstage a file

echo "to be unstaged" >> README
git add README
git status

  # On branch master
  # Changes to be committed:
  #   (use "git reset HEAD <file>..." to unstage)
  #    modified:   README

git reset HEAD README

  # Unstaged changes after reset:
  # M    README    

git status

  # # On branch master
  # # Changes not staged for commit:
  # #   (use "git add <file>..." to update what will be committed)
  # #   (use "git checkout -- <file>..." to discard changes in working directory)
  # #
  # #    modified:   README
  # #
  # no changes added to commit (use "git add" and/or "git commit -a")

Restore file to previous version

echo "these changes will be reset" >> README
git status

  # # On branch master
  # # Changes not staged for commit:
  # #   (use "git add <file>..." to update what will be committed)
  # #   (use "git checkout -- <file>..." to discard changes in working directory)
  # #
  # #    modified:   README
  # #
  # no changes added to commit (use "git add" and/or "git commit -a")

git checkout -- README
git status

  # # On branch master
  # nothing to commit, working directory clean    

Reset all tracked files to previous commit

git reset --hard
  • Deletes all changes since last commit
  • Only affects tracked files
  • Untracked files do not get deleted

Working with remotes

  • (e.g. GitHub, your own server, etc)

Push Changes to Remote

  • Add a remote to you bare repo
  • “git push repo_name branch_to_push”
    git remote -v
    git init ../git.git --bare
    git remote add my_repo ../git.git 
    git remote -v
      # my_repo  ../git.git (fetch)
      # my_repo  ../git.git (push)
    git push my_repo master
      # Counting objects: 24, done.
      # Delta compression using up to 2 threads.
      # Compressing objects: 100% (14/14), done.
      # Writing objects: 100% (24/24), 2.07 KiB | 0 bytes/s, done.
      # Total 24 (delta 1), reused 0 (delta 0)
      # To ../git.git
      #  * [new branch]      master -> master

Clone from a remote repo

  git clone ../git.git ../git_clone
  cd ../git_clone
  git remote -v
     # origin    /Users/user/test_git/../git.git (fetch)
     # origin    /Users/user/test_git/../git.git (push)      
  • “origin” is the default name of your git repo that you have access to

Download changes from a Remote URL

  # git fetch remote_name
  git fetch origin
  • Does not merge into your existing code, just downloads all changes locally so can merge / checkout

Merge Changes from Remote Branch

  git fetch origin
  git merge origin/master master
    #  **fix any conficts if needed and commit**
    # can also do "git pull origin"

Workflow for pushing to a Repo

  • Clone from Repo
    git clone url_to_git_repo
  • Go into directory and make changes
    cd url_to_git_repo
    echo "cloned" >> README
  • Commit your changes
    git commit -am "my changes"
  • Fetch and merge from origin
    git pull origin
  • Fix conflicts (if any)
    git commit -am "merged origin to masteR"
  • Push to origin
    git push origin master

GitHub Pull Requests

  • Fork a project
  • Clone locally
  • Add remote to project you forked from (typically called “upstream”)
    git remote add upstream git.repo
  • Make your changes
  • Make your commit
    git pull upstream/master master
    *resolve conflicts*
    git commit
  • Use web interface to create pull request
  • Go to your fork
  • Sidebar > Pull Request

Note: Markdown was a pain. It rendered the HTML but a mix of tabs and spaces and even manual spacing caused inconsistent behaviour.