diff --git a/src/FsAutoComplete.Core/TipFormatter.fs b/src/FsAutoComplete.Core/TipFormatter.fs index ffc2bfeb3..e2b90eca6 100644 --- a/src/FsAutoComplete.Core/TipFormatter.fs +++ b/src/FsAutoComplete.Core/TipFormatter.fs @@ -890,6 +890,26 @@ let rec private readXmlDoc (reader: XmlReader) (indentationSize: int) (acc: Map< let private xmlDocCache = Collections.Concurrent.ConcurrentDictionary>() +let private findCultures v = + let rec loop state (v: System.Globalization.CultureInfo) = + let state' = v.Name :: state + + if v.Parent = System.Globalization.CultureInfo.InvariantCulture then + "" :: state' |> List.rev + else + loop state' v.Parent + + loop [] v + +let private findLocalizedXmlFile (xmlFile: string) = + let xmlName = Path.GetFileName xmlFile + let path = Path.GetDirectoryName xmlFile + + findCultures System.Globalization.CultureInfo.CurrentUICulture + |> List.map (fun culture -> Path.Combine(path, culture, xmlName)) + |> List.tryFind (fun i -> File.Exists i) + |> Option.defaultValue xmlFile + let private getXmlDoc dllFile = let xmlFile = Path.ChangeExtension(dllFile, ".xml") //Workaround for netstandard.dll @@ -903,6 +923,8 @@ let private getXmlDoc dllFile = else xmlFile + let xmlFile = findLocalizedXmlFile xmlFile + if xmlDocCache.ContainsKey xmlFile then Some xmlDocCache.[xmlFile] else diff --git a/src/FsAutoComplete/CodeFixes.fs b/src/FsAutoComplete/CodeFixes.fs index 77ac654bb..3c11fdd3c 100644 --- a/src/FsAutoComplete/CodeFixes.fs +++ b/src/FsAutoComplete/CodeFixes.fs @@ -326,6 +326,9 @@ module Run = let ifDiagnosticByMessage (checkMessage: string) handler : CodeFix = runDiagnostics (fun d -> d.Message.Contains checkMessage) handler + let ifDiagnosticByCheckMessage (checkMessageFunc: (string -> bool) list) handler : CodeFix = + runDiagnostics (fun d -> checkMessageFunc |> List.exists (fun f -> f d.Message)) handler + let ifDiagnosticByType (diagnosticType: string) handler : CodeFix = runDiagnostics (fun d -> diff --git a/src/FsAutoComplete/CodeFixes.fsi b/src/FsAutoComplete/CodeFixes.fsi index fd300841f..1a8366bbe 100644 --- a/src/FsAutoComplete/CodeFixes.fsi +++ b/src/FsAutoComplete/CodeFixes.fsi @@ -162,6 +162,11 @@ module Run = handler: (Diagnostic -> CodeActionParams -> Async>) -> (CodeActionParams -> Async>) + val ifDiagnosticByCheckMessage: + checkMessageFunc: (string -> bool) list -> + handler: (Diagnostic -> CodeActionParams -> Async>) -> + (CodeActionParams -> Async>) + val ifDiagnosticByType: diagnosticType: string -> handler: (Diagnostic -> CodeActionParams -> Async>) -> diff --git a/src/FsAutoComplete/CodeFixes/ReplaceWithSuggestion.fs b/src/FsAutoComplete/CodeFixes/ReplaceWithSuggestion.fs index afe8615e8..e1ec606bc 100644 --- a/src/FsAutoComplete/CodeFixes/ReplaceWithSuggestion.fs +++ b/src/FsAutoComplete/CodeFixes/ReplaceWithSuggestion.fs @@ -8,10 +8,27 @@ open FSharp.Compiler.Syntax let title suggestion = $"Replace with '%s{suggestion}'" +let undefinedName = + [ "Maybe you want one of the following:" + "Možná budete potřebovat něco z tohoto:" + "Vielleicht möchten Sie eine der folgenden Bezeichnungen verwenden:" + "Puede elegir una de las opciones siguientes:" + "Peut-être souhaitez-vous l'une des options suivantes :" + "Si può specificare uno dei nomi seguenti:" + "次のいずれかの可能性はありませんか:" + "다음 중 하나가 필요할 수 있습니다:" + "Możliwe, że chcesz wykonać jedną z następujących czynności:" + "Talvez você queira um dos seguintes:" + "Возможно, требуется одно из следующих:" + "Aşağıdakilerden birini arıyor olabilirsiniz:" + "你可能需要以下之一:" + "您可能需要下列其中一項:" ] + |> List.map (fun i -> fun (j: string) -> j.Contains(i, System.StringComparison.Ordinal)) + /// a codefix that replaces the use of an unknown identifier with a suggested identifier let fix = - Run.ifDiagnosticByMessage "Maybe you want one of the following:" (fun diagnostic codeActionParams -> - diagnostic.Message.Split('\n').[1..] + Run.ifDiagnosticByCheckMessage undefinedName (fun diagnostic codeActionParams -> + diagnostic.Message.Split('\n', '\u001b').[1..] |> Array.map (fun suggestion -> let suggestion = suggestion.Trim() |> PrettyNaming.NormalizeIdentifierBackticks diff --git a/src/FsAutoComplete/CodeFixes/ResolveNamespace.fs b/src/FsAutoComplete/CodeFixes/ResolveNamespace.fs index f8b59b266..5f1fd243e 100644 --- a/src/FsAutoComplete/CodeFixes/ResolveNamespace.fs +++ b/src/FsAutoComplete/CodeFixes/ResolveNamespace.fs @@ -8,9 +8,29 @@ open FsAutoComplete.LspHelpers open FsAutoComplete open FSharp.Compiler.Text open FSharp.Compiler.EditorServices +open System.Text.RegularExpressions type LineText = string +let undefinedName = + [ "not define" + "nedefinuje|Není definovaný|Není definované|Není definovaná|Nemáte definovaný" + "definiert nicht|nicht.*? definiert" + "no define|no está definido|no está definida" + "ne définit|n'est pas défini" + "non definisce|non è definito|non è definita" + "定義(され|し)ていません" + "정의(하지 않|되지 않았|되어 있지 않)습니다" + "nie definiuje|Nie zdefiniowano|nie jest zdefiniowany" + "não define|não está definido" + "не определяет|не определено|не определены|не определен" + "tanımlamıyor|tanımlı değil" + "未.*?定义" + "未定義" ] + |> List.map (fun i -> + let regex = Regex(i, RegexOptions.IgnoreCase ||| RegexOptions.Compiled) + fun (j: string) -> regex.IsMatch(j)) + /// a codefix the provides suggestions for opening modules or using qualified names when an identifier is found that needs qualification let fix (getParseResultsForFile: GetParseResultsForFile) @@ -112,7 +132,7 @@ let fix Title = $"open %s{actualOpen}" Kind = FixKind.Fix } - Run.ifDiagnosticByMessage "is not defined" (fun diagnostic codeActionParameter -> + Run.ifDiagnosticByCheckMessage undefinedName (fun diagnostic codeActionParameter -> asyncResult { let pos = protocolPosToPos diagnostic.Range.Start