From 5bcd5a47b0d995243b7ba9308991f3a138c61dd2 Mon Sep 17 00:00:00 2001 From: teebarjunk Date: Mon, 18 Oct 2021 19:50:21 -0400 Subject: [PATCH] 1.5 --- CHANGES.md | 12 ++ addons/text_editor/TE_DragLabel.gd | 2 +- .../{TE_TextEditor.gd => TE_Editor.gd} | 184 +++++++++++++----- addons/text_editor/TE_FileEditor.gd | 154 +++++++++------ addons/text_editor/TE_FileTabs.gd | 2 +- addons/text_editor/TE_FilesList.gd | 2 - addons/text_editor/TE_LineEdit.gd | 2 +- addons/text_editor/TE_MetaTabs.gd | 2 +- addons/text_editor/TE_RichTextLabel.gd | 2 +- addons/text_editor/TE_ScriptInfo.gd | 86 ++++---- addons/text_editor/TE_Search.gd | 2 +- addons/text_editor/TE_SymbolsList.gd | 20 +- addons/text_editor/TE_TabScroller.gd | 2 +- addons/text_editor/TextEditor.tscn | 110 +++++++---- addons/text_editor/ext/ext_ini.gd | 3 +- addons/text_editor/ext/ext_json.gd | 2 +- addons/text_editor/ext/ext_md.gd | 18 +- addons/text_editor/ext/ext_yaml.gd | 2 +- addons/text_editor/fonts/font.tres | 1 + addons/text_editor/fonts/font_b.tres | 1 + addons/text_editor/fonts/font_bi.tres | 1 + addons/text_editor/fonts/font_i.tres | 1 + addons/text_editor/fonts/font_r.tres | 1 + addons/text_editor/plugin.cfg | 2 +- 24 files changed, 413 insertions(+), 201 deletions(-) rename addons/text_editor/{TE_TextEditor.gd => TE_Editor.gd} (83%) diff --git a/CHANGES.md b/CHANGES.md index 4c32b78..5d469d1 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,15 @@ +# 1.5 +- Added `Ctrl + N` to immediately create new file without defining path. +- New unsaved file will have contents remembered. +- Added `Ctrl + Shift + Mouse wheel` to change ui font size. +- Added word wrap toggle. +- Fixed sorting error in `sys`. +- Fixed font size save/load. +- `sys` shows chapter count. +- Preserves symbol view scroll value when tabbing. +- Can access full filesystem. +- Fixed "New File" dialog not gaining focus. + # 1.4 - Added `sys` info tab. - Added `console` info tab. (wip) diff --git a/addons/text_editor/TE_DragLabel.gd b/addons/text_editor/TE_DragLabel.gd index 3191a99..c1d052e 100644 --- a/addons/text_editor/TE_DragLabel.gd +++ b/addons/text_editor/TE_DragLabel.gd @@ -1,7 +1,7 @@ tool extends RichTextLabel -var editor:TE_TextEditor +var editor:TE_Editor var click_pos:Vector2 func _init(text): diff --git a/addons/text_editor/TE_TextEditor.gd b/addons/text_editor/TE_Editor.gd similarity index 83% rename from addons/text_editor/TE_TextEditor.gd rename to addons/text_editor/TE_Editor.gd index 41f6229..b7dbee3 100644 --- a/addons/text_editor/TE_TextEditor.gd +++ b/addons/text_editor/TE_Editor.gd @@ -1,6 +1,6 @@ tool extends Control -class_name TE_TextEditor +class_name TE_Editor const FONT:DynamicFont = preload("res://addons/text_editor/fonts/font.tres") @@ -75,6 +75,7 @@ onready var file_dialog:FileDialog = $file_dialog onready var line_edit:LineEdit = $c/div1/div2/c/line_edit onready var menu_file:MenuButton = $c/c/c/file_button onready var menu_view:MenuButton = $c/c/c/view_button +onready var word_wrap:CheckBox = $c/c/c/word_wrap onready var console:RichTextLabel = $c/div1/div2/c/c/meta_tabs/console var popup_file:PopupMenu var popup_view:PopupMenu @@ -103,6 +104,7 @@ func _ready(): if OS.has_feature("standalone"): current_directory = OS.get_executable_path().get_base_dir() + file_dialog.access = FileDialog.ACCESS_FILESYSTEM console.info("current dir: %s" % current_directory) # not needed when editor plugin @@ -126,10 +128,9 @@ func _ready(): popup_file.clear() popup_file.add_font_override("font", FONT_R) popup_file.add_item("New File", 100) - popup_file.add_item("New Folder", 200) popup_file.add_separator() popup_file.add_item("Open last closed", 300) - _e = popup_file.connect("id_pressed", self, "_menu_file") + _e = popup_file.connect("index_pressed", self, "_menu_file") # view menu_view.add_font_override("font", FONT_R) @@ -188,10 +189,19 @@ func _ready(): # tab control _e = tab_parent.connect("tab_changed", self, "_tab_changed") + # word wrap + _e = word_wrap.connect("pressed", self, "_toggle_word_wrap") + word_wrap.add_font_override("font", FONT_R) + load_state() update_checks() set_directory() +func _toggle_word_wrap(): + tab_prefab.set_wrap_enabled(word_wrap.pressed) + for tab in get_all_tabs(): + tab.set_wrap_enabled(word_wrap.pressed) + func update_checks(): # Directories popup_view_dir.set_item_checked(0, show.dir.hidden) @@ -217,6 +227,7 @@ func save_state(): var state:Dictionary = { "save_version": "1", "font_size": FONT.size, + "font_size_ui": FONT_R.size, "tabs": {}, "selected": get_selected_file(), "show": show, @@ -228,8 +239,13 @@ func save_state(): "file_list": file_list, "div1": $c/div1.split_offset, - "div2": $c/div1/div2.split_offset + "div2": $c/div1/div2.split_offset, + "div3": $c/div1/div2/c/c.split_offset, + "div4": $c/div1/div2/c2/c.split_offset } + var ws = OS.get_window_size() + state["window_size"] = [ws.x, ws.y] + for tab in get_all_tabs(): state.tabs[tab.file_path] = tab.get_state() @@ -252,13 +268,27 @@ func load_state(): update_checks() + FONT.size = state.get("font_size", FONT.size) + + var font_size_ui = state.get("font_size_ui", FONT_R.size) + for f in [FONT_R, FONT_B, FONT_I, FONT_BI]: + f.size = font_size_ui + _load_property(state, "file_list") _load_property(state, "tag_counts") _load_property(state, "tags_enabled") _load_property(state, "exts_enabled") + # dividers $c/div1.split_offset = state.get("div1", $c/div1.split_offset) $c/div1/div2.split_offset = state.get("div2", $c/div1/div2.split_offset) + $c/div1/div2/c/c.split_offset = state.get("div3", $c/div1/div2/c/c.split_offset) + $c/div1/div2/c2/c.split_offset = state.get("div4", $c/div1/div2/c2/c.split_offset) + + # window size + if "window_size" in state: + var ws = state.window_size + OS.set_window_size(Vector2(ws[0], ws[1])) emit_signal("state_loaded") @@ -295,25 +325,67 @@ func _input(e): if not is_plugin_active(): return - if e is InputEventMouseButton and e.control: - if e.button_index == BUTTON_WHEEL_DOWN: - FONT.size = int(max(8, FONT.size - 1)) + if e is InputEventKey and e.pressed and e.control: + # tab to next + if e.scancode == KEY_TAB: + if e.shift: + tab_parent.prev() + else: + tab_parent.next() get_tree().set_input_as_handled() - elif e.button_index == BUTTON_WHEEL_UP: - FONT.size = int(min(64, FONT.size + 1)) + # save files + elif e.scancode == KEY_S: + save_files() get_tree().set_input_as_handled() + + # close file + elif e.scancode == KEY_W: + if e.shift: + open_last_file() + else: + get_selected_tab().close() + get_tree().set_input_as_handled() + + # create new file + elif e.scancode == KEY_N: + open_file("", true) + get_tree().set_input_as_handled() + + if e is InputEventMouseButton and e.control: + + # ui font + if e.shift: + if e.button_index == BUTTON_WHEEL_DOWN: + for f in [FONT_B, FONT_BI, FONT_R, FONT_I]: + f.size = int(max(8, f.size - 1)) + get_tree().set_input_as_handled() + + elif e.button_index == BUTTON_WHEEL_UP: + for f in [FONT_B, FONT_BI, FONT_R, FONT_I]: + f.size = int(min(64, f.size + 1)) + get_tree().set_input_as_handled() + + # text font + else: + if e.button_index == BUTTON_WHEEL_DOWN: + FONT.size = int(max(8, FONT.size - 1)) + get_tree().set_input_as_handled() + + elif e.button_index == BUTTON_WHEEL_UP: + FONT.size = int(min(64, FONT.size + 1)) + get_tree().set_input_as_handled() func _apply_fonts(n:Node): if n is Control: if n.has_font("font"): n.add_font_override("font", FONT_R) -func _menu_file(id): - match id: - 100: popup_create_file() # "New File" - 200: popup_create_dir() # "New Folder" - 300: open_last_file() # "Open last closed" +func _menu_file(index:int): + var text = popup_file.get_item_text(index) + match text: + "New File": popup_create_file() # "New File" + "Open last closed": open_last_file() # "Open last closed" func _menu_view_dir(index:int): var text = popup_view_dir.get_item_text(index) @@ -365,8 +437,12 @@ func _menu_view_file(index:int): func _file_dialog_file(file_path:String): match file_dialog.get_meta("mode"): - "create_file": create_file(file_path) - "create_dir": create_dir(file_path) + "create_file": + var text = file_dialog.get_meta("text") + create_file(file_path, text) + + "create_dir": + create_dir(file_path) var tab_index:int = -1 func _tab_changed(index:int): @@ -411,35 +487,40 @@ func is_tagged(file_path:String) -> bool: func is_tagging() -> bool: return len(tags) > 0 -func popup_create_file(dir:String=current_directory): +func popup_create_file(dir:String=current_directory, text:String="", callback:FuncRef=null): file_dialog.mode = FileDialog.MODE_SAVE_FILE file_dialog.current_dir = dir file_dialog.window_title = "Create File" - file_dialog.current_path = "new_file.txt" + file_dialog.current_path = "new_file.md" file_dialog.filters = FILE_FILTERS file_dialog.set_meta("mode", "create_file") + file_dialog.set_meta("text", text) + file_dialog.set_meta("callback", callback) file_dialog.show() + yield(get_tree(), "idle_frame") + file_dialog.get_line_edit().grab_click_focus() + file_dialog.get_line_edit().grab_focus() -func popup_create_dir(dir:String=current_directory): - file_dialog.mode = FileDialog.MODE_OPEN_DIR - file_dialog.current_dir = dir - file_dialog.window_title = "Create Folder" - file_dialog.current_path = "New Folder" - file_dialog.set_meta("mode", "create_dir") - file_dialog.show() - -func create_file(file_path:String): +func create_file(file_path:String, text:String=""): var f:File = File.new() if f.open(file_path, File.WRITE) == OK: - f.store_string("") + f.store_string(text) f.close() refresh_files() + + if file_dialog.has_meta("callback"): + var fr:FuncRef = file_dialog.get_meta("callback") + fr.call_func(file_path) + file_dialog.set_meta("callback", null) + open_file(file_path) - select_file(file_path) + + return true else: var err_msg = "couldnt create %s" % file_path console.err(err_msg) push_error(err_msg) + return false func create_dir(file_path:String): var d:Directory = Directory.new() @@ -460,7 +541,7 @@ func get_selected_file() -> String: func get_tab(file_path:String) -> TextEdit: for child in tab_parent.get_children(): - if child.file_path == file_path: + if child is TextEdit and child.file_path == file_path: return child return null @@ -502,16 +583,25 @@ func close_file(file_path:String): tab.close() func _close_file(file_path, remember:bool=true): - if remember: + if remember and file_path: closed.append(file_path) - var tab = get_tab(file_path) + var tab:Node = get_tab(file_path) tab_parent.remove_child(tab) tab.queue_free() - emit_signal("file_closed", file_path) + + if file_path: + emit_signal("file_closed", file_path) + + # force select a file + yield(get_tree(), "idle_frame") + var fp = get_selected_file() + if fp: + select_file(fp) func _open_file(file_path:String): var tab = tab_prefab.duplicate() + tab.name = "tab" tab.visible = true tab.editor = self tab_parent.add_child(tab) @@ -528,11 +618,11 @@ func open_file(file_path:String, temporary:bool=false): if tab: return tab - elif not File.new().file_exists(file_path): + elif not File.new().file_exists(file_path) and not file_path == "": push_error("no file %s" % file_path) return null - elif not is_allowed_extension(file_path): + elif not is_allowed_extension(file_path) and not file_path == "": push_error("can't open %s" % file_path) return null @@ -542,6 +632,10 @@ func open_file(file_path:String, temporary:bool=false): tab.temporary = true else: opened.append(file_path) + + # select it + tab_parent.current_tab = tab.get_index() + emit_signal("file_opened", file_path) return tab @@ -564,11 +658,15 @@ func unrecycle(file_path:String): d.remove(file_path) refresh_files() else: - print("can't unrecyle") - + var err_msg = "can't unrecyle %s" % file_path + push_error(err_msg) + console.err(err_msg) + func recycle(file_path:String): if file_path.begins_with(PATH_TRASH): - push_error("can't recycle recycled.") + var err_msg = "can't recycle recycled %s" % file_path + push_error(err_msg) + console.err(err_msg) return var tab = get_tab(file_path) @@ -640,10 +738,6 @@ func select_file(file_path:String): _selected_file_changed(file_path) func set_directory(path:String=current_directory): -# var gpath = ProjectSettings.globalize_path(path) -# var dname = gpath.get_file() - console.msg("Set " + path) - current_directory = path file_dialog.current_dir = path refresh_files() @@ -722,7 +816,6 @@ func _scan_dir(id:String, path:String, dir:Directory, last_dir:Dictionary, old_l while fname: var file_path = dir.get_current_dir().plus_file(fname) - console.msg(file_path) if dir.current_is_dir(): if show_dir(fname, file_path): @@ -779,9 +872,8 @@ static func get_extension(file_path:String) -> String: func get_extension_helper(file_path:String) -> TE_ExtensionHelper: var ext:String = get_extension(file_path).replace(".", "_") var ext_path:String = "res://addons/text_editor/ext/ext_%s.gd" % ext - var script = load(ext_path) - if script: - return script.new() + if ext in ["cfg", "csv", "ini", "json", "md", "yaml"]: + return load(ext_path).new() console.err("no helper %s" % ext_path) return load("res://addons/text_editor/ext/TE_ExtensionHelper.gd").new() diff --git a/addons/text_editor/TE_FileEditor.gd b/addons/text_editor/TE_FileEditor.gd index bb3b03d..830c15e 100644 --- a/addons/text_editor/TE_FileEditor.gd +++ b/addons/text_editor/TE_FileEditor.gd @@ -1,7 +1,7 @@ tool extends TextEdit -var editor:TE_TextEditor +var editor:TE_Editor var _hscroll:HScrollBar var _vscroll:VScrollBar @@ -22,6 +22,12 @@ var vscroll:int = 0 var in_focus:bool = false func _ready(): + # prefab? + if name == "file_editor": + set_process(false) + set_process_input(false) + return + var _e if not editor: editor = owner @@ -39,6 +45,10 @@ func _ready(): add_font_override("font", editor.FONT) get_menu().add_font_override("font", editor.FONT) + # hint + theme = Theme.new() + theme.set_font("font", "TooltipLabel", editor.FONT_R) + TE_Util.dig(self, self, "_node") func _node(n): @@ -59,24 +69,31 @@ func _scroll_v(v:VScrollBar): func _tab_changed(index:int): var myindex = get_index() if index == myindex and visible: - grab_focus() - grab_click_focus() +# grab_focus() +# grab_click_focus() yield(get_tree(), "idle_frame") set_h_scroll(hscroll) set_v_scroll(vscroll) func get_state() -> Dictionary: - return { - hscroll=scroll_horizontal, - vscroll=scroll_vertical - } - + var state = { hscroll=scroll_horizontal, vscroll=scroll_vertical } + # unsaved + if file_path == "": + state.text = text + return state + func set_state(state:Dictionary): yield(get_tree(), "idle_frame") hscroll = state.hscroll vscroll = state.vscroll set_h_scroll(state.hscroll) set_v_scroll(state.vscroll) + + if "text" in state: + if state.text.strip_edges(): + text = state.text + else: + editor._close_file(file_path) func _file_renamed(old_path:String, new_path:String): if old_path == file_path: @@ -105,29 +122,6 @@ func _input(e): var link = file_path.get_base_dir().plus_file(file) editor.open_file(link) editor.select_file(link) -# print(link) - - if e is InputEventKey and e.pressed and e.control: - # tab to next - if e.scancode == KEY_TAB: - get_tree().set_input_as_handled() - if e.shift: - get_parent().prev() - else: - get_parent().next() - - # save files - elif e.scancode == KEY_S: - get_tree().set_input_as_handled() - editor.save_files() - - # close file - elif e.scancode == KEY_W: - get_tree().set_input_as_handled() - if e.shift: - editor.open_last_file() - else: - close() # remember last selection if e is InputEventKey and e.pressed: @@ -184,12 +178,38 @@ func _file_selected(p:String): return if p == file_path: - grab_focus() - grab_click_focus() update_symbols() update_heading() + + var cl = cursor_get_line() + var cc = cursor_get_column() + var fl + var fc + var tl + var tc + var had_selection = false + + if is_selection_active(): + had_selection = true + fl = get_selection_from_line() + fc = get_selection_from_column() + tl = get_selection_to_line() + tc = get_selection_to_column() + + grab_focus() + grab_click_focus() + + yield(get_tree(), "idle_frame") + + cursor_set_line(cl) + cursor_set_column(cc) + + if had_selection: + select(fl, fc, tl, tc) + func goto_line(line:int): + prints("goto ", line) # force scroll to bottom so selected line will be at top cursor_set_line(get_line_count()) cursor_set_line(line) @@ -239,56 +259,80 @@ func update_symbols(): else: tags[tag] += 1 -# var _e = TE_Util.sort(tags, true) editor._file_symbols_updated(file_path) func close(): if modified: - var _e - _e = editor.popup_unsaved.connect("confirmed", self, "_popup", ["close"], CONNECT_ONESHOT) - _e = editor.popup_unsaved.connect("custom_action", self, "_popup", [], CONNECT_ONESHOT) - editor.popup_unsaved.show() + if not editor.popup_unsaved.visible: + var _e + _e = editor.popup_unsaved.connect("confirmed", self, "_popup", ["confirm_close"], CONNECT_ONESHOT) + _e = editor.popup_unsaved.connect("custom_action", self, "_popup", [], CONNECT_ONESHOT) +# _e = editor.popup_unsaved.connect("hide", self, "_popup", ["cancel"], CONNECT_ONESHOT) + editor.popup_unsaved.show() else: editor._close_file(file_path) func _popup(msg): match msg: - "close": + "confirm_close": editor._close_file(file_path) "save_and_close": save_file() editor._close_file(file_path) + editor.popup_unsaved.disconnect("confirmed", self, "_popup") + editor.popup_unsaved.disconnect("custom_action", self, "_popup") func load_file(path:String): file_path = path - text = TE_Util.load_text(path) - update_name() + if path != "": + text = TE_Util.load_text(path) update_colors() + update_name() func update_colors(): clear_colors() helper = editor.get_extension_helper(file_path) helper.apply_colors(editor, self) +func _created_nonexisting(fp:String): + file_path = fp + modified = false + update_name() + update_symbols() + func save_file(): - if modified: - if not file_path.begins_with(editor.current_directory): - var err_msg = "can't save to %s" % file_path - push_error(err_msg) - editor.console.err(err_msg) - return - - modified = false - editor.save_file(file_path, text) - update_name() - update_symbols() + if file_path == "": + editor.popup_create_file(editor.current_directory, text, funcref(self, "_created_nonexisting")) + + else: + if modified: + if not file_path.begins_with(editor.current_directory): + var err_msg = "can't save to %s" % file_path + push_error(err_msg) + editor.console.err(err_msg) + return + + modified = false + editor.save_file(file_path, text) + update_name() + update_symbols() func update_name(): - var n = file_path.get_file().split(".", true, 1)[0] - if temporary: n = "?" + n - if modified: n = "*" + n + var n:String + + if file_path == "": + n = "*UNSAVED" + + else: + n = file_path.get_file().split(".", true, 1)[0] + if temporary: n = "?" + n + if modified: n = "*" + n + + if len(n) > 9: + n = n.substr(0, 6) + "..." editor.tab_parent.set_tab_title(get_index(), n) + editor.tab_parent.get_tab_control(get_index()).hint_tooltip = file_path update_heading() func update_heading(): diff --git a/addons/text_editor/TE_FileTabs.gd b/addons/text_editor/TE_FileTabs.gd index 91c7654..3446096 100644 --- a/addons/text_editor/TE_FileTabs.gd +++ b/addons/text_editor/TE_FileTabs.gd @@ -1,6 +1,6 @@ extends TabContainer -onready var editor:TE_TextEditor = owner +onready var editor:TE_Editor = owner var mouse:bool = false func _ready(): diff --git a/addons/text_editor/TE_FilesList.gd b/addons/text_editor/TE_FilesList.gd index aac3b73..bb401b0 100644 --- a/addons/text_editor/TE_FilesList.gd +++ b/addons/text_editor/TE_FilesList.gd @@ -33,7 +33,6 @@ func _ready(): dir_popup.clear() dir_popup.rect_size = Vector2.ZERO dir_popup.add_item("New File") - dir_popup.add_item("New Folder") dir_popup.add_separator() dir_popup.add_item("Remove") _e = dir_popup.connect("index_pressed", self, "_dir_popup") @@ -52,7 +51,6 @@ func _dir_popup(index:int): match dir_popup.get_item_text(index): "New File": editor.popup_create_file(file) - "New Folder": editor.popup_create_dir(file) "Remove": editor.recycle(file) func _file_popup(index:int): diff --git a/addons/text_editor/TE_LineEdit.gd b/addons/text_editor/TE_LineEdit.gd index e6a1287..7ae695b 100644 --- a/addons/text_editor/TE_LineEdit.gd +++ b/addons/text_editor/TE_LineEdit.gd @@ -1,7 +1,7 @@ tool extends LineEdit -onready var editor:TE_TextEditor = owner +onready var editor:TE_Editor = owner var fr:FuncRef func _ready(): diff --git a/addons/text_editor/TE_MetaTabs.gd b/addons/text_editor/TE_MetaTabs.gd index c53ff32..b2c28b1 100644 --- a/addons/text_editor/TE_MetaTabs.gd +++ b/addons/text_editor/TE_MetaTabs.gd @@ -1,7 +1,7 @@ tool extends TabContainer -onready var editor:TE_TextEditor = owner +onready var editor:TE_Editor = owner func _ready(): if not editor.is_plugin_active(): diff --git a/addons/text_editor/TE_RichTextLabel.gd b/addons/text_editor/TE_RichTextLabel.gd index 2470709..2e40792 100644 --- a/addons/text_editor/TE_RichTextLabel.gd +++ b/addons/text_editor/TE_RichTextLabel.gd @@ -1,6 +1,6 @@ extends RichTextLabel -onready var editor:TE_TextEditor = owner +onready var editor:TE_Editor = owner var meta_items:Array = [] var meta_hovered:Array = [] diff --git a/addons/text_editor/TE_ScriptInfo.gd b/addons/text_editor/TE_ScriptInfo.gd index e59a7de..3b26a2e 100644 --- a/addons/text_editor/TE_ScriptInfo.gd +++ b/addons/text_editor/TE_ScriptInfo.gd @@ -3,17 +3,15 @@ extends "res://addons/text_editor/TE_RichTextLabel.gd" var chapter_info:Array = [] var sort_on:String = "words" -var sort_reverse:Dictionary = { id=false, words=false, unique=false } +var sort_reverse:Dictionary = { id=false, words=false, chaps=false } func _ready(): - var _e - _e = editor.connect("file_opened", self, "_update") - _e = editor.connect("file_saved", self, "_update") + var btn = get_parent().get_node("update") + btn.add_font_override("font", editor.FONT_R) + + var _e = btn.connect("pressed", self, "_update") -func _update(f): - set_process(true) - -func _process(_delta): +func _update(): chapter_info.clear() for path in editor.file_paths: @@ -22,21 +20,30 @@ func _process(_delta): match ext: "md": _process_md(path) + # clear empty + for i in range(len(chapter_info)-1, -1, -1): + var info = chapter_info[i] + if not info.words: + chapter_info.remove(i) + _sort() _redraw() - - set_process(false) func _chapter(path:String, line:int, id:String): - chapter_info.append({ path=path, line=line, id=id, words=0, chars=0, unique=0 }) - + if not id: + id = "???" + chapter_info.append({ path=path, line=line, id=id, words=0, chaps=0 }) + func _process_md(path:String): var lines = TE_Util.load_text(path).split("\n") + var is_entire_file:bool = false + _chapter(path, 0, "NOH") var i = 0 while i < len(lines): # skip head meta if i == 0 and lines[i].begins_with("---"): + is_entire_file = true i += 1 while i < len(lines) and not lines[i].begins_with("---"): i += 1 @@ -51,29 +58,20 @@ func _process_md(path:String): # heading elif lines[i].begins_with("#"): var p = lines[i].split(" ", true, 1) - var id = lines[i].split(" ", true, 1)[1].strip_edges() - _chapter(path, i, id) + var id = lines[i].split(" ", true, 1) + var deep = len(id[0]) + id = "???" if len(id) == 1 else id[1].strip_edges() + if deep == 1 and not is_entire_file: + _chapter(path, i, id) + else: + chapter_info[-1].chaps += 1 else: var words = lines[i].split(" ", false) - var unique = [] - for word in words: - var w = clean_word(word.to_lower()) - if w and not w in unique: - unique.append(w) - chapter_info[-1].words += len(words) - chapter_info[-1].unique += len(unique) i += 1 -func clean_word(w:String): - var out = "" - for c in w: - if c in "abcdefghijklmnopqrstuvwxyz": - out += c - return out - func _clicked(args): match args[0]: "sort_table": @@ -87,35 +85,41 @@ func _clicked(args): _redraw() "goto": - print(args) var tab = editor.open_file(args[1]) editor.select_file(args[1]) tab.goto_line(args[2]) func _sort(): if sort_reverse[sort_on]: - chapter_info.sort_custom(self, "_sort_chapters") - else: chapter_info.sort_custom(self, "_sort_chapters_r") + else: + chapter_info.sort_custom(self, "_sort_chapters") -func _sort_chapters(a, b): return a[sort_on] < b[sort_on] -func _sort_chapters_r(a, b): return a[sort_on] >= b[sort_on] +func _sort_chapters(a, b): + return a[sort_on] < b[sort_on] + +func _sort_chapters_r(a, b): + return a[sort_on] > b[sort_on] func _redraw(): clear() var c1 = Color.white.darkened(.4) var c2 = Color.white.darkened(.3) - + var cols = ["id", "words", "chaps"] push_align(RichTextLabel.ALIGN_CENTER) - push_table(3) - for id in ["id", "words", "unique"]: + push_table(len(cols)) + for id in cols: push_cell() push_bold() push_meta(add_meta(["sort_table", id], "sort on %s" % id)) add_text(id) if sort_on == id: - push_color(Color.white.darkened(.5)) + push_color(Color.greenyellow.darkened(.25)) + add_text(" ⯅" if sort_reverse[id] else " ⯆") + pop() + else: + push_color(Color.white.darkened(.7)) add_text(" ⯅" if sort_reverse[id] else " ⯆") pop() pop() @@ -124,10 +128,6 @@ func _redraw(): for i in len(chapter_info): var item = chapter_info[i] - - if item.id == "NOH" and not item.words: - continue - var clr = c1 if i%2==0 else c2 # id @@ -140,10 +140,10 @@ func _redraw(): pop() # word cound - for w in ["words", "unique"]: + for x in ["words", "chaps"]: push_cell() push_color(clr) - add_text(TE_Util.commas(item[w])) + add_text(TE_Util.commas(item[x])) pop() pop() diff --git a/addons/text_editor/TE_Search.gd b/addons/text_editor/TE_Search.gd index 71d27e4..7cec0fb 100644 --- a/addons/text_editor/TE_Search.gd +++ b/addons/text_editor/TE_Search.gd @@ -21,7 +21,7 @@ func _unhandled_key_input(e): line_edit.grab_focus() line_edit.grab_click_focus() get_parent().get_parent().show() - get_parent().get_parent().current_tab = get_index() + get_parent().get_parent().current_tab = get_parent().get_index() get_tree().set_input_as_handled() func _clicked(args): diff --git a/addons/text_editor/TE_SymbolsList.gd b/addons/text_editor/TE_SymbolsList.gd index 1d47f53..719d5bf 100644 --- a/addons/text_editor/TE_SymbolsList.gd +++ b/addons/text_editor/TE_SymbolsList.gd @@ -1,10 +1,14 @@ tool extends "res://addons/text_editor/TE_RichTextLabel.gd" +var hscrolls:Dictionary = {} + func _ready(): var _e _e = editor.connect("symbols_updated", self, "_redraw") _e = editor.connect("tags_updated", self, "_redraw") + _e = editor.connect("file_selected", self, "_file_selected") + _e = get_v_scroll().connect("value_changed", self, "_scrolling") add_font_override("normal_font", editor.FONT_R) add_font_override("bold_font", editor.FONT_B) @@ -13,6 +17,13 @@ func _ready(): call_deferred("_redraw") +func _file_selected(file_path:String): + yield(get_tree(), "idle_frame") + get_v_scroll().value = hscrolls.get(file_path, 0) + +func _scrolling(v): + hscrolls[editor.get_selected_file()] = get_v_scroll().value + func _clicked(args:Array): var te:TextEdit = editor.get_selected_tab() te.goto_line(args[1]) @@ -44,7 +55,14 @@ func _redraw(): var symbol_info = symbols[line_index] var deep = symbol_info.deep var space = "" if not deep else clr("-".repeat(deep), Color.white.darkened(.75)) - var cl = Color.deepskyblue if deep == 0 else Color.white + var cl = Color.white + + if deep == 0: + cl = editor.color_symbol + if symbol_info.name.begins_with("*") and symbol_info.name.ends_with("*"): + cl = TE_Util.hue_shift(cl, -.33) + elif symbol_info.name.begins_with('"') and symbol_info.name.ends_with('"'): + cl = TE_Util.hue_shift(cl, .33) if not editor.is_tagged_or_visible(symbol_info.tags): cl = cl.darkened(.7) diff --git a/addons/text_editor/TE_TabScroller.gd b/addons/text_editor/TE_TabScroller.gd index dac8cb8..f56b142 100644 --- a/addons/text_editor/TE_TabScroller.gd +++ b/addons/text_editor/TE_TabScroller.gd @@ -1,7 +1,7 @@ tool extends TabContainer -onready var editor:TE_TextEditor = owner +onready var editor:TE_Editor = owner var mouse_over:bool = false diff --git a/addons/text_editor/TextEditor.tscn b/addons/text_editor/TextEditor.tscn index 6210480..d9fbbc6 100644 --- a/addons/text_editor/TextEditor.tscn +++ b/addons/text_editor/TextEditor.tscn @@ -1,7 +1,7 @@ -[gd_scene load_steps=24 format=2] +[gd_scene load_steps=25 format=2] [ext_resource path="res://addons/text_editor/TE_Console.gd" type="Script" id=1] -[ext_resource path="res://addons/text_editor/TE_TextEditor.gd" type="Script" id=2] +[ext_resource path="res://addons/text_editor/TE_Editor.gd" type="Script" id=2] [ext_resource path="res://addons/text_editor/TE_FilesList.gd" type="Script" id=3] [ext_resource path="res://addons/text_editor/TE_FileEditor.gd" type="Script" id=4] [ext_resource path="res://addons/text_editor/TE_SymbolsList.gd" type="Script" id=5] @@ -36,6 +36,9 @@ TooltipLabel/fonts/font = ExtResource( 12 ) [sub_resource type="Theme" id=6] TooltipLabel/fonts/font = ExtResource( 12 ) +[sub_resource type="Theme" id=7] +TooltipLabel/fonts/font = ExtResource( 12 ) + [node name="text_editor" type="Control"] anchor_right = 1.0 anchor_bottom = 1.0 @@ -76,23 +79,23 @@ __meta__ = { [node name="c" type="PanelContainer" parent="c"] margin_right = 1024.0 -margin_bottom = 34.0 +margin_bottom = 38.0 [node name="c" type="HBoxContainer" parent="c/c"] margin_left = 7.0 margin_top = 7.0 margin_right = 1017.0 -margin_bottom = 27.0 +margin_bottom = 31.0 [node name="test" type="Button" parent="c/c/c"] margin_right = 12.0 -margin_bottom = 20.0 +margin_bottom = 24.0 text = "⟳" [node name="file_button" type="MenuButton" parent="c/c/c"] margin_left = 16.0 margin_right = 48.0 -margin_bottom = 20.0 +margin_bottom = 24.0 text = "file" items = [ "New File", null, 0, false, false, 0, 0, null, "", false, "Extensions", null, 0, false, false, 1, 0, null, "Extensions", false, "New File", null, 0, false, false, 2, 0, null, "", false, "Extensions", null, 0, false, false, 3, 0, null, "Extensions", false ] __meta__ = { @@ -102,7 +105,7 @@ __meta__ = { [node name="view_button" type="MenuButton" parent="c/c/c"] margin_left = 52.0 margin_right = 93.0 -margin_bottom = 20.0 +margin_bottom = 24.0 focus_mode = 2 text = "view" items = [ "New File", null, 0, false, false, 0, 0, null, "", false, "Extensions", null, 0, false, false, 1, 0, null, "Extensions", false, "New File", null, 0, false, false, 2, 0, null, "", false, "Extensions", null, 0, false, false, 3, 0, null, "Extensions", false ] @@ -110,8 +113,14 @@ __meta__ = { "_edit_use_anchors_": false } +[node name="word_wrap" type="CheckBox" parent="c/c/c"] +margin_left = 97.0 +margin_right = 155.0 +margin_bottom = 24.0 +text = "wrap" + [node name="div1" type="HSplitContainer" parent="c"] -margin_top = 34.0 +margin_top = 38.0 margin_right = 1024.0 margin_bottom = 600.0 size_flags_vertical = 3 @@ -122,7 +131,7 @@ __meta__ = { [node name="c2" type="PanelContainer" parent="c/div1"] margin_right = 206.0 -margin_bottom = 566.0 +margin_bottom = 562.0 rect_min_size = Vector2( 200, 0 ) size_flags_horizontal = 3 size_flags_vertical = 3 @@ -131,7 +140,7 @@ size_flags_vertical = 3 margin_left = 7.0 margin_top = 7.0 margin_right = 199.0 -margin_bottom = 559.0 +margin_bottom = 555.0 size_flags_horizontal = 3 size_flags_vertical = 3 @@ -167,7 +176,7 @@ items = [ "New File", null, 0, false, false, 0, 0, null, "", false, "New Folder" [node name="div2" type="HSplitContainer" parent="c/div1"] margin_left = 218.0 margin_right = 1024.0 -margin_bottom = 566.0 +margin_bottom = 562.0 size_flags_horizontal = 3 size_flags_vertical = 3 split_offset = -80 @@ -177,7 +186,7 @@ __meta__ = { [node name="c" type="VBoxContainer" parent="c/div1/div2"] margin_right = 614.0 -margin_bottom = 566.0 +margin_bottom = 562.0 size_flags_horizontal = 3 size_flags_vertical = 3 @@ -190,14 +199,14 @@ script = ExtResource( 8 ) [node name="c" type="VSplitContainer" parent="c/div1/div2/c"] margin_right = 614.0 -margin_bottom = 566.0 +margin_bottom = 562.0 size_flags_horizontal = 3 size_flags_vertical = 3 split_offset = -200 [node name="tab_container" type="TabContainer" parent="c/div1/div2/c/c"] margin_right = 614.0 -margin_bottom = 566.0 +margin_bottom = 562.0 size_flags_horizontal = 3 size_flags_vertical = 3 custom_fonts/font = ExtResource( 12 ) @@ -224,10 +233,36 @@ margin_right = -4.0 margin_bottom = -4.0 size_flags_horizontal = 3 size_flags_vertical = 3 +theme = SubResource( 2 ) +custom_fonts/bold_italics_font = ExtResource( 13 ) +custom_fonts/italics_font = ExtResource( 10 ) +custom_fonts/bold_font = ExtResource( 11 ) +custom_fonts/normal_font = ExtResource( 12 ) bbcode_enabled = true meta_underlined = false +text = "active: False +" script = ExtResource( 1 ) +[node name="meta" type="RichTextLabel" parent="c/div1/div2/c/c/meta_tabs"] +visible = false +anchor_right = 1.0 +anchor_bottom = 1.0 +margin_left = 4.0 +margin_top = 32.0 +margin_right = -4.0 +margin_bottom = -4.0 +size_flags_horizontal = 3 +size_flags_vertical = 3 +theme = SubResource( 3 ) +custom_constants/table_hseparation = 16 +custom_fonts/bold_italics_font = ExtResource( 13 ) +custom_fonts/italics_font = ExtResource( 10 ) +custom_fonts/bold_font = ExtResource( 11 ) +custom_fonts/normal_font = ExtResource( 12 ) +bbcode_enabled = true +script = ExtResource( 9 ) + [node name="search" type="VBoxContainer" parent="c/div1/div2/c/c/meta_tabs"] visible = false anchor_right = 1.0 @@ -251,7 +286,7 @@ margin_right = 58.0 margin_bottom = 28.0 size_flags_horizontal = 3 size_flags_vertical = 3 -theme = SubResource( 2 ) +theme = SubResource( 4 ) custom_fonts/bold_italics_font = ExtResource( 13 ) custom_fonts/italics_font = ExtResource( 10 ) custom_fonts/bold_font = ExtResource( 11 ) @@ -260,7 +295,7 @@ bbcode_enabled = true meta_underlined = false script = ExtResource( 15 ) -[node name="meta" type="RichTextLabel" parent="c/div1/div2/c/c/meta_tabs"] +[node name="sys" type="VBoxContainer" parent="c/div1/div2/c/c/meta_tabs"] visible = false anchor_right = 1.0 anchor_bottom = 1.0 @@ -268,28 +303,22 @@ margin_left = 4.0 margin_top = 32.0 margin_right = -4.0 margin_bottom = -4.0 -size_flags_horizontal = 3 -size_flags_vertical = 3 -theme = SubResource( 3 ) -custom_constants/table_hseparation = 16 -custom_fonts/bold_italics_font = ExtResource( 13 ) -custom_fonts/italics_font = ExtResource( 10 ) -custom_fonts/bold_font = ExtResource( 11 ) -custom_fonts/normal_font = ExtResource( 12 ) -bbcode_enabled = true -script = ExtResource( 9 ) -[node name="sys" type="RichTextLabel" parent="c/div1/div2/c/c/meta_tabs"] -visible = false +[node name="update" type="Button" parent="c/div1/div2/c/c/meta_tabs/sys"] +margin_right = 12.0 +margin_bottom = 20.0 +size_flags_horizontal = 3 +custom_fonts/font = ExtResource( 12 ) +text = "⟳" + +[node name="sys" type="RichTextLabel" parent="c/div1/div2/c/c/meta_tabs/sys"] anchor_right = 1.0 anchor_bottom = 1.0 -margin_left = 4.0 -margin_top = 32.0 -margin_right = -4.0 -margin_bottom = -4.0 +margin_right = -8.0 +margin_bottom = -36.0 size_flags_horizontal = 3 size_flags_vertical = 3 -theme = SubResource( 4 ) +theme = SubResource( 5 ) custom_constants/table_hseparation = 101 custom_fonts/bold_italics_font = ExtResource( 13 ) custom_fonts/italics_font = ExtResource( 10 ) @@ -303,7 +332,7 @@ script = ExtResource( 17 ) [node name="c2" type="PanelContainer" parent="c/div1/div2"] margin_left = 626.0 margin_right = 806.0 -margin_bottom = 566.0 +margin_bottom = 562.0 rect_min_size = Vector2( 100, 0 ) size_flags_vertical = 3 @@ -311,12 +340,13 @@ size_flags_vertical = 3 margin_left = 7.0 margin_top = 7.0 margin_right = 173.0 -margin_bottom = 559.0 +margin_bottom = 555.0 custom_constants/autohide = 0 +split_offset = 180 [node name="c" type="Panel" parent="c/div1/div2/c2/c"] margin_right = 166.0 -margin_bottom = 270.0 +margin_bottom = 448.0 size_flags_horizontal = 3 size_flags_vertical = 3 @@ -324,7 +354,7 @@ size_flags_vertical = 3 anchor_right = 1.0 anchor_bottom = 1.0 size_flags_vertical = 3 -theme = SubResource( 5 ) +theme = SubResource( 6 ) custom_fonts/bold_italics_font = ExtResource( 13 ) custom_fonts/italics_font = ExtResource( 10 ) custom_fonts/bold_font = ExtResource( 11 ) @@ -339,9 +369,9 @@ __meta__ = { } [node name="c2" type="Panel" parent="c/div1/div2/c2/c"] -margin_top = 282.0 +margin_top = 460.0 margin_right = 166.0 -margin_bottom = 552.0 +margin_bottom = 548.0 size_flags_horizontal = 3 size_flags_vertical = 3 @@ -350,7 +380,7 @@ anchor_right = 1.0 anchor_bottom = 1.0 size_flags_horizontal = 3 size_flags_vertical = 3 -theme = SubResource( 6 ) +theme = SubResource( 7 ) custom_fonts/bold_italics_font = ExtResource( 13 ) custom_fonts/italics_font = ExtResource( 10 ) custom_fonts/bold_font = ExtResource( 11 ) diff --git a/addons/text_editor/ext/ext_ini.gd b/addons/text_editor/ext/ext_ini.gd index 32a2819..776f604 100644 --- a/addons/text_editor/ext/ext_ini.gd +++ b/addons/text_editor/ext/ext_ini.gd @@ -1,7 +1,7 @@ tool extends TE_ExtensionHelper -func apply_colors(e:TE_TextEditor, t:TextEdit): +func apply_colors(e:TE_Editor, t:TextEdit): .apply_colors(e, t) # symbols t.add_color_region("[", "]", e.color_symbol, false) @@ -27,6 +27,7 @@ func get_symbols(t:String) -> Dictionary: # tags elif lines[i].begins_with(";") and "#" in lines[i]: for t in lines[i].substr(1).split("#"): + t = t.strip_edges() if t: last.tags.append(t) diff --git a/addons/text_editor/ext/ext_json.gd b/addons/text_editor/ext/ext_json.gd index 3fbd557..693b6b3 100644 --- a/addons/text_editor/ext/ext_json.gd +++ b/addons/text_editor/ext/ext_json.gd @@ -34,7 +34,7 @@ func get_symbols(t:String): return out -func apply_colors(e:TE_TextEditor, t:TextEdit): +func apply_colors(e:TE_Editor, t:TextEdit): .apply_colors(e, t) # vars diff --git a/addons/text_editor/ext/ext_md.gd b/addons/text_editor/ext/ext_md.gd index 22a2df5..ba30754 100644 --- a/addons/text_editor/ext/ext_md.gd +++ b/addons/text_editor/ext/ext_md.gd @@ -18,7 +18,7 @@ func apply_colors(e:TE_TextEditor, t:TextEdit): t.add_color_region("*", "*", Color.tomato.lightened(.3), false) # quote - t.add_color_region("> ", "", e.color_text.darkened(.6), true) + t.add_color_region("> ", "", lerp(e.color_text, e.color_symbol, .5), true) # comment t.add_color_region("", e.color_comment, false) @@ -66,11 +66,23 @@ func get_symbols(t:String) -> Dictionary: var i = 0 while i < len(lines): + # initial meta data + if i == 0 and lines[i].begins_with("---"): + i += 1 + while i < len(lines) and not lines[i].begins_with("---"): + if "tags: " in lines[i]: + for tag in lines[i].split("tags: ", true, 1)[1].split("#"): + tag = tag.strip_edges() + if tag: + last.tags.append(tag) + i += 1 + i += 1 + # symbols - if lines[i].begins_with("#"): + elif lines[i].begins_with("#"): var p = lines[i].split(" ", true, 1) var deep = len(p[0])-1 - var name = p[1].strip_edges() + var name = "???" if len(p) == 1 else p[1].strip_edges() last = add_symbol(i, deep, name) # tags diff --git a/addons/text_editor/ext/ext_yaml.gd b/addons/text_editor/ext/ext_yaml.gd index c30b520..2452bdc 100644 --- a/addons/text_editor/ext/ext_yaml.gd +++ b/addons/text_editor/ext/ext_yaml.gd @@ -43,7 +43,7 @@ func toggle_comment(t:TextEdit, head:String="", tail:String=""): return [old, new] -func apply_colors(e:TE_TextEditor, t:TextEdit): +func apply_colors(e:TE_Editor, t:TextEdit): .apply_colors(e, t) # strings diff --git a/addons/text_editor/fonts/font.tres b/addons/text_editor/fonts/font.tres index 434cb0c..3b524c2 100644 --- a/addons/text_editor/fonts/font.tres +++ b/addons/text_editor/fonts/font.tres @@ -5,6 +5,7 @@ [ext_resource path="res://addons/text_editor/fonts/unifont-13.0.01.ttf" type="DynamicFontData" id=3] [resource] +use_filter = true font_data = ExtResource( 1 ) fallback/0 = ExtResource( 3 ) fallback/1 = ExtResource( 2 ) diff --git a/addons/text_editor/fonts/font_b.tres b/addons/text_editor/fonts/font_b.tres index 89666f3..fd18dc1 100644 --- a/addons/text_editor/fonts/font_b.tres +++ b/addons/text_editor/fonts/font_b.tres @@ -5,6 +5,7 @@ [ext_resource path="res://addons/text_editor/fonts/unifont-13.0.01.ttf" type="DynamicFontData" id=3] [resource] +use_filter = true font_data = ExtResource( 1 ) fallback/0 = ExtResource( 3 ) fallback/1 = ExtResource( 2 ) diff --git a/addons/text_editor/fonts/font_bi.tres b/addons/text_editor/fonts/font_bi.tres index ca19d40..2961810 100644 --- a/addons/text_editor/fonts/font_bi.tres +++ b/addons/text_editor/fonts/font_bi.tres @@ -5,6 +5,7 @@ [ext_resource path="res://addons/text_editor/fonts/unifont-13.0.01.ttf" type="DynamicFontData" id=3] [resource] +use_filter = true font_data = ExtResource( 1 ) fallback/0 = ExtResource( 3 ) fallback/1 = ExtResource( 2 ) diff --git a/addons/text_editor/fonts/font_i.tres b/addons/text_editor/fonts/font_i.tres index 314dea7..23aa8e0 100644 --- a/addons/text_editor/fonts/font_i.tres +++ b/addons/text_editor/fonts/font_i.tres @@ -5,6 +5,7 @@ [ext_resource path="res://addons/text_editor/fonts/unifont-13.0.01.ttf" type="DynamicFontData" id=3] [resource] +use_filter = true font_data = ExtResource( 1 ) fallback/0 = ExtResource( 3 ) fallback/1 = ExtResource( 2 ) diff --git a/addons/text_editor/fonts/font_r.tres b/addons/text_editor/fonts/font_r.tres index 434cb0c..3b524c2 100644 --- a/addons/text_editor/fonts/font_r.tres +++ b/addons/text_editor/fonts/font_r.tres @@ -5,6 +5,7 @@ [ext_resource path="res://addons/text_editor/fonts/unifont-13.0.01.ttf" type="DynamicFontData" id=3] [resource] +use_filter = true font_data = ExtResource( 1 ) fallback/0 = ExtResource( 3 ) fallback/1 = ExtResource( 2 ) diff --git a/addons/text_editor/plugin.cfg b/addons/text_editor/plugin.cfg index c7e48e2..b8170bc 100644 --- a/addons/text_editor/plugin.cfg +++ b/addons/text_editor/plugin.cfg @@ -3,5 +3,5 @@ name="TextEditor" description="A text editor for Godot." author="teebar" -version="1.4" +version="1.5" script="plugin.gd"