Skip to content

Instantly share code, notes, and snippets.

@Kacarott
Created September 3, 2020 05:34
Show Gist options
  • Save Kacarott/e750aa216a7dc2bbe0ff4728bdbd7d37 to your computer and use it in GitHub Desktop.
Save Kacarott/e750aa216a7dc2bbe0ff4728bdbd7d37 to your computer and use it in GitHub Desktop.
Inputs for Script

Inputs for Script

Script is a one of my favourite packages for Atom. Run your code, directly from a text editor, in a HUGE number of languages. But it has one major flaw, there is no method of getting command line inputs from the user. This means that beginners trying out

name = input("Enter your name: ")
print("Hello " + name)

are going to be waiting endlessly for a python process that can't get user input.

Terminus

Terminus is another great package for Atom. It adds an internal terminal shell to your Atom window, allowing you to run commands from the comfort of your text editor.

Maybe you already see where I'm going with this. If we can pass commands from Script to Terminus, the 'real' shell window should allow us to enter inputs.

Connecting Script and Terminus

  1. Ensure both Packages are installed.

apm install script

apm install terminus

Or simply search for them in Atom's internal package manager.

  1. From Atom -> Settings -> Packages -> Script -> view code or wherever your atom packages install, find the file script/lib/runtime.js and open it.

  2. Find the function execute() around line 50. Add the following code (I have commented out unchanged lines):

NOTE: The first two lines if (atom.config.get... and this.emitter.emit... need to be moved down the page to the indicated spot.

// execute(argType = 'Selection Based', input = null, options = null) {


//   const codeContext = this.codeContextBuilder.buildCodeContext(
//     atom.workspace.getActiveTextEditor(), argType);

  // In the future we could handle a runner without the language being part
  // of the grammar map, using the options runner
//  if (!codeContext || !codeContext.lang) return;

//  const executionOptions = !options ? this.scriptOptions : options;
//  const commandContext = CommandContext.build(this, executionOptions, codeContext);

  try {
    var terminus = require('../../terminus/lib/terminus.js').provideTerminus();
  } catch (e) {
    var terminus = null;
    console.log("Could not find Terminus");
  }
  if (terminus != null) {
     var command = commandContext.command;
     for (let i = 0; i < commandContext.args.length; i++) {
       command += ' "' + commandContext.args[i] + '"';
     }
     terminus.run(['printf "\\33c\\e[3J" && ' + command]);
     return;
   }


  if (atom.config.get('script.stopOnRerun')) this.stop();
  this.emitter.emit('start');    // These were moved from above!!!

//  if (!commandContext) return;

//  if (commandContext.workingDirectory) {
//    executionOptions.workingDirectory = commandContext.workingDirectory;
//  }

//  this.emitter.emit('did-context-create', {
//    lang: codeContext.lang,
//    filename: codeContext.filename,
//    lineNumber: codeContext.lineNumber,
//  });

//  this.runner.scriptOptions = executionOptions;
//  this.runner.run(commandContext.command, commandContext.args, codeContext, input);
//  this.emitter.emit('started', commandContext);
//}

Also, the line terminus.run( adds the command 'printf "\\33c\\e[3J" && '. This is not necessary but cleans up the terminal after running commands. If you would rather see the run commands in your terminal, then replace that line with simply terminus.run([command]);

Done!

Once that code is in, save and reopen Atom. From now on, when you run Script, it will open in a Terminus window, and accept inputs. I have tested with C++ and Python, and I think it should work for others, but if you run into a problem, let me know.

I hope that was helpful to someone, happy coding!

- Keldan

@aeyates
Copy link

aeyates commented May 21, 2021

Thanks for this snippet. It worked great!

@manngo
Copy link

manngo commented Aug 16, 2021

Works beautifully for me. I was looking for a tool to teach Python, and Atom does so many other useful things. This fills in a gap.

Thanks for your work.

@manngo
Copy link

manngo commented Aug 16, 2021

Hi Keldan

There is one minor issue. Every time I run the script the Terminus window closes and reopens, which is a little distracting. Do you know of a solution to this?

@the-j0k3r
Copy link

@Kacarott

If I may suggest an improvement the code you pasted would perhaps make more sense if you used a diff block inside the md file
described here https://support.codebasehq.com/articles/tips-tricks/syntax-highlighting-in-markdown

--- a
+++ b
@@ -12,9 +12,6 @@ def 'cep.App', class App
 
     if @currentUser.isLoggedIn()
       @logoutView.render()
-      @navigateToDashboard()
-    else
+      @navigateToLoginPage()

@manngo
Copy link

manngo commented Jan 30, 2022

I have found some strange behaviour using Script & Terminus on my Macintosh.

If my document is set to CRLF line breaks, I get the dreaded unexpected indent error. This is regardless of whether I run the whole document or a selection.

This is not a mixed indents issues (I prefer tabs to spaces), and it’s not due to using tabs (I have converted tabs to spaces to see what would happen). I can get it working reliably by switching back to using LF line breaks.

The error occurs in line 1, as:

File "<stdin>", line 1
    "-u" "/Users/mark/Library/Mobile Documents/com~apple~CloudDocs/Training/python/while.py"
    ^

so it’s happening when the script is actually run.

On Windows, this doesn’t appear to be a problem.

I’m still trying to get to the bottom of this.

@amancad
Copy link

amancad commented Aug 6, 2022

Hi wmunmun (Jess),

So I am pretty sure this has to do with a different issue with Atom Script. Atom Script by default uses Python 2.x while your code shows you are using Python 3.x.

It is pretty easy to fix. If you go to script/lib/grammars/python.coffee, you will see on lines 5 and 12 something like:

command: 'python'

Just change them both to be:

command: 'python3'

If the problem persists let me know and I'll dig a bit more. Hope that works!

  • Keldan

In my case the following worked for Windows 10 and paython 3.10 and Atom 1.60:

It is pretty easy to fix. If you go to script/lib/grammars/python.js, you will see on lines 16 and 26 something like:

command: 'python'

Just change them both to be:

command: 'python.exe'


I also confirm that it helped me to change the line:

terminus.run(['printf "\\33c\\e[3J" && ' + command]);

along the line:

terminus.run(['clear; ' + command + '; pause; exit']);
@
in the runtime.js file

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment