ronantakizawa/codereview-bench huggingface dataset:
Repository: godotengine/godot
File: modules/visual_script/visual_script_func_nodes.cpp (C++)

Code before:

String VisualScriptPropertySet::get_caption() const {
	static const char *opname[ASSIGN_OP_MAX] = {
		"Set", "Add", "Subtract", "Multiply", "Divide", "Mod", "ShiftLeft", "ShiftRight", "BitAnd", "BitOr", "BitXor"
	};

	String prop = String(opname[assign_op]) + " " + property;
	if (index != StringName()) {
		prop += "." + String(index);
	}

	return prop;
}

String VisualScriptPropertySet::get_text() const {
	if (call_mode == CALL_MODE_BASIC_TYPE) {
		return String("On ") + Variant::get_type_name(basic_type);
	}

	static const char *cname[3] = {
		"Self",
		"Scene Node",
		"Instance"
	};

	return String("On ") + cname[call_mode];
}

void VisualScriptPropertySet::_update_base_type() {
	//cache it because this information may not be available on load
	if (call_mode == CALL_MODE_NODE_PATH) {
		Node *node = _get_base_node();
		if (node) {
			base_type = node->get_class();
		}
	} else if (call_mode == CALL_MODE_SELF) {
		if (get_visual_script().is_valid()) {
			base_type = get_visual_script()->get_instance_base_type();
		}
	}
}

