Opening Sublime Text from the command line
I nearly always open Sublime Text from the command line using subl and have specific requirements for when it should open a new window or re-use one.
If I’m opening a directory, then I would like it to re-use the same window if I have previously opened that directory. However if I open a random file, I never want that file in the last directory window as it’s unrelated.
To do this I wrote a simple bash function:
# subl: wrapper that opens files in a new window, and reuses the window
# for directories
subl() {
local args=() opts=()
for a in "$@"; do
if [[ "$a" == -* ]]; then
opts+=("$a")
else
args+=("$a")
fi
done
# No path argument means the current directory
[[ ${#args[@]} -eq 0 ]] && args=(.)
if [[ ${#args[@]} -eq 1 && -d "${args[0]}" ]]; then
# Single directory: open in same window
command subl "${opts[@]}" "${args[0]}"
else
# File(s): so open in a new window
command subl -n "${opts[@]}" "${args[@]}"
fi
}
Firstly we determine which parameters on the command line are arguments and which are options. Options start with a dash and arguments are either file or directory names.
After that, we inspect the arguments.
- If there’s no arguments, or if there’s one argument that is a directory, then we open Sublime Text with the arguments and options we collected and a new directory window opens, unless the directory is already open, in which case it is reused.
- Otherwise we open Sublime Text with the -n option in addition to those passed in. This has the effect of forcing a new window to open.
Remembering which files were last open
This works really well, but if I close a directory window and then open it again, it has forgotten which files I had open. To get Sublime Text to remember, we need a project file. This is a JSON file with the extension .sublime-project file and a minimal one would be:
{
"folders": [
{
"path": "."
}
]
}
We then open a directory with subl foo.sublime-project and then the open files are persisted across sessions.
Obviously, I’m not going to manually create this file or remember to use it as argument, so I extended my subl() function to manage the project file for me:
# subl: wrapper that opens files in a new window, and directories in the same
# window as a Sublime project, reusing an existing .sublime-project, creating
# one if opening a dir.
subl() {
local args=() opts=()
for a in "$@"; do
if [[ "$a" == -* ]]; then
opts+=("$a")
else
args+=("$a")
fi
done
# No path argument means the current directory
[[ ${#args[@]} -eq 0 ]] && args=(.)
if [[ ${#args[@]} -eq 1 && -d "${args[0]}" ]]; then
# Single directory: use existing project or create one, then open in same window
local proj
proj=$(find "${args[0]}" -maxdepth 1 -name '*.sublime-project' -print -quit)
if [[ -z "$proj" ]]; then
local name
name=$(basename "$(cd "${args[0]}" && pwd)")
proj="${args[0]}/${name}.sublime-project"
cat > "$proj" <
The comment covers what happens. Firstly we check for a sublime-project file. If one doesn't exist, then we create a default one called {directory name}.sublime-project. I'm not particularly interested in this project file, so I exclude it from the Sublime Text side bar using the file_exclude_patterns option within the project file itself. Then we open the project with the options that were provided on the command line.
Now subl . in a fresh directory creates a hidden project file and opens it, and every subl after that picks the project back up with my files open exactly where I left them.


