This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
cyanisaac's profile picture

What are some innovative features you'd love to see in a shell?

Started by cyanisaac, 26 August 2015 - 04:45 PM
cyanisaac #1
Posted 26 August 2015 - 06:45 PM
I have a project in the works. It's an OS, and it has a custom shell (much like OpenTerminalOS my previous project, just better done).

What features would you like to see? I want some innovative ideas.
SquidDev #2
Posted 26 August 2015 - 07:02 PM
Autocomplete in the middle of a line (instead of just at the end). I've wanted to add it to ClamShell for a while and just haven't found the time.
Exerro #3
Posted 26 August 2015 - 07:19 PM
A bash-like language with piping so I can do something like this: echo "hi" -> myfile.txt. Also, support for multiple commands per line, i.e. "build project; project/run.lua"
Lyqyd #4
Posted 26 August 2015 - 07:46 PM
Hah! It's funny that you mention piping. I just added that feature to lsh. I need to push the changes and move it to its own packman package still, but I've got the basic piping features (|, <, >, >>) done. Other things like &amp;&amp; and ; separators would be relatively simple to add. I also wrote programs that have the basic functionality of less, cat, and a grep variant that uses Lua patterns called glpp. Any program that reads with io.read and outputs with io.write is pipable, since lsh just uses ComputerCraft's ability to redirect the input and output of those functions via the io API.
SquidDev #5
Posted 26 August 2015 - 07:47 PM
A bash-like language with piping so I can do something like this: echo "hi" -> myfile.txt. Also, support for multiple commands per line, i.e. "build project; project/run.lua"

ClamShell supports bash style syntax for pipes, redirects, multiple commands and variables. What would be nice, though of limited use, would be subcommands: ls $(echo rom)
cyanisaac #6
Posted 26 August 2015 - 08:50 PM
Can someone explain piping to me?

And some sort of scripting language for this OS is planned to be implemented before v1.0, however limited I choose to make it, so consider that confirmed.
Exerro #7
Posted 26 August 2015 - 08:54 PM
I'll check out lsh and ClamShell right away, they sound awesome. Phoenix (an OS I'm working on) will certainly have it, but I'm not quite there yet. Theoretically, all it should take is the parsing, I've got piping set up with processes. Any reason you're not just using read()/write() for piping Lyqyd?

Anyway, piping is being able to redirect the output of one program into another. Let's say you have program 'a', which does this:

write "Some string"

