Sublimetext3¶
Most biologists first learn to code by typing directly into a shell, for example by starting an R or Python session in the terminal. Interactive coding environments are also hugely popular, such as RStudio or Jupyter, which provide a code-editor-like experience, where you can view or embed figures, see your variables, and even access useful features like tab-completion.
Code editors provide a different set of features from interactive coding environments, and/or make them available in a faster and/or prettier way. This includes syntax highlighting (colorizing different components of code); linting (checking code for style or syntax errors before you run it); tab-completion (and related documentation searching); building/executing (allows you to test the code with single command); filetree organization (easier to see all files in folders); and perhaps most important of all, keybindings.
Learning objectives¶
In this tutorial you will learn to setup sublimetext
for Python development.
Popular text editors for coding¶
There are many coding text editors available, ranging from complex
to simple, and many have a devoted cult following. Despite the many options,
one modern editor has gained broad popularity recently: vscode
. This has
mostly replaced many editors that came before it, including sublime
, atom
,
emacs
, and vim
. However, in my opinion there are some downsides to vscode
compared to other simpler options.
In particular, it tends to be slow and use a ton of memory, and it contains
many distractions. I prefer a more sleek and minimal code editor. You are
free to explore code editors on your own time, but for this exercise, we
will focus on my personal favorite, sublimetext.
History: Emacs and Vim have been around the longest and have historically been pitted against each other as a sort of zero-sum battle to the death. Everyone learns one or the other, completely falls in love with their choice, and abhors the competing editor. This is partly because they are so different in style, and when you get comfortable with one it feels unnatural to change. Regardless of which coding editor you prefer, I would implore you to become very familiar with at least one coding editor, as the more you learn about how to use it, the more it will superpower your efficiency.
Why sublimetext?¶
I personally recommend sublimetext. It is lightweight while also being super extensible. Compared to vscode it lacks a few features (like a built-in terminal) that set vscode apart, but I am fine with keeping a shell open to the side of my editor, if needed. Sublime starts up faster, and by default, it tries to do less than vscode -- it is more minimal. The default setup for vscode examines your entire operating system and tries to recommend many extensions to you: "I see you are on wsl2, do you want me to install the wsl2 extension?"; "I see that you don't have a linter installed, do you want me to install one?" I find this very intrusive. It leaves you with less knowledge of your setup, since the program tries to do it all for you. Instead, this tutorial will walk you through a step-by-step approach to setting up your editor, and in the end I think you will have a better idea on how to toggle or edit these options. Another cool feature of sublimetext is that the program itself is written in Python!
Install SublimeText3¶
To install sublimetext go to https://www.sublimetext.com/ and download the appropriate installer for your operating system. If you are on a mac then after downloading the DMG file click to open it and run the installer. When finished it should show you a folder with Applications/ and a SublimeText icon in it. Just drag the icon into your Applications folder and you are done. You can then remove the DMG installer file (e.g., drag it to Trash). If you are on Windows the SublimeText application should be accessible in your applications after installation.
Test scripts¶
To test that your code editor is properly configured we will use it to examine and edit Python scripts organized into a modular directory structure. Here we are not planning to push our changes back to GitHub, so you do not need to fork this repo, you can just clone the version from the URL below. I recommend you first cd into your hacks directory and then clone the repo there.
cd ~/hacks
git clone https://github.com/hackers-test/hack-9-python
Getting started¶
Next, open sublimetext. You should see two panels, a skinny one on the left and
a wider one on the right. If you don't see this, go to the View
tab at the top, and then "Side bar" and select show sidebar.
The left panel (side bar) is the file tree that will show you files and
directories accessible from your path. That's right, just like when using
a terminal, sublime is aware of the location in which you are accessing files.
We can change our location in a number of ways. Let's start by going to the
File tab at the top of sublime, select "Open Folder", and then select
the hack-9-python
folder that we just cloned from where it is located in your filesystem.
This should populate the side bar with files and folders from this
path location.
Another way you can quickly open a editor view to a path if you are using
Linux of MacOSX is to use the subl
command from a terminal, like below.
[Update: it turns out this option is not available by default for Mac users,
see the section at the end of this tutorial for how to set it up. Sorry
Windows users I have not had an opportunity to test this for you yet. I expect
it will require a similar solution as in OSX, but implemented in WSL. This
is totally optional.]
The command palette¶
All of Sublimetext is centered around a feature called the command palette. This is a place where you can access all of the options from the dropdown menus, as well as hundreds of additional options for performing operations in the editor. Many of these have keyboard shortcuts, as we will discuss further below, but many others do not, and can only be accessed by finding them in the command palette. To open the command palette on a Mac press cmd+shift+p (hold down command and shift then press 'p'). You can press this key combination again to close the command palette. The command palette serves as a search bar, so you can begin to type any keywords associated with a command and it will filter the list of possible solutions to match your entry.
Hotkeys and keybindings¶
When describing the benefits of learning a text editor I emphasize that keybindings are one of the most important features. These are learned key-strokes that can be used to accomplish repetitive tasks more efficiently. This includes mundane things like moving your cursor up one line, or to the end of a line, or highlighting and replacing all instances of the word 'foo' with 'bar'. Such common tasks are the bread and butter of programming. By learning to enter a set of keystrokes to perform these activities, rather than using the mouse to select items on the screen, your efficiency will improve 10X. In fact, once your learn a set of keybindings well, you will become so comfortable and dependent on them that you will likely find it exhausting to type text into any other programs, such as MS Word, that does not support the same richness of key strokes.
How do you learn keybindings? Well, you just learned your first one above, the key-stroke cmd+shift+p to open the command palette. Learning others will take time and practice, but it is worth it. My best tips for learning are to: (1) pick a text editor and stick with it; use the text-editor frequently (take notes with it, write documents and code in it); (3) when you find yourself reaching for the mouse, stop yourself, and instead search for the appropriate keystroke and try to infuse it to your muscle memory.
How to look up keybindings? It depends which keybindings you are trying to learn. SublimeText has a default set of keybindings, and those may be the easiest for you to learn, but you also have the choice of installing alternatives. We'll return to this subject in a minute after learning about how to install packages.
Package Control¶
One of the best features of sublimetext is the rich community of developers that create open source packages to extend its capabilities. We will install a few of these now to demonstrate their utility. First, you will need to install the feature that allows you to search for other packages, called "Package Control". To do this, open the command palette and type Install Package Control and select it. After about one second it should finish and you are now ready to install packages.
You can now use the following steps to install any package: - open the command palette (cmd+shift+p) - type install package and select "package control: install package" - enter the name of the program you wish to install and select the match from the dropdown list. - hit enter and wait for it to finish (usually a new tab will pop-up to provide info on the installed package, but sometimes not).
Let's try it first with a simple package called bracket highlighter. This does exactly what it says, it highlights the brackets on either side of your selection when writing code, making it easier to see which bracket closes a given context. Simply follow the 4-step instructions above to install it. If that worked, then continue to install all of the following packages. Don't worry, these are all very small and lightweight, and can be easily toggled on or off.
- BracketHighlighter: highlights the matching bracket in code.
- GitGutter: highlights in the gutter which lines have changed.
- Sublimelinter: enables linters.
- SublimeLinter-contrib-ruff: a specific linter.
- Emacs Pro Essentials: enables emacs keybindings.
Disable or Enable packages¶
If you download a package and decide that you no longer like what it does, you can simply turn it off by typing "disable package" into the command palette and selecting the name of the package you want to disable. (Note: for some packages that affect the look/style of subl you will need to restart it for them to take effect.) Try this now by disabling the package 'Emacs Pro Essentials'. Then open the command palette and type "enable" to find and execute the command to Enable it again.
Keybindings revisited¶
You now have two options for key-bindings, either the default sublime keys, or the set in your disabled package 'emacs pro essentials'. There are other options as well, such as a package that emulates the keybindings in 'vim'. In addition to these, you can actually define any keybindings you want by editing your settings in sublime; simply type keybindings into the command palette it will open up a new window showing you the default system keys on the left, and with a space to write commands to override those on the right. You can mix and match any keys you like. Close this window for now.
The default keybindings in sublime is built especially for this editor, and thus works the most seamlessly, but is highly specific to sublime. The emacs keyset on the other hand uses many of the same keybindings that also work in your terminal (e.g., ctrl-a and ctrl-e to move the cursor to the beginning versus end of a line, as we learned previously), and so learning these provides utility that is more broadly transferrable. Personally, I'm hooked on emacs keybindings and I'll never change. But if you're learning for the first time you may consider one of the alternatives. Even if you implement the emacs or vim keys in sublime all of its other features are still available to you either through different keystrokes, or through the command palette.
Practice using emacs-style keys¶
Basic Keybindings: Readline vs. Emacs Movement and Navigation:
Ctrl + a: Move cursor to the beginning of the line
Ctrl + e: Move cursor to the end of the line
Ctrl + f: Move cursor forward by one character
Ctrl + b: Move cursor backward by one character
Ctrl + n: Move cursor down by one character
Ctrl + p: Move cursor up by one character
Alt + f: Move cursor forward by one word
Alt + b: Move cursor backward by one word
Editing and Deleting:
Ctrl + d: Delete the character under the cursor
Ctrl + k: Kill (cut) the text from the cursor to the end of the line
Ctrl + y: Yank (paste) the last killed text
Ctrl + /: Comment this line
Undo and Redo:
Ctrl + _ (ctrl + shift + -): Undo the last action.
Ctrl + g: Cancel the current command or editing.
Search and History:
Ctrl + r: search up through script from cursor location
Ctrl + h: open search and replace box for one script (local)
Ctrl + shift + f: open search and replace for whole directory (global)
Save changes to a file:
Ctrl + x + s (Ctrl+x then Ctrl+s): Save file.
Configuring for your Python environment¶
For some extensions to work properly they must be able to find the specific Python installation that you want them to use. In this case we of course will want sublime to find our conda installed version of Python and its packages. This can be specified globally, but I prefer to set this option separately for each project, since you may have different conda environments associated with different projects. To do this we need to create a Project file for our current project.
Go the Project
tab at the top of your SublimeText editor and select "Save Project as".
(Follow these instructions carefully). This will open a view to your filesystem with
a default name for the Project file labeled "untitled.sublime-project". Rename this
file to "darwinday.sublime-project" then select in the file browser to make sure it
is saving it to your hack-9-python
directory, then click save. You should now see
the darwinday.sublime-project file in your left side bar. Click on it in sublime to
open it in the edit panel. You should see something like below, which is a mostly
empty JSON format file where we can entere preferences for this project:
{
"folders":
[
{
"path": "."
}
]
}
The only variable defined in here so far is "path", which is telling it the path location of files to show in the left side bar. Follow the instructions below to add additional variables to this that will specify which version of Python we want to use to execute code (i.e., the build system), and some other things.
Configuring a build system¶
Navigate to the file called darwinday.py
in the sidebar file browser. Once
the file is opened, use the dropdown menu to select Tools, Build System, and
then Automatic. Now press CMD+B to build the script (or a
similar keystroke, depending on your system; look in the dropdown menu),
meaning that it will execute the script as if it had been called from the
terminal. The 'automatic' mode should provide a dropdown asking you which
build system to use. Select Python (or something similar that it shows),
which tells it to execute the current file using the default Python build
settings. This is equivalent to calling python darwinday.py
from a
terminal to execute the script. Because this python module
has a __main__
dunder at the end designating which part of the
code is meant to be run as an executable, it should run that part of the
code and print the output in a build-results window that will pop up from
the bottom of sublime. It should print a few strings of text into the
stdout palette that will open at the bottom of your sublimetext editor.
Hopefully this worked. But this is actually NOT what we will be using going forward. In general, we do not want to use the system-wide version of Python, we want to use a specific version that is installed in a conda environment. To do this we will set a specific "build system" for this project.
For this we'll follow instructions below. Go to your Project file in the left
side bar and enter your file path to your conda versin of Python.
To check this is absolutely correct look for this path in your terminal
first by using tab auto-completion. Your path will be similar to my example below,
but different for your OS and username.
Note that you cannot use relative path names here (no .. or ~ characters in
the path). Once your project
script looks similar to the one below, save the file by typing ctrl+x ctrl+s
(or look at the File tab, then save, for the similar keystroke for your OS)
Then save the file and it should ask you to save it in
{
"folders":
[
{
"path": "."
}
],
"build_systems": [
{
"name": "python-conda-base",
"cmd": ["/home/deren/miniconda3/bin/python", "$file"],
"file_regex": "^\\s*File \"(...*?)\", line ([0-9]*)",
"selector": "source.python",
},
],
}
{
"folders":
[
{
"path": "."
}
],
"build_systems": [
{
"name": "python-conda-base",
"cmd": ["wsl", "/home/deren/miniconda3/bin/python", "$file"],
"file_regex": "^(...*?):([0-9]*):?([0-9]*)",
"selector": "source.python"
},
],
}
Note that if you are on Windows WSL you should click on the tab in the code block above to view the slightly different instructions. Please message me if this doesn't work for you, I was not able to test it yet at the time of writing.
Now when you try to build a Python file by pressing CMD+B it will ask you to select either python or python-conda-base as the build option, and you can choose the latter to build with your latest version of Python. To set this as the default choice go to the tool bar and select Tools, Build System, and select python-conda-base instead of Automatic. This will be remembered for this project.
Configuring your linters¶
Next we will install a linter. This is a tool that will highlight errors in your
code for you. First we need to install the linter into our conda environment. We
will use the Python linter ruff
. Run the following in a terminal for your default
conda environment.
conda install ruff -c conda-forge
Next, to configure sublime to be able to find this specific linter let's add the path to the linter to our Project file like below. This goes in a section called settings. As long as we are adding settings I also added a few additional ones that are nice. Once again, set the path to the ruff executable using your filepath, not mine.
{
"folders":
[
{
"path": "."
}
],
"settings": {
"tab_size": 4,
"translate_tabs_to_spaces": true,
"trim_automatic_white_space": true,
"SublimeLinter.linters.ruff.executable": "/home/deren/miniconda3/bin/ruff",
},
"build_systems": [
{
"name": "python-conda-base",
"cmd": ["/home/deren/miniconda3/bin/python", "$file"],
"file_regex": "^\\s*File \"(...*?)\", line ([0-9]*)",
"selector": "source.python",
},
],
}
{
"folders":
[
{
"path": "."
}
],
"settings": {
"tab_size": 4,
"translate_tabs_to_spaces": true,
"trim_automatic_white_space": true,
"SublimeLinter.linters.ruff.executable": "/home/deren/miniconda3/bin/ruff",
},
"build_systems": [
{
"name": "python-conda-base",
"cmd": ["wsl", "/home/USERNAME/miniconda3/bin/python", "$file"],
"file_regex": "^(...*?):([0-9]*):?([0-9]*)",
"selector": "source.python"
},
],
}
Alternative setup options¶
Note: There are other ways to setup sublimetext to try to automate this process, similar
to in vscode. If you go searching you might find instructions to install a sublimetext
text package called anaconda
for interacting with a conda environment. I don't
recommend this.
[Optional] Start subl
from the terminal¶
For some reason the default installation method on OSX does not install
the subl
binary into your PATH. This means that initially you can only
start sublimetext by clicking on the icon in your Applications bar, and then
finding the file or folder that you want to open from within sublimetext.
That's fine, but it feels a bit slow to me. More often, you will
find yourself working in your terminal, cd
'd into a directory that you are working
on, and you will then decide you want to open sublimetext from within that location.
It's convenient to be able to open your editor to a view of your current directory.
So, the first customized setup option we are going to configure is to setup
the subl
binary (if you are on Linux you'll already have it).
Here is a demonstration of what we will enable:
To enable this we will create a new symlink, called subl
, that will be
located in your PATH and point to the installed sublimetext binary in Applications.
Up to this point in class we have only installed local software using conda
.
Here we are instead installing a tool that we want to be available system-wide.
To make this work we will add the symlink to a location where other binaries
are located globally, in /usr/local/bin/
.
You will need permissions to write the symlink into this location, so the
following will ask for your password. Be sure to use tab-completion
(seriously, always) when writing the filepaths below to make sure you do
not enter a typo.
sudo ln -s "/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl" /usr/local/bin/subl
Perfect. Now that subl
is in your PATH you can call it from any location from
your terminal. Try it out for youself now. In your terminal use cd
to
navigate to the ~/hacks
directory and start sublimetext to see all of your
repos for this class in one place in your text editor. Or, you can just enter
the filepath of your hacks folder as the target to subl
like in the example
below:
subl ~/hacks/