2020-09-22 13:15:36 +02:00
|
|
|
extends Control
|
|
|
|
|
2020-10-23 15:08:51 +02:00
|
|
|
enum FileBrowserMode {
|
|
|
|
WORKING_DIRECTORY,
|
|
|
|
COMMIT,
|
|
|
|
INDEX
|
|
|
|
}
|
|
|
|
|
2020-10-23 16:43:02 +02:00
|
|
|
export(String) var title setget _set_title
|
|
|
|
export(FileBrowserMode) var mode = FileBrowserMode.WORKING_DIRECTORY setget _set_mode
|
2020-10-23 15:08:51 +02:00
|
|
|
|
2020-09-22 13:15:36 +02:00
|
|
|
var shell
|
2020-10-23 15:08:51 +02:00
|
|
|
var commit setget _set_commit
|
2020-10-23 15:19:25 +02:00
|
|
|
var repository
|
2020-09-22 13:15:36 +02:00
|
|
|
|
2020-10-23 16:43:02 +02:00
|
|
|
var open_file
|
|
|
|
|
2020-11-17 17:07:16 +01:00
|
|
|
onready var world = $Panel/Margin/Rows/World
|
2020-10-23 16:43:02 +02:00
|
|
|
onready var text_edit = $Panel/TextEdit
|
|
|
|
onready var save_button = $Panel/TextEdit/SaveButton
|
|
|
|
onready var title_label = $Panel/Margin/Rows/Title
|
2020-11-18 18:06:46 +01:00
|
|
|
#onready var player = $Panel/Margin/Rows/World/You
|
|
|
|
var player
|
2020-09-22 13:15:36 +02:00
|
|
|
|
2020-10-23 15:08:51 +02:00
|
|
|
func _ready():
|
|
|
|
update()
|
2020-10-23 16:43:02 +02:00
|
|
|
_set_mode(mode)
|
|
|
|
_set_title(title)
|
2020-11-10 18:34:51 +01:00
|
|
|
$PopupMenu.add_item("New file", 1)
|
2020-11-18 18:06:46 +01:00
|
|
|
#player.file_browser = self
|
2020-11-18 19:21:10 +01:00
|
|
|
|
2020-10-23 16:43:02 +02:00
|
|
|
func _input(event):
|
|
|
|
if event.is_action_pressed("save"):
|
2020-10-26 16:36:38 +01:00
|
|
|
if text_edit.visible:
|
|
|
|
save()
|
2020-11-18 19:21:10 +01:00
|
|
|
if has_focus():
|
2020-11-18 19:33:28 +01:00
|
|
|
if Input.is_action_pressed("pickup"):
|
2020-11-18 19:21:10 +01:00
|
|
|
if player.held:
|
|
|
|
player.held = null
|
|
|
|
else:
|
|
|
|
for item in world.get_children():
|
2020-11-18 19:33:28 +01:00
|
|
|
if item != player and item.item_type == "wd":
|
|
|
|
if item.position.distance_to(player.position) < 150:
|
2020-11-18 19:21:10 +01:00
|
|
|
player.held = item
|
2020-10-23 15:19:25 +02:00
|
|
|
|
|
|
|
func clear():
|
2020-11-17 16:27:16 +01:00
|
|
|
pass
|
2020-11-17 17:07:16 +01:00
|
|
|
for item in world.get_children():
|
2020-11-17 18:31:19 +01:00
|
|
|
if item.label != "":
|
|
|
|
item.queue_free()
|
2020-10-23 15:19:25 +02:00
|
|
|
|
2020-11-10 15:27:42 +01:00
|
|
|
func substr2(s):
|
|
|
|
return s.substr(2)
|
|
|
|
|
2020-11-18 19:33:28 +01:00
|
|
|
func _process(delta):
|
|
|
|
if has_focus():
|
|
|
|
var speed = 300*delta
|
|
|
|
var motion = Vector2(0, 0)
|
|
|
|
if Input.is_action_pressed("down"):
|
|
|
|
motion += Vector2(0,1)
|
|
|
|
if Input.is_action_pressed("up"):
|
|
|
|
motion += Vector2(0,-1)
|
|
|
|
if Input.is_action_pressed("right"):
|
|
|
|
motion += Vector2(1, 0)
|
|
|
|
if Input.is_action_pressed("left"):
|
|
|
|
motion += Vector2(-1, 0)
|
|
|
|
if motion.length() > 0:
|
|
|
|
player.move(motion.normalized()*speed)
|
|
|
|
|
|
|
|
func update():
|
2020-11-17 16:27:16 +01:00
|
|
|
if true:#grid:
|
2020-10-23 15:19:25 +02:00
|
|
|
clear()
|
2020-10-23 15:08:51 +02:00
|
|
|
match mode:
|
|
|
|
FileBrowserMode.WORKING_DIRECTORY:
|
|
|
|
if shell:
|
2020-11-18 19:08:27 +01:00
|
|
|
# Populate HEAD versions.
|
|
|
|
|
|
|
|
if shell.run("test -d .git && echo yes || echo no") == "yes\n":
|
|
|
|
var files = Array(shell.run("git ls-tree --name-only -r %s" % "HEAD").split("\n"))
|
|
|
|
# The last entry is an empty string, remove it.
|
|
|
|
files.pop_back()
|
|
|
|
for file_path in files:
|
|
|
|
var item = preload("res://scenes/item.tscn").instance()
|
|
|
|
item.label = file_path
|
|
|
|
item.item_type = "head"
|
|
|
|
item.type = "nothing"
|
|
|
|
item.file_browser = self
|
|
|
|
world.add_child(item)
|
|
|
|
|
|
|
|
# Populate index.
|
|
|
|
|
|
|
|
if shell.run("test -d .git && echo yes || echo no") == "yes\n":
|
|
|
|
var index_files = Array(shell.run("git ls-files -s | cut -f2 | uniq").split("\n"))
|
|
|
|
#var deleted_files = Array(repository.shell.run("git status -s | grep '^D' | sed 's/^...//'").split("\n"))
|
|
|
|
# The last entries are empty strings, remove them.
|
|
|
|
index_files.pop_back()
|
|
|
|
#deleted_files.pop_back()
|
|
|
|
var files = index_files# + deleted_files
|
|
|
|
for file_path in files:
|
|
|
|
var item = preload("res://scenes/item.tscn").instance()
|
|
|
|
item.label = file_path
|
|
|
|
item.item_type = "index"
|
|
|
|
item.type = "nothing"
|
|
|
|
item.file_browser = self
|
|
|
|
#item.connect("clicked", self, "item_clicked")
|
|
|
|
#item.status = get_file_status(file_path, repository.shell, 0)
|
|
|
|
world.add_child(item)
|
|
|
|
|
2020-11-18 18:36:29 +01:00
|
|
|
# Populate working directory.
|
|
|
|
|
2020-11-10 15:27:42 +01:00
|
|
|
var wd_files = Array(shell.run("find . -type f").split("\n"))
|
2020-10-23 15:08:51 +02:00
|
|
|
# The last entry is an empty string, remove it.
|
2020-11-10 15:27:42 +01:00
|
|
|
wd_files.pop_back()
|
|
|
|
wd_files = helpers.map(wd_files, self, "substr2")
|
|
|
|
|
2020-11-10 18:22:24 +01:00
|
|
|
var deleted_files = []
|
|
|
|
if shell.run("test -d .git && echo yes || echo no") == "yes\n":
|
2020-11-17 10:52:59 +01:00
|
|
|
deleted_files = Array(shell.run("git status -s | grep '^.D' | sed 's/^...//'").split("\n"))
|
2020-11-10 18:22:24 +01:00
|
|
|
deleted_files.pop_back()
|
|
|
|
|
2020-11-10 15:27:42 +01:00
|
|
|
var files = wd_files + deleted_files
|
|
|
|
|
2020-11-18 19:08:27 +01:00
|
|
|
player = null
|
2020-10-23 15:08:51 +02:00
|
|
|
files.sort_custom(self, "very_best_sort")
|
|
|
|
for file_path in files:
|
|
|
|
if file_path.substr(0, 5) == ".git/":
|
|
|
|
continue
|
2020-11-17 17:07:16 +01:00
|
|
|
var item = preload("res://scenes/item.tscn").instance()
|
2020-10-23 15:08:51 +02:00
|
|
|
item.label = file_path
|
2020-11-17 18:31:19 +01:00
|
|
|
item.file_browser = self
|
2020-11-18 18:36:29 +01:00
|
|
|
#item.status = get_file_status(file_path, shell, 1)
|
|
|
|
item.item_type = "wd"
|
|
|
|
#seed(item.label.hash())
|
|
|
|
#item.position = Vector2(rand_range(0, world.rect_size.x), rand_range(0, world.rect_size.y))
|
|
|
|
#randomize()
|
2020-11-17 17:07:16 +01:00
|
|
|
world.add_child(item)
|
2020-11-18 19:51:27 +01:00
|
|
|
if file_path == "you":
|
2020-11-18 19:08:27 +01:00
|
|
|
player = item
|
2020-11-07 13:59:47 +01:00
|
|
|
|
2020-10-23 15:08:51 +02:00
|
|
|
FileBrowserMode.COMMIT:
|
|
|
|
if commit:
|
|
|
|
var files = Array(commit.repository.shell.run("git ls-tree --name-only -r %s" % commit.id).split("\n"))
|
|
|
|
# The last entry is an empty string, remove it.
|
|
|
|
files.pop_back()
|
|
|
|
for file_path in files:
|
2020-10-26 19:15:47 +01:00
|
|
|
var item = preload("res://scenes/file_browser_item.tscn").instance()
|
2020-10-23 15:08:51 +02:00
|
|
|
item.label = file_path
|
2020-10-23 16:43:02 +02:00
|
|
|
item.connect("clicked", self, "item_clicked")
|
2020-11-17 16:27:16 +01:00
|
|
|
#grid.add_child(item)
|
2020-10-23 15:19:25 +02:00
|
|
|
FileBrowserMode.INDEX:
|
2020-11-10 21:51:59 +01:00
|
|
|
#var is_visible = false
|
2020-11-03 16:39:55 +01:00
|
|
|
if repository and repository.there_is_a_git():
|
2020-11-10 15:27:42 +01:00
|
|
|
var index_files = Array(repository.shell.run("git ls-files -s | cut -f2 | uniq").split("\n"))
|
2020-11-17 10:52:59 +01:00
|
|
|
var deleted_files = Array(repository.shell.run("git status -s | grep '^D' | sed 's/^...//'").split("\n"))
|
2020-11-10 15:27:42 +01:00
|
|
|
# The last entries are empty strings, remove them.
|
|
|
|
index_files.pop_back()
|
|
|
|
deleted_files.pop_back()
|
|
|
|
var files = index_files + deleted_files
|
2020-10-23 15:19:25 +02:00
|
|
|
for file_path in files:
|
2020-10-26 19:15:47 +01:00
|
|
|
var item = preload("res://scenes/file_browser_item.tscn").instance()
|
2020-10-23 15:19:25 +02:00
|
|
|
item.label = file_path
|
2020-10-23 16:43:02 +02:00
|
|
|
item.connect("clicked", self, "item_clicked")
|
2020-11-03 16:39:55 +01:00
|
|
|
item.status = get_file_status(file_path, repository.shell, 0)
|
2020-11-17 16:27:16 +01:00
|
|
|
#grid.add_child(item)
|
2020-11-10 21:51:59 +01:00
|
|
|
#if item.status != item.IconStatus.NONE:
|
|
|
|
# is_visible = true
|
|
|
|
#visible = is_visible
|
2020-11-03 16:39:55 +01:00
|
|
|
|
2020-11-10 22:37:10 +01:00
|
|
|
func get_file_status(file_path, the_shell, idx):
|
|
|
|
var file_status = the_shell.run("git status -s '%s'" % file_path)
|
2020-11-03 16:39:55 +01:00
|
|
|
if file_status.length()>0:
|
|
|
|
match file_status[idx]:
|
|
|
|
"D":
|
2020-11-17 17:07:16 +01:00
|
|
|
return Item.IconStatus.REMOVED
|
2020-11-03 16:39:55 +01:00
|
|
|
"M":
|
2020-11-17 17:07:16 +01:00
|
|
|
return Item.IconStatus.EDIT
|
2020-11-03 16:39:55 +01:00
|
|
|
"U":
|
2020-11-17 17:07:16 +01:00
|
|
|
return Item.IconStatus.CONFLICT
|
2020-11-03 16:39:55 +01:00
|
|
|
" ":
|
2020-11-17 17:07:16 +01:00
|
|
|
return Item.IconStatus.NONE
|
2020-11-03 16:39:55 +01:00
|
|
|
"A":
|
2020-11-17 17:07:16 +01:00
|
|
|
return Item.IconStatus.NEW
|
2020-11-03 16:39:55 +01:00
|
|
|
"?":
|
2020-11-17 17:07:16 +01:00
|
|
|
return Item.IconStatus.UNTRACKED
|
2020-11-03 16:39:55 +01:00
|
|
|
else:
|
2020-11-17 17:07:16 +01:00
|
|
|
return Item.IconStatus.NONE
|
2020-09-22 13:15:36 +02:00
|
|
|
|
2020-10-23 13:07:16 +02:00
|
|
|
func item_clicked(item):
|
2020-11-10 15:27:42 +01:00
|
|
|
if item.status == item.IconStatus.REMOVED:
|
|
|
|
return
|
|
|
|
|
2020-10-23 16:43:02 +02:00
|
|
|
match mode:
|
|
|
|
FileBrowserMode.WORKING_DIRECTORY:
|
|
|
|
text_edit.text = helpers.read_file(shell._cwd + item.label)
|
|
|
|
FileBrowserMode.COMMIT:
|
|
|
|
text_edit.text = commit.repository.shell.run("git show %s:\"%s\"" % [commit.id, item.label])
|
|
|
|
FileBrowserMode.INDEX:
|
2020-11-03 16:39:55 +01:00
|
|
|
if item.status == item.IconStatus.CONFLICT:
|
|
|
|
return
|
2020-10-23 16:43:02 +02:00
|
|
|
text_edit.text = repository.shell.run("git show :\"%s\"" % [item.label])
|
2020-11-03 16:39:55 +01:00
|
|
|
|
|
|
|
open_file = item.label
|
2020-10-23 16:43:02 +02:00
|
|
|
text_edit.show()
|
|
|
|
text_edit.grab_focus()
|
2020-11-10 18:22:24 +01:00
|
|
|
|
|
|
|
func item_deleted(item):
|
|
|
|
helpers.careful_delete(shell._cwd + item.label)
|
|
|
|
update()
|
2020-10-23 16:43:02 +02:00
|
|
|
|
|
|
|
func close():
|
|
|
|
text_edit.hide()
|
|
|
|
|
|
|
|
func save():
|
|
|
|
match mode:
|
|
|
|
FileBrowserMode.WORKING_DIRECTORY:
|
|
|
|
var fixme_path = shell._cwd
|
|
|
|
|
|
|
|
# Add a newline to the end of the file if there is none.
|
|
|
|
if text_edit.text.length() > 0 and text_edit.text.substr(text_edit.text.length()-1, 1) != "\n":
|
|
|
|
text_edit.text += "\n"
|
|
|
|
|
|
|
|
helpers.write_file(fixme_path+open_file, text_edit.text)
|
2020-11-03 17:06:22 +01:00
|
|
|
update()
|
2020-10-23 16:43:02 +02:00
|
|
|
close()
|
2020-10-23 13:07:16 +02:00
|
|
|
|
2020-10-23 15:08:51 +02:00
|
|
|
func _set_commit(new_commit):
|
|
|
|
commit = new_commit
|
|
|
|
update()
|
2020-10-23 16:43:02 +02:00
|
|
|
|
|
|
|
func _set_mode(new_mode):
|
|
|
|
mode = new_mode
|
2020-10-29 17:39:26 +01:00
|
|
|
|
2020-10-23 16:43:02 +02:00
|
|
|
if save_button:
|
|
|
|
save_button.visible = mode == FileBrowserMode.WORKING_DIRECTORY
|
|
|
|
text_edit.readonly = not mode == FileBrowserMode.WORKING_DIRECTORY
|
|
|
|
text_edit.selecting_enabled = mode == FileBrowserMode.WORKING_DIRECTORY
|
|
|
|
if mode == FileBrowserMode.WORKING_DIRECTORY:
|
|
|
|
text_edit.focus_mode = Control.FOCUS_CLICK
|
|
|
|
else:
|
|
|
|
text_edit.focus_mode = Control.FOCUS_NONE
|
|
|
|
|
|
|
|
func _set_title(new_title):
|
|
|
|
title = new_title
|
|
|
|
if title_label:
|
|
|
|
title_label.text = new_title
|
2020-10-23 15:08:51 +02:00
|
|
|
|
2020-09-22 15:50:57 +02:00
|
|
|
func very_best_sort(a,b):
|
2020-11-10 15:27:42 +01:00
|
|
|
if a[0] == "." and b[0] != ".":
|
2020-09-22 15:50:57 +02:00
|
|
|
return false
|
2020-11-10 15:27:42 +01:00
|
|
|
if a[0] != "." and b[0] == ".":
|
2020-09-22 15:50:57 +02:00
|
|
|
return true
|
|
|
|
return a.casecmp_to(b) == -1
|