void VisualScriptPropertySet::set_basic_type(Variant::Type p_type) {
	if (basic_type == p_type) {
		return;
	}
	basic_type = p_type;

	notify_property_list_changed();
	_update_base_type();
	ports_changed_notify();

Review comment (suggestion):
```suggestion
	if (!has_input_sequence_port()) {
		return "";
	}
```

Code after:
PropertyInfo VisualScriptPropertySet::get_output_value_port_info(int p_idx) const {
	if (call_mode == CALL_MODE_BASIC_TYPE) {
		return PropertyInfo(basic_type, "pass");
	} else if (call_mode == CALL_MODE_INSTANCE) {
		return PropertyInfo(Variant::OBJECT, "pass", PROPERTY_HINT_TYPE_STRING, get_base_type());
	} else {
		return PropertyInfo();
	}
}

String VisualScriptPropertySet::get_caption() const {
	static const char *opname[ASSIGN_OP_MAX] = {
		"Set", "Add", "Subtract", "Multiply", "Divide", "Mod", "ShiftLeft", "ShiftRight", "BitAnd", "BitOr", "BitXor"
	};

	String prop = String(opname[assign_op]) + " " + property;
	if (index != StringName()) {
		prop += "." + String(index);
	}

	return prop;
}

String VisualScriptPropertySet::get_text() const {
	if (!has_input_sequence_port()) {
		return "";
	}
	if (call_mode == CALL_MODE_BASIC_TYPE) {
		return String("On ") + Variant::get_type_name(basic_type);
	} else if (call_mode == CALL_MODE_INSTANCE) {
		return String("On ") + base_type;
	} else if (call_mode == CALL_MODE_NODE_PATH) {
		return " [" + String(base_path.simplified()) + "]";
	} else {
		return "On Self";
	}
}

void VisualScriptPropertySet::_update_base_type() {
	//cache it because this information may not be available on load
	if (call_mode == CALL_MODE_NODE_PATH) {
		Node *node = _get_base_node();
		if (node) {
			base_type = node->get_class();
		}
	} else if (call_mode == CALL_MODE_SELF) {
		if (get_visual_script().is_valid()) {
			base_type = get_visual_script()->get_instance_base_type();
		}
	}
}
Repository: godotengine/godot
File: modules/visual_script/visual_script_builtin_funcs.h (C/C++)

Code before:
		MATH_ATAN,
		MATH_ATAN2,
		MATH_SQRT,
		MATH_FMOD,
		MATH_FPOSMOD,
		MATH_FLOOR,
		MATH_CEIL,
		MATH_ROUND,
		MATH_ABS,
		MATH_SIGN,
		MATH_POW,
		MATH_LOG,
		MATH_EXP,
		MATH_ISNAN,
		MATH_ISINF,
		MATH_EASE,
		MATH_STEP_DECIMALS,
		MATH_SNAPPED,
		MATH_LERP,
		MATH_INVERSE_LERP,
		MATH_RANGE_LERP,
		MATH_MOVE_TOWARD,
		MATH_RANDOMIZE,
		MATH_RANDI,
		MATH_RANDF,
		MATH_RANDF_RANGE,
		MATH_RANDI_RANGE,
		MATH_SEED,
		MATH_RANDSEED,
		MATH_DEG2RAD,
		MATH_RAD2DEG,
		MATH_LINEAR2DB,
		MATH_DB2LINEAR,
		MATH_WRAP,
		MATH_WRAPF,
		MATH_PINGPONG,
		LOGIC_MAX,
		LOGIC_MIN,
		LOGIC_CLAMP,
		LOGIC_NEAREST_PO2,
		OBJ_WEAKREF,
		TYPE_CONVERT,
		TYPE_OF,
		TYPE_EXISTS,
		TEXT_CHAR,
		TEXT_STR,
		TEXT_PRINT,
		TEXT_PRINTERR,
		TEXT_PRINTRAW,
		TEXT_PRINT_VERBOSE,
		VAR_TO_STR,

Review comment (refactor):
The order is a bit awkward, I would change it to match `variant_utility`:
```suggestion
		MATH_RANDI,
		MATH_RANDF,
		MATH_RANDFN,
		MATH_RANDI_RANGE,
		MATH_RANDF_RANGE,
```
And thus moving stuff around elsewhere to match that order.

Code after:
		MATH_ATAN,
		MATH_ATAN2,
		MATH_SQRT,
		MATH_FMOD,
		MATH_FPOSMOD,
		MATH_FLOOR,
		MATH_CEIL,
		MATH_ROUND,
		MATH_ABS,
		MATH_SIGN,
		MATH_POW,
		MATH_LOG,
		MATH_EXP,
		MATH_ISNAN,
		MATH_ISINF,
		MATH_EASE,
		MATH_STEP_DECIMALS,
		MATH_SNAPPED,
		MATH_LERP,
		MATH_INVERSE_LERP,
		MATH_RANGE_LERP,
		MATH_MOVE_TOWARD,
		MATH_RANDOMIZE,
		MATH_RANDI,
		MATH_RANDF,
		MATH_RANDI_RANGE,
		MATH_RANDF_RANGE,
		MATH_RANDFN,
		MATH_SEED,
		MATH_RANDSEED,
		MATH_DEG2RAD,
		MATH_RAD2DEG,
		MATH_LINEAR2DB,
		MATH_DB2LINEAR,
		MATH_WRAP,
		MATH_WRAPF,
		MATH_PINGPONG,
		LOGIC_MAX,
		LOGIC_MIN,
		LOGIC_CLAMP,
		LOGIC_NEAREST_PO2,
		OBJ_WEAKREF,
		TYPE_CONVERT,
		TYPE_OF,
		TYPE_EXISTS,
		TEXT_CHAR,
		TEXT_STR,
		TEXT_PRINT,
		TEXT_PRINTERR,
		TEXT_PRINTRAW,
		TEXT_PRINT_VERBOSE,
Repository: godotengine/godot
File: modules/visual_script/visual_script_nodes.cpp (C++)

Code before:
	"Add", //OP_ADD,
	"Subtract", //OP_SUBTRACT,
	"Multiply", //OP_MULTIPLY,
	"Divide", //OP_DIVIDE,
	"Negate", //OP_NEGATE,
	"Positive", //OP_POSITIVE,
	"Remainder", //OP_MODULE,
	"Concatenate", //OP_STRING_CONCAT,
	//bitwise
	"Bit Shift Left", //OP_SHIFT_LEFT,
	"Bit Shift Right", //OP_SHIFT_RIGHT,
	"Bit And", //OP_BIT_AND,
	"Bit Or", //OP_BIT_OR,
	"Bit Xor", //OP_BIT_XOR,
	"Bit Negate", //OP_BIT_NEGATE,
	//logic
	"And", //OP_AND,
	"Or", //OP_OR,
	"Xor", //OP_XOR,
	"Not", //OP_NOT,
	//containment
	"In", //OP_IN,
};

