terminal addon and bindgen
This commit is contained in:
1357
src/SharpIDE.Godot/GDExtensionBindgen/PTY.cs
Normal file
1357
src/SharpIDE.Godot/GDExtensionBindgen/PTY.cs
Normal file
File diff suppressed because it is too large
Load Diff
1
src/SharpIDE.Godot/GDExtensionBindgen/PTY.cs.uid
Normal file
1
src/SharpIDE.Godot/GDExtensionBindgen/PTY.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://h0iecoac1l48
|
||||
3026
src/SharpIDE.Godot/GDExtensionBindgen/Terminal.cs
Normal file
3026
src/SharpIDE.Godot/GDExtensionBindgen/Terminal.cs
Normal file
File diff suppressed because it is too large
Load Diff
1
src/SharpIDE.Godot/GDExtensionBindgen/Terminal.cs.uid
Normal file
1
src/SharpIDE.Godot/GDExtensionBindgen/Terminal.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cnwhkhvgxtf6x
|
||||
@@ -0,0 +1,24 @@
|
||||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more information, please refer to <http://unlicense.org/>
|
||||
@@ -0,0 +1,9 @@
|
||||
extends SceneTree
|
||||
|
||||
|
||||
const CSharpGDExtensionBindgen = preload("csharp_gdextension_bindgen.gd")
|
||||
|
||||
|
||||
func _initialize():
|
||||
CSharpGDExtensionBindgen.generate_gdextension_csharp_scripts.callv(OS.get_cmdline_user_args())
|
||||
quit()
|
||||
@@ -0,0 +1 @@
|
||||
uid://najinjv0m445
|
||||
@@ -0,0 +1,849 @@
|
||||
## GDExtension to C# binding generator
|
||||
##
|
||||
## The C# classes generated are not attached scripts, but rather wrappers that
|
||||
## forward execution to a GodotObject using dynamic calls.
|
||||
##
|
||||
## Use the "Project -> Tools -> Generate C# GDExtension Bindings" menu item to
|
||||
## generate C# bindings from GDExtension.
|
||||
@tool
|
||||
extends EditorPlugin
|
||||
|
||||
|
||||
const MENU_ITEM_NAME = "Generate C# GDExtension Bindings"
|
||||
const GENERATED_NAMESPACE = "GDExtensionBindgen"
|
||||
const GENERATED_SCRIPTS_FOLDER = "res://GDExtensionBindgen"
|
||||
|
||||
enum StringNameType {
|
||||
PROPERTY_NAME,
|
||||
METHOD_NAME,
|
||||
SIGNAL_NAME,
|
||||
}
|
||||
const StringNameTypeName = {
|
||||
StringNameType.PROPERTY_NAME: "PropertyName",
|
||||
StringNameType.METHOD_NAME: "MethodName",
|
||||
StringNameType.SIGNAL_NAME: "SignalName",
|
||||
}
|
||||
const PASCAL_CASE_NAME_OVERRIDES = {
|
||||
"BitMap": "Bitmap",
|
||||
"JSONRPC": "JsonRpc",
|
||||
"Object": "GodotObject",
|
||||
"OpenXRIPBinding": "OpenXRIPBinding",
|
||||
"SkeletonModification2DCCDIK": "SkeletonModification2DCcdik",
|
||||
"SkeletonModification2DFABRIK": "SkeletonModification2DFabrik",
|
||||
"SkeletonModification3DCCDIK": "SkeletonModification3DCcdik",
|
||||
"SkeletonModification3DFABRIK": "SkeletonModification3DFabrik",
|
||||
"System": "System_",
|
||||
"Thread": "GodotThread",
|
||||
}
|
||||
const PASCAL_CASE_PART_OVERRIDES = {
|
||||
"AA": "AA", # Anti Aliasing
|
||||
"AO": "AO", # Ambient Occlusion
|
||||
"FILENAME": "FileName",
|
||||
"FADEIN": "FadeIn",
|
||||
"FADEOUT": "FadeOut",
|
||||
"FX": "FX",
|
||||
"GI": "GI", # Global Illumination
|
||||
"GZIP": "GZip",
|
||||
"HBOX": "HBox", # Horizontal Box
|
||||
"ID": "Id",
|
||||
"IO": "IO", # Input/Output
|
||||
"IP": "IP", # Internet Protocol
|
||||
"IV": "IV", # Initialization Vector
|
||||
"MACOS": "MacOS",
|
||||
"NODEPATH": "NodePath",
|
||||
"SPIRV": "SpirV",
|
||||
"STDIN": "StdIn",
|
||||
"STDOUT": "StdOut",
|
||||
"USERNAME": "UserName",
|
||||
"UV": "UV",
|
||||
"UV2": "UV2",
|
||||
"VBOX": "VBox", # Vertical Box
|
||||
"WHITESPACE": "WhiteSpace",
|
||||
"WM": "WM",
|
||||
"XR": "XR",
|
||||
"XRAPI": "XRApi",
|
||||
}
|
||||
|
||||
|
||||
func _enter_tree():
|
||||
add_tool_menu_item(MENU_ITEM_NAME, generate_gdextension_csharp_scripts)
|
||||
|
||||
|
||||
func _exit_tree():
|
||||
remove_tool_menu_item(MENU_ITEM_NAME)
|
||||
|
||||
|
||||
static func generate_csharp_script(
|
||||
cls_name: StringName,
|
||||
output_dir := GENERATED_SCRIPTS_FOLDER,
|
||||
name_space := GENERATED_NAMESPACE,
|
||||
):
|
||||
var class_is_editor_only = _is_editor_extension_class(cls_name)
|
||||
var parent_class = ClassDB.get_parent_class(cls_name)
|
||||
var parent_class_is_extension = _is_extension_class(parent_class)
|
||||
var no_inheritance = parent_class_is_extension
|
||||
var engine_class = _first_non_extension_parent(cls_name)
|
||||
|
||||
var regions = PackedStringArray()
|
||||
|
||||
# Engine object used for calling engine methods
|
||||
if not parent_class_is_extension:
|
||||
regions.append("// Engine object used for calling engine methods\nprotected %s _object;" % parent_class)
|
||||
|
||||
# Constructors
|
||||
var ctor_fmt
|
||||
if parent_class_is_extension:
|
||||
ctor_fmt = """
|
||||
public {cls_name}() : base(NativeName)
|
||||
{
|
||||
}
|
||||
protected {cls_name}(StringName @class) : base(@class)
|
||||
{
|
||||
}
|
||||
protected {cls_name}(Variant variant) : base(variant)
|
||||
{
|
||||
}
|
||||
protected {cls_name}([NotNull] {engine_class} @object) : base(@object)
|
||||
{
|
||||
}
|
||||
"""
|
||||
else:
|
||||
ctor_fmt = """
|
||||
public {cls_name}() : this(NativeName)
|
||||
{
|
||||
}
|
||||
protected {cls_name}(StringName @class) : this(ClassDB.Instantiate(@class))
|
||||
{
|
||||
}
|
||||
protected {cls_name}(Variant variant) : this(({engine_class}) variant)
|
||||
{
|
||||
}
|
||||
protected {cls_name}([NotNull] {engine_class} @object)
|
||||
{
|
||||
_object = @object;
|
||||
}
|
||||
"""
|
||||
var ctor = ctor_fmt.dedent().format({
|
||||
cls_name = cls_name,
|
||||
engine_class = engine_class,
|
||||
}).strip_edges()
|
||||
regions.append(ctor)
|
||||
|
||||
var casts = """
|
||||
public static implicit operator {engine_class}({cls_name} self) => self?._object;
|
||||
public static implicit operator Variant({cls_name} self) => self?._object;
|
||||
public static explicit operator {cls_name}(Variant variant) => variant.AsGodotObject() != null ? new(variant) : null;
|
||||
""".dedent().format({
|
||||
cls_name = cls_name,
|
||||
engine_class = engine_class,
|
||||
}).strip_edges()
|
||||
regions.append(casts)
|
||||
|
||||
# ENUMS
|
||||
var enums = PackedStringArray()
|
||||
for enum_name in ClassDB.class_get_enum_list(cls_name, true):
|
||||
enums.append(_generate_enum(cls_name, enum_name))
|
||||
|
||||
# INTEGER CONSTANTS
|
||||
var integer_constants = PackedStringArray()
|
||||
for constant_name in ClassDB.class_get_integer_constant_list(cls_name, true):
|
||||
if not ClassDB.class_get_integer_constant_enum(cls_name, constant_name, true).is_empty():
|
||||
continue
|
||||
integer_constants.append(_generate_integer_constant(cls_name, constant_name))
|
||||
|
||||
# PROPERTIES
|
||||
var properties = PackedStringArray()
|
||||
var property_names = PackedStringArray()
|
||||
for property in ClassDB.class_get_property_list(cls_name, true):
|
||||
if property["usage"] & (PROPERTY_USAGE_GROUP | PROPERTY_USAGE_SUBGROUP):
|
||||
continue
|
||||
property_names.append(property["name"])
|
||||
properties.append(_generate_property(cls_name, property))
|
||||
|
||||
var inherited_properties = PackedStringArray()
|
||||
if not parent_class_is_extension:
|
||||
for inherited_class in _get_parent_classes(cls_name):
|
||||
for property in ClassDB.class_get_property_list(inherited_class, true):
|
||||
if property["usage"] & (PROPERTY_USAGE_GROUP | PROPERTY_USAGE_SUBGROUP):
|
||||
continue
|
||||
inherited_properties.append(_generate_property(inherited_class, property))
|
||||
|
||||
# METHODS
|
||||
var methods = PackedStringArray()
|
||||
var method_names = PackedStringArray()
|
||||
for method in ClassDB.class_get_method_list(cls_name, true):
|
||||
if method["flags"] & (METHOD_FLAG_VIRTUAL | METHOD_FLAG_VIRTUAL_REQUIRED):
|
||||
continue
|
||||
if method["name"].begins_with("_"):
|
||||
continue
|
||||
method_names.append(method["name"])
|
||||
methods.append(_generate_method(cls_name, method))
|
||||
|
||||
var inherited_methods = PackedStringArray()
|
||||
if not parent_class_is_extension:
|
||||
for inherited_class in _get_parent_classes(cls_name):
|
||||
for method in ClassDB.class_get_method_list(inherited_class, true):
|
||||
if method["flags"] & (METHOD_FLAG_VIRTUAL | METHOD_FLAG_VIRTUAL_REQUIRED):
|
||||
continue
|
||||
if method["name"].begins_with("_"):
|
||||
continue
|
||||
inherited_methods.append(_generate_method(inherited_class, method))
|
||||
|
||||
# SIGNALS
|
||||
var signals = PackedStringArray()
|
||||
var signal_names = PackedStringArray()
|
||||
for sig in ClassDB.class_get_signal_list(cls_name, true):
|
||||
signal_names.append(sig["name"])
|
||||
signals.append(_generate_signal(cls_name, sig))
|
||||
|
||||
var inherited_signals = PackedStringArray()
|
||||
if not parent_class_is_extension:
|
||||
for inherited_class in _get_parent_classes(cls_name):
|
||||
for method in ClassDB.class_get_signal_list(inherited_class, true):
|
||||
inherited_signals.append(_generate_signal(inherited_class, method))
|
||||
|
||||
# StringName caches
|
||||
regions.append(_generate_strings_class(cls_name, StringNameType.PROPERTY_NAME, property_names))
|
||||
regions.append(_generate_strings_class(cls_name, StringNameType.METHOD_NAME, method_names))
|
||||
regions.append(_generate_strings_class(cls_name, StringNameType.SIGNAL_NAME, signal_names))
|
||||
regions.append("private static readonly StringName NativeName = \"{cls_name}\";".format({
|
||||
cls_name = cls_name,
|
||||
}))
|
||||
|
||||
if not enums.is_empty():
|
||||
regions.append("#region Enums")
|
||||
regions.append("\n\n".join(enums))
|
||||
regions.append("#endregion")
|
||||
if not integer_constants.is_empty():
|
||||
regions.append("#region Integer Constants")
|
||||
regions.append("\n\n".join(integer_constants))
|
||||
regions.append("#endregion")
|
||||
if not properties.is_empty():
|
||||
regions.append("#region Properties")
|
||||
regions.append("\n\n".join(properties))
|
||||
regions.append("#endregion")
|
||||
if not inherited_properties.is_empty():
|
||||
regions.append("#region Inherited Properties")
|
||||
regions.append("\n\n".join(inherited_properties))
|
||||
regions.append("#endregion")
|
||||
if not methods.is_empty():
|
||||
regions.append("#region Methods")
|
||||
regions.append("\n\n".join(methods))
|
||||
regions.append("#endregion")
|
||||
if not inherited_methods.is_empty():
|
||||
regions.append("#region Inherited Methods")
|
||||
regions.append("\n\n".join(inherited_methods))
|
||||
regions.append("#endregion")
|
||||
if not signals.is_empty():
|
||||
regions.append("#region Signals")
|
||||
regions.append("\n\n".join(signals))
|
||||
regions.append("#endregion")
|
||||
if not inherited_signals.is_empty():
|
||||
regions.append("#region Inherited Signals")
|
||||
regions.append("\n\n".join(inherited_signals))
|
||||
regions.append("#endregion")
|
||||
|
||||
var code = """
|
||||
// This code was automatically generated by GDExtension C# Bindgen
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Godot;
|
||||
|
||||
namespace {name_space};
|
||||
|
||||
public class {cls_name}{inheritance}
|
||||
{
|
||||
{regions}
|
||||
}
|
||||
""".dedent().format({
|
||||
name_space = name_space,
|
||||
cls_name = cls_name,
|
||||
inheritance = " : " + parent_class if parent_class_is_extension else "",
|
||||
regions = "\n\n".join(regions).indent("\t"),
|
||||
}).strip_edges()
|
||||
|
||||
if class_is_editor_only:
|
||||
code = """
|
||||
#if TOOLS
|
||||
{code}
|
||||
#endif
|
||||
""".dedent().format({
|
||||
code = code,
|
||||
}).strip_edges()
|
||||
|
||||
code += "\n"
|
||||
|
||||
if not DirAccess.dir_exists_absolute(output_dir):
|
||||
DirAccess.make_dir_recursive_absolute(output_dir)
|
||||
|
||||
var new_script = FileAccess.open(output_dir.path_join(cls_name + ".cs"), FileAccess.WRITE)
|
||||
new_script.store_string(code)
|
||||
|
||||
|
||||
static func generate_gdextension_csharp_scripts(
|
||||
output_dir := GENERATED_SCRIPTS_FOLDER,
|
||||
name_space := GENERATED_NAMESPACE,
|
||||
):
|
||||
var classes = ClassDB.get_class_list()
|
||||
for cls_name in classes:
|
||||
if _is_extension_class(cls_name):
|
||||
generate_csharp_script(cls_name, output_dir, name_space)
|
||||
|
||||
|
||||
static func _generate_enum(cls_name: StringName, enum_name: StringName) -> String:
|
||||
var common_prefix = null
|
||||
for constant_name in ClassDB.class_get_enum_constants(cls_name, enum_name, true):
|
||||
if common_prefix == null:
|
||||
common_prefix = constant_name
|
||||
else:
|
||||
common_prefix = _get_common_prefix(common_prefix, constant_name)
|
||||
# Handle special case where one of the constants is present in all constant
|
||||
# names: remove last word from prefix.
|
||||
# Example case: Node.ProcessThreadMessages and FLAG_PROCESS_THREAD_MESSAGES
|
||||
if common_prefix in ClassDB.class_get_enum_constants(cls_name, enum_name, true):
|
||||
common_prefix = common_prefix.rsplit("_", false, 1)[0]
|
||||
|
||||
var constants = PackedStringArray()
|
||||
for constant_name in ClassDB.class_get_enum_constants(cls_name, enum_name, true):
|
||||
constants.append("{csharp_constant_name} = {constant_value}L,".format({
|
||||
csharp_constant_name = constant_name.substr(common_prefix.length()).to_pascal_case(),
|
||||
constant_value = ClassDB.class_get_integer_constant(cls_name, constant_name),
|
||||
}))
|
||||
|
||||
return """
|
||||
{flags}
|
||||
public enum {enum_name}{maybe_enum_suffix} : long
|
||||
{
|
||||
{constants}
|
||||
}
|
||||
""".dedent().format({
|
||||
flags = "[Flags]" if ClassDB.is_class_enum_bitfield(cls_name, enum_name) else "",
|
||||
enum_name = enum_name,
|
||||
constants = "\n".join(constants).indent("\t"),
|
||||
maybe_enum_suffix = "Enum" if _needs_enum_suffix(cls_name, enum_name) else "",
|
||||
}).strip_edges()
|
||||
|
||||
|
||||
static func _generate_integer_constant(cls_name: StringName, constant_name: StringName) -> String:
|
||||
return "public const long {csharp_constant_name} = {constant_value}L;".format({
|
||||
csharp_constant_name = constant_name.to_pascal_case(),
|
||||
constant_value = ClassDB.class_get_integer_constant(cls_name, constant_name),
|
||||
})
|
||||
|
||||
|
||||
static func _generate_property(cls_name: StringName, property: Dictionary) -> String:
|
||||
var property_name = property["name"]
|
||||
var csharp_property_name = property_name.to_pascal_case()
|
||||
var property_type = _get_property_type(cls_name, property)
|
||||
|
||||
var getset = PackedStringArray()
|
||||
|
||||
var getter = ClassDB.class_get_property_getter(cls_name, property_name)
|
||||
if getter:
|
||||
if _is_extension_class(cls_name):
|
||||
getset.append("get => {get_cast}_object.Get(PropertyName.{csharp_property_name});".format({
|
||||
get_cast = _property_get_cast(cls_name, property),
|
||||
csharp_property_name = csharp_property_name,
|
||||
}))
|
||||
else:
|
||||
getset.append("get => _object.{csharp_property_name};".format({
|
||||
csharp_property_name = csharp_property_name,
|
||||
}))
|
||||
|
||||
var setter = ClassDB.class_get_property_setter(cls_name, property_name)
|
||||
if setter:
|
||||
if _is_extension_class(cls_name):
|
||||
getset.append("set => _object.Set(PropertyName.{csharp_property_name}, {set_cast}value);".format({
|
||||
set_cast = _property_set_cast(property),
|
||||
csharp_property_name = csharp_property_name,
|
||||
}))
|
||||
else:
|
||||
getset.append("set => _object.{csharp_property_name} = value;".format({
|
||||
csharp_property_name = csharp_property_name,
|
||||
}))
|
||||
|
||||
return """
|
||||
public {property_type} {csharp_property_name}
|
||||
{
|
||||
{getset}
|
||||
}
|
||||
""".dedent().format({
|
||||
property_type = property_type,
|
||||
csharp_property_name = csharp_property_name,
|
||||
getset = "\n".join(getset).indent("\t"),
|
||||
}).strip_edges()
|
||||
|
||||
|
||||
static func _generate_method(cls_name: StringName, method: Dictionary) -> String:
|
||||
var method_name = method["name"]
|
||||
var csharp_method_name = method_name.to_pascal_case()
|
||||
var return_type = _get_method_return_type(cls_name, method_name, method["return"])
|
||||
var is_static = method["flags"] & METHOD_FLAG_STATIC
|
||||
|
||||
var arg_types = PackedStringArray()
|
||||
var arg_names = PackedStringArray()
|
||||
|
||||
var args = PackedStringArray()
|
||||
for argument in method["args"]:
|
||||
var arg_type = _get_property_type(cls_name, argument)
|
||||
var arg_name = "@" + argument["name"]
|
||||
# hardcode type that cannot be known from reflection in GDScript
|
||||
if method["name"] == "connect" and arg_name == "@flags":
|
||||
arg_type = "uint"
|
||||
args.append("{arg_type} {arg_name}".format({
|
||||
arg_type = arg_type,
|
||||
arg_name = arg_name,
|
||||
}))
|
||||
arg_types.append(arg_type)
|
||||
if _property_is_enum(argument):
|
||||
arg_names.append("(int)" + arg_name)
|
||||
else:
|
||||
arg_names.append(arg_name)
|
||||
|
||||
var implementation = PackedStringArray()
|
||||
var default_args = method["default_args"]
|
||||
var i = args.size() - default_args.size()
|
||||
for default_value in default_args:
|
||||
if default_value == null:
|
||||
default_value = "default"
|
||||
# handle enums
|
||||
elif default_value is int and arg_types[i] != "int":
|
||||
default_value = ("(%s)" % arg_types[i]) + str(default_value)
|
||||
# C# requires the "f" suffix for float literals
|
||||
elif default_value is float and arg_types[i] == "float":
|
||||
default_value = "%sf" % default_value
|
||||
# NOTE: don't move this branch below the String one, since most of the
|
||||
# time when arg_types[i] == StringName, default_value is String
|
||||
elif default_value is StringName or arg_types[i] == "Godot.StringName":
|
||||
implementation.append('%s ??= "%s";' % [arg_names[i], default_value])
|
||||
default_value = "null"
|
||||
elif default_value is String:
|
||||
default_value = '"%s"' % default_value
|
||||
elif default_value is Array:
|
||||
assert(default_value.is_empty(), "Populated Array not supported yet! " + str(default_value)) # TODO: support populated array as default value
|
||||
implementation.append("%s ??= new();" % arg_names[i])
|
||||
default_value = "null"
|
||||
elif default_value is Dictionary:
|
||||
assert(default_value.is_empty(), "Populated Dictionary not supported yet! " + str(default_value)) # TODO: support populated dictionary as default value
|
||||
implementation.append("%s ??= new();" % arg_names[i])
|
||||
default_value = "null"
|
||||
elif (
|
||||
default_value is Vector2 or default_value is Vector3 or default_value is Vector4
|
||||
or default_value is Color
|
||||
):
|
||||
args[i] = args[i].replace(arg_types[i], arg_types[i] + "?")
|
||||
var impl = "%s ??= new%s;" % [arg_names[i], default_value]
|
||||
if not OS.has_feature("double"):
|
||||
impl = impl.replace(",", "f,").replace(")", "f)")
|
||||
implementation.append(impl)
|
||||
default_value = "null"
|
||||
elif (
|
||||
default_value is PackedByteArray
|
||||
or default_value is PackedInt32Array or default_value is PackedInt64Array
|
||||
or default_value is PackedFloat32Array or default_value is PackedFloat64Array
|
||||
or default_value is PackedVector2Array or default_value is PackedVector3Array or default_value is PackedVector4Array
|
||||
or default_value is PackedColorArray
|
||||
):
|
||||
assert(default_value.is_empty(), "Populated Packed Array not supported yet! " + str(default_value))
|
||||
implementation.append("%s ??= System.Array.Empty<%s>();" % [arg_names[i], arg_types[i].replace("[]", "")])
|
||||
default_value = "null"
|
||||
elif default_value is Transform2D:
|
||||
assert(default_value == Transform2D.IDENTITY, "Only identity Transform2D is supported as default value")
|
||||
args[i] = args[i].replace(arg_types[i], arg_types[i] + "?")
|
||||
implementation.append("%s ??= Godot.Transform2D.Identity;" % arg_names[i])
|
||||
default_value = "null"
|
||||
elif default_value is Transform3D:
|
||||
assert(default_value == Transform3D.IDENTITY, "Only identity Transform3D is supported as default value")
|
||||
args[i] = args[i].replace(arg_types[i], arg_types[i] + "?")
|
||||
implementation.append("%s ??= Godot.Transform3D.Identity;" % arg_names[i])
|
||||
default_value = "null"
|
||||
args[i] += " = " + str(default_value)
|
||||
i += 1
|
||||
|
||||
if method["flags"] & METHOD_FLAG_VARARG:
|
||||
args.append("params Variant[] varargs")
|
||||
arg_names.append("varargs")
|
||||
|
||||
if _is_extension_class(cls_name):
|
||||
arg_names.insert(0, "MethodName.{csharp_method_name}".format({
|
||||
csharp_method_name = csharp_method_name,
|
||||
}))
|
||||
if is_static:
|
||||
implementation.append("{maybe_return}ClassDB.ClassCallStatic(NativeName, {arg_names});".format({
|
||||
arg_names = ", ".join(arg_names),
|
||||
maybe_return = "return " + _property_get_cast(cls_name, method["return"]) if return_type != "void" else "",
|
||||
}))
|
||||
else:
|
||||
implementation.append("{maybe_return}_object.Call({arg_names});".format({
|
||||
arg_names = ", ".join(arg_names),
|
||||
maybe_return = "return " + _property_get_cast(cls_name, method["return"]) if return_type != "void" else "",
|
||||
}))
|
||||
else:
|
||||
if is_static:
|
||||
implementation.append("{maybe_return}{engine_class}.{csharp_method_name}({arg_names});".format({
|
||||
arg_names = ", ".join(arg_names),
|
||||
engine_class = _first_non_extension_parent(cls_name),
|
||||
csharp_method_name = csharp_method_name,
|
||||
maybe_return = "return " if return_type != "void" else "",
|
||||
}))
|
||||
else:
|
||||
implementation.append("{maybe_return}_object.{csharp_method_name}({arg_names});".format({
|
||||
arg_names = ", ".join(arg_names),
|
||||
csharp_method_name = csharp_method_name,
|
||||
maybe_return = "return " if return_type != "void" else "",
|
||||
}))
|
||||
|
||||
return """
|
||||
public {maybe_static}{maybe_override}{return_type} {csharp_method_name}({args})
|
||||
{
|
||||
{implementation}
|
||||
}
|
||||
""".dedent().format({
|
||||
args = ", ".join(args),
|
||||
csharp_method_name = csharp_method_name,
|
||||
implementation = "\n".join(implementation).indent("\t"),
|
||||
maybe_override = "override " if csharp_method_name == "ToString" else "",
|
||||
maybe_static = "static " if is_static else "",
|
||||
return_type = return_type,
|
||||
}).strip_edges()
|
||||
|
||||
|
||||
static func _generate_signal(cls_name: StringName, sig: Dictionary):
|
||||
var signal_name = sig["name"]
|
||||
var csharp_signal_name = signal_name.to_pascal_case()
|
||||
var return_type = _get_method_return_type(cls_name, signal_name, sig["return"])
|
||||
|
||||
var arg_types = PackedStringArray()
|
||||
for argument in sig["args"]:
|
||||
var arg_type = _get_property_type(cls_name, argument)
|
||||
arg_types.append(arg_type)
|
||||
|
||||
var delegate_type
|
||||
if return_type == "void":
|
||||
if not arg_types.is_empty():
|
||||
delegate_type = "Action<{arg_types}>".format({
|
||||
arg_types = ", ".join(arg_types)
|
||||
})
|
||||
else:
|
||||
delegate_type = "Action"
|
||||
else:
|
||||
arg_types.append(return_type)
|
||||
delegate_type = "Func<{arg_types}>".format({
|
||||
arg_types = ", ".join(arg_types)
|
||||
})
|
||||
|
||||
return """
|
||||
public event {delegate_type} {csharp_signal_name}
|
||||
{
|
||||
add
|
||||
{
|
||||
Connect(SignalName.{csharp_signal_name}, Callable.From(value));
|
||||
}
|
||||
remove
|
||||
{
|
||||
Disconnect(SignalName.{csharp_signal_name}, Callable.From(value));
|
||||
}
|
||||
}
|
||||
""".dedent().format({
|
||||
delegate_type = delegate_type,
|
||||
csharp_signal_name = csharp_signal_name,
|
||||
}).strip_edges()
|
||||
|
||||
|
||||
static func _property_is_enum(property: Dictionary) -> bool:
|
||||
return property["usage"] & (PROPERTY_USAGE_CLASS_IS_ENUM | PROPERTY_USAGE_CLASS_IS_BITFIELD)
|
||||
|
||||
|
||||
static func _get_property_type(cls_name: StringName, property: Dictionary) -> String:
|
||||
match property["type"]:
|
||||
TYPE_NIL:
|
||||
return "Variant"
|
||||
TYPE_BOOL:
|
||||
return "bool"
|
||||
TYPE_INT:
|
||||
if _property_is_enum(property):
|
||||
var enum_name = property["class_name"]
|
||||
if enum_name == "Error":
|
||||
return "Godot.Error"
|
||||
var split = enum_name.split(".")
|
||||
if split.size() == 1:
|
||||
return enum_name + ("Enum" if _needs_enum_suffix(cls_name, enum_name) else "")
|
||||
else:
|
||||
return enum_name + ("Enum" if _needs_enum_suffix(split[0], split[1]) else "")
|
||||
return "int"
|
||||
TYPE_FLOAT:
|
||||
return "double" if OS.has_feature("double") else "float"
|
||||
TYPE_STRING:
|
||||
return "string"
|
||||
TYPE_VECTOR2I:
|
||||
return "Godot.Vector2I"
|
||||
TYPE_RECT2I:
|
||||
return "Godot.Rect2I"
|
||||
TYPE_VECTOR3I:
|
||||
return "Godot.Vector3I"
|
||||
TYPE_VECTOR4I:
|
||||
return "Godot.Vector4I"
|
||||
TYPE_AABB:
|
||||
return "Godot.Aabb"
|
||||
TYPE_RID:
|
||||
return "Godot.Rid"
|
||||
TYPE_OBJECT:
|
||||
if property["class_name"] and property["class_name"] != "Object":
|
||||
return _pascal_to_pascal_case(_get_class_from_class_name(property["class_name"]))
|
||||
else:
|
||||
return "GodotObject"
|
||||
TYPE_ARRAY:
|
||||
if property["hint"] & PROPERTY_HINT_ARRAY_TYPE:
|
||||
return "Godot.Collections.Array<%s>" % _get_mapped_variant_type(property["hint_string"])
|
||||
else:
|
||||
return "Godot.Collections.Array"
|
||||
TYPE_DICTIONARY:
|
||||
return "Godot.Collections.Dictionary"
|
||||
TYPE_PACKED_BYTE_ARRAY:
|
||||
return "byte[]"
|
||||
TYPE_PACKED_INT32_ARRAY:
|
||||
return "int[]"
|
||||
TYPE_PACKED_INT64_ARRAY:
|
||||
return "long[]"
|
||||
TYPE_PACKED_FLOAT32_ARRAY:
|
||||
return "float[]"
|
||||
TYPE_PACKED_FLOAT64_ARRAY:
|
||||
return "double[]"
|
||||
TYPE_PACKED_STRING_ARRAY:
|
||||
return "string[]"
|
||||
TYPE_PACKED_VECTOR2_ARRAY:
|
||||
return "Godot.Vector2[]"
|
||||
TYPE_PACKED_VECTOR3_ARRAY:
|
||||
return "Godot.Vector3[]"
|
||||
TYPE_PACKED_VECTOR4_ARRAY:
|
||||
return "Godot.Vector4[]"
|
||||
TYPE_PACKED_COLOR_ARRAY:
|
||||
return "Godot.Color[]"
|
||||
var t:
|
||||
return "Godot." + type_string(t)
|
||||
|
||||
|
||||
static func _get_mapped_variant_type(variant_type_name: String) -> String:
|
||||
var _type_map = {
|
||||
"Variant": "Variant",
|
||||
type_string(TYPE_BOOL): "bool",
|
||||
type_string(TYPE_INT): "int",
|
||||
type_string(TYPE_FLOAT): "double" if OS.has_feature("double") else "float",
|
||||
type_string(TYPE_STRING): "string",
|
||||
type_string(TYPE_STRING_NAME): "StringName",
|
||||
type_string(TYPE_VECTOR2I): "Godot.Vector2I",
|
||||
type_string(TYPE_RECT2I): "Godot.Rect2I",
|
||||
type_string(TYPE_VECTOR3I): "Godot.Vector3I",
|
||||
type_string(TYPE_VECTOR4I): "Godot.Vector4I",
|
||||
type_string(TYPE_AABB): "Godot.Aabb",
|
||||
type_string(TYPE_RID): "Godot.Rid",
|
||||
type_string(TYPE_OBJECT): "GodotObject",
|
||||
type_string(TYPE_ARRAY): "Godot.Collections.Array",
|
||||
type_string(TYPE_DICTIONARY): "Godot.Collections.Dictionary",
|
||||
type_string(TYPE_PACKED_BYTE_ARRAY): "byte[]",
|
||||
type_string(TYPE_PACKED_INT32_ARRAY): "int[]",
|
||||
type_string(TYPE_PACKED_INT64_ARRAY): "long[]",
|
||||
type_string(TYPE_PACKED_FLOAT32_ARRAY): "float[]",
|
||||
type_string(TYPE_PACKED_FLOAT64_ARRAY): "double[]",
|
||||
type_string(TYPE_PACKED_STRING_ARRAY): "string[]",
|
||||
type_string(TYPE_PACKED_VECTOR2_ARRAY): "Godot.Vector2[]",
|
||||
type_string(TYPE_PACKED_VECTOR3_ARRAY): "Godot.Vector3[]",
|
||||
type_string(TYPE_PACKED_VECTOR4_ARRAY): "Godot.Vector4[]",
|
||||
type_string(TYPE_PACKED_COLOR_ARRAY): "Godot.Color[]",
|
||||
}
|
||||
return _type_map.get(variant_type_name, "Godot." + variant_type_name)
|
||||
|
||||
|
||||
static func _property_get_cast(cls_name: StringName, property: Dictionary):
|
||||
var property_type = _get_property_type(cls_name, property)
|
||||
if _property_is_enum(property):
|
||||
return "(%s)(int)" % property_type
|
||||
else:
|
||||
return "(%s)" % property_type
|
||||
|
||||
|
||||
static func _property_set_cast(property: Dictionary):
|
||||
if _property_is_enum(property):
|
||||
return "(int)"
|
||||
else:
|
||||
return ""
|
||||
|
||||
|
||||
static func _is_extension_class(cls_name: StringName) -> bool:
|
||||
return ClassDB.class_get_api_type(cls_name) in [
|
||||
ClassDB.APIType.API_EXTENSION,
|
||||
ClassDB.APIType.API_EDITOR_EXTENSION,
|
||||
]
|
||||
|
||||
|
||||
static func _is_editor_extension_class(cls_name: StringName) -> bool:
|
||||
return ClassDB.class_get_api_type(cls_name) == ClassDB.APIType.API_EDITOR_EXTENSION
|
||||
|
||||
|
||||
static func _first_non_extension_parent(cls_name: StringName) -> StringName:
|
||||
while _is_extension_class(cls_name):
|
||||
cls_name = ClassDB.get_parent_class(cls_name)
|
||||
return cls_name
|
||||
|
||||
|
||||
static func _get_method_return_type(cls_name: StringName, method_name: StringName, method_return: Dictionary) -> String:
|
||||
# hardcode type that cannot be known from reflection in GDScript
|
||||
if method_name == "get_instance_id":
|
||||
return "ulong"
|
||||
|
||||
if method_return["type"] == TYPE_NIL:
|
||||
if method_return["usage"] & PROPERTY_USAGE_NIL_IS_VARIANT:
|
||||
return "Variant"
|
||||
else:
|
||||
return "void"
|
||||
else:
|
||||
return _get_property_type(cls_name, method_return)
|
||||
|
||||
|
||||
static func _get_parent_classes(cls_name: StringName) -> Array[StringName]:
|
||||
var parent_classes = [] as Array[StringName]
|
||||
while true:
|
||||
cls_name = ClassDB.get_parent_class(cls_name)
|
||||
parent_classes.append(cls_name)
|
||||
if cls_name == "Object":
|
||||
break
|
||||
return parent_classes
|
||||
|
||||
|
||||
static func _generate_strings_class(cls_name: StringName, string_name_type: StringNameType, string_names: PackedStringArray) -> String:
|
||||
var parent_class = ClassDB.get_parent_class(cls_name)
|
||||
var lines = PackedStringArray()
|
||||
for name in string_names:
|
||||
if string_name_type == StringNameType.METHOD_NAME and ClassDB.class_has_method(parent_class, name):
|
||||
continue
|
||||
if string_name_type == StringNameType.SIGNAL_NAME and ClassDB.class_has_signal(parent_class, name):
|
||||
continue
|
||||
lines.append("public static readonly StringName {cs_name} = \"{name}\";".format({
|
||||
cs_name = name.to_pascal_case(),
|
||||
name = name,
|
||||
}))
|
||||
return """
|
||||
public {maybe_new}class {strings_class} : {parent_class}.{strings_class}
|
||||
{
|
||||
{lines}
|
||||
}
|
||||
""".dedent().format({
|
||||
lines = "\n".join(lines).indent("\t"),
|
||||
maybe_new = "new " if _is_extension_class(parent_class) else "",
|
||||
parent_class = parent_class,
|
||||
strings_class = StringNameTypeName[string_name_type],
|
||||
}).strip_edges()
|
||||
|
||||
|
||||
static func _get_common_prefix(s1: String, s2: String) -> String:
|
||||
var common_length = min(s1.length(), s2.length())
|
||||
for i in range(common_length):
|
||||
if s1[i] != s2[i]:
|
||||
return s1.substr(0, i)
|
||||
return s1.substr(0, common_length)
|
||||
|
||||
|
||||
static func _get_class_from_class_name(cls_name: String) -> String:
|
||||
var classes = cls_name.split(",")
|
||||
if classes.size() == 1:
|
||||
return cls_name
|
||||
|
||||
# Handle special case where 2 or more class names are present separated
|
||||
# by ",": calculate the common parent class.
|
||||
# Example case: CanvasItem.material uses "CanvasItemMaterial,ShaderMaterial"
|
||||
var parent_classes = _get_parent_classes(classes[0])
|
||||
for i in range(1, classes.size()):
|
||||
var test_cls = classes[i]
|
||||
while not ClassDB.is_parent_class(test_cls, parent_classes[0]):
|
||||
parent_classes.pop_front()
|
||||
return parent_classes[0]
|
||||
|
||||
|
||||
static func _needs_enum_suffix(cls_name: StringName, enum_name: String) -> bool:
|
||||
var snake_case_enum_name = enum_name.to_snake_case()
|
||||
if ClassDB.class_has_method(cls_name, snake_case_enum_name):
|
||||
return true
|
||||
if ClassDB.class_has_signal(cls_name, snake_case_enum_name):
|
||||
return true
|
||||
var properties = ClassDB.class_get_property_list(cls_name)
|
||||
for property in properties:
|
||||
if snake_case_enum_name == property["name"]:
|
||||
return true
|
||||
return false
|
||||
|
||||
|
||||
# Pascal case conversion used for class names.
|
||||
# Replicates the logic from `godot/modules/mono/utils/naming_utils.cpp`
|
||||
static func _is_ascii_upper_case(c: String) -> bool:
|
||||
return c.to_upper() == c
|
||||
|
||||
|
||||
static func _is_ascii_lower_case(c: String) -> bool:
|
||||
return c.to_lower() == c
|
||||
|
||||
|
||||
static func _is_digit(c: String) -> bool:
|
||||
return c >= "0" and c <= "9"
|
||||
|
||||
|
||||
static func _split_pascal_case(p_identifier: String) -> PackedStringArray:
|
||||
var parts := PackedStringArray()
|
||||
var current_part_start := 0
|
||||
var prev_was_upper := _is_ascii_upper_case(p_identifier[0])
|
||||
for i in range(1, p_identifier.length()):
|
||||
if prev_was_upper:
|
||||
if _is_digit(p_identifier[i]) or _is_ascii_lower_case(p_identifier[i]):
|
||||
if not _is_digit(p_identifier[i]):
|
||||
# These conditions only apply when the separator is not a digit.
|
||||
if i - current_part_start == 1:
|
||||
# Upper character was only the beginning of a word.
|
||||
prev_was_upper = false
|
||||
continue
|
||||
if i != p_identifier.length():
|
||||
# If this is not the last character, the last uppercase
|
||||
# character is the start of the next word.
|
||||
i -= 1
|
||||
if i - current_part_start > 0:
|
||||
parts.append(p_identifier.substr(current_part_start, i - current_part_start))
|
||||
current_part_start = i
|
||||
prev_was_upper = false
|
||||
else:
|
||||
if _is_digit(p_identifier[i]) or _is_ascii_upper_case(p_identifier[i]):
|
||||
parts.append(p_identifier.substr(current_part_start, i - current_part_start))
|
||||
current_part_start = i
|
||||
prev_was_upper = true
|
||||
|
||||
# Add the rest of the identifier as the last part.
|
||||
if current_part_start != p_identifier.length():
|
||||
parts.append(p_identifier.substr(current_part_start))
|
||||
return parts
|
||||
|
||||
|
||||
static func _pascal_to_pascal_case(p_identifier: String) -> String:
|
||||
if p_identifier.length() == 0:
|
||||
return p_identifier
|
||||
if p_identifier.length() <= 2:
|
||||
return p_identifier.to_upper()
|
||||
if PASCAL_CASE_NAME_OVERRIDES.has(p_identifier):
|
||||
return PASCAL_CASE_NAME_OVERRIDES[p_identifier]
|
||||
|
||||
var parts := _split_pascal_case(p_identifier)
|
||||
var ret := ""
|
||||
for part in parts:
|
||||
if PASCAL_CASE_PART_OVERRIDES.has(part):
|
||||
ret += PASCAL_CASE_PART_OVERRIDES[part]
|
||||
continue
|
||||
|
||||
if part.length() <= 2 and _is_ascii_upper_case(part):
|
||||
ret += part.to_upper()
|
||||
continue
|
||||
|
||||
part[0] = part[0].to_upper()
|
||||
for i in range(1, part.length()):
|
||||
if _is_digit(part[i - 1]):
|
||||
# Use uppercase after digits.
|
||||
part[i] = part[i].to_upper()
|
||||
else:
|
||||
part[i] = part[i].to_lower()
|
||||
ret += part
|
||||
return ret
|
||||
@@ -0,0 +1 @@
|
||||
uid://cy4tmwy5iyogu
|
||||
BIN
src/SharpIDE.Godot/addons/csharp_gdextension_bindgen/icon.png
Normal file
BIN
src/SharpIDE.Godot/addons/csharp_gdextension_bindgen/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.0 KiB |
@@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://blckign68biqs"
|
||||
path="res://.godot/imported/icon.png-6749c396fd9e755f292f935bb84594b0.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/csharp_gdextension_bindgen/icon.png"
|
||||
dest_files=["res://.godot/imported/icon.png-6749c396fd9e755f292f935bb84594b0.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
@@ -0,0 +1,7 @@
|
||||
[plugin]
|
||||
|
||||
name="C# GDExtension Bindgen"
|
||||
description="Automatic C# bindings generator for GDExtension classes (Godot 4.4+)"
|
||||
author="gilzoide"
|
||||
version="0.3.1"
|
||||
script="csharp_gdextension_bindgen.gd"
|
||||
362
src/SharpIDE.Godot/addons/godot_xterm/.gitignore
vendored
Normal file
362
src/SharpIDE.Godot/addons/godot_xterm/.gitignore
vendored
Normal file
@@ -0,0 +1,362 @@
|
||||
# Godot auto generated files
|
||||
*.gen.*
|
||||
.import/
|
||||
|
||||
# Documentation generated by doxygen or from classes.xml
|
||||
doc/_build/
|
||||
|
||||
# Javascript specific
|
||||
*.bc
|
||||
|
||||
# CLion
|
||||
cmake-build-debug
|
||||
|
||||
# Android specific
|
||||
.gradle
|
||||
local.properties
|
||||
*.iml
|
||||
.idea
|
||||
.gradletasknamecache
|
||||
project.properties
|
||||
platform/android/java/app/libs/*
|
||||
platform/android/java/libs/*
|
||||
platform/android/java/lib/.cxx/
|
||||
|
||||
# General c++ generated files
|
||||
*.lib
|
||||
*.o
|
||||
*.ox
|
||||
*.a
|
||||
*.ax
|
||||
*.d
|
||||
*.so
|
||||
*.os
|
||||
*.Plo
|
||||
*.lo
|
||||
|
||||
# Libs generated files
|
||||
.deps/*
|
||||
.dirstamp
|
||||
|
||||
# Gprof output
|
||||
gmon.out
|
||||
|
||||
# Vim temp files
|
||||
*.swo
|
||||
*.swp
|
||||
|
||||
# Qt project files
|
||||
*.config
|
||||
*.creator
|
||||
*.creator.*
|
||||
*.files
|
||||
*.includes
|
||||
*.cflags
|
||||
*.cxxflags
|
||||
|
||||
# Code::Blocks files
|
||||
*.cbp
|
||||
*.layout
|
||||
*.depend
|
||||
|
||||
# Eclipse CDT files
|
||||
.cproject
|
||||
.settings/
|
||||
*.pydevproject
|
||||
*.launch
|
||||
|
||||
# Geany/geany-plugins files
|
||||
*.geany
|
||||
.geanyprj
|
||||
|
||||
# Jetbrains IDEs
|
||||
.idea/
|
||||
|
||||
# Misc
|
||||
.DS_Store
|
||||
__MACOSX
|
||||
logs/
|
||||
|
||||
# for projects that use SCons for building: http://http://www.scons.org/
|
||||
.sconf_temp
|
||||
.sconsign*.dblite
|
||||
*.pyc
|
||||
|
||||
# https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.sln.docstates
|
||||
*.sln
|
||||
*.vcxproj*
|
||||
|
||||
# Custom SCons configuration override
|
||||
/custom.py
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
x64/
|
||||
build/
|
||||
bld/
|
||||
[Oo]bj/
|
||||
*.debug
|
||||
*.dSYM
|
||||
|
||||
# Visual Studio cache/options directory
|
||||
.vs/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# Hints for improving IntelliSense, created together with VS project
|
||||
cpp.hint
|
||||
|
||||
#NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
*.o
|
||||
*.a
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_i.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.bak
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
*.nib
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.opendb
|
||||
*.VC.VC.opendb
|
||||
enc_temp_folder/
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
|
||||
# CodeLite project files
|
||||
*.project
|
||||
*.workspace
|
||||
.codelite/
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# JustCode is a .NET coding addin-in
|
||||
.JustCode
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# NCrunch
|
||||
*.ncrunch*
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
|
||||
# NuGet Packages Directory
|
||||
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
|
||||
#packages/*
|
||||
## TODO: If the tool you use requires repositories.config, also uncomment the next line
|
||||
#!packages/repositories.config
|
||||
|
||||
# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
|
||||
# This line needs to be after the ignore of the build folder (and the packages folder if the line above has been uncommented)
|
||||
!packages/build/
|
||||
|
||||
# Windows Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Windows Store app package directory
|
||||
AppPackages/
|
||||
|
||||
# Others
|
||||
sql/
|
||||
*.Cache
|
||||
ClientBin/
|
||||
[Ss]tyle[Cc]op.*
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
node_modules/
|
||||
__pycache__/
|
||||
|
||||
# KDE
|
||||
.directory
|
||||
|
||||
#Kdevelop project files
|
||||
*.kdev4
|
||||
|
||||
# Xcode
|
||||
xcuserdata/
|
||||
*.xcscmblueprint
|
||||
*.xccheckout
|
||||
*.xcodeproj/*
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file to a newer
|
||||
# Visual Studio version. Backup files are not needed, because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# SQL Server files
|
||||
App_Data/*.mdf
|
||||
App_Data/*.ldf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# =========================
|
||||
# Windows detritus
|
||||
# =========================
|
||||
|
||||
# Windows image file caches
|
||||
[Tt]humbs.db
|
||||
[Tt]humbs.db:encryptable
|
||||
ehthumbs.db
|
||||
ehthumbs_vista.db
|
||||
|
||||
# Windows stackdumps
|
||||
*.stackdump
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
# Folder config file
|
||||
[Dd]esktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
logo.h
|
||||
*.autosave
|
||||
|
||||
# https://github.com/github/gitignore/blob/master/Global/Tags.gitignore
|
||||
# Ignore tags created by etags, ctags, gtags (GNU global) and cscope
|
||||
TAGS
|
||||
!TAGS/
|
||||
tags
|
||||
*.tags
|
||||
!tags/
|
||||
gtags.files
|
||||
GTAGS
|
||||
GRTAGS
|
||||
GPATH
|
||||
cscope.files
|
||||
cscope.out
|
||||
cscope.in.out
|
||||
cscope.po.out
|
||||
godot.creator.*
|
||||
|
||||
projects/
|
||||
platform/windows/godot_res.res
|
||||
|
||||
# Visual Studio 2017 and Visual Studio Code workspace folder
|
||||
/.vs
|
||||
*.vscode
|
||||
|
||||
# Visual Studio Code workspace file
|
||||
*.code-workspace
|
||||
|
||||
# Scons construction environment dump
|
||||
.scons_env.json
|
||||
|
||||
# Scons cache
|
||||
.cache
|
||||
|
||||
# Scons progress indicator
|
||||
.scons_node_count
|
||||
|
||||
# ccls cache (https://github.com/MaskRay/ccls)
|
||||
.ccls-cache/
|
||||
|
||||
# compile commands (https://clang.llvm.org/docs/JSONCompilationDatabase.html)
|
||||
compile_commands.json
|
||||
|
||||
# Cppcheck
|
||||
*.cppcheck
|
||||
21
src/SharpIDE.Godot/addons/godot_xterm/LICENSE.md
Normal file
21
src/SharpIDE.Godot/addons/godot_xterm/LICENSE.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# MIT License
|
||||
|
||||
Copyright (c) 2020-2025, Leroy Hopson and GodotXterm contributors.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
1038
src/SharpIDE.Godot/addons/godot_xterm/THIRDPARTY_NOTICES.txt
Normal file
1038
src/SharpIDE.Godot/addons/godot_xterm/THIRDPARTY_NOTICES.txt
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,715 @@
|
||||
THIRD-PARTY SOFTWARE NOTICES AND INFORMATION
|
||||
|
||||
The GodotXterm project incorporates components from the projects listed below.
|
||||
The original copyright notices and the licenses under which GodotXterm received such components are set forth below.
|
||||
|
||||
1. godot-cpp
|
||||
2. htable
|
||||
3. libtsm
|
||||
4. wcwidth
|
||||
|
||||
|
||||
%% godot-cpp NOTICES AND INFORMATION BEGIN HERE
|
||||
=========================================
|
||||
# MIT License
|
||||
|
||||
Copyright (c) 2017-present Godot Engine contributors.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
=========================================
|
||||
END OF godot-cpp NOTICES AND INFORMATION
|
||||
|
||||
%% htable NOTICES AND INFORMATION BEGIN HERE
|
||||
=========================================
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations
|
||||
below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it
|
||||
becomes a de-facto standard. To achieve this, non-free programs must
|
||||
be allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control
|
||||
compilation and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at least
|
||||
three years, to give the same user the materials specified in
|
||||
Subsection 6a, above, for a charge no more than the cost of
|
||||
performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply, and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License
|
||||
may add an explicit geographical distribution limitation excluding those
|
||||
countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms
|
||||
of the ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library.
|
||||
It is safest to attach them to the start of each source file to most
|
||||
effectively convey the exclusion of warranty; and each file should
|
||||
have at least the "copyright" line and a pointer to where the full
|
||||
notice is found.
|
||||
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or
|
||||
your school, if any, to sign a "copyright disclaimer" for the library,
|
||||
if necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James
|
||||
Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
|
||||
|
||||
=========================================
|
||||
END OF htable NOTICES AND INFORMATION
|
||||
|
||||
%% libtsm NOTICES AND INFORMATION BEGIN HERE
|
||||
=========================================
|
||||
= Authors =
|
||||
|
||||
This software was written by:
|
||||
Aetf <aetf@unlimitedcodeworks.xyz>
|
||||
David Herrmann <dh.herrmann@gmail.com>
|
||||
Fredrik Wikstrom <fredrik@a500.org>
|
||||
Ran Benita <ran234@gmail.com>
|
||||
|
||||
= Copyright Notice =
|
||||
|
||||
This software is licensed under the terms of the MIT license. Please see each
|
||||
source file for the related copyright notice and license.
|
||||
|
||||
If a file does not contain a copright notice, the following license shall
|
||||
apply:
|
||||
|
||||
Copyright (c) 2019-2020 Fredrik Wikstrom <fredrik@a500.org>
|
||||
Copyright (c) 2017-2018 Aetf <aetf@unlimitedcodeworks.xyz>
|
||||
Copyright (c) 2011-2013 David Herrmann <dh.herrmann@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files
|
||||
(the "Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
== Third-Party Source ==
|
||||
The hash-table implementation in src/shared/shl-htable.* uses internally the
|
||||
htable from CCAN, see LICENSE_htable.
|
||||
|
||||
The wcwidth() implementation in ./external/wcwidth is from
|
||||
|
||||
Copyright (C) Fredrik Fornwall 2016.
|
||||
Distributed under the MIT License.
|
||||
|
||||
Implementation of wcwidth(3) as a C port of:
|
||||
https://github.com/jquast/wcwidth
|
||||
|
||||
Report issues at:
|
||||
https://github.com/termux/wcwidth
|
||||
|
||||
UCS-4 to UTF-8 encoding is copied from "terminology":
|
||||
|
||||
Copyright (C) 2012-2012 Carsten Haitzler and various contributors
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
The "solarized" color palettes in tsm_vte.c are from:
|
||||
|
||||
Copyright (c) 2011 Ethan Schoonover
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
=========================================
|
||||
END OF libtsm NOTICES AND INFORMATION
|
||||
|
||||
%% wcwidth NOTICES AND INFORMATION BEGIN HERE
|
||||
=========================================
|
||||
This project is licensed for use as follows:
|
||||
|
||||
"""
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Fredrik Fornwall <fredrik@fornwall.net>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
"""
|
||||
|
||||
This license applies to parts originating from the
|
||||
https://github.com/jquast/wcwidth repository:
|
||||
|
||||
"""
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Jeff Quast <contact@jeffquast.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
"""
|
||||
=========================================
|
||||
END OF wcwidth NOTICES AND INFORMATION
|
||||
@@ -0,0 +1,116 @@
|
||||
@tool
|
||||
extends Terminal
|
||||
|
||||
signal exited(exit_code, signum)
|
||||
|
||||
var editor_settings: EditorSettings
|
||||
|
||||
@onready var pty = $PTY
|
||||
|
||||
|
||||
# Sets terminal colors according to a dictionary that maps terminal color names
|
||||
# to TextEditor theme color names.
|
||||
func _set_terminal_colors(color_map: Dictionary) -> void:
|
||||
for key in color_map.keys():
|
||||
var val: String = color_map[key]
|
||||
var editor_color = editor_settings.get_setting("text_editor/theme/highlighting/%s" % val)
|
||||
var color: Color = editor_color if editor_color else Color.BLACK
|
||||
add_theme_color_override(key, color)
|
||||
|
||||
|
||||
func _apply_font_size(font_size: int) -> void:
|
||||
add_theme_font_size_override("normal_font_size", font_size)
|
||||
add_theme_font_size_override("bold_font_size", font_size)
|
||||
add_theme_font_size_override("italics_font_size", font_size)
|
||||
add_theme_font_size_override("bold_italics_font_size", font_size)
|
||||
|
||||
|
||||
func _set_terminal_font() -> void:
|
||||
# Try to get editor's code font and font size first.
|
||||
var editor_font = null
|
||||
if editor_settings.has_setting("interface/editor/code_font"):
|
||||
editor_font = editor_settings.get_setting("interface/editor/code_font")
|
||||
if editor_settings.has_setting("interface/editor/code_font_size"):
|
||||
var editor_font_size = editor_settings.get_setting("interface/editor/code_font_size")
|
||||
if editor_font_size is int:
|
||||
_apply_font_size(editor_font_size)
|
||||
|
||||
# If we have an editor font, use it.
|
||||
if editor_font and editor_font is Font:
|
||||
add_theme_font_override("normal_font", editor_font)
|
||||
add_theme_font_override("bold_font", editor_font)
|
||||
add_theme_font_override("italics_font", editor_font)
|
||||
add_theme_font_override("bold_italics_font", editor_font)
|
||||
return
|
||||
|
||||
# Fallback to bundled monospace font.
|
||||
var font_path = "res://addons/godot_xterm/themes/fonts/regular.tres"
|
||||
if ResourceLoader.exists(font_path):
|
||||
var default_font = load(font_path)
|
||||
if default_font and default_font is Font:
|
||||
add_theme_font_override("normal_font", default_font)
|
||||
add_theme_font_override("bold_font", default_font)
|
||||
add_theme_font_override("italics_font", default_font)
|
||||
add_theme_font_override("bold_italics_font", default_font)
|
||||
|
||||
|
||||
func _ready():
|
||||
if not editor_settings:
|
||||
return
|
||||
|
||||
# Ensure monospace font is loaded for editor terminal.
|
||||
_set_terminal_font()
|
||||
|
||||
# Get colors from TextEdit theme. Created using the default (Adaptive) theme
|
||||
# for reference, but will probably cause strange results if using another theme
|
||||
# better to use a dedicated terminal theme, rather than relying on this.
|
||||
_set_terminal_colors(
|
||||
{
|
||||
"background_color": "background_color",
|
||||
"foreground_color": "text_color",
|
||||
"ansi_0_color": "caret_background_color",
|
||||
"ansi_1_color": "brace_mismatch_color",
|
||||
"ansi_2_color": "gdscript/node_reference_color",
|
||||
"ansi_3_color": "executing_line_color",
|
||||
"ansi_4_color": "bookmark_color",
|
||||
"ansi_5_color": "control_flow_keyword_color",
|
||||
"ansi_6_color": "engine_type_color",
|
||||
"ansi_7_color": "comment_color",
|
||||
"ansi_8_color": "completion_background_color",
|
||||
"ansi_9_color": "keyword_color",
|
||||
"ansi_10_color": "base_type_color",
|
||||
"ansi_11_color": "string_color",
|
||||
"ansi_12_color": "function_color",
|
||||
"ansi_13_color": "gdscript/global_function_color",
|
||||
"ansi_14_color": "gdscript/function_definition_color",
|
||||
"ansi_15_color": "caret_color",
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
func _input(event):
|
||||
if has_focus() and event is InputEventKey and event.is_pressed():
|
||||
if event.ctrl_pressed and event.keycode in [KEY_PAGEUP, KEY_PAGEDOWN]:
|
||||
# Handled by switch tabs shortcut.
|
||||
return
|
||||
|
||||
if event.ctrl_pressed and event.shift_pressed:
|
||||
# Not handled by terminal.
|
||||
return
|
||||
|
||||
# Handle all other InputEventKey events to prevent triggering of editor
|
||||
# shortcuts when using the terminal.
|
||||
#
|
||||
# Currently the only way to get shortcuts is by calling editor_settings.get_setting("shortcuts")
|
||||
# and it returns an array that *only* contains shortcuts that have been modified from the original.
|
||||
# Once https://github.com/godotengine/godot-proposals/issues/4112 is resolved it should be possible
|
||||
# to get all shortcuts by their editor setting string as documented here:
|
||||
# https://docs.godotengine.org/en/stable/tutorials/editor/default_key_mapping.html.
|
||||
# In this case we could simply add a setting called something like "allowed shortcuts" or
|
||||
# "propagated shortcuts" consisting of an array of shortcut editor setting strings.
|
||||
# For example "editor/save_scene" which saves the scene and by default maps to 'Ctrl + S'.
|
||||
# Then any shortcut events listed here can be handled by the terminal *and* the editor.
|
||||
|
||||
|
||||
func _on_PTY_exited(exit_code: int, signum: int):
|
||||
emit_signal("exited", exit_code, signum)
|
||||
@@ -0,0 +1 @@
|
||||
uid://cgjg4p52appdp
|
||||
@@ -0,0 +1,26 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://bkcyv0w3setep"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://cgjg4p52appdp" path="res://addons/godot_xterm/editor_plugins/terminal/editor_terminal.gd" id="1"]
|
||||
|
||||
[node name="Terminal" type="Terminal"]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
size_flags_horizontal = 4
|
||||
size_flags_vertical = 4
|
||||
focus_mode = 1
|
||||
script = ExtResource("1")
|
||||
|
||||
[node name="PTY" type="PTY" parent="."]
|
||||
cols = 114
|
||||
rows = 29
|
||||
terminal_path = NodePath("..")
|
||||
|
||||
[node name="Bell" type="AudioStreamPlayer" parent="."]
|
||||
|
||||
[connection signal="data_sent" from="." to="PTY" method="write"]
|
||||
[connection signal="size_changed" from="." to="PTY" method="resizev"]
|
||||
[connection signal="data_received" from="PTY" to="." method="write"]
|
||||
[connection signal="exited" from="PTY" to="." method="_on_PTY_exited"]
|
||||
@@ -0,0 +1,9 @@
|
||||
[gd_resource type="Shortcut" load_steps=2 format=3 uid="uid://cdr3iu6ttahlt"]
|
||||
|
||||
[sub_resource type="InputEventKey" id="InputEventKey_emaic"]
|
||||
shift_pressed = true
|
||||
ctrl_pressed = true
|
||||
keycode = 67
|
||||
|
||||
[resource]
|
||||
events = [SubResource("InputEventKey_emaic")]
|
||||
@@ -0,0 +1,9 @@
|
||||
[gd_resource type="Shortcut" load_steps=2 format=3 uid="uid://b5vans7f0vp2y"]
|
||||
|
||||
[sub_resource type="InputEventKey" id="InputEventKey_7k47m"]
|
||||
shift_pressed = true
|
||||
ctrl_pressed = true
|
||||
keycode = 88
|
||||
|
||||
[resource]
|
||||
events = [SubResource("InputEventKey_7k47m")]
|
||||
@@ -0,0 +1,9 @@
|
||||
[gd_resource type="Shortcut" load_steps=2 format=3 uid="uid://d3iu5cplfailp"]
|
||||
|
||||
[sub_resource type="InputEventKey" id="InputEventKey_0hq5g"]
|
||||
shift_pressed = true
|
||||
ctrl_pressed = true
|
||||
keycode = 84
|
||||
|
||||
[resource]
|
||||
events = [SubResource("InputEventKey_0hq5g")]
|
||||
@@ -0,0 +1,9 @@
|
||||
[gd_resource type="Shortcut" load_steps=2 format=3 uid="uid://cn2b3aeang6b"]
|
||||
|
||||
[sub_resource type="InputEventKey" id="InputEventKey_sihkr"]
|
||||
shift_pressed = true
|
||||
ctrl_pressed = true
|
||||
keycode = 86
|
||||
|
||||
[resource]
|
||||
events = [SubResource("InputEventKey_sihkr")]
|
||||
@@ -0,0 +1,8 @@
|
||||
[gd_resource type="Shortcut" load_steps=2 format=3 uid="uid://dpb1qwlv6mkfs"]
|
||||
|
||||
[sub_resource type="InputEventKey" id="InputEventKey_v5b4d"]
|
||||
ctrl_pressed = true
|
||||
keycode = 4194324
|
||||
|
||||
[resource]
|
||||
events = [SubResource("InputEventKey_v5b4d")]
|
||||
@@ -0,0 +1,8 @@
|
||||
[gd_resource type="Shortcut" load_steps=2 format=3 uid="uid://djs5hhu8vbmqf"]
|
||||
|
||||
[sub_resource type="InputEventKey" id="InputEventKey_svjos"]
|
||||
ctrl_pressed = true
|
||||
keycode = 4194323
|
||||
|
||||
[resource]
|
||||
events = [SubResource("InputEventKey_svjos")]
|
||||
@@ -0,0 +1,63 @@
|
||||
extends Resource
|
||||
|
||||
enum FileType {
|
||||
USE_SHELL_ENV,
|
||||
CUSTOM_FILE,
|
||||
}
|
||||
|
||||
enum CWDType {
|
||||
USE_PROJECT_DIRECTORY,
|
||||
CUSTOM_CWD,
|
||||
}
|
||||
|
||||
### Shortcuts ###
|
||||
|
||||
@export var new_terminal_shortcut: Shortcut = preload("./default_new_terminal_shortcut.tres")
|
||||
@export var kill_terminal_shortcut: Shortcut = preload("./default_kill_terminal_shortcut.tres")
|
||||
@export var copy_shortcut: Shortcut = preload("./default_copy_shortcut.tres")
|
||||
@export var paste_shortcut: Shortcut = preload("./default_paste_shortcut.tres")
|
||||
|
||||
@export var next_tab_shortcut: Shortcut = preload("./default_tab_right_shortcut.tres")
|
||||
@export var previous_tab_shortcut: Shortcut = preload("./default_tab_left_shortcut.tres")
|
||||
|
||||
### Scroll settings ###
|
||||
|
||||
# The maximum amount of lines the terminal keeps in its buffer.
|
||||
@export var scrollback_buffer_lines := 1000
|
||||
# If true, mouse wheel up and down can be used to scroll the terminal.
|
||||
@export var mouse_wheel_scroll := true
|
||||
# Whether or not to display scroll bar.
|
||||
@export var show_scroll_bar := true
|
||||
|
||||
# Copy/paste settings.
|
||||
@export var copy_on_selection := false
|
||||
|
||||
# Font settings.
|
||||
@export var font_size: int = 14
|
||||
@export var letter_spacing: int = 0
|
||||
@export var line_height: float = 1.2
|
||||
@export var ctrl_scroll_to_resize_font := true
|
||||
|
||||
# Bell settings.
|
||||
@export var visual_bell := true
|
||||
@export var audio_bell := true
|
||||
@export var bell_sound: AudioStream
|
||||
|
||||
# Exec args.
|
||||
@export var file_type := FileType.USE_SHELL_ENV
|
||||
@export var custom_file := "/bin/sh"
|
||||
|
||||
@export var cwd_type := CWDType.USE_PROJECT_DIRECTORY
|
||||
@export var custom_cwd := ""
|
||||
|
||||
@export var args := PackedStringArray()
|
||||
|
||||
@export var use_os_env := true
|
||||
@export var extra_env := {
|
||||
TERM = "xterm-256color",
|
||||
COLORTERM = "truecolor",
|
||||
}
|
||||
|
||||
|
||||
func _init(p_copy_on_selection := false):
|
||||
copy_on_selection = p_copy_on_selection
|
||||
@@ -0,0 +1 @@
|
||||
uid://b6t33wgbi4wx5
|
||||
@@ -0,0 +1,290 @@
|
||||
# Copyright (c) 2021, Leroy Hopson (MIT License).
|
||||
#
|
||||
# This file contains snippets of code derived from Godot's editor_node.cpp file.
|
||||
# These snippets are copyright of their authors and released under the MIT license:
|
||||
# - Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur (MIT License).
|
||||
# - Copyright (c) 2014-2021 Godot Engine contributors (MIT License).
|
||||
@tool
|
||||
extends Control
|
||||
|
||||
const EditorTerminal := preload("./editor_terminal.tscn")
|
||||
const TerminalSettings := preload("./settings/terminal_settings.gd")
|
||||
|
||||
const SETTINGS_FILE_PATH := "res://.gdxterm/settings.tres"
|
||||
|
||||
enum TerminalPopupMenuOptions {
|
||||
NEW_TERMINAL = 0,
|
||||
COPY = 2,
|
||||
PASTE = 3,
|
||||
SELECT_ALL = 4,
|
||||
CLEAR = 6,
|
||||
KILL_TERMINAL = 7,
|
||||
}
|
||||
|
||||
# Has access to the EditorSettings singleton so it can dynamically generate the
|
||||
# terminal color scheme based on editor theme settings.
|
||||
var editor_plugin: EditorPlugin
|
||||
var editor_interface: EditorInterface
|
||||
var editor_settings: EditorSettings
|
||||
|
||||
@onready var tabs: TabBar = $VBoxContainer/TabbarContainer/Tabs
|
||||
@onready var tabbar_container: HBoxContainer = $VBoxContainer/TabbarContainer
|
||||
@onready var add_button: Button = $VBoxContainer/TabbarContainer/AddButton
|
||||
@onready var tab_container: TabContainer = $VBoxContainer/TabContainer
|
||||
@onready var terminal_popup_menu: PopupMenu = $VBoxContainer/TerminalPopupMenu
|
||||
|
||||
# Size label.
|
||||
# Used to show the size of the terminal (rows/cols) and panel (pixels) when resized.
|
||||
@onready var size_label: Label = $SizeLabel
|
||||
@onready var size_label_timer: Timer = $SizeLabel/SizeLabelTimer
|
||||
|
||||
@onready var is_ready := true
|
||||
|
||||
var _theme := Theme.new()
|
||||
var _settings: TerminalSettings
|
||||
var _tab_container_min_size
|
||||
|
||||
|
||||
func _ready():
|
||||
if editor_interface:
|
||||
add_button.set("icon", get_theme_icon("Add", "EditorIcons"))
|
||||
editor_settings = editor_interface.get_editor_settings()
|
||||
_update_settings()
|
||||
|
||||
|
||||
func _load_or_create_settings() -> void:
|
||||
# Use only default settings for now, until settings are properly defined
|
||||
# and documented.
|
||||
_settings = TerminalSettings.new()
|
||||
|
||||
|
||||
func _update_settings() -> void:
|
||||
_load_or_create_settings()
|
||||
|
||||
var editor_scale: float = 1.0
|
||||
if editor_interface and editor_interface.has_method("get_editor_scale"):
|
||||
editor_scale = editor_interface.get_editor_scale()
|
||||
|
||||
custom_minimum_size = Vector2(0, tabbar_container.size.y + 182) * editor_scale
|
||||
call_deferred("set_size", Vector2(size.x, 415))
|
||||
|
||||
tabs.tab_close_display_policy = TabBar.CLOSE_BUTTON_SHOW_ALWAYS
|
||||
|
||||
# Update shortcuts.
|
||||
if _settings.new_terminal_shortcut:
|
||||
terminal_popup_menu.set_item_shortcut(
|
||||
TerminalPopupMenuOptions.NEW_TERMINAL, _settings.new_terminal_shortcut, true
|
||||
)
|
||||
if _settings.kill_terminal_shortcut:
|
||||
terminal_popup_menu.set_item_shortcut(
|
||||
TerminalPopupMenuOptions.KILL_TERMINAL, _settings.kill_terminal_shortcut, false
|
||||
)
|
||||
if _settings.copy_shortcut:
|
||||
terminal_popup_menu.set_item_shortcut(
|
||||
TerminalPopupMenuOptions.COPY, _settings.copy_shortcut, false
|
||||
)
|
||||
if _settings.paste_shortcut:
|
||||
terminal_popup_menu.set_item_shortcut(
|
||||
TerminalPopupMenuOptions.PASTE, _settings.paste_shortcut, false
|
||||
)
|
||||
|
||||
_update_terminal_tabs()
|
||||
|
||||
|
||||
func _update_terminal_tabs():
|
||||
# Wait a couple of frames to allow everything to resize before updating.
|
||||
var tree = get_tree()
|
||||
if tree:
|
||||
await tree.process_frame
|
||||
await tree.process_frame
|
||||
|
||||
if tabs.get_offset_buttons_visible():
|
||||
# Move add button to fixed position at the right of the tabbar container.
|
||||
if add_button.get_parent() == tabs:
|
||||
tabs.remove_child(add_button)
|
||||
tabbar_container.add_child(add_button)
|
||||
# Keep it at the end (right side) of the container.
|
||||
else:
|
||||
# Move add button after last tab.
|
||||
if tabs.tab_count > 0 and add_button.get_parent() == tabbar_container:
|
||||
tabbar_container.remove_child(add_button)
|
||||
tabs.add_child(add_button)
|
||||
var last_tab := Rect2()
|
||||
if tabs.get_tab_count() > 0:
|
||||
last_tab = tabs.get_tab_rect(tabs.get_tab_count() - 1)
|
||||
add_button.position = Vector2(
|
||||
last_tab.position.x + last_tab.size.x + 3, last_tab.position.y
|
||||
)
|
||||
if tabs.tab_count == 0 and add_button.get_parent() == tabs:
|
||||
tabs.remove_child(add_button)
|
||||
tabbar_container.add_child(add_button)
|
||||
tabbar_container.move_child(add_button, 0) # Move to start (left side)
|
||||
add_button.position = Vector2.ZERO
|
||||
|
||||
# Make sure we still own the button, so it gets saved with our scene.
|
||||
add_button.owner = self
|
||||
|
||||
|
||||
func _on_AddButton_pressed():
|
||||
var shell = (
|
||||
OS.get_environment("SHELL")
|
||||
if OS.has_environment("SHELL")
|
||||
else ("powershell" if OS.get_name() == "Windows" else "sh")
|
||||
)
|
||||
var terminal := EditorTerminal.instantiate()
|
||||
tabs.add_tab(shell.get_file())
|
||||
terminal.editor_settings = editor_settings
|
||||
terminal.set_anchors_preset(PRESET_BOTTOM_WIDE)
|
||||
terminal.connect("gui_input", Callable(self, "_on_TabContainer_gui_input"))
|
||||
terminal.connect("exited", Callable(self, "_on_Terminal_exited").bind(terminal))
|
||||
tab_container.add_child(terminal)
|
||||
terminal.pty.fork(shell)
|
||||
terminal.grab_focus()
|
||||
tabs.current_tab = tabs.get_tab_count() - 1
|
||||
tab_container.current_tab = tabs.current_tab
|
||||
_update_terminal_tabs()
|
||||
|
||||
|
||||
func _on_Tabs_tab_changed(tab_index):
|
||||
# Simply sync the TabContainer - focus handling happens in TabContainer signal
|
||||
# Only sync if TabContainer has enough tabs
|
||||
if tab_index < tab_container.get_tab_count():
|
||||
tab_container.current_tab = tab_index
|
||||
|
||||
|
||||
func _on_TabContainer_tab_changed(tab_index):
|
||||
# TabContainer has already changed, so we can safely focus immediately
|
||||
var current_tab_control = tab_container.get_current_tab_control()
|
||||
if current_tab_control:
|
||||
current_tab_control.grab_focus()
|
||||
|
||||
|
||||
func _on_Tabs_tab_close(tab_index):
|
||||
tabs.remove_tab(tab_index)
|
||||
tab_container.get_child(tab_index).queue_free()
|
||||
|
||||
# Sync TabContainer to the current TabBar selection
|
||||
# Focus will be handled automatically by the TabContainer signal
|
||||
if tabs.get_tab_count() > 0:
|
||||
tab_container.current_tab = tabs.current_tab
|
||||
|
||||
_update_terminal_tabs()
|
||||
|
||||
|
||||
func _notification(what):
|
||||
if not is_ready:
|
||||
return
|
||||
|
||||
match what:
|
||||
EditorSettings.NOTIFICATION_EDITOR_SETTINGS_CHANGED:
|
||||
_update_settings()
|
||||
_update_terminal_tabs()
|
||||
NOTIFICATION_RESIZED:
|
||||
_update_terminal_tabs()
|
||||
NOTIFICATION_APPLICATION_FOCUS_IN:
|
||||
_update_terminal_tabs()
|
||||
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
if not _settings or not event.is_pressed():
|
||||
return
|
||||
|
||||
# Global shortcut to open new terminal and make terminal panel visible.
|
||||
if _settings.new_terminal_shortcut and _settings.new_terminal_shortcut.matches_event(event):
|
||||
get_viewport().set_input_as_handled()
|
||||
editor_plugin.make_bottom_panel_item_visible(self)
|
||||
_on_AddButton_pressed()
|
||||
|
||||
# Non-global shortcuts, only applied if terminal is active and focused.
|
||||
if (
|
||||
tabs.get_tab_count() > 0 and tab_container.get_child(tabs.current_tab).has_focus()
|
||||
or terminal_popup_menu.has_focus()
|
||||
):
|
||||
# Kill terminal.
|
||||
if (
|
||||
_settings.kill_terminal_shortcut
|
||||
and _settings.kill_terminal_shortcut.matches_event(event)
|
||||
):
|
||||
get_viewport().set_input_as_handled()
|
||||
_on_TerminalPopupMenu_id_pressed(TerminalPopupMenuOptions.KILL_TERMINAL)
|
||||
|
||||
# Copy.
|
||||
if _settings.copy_shortcut and _settings.copy_shortcut.matches_event(event):
|
||||
get_viewport().set_input_as_handled()
|
||||
_on_TerminalPopupMenu_id_pressed(TerminalPopupMenuOptions.COPY)
|
||||
|
||||
# Paste.
|
||||
if _settings.paste_shortcut and _settings.paste_shortcut.matches_event(event):
|
||||
get_viewport().set_input_as_handled()
|
||||
_on_TerminalPopupMenu_id_pressed(TerminalPopupMenuOptions.PASTE)
|
||||
|
||||
# Next tab.
|
||||
if _settings.next_tab_shortcut and _settings.next_tab_shortcut.matches_event(event):
|
||||
get_viewport().set_input_as_handled()
|
||||
tabs.current_tab = min(tabs.current_tab + 1, tabs.get_tab_count() - 1)
|
||||
|
||||
# Previous tab.
|
||||
if _settings.previous_tab_shortcut and _settings.previous_tab_shortcut.matches_event(event):
|
||||
get_viewport().set_input_as_handled()
|
||||
tabs.current_tab = max(tabs.current_tab - 1, 0)
|
||||
|
||||
|
||||
func _on_TabContainer_gui_input(event):
|
||||
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_RIGHT:
|
||||
terminal_popup_menu.position = event.global_position
|
||||
terminal_popup_menu.popup()
|
||||
|
||||
|
||||
func _on_TerminalPopupMenu_id_pressed(id):
|
||||
match id:
|
||||
TerminalPopupMenuOptions.NEW_TERMINAL:
|
||||
_on_AddButton_pressed()
|
||||
|
||||
if tabs.get_tab_count() > 0:
|
||||
var terminal = tab_container.get_child(tab_container.current_tab)
|
||||
match id:
|
||||
TerminalPopupMenuOptions.COPY:
|
||||
DisplayServer.clipboard_set(terminal.copy_selection())
|
||||
TerminalPopupMenuOptions.PASTE:
|
||||
terminal.write(DisplayServer.clipboard_get())
|
||||
TerminalPopupMenuOptions.SELECT_ALL:
|
||||
terminal.select(0, 0, terminal.get_rows(), terminal.get_cols())
|
||||
TerminalPopupMenuOptions.CLEAR:
|
||||
terminal.clear()
|
||||
TerminalPopupMenuOptions.KILL_TERMINAL:
|
||||
_on_Tabs_tab_close(tabs.current_tab)
|
||||
|
||||
|
||||
func _on_Tabs_reposition_active_tab_request(idx_to):
|
||||
var active = tab_container.get_child(tab_container.current_tab)
|
||||
tab_container.move_child(active, idx_to)
|
||||
|
||||
|
||||
func _on_Panel_resized():
|
||||
if not size_label:
|
||||
return
|
||||
|
||||
var size = tab_container.size
|
||||
if tabs.get_tab_count() > 0:
|
||||
var terminal = tab_container.get_child(tabs.current_tab)
|
||||
var cols = terminal.get_cols()
|
||||
var rows = terminal.get_rows()
|
||||
size_label.text = "Size: %d cols; %d rows\n(%d x %d px)" % [cols, rows, size.x, size.y]
|
||||
else:
|
||||
size_label.text = "Size:\n(%d x %d px)" % [size.x, size.y]
|
||||
|
||||
size_label.visible = true
|
||||
size_label_timer.wait_time = 1
|
||||
size_label_timer.start()
|
||||
|
||||
|
||||
func _on_SizeLabelTimer_timeout():
|
||||
if size_label:
|
||||
size_label.visible = false
|
||||
|
||||
|
||||
func _on_Terminal_exited(exit_code, signum, terminal):
|
||||
# Leave non-zero exit code terminals open in case they have some important
|
||||
# error information.
|
||||
if exit_code == 0:
|
||||
_on_Tabs_tab_close(terminal.get_index())
|
||||
@@ -0,0 +1 @@
|
||||
uid://cufcnr6pxqofk
|
||||
@@ -0,0 +1,135 @@
|
||||
[gd_scene load_steps=5 format=3 uid="uid://cbxovnvw5o4mo"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://cufcnr6pxqofk" path="res://addons/godot_xterm/editor_plugins/terminal/terminal_panel.gd" id="1"]
|
||||
|
||||
[sub_resource type="Image" id="Image_stuna"]
|
||||
data = {
|
||||
"data": PackedByteArray(255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 92, 92, 0, 255, 92, 92, 0, 255, 92, 92, 0, 255, 92, 92, 0, 255, 92, 92, 0, 255, 92, 92, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 0, 255, 92, 92, 127, 255, 92, 92, 0, 255, 92, 92, 0, 255, 92, 92, 0, 255, 92, 92, 0, 255, 92, 92, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 0, 255, 93, 93, 255, 255, 92, 92, 127, 255, 92, 92, 0, 255, 92, 92, 0, 255, 92, 92, 0, 255, 92, 92, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 92, 92, 127, 255, 92, 92, 0, 255, 92, 92, 0, 255, 92, 92, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 92, 92, 127, 255, 92, 92, 0, 255, 92, 92, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 92, 92, 0, 255, 92, 92, 0, 255, 92, 92, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 231, 255, 90, 90, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 231, 255, 90, 90, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 0, 255, 93, 93, 0, 255, 91, 91, 0, 255, 91, 91, 0, 255, 91, 91, 42, 255, 90, 90, 0, 255, 94, 94, 0, 255, 91, 91, 42, 255, 93, 93, 233, 255, 92, 92, 232, 255, 93, 93, 41, 255, 90, 90, 0, 255, 94, 94, 0, 255, 91, 91, 42, 255, 93, 93, 233, 255, 92, 92, 232, 255, 92, 92, 0, 255, 92, 92, 0, 255, 91, 91, 0, 255, 91, 91, 0, 255, 91, 91, 0, 255, 91, 91, 45, 255, 93, 93, 44, 255, 91, 91, 0, 255, 91, 91, 42, 255, 91, 91, 42, 255, 93, 93, 0, 255, 91, 91, 45, 255, 93, 93, 44, 255, 91, 91, 0, 255, 91, 91, 42, 255, 91, 91, 42, 255, 91, 91, 0, 255, 91, 91, 0, 255, 91, 91, 0, 255, 91, 91, 0, 255, 91, 91, 45, 255, 92, 92, 235, 255, 92, 92, 234, 255, 89, 89, 43, 255, 91, 91, 0, 255, 91, 91, 0, 255, 91, 91, 45, 255, 92, 92, 235, 255, 92, 92, 234, 255, 89, 89, 43, 255, 91, 91, 0, 255, 91, 91, 0, 255, 91, 91, 0, 255, 91, 91, 0, 255, 92, 92, 0, 255, 92, 92, 0, 255, 92, 92, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 91, 91, 59, 255, 92, 92, 61, 255, 92, 92, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 91, 91, 59, 255, 92, 92, 61, 255, 92, 92, 0, 255, 92, 92, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0),
|
||||
"format": "RGBA8",
|
||||
"height": 16,
|
||||
"mipmaps": false,
|
||||
"width": 16
|
||||
}
|
||||
|
||||
[sub_resource type="ImageTexture" id="ImageTexture_umfb5"]
|
||||
image = SubResource("Image_stuna")
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_osmrc"]
|
||||
bg_color = Color(0.113329, 0.129458, 0.156802, 1)
|
||||
|
||||
[node name="Panel" type="Panel"]
|
||||
custom_minimum_size = Vector2(0, 206)
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_right = 2304.0
|
||||
offset_bottom = -233.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1")
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
theme_override_constants/separation = 0
|
||||
|
||||
[node name="TabbarContainer" type="HBoxContainer" parent="VBoxContainer"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Tabs" type="TabBar" parent="VBoxContainer/TabbarContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
focus_mode = 0
|
||||
tab_close_display_policy = 2
|
||||
drag_to_rearrange_enabled = true
|
||||
|
||||
[node name="AddButton" type="Button" parent="VBoxContainer/TabbarContainer"]
|
||||
layout_mode = 2
|
||||
tooltip_text = "New Terminal (Ctrl+Shift+T)"
|
||||
theme_override_colors/icon_normal_color = Color(0.6, 0.6, 0.6, 0.8)
|
||||
flat = true
|
||||
|
||||
[node name="PopupMenu" type="PopupMenu" parent="VBoxContainer/TabbarContainer"]
|
||||
item_count = 4
|
||||
item_0/text = "Kill"
|
||||
item_0/id = 0
|
||||
item_1/text = "Kill Others"
|
||||
item_1/id = 1
|
||||
item_2/text = "Kill to the Right"
|
||||
item_2/id = 2
|
||||
item_3/text = "Kill All"
|
||||
item_3/id = 3
|
||||
|
||||
[node name="TabContainer" type="TabContainer" parent="VBoxContainer"]
|
||||
clip_contents = true
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
theme_override_styles/panel = SubResource("StyleBoxFlat_osmrc")
|
||||
tabs_visible = false
|
||||
deselect_enabled = true
|
||||
|
||||
[node name="TerminalPopupMenu" type="PopupMenu" parent="VBoxContainer"]
|
||||
size = Vector2i(136, 178)
|
||||
item_count = 8
|
||||
item_0/text = "New Terminal"
|
||||
item_0/id = 0
|
||||
item_1/id = 1
|
||||
item_1/disabled = true
|
||||
item_1/separator = true
|
||||
item_2/text = "Copy"
|
||||
item_2/id = 2
|
||||
item_3/text = "Paste"
|
||||
item_3/id = 3
|
||||
item_4/text = "Select All"
|
||||
item_4/id = 4
|
||||
item_5/id = 5
|
||||
item_5/separator = true
|
||||
item_6/text = "Clear"
|
||||
item_6/id = 6
|
||||
item_7/text = "Kill Terminal"
|
||||
item_7/id = 7
|
||||
|
||||
[node name="SizeLabel" type="Label" parent="."]
|
||||
visible = false
|
||||
layout_mode = 1
|
||||
anchors_preset = 8
|
||||
anchor_left = 0.5
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 0.5
|
||||
offset_left = -52.0
|
||||
offset_top = -15.5
|
||||
offset_right = 52.0
|
||||
offset_bottom = 15.5
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
text = "Size:
|
||||
(3456 x 1035 px)"
|
||||
|
||||
[node name="Panel" type="Panel" parent="SizeLabel"]
|
||||
show_behind_parent = true
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_left = -5.0
|
||||
offset_top = -5.0
|
||||
offset_right = 5.0
|
||||
offset_bottom = 5.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="SizeLabelTimer" type="Timer" parent="SizeLabel"]
|
||||
|
||||
[connection signal="resized" from="." to="." method="_on_Panel_resized"]
|
||||
[connection signal="tab_changed" from="VBoxContainer/TabbarContainer/Tabs" to="." method="_on_Tabs_tab_changed"]
|
||||
[connection signal="tab_close_pressed" from="VBoxContainer/TabbarContainer/Tabs" to="." method="_on_Tabs_tab_close"]
|
||||
[connection signal="pressed" from="VBoxContainer/TabbarContainer/AddButton" to="." method="_on_AddButton_pressed"]
|
||||
[connection signal="gui_input" from="VBoxContainer/TabContainer" to="." method="_on_TabContainer_gui_input"]
|
||||
[connection signal="tab_changed" from="VBoxContainer/TabContainer" to="." method="_on_TabContainer_tab_changed"]
|
||||
[connection signal="id_pressed" from="VBoxContainer/TerminalPopupMenu" to="." method="_on_TerminalPopupMenu_id_pressed"]
|
||||
[connection signal="timeout" from="SizeLabel/SizeLabelTimer" to="." method="_on_SizeLabelTimer_timeout"]
|
||||
@@ -0,0 +1,24 @@
|
||||
[configuration]
|
||||
|
||||
entry_symbol = "godot_xterm_library_init"
|
||||
compatibility_minimum = "4.2.0"
|
||||
|
||||
[icons]
|
||||
|
||||
Terminal = "res://addons/godot_xterm/icons/terminal_icon.svg"
|
||||
PTY = "res://addons/godot_xterm/icons/pty_icon.svg"
|
||||
|
||||
[libraries]
|
||||
|
||||
linux.debug.x86_64 = "res://addons/godot_xterm/bin/libgodot-xterm.linux.template_debug.x86_64.so"
|
||||
linux.release.x86_64 = "res://addons/godot_xterm/bin/libgodot-xterm.linux.template_release.x86_64.so"
|
||||
linux.debug.x86_32 = "res://addons/godot_xterm/bin/libgodot-xterm.linux.template_debug.x86_32.so"
|
||||
linux.release.x86_32 = "res://addons/godot_xterm/bin/libgodot-xterm.linux.template_release.x86_32.so"
|
||||
web.debug.wasm32 = "res://addons/godot_xterm/bin/libgodot-xterm.web.template_debug.wasm32.wasm"
|
||||
web.release.wasm32 = "res://addons/godot_xterm/bin/libgodot-xterm.web.template_release.wasm32.wasm"
|
||||
macos.debug = "res://addons/godot_xterm/bin/libgodot-xterm.macos.template_debug.framework"
|
||||
macos.release = "res://addons/godot_xterm/bin/libgodot-xterm.macos.template_release.framework"
|
||||
windows.debug.x86_64 = "res://addons/godot_xterm/bin/libgodot-xterm.windows.template_debug.x86_64.dll"
|
||||
windows.release.x86_64 = "res://addons/godot_xterm/bin/libgodot-xterm.windows.template_release.x86_64.dll"
|
||||
windows.debug.x86_32 = "res://addons/godot_xterm/bin/libgodot-xterm.windows.template_debug.x86_32.dll"
|
||||
windows.release.x86_32 = "res://addons/godot_xterm/bin/libgodot-xterm.windows.template_release.x86_32.dll"
|
||||
@@ -0,0 +1 @@
|
||||
uid://xlyw0p2epn3l
|
||||
51
src/SharpIDE.Godot/addons/godot_xterm/icons/pty_icon.svg
Normal file
51
src/SharpIDE.Godot/addons/godot_xterm/icons/pty_icon.svg
Normal file
@@ -0,0 +1,51 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
id="svg4716"
|
||||
version="1.1"
|
||||
width="16"
|
||||
viewBox="0 0 16 16"
|
||||
height="16">
|
||||
<metadata
|
||||
id="metadata4722">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs4720">
|
||||
<clipPath
|
||||
id="clipPath826"
|
||||
clipPathUnits="userSpaceOnUse">
|
||||
<use
|
||||
height="100%"
|
||||
width="100%"
|
||||
id="use828"
|
||||
xlink:href="#g822"
|
||||
y="0"
|
||||
x="0" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
<g
|
||||
clip-path="url(#clipPath826)"
|
||||
id="g824">
|
||||
<g
|
||||
id="g822">
|
||||
<path
|
||||
style="fill:#e0e0e0;fill-opacity:0.99607999"
|
||||
d="M 4,1 1,5 H 3 V 8 H 5 V 5 h 2 z m 7,0 V 4 H 9 l 3,4 3,-4 H 13 V 1 Z m -2,9 v 1 h 1 v 4 h 1 v -4 h 1 v -1 z m -4,0 v 2 1 2 H 6 V 13 H 7 8 V 12 10 H 6 Z m 1,1 h 1 v 1 H 6 Z"
|
||||
id="path4714" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1,38 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://ixravk0w4lkt"
|
||||
path="res://.godot/imported/pty_icon.svg-7c3f500292e2f95935d23c435d6de47f.ctex"
|
||||
metadata={
|
||||
"has_editor_variant": true,
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/godot_xterm/icons/pty_icon.svg"
|
||||
dest_files=["res://.godot/imported/pty_icon.svg-7c3f500292e2f95935d23c435d6de47f.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=0
|
||||
svg/scale=1.0
|
||||
editor/scale_with_editor_scale=true
|
||||
editor/convert_colors_with_editor_theme=false
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<metadata>
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<dc:title/>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<path d="m4.5605 3.9746c-0.074558 0-0.14819 0.029049-0.20508 0.085938l-0.27539 0.27539c-0.11354 0.11358-0.11332 0.29631 0 0.41016l1.8691 1.8789-1.8691 1.8789c-0.11336 0.11385-0.11358 0.29657 0 0.41016l0.27539 0.27539c0.11377 0.11378 0.29833 0.11378 0.41211 0l2.3594-2.3594c0.11378-0.11378 0.11378-0.29834 0-0.41211l-2.3594-2.3574c-0.056882-0.056888-0.13247-0.085938-0.20703-0.085938zm3.2207 4.3984c-0.1609 0-0.29102 0.13012-0.29102 0.29102v0.38867c0 0.1609 0.13012 0.29102 0.29102 0.29102h3.6914c0.1609 0 0.29102-0.13012 0.29102-0.29102v-0.38867c0-0.1609-0.13012-0.29102-0.29102-0.29102z" fill="#a5efac" stroke-width=".012139"/>
|
||||
<path d="m3 1c-1.1046 0-2 0.8954-2 2v10c0 1.1046 0.89543 2 2 2h10c1.1046 0 2-0.8954 2-2v-10c0-1.1046-0.89543-2-2-2zm0 2h10v10h-10z" fill="#a5efac"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1,38 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://b1cq080dxs1ft"
|
||||
path="res://.godot/imported/terminal_icon.svg-2a4b198a0e3aa43f04b43cec3e3f109d.ctex"
|
||||
metadata={
|
||||
"has_editor_variant": true,
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/godot_xterm/icons/terminal_icon.svg"
|
||||
dest_files=["res://.godot/imported/terminal_icon.svg-2a4b198a0e3aa43f04b43cec3e3f109d.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=0
|
||||
svg/scale=1.0
|
||||
editor/scale_with_editor_scale=true
|
||||
editor/convert_colors_with_editor_theme=false
|
||||
@@ -0,0 +1,90 @@
|
||||
@tool
|
||||
extends EditorImportPlugin
|
||||
|
||||
const Asciicast = preload("../resources/asciicast.gd")
|
||||
|
||||
|
||||
func _get_importer_name():
|
||||
return "godot_xterm"
|
||||
|
||||
|
||||
func _get_visible_name():
|
||||
return "asciicast"
|
||||
|
||||
|
||||
func _get_recognized_extensions():
|
||||
return ["cast"]
|
||||
|
||||
|
||||
func _get_save_extension():
|
||||
return "res"
|
||||
|
||||
|
||||
func _get_resource_type():
|
||||
return "Animation"
|
||||
|
||||
|
||||
func _get_import_options(preset, _i):
|
||||
return []
|
||||
|
||||
|
||||
func _get_priority():
|
||||
return 1.0
|
||||
|
||||
|
||||
func _get_import_order():
|
||||
return 0
|
||||
|
||||
|
||||
func _get_preset_count():
|
||||
return 0
|
||||
|
||||
|
||||
func _import(source_file, save_path, options, r_platform_variant, r_gen_files):
|
||||
var file = FileAccess.open(source_file, FileAccess.READ)
|
||||
var err = FileAccess.get_open_error()
|
||||
if err != OK:
|
||||
return err
|
||||
|
||||
var header = file.get_line()
|
||||
|
||||
var asciicast = Asciicast.new()
|
||||
|
||||
asciicast.add_track(Animation.TYPE_METHOD, 0)
|
||||
asciicast.track_set_path(0, ".")
|
||||
|
||||
var frame = {"time": 0.0, "data": {"method": "write", "args": [PackedByteArray()]}}
|
||||
|
||||
while not file.eof_reached():
|
||||
var line = file.get_line()
|
||||
if line == "":
|
||||
continue
|
||||
|
||||
var test_json_conv = JSON.new()
|
||||
test_json_conv.parse(line)
|
||||
var p = test_json_conv.get_data()
|
||||
if typeof(p) != TYPE_ARRAY:
|
||||
continue
|
||||
|
||||
var event_type: String = p[1]
|
||||
var event_data: PackedByteArray = p[2].to_utf8_buffer()
|
||||
|
||||
# Asciicast recordings have a resolution of 0.000001, however animation
|
||||
# track keys only have a resolution of 0.01, therefore we must combine
|
||||
# events that would occur in the same keyframe, otherwise only the last
|
||||
# event is inserted and the previous events are overwritten.
|
||||
var time = snapped(p[0], 0.01)
|
||||
|
||||
if event_type == "o":
|
||||
if time == frame.time:
|
||||
asciicast.track_remove_key_at_time(0, time)
|
||||
frame.data.args[0] = frame.data.args[0] + event_data
|
||||
else:
|
||||
frame.time = time
|
||||
frame.data.args = [event_data]
|
||||
|
||||
asciicast.track_insert_key(0, frame.time, frame.data)
|
||||
|
||||
asciicast.length = frame.time
|
||||
|
||||
return ResourceSaver.save(asciicast, "%s.%s" % [save_path, _get_save_extension()])
|
||||
@@ -0,0 +1 @@
|
||||
uid://ghf570kuknhi
|
||||
@@ -0,0 +1,135 @@
|
||||
@tool
|
||||
extends EditorImportPlugin
|
||||
|
||||
const XrdbTheme := preload("../resources/xrdb_theme.gd")
|
||||
|
||||
|
||||
func _get_importer_name():
|
||||
return "godot_xterm_xrdb_importer"
|
||||
|
||||
|
||||
func _get_visible_name():
|
||||
return "xrdb_theme"
|
||||
|
||||
|
||||
func _get_recognized_extensions():
|
||||
return ["xrdb", "Xresources", "xresources"]
|
||||
|
||||
|
||||
func _get_save_extension():
|
||||
return "res"
|
||||
|
||||
|
||||
func _get_resource_type():
|
||||
return "Theme"
|
||||
|
||||
|
||||
func _get_import_options(preset, _i):
|
||||
return []
|
||||
|
||||
|
||||
func _get_priority():
|
||||
return 1.0
|
||||
|
||||
|
||||
func _get_import_order():
|
||||
return 0
|
||||
|
||||
|
||||
func _get_preset_count():
|
||||
return 0
|
||||
|
||||
|
||||
func _import(source_file, save_path, options, r_platform_variant, r_gen_files):
|
||||
var file = FileAccess.open(source_file, FileAccess.READ)
|
||||
var err = FileAccess.get_open_error()
|
||||
if err != OK:
|
||||
return err
|
||||
|
||||
var theme: Theme = XrdbTheme.new()
|
||||
theme.set_theme_item(Theme.DATA_TYPE_FONT_SIZE, "font_size", "Terminal", 14)
|
||||
theme.set_theme_item(
|
||||
Theme.DATA_TYPE_FONT, "normal_font", "Terminal", preload("../themes/fonts/regular.tres")
|
||||
)
|
||||
|
||||
var word_regex = RegEx.new()
|
||||
word_regex.compile("\\S+")
|
||||
|
||||
var color_regex = RegEx.new()
|
||||
color_regex.compile(".*(?<name>cursor|foreground|background|color\\d+):")
|
||||
|
||||
while not file.eof_reached():
|
||||
var line = file.get_line().strip_edges()
|
||||
var words = word_regex.search_all(line)
|
||||
if words.size() < 2:
|
||||
continue
|
||||
|
||||
var name: String
|
||||
var color: Color
|
||||
|
||||
if words.size() == 2:
|
||||
if "cursorColor" in words[0].get_string():
|
||||
name = "cursorcolor"
|
||||
color = Color(words[1].get_string())
|
||||
else:
|
||||
var c = color_regex.search_all(words[0].get_string().to_lower())
|
||||
if c.size() > 0:
|
||||
name = c[0].get_string("name").to_lower()
|
||||
color = Color(words[1].get_string())
|
||||
|
||||
if words.size() == 3 and words[0].get_string() == "#define":
|
||||
name = words[1].get_string().to_lower()
|
||||
color = Color(words[2].get_string())
|
||||
|
||||
if name == null or color == null:
|
||||
continue
|
||||
|
||||
match name:
|
||||
"color0", "ansi_0_color":
|
||||
theme.set_theme_item(Theme.DATA_TYPE_COLOR, "ansi_0_color", "Terminal", color)
|
||||
"color1", "ansi_1_color":
|
||||
theme.set_theme_item(Theme.DATA_TYPE_COLOR, "ansi_1_color", "Terminal", color)
|
||||
"color2", "ansi_2_color":
|
||||
theme.set_theme_item(Theme.DATA_TYPE_COLOR, "ansi_2_color", "Terminal", color)
|
||||
"color3", "ansi_3_color":
|
||||
theme.set_theme_item(Theme.DATA_TYPE_COLOR, "ansi_3_color", "Terminal", color)
|
||||
"color4", "ansi_4_color":
|
||||
theme.set_theme_item(Theme.DATA_TYPE_COLOR, "ansi_4_color", "Terminal", color)
|
||||
"color5", "ansi_5_color":
|
||||
theme.set_theme_item(Theme.DATA_TYPE_COLOR, "ansi_5_color", "Terminal", color)
|
||||
"color6", "ansi_6_color":
|
||||
theme.set_theme_item(Theme.DATA_TYPE_COLOR, "ansi_6_color", "Terminal", color)
|
||||
"color7", "ansi_7_color":
|
||||
theme.set_theme_item(Theme.DATA_TYPE_COLOR, "ansi_7_color", "Terminal", color)
|
||||
"color8", "ansi_8_color":
|
||||
theme.set_theme_item(Theme.DATA_TYPE_COLOR, "ansi_8_color", "Terminal", color)
|
||||
"color9", "ansi_9_color":
|
||||
theme.set_theme_item(Theme.DATA_TYPE_COLOR, "ansi_9_color", "Terminal", color)
|
||||
"color10", "ansi_10_color":
|
||||
theme.set_theme_item(Theme.DATA_TYPE_COLOR, "ansi_10_color", "Terminal", color)
|
||||
"color11", "ansi_11_color":
|
||||
theme.set_theme_item(Theme.DATA_TYPE_COLOR, "ansi_11_color", "Terminal", color)
|
||||
"color12", "ansi_12_color":
|
||||
theme.set_theme_item(Theme.DATA_TYPE_COLOR, "ansi_12_color", "Terminal", color)
|
||||
"color13", "ansi_13_color":
|
||||
theme.set_theme_item(Theme.DATA_TYPE_COLOR, "ansi_13_color", "Terminal", color)
|
||||
"color14", "ansi_14_color":
|
||||
theme.set_theme_item(Theme.DATA_TYPE_COLOR, "ansi_14_color", "Terminal", color)
|
||||
"color15", "ansi_15_color":
|
||||
theme.set_theme_item(Theme.DATA_TYPE_COLOR, "ansi_15_color", "Terminal", color)
|
||||
"foreground", "foreground_color":
|
||||
theme.set_theme_item(Theme.DATA_TYPE_COLOR, "foreground_color", "Terminal", color)
|
||||
"background", "background_color":
|
||||
theme.set_theme_item(Theme.DATA_TYPE_COLOR, "background_color", "Terminal", color)
|
||||
"selection_color":
|
||||
theme.set_theme_item(Theme.DATA_TYPE_COLOR, "selection_color", "Terminal", color)
|
||||
"selected_text_color":
|
||||
theme.set_theme_item(
|
||||
Theme.DATA_TYPE_COLOR, "selected_text_color", "Terminal", color
|
||||
)
|
||||
"cursorcolor", "cursor_color":
|
||||
theme.set_theme_item(Theme.DATA_TYPE_COLOR, "cursor_color", "Terminal", color)
|
||||
"cursor_text_color":
|
||||
theme.set_theme_item(Theme.DATA_TYPE_COLOR, "cursor_text_color", "Terminal", color)
|
||||
|
||||
return ResourceSaver.save(theme, "%s.%s" % [save_path, _get_save_extension()])
|
||||
@@ -0,0 +1 @@
|
||||
uid://dgssqoaaxy4xh
|
||||
7
src/SharpIDE.Godot/addons/godot_xterm/plugin.cfg
Normal file
7
src/SharpIDE.Godot/addons/godot_xterm/plugin.cfg
Normal file
@@ -0,0 +1,7 @@
|
||||
[plugin]
|
||||
|
||||
name="GodotXterm"
|
||||
description=""
|
||||
author="Leroy Hopson"
|
||||
version="4.0.0-rc.2"
|
||||
script="plugin.gd"
|
||||
40
src/SharpIDE.Godot/addons/godot_xterm/plugin.gd
Normal file
40
src/SharpIDE.Godot/addons/godot_xterm/plugin.gd
Normal file
@@ -0,0 +1,40 @@
|
||||
@tool
|
||||
extends EditorPlugin
|
||||
|
||||
var pty_supported := (
|
||||
OS.get_name() in ["Linux", "FreeBSD", "NetBSD", "OpenBSD", "BSD", "macOS", "Windows"]
|
||||
)
|
||||
var asciicast_import_plugin
|
||||
var xrdb_import_plugin
|
||||
var terminal_panel: Control
|
||||
|
||||
|
||||
func _enter_tree():
|
||||
asciicast_import_plugin = preload("./import_plugins/asciicast_import_plugin.gd").new()
|
||||
add_import_plugin(asciicast_import_plugin)
|
||||
|
||||
xrdb_import_plugin = preload("./import_plugins/xrdb_import_plugin.gd").new()
|
||||
add_import_plugin(xrdb_import_plugin)
|
||||
|
||||
var asciicast_script = preload("./resources/asciicast.gd")
|
||||
add_custom_type("Asciicast", "Animation", asciicast_script, null)
|
||||
|
||||
if pty_supported:
|
||||
terminal_panel = preload("./editor_plugins/terminal/terminal_panel.tscn").instantiate()
|
||||
terminal_panel.editor_plugin = self
|
||||
terminal_panel.editor_interface = get_editor_interface()
|
||||
add_control_to_bottom_panel(terminal_panel, "Terminal")
|
||||
|
||||
|
||||
func _exit_tree():
|
||||
remove_import_plugin(asciicast_import_plugin)
|
||||
asciicast_import_plugin = null
|
||||
|
||||
remove_import_plugin(xrdb_import_plugin)
|
||||
xrdb_import_plugin = null
|
||||
|
||||
remove_custom_type("Asciicast")
|
||||
|
||||
if pty_supported:
|
||||
remove_control_from_bottom_panel(terminal_panel)
|
||||
terminal_panel.free()
|
||||
1
src/SharpIDE.Godot/addons/godot_xterm/plugin.gd.uid
Normal file
1
src/SharpIDE.Godot/addons/godot_xterm/plugin.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://ds0khigrtnemq
|
||||
22
src/SharpIDE.Godot/addons/godot_xterm/resources/asciicast.gd
Normal file
22
src/SharpIDE.Godot/addons/godot_xterm/resources/asciicast.gd
Normal file
@@ -0,0 +1,22 @@
|
||||
extends Animation
|
||||
|
||||
signal data_written(data)
|
||||
signal data_read(data)
|
||||
|
||||
@export var version: int = 2
|
||||
# Initial terminal width (number of columns).
|
||||
@export var width: int
|
||||
# Initial terminal height (number of rows).
|
||||
@export var height: int
|
||||
|
||||
|
||||
func get_class() -> String:
|
||||
return "Asciicast"
|
||||
|
||||
|
||||
func is_class(name) -> bool:
|
||||
return name == get_class() or super.is_class(name)
|
||||
|
||||
|
||||
func _init():
|
||||
step = 0.01 # Parent override.
|
||||
@@ -0,0 +1 @@
|
||||
uid://daqhwrk6s4r7s
|
||||
@@ -0,0 +1,9 @@
|
||||
extends Theme
|
||||
|
||||
|
||||
func get_class() -> String:
|
||||
return "XrdbTheme"
|
||||
|
||||
|
||||
func is_class(name) -> bool:
|
||||
return name == get_class() or super.is_class(name)
|
||||
@@ -0,0 +1 @@
|
||||
uid://b5w7m5xhi0vba
|
||||
@@ -0,0 +1,5 @@
|
||||
// SPDX-FileCopyrightText: 2024 Leroy Hopson <godot-xterm@leroy.nix.nz>
|
||||
// SPDX-License-Identifier: MIT
|
||||
shader_type canvas_item;
|
||||
#define BACKGROUND
|
||||
#include "./common.gdshaderinc"
|
||||
@@ -0,0 +1 @@
|
||||
uid://d3dy6nhv17r6y
|
||||
@@ -0,0 +1,94 @@
|
||||
// SPDX-FileCopyrightText: 2024 Leroy Hopson <godot-xterm@leroy.nix.nz>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#define FLAG_INVERSE 1 << 0
|
||||
#define FLAG_BLINK 1 << 1
|
||||
#define FLAG_CURSOR 1 << 2
|
||||
|
||||
#define transparent vec4(0)
|
||||
|
||||
uniform int cols;
|
||||
uniform int rows;
|
||||
uniform vec2 size;
|
||||
uniform vec2 cell_size;
|
||||
uniform vec2 grid_size;
|
||||
|
||||
uniform sampler2D attributes;
|
||||
uniform bool inverse_enabled = true;
|
||||
uniform bool has_focus = false;
|
||||
|
||||
#ifdef BACKGROUND
|
||||
uniform vec4 background_color;
|
||||
uniform sampler2D background_colors;
|
||||
uniform sampler2D screen_texture : hint_screen_texture, repeat_disable, filter_nearest;
|
||||
#endif
|
||||
|
||||
#ifdef FOREGROUND
|
||||
uniform float blink_off_time = 0.3;
|
||||
uniform float blink_on_time = 0.6;
|
||||
#endif
|
||||
|
||||
bool has_attribute(vec2 uv, int flag) {
|
||||
int flags = int(texture(attributes, uv).r * 255.0 + 0.5);
|
||||
return (flags & flag) != 0;
|
||||
}
|
||||
|
||||
void fragment() {
|
||||
// Check if we are inside the grid.
|
||||
if (UV.x * size.x < grid_size.x && UV.y * size.y < grid_size.y) {
|
||||
vec2 grid_uv = UV * size / cell_size;
|
||||
|
||||
int cell_x = int(grid_uv.x);
|
||||
int cell_y = int(grid_uv.y);
|
||||
|
||||
vec2 sample_uv = (vec2(float(cell_x), float(cell_y)) + 0.5) / vec2(float(cols), float(rows));
|
||||
|
||||
vec4 color;
|
||||
#ifdef BACKGROUND
|
||||
color = texture(background_colors, sample_uv);
|
||||
#elif defined(FOREGROUND)
|
||||
color = texture(TEXTURE, UV);
|
||||
#endif
|
||||
|
||||
bool unfocused_cursor = !has_focus && has_attribute(sample_uv, FLAG_CURSOR);
|
||||
|
||||
#ifdef BACKGROUND
|
||||
if (has_attribute(sample_uv, FLAG_INVERSE) && inverse_enabled) {
|
||||
vec4 bg_color = textureLod(screen_texture, SCREEN_UV, 0.0);
|
||||
vec4 target_color;
|
||||
target_color.a = color.a + (1.0 - color.a) * bg_color.a;
|
||||
target_color.rgb = 1.0 / target_color.a * (color.a * color.rgb + (1.0 - color.a) * bg_color.a * bg_color.rgb);
|
||||
color = vec4(1.0 - target_color.rgb, target_color.a);
|
||||
}
|
||||
#else
|
||||
if (has_attribute(sample_uv, FLAG_INVERSE) && inverse_enabled && !unfocused_cursor) {
|
||||
color.rgb = vec3(1.0 - color.rgb);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FOREGROUND
|
||||
if (has_attribute(sample_uv, FLAG_BLINK)) {
|
||||
float blink_cycle = blink_on_time + blink_off_time;
|
||||
float current_time = mod(TIME + blink_cycle, blink_cycle); // The offset ensures blink always starts at the beginning of the ON cycle.
|
||||
if (current_time > blink_on_time) {
|
||||
color = transparent;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BACKGROUND
|
||||
if (unfocused_cursor) {
|
||||
// Draw hollow cursor when not focused.
|
||||
bool isBorderX = (UV.x * size.x - float(cell_x) * cell_size.x) < 1.0 || (float(cell_x + 1) * cell_size.x - UV.x * size.x) < 1.0;
|
||||
bool isBorderY = (UV.y * size.y - float(cell_y) * cell_size.y) < 1.0 || (float(cell_y + 1) * cell_size.y - UV.y * size.y) < 1.0;
|
||||
if (!isBorderX && !isBorderY) {
|
||||
color = transparent;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
COLOR = color;
|
||||
} else { // Outside the grid.
|
||||
COLOR = transparent;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://ceh0d3iwam1vt
|
||||
@@ -0,0 +1,5 @@
|
||||
// SPDX-FileCopyrightText: 2024 Leroy Hopson <godot-xterm@leroy.nix.nz>
|
||||
// SPDX-License-Identifier: MIT
|
||||
shader_type canvas_item;
|
||||
#define FOREGROUND
|
||||
#include "./common.gdshaderinc"
|
||||
@@ -0,0 +1 @@
|
||||
uid://dvtgnfmmhwteh
|
||||
@@ -0,0 +1,10 @@
|
||||
# This is the official list of project authors for copyright purposes.
|
||||
# This file is distinct from the CONTRIBUTORS.txt file.
|
||||
# See the latter for an explanation.
|
||||
#
|
||||
# Names should be added to this file as:
|
||||
# Name or Organization <email address>
|
||||
|
||||
JetBrains <>
|
||||
Philipp Nurullin <philipp.nurullin@jetbrains.com>
|
||||
Konstantin Bulenkov <kb@jetbrains.com>
|
||||
@@ -0,0 +1,93 @@
|
||||
Copyright 2020 The JetBrains Mono Project Authors (https://github.com/JetBrains/JetBrainsMono)
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
https://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
Binary file not shown.
@@ -0,0 +1,35 @@
|
||||
[remap]
|
||||
|
||||
importer="font_data_dynamic"
|
||||
type="FontFile"
|
||||
uid="uid://c51gnbjamppg"
|
||||
path="res://.godot/imported/jet_brains_mono_nl-regular-2.304.ttf-96fa438503371775be3cc744a4450fc2.fontdata"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/godot_xterm/themes/fonts/jet_brains_mono/jet_brains_mono_nl-regular-2.304.ttf"
|
||||
dest_files=["res://.godot/imported/jet_brains_mono_nl-regular-2.304.ttf-96fa438503371775be3cc744a4450fc2.fontdata"]
|
||||
|
||||
[params]
|
||||
|
||||
Rendering=null
|
||||
antialiasing=1
|
||||
generate_mipmaps=false
|
||||
disable_embedded_bitmaps=true
|
||||
multichannel_signed_distance_field=false
|
||||
msdf_pixel_range=8
|
||||
msdf_size=48
|
||||
allow_system_fallback=true
|
||||
force_autohinter=false
|
||||
hinting=1
|
||||
subpixel_positioning=1
|
||||
keep_rounding_remainders=true
|
||||
oversampling=0.0
|
||||
Fallbacks=null
|
||||
fallbacks=[]
|
||||
Compress=null
|
||||
compress=true
|
||||
preload=[]
|
||||
language_support={}
|
||||
script_support={}
|
||||
opentype_features={}
|
||||
@@ -0,0 +1,6 @@
|
||||
[gd_resource type="FontVariation" load_steps=2 format=3 uid="uid://vmgmcu8gc6nt"]
|
||||
|
||||
[ext_resource type="FontFile" uid="uid://c51gnbjamppg" path="res://addons/godot_xterm/themes/fonts/jet_brains_mono/jet_brains_mono_nl-regular-2.304.ttf" id="1_8kori"]
|
||||
|
||||
[resource]
|
||||
base_font = ExtResource("1_8kori")
|
||||
104
src/SharpIDE.Godot/addons/godot_xterm/util/tput.gd
Normal file
104
src/SharpIDE.Godot/addons/godot_xterm/util/tput.gd
Normal file
@@ -0,0 +1,104 @@
|
||||
extends RefCounted
|
||||
|
||||
# Control Sequence Introducer
|
||||
const CSI = "\u001b["
|
||||
|
||||
const CURSOR_UP = "\u001b[A"
|
||||
const CURSOR_DOWN = "\u001b[B"
|
||||
const CURSOR_RIGHT = "\u001b[C"
|
||||
const CURSOR_LEFT = "\u001b[D"
|
||||
|
||||
const DEFAULT_FOREGROUND_COLOR = "\u001b[0m"
|
||||
|
||||
|
||||
class ANSIColor:
|
||||
extends Object
|
||||
# Using ANSIColor constants, rather than Color will respect the
|
||||
# colors of the selected terminal theme. Whereas Color will set
|
||||
# the exact color specified regardless of theme.
|
||||
|
||||
const black = {fg = 30, panel = 40}
|
||||
const red = {fg = 31, panel = 41}
|
||||
const green = {fg = 32, panel = 42}
|
||||
const yellow = {fg = 33, panel = 43}
|
||||
const blue = {fg = 34, panel = 44}
|
||||
const magenta = {fg = 35, panel = 45}
|
||||
const cyan = {fg = 36, panel = 46}
|
||||
const white = {fg = 37, panel = 47}
|
||||
const bright_black = {fg = 90, panel = 100}
|
||||
const gray = bright_black
|
||||
const grey = bright_black
|
||||
const bright_red = {fg = 91, panel = 101}
|
||||
const bright_green = {fg = 92, panel = 102}
|
||||
const bright_yellow = {fg = 93, panel = 103}
|
||||
const bright_blue = {fg = 94, panel = 104}
|
||||
const bright_magenta = {fg = 95, panel = 105}
|
||||
const bright_cyan = {fg = 96, panel = 106}
|
||||
const bright_white = {fg = 97, panel = 107}
|
||||
|
||||
func _init():
|
||||
# "ANSIColor is an abstract class. You should only use the color constants (e.g. ANSIColor.black)."
|
||||
assert(false)
|
||||
|
||||
|
||||
var terminal
|
||||
|
||||
|
||||
func _init(p_terminal: Control):
|
||||
if p_terminal:
|
||||
terminal = p_terminal
|
||||
|
||||
|
||||
func write_string(string: String, color: Color = Color.WHITE) -> void:
|
||||
if color:
|
||||
var fg = "\u001b[38;2;%d;%d;%dm" % [color.r8, color.g8, color.b8]
|
||||
terminal.write(fg.to_utf8_buffer())
|
||||
|
||||
terminal.write(string.to_utf8_buffer())
|
||||
|
||||
# Reset color back to default.
|
||||
terminal.write("\u001b[0m".to_utf8_buffer())
|
||||
|
||||
|
||||
# tput_* functions based on the tput command.
|
||||
# See: https://man7.org/linux/man-pages/man1/tput.1.html for more info.
|
||||
|
||||
|
||||
# Hide the cursor.
|
||||
func civis():
|
||||
terminal.write("%s?25l" % CSI)
|
||||
|
||||
|
||||
# Position the cursor at the given row and col.
|
||||
func cup(row: int = 0, col: int = 0) -> void:
|
||||
terminal.write("\u001b[%d;%dH" % [row, col])
|
||||
|
||||
|
||||
func setaf(color) -> void:
|
||||
if color is Color:
|
||||
terminal.write("\u001b[38;2;%d;%d;%dm" % [color.r8, color.g8, color.b8])
|
||||
elif "fg" in color and color.fg is int:
|
||||
terminal.write("\u001b[%dm" % color.fg)
|
||||
else:
|
||||
push_error("Invalid color: %s" % color)
|
||||
|
||||
|
||||
func setab(color) -> void:
|
||||
if color is Color:
|
||||
terminal.write("\u001b[48;2;%d;%d;%dm" % [color.r8, color.g8, color.b8])
|
||||
elif "panel" in color and color.panel is int:
|
||||
terminal.write("\u001b[%dm" % color.panel)
|
||||
else:
|
||||
push_error("Invalid color: %s" % color)
|
||||
|
||||
|
||||
func rev() -> void:
|
||||
terminal.write("\u001b[7m")
|
||||
|
||||
|
||||
func sgr0() -> void:
|
||||
terminal.write("\u001b[0m")
|
||||
|
||||
|
||||
func reset() -> void:
|
||||
terminal.write("\u001bc")
|
||||
1
src/SharpIDE.Godot/addons/godot_xterm/util/tput.gd.uid
Normal file
1
src/SharpIDE.Godot/addons/godot_xterm/util/tput.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://dud4ii1gy5sa
|
||||
Reference in New Issue
Block a user