tool extends TextEdit var editor:TextEditor var _hscroll:HScrollBar var _vscroll:VScrollBar var helper:TE_ExtensionHelper var temporary:bool = false setget set_temporary var modified:bool = false var file_path:String = "" var symbols:Dictionary = {} var tags:Dictionary = {} var last_key:int var last_shift:bool var last_selected:bool var last_selection:Array = [0, 0, 0, 0] var hscroll:int = 0 var vscroll:int = 0 func _ready(): var _e if not editor: editor = owner _e = editor.connect("save_files", self, "save_file") _e = editor.connect("file_selected", self, "_file_selected") _e = editor.connect("file_renamed", self, "_file_renamed") _e = connect("text_changed", self, "text_changed") if get_parent() is TabContainer: get_parent().connect("tab_changed", self, "_tab_changed") add_font_override("font", editor.FONT) get_menu().add_font_override("font", editor.FONT) TE_Util.dig(self, self, "_node") func _node(n): var _e if n is HScrollBar: _e = n.connect("changed", self, "_scroll_h", [n]) elif n is VScrollBar: _e = n.connect("changed", self, "_scroll_v", [n]) n.allow_greater = true func _scroll_h(h:HScrollBar): hscroll = h.value func _scroll_v(v:VScrollBar): vscroll = v.value prints(file_path, vscroll) func _tab_changed(index:int): var myindex = get_index() if index == myindex and visible: yield(get_tree(), "idle_frame") set_h_scroll(hscroll) set_v_scroll(vscroll) func get_state() -> Dictionary: return { hscroll=scroll_horizontal, vscroll=scroll_vertical } 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) func _file_renamed(old_path:String, new_path:String): if old_path == file_path: file_path = new_path update_name() func _input(e): if not editor.is_plugin_active(): return if not visible: return # remember last selection if e is InputEventKey and e.pressed: last_key = e.scancode last_shift = e.shift if is_selection_active(): last_selected = true last_selection[0] = get_selection_from_line() last_selection[1] = get_selection_from_column() last_selection[2] = get_selection_to_line() last_selection[3] = get_selection_to_column() else: last_selected = false # move lines up/down if e is InputEventKey and e.control and e.shift and e.pressed: var f var t if is_selection_active(): f = get_selection_from_line() t = get_selection_to_line() else: f = cursor_get_line() t = cursor_get_line() # move selected text up or down if e.scancode == KEY_UP and f > 0: var lines = [] for i in range(f-1, t+1): lines.append(get_line(i)) lines.push_back(lines.pop_front()) for i in len(lines): set_line(f-1+i, lines[i]) select(f-1, 0, t-1, len(get_line(t-1))) cursor_set_line(cursor_get_line()-1, false) if e.scancode == KEY_DOWN and t < get_line_count()-1: var lines = [] for i in range(f, t+2): lines.append(get_line(i)) lines.push_front(lines.pop_back()) for i in len(lines): set_line(f+i, lines[i]) select(f+1, 0, t+1, len(get_line(t+1))) cursor_set_line(cursor_get_line()+1, false) func _unhandled_key_input(e): if not visible: return # comment code if e.scancode == KEY_SLASH and e.control and e.pressed: helper.toggle_comment(self) get_tree().set_input_as_handled() func _file_selected(p:String): if not p: return if p == file_path: grab_focus() grab_click_focus() update_symbols() update_heading() func text_changed(): if last_selected: match last_key: KEY_APOSTROPHE: undo() select(last_selection[0], last_selection[1], last_selection[2], last_selection[3]) if last_shift: insert_text_at_cursor("\"%s\"" % get_selection_text()) else: insert_text_at_cursor("'%s'" % get_selection_text()) KEY_QUOTELEFT: undo() select(last_selection[0], last_selection[1], last_selection[2], last_selection[3]) insert_text_at_cursor("`%s`" % get_selection_text()) _: print(last_key) if not modified: if temporary: temporary = false modified = true update_name() func set_temporary(t): temporary = t update_name() func update_symbols(): symbols.clear() tags.clear() # symbol getter symbols = helper.get_symbols(text) # collect tags for line_index in symbols: var line_info = symbols[line_index] for tag in line_info.tags: if not tag in tags: tags[tag] = 1 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() else: editor._close_file(file_path) func _popup(msg): match msg: "close": editor._close_file(file_path) "save_and_close": save_file() editor._close_file(file_path) func load_file(path:String): file_path = path text = TE_Util.load_text(path) update_name() # update colors clear_colors() helper = TextEditor.get_extension_helper(file_path) helper.apply_colors(editor, self) func save_file(): if modified: if not file_path.begins_with("res://"): push_error("can't save to %s" % file_path) 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 editor.tab_parent.set_tab_title(get_index(), n) update_heading() func update_heading(): # set window "file (directory)" var f = file_path.get_file() if modified: f = "*" + f var d = file_path.get_base_dir().get_file() if d: OS.set_window_title("%s (%s)" % [f, d]) else: OS.set_window_title(f) func needs_save() -> bool: return modified or not File.new().file_exists(file_path)