String VisualScriptOperator::get_caption() const {
	static const char32_t *op_names[] = {
		//comparison
		U"A = B", //OP_EQUAL,
		U"A \u2260 B", //OP_NOT_EQUAL,
		U"A < B", //OP_LESS,
		U"A \u2264 B", //OP_LESS_EQUAL,
		U"A > B", //OP_GREATER,
		U"A \u2265 B", //OP_GREATER_EQUAL,
		//mathematic
		U"A + B", //OP_ADD,
		U"A - B", //OP_SUBTRACT,
		U"A \u00D7 B", //OP_MULTIPLY,
		U"A \u00F7 B", //OP_DIVIDE,
		U"\u00AC A", //OP_NEGATE,
		U"+ A", //OP_POSITIVE,
		U"A mod B", //OP_MODULE,
		U"A .. B", //OP_STRING_CONCAT,
		//bitwise
		U"A << B", //OP_SHIFT_LEFT,
		U"A >> B", //OP_SHIFT_RIGHT,
		U"A & B", //OP_BIT_AND,
		U"A | B", //OP_BIT_OR,
		U"A ^ B", //OP_BIT_XOR,
		U"~A", //OP_BIT_NEGATE,
		//logic
		U"A and B", //OP_AND,

Review comment (bug):
Fix code style to comply with the guidelines (otherwise, static checks will fail on CI):

```suggestion
	switch (op) {
```

I recommend [installing clang-format and the pre-commit hooks](https://docs.godotengine.org/en/latest/community/contributing/code_style_guidelines.html#using-clang-format-locally) to format your commits automatically.

Code after:
	"Add", //OP_ADD,
	"Subtract", //OP_SUBTRACT,
	"Multiply", //OP_MULTIPLY,
	"Divide", //OP_DIVIDE,
	"Negate", //OP_NEGATE,
	"Positive", //OP_POSITIVE,
	"Remainder", //OP_MODULE,
	"Concatenate", //OP_STRING_CONCAT,
	//bitwise
	"Bit Shift Left", //OP_SHIFT_LEFT,
	"Bit Shift Right", //OP_SHIFT_RIGHT,
	"Bit And", //OP_BIT_AND,
	"Bit Or", //OP_BIT_OR,
	"Bit Xor", //OP_BIT_XOR,
	"Bit Negate", //OP_BIT_NEGATE,
	//logic
	"And", //OP_AND,
	"Or", //OP_OR,
	"Xor", //OP_XOR,
	"Not", //OP_NOT,
	//containment
	"In", //OP_IN,
};

String VisualScriptOperator::get_caption() const {
	switch (op) {
		// comparison
		case Variant::OP_EQUAL:
			return U"A = B";
		case Variant::OP_NOT_EQUAL:
			return U"A \u2260 B";
		case Variant::OP_LESS:
			return U"A < B";
		case Variant::OP_LESS_EQUAL:
			return U"A \u2264 B";
		case Variant::OP_GREATER:
			return U"A > B";
		case Variant::OP_GREATER_EQUAL:
			return U"A \u2265 B";

		// mathematic
		case Variant::OP_ADD:
			return U"A + B";
		case Variant::OP_SUBTRACT:
			return U"A - B";
		case Variant::OP_MULTIPLY:
			return U"A \u00D7 B";
		case Variant::OP_DIVIDE:
			return U"A \u00F7 B";
		case Variant::OP_NEGATE:
			return U"\u00AC A";
Repository: godotengine/godot
File: modules/visual_script/visual_script_nodes.cpp (C++)

Code before:
void VisualScriptOperator::set_operator(Variant::Operator p_op) {
	if (op == p_op) {
		return;
	}
	op = p_op;
	ports_changed_notify();
}

Variant::Operator VisualScriptOperator::get_operator() const {
	return op;
}

void VisualScriptOperator::set_typed(Variant::Type p_op) {
	if (typed == p_op) {
		return;
	}

	typed = p_op;
	ports_changed_notify();
}

Variant::Type VisualScriptOperator::get_typed() const {
	return typed;
}

void VisualScriptOperator::_bind_methods() {
	ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualScriptOperator::set_operator);
	ClassDB::bind_method(D_METHOD("get_operator"), &VisualScriptOperator::get_operator);

	ClassDB::bind_method(D_METHOD("set_typed", "type"), &VisualScriptOperator::set_typed);
	ClassDB::bind_method(D_METHOD("get_typed"), &VisualScriptOperator::get_typed);

	String types;
	for (int i = 0; i < Variant::OP_MAX; i++) {
		if (i > 0) {
			types += ",";
		}
		types += op_names[i];
	}

	String argt = "Any";
	for (int i = 1; i < Variant::VARIANT_MAX; i++) {
		argt += "," + Variant::get_type_name(Variant::Type(i));
	}

	ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, types), "set_operator", "get_operator");
	ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, argt), "set_typed", "get_typed");
}

