programming

Code editor: Sublime Text 2

I have been looking for a decent code editor for a long time, as my favourite was previously Smultron but it's been slewed with problems in newer OS X releases ever since it was discontinued (and then subsequently forked and re-started as a closed-source application). I tried Eclipse, TextWrangler, Coda, and Xcode at different times but each had little things that I didn't like about them so I kept putting up with Smultron's little glitches.

I came across this thread in r/apple on reddit that suggested Sublime Text 2 and I absolutely recommend it to everyone! I have been using it ever since I first installed it.

The UI is very simple and clean and there's no button toolbar giving it a minimalistic feel (which I prefer in text editors; this is where Eclipse failed me). I should also mention that the whole program is very snappy and it responds very quickly to any query, even complex regex finds across several files or editing large files.

It has some really nice features (some very unique) which are worth mentioning (for simplicity's sake I use Ctrl below as the modifier of choice, on OS X simply substitute with Command):

Cross OS with per-user license

This strictly speaking isn't a "feature" but it certainly is worth mentioning. ST2 merits its $59.99 pricetag based on its features alone but what makes it even more attractive is that it runs very well on Windows, OS X and Linux with portable editions available and the licensing is per-user... Use it at work, at home, on the go, on any number of your computers with any OS. Oh, and did I mention you can even sync your packages & settings across all these machines and OSs via Dropbox? Awesome sauce.

Multi-line editing

After trying it in ST2, the feature now seems so obvious and natural that I wonder how I ever got by without it. Each line receives to receive its own cursor and copy/paste buffer, so you can very easily perform multi-line edits or variable renames. There are also several ways to create several cursors:

  • Select a block of text and then use Ctrl+L to select the whole lines, follow up with Ctrl+Shift+L to split each line give each selected line its own cursor.
  • Hold Ctrl and click where you want to place a new cursor
  • Highlight a text symbol (variable, associative array index or other) and matches will be highlighted. Press Ctrl+D to select them in sequence
  • Open the Find Text (Ctrl+F) and enter your query then click Find All

There's a good animated demo of this feature on the ST2 homepage.

Command palette

Press Ctrl+Shift+P to bring up the Command Palette, where various ST2 or plugin actions such as setting file syntax, changing themes, inserting code snippets. The menu updates as you type and displays the best matches to your query. Enter confirms and Esc cancel.

It is particularly handy for add-on packages, as a package may provide some custom snippets or git integration (yes, you can diff and commit)!

Function search

Hit Ctrl+R and start typing a part of a function name. ST2 will filter through all function names in your file and jump to the best match as you continue typing. Enter dismisses the search, Esc cancels.

Package management

ST2 has built-in package management via the Sublime Package Control extension. Simply copy the command from the page and enter it into the Console (opened via Ctrl+`) and it auto-installs. From there, hit Ctrl+Shift+P/Command+Shift+P to install, list or remove a slew of extensions right from with ST2 itself. There's even no need to restart it after installing or removing a plugin, it reloads what's necessary to get you going straight away.

Build system

Although ST2 is a text editor, not an IDE, it does have limited support for compiling & running files directly from within the editor. Its pluggable build system system allows add-ons to supply details on how to compile or run different file types. Ctrl+B runs the one associated with the current file type/syntax. SublimeREPL is a great extension that provides a build system plugin and can also run interpreters as a new tab inside ST2.

Extremely customizable preferences

The ST2 preferences file is simple a JSON-like file where you place the parameters. Getting it set up the way you like may be a bit tricky since there is, at the moment, no preferences UI. That said, ST2 is one of the most flexible text editors I have encountered and practically every aspect can be tweaked provided you can find the configuration parameter's key name.

Edit single file in many places

Smultron had this feature as well but it was horribly buggy so I never was able to use it much... It works flawlessly in ST2. Just select File > New View Into File... and it opens up a new tab of the current file. You can view and edit in different portions, both buffers update simultaneously and undo/redo history works across views into the same file.

Layout customization

Alt+Shift on Windows or Command+Alt on Windows allows you to layout the window in various configurations such as right/left or top/bottom. Triple column/row or 2x2 grid modes are also supported. These prove to be very useful in combination with the multi-view feature mentioned earlier, as you can setup to have 2+ views editing same file at different locations in a single window.

My thoughts on Java (part 2)

Sometimes, I feel like people give Java a bad rap. It's a language that's in demand out on the field and after using it for my school classes, I have found that it is easy to program in, it performs very well and your code is portable/cross-platform. Sounds great, right? At first glance Java magically turns everything that's hard to do into something easy.

But then I'll use Java-based software and somehow it manages to consistently be extremely complex to setup/configure (ie, tomcat+webapps), to have horrible looking UIs (ie, LimeWire, FreeNode, OpenOffice) and often it consumes lots of resources needlessly (ie, OpenOffice, LimeWire). I mean seriously, you can get a PHP or Python-enabled webserver up and running in under 2 commands on RHEL and then you just need to create a single script file to start serving pages. The Java community really needs to spend some time working on developer/user experience in my opinion.

My thoughts on Java after having used it for 2 months

One thing that has always annoyed me during my CEGEP studies is that although my CEGEP actually offers a computer programming profile, I can't take it. It is much easier for me to study pure & applied sciences in CEGEP and then apply to software engineering or computer science at university afterwards than it is to take the computer programming route at CEGEP because then I would be stuck catching up on a bunch of the requirements like calculus and physics after CEGEP.

You might ask, "Pure & applied sciences aren't so bad... So why is it annoying?" It's annoying because I cannot take more than one computer science-related course throughout my two years of studies at CEGEP in pure and applied science. Anyways, that ranting just to say that I've been saving that one computer-related class for my last semester, so this term I've been attending Introduction to Computer Programming in Engineering.

To my disappointment, I found out that we were going to be using Java throughout the entire class in class (I was hoping for a more modern programming language like Python, which I think would have been better suited for programming beginners). I've also always hated Java. Up until now I didn't really have a solid foundation for the hate - I just didn't like anything about it.

Now that two months of the course have gone by, I can say that I still dislike Java. I'll keep my reasons quick and to the point, but keep in mind that I'm saying this from the perspective of designing user applications to be run on a desktop machine:

  • For the longest time, Java was closed-soure and remained under the sole control of Sun Microsystems (now Oracle). Although most of Java has now been open sourced, the OpenJDK implementations are still incomplete.
  • Have you ever seen a GUI Java project? Even with a good deal of theming, they tend to look terrible next to some of the C++ GUI projects using Qt or WxWidgets for example. I'm a big fan of ease of use and good user interfaces, and Java does this very poorly with very little integration with the OS running the JVM. This point alone is enough to make me never touch Java again.
  • Java has much of the complexity of C or C++... So why not just program in C or C++? Doing the bit of extra work to handle garbage collection and getting it to work on multiple platforms will just make you a more experienced and better programmer in the long run. In addition, if you decide to use a toolkit like Qt or WxWidgets then much of the multi-platform work is done for you already.
  • Java has many annoying quirks:
    • Only one public class per file allowed
    • The filename must be the same as the name of that one public class
    • For all functional purposes it doesn't matter, you cannot make a simple, global "subroutine" in Java; everything must be a method and belong to a class.
  • It's clunky. If you start to add in GUI, networking and a few other components to your program it starts to get pretty large and resource-intensive. A C++ equivalent of the same program would be more efficient.

And there you have it: why I don't like using Java for real world application programming. Java certainly has its place - I think that it takes care of the mobile market/niche wonderfully - but for desktop applications Java is the wrong tool for the job.

Writing cross-platform applications with Git, Qt and CMake

I've been working a lot on the new fwbackups branch, where my main goal was to make it faster, more versatile and cross-platform. I decided to write it in C++ and use Qt for the interface, since when combined with CMake it would be very easy to have it compiling on all platforms. Stick the code into a git repo and you've got cross-platform building with cross-platform revision control! If you're looking for a way to setup a cross-platform application, I've listed the steps I took below:

Step 1: Install the Dependencies

Before we begin, you'll have to install a few dependencies:

Step 2: Create the git repository

Now that you have Git installed, it's time to create the Git repository which will host your project. Open up a command line and type:

  • Linux (Applications Menu > System Tools > Terminal), Unix or Mac OS X (Macintosh HD > Applications > Utilities > Terminal):

    mkdir -p ~/development/ProjectName
    cd ~/development/ProjectName
    git init
  • Microsoft Windows (Start > Run, type "cmd"):
    mkdir "My Documents"
    mkdir "My Documents\development"
    mkdir "My Documents\development\ProjectName"
    cd "My Documents\development\ProjectName"
    git init

This will initialize a git repository called ProjectName inside the "development" folder in your home. You can replace ProjectName with whatever you'd like, but just remember to replace all further instances of it in this tutorial with the same name.

If you'd like to share the project and authorize with other developers to commit to the Git repository, be sure to check out gitosis.

Step 3: Directory Layout

While it's not required, I chose to use an out-of-source build to help keep the source directories clean and keep the build files for each platform separate. Inside your newly-created ProjectName folder, create the following directory tree:

  • build/
  • build/mingw/
  • build/linux/
  • build/osx/
  • build/unix/
  • pixmaps/
  • src/
  • translations/

Step 4: Configure CMake

The last step is to configure CMake. When CMake is invoked, it reads the CMakeLists.txt file and then automatically generates Makefiles for your platform. Use this template CMakeLists.txt file and save it in the ProjectName directory created earlier:

# Name of the project
project( ProjectName )

# Essentially, just split up your project version numbers by the dot.
# These variables map version 0.0.1 of ProjectName.
set( VERSION_MAJOR "0" )
set( VERSION_MINOR "0" )
set( VERSION_PATCH "1" )

if( APPLE )
  # If we're running OS X, we need CMake 2.6.0
  cmake_minimum_required(VERSION 2.6.0)
  set( CMAKE_OSX_ARCHITECTURES "ppc;i386" )
else( APPLE )
  # Otherwise, CMake 2.4.8 is fine
  cmake_minimum_required( VERSION 2.4.8 )
endif( APPLE )

# This project requires Qt4 and Gettext
# If your project does not use Qt or Gettext, simpy remove these lines.
find_package( Qt4 REQUIRED )
find_package( Gettext REQUIRED )

# Enable all compiler warnings
add_definitions( -Wall )

# Process the "src" subdirectory
add_subdirectory(src)

If you're using gettext for translations (as many open-source projects do) then all you need to change is the ProjectName at the beginning and the version number. You'll notice that "add_subdirectory(src)" is called, so the next step is to create the CMakeLists.txt in the ProjectName/src directory:

# All cpp files go here
set(SRC_FILES
    main.cpp
    ProjectName.cpp
   )

# Headers with signal/slot definitions go here
# Remove me if not using Qt
set(MOC_HDRS
    ProjectName.h
    )

# Qt designer interface files go here
# Remove me if not using Qt
set(UI_FILES
    interface/ProjectName.ui
    )

# Qt RC files go here, uncomment if applicable
# Remove me if not using Qt
#set(RC_FILES ProjectName.qrc)

# Remove me if not using Qt
qt4_wrap_ui( UI_HDRS ${UI_FILES} )
qt4_wrap_cpp( MOC_SRCS ${MOC_HDRS} )
# If you're using Qt RC files, uncomment this too
#qt4_add_resources( RC_SRC_FILES ${RC_FILES} )
# Includes the standard Qt libraries
include( ${QT_USE_FILE} )

# Include your headers in the build and source directories
# If you need to include more directories, add them here
include_directories( ${ProjectName_BINARY_DIR}/src
                     ${ProjectName_SOURCE_DIR}/src
                     )

if( APPLE )
  # Define some settings for the Bundle
  set( MACOSX_BUNDLE_BUNDLE_NAME ProjectName )
  set( MACOSX_BUNDLE_GUI_IDENTIFIER "ProjectName" )
  set( MACOSX_BUNDLE_ICON_FILE ProjectName.icns )
  set( MACOSX_BUNDLE_INFO_STRING ""${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}",
                                 Copyright 2008 ProjectName team" )
  set( MACOSX_BUNDLE_SHORT_VERSION_STRING "${VERSION_MAJOR}.${VERSION_MINOR}" )
  set( MACOSX_BUNDLE_LONG_VERSION_STRING "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}" )
  set( MACOSX_BUNDLE_BUNDLE_VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}" )
  set( MACOSX_BUNDLE_COPYRIGHT "(C) 2005-2008 Stewart Adam" )
  # create a bundle with an icon too!
  # If you're not using Qt, uncomment the next line and comment the line below it:
  #add_executable( ProjectName MACOSX_BUNDLE ${SRC_FILES} )
  add_executable( ProjectName MACOSX_BUNDLE ${SRC_FILES} ${MOC_SRCS} ${RC_SRC_FILES} ${UI_HDRS} )
  
  # Allows for bundle re-creation just by running "make". Also installs bundle icon
  add_custom_target( osx_bundle_dirs
    COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/ProjectName.app/Contents/Resources
    COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/ProjectName.app/Contents/MacOS
    COMMAND cp ../../../pixmaps/${MACOSX_BUNDLE_ICON_FILE}
            ${CMAKE_CURRENT_BINARY_DIR}/ProjectName.app/Contents/Resources/${MACOSX_BUNDLE_ICON_FILE}
    # Qt translations - uncomment this line when you need to install them to the bundle
    #COMMAND cp *.qm ${CMAKE_CURRENT_BINARY_DIR}/ProjectName.app/Contents/Resources/
   )
  add_dependencies( ProjectName osx_bundle_dirs )
  # This tells cmake where to place files inside the bundle
  set_source_files_properties( ${ProjectName_RESOURCES} ${ProjectName_TRANSLATIONS}
    PROPERTIES MACOSX_PACKAGE_LOCATION Resources )
else( NOT APPLE )
  # Builds a binary for windows (without cmdline showing), regular for Linux
  # If you need the cmdline showing, remove the WIN32 attribute
  
  # If you're not using Qt, uncomment the next line and comment the line below it:
  #add_executable( ProjectName WIN32 ${SRC_FILES} )
  add_executable( ProjectName WIN32 ${SRC_FILES} ${MOC_SRCS} ${RC_SRC_FILES} ${UI_HDRS} )
endif( APPLE )

# Link Qt to the executable
target_link_libraries( ProjectName ${QT_LIBRARIES} ) 

Step 5: Build the project

Now that CMake is configured, you're good to go! To build the project, run:

cd ~/development/ProjectName/build/osx
cmake . ../../
make

If you'd like to build for Unix or Linux instead of Mac OS X, change the "build/osx" to "build/unix" or "build/linux" respectively. If you're running Windows, you need to reverse the slash direction and add an additional parameter to CMake:

cd "My Documents\development\ProjectName\build\mingw"
cmake . ..\..\ -G "MinGW Makefiles"
make

Join the team

Because of time constrains, it's getting tougher to upkeep every one of my open source projects - If you'd like to help out developing one of them, please let me know.