From 06a0ec28eb861fa5dff49e83d88ca519f420f554 Mon Sep 17 00:00:00 2001 From: Devin Bidwell Date: Mon, 22 Dec 2025 17:45:42 -0700 Subject: [PATCH 1/8] Modify IC10 view logic to conform to the new IC10Editor update --- csharp_mod/Formatter.cs | 57 +++++++++++++++++----------------------- rust_compiler/Cargo.lock | 2 +- 2 files changed, 25 insertions(+), 34 deletions(-) diff --git a/csharp_mod/Formatter.cs b/csharp_mod/Formatter.cs index 79cdbd8..24ba823 100644 --- a/csharp_mod/Formatter.cs +++ b/csharp_mod/Formatter.cs @@ -12,6 +12,8 @@ using UnityEngine; public class SlangFormatter : ICodeFormatter { + protected static Editor? Ic10Editor = null; + private CancellationTokenSource? _lspCancellationToken; private object _tokenLock = new(); @@ -78,34 +80,6 @@ public class SlangFormatter : ICodeFormatter return this.Lines.RawText; } - public override void DrawLine(int lineIndex, TextRange selection, bool drawLineNumber = true) - { - Vector2 cursorPos = ImGui.GetCursorScreenPos(); - Vector2 space = ImGui.GetContentRegionAvail(); - base.DrawLine(lineIndex, selection, drawLineNumber); - - var charWidth = Settings.CharWidth; - - var width = Mathf.Max(Lines.Width + 10.0f + LineNumberOffset * charWidth, space.x / 2); - - ImGui - .GetWindowDrawList() - .AddLine( - new Vector2(cursorPos.x + width + 4.5f * charWidth, cursorPos.y), - new Vector2( - cursorPos.x + width + 4.5f * charWidth, - cursorPos.y + space.y + Settings.LineHeight - ), - ColorLineNumber, - 1.0f - ); - - cursorPos.x += width; - ImGui.SetCursorScreenPos(cursorPos); - if (lineIndex < iC10CodeFormatter.Lines.Count) - iC10CodeFormatter.DrawLine(lineIndex, new TextRange(), true); - } - public override StyledLine ParseLine(string line) { // We create the line first @@ -186,7 +160,15 @@ public class SlangFormatter : ICodeFormatter { ic10CompilationResult = compiled; ic10SourceMap = sourceMap; - UpdateIc10Formatter(); + try + { + UpdateIc10Formatter(); + } + catch (Exception ex) + { + L.Error(ex.Message); + L.Error(ex.StackTrace); + } } } catch (OperationCanceledException) { } @@ -198,7 +180,16 @@ public class SlangFormatter : ICodeFormatter private void UpdateIc10Formatter() { - iC10CodeFormatter.Editor = Editor; + if (Ic10Editor is null) + { + var tab = Editor.ParentTab; + iC10CodeFormatter = new IC10CodeFormatter(); + Ic10Editor = new Editor(Editor.KeyHandler); + Ic10Editor.IsReadOnly = true; + iC10CodeFormatter.Editor = Ic10Editor; + tab.AddEditor(Ic10Editor); + } + var caretPos = Editor.CaretPos.Line; // get the slang sourceMap at the current editor line @@ -210,7 +201,7 @@ public class SlangFormatter : ICodeFormatter // should be directly next to the compiled IC10 source line, and we should highlight the // IC10 code that directly represents the Slang source - iC10CodeFormatter.ResetCode(ic10CompilationResult); + Ic10Editor.ResetCode(ic10CompilationResult); if (lines.Count() < 1) { @@ -223,7 +214,7 @@ public class SlangFormatter : ICodeFormatter // highlight all the IC10 lines that are within the specified range foreach (var index in Enumerable.Range((int)min, (int)(max - min) + 1)) { - var lineText = iC10CodeFormatter.Lines[index].Text; + var lineText = Ic10Editor.Lines[index].Text; var newLine = new StyledLine( lineText, @@ -239,7 +230,7 @@ public class SlangFormatter : ICodeFormatter ] ); - iC10CodeFormatter.Lines[index] = newLine; + Ic10Editor.Lines[index] = newLine; } } diff --git a/rust_compiler/Cargo.lock b/rust_compiler/Cargo.lock index b13e2ce..87e36d8 100644 --- a/rust_compiler/Cargo.lock +++ b/rust_compiler/Cargo.lock @@ -930,7 +930,7 @@ checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" [[package]] name = "slang" -version = "0.4.0" +version = "0.4.1" dependencies = [ "anyhow", "clap", -- 2.49.1 From 5230c620e8d0f75b85ece698bc8a805021d5f874 Mon Sep 17 00:00:00 2001 From: Devin Bidwell Date: Tue, 23 Dec 2025 20:32:27 -0700 Subject: [PATCH 2/8] WIP -- before another refactor --- csharp_mod/Formatter.cs | 19 ++++--------------- csharp_mod/GlobalCode.cs | 41 +++------------------------------------- 2 files changed, 7 insertions(+), 53 deletions(-) diff --git a/csharp_mod/Formatter.cs b/csharp_mod/Formatter.cs index 24ba823..486ca5f 100644 --- a/csharp_mod/Formatter.cs +++ b/csharp_mod/Formatter.cs @@ -12,16 +12,15 @@ using UnityEngine; public class SlangFormatter : ICodeFormatter { - protected static Editor? Ic10Editor = null; - private CancellationTokenSource? _lspCancellationToken; private object _tokenLock = new(); + protected static Editor? Ic10Editor = null; private IC10CodeFormatter iC10CodeFormatter = new IC10CodeFormatter(); private string ic10CompilationResult = ""; private List ic10SourceMap = new(); - // VS Code Dark Theme Palette + #region Colors public static readonly uint ColorControl = ColorFromHTML("#C586C0"); // Pink (if, return, loop) public static readonly uint ColorDeclaration = ColorFromHTML("#569CD6"); // Blue (let, device, fn) public static readonly uint ColorFunction = ColorFromHTML("#DCDCAA"); // Yellow (syscalls) @@ -30,10 +29,8 @@ public class SlangFormatter : ICodeFormatter public static readonly uint ColorBoolean = ColorFromHTML("#569CD6"); // Blue (true/false) public static readonly uint ColorIdentifier = ColorFromHTML("#9CDCFE"); // Light Blue (variables) public static new readonly uint ColorDefault = ColorFromHTML("#D4D4D4"); // White (punctuation ; { } ) - - // Operators are often the same color as default text in VS Code Dark, - // but having a separate definition lets you tweak it (e.g. make them slightly darker or distinct) public static readonly uint ColorOperator = ColorFromHTML("#D4D4D4"); + #endregion private HashSet _linesWithErrors = new(); private int _lastLineCount = -1; @@ -160,15 +157,7 @@ public class SlangFormatter : ICodeFormatter { ic10CompilationResult = compiled; ic10SourceMap = sourceMap; - try - { - UpdateIc10Formatter(); - } - catch (Exception ex) - { - L.Error(ex.Message); - L.Error(ex.StackTrace); - } + UpdateIc10Formatter(); } } catch (OperationCanceledException) { } diff --git a/csharp_mod/GlobalCode.cs b/csharp_mod/GlobalCode.cs index 88286df..786c5ce 100644 --- a/csharp_mod/GlobalCode.cs +++ b/csharp_mod/GlobalCode.cs @@ -1,15 +1,12 @@ using System; using System.Collections.Generic; -using System.IO; -using System.IO.Compression; -using System.Text; namespace Slang; public static class GlobalCode { public const string SLANG_REF = "#SLANG_REF:"; - public const string SLANG_SRC = "#SLANG_SRC:"; + public const string SLANG_SRC = "SLANG_SRC"; // This is a Dictionary of ENCODED source code, compressed // so that save file data is smaller @@ -110,43 +107,11 @@ public static class GlobalCode private static string EncodeSource(string source) { - if (string.IsNullOrEmpty(source)) - { - return ""; - } - - byte[] bytes = Encoding.UTF8.GetBytes(source); - - using (var memoryStream = new MemoryStream()) - { - using (var gzipStream = new GZipStream(memoryStream, CompressionMode.Compress)) - { - gzipStream.Write(bytes, 0, bytes.Length); - } - return Convert.ToBase64String(memoryStream.ToArray()); - } + return SlangFormatter.EncodeSource(source, SLANG_SRC); } private static string DecodeSource(string source) { - if (string.IsNullOrEmpty(source)) - { - return ""; - } - - byte[] compressedBytes = Convert.FromBase64String(source); - - using (var memoryStream = new MemoryStream(compressedBytes)) - { - using (var gzipStream = new GZipStream(memoryStream, CompressionMode.Decompress)) - { - using (var outputStream = new MemoryStream()) - { - gzipStream.CopyTo(outputStream); - - return Encoding.UTF8.GetString(outputStream.ToArray()); - } - } - } + return SlangFormatter.DecodeSource(source, SLANG_SRC); } } -- 2.49.1 From 42b0b0acf9196c31327b9faa85d4781535c379c4 Mon Sep 17 00:00:00 2001 From: Devin Bidwell Date: Wed, 24 Dec 2025 01:24:16 -0700 Subject: [PATCH 3/8] Working saving / loading from the IC10Editor mod. Removed all patches until they can be properly re-implemented --- Changelog.md | 9 + ModData/About/About.xml | 4 +- csharp_mod/Formatter.cs | 31 ++- csharp_mod/GlobalCode.cs | 73 ++---- csharp_mod/Patches.cs | 362 ----------------------------- csharp_mod/Plugin.cs | 2 +- csharp_mod/stationeersSlang.csproj | 2 +- rust_compiler/Cargo.lock | 2 +- rust_compiler/Cargo.toml | 2 +- 9 files changed, 57 insertions(+), 430 deletions(-) delete mode 100644 csharp_mod/Patches.cs diff --git a/Changelog.md b/Changelog.md index 87dc8b5..734956c 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,14 @@ # Changelog +[0.4.2] + +- Removed all harmony patches as most functionality as been added into the + `IC10 Editor` mod +- IC10 runtime errors will have been reverted back to showing as IC10 line + numbers instead of Slang line numbers. + - The IC10 line should be easily mapped to a Slang line via the side-by-side + IC10 compilation view. + [0.4.1] - Update syscalls for `loadSlot` and `setSlot` to support expressions instead of diff --git a/ModData/About/About.xml b/ModData/About/About.xml index 2a468d3..a79e411 100644 --- a/ModData/About/About.xml +++ b/ModData/About/About.xml @@ -2,7 +2,7 @@ Slang JoeDiertay - 0.4.1 + 0.4.2 [h1]Slang: High-Level Programming for Stationeers[/h1] @@ -86,7 +86,7 @@ A: Yes! Slang does not modify any existing IC10 code, it is only a compiler. As Quality of Life - + Slang - High Level Language Compiler A modern programming experience for Stationeers. Write C-style code that compiles to IC10 instantly. diff --git a/csharp_mod/Formatter.cs b/csharp_mod/Formatter.cs index 486ca5f..16f81fc 100644 --- a/csharp_mod/Formatter.cs +++ b/csharp_mod/Formatter.cs @@ -5,13 +5,12 @@ using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; -using ImGuiNET; using StationeersIC10Editor; using StationeersIC10Editor.IC10; -using UnityEngine; public class SlangFormatter : ICodeFormatter { + public const string SLANG_SRC = "SLANG_SRC"; private CancellationTokenSource? _lspCancellationToken; private object _tokenLock = new(); @@ -48,6 +47,11 @@ public class SlangFormatter : ICodeFormatter if (string.IsNullOrWhiteSpace(input)) return 0d; + if (input.Contains(SLANG_SRC)) + { + return 1.0; + } + // Run the compiler to get diagnostics var diagnostics = Marshal.DiagnoseSource(input); @@ -74,7 +78,28 @@ public class SlangFormatter : ICodeFormatter public override string Compile() { - return this.Lines.RawText; + if (!Marshal.CompileFromString(RawText, out var compilationResult, out var sourceMap)) + { + return "Compilation Error"; + } + + return compilationResult + $"\n{EncodeSource(RawText, SLANG_SRC)}"; + } + + public override void ResetCode(string code) + { + // for compatibility, we need to check for GlobalCode.SLANG_SRC + // `#SLANG_SRC:` + // and replace with `# SLANG_SRC: ` + if (code.Contains(GlobalCode.SLANG_SRC)) + { + code = code.Replace(GlobalCode.SLANG_SRC, $"# {SLANG_SRC}: "); + } + if (code.Contains(SLANG_SRC)) + { + code = ExtractEncodedSource(code, SLANG_SRC); + } + base.ResetCode(code); } public override StyledLine ParseLine(string line) diff --git a/csharp_mod/GlobalCode.cs b/csharp_mod/GlobalCode.cs index 786c5ce..bb00095 100644 --- a/csharp_mod/GlobalCode.cs +++ b/csharp_mod/GlobalCode.cs @@ -1,27 +1,27 @@ using System; using System.Collections.Generic; +using System.IO; +using System.IO.Compression; +using System.Text; namespace Slang; public static class GlobalCode { - public const string SLANG_REF = "#SLANG_REF:"; - public const string SLANG_SRC = "SLANG_SRC"; + /// + /// This is the OLD way of handling saving / loading. This has been replaced with a native + /// save / load from IC10 Editor. However; this needs to remain for compatibility with + /// previous versions of code not compiled with 0.4.2 or later. + /// + public const string SLANG_SRC = "#SLANG_SRC:"; - // This is a Dictionary of ENCODED source code, compressed - // so that save file data is smaller - private static Dictionary codeDict = new(); - - // This Dictionary stores the source maps for the given SLANG_REF, where - // the key is the IC10 line, and the value is a List of Slang ranges where that - // line would have come from + /// + /// This Dictionary stores the source maps for the given SLANG_REF, where + /// the key is the IC10 line, and the value is a List of Slang ranges where that + /// line would have come from + /// private static Dictionary>> sourceMaps = new(); - public static void ClearCache() - { - codeDict.Clear(); - } - public static void SetSourceMap(Guid reference, List sourceMapEntries) { var builtDictionary = new Dictionary>(); @@ -69,49 +69,4 @@ public static class GlobalCode slangSpan = foundRange[0]; return true; } - - public static string GetSource(Guid reference) - { - if (!codeDict.ContainsKey(reference)) - { - return string.Empty; - } - - return DecodeSource(codeDict[reference]); - } - - public static void SetSource(Guid reference, string source) - { - codeDict[reference] = EncodeSource(source); - } - - public static string? GetEncoded(Guid reference) - { - if (!codeDict.ContainsKey(reference)) - return null; - - return codeDict[reference]; - } - - public static void SetEncoded(Guid reference, string encodedSource) - { - if (codeDict.ContainsKey(reference)) - { - codeDict[reference] = encodedSource; - } - else - { - codeDict.Add(reference, encodedSource); - } - } - - private static string EncodeSource(string source) - { - return SlangFormatter.EncodeSource(source, SLANG_SRC); - } - - private static string DecodeSource(string source) - { - return SlangFormatter.DecodeSource(source, SLANG_SRC); - } } diff --git a/csharp_mod/Patches.cs b/csharp_mod/Patches.cs deleted file mode 100644 index 12fb8a2..0000000 --- a/csharp_mod/Patches.cs +++ /dev/null @@ -1,362 +0,0 @@ -namespace Slang; - -using System; -using System.Runtime.CompilerServices; -using Assets.Scripts.Objects; -using Assets.Scripts.Objects.Electrical; -using Assets.Scripts.Objects.Motherboards; -using Assets.Scripts.UI; -using HarmonyLib; - -class LineErrorData -{ - public AsciiString SourceRef; - public uint IC10ErrorSource; - public string SlangErrorReference; - public Range SlangErrorSpan; - - public LineErrorData( - AsciiString sourceRef, - uint ic10ErrorSource, - string slangErrorRef, - Range slangErrorSpan - ) - { - this.SourceRef = sourceRef; - this.IC10ErrorSource = ic10ErrorSource; - this.SlangErrorReference = slangErrorRef; - this.SlangErrorSpan = slangErrorSpan; - } -} - -[HarmonyPatch] -public static class SlangPatches -{ - private static ProgrammableChipMotherboard? _currentlyEditingMotherboard; - private static AsciiString? _motherboardCachedCode; - private static Guid? _currentlyEditingGuid; - - private static ConditionalWeakTable _errorReferenceTable = - new(); - - [HarmonyPatch( - typeof(ProgrammableChipMotherboard), - nameof(ProgrammableChipMotherboard.InputFinished) - )] - [HarmonyPrefix] - public static void pgmb_InputFinished(ref string result) - { - _currentlyEditingMotherboard = null; - _motherboardCachedCode = null; - // guard to ensure we have valid IC10 before continuing - if ( - !SlangPlugin.IsSlangSource(ref result) - || !Marshal.CompileFromString(result, out var compiled, out var sourceMap) - || string.IsNullOrEmpty(compiled) - ) - { - return; - } - - var thisRef = _currentlyEditingGuid ?? Guid.NewGuid(); - - // Ensure we cache this compiled code for later retreival. - GlobalCode.SetSource(thisRef, result); - GlobalCode.SetSourceMap(thisRef, sourceMap); - - _currentlyEditingGuid = null; - - // Append REF to the bottom - compiled += $"\n{GlobalCode.SLANG_REF}{thisRef}"; - result = compiled; - } - - [HarmonyPatch(typeof(ProgrammableChipMotherboard), nameof(ProgrammableChipMotherboard.OnEdit))] - [HarmonyPrefix] - public static void isc_OnEdit(ProgrammableChipMotherboard __instance) - { - _currentlyEditingMotherboard = __instance; - _motherboardCachedCode = __instance.GetSourceCode(); - var sourceCode = System.Text.Encoding.UTF8.GetString( - System.Text.Encoding.ASCII.GetBytes(__instance.GetSourceCode()) - ); - - if (string.IsNullOrEmpty(sourceCode)) - { - return; - } - - // Look for REF at the bottom - var tagIndex = sourceCode.LastIndexOf(GlobalCode.SLANG_REF); - - if (tagIndex == -1) - { - // this is not slang managed code - return; - } - - if ( - !Guid.TryParse( - sourceCode.Substring(tagIndex + GlobalCode.SLANG_REF.Length).Trim(), - out Guid sourceRef - ) - ) - { - // not a valid Guid, not managed by slang - return; - } - - _currentlyEditingGuid = sourceRef; - var slangSource = GlobalCode.GetSource(sourceRef); - - if (string.IsNullOrEmpty(slangSource)) - { - // Didn't find that source ref in the global code manager. - return; - } - - __instance.SetSourceCode(slangSource); - } - - private static void HandleSerialization(ref string sourceCode) - { - if (string.IsNullOrEmpty(sourceCode)) - return; - - // Check if the file ends with the Reference Tag - var tagIndex = sourceCode.LastIndexOf(GlobalCode.SLANG_REF); - - if (tagIndex == -1) - return; - - string guidString = sourceCode.Substring(tagIndex + GlobalCode.SLANG_REF.Length).Trim(); - - if (!Guid.TryParse(guidString, out Guid slangRefGuid)) - { - L.Warning($"Found SLANG_REF but failed to parse GUID: {guidString}"); - return; - } - - var slangEncoded = GlobalCode.GetEncoded(slangRefGuid); - - if (string.IsNullOrEmpty(slangEncoded)) - { - L.Warning( - $"Could not find encoded source for ref {slangRefGuid}. Save will contain compiled IC10 only." - ); - return; - } - - // Extract the clean IC10 code (everything before the tag) - var cleanIc10 = sourceCode.Substring(0, tagIndex).TrimEnd(); - - // Append the encoded source tag to the bottom - sourceCode = $"{cleanIc10}\n{GlobalCode.SLANG_SRC}{slangEncoded}"; - } - - [HarmonyPatch(typeof(ProgrammableChip), nameof(ProgrammableChip.SerializeSave))] - [HarmonyPostfix] - public static void pgc_SerializeSave(ProgrammableChip __instance, ref ThingSaveData __result) - { - if (__result is not ProgrammableChipSaveData chipData) - return; - - string code = chipData.SourceCode; - HandleSerialization(ref code); - chipData.SourceCode = code; - } - - [HarmonyPatch( - typeof(ProgrammableChip), - nameof(ProgrammableChip.ErrorLineNumberString), - MethodType.Getter - )] - [HarmonyPostfix] - public static void pgc_ErrorLineNumberString(ProgrammableChip __instance, ref string __result) - { - if ( - String.IsNullOrEmpty(__result) - || !uint.TryParse(__result.Trim(), out var ic10ErrorLineNumber) - ) - { - return; - } - - var sourceAscii = __instance.GetSourceCode(); - - if (_errorReferenceTable.TryGetValue(__instance, out var cache)) - { - if (cache.SourceRef.Equals(sourceAscii) && cache.IC10ErrorSource == ic10ErrorLineNumber) - { - __result = cache.SlangErrorReference; - return; - } - } - - var source = System.Text.Encoding.UTF8.GetString( - System.Text.Encoding.ASCII.GetBytes(__instance.GetSourceCode()) - ); - - var slangIndex = source.LastIndexOf(GlobalCode.SLANG_REF); - - if ( - slangIndex < 0 - || !Guid.TryParse( - source - .Substring( - source.LastIndexOf(GlobalCode.SLANG_REF) + GlobalCode.SLANG_REF.Length - ) - .Trim(), - out var slangGuid - ) - || !GlobalCode.GetSlangErrorLineFromICError( - slangGuid, - ic10ErrorLineNumber, - out var slangErrorLineNumber, - out var slangSpan - ) - ) - { - return; - } - - L.Warning($"IC error at: {__result} -- Slang source error line: {slangErrorLineNumber}"); - __result = slangErrorLineNumber.ToString(); - _errorReferenceTable.Remove(__instance); - _errorReferenceTable.Add( - __instance, - new LineErrorData( - sourceAscii, - ic10ErrorLineNumber, - slangErrorLineNumber.ToString(), - slangSpan - ) - ); - } - - [HarmonyPatch( - typeof(ProgrammableChip), - nameof(ProgrammableChip.SetSourceCode), - new Type[] { typeof(string) } - )] - [HarmonyPostfix] - public static void pgc_SetSourceCode_string(ProgrammableChip __instance, string sourceCode) - { - _errorReferenceTable.Remove(__instance); - } - - [HarmonyPatch( - typeof(ProgrammableChip), - nameof(ProgrammableChip.SetSourceCode), - new Type[] { typeof(string), typeof(ICircuitHolder) } - )] - [HarmonyPostfix] - public static void pgc_SetSourceCode_string_parent( - ProgrammableChip __instance, - string sourceCode, - ICircuitHolder parent - ) - { - _errorReferenceTable.Remove(__instance); - } - - [HarmonyPatch( - typeof(ProgrammableChipMotherboard), - nameof(ProgrammableChipMotherboard.SerializeSave) - )] - [HarmonyPostfix] - public static void pgmb_SerializeSave( - ProgrammableChipMotherboard __instance, - ref ThingSaveData __result - ) - { - if (__result is not ProgrammableChipMotherboardSaveData chipData) - return; - - string code = chipData.SourceCode; - HandleSerialization(ref code); - chipData.SourceCode = code; - } - - private static void HandleDeserialization(ref string sourceCode) - { - // Safety check for null/empty code - if (string.IsNullOrEmpty(sourceCode)) - return; - - // Check for the #SLANG_SRC: footer - int tagIndex = sourceCode.LastIndexOf(GlobalCode.SLANG_SRC); - - // If the tag is missing, this is just a normal IC10 script. Do nothing. - if (tagIndex == -1) - return; - - // Extract the Encoded Source (Base64) - string encodedSource = sourceCode.Substring(tagIndex + GlobalCode.SLANG_SRC.Length).Trim(); - - // Extract the IC10 Code (strip off the tag and the newline before it) - string ic10Code = sourceCode.Substring(0, tagIndex).TrimEnd(); - - // Generate a new Runtime GUID for this session - Guid runtimeGuid = Guid.NewGuid(); - - // Hydrate the Cache - GlobalCode.SetEncoded(runtimeGuid, encodedSource); - - // Rewrite the SourceCode to the "Runtime" format (REF at bottom) - sourceCode = $"{ic10Code}\n{GlobalCode.SLANG_REF}{runtimeGuid}"; - } - - [HarmonyPatch(typeof(ProgrammableChip), nameof(ProgrammableChip.DeserializeSave))] - [HarmonyPrefix] - public static void pgc_DeserializeSave(ref ThingSaveData savedData) - { - if (savedData is not ProgrammableChipSaveData pcSaveData) - return; - - string code = pcSaveData.SourceCode; - HandleDeserialization(ref code); - pcSaveData.SourceCode = code; - } - - [HarmonyPatch( - typeof(ProgrammableChipMotherboard), - nameof(ProgrammableChipMotherboard.DeserializeSave) - )] - [HarmonyPrefix] - public static void pgmb_DeserializeSave(ref ThingSaveData savedData) - { - if (savedData is not ProgrammableChipMotherboardSaveData pcSaveData) - return; - - string code = pcSaveData.SourceCode; - HandleDeserialization(ref code); - pcSaveData.SourceCode = code; - } - - [HarmonyPatch(typeof(InputSourceCode), nameof(InputSourceCode.ButtonInputCancel))] - [HarmonyPrefix] - public static void isc_ButtonInputCancel() - { - if (_currentlyEditingMotherboard is null || _motherboardCachedCode is null) - { - return; - } - - _currentlyEditingMotherboard.SetSourceCode(_motherboardCachedCode); - - _currentlyEditingMotherboard = null; - _motherboardCachedCode = null; - _currentlyEditingGuid = null; - } - - [HarmonyPatch(typeof(Stationpedia), nameof(Stationpedia.Regenerate))] - [HarmonyPostfix] - public static void Stationpedia_Regenerate() - { - foreach (var page in Marshal.GetSlangDocs()) - { - Stationpedia.Register(page); - } - } -} diff --git a/csharp_mod/Plugin.cs b/csharp_mod/Plugin.cs index 84d3d35..37e50f1 100644 --- a/csharp_mod/Plugin.cs +++ b/csharp_mod/Plugin.cs @@ -41,7 +41,7 @@ namespace Slang { public const string PluginGuid = "com.biddydev.slang"; public const string PluginName = "Slang"; - public const string PluginVersion = "0.4.1"; + public const string PluginVersion = "0.4.2"; public static Mod MOD = new Mod(PluginName, PluginVersion); diff --git a/csharp_mod/stationeersSlang.csproj b/csharp_mod/stationeersSlang.csproj index e7aba92..f62a17e 100644 --- a/csharp_mod/stationeersSlang.csproj +++ b/csharp_mod/stationeersSlang.csproj @@ -5,7 +5,7 @@ enable StationeersSlang Slang Compiler Bridge - 0.4.0 + 0.4.2 true latest diff --git a/rust_compiler/Cargo.lock b/rust_compiler/Cargo.lock index 87e36d8..34712a0 100644 --- a/rust_compiler/Cargo.lock +++ b/rust_compiler/Cargo.lock @@ -930,7 +930,7 @@ checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" [[package]] name = "slang" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "clap", diff --git a/rust_compiler/Cargo.toml b/rust_compiler/Cargo.toml index f6a1882..99ef668 100644 --- a/rust_compiler/Cargo.toml +++ b/rust_compiler/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "slang" -version = "0.4.1" +version = "0.4.2" edition = "2021" [workspace] -- 2.49.1 From c7aa30581d0bf816b91653660716fef2d18834fb Mon Sep 17 00:00:00 2001 From: Devin Bidwell Date: Wed, 24 Dec 2025 11:10:10 -0700 Subject: [PATCH 4/8] Added logging around the creation of the IC10Editor tab --- csharp_mod/Formatter.cs | 14 +++++++++++--- csharp_mod/GlobalCode.cs | 3 --- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/csharp_mod/Formatter.cs b/csharp_mod/Formatter.cs index 16f81fc..334403a 100644 --- a/csharp_mod/Formatter.cs +++ b/csharp_mod/Formatter.cs @@ -14,7 +14,7 @@ public class SlangFormatter : ICodeFormatter private CancellationTokenSource? _lspCancellationToken; private object _tokenLock = new(); - protected static Editor? Ic10Editor = null; + protected Editor? Ic10Editor = null; private IC10CodeFormatter iC10CodeFormatter = new IC10CodeFormatter(); private string ic10CompilationResult = ""; private List ic10SourceMap = new(); @@ -37,6 +37,7 @@ public class SlangFormatter : ICodeFormatter public SlangFormatter() : base() { + L.Info("Slang Constructor"); OnCodeChanged += HandleCodeChanged; OnCaretMoved += UpdateIc10Formatter; } @@ -194,13 +195,20 @@ public class SlangFormatter : ICodeFormatter private void UpdateIc10Formatter() { - if (Ic10Editor is null) + var tab = Editor.ParentTab; + if (Ic10Editor == null) { - var tab = Editor.ParentTab; + L.Info("Ic10Editor was null"); iC10CodeFormatter = new IC10CodeFormatter(); Ic10Editor = new Editor(Editor.KeyHandler); Ic10Editor.IsReadOnly = true; iC10CodeFormatter.Editor = Ic10Editor; + tab.ClearExtraEditors(); + } + + if (tab.Editors.Count < 2) + { + L.Info("Adding new editor tab"); tab.AddEditor(Ic10Editor); } diff --git a/csharp_mod/GlobalCode.cs b/csharp_mod/GlobalCode.cs index bb00095..bbe5f08 100644 --- a/csharp_mod/GlobalCode.cs +++ b/csharp_mod/GlobalCode.cs @@ -1,8 +1,5 @@ using System; using System.Collections.Generic; -using System.IO; -using System.IO.Compression; -using System.Text; namespace Slang; -- 2.49.1 From 445f731170905c24edd72b773d0d3e0eed61c7fc Mon Sep 17 00:00:00 2001 From: Devin Bidwell Date: Wed, 24 Dec 2025 12:08:17 -0700 Subject: [PATCH 5/8] Fixed IC10 ouput window, refactored IC10 highlighting --- csharp_mod/Formatter.cs | 27 +++++++-------------------- 1 file changed, 7 insertions(+), 20 deletions(-) diff --git a/csharp_mod/Formatter.cs b/csharp_mod/Formatter.cs index 334403a..c07af8d 100644 --- a/csharp_mod/Formatter.cs +++ b/csharp_mod/Formatter.cs @@ -203,7 +203,6 @@ public class SlangFormatter : ICodeFormatter Ic10Editor = new Editor(Editor.KeyHandler); Ic10Editor.IsReadOnly = true; iC10CodeFormatter.Editor = Ic10Editor; - tab.ClearExtraEditors(); } if (tab.Editors.Count < 2) @@ -233,27 +232,15 @@ public class SlangFormatter : ICodeFormatter var max = lines.Max(line => line.Ic10Line); var min = lines.Min(line => line.Ic10Line); + Ic10Editor.CaretPos = new TextPosition { Col = 0, Line = (int)max }; + // highlight all the IC10 lines that are within the specified range - foreach (var index in Enumerable.Range((int)min, (int)(max - min) + 1)) + Ic10Editor.Selection.Start = new TextPosition { Col = 0, Line = (int)min }; + Ic10Editor.Selection.End = new TextPosition { - var lineText = Ic10Editor.Lines[index].Text; - - var newLine = new StyledLine( - lineText, - [ - new SemanticToken - { - Column = 0, - Length = lineText.Length, - Line = index, - Background = ColorIdentifier, - Color = ColorFromHTML("black"), - }, - ] - ); - - Ic10Editor.Lines[index] = newLine; - } + Col = Ic10Editor.Lines[(int)max].Text.Length, + Line = (int)max, + }; } // This runs on the Main Thread -- 2.49.1 From 47bcd0be34acaf6737534179408bce391e963393 Mon Sep 17 00:00:00 2001 From: Devin Bidwell Date: Wed, 24 Dec 2025 12:10:11 -0700 Subject: [PATCH 6/8] Cleaned up BepInEx logging --- csharp_mod/Formatter.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/csharp_mod/Formatter.cs b/csharp_mod/Formatter.cs index c07af8d..a7a0532 100644 --- a/csharp_mod/Formatter.cs +++ b/csharp_mod/Formatter.cs @@ -37,7 +37,6 @@ public class SlangFormatter : ICodeFormatter public SlangFormatter() : base() { - L.Info("Slang Constructor"); OnCodeChanged += HandleCodeChanged; OnCaretMoved += UpdateIc10Formatter; } @@ -198,7 +197,6 @@ public class SlangFormatter : ICodeFormatter var tab = Editor.ParentTab; if (Ic10Editor == null) { - L.Info("Ic10Editor was null"); iC10CodeFormatter = new IC10CodeFormatter(); Ic10Editor = new Editor(Editor.KeyHandler); Ic10Editor.IsReadOnly = true; @@ -207,7 +205,6 @@ public class SlangFormatter : ICodeFormatter if (tab.Editors.Count < 2) { - L.Info("Adding new editor tab"); tab.AddEditor(Ic10Editor); } -- 2.49.1 From 1c39e146fbb259466c4765b07a2b9f3196df7544 Mon Sep 17 00:00:00 2001 From: Devin Bidwell Date: Wed, 24 Dec 2025 12:36:33 -0700 Subject: [PATCH 7/8] Clear editor selection for IC10 if no slang source maps to an IC10 source --- csharp_mod/Formatter.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/csharp_mod/Formatter.cs b/csharp_mod/Formatter.cs index a7a0532..890b79c 100644 --- a/csharp_mod/Formatter.cs +++ b/csharp_mod/Formatter.cs @@ -223,6 +223,11 @@ public class SlangFormatter : ICodeFormatter if (lines.Count() < 1) { + Ic10Editor.Selection = new TextRange + { + End = new TextPosition { Col = 0, Line = 0 }, + Start = new TextPosition { Col = 0, Line = 0 }, + }; return; } // get the total range of the IC10 source for the selected Slang line -- 2.49.1 From 792bba4875c9f2c50850453e284cf83b6c2504e0 Mon Sep 17 00:00:00 2001 From: Devin Bidwell Date: Wed, 24 Dec 2025 12:39:21 -0700 Subject: [PATCH 8/8] Removed unused macro imports as they are implicit --- rust_compiler/libs/compiler/src/test/binary_expression.rs | 1 - rust_compiler/libs/compiler/src/test/branching.rs | 1 - .../libs/compiler/src/test/declaration_function_invocation.rs | 1 - rust_compiler/libs/compiler/src/test/logic_expression.rs | 1 - rust_compiler/libs/compiler/src/test/loops.rs | 1 - rust_compiler/libs/compiler/src/test/math_syscall.rs | 1 - rust_compiler/libs/compiler/src/test/syscall.rs | 1 - 7 files changed, 7 deletions(-) diff --git a/rust_compiler/libs/compiler/src/test/binary_expression.rs b/rust_compiler/libs/compiler/src/test/binary_expression.rs index 5effd99..e4aebef 100644 --- a/rust_compiler/libs/compiler/src/test/binary_expression.rs +++ b/rust_compiler/libs/compiler/src/test/binary_expression.rs @@ -1,4 +1,3 @@ -use crate::compile; use anyhow::Result; use indoc::indoc; use pretty_assertions::assert_eq; diff --git a/rust_compiler/libs/compiler/src/test/branching.rs b/rust_compiler/libs/compiler/src/test/branching.rs index 92f876b..9addbe7 100644 --- a/rust_compiler/libs/compiler/src/test/branching.rs +++ b/rust_compiler/libs/compiler/src/test/branching.rs @@ -1,4 +1,3 @@ -use crate::compile; use indoc::indoc; use pretty_assertions::assert_eq; diff --git a/rust_compiler/libs/compiler/src/test/declaration_function_invocation.rs b/rust_compiler/libs/compiler/src/test/declaration_function_invocation.rs index aa797bb..adfcdfd 100644 --- a/rust_compiler/libs/compiler/src/test/declaration_function_invocation.rs +++ b/rust_compiler/libs/compiler/src/test/declaration_function_invocation.rs @@ -1,4 +1,3 @@ -use crate::compile; use indoc::indoc; use pretty_assertions::assert_eq; diff --git a/rust_compiler/libs/compiler/src/test/logic_expression.rs b/rust_compiler/libs/compiler/src/test/logic_expression.rs index df77bd5..b7699ea 100644 --- a/rust_compiler/libs/compiler/src/test/logic_expression.rs +++ b/rust_compiler/libs/compiler/src/test/logic_expression.rs @@ -1,4 +1,3 @@ -use crate::compile; use indoc::indoc; use pretty_assertions::assert_eq; diff --git a/rust_compiler/libs/compiler/src/test/loops.rs b/rust_compiler/libs/compiler/src/test/loops.rs index b803354..63ce5d9 100644 --- a/rust_compiler/libs/compiler/src/test/loops.rs +++ b/rust_compiler/libs/compiler/src/test/loops.rs @@ -1,4 +1,3 @@ -use crate::compile; use indoc::indoc; use pretty_assertions::assert_eq; diff --git a/rust_compiler/libs/compiler/src/test/math_syscall.rs b/rust_compiler/libs/compiler/src/test/math_syscall.rs index cf3b3e0..db9bcef 100644 --- a/rust_compiler/libs/compiler/src/test/math_syscall.rs +++ b/rust_compiler/libs/compiler/src/test/math_syscall.rs @@ -1,4 +1,3 @@ -use crate::compile; use anyhow::Result; use indoc::indoc; use pretty_assertions::assert_eq; diff --git a/rust_compiler/libs/compiler/src/test/syscall.rs b/rust_compiler/libs/compiler/src/test/syscall.rs index f7df25e..f70da30 100644 --- a/rust_compiler/libs/compiler/src/test/syscall.rs +++ b/rust_compiler/libs/compiler/src/test/syscall.rs @@ -1,4 +1,3 @@ -use crate::compile; use indoc::indoc; use pretty_assertions::assert_eq; -- 2.49.1