Sublime Forum

Build System Output

#1

I made a new build system and the output for some builds (depending on the function and result) can be different compared to when it is run in the Terminal on macOS. The difference is mainly due to the output in ST3 having “”;"" instead of line breaks in Terminal. This is the current build system code:

{
"shell_cmd": "/Users/Documents/Code/bin/j ${file}",
"file_regex": "^(...*?):([0-9]*):?([0-9]*)",
"selector": "source.j"
}

The file I run the build on is located in “/Users/Documents/Code” and I didn’t think it was necessary to specify the working directory.

I could format the output from the build in ST using several find and replaces to match the output when running in terminal but I’m not sure if this is possible (maybe with “file_regex”).

Please let me know how to fix this.

Thanks.

0 Likes

#2

Sublime just captures whatever the program you execute writes to stdout and stderr and displays it. So generally speaking it should display the same thing as the terminal. Where this falls down is in things like terminal emulation; If a program is generating sequences that tell the terminal to move the cursor or change the text color, Sublime’s going to just display those as-is.

Additionally it can fall down if you’re running a program that uses a line-feed at the end of lines so that it can go back and update the same line (for example when display a running percentage of a job done) because internally all output is dumped directly to the output panel without translation and all line endings are normalized.

From the sounds of your problem it seems like the first one may be the issue. Possibly the ANSIEscape package could be of use to you in this case.

This is possible, but not via file_regex; that’s just used by Sublime to detect error messages in the output of the program so that you can navigate to them in your code, they don’t adjust the content at all.

The program you execute can perform manipulations on the output (say for example your sublime-build executes a script that runs your program and rewrites the output that Sublime sees) or for a more advanced technique you could write a plugin that modifies the output as it’s appearing in the output panel. That’s a fairly advanced topic though.

0 Likes

#3

Thanks for the reply OdatNurd and all of the information! I could have the build sent/run in Terminal and view it there. I’ve seen a number of posts regarding this but haven’t been able to make it work.

The executable/compiler is located here - “/Users/Documents/Code/bin/j”
The file I’m working on is located here - “”/Users/Documents/Code"

Any help would be appreciated. Thanks.

I’ve also seen someone mention that it’s not always necessary compile every time you run it (i.e. when you just modify some external resources or play with main args).

0 Likes

#4

One of the more simple and robust ways to do what you want to do is by using the Terminus package. If you install that package, you gain access to the ability to open a terminal emulator directly inside of Sublime text.

One of the features of this is the ability to use it in a build system; the build will open a new Terminus tab, execute the build inside of it just like in a normal terminal, and then quit. One of the nice things about this is that you can also run programs that you need to manually interact with, which Sublime doesn’t support by default.

If you install Terminus, you could create a build system such as the following:

{
    "target": "terminus_open",

    "cmd": ["/Users/Documents/Code/bin/j", "$file"],
    "working_dir": "${file_path}",
    "auto_close": false,

    "selector": "source.j"
}

This build will open a Terminus tab and execute the program inside of it. This video covers installing and using Terminus, including using it in a build system like this. A more expanded version of this topic can also be found in this video as well.

This is true of languages where there are a lot of preparatory steps to running the program, but it’s not always needed.

For example, in the C and C++ programming languages, you need to pass your program through a compiler to generate an object file, then run a separate tool to link that object file and the require libraries together in order to come up with the final executable, which you can then run.

If your program is made up of two or more files, then there’s no need to compile files that you haven’t modified because the result is going to be the same object file anyway. Similarly if you’re not actively modifying your program and just running it, then compiling and linking is also a waste of time because the executable isn’t going to change.

I’m not familiar with J as a programming language, but from a (little) google search it appears to be an interpreted language. In that case you pass your program source code to a an interpreter that compiles and runs it as one step (i.e. there are no intermediary files generated).

In such a case, I wouldn’t worry about trying to set something like this up because it would either be not possible or otherwise just not worth it.

If you want to set something like that up you need to know what commands you would use instead of the one you outlined in your original post to re-run a program without compiling it first. Once you know that you can augment your build system with a variant so you can choose that one if you want to.

This video playlist covers the topic of build systems in Sublime text, from the simple to the more advanced, including a video on variants. The video mentioned above also appears here as well.

0 Likes

#5

Thanks for your help once again OdatNurd. Managed to get it working after watching some of your videos. Here’s the code:

{
    "target": "terminus_open",
    "cmd": ["/Users/Documents/Code/bin/j", "$file"],
    "auto_close": "false"
}

Is it possible to also display the build time in the Terminus/shell window that opens? You have spoken about build times previously.

Thanks!

0 Likes

#6

Capturing the build time works in standard build systems because the exec command times the build and prints when it’s done. Terminus doesn’t do that because it’s literally just displaying the output of your program for you.

In order to time something like this, your program would need to do it manually. Alternatively you would need to write a program or script that runs something and times it, and then use that in your build to execute your program.

0 Likes

#7

Thanks again OdatNurd!

How would you change the above build system code to open Terminal instead of Terminus?

I tried changing the first line to the following but it didn’t work:

"target": "terminal_open",
"target": "terminal",

Also, how could you get the build to open in a panel in the same window, as opposed to a new file/view?

Thank you.

0 Likes

#8

You just need to provide panel_name when you launch terminal_open.

1 Like

#9

Terminus v0.3.0 now has a setting to show time elapsed (timeit) or even better simply use terminus_exec in your build system. Check https://github.com/randy3k/Terminus#terminus-build-system

0 Likes

#10

offtopic question, what screen recorder are you using here ?

0 Likes

#11
1 Like

#12

Thanks for all your help OdatNurd and randy3k. I’d just like to confirm how to do 2 things (current build code is below with certain lines commented out):

  1. Open the output in Terminal on macOS, and not a new panel/tab? I’ve tried "target": "terminal_open", and also provided a panel name ("panel_name": "j build",), but it didn’t work.

  2. Get the build time? I’ve tried "timeit": "true", but it didn’t work.

Working Terminus build code:

{
    "target": "terminus_open",
    //"target": "terminal_open",
    //"timeit": "true",
    "cmd": ["/Users/Documents/Code/bin/j", "$file"],
    "title": "j build",
    //"panel_name": "j build",
    "focus": "true",
    "auto_close": "false"
}

Also, if any of the build code is not incorporating best practise please let me know.

0 Likes

#13
  1. If what you want is just to run /Users/Documents/Code/bin/j $file on Terminal, checkout SendCode. You could create a sublime-build for example
{
    "target": "send_code",
    "cmd": "/Users/Documents/Code/bin/j '$file'",
    "prog": "terminal"
}

It is quite self explainatory, the command sends the cmd to terminal.

  1. timeit should work, please check if the latest version of Terminus is being used.
0 Likes

#14

Thanks randy3k. Unfortunately neither are working for me. I’ve updated/removed/installed both Terminus and SendCode. I also tried variations of your SendCode code with regard to the naming of the targets for both "target" and "prog".

If anyone has further insights that would be great. Thanks once again.

0 Likes

#15

Perhaps you should tell us what you have tried and what error you encountered if it was not working for you.

0 Likes