denoland / deno

A modern runtime for JavaScript and TypeScript.
https://deno.com
MIT License
95.43k stars 5.3k forks source link

Improvements to REPL #12896

Open bartlomieju opened 2 years ago

bartlomieju commented 2 years ago

Deno REPL got a lot better in recent months: support for TypeScript, transformations for import statements, etc. I think there are a few improvements that we could do that would make REPL even more useful:

Press Ctrl+C to abort current expression, Ctrl+D to exit the REPL

I have not used `.break`, `.clear` and `.editor` so I can't speak much about them. `.load` is IMO not that useful considering that one can just import file. `.exit` has equivalent `close()` function in Deno - the trouble is if you overwrite the `exit` global you might get stuck. `.save` is really useful, dumping all commands used in the REPL to a file means that one can build script interactively and them save it immediately to file.

- don't print `undefined` after evaluating declarations

❯ deno Deno 1.16.2+d8afd56 exit using ctrl+d or close()

const foo = "bar"; undefined function fizz() { return "buzz" } undefined undefined undefined 1+2 3


`undefined` printed after `const foo` declaration and `fizz` function are superfluous and don't really help besides taking up space

In [2]: 21 * 2 Out[2]: 42

In [3]: def say_hello(name): ...: print('Hello {name}'.format(name=name)) ...:


- change prompt in multiline input
Currently prompts looks like this for multiline input:

❯ deno Deno 1.16.2+d8afd56 exit using ctrl+d or close()

function a() { return "a" }

After entering multiline input the next line starts at column 0 and there's actually no prompt displayed. I suggest we follow similar prompt to IPython, so example above would look like:

❯ deno Deno 1.16.2+d8afd56 exit using ctrl+d or close() function a() { .. return "a" ..}

These are just the ideas that I accumulated and decided to write them down. More suggestions are welcome to make REPL as useful as possible.

kitsonk commented 2 years ago

When we talked about .exit before (it used to be that way), the main reason that was argued at the time was that we should not use "magical" commands, but instead leverage the web platform APIs and went with close().

.load I think becomes really confusing and we already support import statements and dynamic import().

Would an automatic history file, like shell history or the Chrome debugger history work better than .save?

For .clear we should ensure console.clear() works properly in the REPL. In fact all the "magical" fun stuff you can do in the Chrome Debug Console outside of the $* selectors hangs off console, which my feeling is a pattern we should continue to follow.

  • don't print undefined after evaluating declarations

This is a significant divergence from both Node.js and every browser console. It is the result of evaluating the statement and a variable assignment statement returns undefined. You then have to pick and choose what the return value of the statement is "useful" and "useless", which becomes really problematic quickly. Like for example, defining a function.

I agree the multi-line could be improved.

bartlomieju commented 2 years ago

When we talked about .exit before (it used to be that way), the main reason that was argued at the time was that we should not use "magical" commands, but instead leverage the web platform APIs and went with close().

That's true, OTOH one can override value of close() while "magical command" like .exit wouldn't be overridable. ie, you could create .exit() function, but it would be different that .exit.

.load I think becomes really confusing and we already support import statements and dynamic import().

I agree and as per issue I suggest not to do it.

Would an automatic history file, like shell history or the Chrome debugger history work better than .save?

There is a history file, but I'd argue it's cumbersome and requires a lot of work to extract the commands you used current session; much more work than .save ./session.js.

For .clear we should ensure console.clear() works properly in the REPL. In fact all the "magical" fun stuff you can do in the Chrome Debug Console outside of the $* selectors hangs off console, which my feeling is a pattern we should continue to follow.

This is not entirely true, Chrome Debug Console adds a bunch of magic methods: https://developer.chrome.com/docs/devtools/console/utilities/

This is a significant divergence from both Node.js and every browser console. It is the result of evaluating the statement and a variable assignment statement returns undefined. You then have to pick and choose what the return value of the statement is "useful" and "useless", which becomes really problematic quickly. Like for example, defining a function.

That's a good point, maybe it'd become less confusing if we had numbered prompts.

Solonotix commented 2 years ago
  • don't print undefined after evaluating declarations

This is a significant divergence from both Node.js and every browser console. It is the result of evaluating the statement and a variable assignment statement returns undefined. You then have to pick and choose what the return value of the statement is "useful" and "useless", which becomes really problematic quickly. Like for example, defining a function.

Hi! New user to Deno after hearing many great things. Could this be configurable, such as a .denorc file, or an environment variable like DENO_ONLY_DEFINED? I agree consistent standards should be followed, but allowing a user to configure their preference should also be considered of value.

I don't have any stakes in this, as I've just accepted the existing behavior across multiple platforms, but I know other REPLs (i.e. Python) intentionally suppress printing undefined values.

raythurnvoid commented 9 months ago

Julia has an incredibly good REPL experience and the integration with VSCode makes it even better.

Great features to note when using vscode: