Compare commits

...

3 commits

Author SHA1 Message Date
Morten M. Neergaard f91a10bb40
Merge 348c24dda5 into 9da0bd1fbd 2024-02-19 07:17:15 -07:00
Marcel Ribeiro-Dantas 9da0bd1fbd Fix typos 2024-02-13 15:20:04 +01:00
Morten Minde Neergaard 348c24dda5 terminal: handle basic coloring
This closes issue #156
2022-11-03 09:38:23 +01:00
7 changed files with 75 additions and 9 deletions

View file

@ -21,7 +21,7 @@ Wanna build your own level? Great! Here's how to do it:
1. Run the game the easiest way to do so is to run `godot scenes/main.tscn` from the project directory.
1. Get a bit familiar with the levels which are currently there.
1. Take a look into the `levels` directory. It's split into chapters, and each level is a file.
1. Make a copy of an existing level or start writing your own. See the documention of the format below.
1. Make a copy of an existing level or start writing your own. See the documentation of the format below.
1. Write and test your level. If you're happy with it, feel free to send it to us in a pull request! <3
### Level format

View file

@ -35,4 +35,4 @@ test "$(git show main^:c)" != "c"
[congrats]
Well done! Try tavelling between the commits using `git checkout`, so you can look at their contents again!
Well done! Try travelling between the commits using `git checkout`, so you can look at their contents again!

View file

@ -39,7 +39,7 @@ git add recipe
[win]
# Did you resolve the confict and commit?
# Did you resolve the conflict and commit?
{ git show HEAD | grep "Flour"; } && { git show HEAD | grep "Salt"; }
# Did you clear stash stack?

View file

@ -74,7 +74,7 @@ func shell_received(text):
func _notification(what):
if what == MainLoop.NOTIFICATION_WM_QUIT_REQUEST:
#get_tree().quit() # default behavio
#get_tree().quit() # default behavior
get_tree().change_scene("res://scenes/survey.tscn")

View file

@ -26,9 +26,12 @@ func run(command, crash_on_fail=true):
exit_code = shell_command.exit_code
return shell_command.output
func run_async(command, crash_on_fail=true):
func run_async(command, pretty_command=null, crash_on_fail=true):
var shell_command = ShellCommand.new()
shell_command.command = command
shell_command.pretty_command = command
if pretty_command:
shell_command.pretty_command = pretty_command
shell_command.crash_on_fail = crash_on_fail
var t = Thread.new()
@ -48,6 +51,7 @@ func run_async_thread(shell_command):
var env = {}
env["HOME"] = game.tmp_prefix
env["TERM"] = "xterm"
var hacky_command = ""
for variable in env:

View file

@ -4,6 +4,7 @@ class_name ShellCommand
signal done
var command
var pretty_command = null
var output
var exit_code
var crash_on_fail = true

View file

@ -15,6 +15,17 @@ onready var main = get_tree().get_root().get_node("Main")
var shell = Shell.new()
var COLORS = [
Color.webgray, # black
Color.crimson, # red
Color.chartreuse, # green
Color.gold, # yellow
Color.royalblue, # blue
Color.magenta, # magenta
Color.cyan, # cyan
Color.white # white
]
var premade_commands = [
'git commit --allow-empty -m "empty"',
'echo $RANDOM | git hash-object -w --stdin',
@ -82,16 +93,63 @@ func send_command(command):
input.editable = false
completions.hide()
var pretty_command = command
# If someone tries to run an editor, use fake-editor instead.
var editor_regex = RegEx.new()
editor_regex.compile("^(vim?|gedit|emacs|kate|nano|code) ")
command = editor_regex.sub(command, "fake-editor ")
# If someone tries to run git and don't pipe it, add color
var commands = command.rsplit("|", 1)
var git_regex = RegEx.new()
git_regex.compile("^git ([^>|]*)$")
commands[-1] = git_regex.sub(commands[-1], "git -c color.ui=always $1")
var gnu_color_regex = RegEx.new()
gnu_color_regex.compile("^(\\s*([a-z]?grep|ls|diff))\\b([^>]*)$")
commands[-1] = gnu_color_regex.sub(commands[-1], "$1 --color=always$3")
command = "|".join(commands)
shell.cd(repository.path)
var cmd = shell.run_async(command, false)
var cmd = shell.run_async(command, pretty_command, false)
yield(cmd, "done")
call_deferred("command_done", cmd)
func add_ansi_command(pager, cmd):
pager.push_color(Color.darkgoldenrod)
pager.add_text("$ ")
pager.push_color(pager.get_color("default_color"))
pager.add_text(cmd.pretty_command + "\n")
func perform_ansi(pager, codes):
# TODO lacks support for bold, italics, strikthrough, strong colors, etc
# Not doing that for now because there are no relevant fonts anyways.
for code in codes.split(";"):
match code:
"","0","39": # reset, reset, normal color
pager.push_color(pager.get_color("default_color"))
_: # 30 <= code <= 37 -> colors
var color_index = int(code) - 30
if (color_index >= 0) and (color_index <= 7):
pager.push_color(COLORS[color_index])
func add_ansi_output(pager, cmd):
var escape_start = char(27) + "["
var escape_end = "m"
var data = cmd.output
while escape_start in data:
var parts = data.split(escape_start, true, 1)
pager.add_text(parts[0])
if parts[1].begins_with("K"):
data = parts[1].substr(1)
continue
if "m" in parts[1]:
parts = parts[1].split("m", true, 1)
data = parts[1]
perform_ansi(pager, parts[0])
else:
data = parts[1]
pager.add_text(data)
func command_done(cmd):
if cmd.exit_code == 0:
$OkSound.pitch_scale = rand_range(0.8, 1.2)
@ -102,11 +160,14 @@ func command_done(cmd):
input.text = ""
input.editable = true
add_ansi_command(output, cmd)
if cmd.output.length() <= 1000:
output.text = output.text + "$ " + cmd.command + "\n" + cmd.output
add_ansi_output(output, cmd)
game.notify("This is your terminal! All commands are executed here, and you can see their output. You can also type your own commands here!", self, "terminal")
else:
$Pager/Text.text = cmd.output
var pager = $Pager/Text
pager.clear()
add_ansi_output(pager, cmd)
$Pager.popup()
emit_signal("command_done")
@ -116,7 +177,7 @@ func receive_output(text):
repository.update_everything()
func clear():
output.text = ""
output.clear()
func editor_closed():
input.grab_focus()