class VisualScriptNodeInstanceOperator : public VisualScriptNodeInstance {
public:

Review comment (bug):
Here should be probably `ERR_FAIL` which will show an error/

Code after:
			return U"A >> B";
		case Variant::OP_BIT_AND:
			return U"A & B";
		case Variant::OP_BIT_OR:
			return U"A | B";
		case Variant::OP_BIT_XOR:
			return U"A ^ B";
		case Variant::OP_BIT_NEGATE:
			return U"~A";

		// logic
		case Variant::OP_AND:
			return U"A and B";
		case Variant::OP_OR:
			return U"A or B";
		case Variant::OP_XOR:
			return U"A xor B";
		case Variant::OP_NOT:
			return U"not A";
		case Variant::OP_IN:
			return U"A in B";

		default: {
			ERR_FAIL_V_MSG(
					U"Unknown node",
					U"Unknown node type encountered, caption not available.");
		}
	}
}

void VisualScriptOperator::set_operator(Variant::Operator p_op) {
	if (op == p_op) {
		return;
	}
	op = p_op;
	ports_changed_notify();
}

Variant::Operator VisualScriptOperator::get_operator() const {
	return op;
}

void VisualScriptOperator::set_typed(Variant::Type p_op) {
	if (typed == p_op) {
		return;
	}

	typed = p_op;
	ports_changed_notify();
}
Repository: godotengine/godot
File: modules/visual_script/visual_script_builtin_funcs.cpp (C++)

Code before:
		case MATH_TAN:
		case MATH_SINH:
		case MATH_COSH:
		case MATH_TANH:
		case MATH_ASIN:
		case MATH_ACOS:
		case MATH_ATAN:
		case MATH_ATAN2:
		case MATH_SQRT:
		case MATH_FMOD:
		case MATH_FPOSMOD:
		case MATH_FLOOR:
		case MATH_CEIL: {
			t = Variant::REAL;
		} break;
		case MATH_POSMOD: {
			t = Variant::INT;
		} break;
		case MATH_ROUND: {
			t = Variant::REAL;
		} break;
		case MATH_ABS: {
			t = Variant::NIL;
		} break;
		case MATH_SIGN: {
			t = Variant::NIL;
		} break;
		case MATH_POW:
		case MATH_LOG:
		case MATH_EXP: {
			t = Variant::REAL;
		} break;
		case MATH_ISNAN:
		case MATH_ISINF: {
			t = Variant::BOOL;
		} break;
		case MATH_EASE: {
			t = Variant::REAL;
		} break;
		case MATH_DECIMALS: {
			t = Variant::INT;
		} break;
		case MATH_STEPIFY:
		case MATH_LERP:
		case MATH_LERP_ANGLE:
		case MATH_INVERSE_LERP:
		case MATH_RANGE_LERP:
		case MATH_SMOOTHSTEP:
		case MATH_MOVE_TOWARD:
		case MATH_DECTIME: {
			t = Variant::REAL;

Review comment (suggestion):
In GDScript `sign` returns a `float`, so this should likely be `REAL` here too.
https://docs.godotengine.org/en/stable/classes/class_%40gdscript.html#class-gdscript-method-sign

Code after:
		case MATH_TAN:
		case MATH_SINH:
		case MATH_COSH:
		case MATH_TANH:
		case MATH_ASIN:
		case MATH_ACOS:
		case MATH_ATAN:
		case MATH_ATAN2:
		case MATH_SQRT:
		case MATH_FMOD:
		case MATH_FPOSMOD:
		case MATH_FLOOR:
		case MATH_CEIL: {
			t = Variant::REAL;
		} break;
		case MATH_POSMOD: {
			t = Variant::INT;
		} break;
		case MATH_ROUND: {
			t = Variant::REAL;
		} break;
		case MATH_ABS: {
			t = Variant::REAL;
		} break;
		case MATH_SIGN: {
			t = Variant::REAL;
		} break;
		case MATH_POW:
		case MATH_LOG:
		case MATH_EXP: {
			t = Variant::REAL;
		} break;
		case MATH_ISNAN:
		case MATH_ISINF: {
			t = Variant::BOOL;
		} break;
		case MATH_EASE: {
			t = Variant::REAL;
		} break;
		case MATH_DECIMALS: {
			t = Variant::INT;
		} break;
		case MATH_STEPIFY:
		case MATH_LERP:
		case MATH_LERP_ANGLE:
		case MATH_INVERSE_LERP:
		case MATH_RANGE_LERP:
		case MATH_SMOOTHSTEP:
		case MATH_MOVE_TOWARD:
		case MATH_DECTIME: {
			t = Variant::REAL;
Repository: godotengine/godot
File: scene/gui/shortcut.cpp (C++)

Code before:
	return shortcut;
}

bool Shortcut::is_shortcut(const Ref<InputEvent> &p_event) const {
	return shortcut.is_valid() && shortcut->is_match(p_event, true);
}

String Shortcut::get_as_text() const {
	if (shortcut.is_valid()) {
		return shortcut->as_text();
	} else {
		return "None";
	}
}

bool Shortcut::is_valid() const {
	return shortcut.is_valid();
}

void Shortcut::_bind_methods() {
	ClassDB::bind_method(D_METHOD("set_shortcut", "event"), &Shortcut::set_shortcut);
	ClassDB::bind_method(D_METHOD("get_shortcut"), &Shortcut::get_shortcut);

	ClassDB::bind_method(D_METHOD("is_valid"), &Shortcut::is_valid);

	ClassDB::bind_method(D_METHOD("is_shortcut", "event"), &Shortcut::is_shortcut);
	ClassDB::bind_method(D_METHOD("get_as_text"), &Shortcut::get_as_text);

	ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shortcut", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"), "set_shortcut", "get_shortcut");
}

