Default message when Build System starts in Sublime Text

54 views Asked by At

When you run Sublime Build and it finishes, there is a message [Finished ] (in the picture). I would like to add default message when every Build starts to be like "[Started]":

enter image description here

Also it would be nice to add local time when Build System started, e.g. [Started 22:20:23]

1

There are 1 answers

0
MattDMo On

The are (at least) three ways to do this. The first way is to add the functionality to the beginning of your code, so it prints out the information you want. The disadvantage of this method is that the message is printed only when the code begins to run, not at the beginning of the build. Depending on the language you're using, whether it's compiled or interpreted, and the size of your codebase, this could be a significant lag.


The second method is to run your build through a shell file which executes using bash. On Windows, this requires that you have bash installed - Git Bash and Cygwin are two common ways of obtaining it. The following script accepts an arbitrary number of arguments, which it runs after printing "Started" and the date.

#!/bin/bash

echo "[Started at `date`]"
# check to see if we have at least 1 arg
if [ $1 ]
    then
        # replace this process w/ arg(s) so `exec.py` (the Sublime
        # build system) gets the proper return value
        exec "${@}"
fi

Save this file as build.sh somewhere in your PATH.

Now, take a look at the .sublime-build file for the build system you're using, specifically the "shell_cmd" or "cmd" line. If it's a "shell_cmd", all you'll need to do is copy and paste it (without the enclosing double quotes) into the build system below. If it's a "cmd", convert the array/list following "cmd": to a single string. So, for example, if you're using the default Python build system on Windows, "cmd": ["py", "-u", "$file"] would become py -u $file. Essentially, you're converting the array to what you would type at the command prompt, keeping Sublime-internal variables beginning with $ (like $file) intact.

Next, select Tools → Build System → New Build System…. Erase its contents and paste in the following template:

{
    "shell_cmd": "bash -c \"build.sh new_cmd_goes_here\"",
    "working_dir": "$file_path",
    // "file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)",
    // "selector": "source.python",
    // "env": {"PYTHONIOENCODING": "utf-8"}
}

replacing new_cmd_goes_here with the command string you just created in the step above. So, for our Python example, that line would become:

"shell_cmd": "bash -c \"build.sh py -u $file_name\"",

You can uncomment the commented-out lines in the build system template if you wish.

When you're done editing the build system, simply hit CtrlS to save, naming it something like Python (start message).sublime-build, for example. You don't need to change the directory the file is saved in, as Sublime will automatically put it in your Packages/User directory.


The third option is to modify Packages/Default/exec.py to fit your needs. This requires knowledge of Python and Sublime's internals. You can find the basics of how build systems work and how to extend them here.

Briefly, you would save Packages/Default/exec.py as Packages/User/exec_with_dt.py, setting the read_only flag to False if necessary. Next, change the name of the ExecCommand class to ExecWithDtCommand. Then, just after self.proc is defined as an AsyncProcess, add a line calling either self.append_string() (ST3) or self.write() (ST4) writing your desired string to the output. In ST4, I used:

from datetime import datetime as dt
self.write("[Started " + dt.now().strftime("%Y-%m-%d %H:%M:%S") + "]\n")

I haven't tested this in ST3, but the following should work there:

from datetime import datetime as dt
self.append_string(None, "[Started " + dt.now().strftime("%Y-%m-%d %H:%M:%S") + "]\n")

Save the file, then create a new build system with the following contents:

{
    "target": "exec_with_dt",
    "cmd": ["py", "-u", "$file"],
}

I don't recommend this approach unless you really know what you are doing, and the shell script method isn't sufficient for your needs. Other edits may need to be made to exec_with_dt.py to ensure complete parallel functionality with the original exec.py, so look through it carefully. For example, you may want to modify ExecEventListener to ExecWithDtEventListener and change its code to run the exec_with_dt command, just to keep everything in-house.