diff options
author | RĂ©mi Verschelde <rverschelde@gmail.com> | 2020-06-24 01:00:05 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-24 01:00:05 +0200 |
commit | 7d60a88888afa3d62ea66fb6339547d65e2031d1 (patch) | |
tree | 16742eb186ea1fc043b69928faac287b6f05e5c8 /modules | |
parent | 05395cb14fa0fbd270f6d8c63bcb7b80f45f4dfe (diff) | |
parent | d569b447ffd68f59842abf6cebb31f787fe0c559 (diff) |
Merge pull request #39783 from neikeq/messaging-codecompletion-localize-fix
C#: Fix completion request with case insensitive resource path
Diffstat (limited to 'modules')
3 files changed, 57 insertions, 2 deletions
diff --git a/modules/mono/editor/GodotTools/GodotTools.Core/StringExtensions.cs b/modules/mono/editor/GodotTools/GodotTools.Core/StringExtensions.cs index 7ab5c5fc59..012b69032e 100644 --- a/modules/mono/editor/GodotTools/GodotTools.Core/StringExtensions.cs +++ b/modules/mono/editor/GodotTools/GodotTools.Core/StringExtensions.cs @@ -25,8 +25,9 @@ namespace GodotTools.Core bool rooted = path.IsAbsolutePath(); path = path.Replace('\\', '/'); + path = path[path.Length - 1] == '/' ? path.Substring(0, path.Length - 1) : path; - string[] parts = path.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); + string[] parts = path.Split(new[] {'/'}, StringSplitOptions.RemoveEmptyEntries); path = string.Join(Path.DirectorySeparatorChar.ToString(), parts).Trim(); diff --git a/modules/mono/editor/GodotTools/GodotTools/Ides/MessagingServer.cs b/modules/mono/editor/GodotTools/GodotTools/Ides/MessagingServer.cs index 98e8d13be0..17f3339560 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Ides/MessagingServer.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Ides/MessagingServer.cs @@ -12,6 +12,7 @@ using GodotTools.IdeMessaging; using GodotTools.IdeMessaging.Requests; using GodotTools.IdeMessaging.Utils; using GodotTools.Internals; +using GodotTools.Utils; using Newtonsoft.Json; using Directory = System.IO.Directory; using File = System.IO.File; @@ -362,8 +363,13 @@ namespace GodotTools.Ides private static async Task<Response> HandleCodeCompletionRequest(CodeCompletionRequest request) { + // This is needed if the "resource path" part of the path is case insensitive. + // However, it doesn't fix resource loading if the rest of the path is also case insensitive. + string scriptFileLocalized = FsPathUtils.LocalizePathWithCaseChecked(request.ScriptFile); + var response = new CodeCompletionResponse {Kind = request.Kind, ScriptFile = request.ScriptFile}; - response.Suggestions = await Task.Run(() => Internal.CodeCompletionRequest(response.Kind, response.ScriptFile)); + response.Suggestions = await Task.Run(() => + Internal.CodeCompletionRequest(response.Kind, scriptFileLocalized ?? request.ScriptFile)); return response; } } diff --git a/modules/mono/editor/GodotTools/GodotTools/Utils/FsPathUtils.cs b/modules/mono/editor/GodotTools/GodotTools/Utils/FsPathUtils.cs new file mode 100644 index 0000000000..c6724ccaf7 --- /dev/null +++ b/modules/mono/editor/GodotTools/GodotTools/Utils/FsPathUtils.cs @@ -0,0 +1,48 @@ +using System; +using System.IO; +using Godot; +using GodotTools.Core; +using JetBrains.Annotations; + +namespace GodotTools.Utils +{ + public static class FsPathUtils + { + private static readonly string ResourcePath = ProjectSettings.GlobalizePath("res://"); + + private static bool PathStartsWithAlreadyNorm(this string childPath, string parentPath) + { + // This won't work for Linux/macOS case insensitive file systems, but it's enough for our current problems + bool caseSensitive = !OS.IsWindows; + + string parentPathNorm = parentPath.NormalizePath() + Path.DirectorySeparatorChar; + string childPathNorm = childPath.NormalizePath() + Path.DirectorySeparatorChar; + + return childPathNorm.StartsWith(parentPathNorm, + caseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase); + } + + public static bool PathStartsWith(this string childPath, string parentPath) + { + string childPathNorm = childPath.NormalizePath() + Path.DirectorySeparatorChar; + string parentPathNorm = parentPath.NormalizePath() + Path.DirectorySeparatorChar; + + return childPathNorm.PathStartsWithAlreadyNorm(parentPathNorm); + } + + [CanBeNull] + public static string LocalizePathWithCaseChecked(string path) + { + string pathNorm = path.NormalizePath() + Path.DirectorySeparatorChar; + string resourcePathNorm = ResourcePath.NormalizePath() + Path.DirectorySeparatorChar; + + if (!pathNorm.PathStartsWithAlreadyNorm(resourcePathNorm)) + return null; + + string result = "res://" + pathNorm.Substring(resourcePathNorm.Length); + + // Remove the last separator we added + return result.Substring(0, result.Length - 1); + } + } +} |