Shortcut::Shortcut() {
}


Review comment (suggestion):
Feedback welcome on the new name for this method. Right after opening this PR I also thought that `matches_event()` might also be a good option.

Code after:
	return event;
}

bool Shortcut::matches_event(const Ref<InputEvent> &p_event) const {
	return event.is_valid() && event->is_match(p_event, true);
}

String Shortcut::get_as_text() const {
	if (event.is_valid()) {
		return event->as_text();
	} else {
		return "None";
	}
}

bool Shortcut::has_valid_event() const {
	return event.is_valid();
}

void Shortcut::_bind_methods() {
	ClassDB::bind_method(D_METHOD("set_event", "event"), &Shortcut::set_event);
	ClassDB::bind_method(D_METHOD("get_event"), &Shortcut::get_event);

	ClassDB::bind_method(D_METHOD("has_valid_event"), &Shortcut::has_valid_event);

	ClassDB::bind_method(D_METHOD("matches_event", "event"), &Shortcut::matches_event);
	ClassDB::bind_method(D_METHOD("get_as_text"), &Shortcut::get_as_text);

	ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"), "set_event", "get_event");
}
Repository: godotengine/godot
File: editor/plugins/node_3d_editor_plugin.cpp (C++)

Code before:
			se->gizmo.unref();
			se->subgizmos.clear();
		}
		selected->update_gizmos();
		selected = nullptr;
	}
	update_transform_gizmo();
}

void Node3DEditor::_refresh_menu_icons() {
	bool all_locked = true;
	bool all_grouped = true;

	List<Node *> &selection = editor_selection->get_selected_node_list();

	if (selection.is_empty()) {
		all_locked = false;
		all_grouped = false;
	} else {
		for (Node *E : selection) {
			if (Object::cast_to<Node3D>(E) && !Object::cast_to<Node3D>(E)->has_meta("_edit_lock_")) {
				all_locked = false;
				break;
			}
		}
		for (Node *E : selection) {
			if (Object::cast_to<Node3D>(E) && !Object::cast_to<Node3D>(E)->has_meta("_edit_group_")) {
				all_grouped = false;
				break;
			}
		}
	}

	tool_button[TOOL_LOCK_SELECTED]->set_visible(!all_locked);
	tool_button[TOOL_LOCK_SELECTED]->set_disabled(selection.is_empty());
	tool_button[TOOL_UNLOCK_SELECTED]->set_visible(all_locked);

	tool_button[TOOL_GROUP_SELECTED]->set_visible(!all_grouped);
	tool_button[TOOL_GROUP_SELECTED]->set_disabled(selection.is_empty());
	tool_button[TOOL_UNGROUP_SELECTED]->set_visible(all_grouped);
}

