Browse Source

Store line change in script navigation history

kobewi 2 years ago
parent
commit
3a1246c198

+ 6 - 0
doc/classes/ScriptEditorBase.xml

@@ -71,6 +71,12 @@
 				Emitted when the user contextual goto and the item is in the same script.
 				Emitted when the user contextual goto and the item is in the same script.
 			</description>
 			</description>
 		</signal>
 		</signal>
+		<signal name="request_save_previous_state">
+			<param index="0" name="line" type="int" />
+			<description>
+				Emitted when the user changes current script or moves caret by 10 or more columns within the same script.
+			</description>
+		</signal>
 		<signal name="search_in_files_requested">
 		<signal name="search_in_files_requested">
 			<param index="0" name="text" type="String" />
 			<param index="0" name="text" type="String" />
 			<description>
 			<description>

+ 18 - 1
editor/code_editor.cpp

@@ -1613,13 +1613,26 @@ Variant CodeTextEditor::get_edit_state() {
 	return state;
 	return state;
 }
 }
 
 
+Variant CodeTextEditor::get_previous_state() {
+	return previous_state;
+}
+
+void CodeTextEditor::store_previous_state() {
+	previous_state = get_navigation_state();
+}
+
 void CodeTextEditor::set_edit_state(const Variant &p_state) {
 void CodeTextEditor::set_edit_state(const Variant &p_state) {
 	Dictionary state = p_state;
 	Dictionary state = p_state;
 
 
 	/* update the row first as it sets the column to 0 */
 	/* update the row first as it sets the column to 0 */
 	text_editor->set_caret_line(state["row"]);
 	text_editor->set_caret_line(state["row"]);
 	text_editor->set_caret_column(state["column"]);
 	text_editor->set_caret_column(state["column"]);
-	text_editor->set_v_scroll(state["scroll_position"]);
+	if (int(state["scroll_position"]) == -1) {
+		// Special case for previous state.
+		text_editor->center_viewport_to_caret();
+	} else {
+		text_editor->set_v_scroll(state["scroll_position"]);
+	}
 	text_editor->set_h_scroll(state["h_scroll_position"]);
 	text_editor->set_h_scroll(state["h_scroll_position"]);
 
 
 	if (state.get("selection", false)) {
 	if (state.get("selection", false)) {
@@ -1648,6 +1661,10 @@ void CodeTextEditor::set_edit_state(const Variant &p_state) {
 			text_editor->set_line_as_bookmarked(bookmarks[i], true);
 			text_editor->set_line_as_bookmarked(bookmarks[i], true);
 		}
 		}
 	}
 	}
+
+	if (previous_state.is_empty()) {
+		previous_state = p_state;
+	}
 }
 }
 
 
 Variant CodeTextEditor::get_navigation_state() {
 Variant CodeTextEditor::get_navigation_state() {

+ 4 - 0
editor/code_editor.h

@@ -174,6 +174,8 @@ class CodeTextEditor : public VBoxContainer {
 	int error_line;
 	int error_line;
 	int error_column;
 	int error_column;
 
 
+	Dictionary previous_state;
+
 	void _update_text_editor_theme();
 	void _update_text_editor_theme();
 	void _update_font_ligatures();
 	void _update_font_ligatures();
 	void _complete_request();
 	void _complete_request();
@@ -254,6 +256,8 @@ public:
 	Variant get_edit_state();
 	Variant get_edit_state();
 	void set_edit_state(const Variant &p_state);
 	void set_edit_state(const Variant &p_state);
 	Variant get_navigation_state();
 	Variant get_navigation_state();
+	Variant get_previous_state();
+	void store_previous_state();
 
 
 	void set_error_count(int p_error_count);
 	void set_error_count(int p_error_count);
 	void set_warning_count(int p_warning_count);
 	void set_warning_count(int p_warning_count);

+ 2 - 0
editor/editor_help.cpp

@@ -287,6 +287,7 @@ void EditorHelp::_class_desc_select(const String &p_select) {
 		if (table->has(link)) {
 		if (table->has(link)) {
 			// Found in the current page.
 			// Found in the current page.
 			if (class_desc->is_ready()) {
 			if (class_desc->is_ready()) {
+				emit_signal(SNAME("request_save_history"));
 				class_desc->scroll_to_paragraph((*table)[link]);
 				class_desc->scroll_to_paragraph((*table)[link]);
 			} else {
 			} else {
 				scroll_to = (*table)[link];
 				scroll_to = (*table)[link];
@@ -3077,6 +3078,7 @@ void EditorHelp::_bind_methods() {
 	ClassDB::bind_method("_help_callback", &EditorHelp::_help_callback);
 	ClassDB::bind_method("_help_callback", &EditorHelp::_help_callback);
 
 
 	ADD_SIGNAL(MethodInfo("go_to_help"));
 	ADD_SIGNAL(MethodInfo("go_to_help"));
+	ADD_SIGNAL(MethodInfo("request_save_history"));
 }
 }
 
 
 void EditorHelp::init_gdext_pointers() {
 void EditorHelp::init_gdext_pointers() {

+ 45 - 5
editor/plugins/script_editor_plugin.cpp

@@ -273,6 +273,7 @@ void ScriptEditorBase::_bind_methods() {
 	ADD_SIGNAL(MethodInfo("request_help", PropertyInfo(Variant::STRING, "topic")));
 	ADD_SIGNAL(MethodInfo("request_help", PropertyInfo(Variant::STRING, "topic")));
 	ADD_SIGNAL(MethodInfo("request_open_script_at_line", PropertyInfo(Variant::OBJECT, "script"), PropertyInfo(Variant::INT, "line")));
 	ADD_SIGNAL(MethodInfo("request_open_script_at_line", PropertyInfo(Variant::OBJECT, "script"), PropertyInfo(Variant::INT, "line")));
 	ADD_SIGNAL(MethodInfo("request_save_history"));
 	ADD_SIGNAL(MethodInfo("request_save_history"));
+	ADD_SIGNAL(MethodInfo("request_save_previous_state", PropertyInfo(Variant::INT, "line")));
 	ADD_SIGNAL(MethodInfo("go_to_help", PropertyInfo(Variant::STRING, "what")));
 	ADD_SIGNAL(MethodInfo("go_to_help", PropertyInfo(Variant::STRING, "what")));
 	ADD_SIGNAL(MethodInfo("search_in_files_requested", PropertyInfo(Variant::STRING, "text")));
 	ADD_SIGNAL(MethodInfo("search_in_files_requested", PropertyInfo(Variant::STRING, "text")));
 	ADD_SIGNAL(MethodInfo("replace_in_files_requested", PropertyInfo(Variant::STRING, "text")));
 	ADD_SIGNAL(MethodInfo("replace_in_files_requested", PropertyInfo(Variant::STRING, "text")));
@@ -639,6 +640,32 @@ void ScriptEditor::_save_history() {
 	_update_history_arrows();
 	_update_history_arrows();
 }
 }
 
 
+void ScriptEditor::_save_previous_state(Dictionary p_state) {
+	if (lock_history) {
+		// Done as a result of a deferred call triggered by set_edit_state().
+		lock_history = false;
+		return;
+	}
+
+	if (history_pos >= 0 && history_pos < history.size() && history[history_pos].control == tab_container->get_current_tab_control()) {
+		Node *n = tab_container->get_current_tab_control();
+
+		if (Object::cast_to<ScriptTextEditor>(n)) {
+			history.write[history_pos].state = p_state;
+		}
+	}
+
+	history.resize(history_pos + 1);
+	ScriptHistory sh;
+	sh.control = tab_container->get_current_tab_control();
+	sh.state = Variant();
+
+	history.push_back(sh);
+	history_pos++;
+
+	_update_history_arrows();
+}
+
 void ScriptEditor::_go_to_tab(int p_idx) {
 void ScriptEditor::_go_to_tab(int p_idx) {
 	ScriptEditorBase *current = _get_current_editor();
 	ScriptEditorBase *current = _get_current_editor();
 	if (current) {
 	if (current) {
@@ -668,8 +695,10 @@ void ScriptEditor::_go_to_tab(int p_idx) {
 	sh.control = c;
 	sh.control = c;
 	sh.state = Variant();
 	sh.state = Variant();
 
 
-	history.push_back(sh);
-	history_pos++;
+	if (!lock_history && (history.is_empty() || history[history.size() - 1].control != sh.control)) {
+		history.push_back(sh);
+		history_pos++;
+	}
 
 
 	tab_container->set_current_tab(p_idx);
 	tab_container->set_current_tab(p_idx);
 
 
@@ -2185,8 +2214,11 @@ void ScriptEditor::_update_script_names() {
 			sd.index = i;
 			sd.index = i;
 			sedata.set(i, sd);
 			sedata.set(i, sd);
 		}
 		}
+
+		lock_history = true;
 		_go_to_tab(new_prev_tab);
 		_go_to_tab(new_prev_tab);
 		_go_to_tab(new_cur_tab);
 		_go_to_tab(new_cur_tab);
+		lock_history = false;
 		_sort_list_on_update = false;
 		_sort_list_on_update = false;
 	}
 	}
 
 
@@ -2474,6 +2506,10 @@ bool ScriptEditor::edit(const Ref<Resource> &p_resource, int p_line, int p_col,
 
 
 	if (script_editor_cache->has_section(p_resource->get_path())) {
 	if (script_editor_cache->has_section(p_resource->get_path())) {
 		se->set_edit_state(script_editor_cache->get_value(p_resource->get_path(), "state"));
 		se->set_edit_state(script_editor_cache->get_value(p_resource->get_path(), "state"));
+		ScriptTextEditor *ste = Object::cast_to<ScriptTextEditor>(se);
+		if (ste) {
+			ste->store_previous_state();
+		}
 	}
 	}
 
 
 	_sort_list_on_update = true;
 	_sort_list_on_update = true;
@@ -2485,6 +2521,7 @@ bool ScriptEditor::edit(const Ref<Resource> &p_resource, int p_line, int p_col,
 	se->connect("request_open_script_at_line", callable_mp(this, &ScriptEditor::_goto_script_line));
 	se->connect("request_open_script_at_line", callable_mp(this, &ScriptEditor::_goto_script_line));
 	se->connect("go_to_help", callable_mp(this, &ScriptEditor::_help_class_goto));
 	se->connect("go_to_help", callable_mp(this, &ScriptEditor::_help_class_goto));
 	se->connect("request_save_history", callable_mp(this, &ScriptEditor::_save_history));
 	se->connect("request_save_history", callable_mp(this, &ScriptEditor::_save_history));
+	se->connect("request_save_previous_state", callable_mp(this, &ScriptEditor::_save_previous_state));
 	se->connect("search_in_files_requested", callable_mp(this, &ScriptEditor::_on_find_in_files_requested));
 	se->connect("search_in_files_requested", callable_mp(this, &ScriptEditor::_on_find_in_files_requested));
 	se->connect("replace_in_files_requested", callable_mp(this, &ScriptEditor::_on_replace_in_files_requested));
 	se->connect("replace_in_files_requested", callable_mp(this, &ScriptEditor::_on_replace_in_files_requested));
 	se->connect("go_to_method", callable_mp(this, &ScriptEditor::script_goto_method));
 	se->connect("go_to_method", callable_mp(this, &ScriptEditor::script_goto_method));
@@ -3421,6 +3458,7 @@ void ScriptEditor::_help_class_open(const String &p_class) {
 	_go_to_tab(tab_container->get_tab_count() - 1);
 	_go_to_tab(tab_container->get_tab_count() - 1);
 	eh->go_to_class(p_class);
 	eh->go_to_class(p_class);
 	eh->connect("go_to_help", callable_mp(this, &ScriptEditor::_help_class_goto));
 	eh->connect("go_to_help", callable_mp(this, &ScriptEditor::_help_class_goto));
+	eh->connect("request_save_history", callable_mp(this, &ScriptEditor::_save_history));
 	_add_recent_script(p_class);
 	_add_recent_script(p_class);
 	_sort_list_on_update = true;
 	_sort_list_on_update = true;
 	_update_script_names();
 	_update_script_names();
@@ -3549,6 +3587,7 @@ void ScriptEditor::_update_history_pos(int p_new_pos) {
 
 
 	ScriptEditorBase *seb = Object::cast_to<ScriptEditorBase>(n);
 	ScriptEditorBase *seb = Object::cast_to<ScriptEditorBase>(n);
 	if (seb) {
 	if (seb) {
+		lock_history = true;
 		seb->set_edit_state(history[history_pos].state);
 		seb->set_edit_state(history[history_pos].state);
 		seb->ensure_focus();
 		seb->ensure_focus();
 
 
@@ -3558,9 +3597,10 @@ void ScriptEditor::_update_history_pos(int p_new_pos) {
 		}
 		}
 	}
 	}
 
 
-	if (Object::cast_to<EditorHelp>(n)) {
-		Object::cast_to<EditorHelp>(n)->set_scroll(history[history_pos].state);
-		Object::cast_to<EditorHelp>(n)->set_focused();
+	EditorHelp *eh = Object::cast_to<EditorHelp>(n);
+	if (eh) {
+		eh->set_scroll(history[history_pos].state);
+		eh->set_focused();
 	}
 	}
 
 
 	n->set_meta("__editor_pass", ++edit_pass);
 	n->set_meta("__editor_pass", ++edit_pass);

+ 2 - 0
editor/plugins/script_editor_plugin.h

@@ -472,12 +472,14 @@ class ScriptEditor : public PanelContainer {
 	void _history_back();
 	void _history_back();
 
 
 	bool waiting_update_names;
 	bool waiting_update_names;
+	bool lock_history = false;
 
 
 	void _help_class_open(const String &p_class);
 	void _help_class_open(const String &p_class);
 	void _help_class_goto(const String &p_desc);
 	void _help_class_goto(const String &p_desc);
 	bool _help_tab_goto(const String &p_name, const String &p_desc);
 	bool _help_tab_goto(const String &p_name, const String &p_desc);
 	void _update_history_arrows();
 	void _update_history_arrows();
 	void _save_history();
 	void _save_history();
+	void _save_previous_state(Dictionary p_state);
 	void _go_to_tab(int p_idx);
 	void _go_to_tab(int p_idx);
 	void _update_history_pos(int p_new_pos);
 	void _update_history_pos(int p_new_pos);
 	void _update_script_colors();
 	void _update_script_colors();

+ 24 - 3
editor/plugins/script_text_editor.cpp

@@ -412,6 +412,14 @@ Variant ScriptTextEditor::get_navigation_state() {
 	return code_editor->get_navigation_state();
 	return code_editor->get_navigation_state();
 }
 }
 
 
+Variant ScriptTextEditor::get_previous_state() {
+	return code_editor->get_previous_state();
+}
+
+void ScriptTextEditor::store_previous_state() {
+	return code_editor->store_previous_state();
+}
+
 void ScriptTextEditor::_convert_case(CodeTextEditor::CaseStyle p_case) {
 void ScriptTextEditor::_convert_case(CodeTextEditor::CaseStyle p_case) {
 	code_editor->convert_case(p_case);
 	code_editor->convert_case(p_case);
 }
 }
@@ -904,6 +912,18 @@ void ScriptTextEditor::_breakpoint_toggled(int p_row) {
 	EditorDebuggerNode::get_singleton()->set_breakpoint(script->get_path(), p_row + 1, code_editor->get_text_editor()->is_line_breakpointed(p_row));
 	EditorDebuggerNode::get_singleton()->set_breakpoint(script->get_path(), p_row + 1, code_editor->get_text_editor()->is_line_breakpointed(p_row));
 }
 }
 
 
+void ScriptTextEditor::_on_caret_moved() {
+	int current_line = code_editor->get_text_editor()->get_caret_line();
+	if (ABS(current_line - previous_line) >= 10) {
+		Dictionary nav_state = get_navigation_state();
+		nav_state["row"] = previous_line;
+		nav_state["scroll_position"] = -1;
+		emit_signal(SNAME("request_save_previous_state"), nav_state);
+		store_previous_state();
+	}
+	previous_line = current_line;
+}
+
 void ScriptTextEditor::_lookup_symbol(const String &p_symbol, int p_row, int p_column) {
 void ScriptTextEditor::_lookup_symbol(const String &p_symbol, int p_row, int p_column) {
 	Node *base = get_tree()->get_edited_scene_root();
 	Node *base = get_tree()->get_edited_scene_root();
 	if (base) {
 	if (base) {
@@ -1344,12 +1364,12 @@ void ScriptTextEditor::_edit_option(int p_op) {
 			code_editor->get_text_editor()->duplicate_lines();
 			code_editor->get_text_editor()->duplicate_lines();
 		} break;
 		} break;
 		case EDIT_TOGGLE_FOLD_LINE: {
 		case EDIT_TOGGLE_FOLD_LINE: {
-			int previous_line = -1;
+			int prev_line = -1;
 			for (int caret_idx : tx->get_caret_index_edit_order()) {
 			for (int caret_idx : tx->get_caret_index_edit_order()) {
 				int line_idx = tx->get_caret_line(caret_idx);
 				int line_idx = tx->get_caret_line(caret_idx);
-				if (line_idx != previous_line) {
+				if (line_idx != prev_line) {
 					tx->toggle_foldable_line(line_idx);
 					tx->toggle_foldable_line(line_idx);
-					previous_line = line_idx;
+					prev_line = line_idx;
 				}
 				}
 			}
 			}
 			tx->queue_redraw();
 			tx->queue_redraw();
@@ -2352,6 +2372,7 @@ ScriptTextEditor::ScriptTextEditor() {
 	code_editor->get_text_editor()->set_draw_breakpoints_gutter(true);
 	code_editor->get_text_editor()->set_draw_breakpoints_gutter(true);
 	code_editor->get_text_editor()->set_draw_executing_lines_gutter(true);
 	code_editor->get_text_editor()->set_draw_executing_lines_gutter(true);
 	code_editor->get_text_editor()->connect("breakpoint_toggled", callable_mp(this, &ScriptTextEditor::_breakpoint_toggled));
 	code_editor->get_text_editor()->connect("breakpoint_toggled", callable_mp(this, &ScriptTextEditor::_breakpoint_toggled));
+	code_editor->get_text_editor()->connect("caret_changed", callable_mp(this, &ScriptTextEditor::_on_caret_moved));
 
 
 	connection_gutter = 1;
 	connection_gutter = 1;
 	code_editor->get_text_editor()->add_gutter(connection_gutter);
 	code_editor->get_text_editor()->add_gutter(connection_gutter);

+ 6 - 0
editor/plugins/script_text_editor.h

@@ -99,6 +99,7 @@ class ScriptTextEditor : public ScriptEditorBase {
 
 
 	Color marked_line_color = Color(1, 1, 1);
 	Color marked_line_color = Color(1, 1, 1);
 	Color folded_code_region_color = Color(1, 1, 1);
 	Color folded_code_region_color = Color(1, 1, 1);
+	int previous_line = 0;
 
 
 	PopupPanel *color_panel = nullptr;
 	PopupPanel *color_panel = nullptr;
 	ColorPicker *color_picker = nullptr;
 	ColorPicker *color_picker = nullptr;
@@ -164,6 +165,8 @@ protected:
 	void _breakpoint_item_pressed(int p_idx);
 	void _breakpoint_item_pressed(int p_idx);
 	void _breakpoint_toggled(int p_row);
 	void _breakpoint_toggled(int p_row);
 
 
+	void _on_caret_moved();
+
 	void _validate_script(); // No longer virtual.
 	void _validate_script(); // No longer virtual.
 	void _update_warnings();
 	void _update_warnings();
 	void _update_errors();
 	void _update_errors();
@@ -260,6 +263,9 @@ public:
 
 
 	virtual void validate() override;
 	virtual void validate() override;
 
 
+	Variant get_previous_state();
+	void store_previous_state();
+
 	ScriptTextEditor();
 	ScriptTextEditor();
 	~ScriptTextEditor();
 	~ScriptTextEditor();
 };
 };