If you ran that, it would normally write "Some string" to the shell you ran it from, but by using "a | b.txt" (I think it's the '|' symbol, not entirely sure though), it would write "Some string" to the file b.txt instead. You could also do this between programs, where one calls read(), but instead of having to type it in from the shell, whatever the first program writes, the second gets as a result of read().
SquidDev #8
Posted 26 August 2015 - 08:57 PM
Can someone explain piping to me?

So for instance the "cat" command takes one (or more) file names as arguments and prints it to the screen.

local file = fs.open(..., "r")
write(file.readAll())
file.close()

The linux command grep (or glep for clamshell, glpp for lsh) reads lines in and then prints them out if they match a pattern.

while true do
  local line = read()
  if not line then break end
  if line:matches(...) then print(line) end
end

You could then 'pipe' the output of one program into another. So running "cat foo" would print the contents of foo, but "cat foo | grep [a-z]+" would only print lines with characters on them. The output of cat is redirected into grep. You could then redirect this into a file instead (cat foo | grep [a-z]+ > output.txt) or even input from a file (grep [a-z]+ < foo > output.txt).

From memory the most common piping commands are:
  • commandA | commandB (redirect output of commandA to input of commandB)
  • command > output.txt (write output of command to file output.txt)
  • command >> output.txt (append output of command to file output.txt)
  • command < input.txt (set the input of command to be the contents of input.txt)
Edited on 26 August 2015 - 06:59 PM
cyanisaac #9
Posted 26 August 2015 - 09:17 PM
Can someone explain piping to me?

So for instance the "cat" command takes one (or more) file names as arguments and prints it to the screen.

local file = fs.open(..., "r")
write(file.readAll())
file.close()

The linux command grep (or glep for clamshell, glpp for lsh) reads lines in and then prints them out if they match a pattern.

while true do
  local line = read()
  if not line then break end
  if line:matches(...) then print(line) end
end

You could then 'pipe' the output of one program into another. So running "cat foo" would print the contents of foo, but "cat foo | grep [a-z]+" would only print lines with characters on them. The output of cat is redirected into grep. You could then redirect this into a file instead (cat foo | grep [a-z]+ > output.txt) or even input from a file (grep [a-z]+ < foo > output.txt).

From memory the most common piping commands are:
  • commandA | commandB (redirect output of commandA to input of commandB)
  • command > output.txt (write output of command to file output.txt)
  • command >> output.txt (append output of command to file output.txt)
  • command < input.txt (set the input of command to be the contents of input.txt)

Piping sounds complex but… I think I might be able to implement something like this. I can parse stuff like that pretty easily, so I will definitely consider this. It might use slightly different syntax though, I don't know yet.
Lyqyd #10
Posted 26 August 2015 - 10:14 PM
Any reason you're not just using read()/write() for piping Lyqyd?

Yeah, I wanted to ensure that programs have some way to explicitly choose whether they can be piped or not. If a program just wants an input string, they can use io.read, which by default would call read(), but can also be redirected to gather input from other sources. Same thing with output. Say a program wants to provide useful output that can be redirected, but also decorative output that would not be. They can use io.write for the functional output and print for the pretty/status/etc. output.

Also, don't check out lsh until I have a chance to upload the work I've done on piping! :P/> I'll throw that onto a new github repo of its own tonight.
cyanisaac #11
Posted 26 August 2015 - 11:20 PM
So I assume a way to do things is to override term.write() and have it store the output, then take that output and use it in a shell.run()? (Or put it in a file, etc.)

If that's what it is then I will certainly add that, although I will probably make it some sort of option to enable it (to avoid confusing people)
Exerro #12
Posted 27 August 2015 - 12:15 AM
Well ideally it would work seamlessly without any modification of programs. As for putting it in a shell.run, nah, you'd need to run the different parts in different processes with environments that have custom read/write functions. It's not "running the next program with the output of the first", it's "piping the output of one program into the input of another", i.e. one program's write() calls go to the next's read().
cyanisaac #13
Posted 27 August 2015 - 12:16 AM
Well ideally it would work seamlessly without any modification of programs. As for putting it in a shell.run, nah, you'd need to run the different parts in different processes with environments that have custom read/write functions. It's not "running the next program with the output of the first", it's "piping the output of one program into the input of another", i.e. one program's write() calls go to the next's read().

Oh, yikees that sounds difficult. Erm, I might include piping. Might.

EDIT: and per your earlier request, yes, I will definitely add multiple commands per line.
Edited on 26 August 2015 - 10:18 PM
Lyqyd #14
Posted 27 August 2015 - 01:16 AM
Here's the lsh repo, for anyone curious.

And yes, ideally, piping would work without needing to modify anything, but it's not always practicable. To catch everything, you can't just override write(), as some programs use term.write directly. And if you're using term.write, where do you break up each line of the output? Sometimes multiple writes should be part of one line of output (multi-colored text that would usually be displayed on the screen), but other times, they would not be. I find it easiest to just require that programs be explicitly written to support piping.
cyanisaac #15
Posted 29 August 2015 - 09:12 PM
Here's the lsh repo, for anyone curious.

And yes, ideally, piping would work without needing to modify anything, but it's not always practicable. To catch everything, you can't just override write(), as some programs use term.write directly. And if you're using term.write, where do you break up each line of the output? Sometimes multiple writes should be part of one line of output (multi-colored text that would usually be displayed on the screen), but other times, they would not be. I find it easiest to just require that programs be explicitly written to support piping.

I would assume programs that were meant to be piped would not focus on such stupid things like multicolor text, unless it was actually meant to pipe out different things of text.
Lyqyd #16
Posted 29 August 2015 - 10:42 PM
Right, but we're talking about programs that weren't explicitly designed for being piped. The discussion was about how/what to override to capture output from programs not designed for it.
cyanisaac #17
Posted 29 August 2015 - 11:48 PM
Right, but we're talking about programs that weren't explicitly designed for being piped. The discussion was about how/what to override to capture output from programs not designed for it.

Ah, I see.
cyanisaac #18
Posted 30 August 2015 - 03:09 AM
So far the suggestions I have are highlighting midline (which might require a redone read function, IDK), and piping. Are there any other features that you guys would like added? I'm aiming to make a shell to dominate so if there's any other cool features you want let me know!
Lupus590 #19
Posted 30 August 2015 - 04:05 PM
I made a thread in ask a pro with similar questions to this one. You may find it useful. http://www.computerc...tually-a-shell/
Edited on 30 August 2015 - 02:12 PM
cyanisaac #20
Posted 30 August 2015 - 05:20 PM
I made a thread in ask a pro with similar questions to this one. You may find it useful. http://www.computerc...tually-a-shell/

Definitely useful. Thank you very much.