Skip to content

Commit

Permalink
fix and improves l10n
Browse files Browse the repository at this point in the history
fix: codefix ReplaceWithSuggestion and ResolveNamespace can now
deal with localized compiler texts
improves: now can load localized xml documents
  • Loading branch information
ijklam committed Oct 22, 2023
1 parent 7f88622 commit 26bce28
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 3 deletions.
19 changes: 19 additions & 0 deletions src/FsAutoComplete.Core/TipFormatter.fs
Original file line number Diff line number Diff line change
Expand Up @@ -890,6 +890,23 @@ let rec private readXmlDoc (reader: XmlReader) (indentationSize: int) (acc: Map<
let private xmlDocCache =
Collections.Concurrent.ConcurrentDictionary<string, Map<string, XmlDocMember>>()

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
Expand All @@ -903,6 +920,8 @@ let private getXmlDoc dllFile =
else
xmlFile

let xmlFile = findLocalizedXmlFile xmlFile

if xmlDocCache.ContainsKey xmlFile then
Some xmlDocCache.[xmlFile]
else
Expand Down
5 changes: 5 additions & 0 deletions src/FsAutoComplete/CodeFixes.fs
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,11 @@ 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 ->
Expand Down
5 changes: 5 additions & 0 deletions src/FsAutoComplete/CodeFixes.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,11 @@ module Run =
handler: (Diagnostic -> CodeActionParams -> Async<Result<Fix list, string>>) ->
(CodeActionParams -> Async<Result<Fix list, string>>)

val ifDiagnosticByCheckMessage:
checkMessageFunc: (string -> bool) list ->
handler: (Diagnostic -> CodeActionParams -> Async<Result<Fix list, string>>) ->
(CodeActionParams -> Async<Result<Fix list, string>>)

val ifDiagnosticByType:
diagnosticType: string ->
handler: (Diagnostic -> CodeActionParams -> Async<Result<Fix list, string>>) ->
Expand Down
22 changes: 20 additions & 2 deletions src/FsAutoComplete/CodeFixes/ReplaceWithSuggestion.fs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,28 @@ 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

Expand Down
23 changes: 22 additions & 1 deletion src/FsAutoComplete/CodeFixes/ResolveNamespace.fs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,30 @@ 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)
Expand Down Expand Up @@ -112,7 +133,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

Expand Down

0 comments on commit 26bce28

Please sign in to comment.