oh-my-git/scenes/file_browser.gd

209 lines
6.1 KiB
GDScript3
Raw Permalink Normal View History

extends Control
enum FileBrowserMode {
WORKING_DIRECTORY,
COMMIT,
INDEX
}
signal saved
2023-09-06 16:04:23 +02:00
@export var title: String: set = _set_title
@export var mode: FileBrowserMode = FileBrowserMode.WORKING_DIRECTORY: set = _set_mode
var shell
2023-09-06 16:04:23 +02:00
var commit : set = _set_commit
2020-10-23 15:19:25 +02:00
var repository
var open_file
2023-09-06 16:04:23 +02:00
@onready var grid = $Panel/Margin/Rows/Scroll/Grid
@onready var text_edit = $Panel/TextEdit
@onready var save_button = $Panel/TextEdit/SaveButton
@onready var title_label = $Panel/Margin/Rows/Title
func _ready():
update()
_set_mode(mode)
_set_title(title)
2020-11-10 18:34:51 +01:00
$PopupMenu.add_item("New file", 1)
func _input(event):
if event.is_action_pressed("save"):
if text_edit.visible:
save()
2020-10-23 15:19:25 +02:00
func clear():
for item in grid.get_children():
item.queue_free()
func substr2(s):
return s.substr(2)
func update():
if grid and repository:
2020-10-23 15:19:25 +02:00
clear()
# Files in the working directory.
var wd_files = Array((await repository.shell.run("find . -type f -not -path '*/\\.git/*'")).split("\n"))
# The last entry is an empty string, remove it.
wd_files.pop_back()
wd_files = helpers.map(wd_files, self, "substr2")
2021-01-07 11:36:11 +01:00
var files = wd_files
var head_files
var index_files
if repository.there_is_a_git_cache:
# Files in the HEAD commit.
2023-09-07 14:45:52 +02:00
head_files = Array((await repository.shell.run("git ls-tree --name-only -r HEAD 2> /dev/null || true")).split("\n"))
# The last entry is an empty string, remove it.
head_files.pop_back()
# Files in the index.
2023-09-07 14:45:52 +02:00
index_files = Array((await repository.shell.run("git ls-files -s | cut -f2 | uniq")).split("\n"))
# The last entry is an empty string, remove it.
index_files.pop_back()
2021-01-07 11:36:11 +01:00
for f in head_files:
if not f in files:
files.push_back(f)
for f in index_files:
if not f in files:
files.push_back(f)
2023-09-06 16:04:23 +02:00
files.sort_custom(Callable(self, "very_best_sort"))
for file_path in files:
2023-09-06 16:04:23 +02:00
var item = preload("res://scenes/file_browser_item.tscn").instantiate()
item.label = file_path
item.repository = repository
2023-09-06 16:04:23 +02:00
item.connect("clicked", Callable(self, "item_clicked"))
grid.add_child(item)
if files.size() > 0:
game.notify("Click on these files to edit them!", self, "file-browser")
if false:
match mode:
FileBrowserMode.WORKING_DIRECTORY:
if shell:
var deleted_files = []
2023-09-07 14:45:52 +02:00
if (await shell.run("test -d super.git && echo yes || echo no")) == "yes\n":
deleted_files = Array((await shell.run("git status -s | grep '^.D' | sed 's/^...//'")).split("\n"))
deleted_files.pop_back()
#var is_visible = false
for file_path in files:
if file_path.substr(0, 5) == ".git/":
continue
#is_visible = true
2023-09-06 16:04:23 +02:00
var item = preload("res://scenes/file_browser_item.tscn").instantiate()
item.label = file_path
2023-09-06 16:04:23 +02:00
item.connect("clicked", Callable(self, "item_clicked"))
item.connect("deleted", Callable(self, "item_deleted"))
#ToDo what'shappening with the status?
#item.status = get_file_status(file_path, shell, 1)
grid.add_child(item)
#visible = is_visible
FileBrowserMode.COMMIT:
if commit:
# The last entry is an empty string, remove it.
files.pop_back()
for file_path in files:
2023-09-06 16:04:23 +02:00
var item = preload("res://scenes/file_browser_item.tscn").instantiate()
item.label = file_path
2023-09-06 16:04:23 +02:00
item.connect("clicked", Callable(self, "item_clicked"))
grid.add_child(item)
FileBrowserMode.INDEX:
#var is_visible = false
if repository and repository.there_is_a_git_cache:
2023-09-07 14:45:52 +02:00
var deleted_files = Array((await repository.shell.run("git status -s | grep '^D' | sed 's/^...//'")).split("\n"))
# The last entries are empty strings, remove them.
2020-11-10 18:22:24 +01:00
for file_path in files:
2023-09-06 16:04:23 +02:00
var item = preload("res://scenes/file_browser_item.tscn").instantiate()
item.label = file_path
2023-09-06 16:04:23 +02:00
item.connect("clicked", Callable(self, "item_clicked"))
#item.status = get_file_status(file_path, repository.shell, 0)
grid.add_child(item)
#if item.status != item.IconStatus.NONE:
# is_visible = true
#visible = is_visible
2020-11-03 16:39:55 +01:00
func item_clicked(item):
if not item.get_node("VBoxContainer/Control/WD").visible:
return
match mode:
FileBrowserMode.WORKING_DIRECTORY:
text_edit.text = helpers.read_file(repository.shell._cwd + item.label)
FileBrowserMode.COMMIT:
2023-09-07 14:45:52 +02:00
text_edit.text = await 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
2023-09-07 14:45:52 +02:00
text_edit.text = await repository.shell.run("git show :\"%s\"" % [item.label])
2020-11-03 16:39:55 +01:00
open_file = item.label
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()
func close():
text_edit.hide()
emit_signal("saved")
func save():
match mode:
FileBrowserMode.WORKING_DIRECTORY:
var fixme_path = repository.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)
update()
close()
func _set_commit(new_commit):
commit = new_commit
update()
func _set_mode(new_mode):
mode = new_mode
2020-10-29 17:39:26 +01:00
if save_button:
save_button.visible = mode == FileBrowserMode.WORKING_DIRECTORY
2023-09-06 16:04:23 +02:00
text_edit.editable = 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-11-10 18:34:51 +01:00
func _gui_input(event):
2023-09-06 16:04:23 +02:00
if event is InputEventMouseButton and event.is_pressed() and event.button_index == MOUSE_BUTTON_RIGHT:
2020-11-10 18:34:51 +01:00
$PopupMenu.set_position(get_global_mouse_position())
$PopupMenu.popup()
func very_best_sort(a,b):
if a[0] == "." and b[0] != ".":
return false
if a[0] != "." and b[0] == ".":
return true
return a.casecmp_to(b) == -1