mirror of
https://github.com/Relintai/Godot-TextEditor.git
synced 2025-01-26 16:59:19 +01:00
1.2
This commit is contained in:
parent
326ddf3299
commit
2f3dfacf47
@ -1,5 +1,13 @@
|
|||||||
# 1.2
|
# 1.2
|
||||||
|
- Can unrecycle now. (Make sure `view/Directories/.trash` is toggled, then press arrow.
|
||||||
|
- Added folder recycle option
|
||||||
|
- Added folder move/drag.
|
||||||
- Empty directories properly hide if they have no subdirectories.
|
- Empty directories properly hide if they have no subdirectories.
|
||||||
|
- Fixed hide/show file type not updating list.
|
||||||
|
- Settings are saved more frequently.
|
||||||
|
- Fixed file dragging.
|
||||||
|
- Fixed meta table not resizing.
|
||||||
|
- Bug fixes.
|
||||||
|
|
||||||
# 1.1
|
# 1.1
|
||||||
- Added `addons` folder hider option.
|
- Added `addons` folder hider option.
|
||||||
|
@ -60,9 +60,9 @@ This will then highlight *Files* and *Symbols* that have that tag.
|
|||||||
- [x] `1.1` Preserve folders open/close state.
|
- [x] `1.1` Preserve folders open/close state.
|
||||||
- [ ] Search.
|
- [ ] Search.
|
||||||
- [ ] Find and replace.
|
- [ ] Find and replace.
|
||||||
- [ ] Improvve meta data based on format.
|
- [ ] Improve meta data based on format.
|
||||||
- [ ] Show recycle folder with revert actions.
|
- [x] `1.2` Recycle folders.
|
||||||
|
- [x] `1.2` Unrecylce. (Toggle `view/directories/.trash` and press green arrow.
|
||||||
- [ ] Add your own `allow/block` list for file extensions.
|
- [ ] Add your own `allow/block` list for file extensions.
|
||||||
- [ ] JSON formatting.
|
- [ ] JSON formatting.
|
||||||
- [ ] JSON error testing.
|
- [ ] JSON error testing.
|
||||||
- [ ] Auto open/close quotes in MD and TXT.
|
|
@ -2,15 +2,26 @@ tool
|
|||||||
extends RichTextLabel
|
extends RichTextLabel
|
||||||
|
|
||||||
var editor:TextEditor
|
var editor:TextEditor
|
||||||
|
var click_pos:Vector2
|
||||||
|
|
||||||
|
func _init(text):
|
||||||
|
set_bbcode(text)
|
||||||
|
visible = false
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
add_font_override("normal_font", editor.FONT_R)
|
add_font_override("normal_font", editor.FONT_R)
|
||||||
add_font_override("bold_font", editor.FONT_B)
|
click_pos = get_global_mouse_position()
|
||||||
add_font_override("italics_font", editor.FONT_I)
|
# add_font_override("bold_font", editor.FONT_B)
|
||||||
add_font_override("bold_italics_font", editor.FONT_BI)
|
# add_font_override("italics_font", editor.FONT_I)
|
||||||
|
# add_font_override("bold_italics_font", editor.FONT_BI)
|
||||||
|
|
||||||
|
rect_size = editor.FONT_R.get_string_size(text)
|
||||||
|
rect_size += Vector2(16, 16)
|
||||||
|
|
||||||
func _process(_delta):
|
func _process(_delta):
|
||||||
set_global_position(get_global_mouse_position())
|
var mp = get_global_mouse_position()
|
||||||
|
set_visible(mp.distance_to(click_pos) > 16.0)
|
||||||
|
set_global_position(mp + Vector2(16, 8))
|
||||||
|
|
||||||
func _input(e):
|
func _input(e):
|
||||||
if e is InputEventMouseButton:
|
if e is InputEventMouseButton:
|
||||||
|
@ -15,6 +15,7 @@ var hovered:String = ""
|
|||||||
var dragging:String = ""
|
var dragging:String = ""
|
||||||
var drag_start:Vector2
|
var drag_start:Vector2
|
||||||
|
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
var _e
|
var _e
|
||||||
_e = editor.connect("updated_file_list", self, "_redraw")
|
_e = editor.connect("updated_file_list", self, "_redraw")
|
||||||
@ -44,6 +45,8 @@ func _ready():
|
|||||||
dir_popup.rect_size = Vector2.ZERO
|
dir_popup.rect_size = Vector2.ZERO
|
||||||
dir_popup.add_item("New File")
|
dir_popup.add_item("New File")
|
||||||
dir_popup.add_item("New Folder")
|
dir_popup.add_item("New Folder")
|
||||||
|
dir_popup.add_separator()
|
||||||
|
dir_popup.add_item("Remove")
|
||||||
_e = dir_popup.connect("index_pressed", self, "_dir_popup")
|
_e = dir_popup.connect("index_pressed", self, "_dir_popup")
|
||||||
dir_popup.add_font_override("font", TextEditor.FONT)
|
dir_popup.add_font_override("font", TextEditor.FONT)
|
||||||
|
|
||||||
@ -60,6 +63,7 @@ func _dir_popup(index:int):
|
|||||||
match dir_popup.get_item_text(index):
|
match dir_popup.get_item_text(index):
|
||||||
"New File": editor.popup_create_file(file)
|
"New File": editor.popup_create_file(file)
|
||||||
"New Folder": editor.popup_create_dir(file)
|
"New Folder": editor.popup_create_dir(file)
|
||||||
|
"Remove": editor.recycle(file)
|
||||||
|
|
||||||
func _file_popup(index:int):
|
func _file_popup(index:int):
|
||||||
var p = _meta_to_file(selected)
|
var p = _meta_to_file(selected)
|
||||||
@ -75,7 +79,7 @@ func _file_popup(index:int):
|
|||||||
|
|
||||||
"Remove":
|
"Remove":
|
||||||
if type == "f":
|
if type == "f":
|
||||||
editor.recycle_file(file)
|
editor.recycle(file)
|
||||||
|
|
||||||
_:
|
_:
|
||||||
selected = {}
|
selected = {}
|
||||||
@ -104,24 +108,31 @@ func _input(e:InputEvent):
|
|||||||
if e.button_index == BUTTON_LEFT:
|
if e.button_index == BUTTON_LEFT:
|
||||||
|
|
||||||
if e.pressed:
|
if e.pressed:
|
||||||
dragging = hovered
|
if type in ["f", "d"]:
|
||||||
|
if file.begins_with(editor.PATH_TRASH):
|
||||||
if type == "f":
|
return # can't move recycling
|
||||||
drag_label = DragLabel.new()
|
|
||||||
drag_label.editor = editor
|
else:
|
||||||
drag_label.set_bbcode(file.get_file())
|
dragging = hovered
|
||||||
editor.add_child(drag_label)
|
|
||||||
|
drag_label = DragLabel.new(file.get_file())
|
||||||
|
drag_label.editor = editor
|
||||||
|
editor.add_child(drag_label)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
prints(dragging, dragging != hovered, type, file)
|
||||||
if dragging and dragging != hovered:
|
if dragging and dragging != hovered:
|
||||||
var p2 = _meta_to_file(dragging)
|
var p2 = _meta_to_file(dragging)
|
||||||
var drag_type = p[0]
|
var drag_type = p2[0]
|
||||||
var drag_file = p[1]
|
var drag_file = p2[1]
|
||||||
if drag_type == "f" and type == "d":
|
|
||||||
|
if type == "d":
|
||||||
var dir:String = file
|
var dir:String = file
|
||||||
var old_path:String = drag_file
|
var old_path:String = drag_file
|
||||||
var new_path:String = dir.plus_file(old_path.get_file())
|
var new_path:String = dir.plus_file(old_path.get_file())
|
||||||
editor.rename_file(old_path, new_path)
|
editor.rename_file(old_path, new_path)
|
||||||
|
|
||||||
|
dragging = ""
|
||||||
|
|
||||||
else:
|
else:
|
||||||
match type:
|
match type:
|
||||||
@ -130,6 +141,10 @@ func _input(e:InputEvent):
|
|||||||
p[2].open = not p[2].open
|
p[2].open = not p[2].open
|
||||||
_redraw()
|
_redraw()
|
||||||
|
|
||||||
|
# unrecycle
|
||||||
|
"unrecycle":
|
||||||
|
editor.unrecycle(file)
|
||||||
|
|
||||||
# select
|
# select
|
||||||
"f":
|
"f":
|
||||||
editor.select_file(file)
|
editor.select_file(file)
|
||||||
@ -154,7 +169,7 @@ func _meta_to_file(m:String):
|
|||||||
var type = p[0]
|
var type = p[0]
|
||||||
var index = int(p[1])
|
var index = int(p[1])
|
||||||
match type:
|
match type:
|
||||||
"d":
|
"d", "unrecycle":
|
||||||
return [type, dirs[index].file_path, dirs[index]]
|
return [type, dirs[index].file_path, dirs[index]]
|
||||||
"f":
|
"f":
|
||||||
return [type, files[index]]
|
return [type, files[index]]
|
||||||
@ -164,6 +179,7 @@ func _meta_entered(m):
|
|||||||
var f = _meta_to_file(m)
|
var f = _meta_to_file(m)
|
||||||
match f[0]:
|
match f[0]:
|
||||||
"f", "d": hint_tooltip = f[1]
|
"f", "d": hint_tooltip = f[1]
|
||||||
|
"unrecycle": hint_tooltip = "Unrecycle %s" % f[1]
|
||||||
|
|
||||||
func _meta_exited(_m):
|
func _meta_exited(_m):
|
||||||
hovered = ""
|
hovered = ""
|
||||||
@ -199,6 +215,8 @@ func _draw_dir(dir:Dictionary, deep:int):
|
|||||||
var head:String = "▼" if dir.open else "▶"
|
var head:String = "▼" if dir.open else "▶"
|
||||||
var dir_index:int = len(dirs)
|
var dir_index:int = len(dirs)
|
||||||
var link:String = url(space+clr(FOLDER+head, Color.white.darkened(.5))+" "+name, "d:%s" % dir_index)
|
var link:String = url(space+clr(FOLDER+head, Color.white.darkened(.5))+" "+name, "d:%s" % dir_index)
|
||||||
|
if file.begins_with(editor.PATH_TRASH) and file.count("/") == 3:
|
||||||
|
link += " " + url(clr("⬅", Color.yellowgreen), "unrecycle:%s" % dir_index)
|
||||||
lines.append(clr(link, Color.white.darkened(dimmest)))
|
lines.append(clr(link, Color.white.darkened(dimmest)))
|
||||||
dirs.append(dir)
|
dirs.append(dir)
|
||||||
|
|
||||||
|
@ -7,6 +7,10 @@ func _ready():
|
|||||||
var _e
|
var _e
|
||||||
_e = editor.connect("file_selected", self, "_file_selected")
|
_e = editor.connect("file_selected", self, "_file_selected")
|
||||||
_e = editor.connect("file_saved", self, "_file_saved")
|
_e = editor.connect("file_saved", self, "_file_saved")
|
||||||
|
_e = connect("resized", self, "_resized")
|
||||||
|
|
||||||
|
func _resized():
|
||||||
|
add_constant_override("table_hseparation", int(rect_size.x / 6.0))
|
||||||
|
|
||||||
func _unhandled_key_input(e):
|
func _unhandled_key_input(e):
|
||||||
if e.scancode == KEY_M and e.pressed:
|
if e.scancode == KEY_M and e.pressed:
|
||||||
|
@ -10,7 +10,6 @@ const FONT_I:DynamicFont = preload("res://addons/text_editor/fonts/font_i.tres")
|
|||||||
const FONT_BI:DynamicFont = preload("res://addons/text_editor/fonts/font_bi.tres")
|
const FONT_BI:DynamicFont = preload("res://addons/text_editor/fonts/font_bi.tres")
|
||||||
|
|
||||||
const PATH_TRASH:String = "res://.trash"
|
const PATH_TRASH:String = "res://.trash"
|
||||||
const PATH_TRASH_INFO:String = "res://.trash.json"
|
|
||||||
const PATH_STATE:String = "res://.text_editor_state.json"
|
const PATH_STATE:String = "res://.text_editor_state.json"
|
||||||
|
|
||||||
const MAIN_EXTENSIONS:PoolStringArray = PoolStringArray([
|
const MAIN_EXTENSIONS:PoolStringArray = PoolStringArray([
|
||||||
@ -337,6 +336,7 @@ func _menu_view_dir(index:int):
|
|||||||
popup_view_dir.set_item_checked(index, show.dir.trash)
|
popup_view_dir.set_item_checked(index, show.dir.trash)
|
||||||
|
|
||||||
refresh_files()
|
refresh_files()
|
||||||
|
save_state()
|
||||||
|
|
||||||
func _menu_view_file(index:int):
|
func _menu_view_file(index:int):
|
||||||
# hidden files
|
# hidden files
|
||||||
@ -352,6 +352,9 @@ func _menu_view_file(index:int):
|
|||||||
prints(index, text)
|
prints(index, text)
|
||||||
exts_enabled[ext] = not exts_enabled[ext]
|
exts_enabled[ext] = not exts_enabled[ext]
|
||||||
popup_view_file.set_item_checked(index, exts_enabled[ext])
|
popup_view_file.set_item_checked(index, exts_enabled[ext])
|
||||||
|
|
||||||
|
refresh_files()
|
||||||
|
save_state()
|
||||||
|
|
||||||
func _file_dialog_file(file_path:String):
|
func _file_dialog_file(file_path:String):
|
||||||
match file_dialog.get_meta("mode"):
|
match file_dialog.get_meta("mode"):
|
||||||
@ -527,34 +530,51 @@ func is_opened(file_path:String) -> bool:
|
|||||||
func is_selected(file_path:String) -> bool:
|
func is_selected(file_path:String) -> bool:
|
||||||
return get_selected_file() == file_path
|
return get_selected_file() == file_path
|
||||||
|
|
||||||
func recycle_file(file_path:String):
|
func unrecycle(file_path:String):
|
||||||
var old_base:String = file_path.substr(len("res://")).get_base_dir()
|
var op = file_path.plus_file(".old_path")
|
||||||
var p = file_path.get_file().split(".", true, 1)
|
var np = file_path.plus_file(".new_path")
|
||||||
var old_name:String = p[0]
|
var d:Directory = Directory.new()
|
||||||
var old_ext:String = p[1]
|
if d.file_exists(op) and d.file_exists(np):
|
||||||
var tab = get_tab(file_path)
|
var old_path:String = TE_Util.load_text(np)
|
||||||
|
var new_path:String = TE_Util.load_text(op)
|
||||||
|
d.rename(old_path, new_path)
|
||||||
|
d.remove(op)
|
||||||
|
d.remove(np)
|
||||||
|
d.remove(file_path)
|
||||||
|
refresh_files()
|
||||||
|
else:
|
||||||
|
print("can't unrecyle")
|
||||||
|
|
||||||
var new_file = "%s_%s.%s" % [old_name, OS.get_system_time_secs(), old_ext]
|
func recycle(file_path:String):
|
||||||
var new_path:String = PATH_TRASH.plus_file(old_base).plus_file(new_file)
|
if file_path.begins_with(PATH_TRASH):
|
||||||
|
push_error("can't recycle recycled.")
|
||||||
# create directory
|
|
||||||
var new_dir = new_path.get_base_dir()
|
|
||||||
if Directory.new().make_dir_recursive(new_dir) != OK:
|
|
||||||
print("couldn't remove %s" % file_path)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
# save recovery information
|
var tab = get_tab(file_path)
|
||||||
var trash_info = TE_Util.load_json(PATH_TRASH_INFO)
|
|
||||||
trash_info[new_path] = file_path
|
|
||||||
TE_Util.save_json(PATH_TRASH_INFO, trash_info)
|
|
||||||
|
|
||||||
# remove by renaming
|
var time = str(OS.get_system_time_secs())
|
||||||
rename_file(file_path, new_path)
|
var old_path:String = file_path
|
||||||
|
var d:Directory = Directory.new()
|
||||||
|
|
||||||
|
# is dir?
|
||||||
|
var base_name = file_path.get_file()
|
||||||
|
var new_dir = PATH_TRASH.plus_file(time)
|
||||||
|
var new_path = new_dir.plus_file(base_name)
|
||||||
|
|
||||||
|
if not d.dir_exists(PATH_TRASH):
|
||||||
|
var _err = d.make_dir(PATH_TRASH)
|
||||||
|
|
||||||
|
var _err = d.make_dir(new_dir)
|
||||||
|
d.rename(file_path, new_path)
|
||||||
|
save_file(new_dir.plus_file(".old_path"), old_path)
|
||||||
|
save_file(new_dir.plus_file(".new_path"), new_path)
|
||||||
|
|
||||||
|
refresh_files()
|
||||||
|
|
||||||
if tab:
|
if tab:
|
||||||
tab_parent.remove_child(tab)
|
tab_parent.remove_child(tab)
|
||||||
tab.queue_free()
|
tab.queue_free()
|
||||||
|
|
||||||
if opened:
|
if opened:
|
||||||
select_file(opened[-1])
|
select_file(opened[-1])
|
||||||
|
|
||||||
@ -647,7 +667,7 @@ func show_file(fname:String) -> bool:
|
|||||||
if not show.file.hidden: return false
|
if not show.file.hidden: return false
|
||||||
|
|
||||||
var ext = get_extension(fname)
|
var ext = get_extension(fname)
|
||||||
return ext in exts_enabled
|
return exts_enabled.get(ext, false)
|
||||||
|
|
||||||
func _scan_dir(id:String, path:String, dir:Directory, last_dir:Dictionary, old_last_dir:Dictionary):
|
func _scan_dir(id:String, path:String, dir:Directory, last_dir:Dictionary, old_last_dir:Dictionary):
|
||||||
var _e = dir.list_dir_begin(true, false)
|
var _e = dir.list_dir_begin(true, false)
|
||||||
@ -677,8 +697,6 @@ func _scan_dir(id:String, path:String, dir:Directory, last_dir:Dictionary, old_l
|
|||||||
else:
|
else:
|
||||||
if show_file(fname):
|
if show_file(fname):
|
||||||
a_dirs_and_files[fname] = file_path
|
a_dirs_and_files[fname] = file_path
|
||||||
else:
|
|
||||||
print("bad file ", fname)
|
|
||||||
|
|
||||||
fname = dir.get_next()
|
fname = dir.get_next()
|
||||||
|
|
||||||
@ -693,10 +711,6 @@ func _scan_dir(id:String, path:String, dir:Directory, last_dir:Dictionary, old_l
|
|||||||
sort_on_ext(a_dirs)
|
sort_on_ext(a_dirs)
|
||||||
sort_on_ext(a_files)
|
sort_on_ext(a_files)
|
||||||
|
|
||||||
prints("DIRS", a_dirs)
|
|
||||||
prints("FILES", a_files)
|
|
||||||
prints("ALL", a_dirs_and_files.keys())
|
|
||||||
|
|
||||||
if id and not (show.dir.empty or a_files):
|
if id and not (show.dir.empty or a_files):
|
||||||
info.show = false
|
info.show = false
|
||||||
|
|
||||||
|
@ -25,14 +25,20 @@ func apply_colors(e:TextEditor, t:TextEdit):
|
|||||||
|
|
||||||
# headings
|
# headings
|
||||||
var head = e.color_symbol
|
var head = e.color_symbol
|
||||||
t.add_color_region("# *", "*", TE_Util.hue_shift(head, -.33), true)
|
var tint1 = TE_Util.hue_shift(head, -.33)
|
||||||
t.add_color_region("# \"", "\"", TE_Util.hue_shift(head, .33), true)
|
var tint2 = TE_Util.hue_shift(head, .33)
|
||||||
t.add_color_region("# ", "", head, true)
|
for i in range(1, 6):
|
||||||
t.add_color_region("## ", "", head, true)
|
var h = "#".repeat(i)
|
||||||
t.add_color_region("### ", "", head, true)
|
t.add_color_region("%s *" % h, "*", tint1, true)
|
||||||
t.add_color_region("#### ", "", head, true)
|
t.add_color_region("%s \"" % h, "\"", tint2, true)
|
||||||
t.add_color_region("##### ", "", head, true)
|
t.add_color_region("%s " % h, "*", head, true)
|
||||||
t.add_color_region("###### ", "", head, true)
|
# t.add_color_region("# \"", "\"", TE_Util.hue_shift(head, .33), true)
|
||||||
|
# t.add_color_region("# ", "", head, true)
|
||||||
|
# t.add_color_region("## ", "", head, true)
|
||||||
|
# t.add_color_region("### ", "", head, true)
|
||||||
|
# t.add_color_region("#### ", "", head, true)
|
||||||
|
# t.add_color_region("##### ", "", head, true)
|
||||||
|
# t.add_color_region("###### ", "", head, true)
|
||||||
|
|
||||||
# url links
|
# url links
|
||||||
t.add_color_region("![", ")", e.color_var.lightened(.5))
|
t.add_color_region("![", ")", e.color_var.lightened(.5))
|
||||||
|
@ -3,5 +3,5 @@
|
|||||||
name="TextEditor"
|
name="TextEditor"
|
||||||
description="A text editor for Godot."
|
description="A text editor for Godot."
|
||||||
author="teebar"
|
author="teebar"
|
||||||
version="1.1"
|
version="1.2"
|
||||||
script="plugin.gd"
|
script="plugin.gd"
|
||||||
|
Loading…
Reference in New Issue
Block a user