template <typename T>
Set<T *> _get_child_nodes(Node *parent_node) {
	Set<T *> nodes = Set<T *>();
	T *node = Node::cast_to<T>(parent_node);
	if (node) {
		nodes.insert(node);
	}

	for (int i = 0; i < parent_node->get_child_count(); i++) {

Review comment (suggestion):
Style issue here, you're using a tab instead of a space after `=`.

Code after:
}

void Node3DEditor::_finish_indicators() {
	RenderingServer::get_singleton()->free(origin_instance);
	RenderingServer::get_singleton()->free(origin);

	_finish_grid();
}

void Node3DEditor::_finish_grid() {
	for (int i = 0; i < 3; i++) {
		RenderingServer::get_singleton()->free(grid_instance[i]);
		RenderingServer::get_singleton()->free(grid[i]);
	}
}

void Node3DEditor::update_grid() {
	const Camera3D::Projection current_projection = viewports[0]->camera->get_projection();

	if (current_projection != grid_camera_last_update_perspective) {
		grid_init_draw = false; // redraw
		grid_camera_last_update_perspective = current_projection;
	}

	// Gets a orthogonal or perspective position correctly (for the grid comparison)
	const Vector3 camera_position = get_editor_viewport(0)->camera->get_position();

	if (!grid_init_draw || (camera_position - grid_camera_last_update_position).length() >= 10.0f) {
		_finish_grid();
		_init_grid();
		grid_init_draw = true;
		grid_camera_last_update_position = camera_position;
	}
}

void Node3DEditor::_selection_changed() {
	_refresh_menu_icons();
	if (selected && editor_selection->get_selected_node_list().size() != 1) {
		Vector<Ref<Node3DGizmo>> gizmos = selected->get_gizmos();
		for (int i = 0; i < gizmos.size(); i++) {
			Ref<EditorNode3DGizmo> seg = gizmos[i];
			if (!seg.is_valid()) {
				continue;
			}
			seg->set_selected(false);
		}

		Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(selected);
		if (se) {
			se->gizmo.unref();
			se->subgizmos.clear();
Repository: godotengine/godot
File: editor/animation_track_editor.cpp (C++)

Code before:
			} else {
				insert_confirm_text->set_text(vformat(TTR("Create %d new tracks and insert keys?"), num_tracks));
			}

			insert_confirm_bezier->set_visible(all_bezier);
			insert_confirm_reset->set_visible(reset_allowed);

			insert_confirm->get_ok_button()->set_text(TTR("Create"));
			insert_confirm->popup_centered();
			insert_query = true;
		} else {
			call_deferred(SNAME("_insert_delay"), reset_allowed && EDITOR_GET("editors/animation/default_create_reset_tracks"), all_bezier && EDITOR_GET("editors/animation/default_create_bezier_tracks"));
			insert_queue = true;
		}

	} else {
		if (!insert_query && !insert_queue) {
			// Create Beziers wouldn't make sense in this case, where no tracks are being created
			call_deferred(SNAME("_insert_delay"), reset_allowed && EDITOR_GET("editors/animation/default_create_reset_tracks"), false);
			insert_queue = true;
		}
	}
}

void AnimationTrackEditor::_insert_delay(bool p_create_reset, bool p_create_beziers) {
	if (insert_query) {
		//discard since it's entered into query mode
		insert_queue = false;
		return;
	}

	undo_redo->create_action(TTR("Anim Insert"));

	Ref<Animation> reset_anim;
	if (p_create_reset) {
		reset_anim = _create_and_get_reset_animation();
	}

	TrackIndices next_tracks(animation.ptr(), reset_anim.ptr());
	bool advance = false;
	while (insert_data.size()) {
		if (insert_data.front()->get().advance) {
			advance = true;
		}
		next_tracks = _confirm_insert(insert_data.front()->get(), next_tracks, p_create_reset, reset_anim, p_create_beziers);
		insert_data.pop_front();
	}

	undo_redo->commit_action();

	if (advance) {

Review comment (suggestion):
```suggestion
	// Without queue, commit immediately.
```

Code after:

	for (const InsertData &E : insert_data) {
		// Prevent insertion of multiple tracks.
		if (E.path == p_id.path) {
			return; // Already inserted a track this frame.
		}
	}

	insert_data.push_back(p_id);

	// Without queue, commit immediately.
	if (!insert_queue) {
		commit_insert_queue();
	}
}

void AnimationTrackEditor::_insert_track(bool p_create_reset, bool p_create_beziers) {
	undo_redo->create_action(TTR("Anim Insert"));

	Ref<Animation> reset_anim;
	if (p_create_reset) {
		reset_anim = _create_and_get_reset_animation();
	}

	TrackIndices next_tracks(animation.ptr(), reset_anim.ptr());
	bool advance = false;
	while (insert_data.size()) {
		if (insert_data.front()->get().advance) {
			advance = true;
		}
		next_tracks = _confirm_insert(insert_data.front()->get(), next_tracks, p_create_reset, reset_anim, p_create_beziers);
		insert_data.pop_front();
	}

	undo_redo->commit_action();

	if (advance) {
		float step = animation->get_step();
		if (step == 0) {
			step = 1;
		}

		float pos = timeline->get_play_position();

		pos = Math::snapped(pos + step, step);
		if (pos > animation->get_length()) {
			pos = animation->get_length();
		}
		set_anim_pos(pos);
		emit_signal(SNAME("timeline_changed"), pos, true);
	}
Repository: godotengine/godot
File: editor/plugins/script_editor_plugin.cpp (C++)

Code before:
		} break;
		case SEARCH_WEBSITE: {
			OS::get_singleton()->shell_open("https://docs.godotengine.org/");
		} break;
		case WINDOW_NEXT: {
			_history_forward();
		} break;
		case WINDOW_PREV: {
			_history_back();
		} break;
		case WINDOW_SORT: {
			_sort_list_on_update = true;
			_update_script_names();
		} break;
		case TOGGLE_SCRIPTS_PANEL: {
			if (current) {
				ScriptTextEditor *editor = Object::cast_to<ScriptTextEditor>(current);
				toggle_scripts_panel();
				if (editor) {
					editor->update_toggle_scripts_button();
				}
			} else {
				toggle_scripts_panel();
			}
		}
	}

	if (current) {
		switch (p_option) {
			case FILE_SAVE: {
				save_current_script();
			} break;
			case FILE_SAVE_AS: {
				if (trim_trailing_whitespace_on_save) {
					current->trim_trailing_whitespace();
				}

				current->insert_final_newline();

				if (convert_indent_on_save) {
					if (use_space_indentation) {
						current->convert_indent_to_spaces();
					} else {
						current->convert_indent_to_tabs();
					}
				}

				RES resource = current->get_edited_resource();
				Ref<TextFile> text_file = resource;
				Ref<Script> script = resource;


Review comment (suggestion):
Probably best to put this as a virtual method on `ScriptEditorBase` so can remove all this casting.

Code after:
			help_search_dialog->popup_dialog();
		} break;
		case SEARCH_WEBSITE: {
			OS::get_singleton()->shell_open("https://docs.godotengine.org/");
		} break;
		case WINDOW_NEXT: {
			_history_forward();
		} break;
		case WINDOW_PREV: {
			_history_back();
		} break;
		case WINDOW_SORT: {
			_sort_list_on_update = true;
			_update_script_names();
		} break;
		case TOGGLE_SCRIPTS_PANEL: {
			toggle_scripts_panel();
			if (current) {
				current->update_toggle_scripts_button();
			} else {
				Control *tab = tab_container->get_current_tab_control();
				EditorHelp *editor_help = Object::cast_to<EditorHelp>(tab);
				if (editor_help) {
					editor_help->update_toggle_scripts_button();
				}
			}
		}
	}

	if (current) {
		switch (p_option) {
			case FILE_SAVE: {
				save_current_script();
			} break;
			case FILE_SAVE_AS: {
				if (trim_trailing_whitespace_on_save) {
					current->trim_trailing_whitespace();
				}

				current->insert_final_newline();

				if (convert_indent_on_save) {
					if (use_space_indentation) {
						current->convert_indent_to_spaces();
					} else {
						current->convert_indent_to_tabs();
					}
				}

				RES resource = current->get_edited_resource();
				Ref<TextFile> text_file = resource;