diff --git a/CHANGELOG.md b/CHANGELOG.md index a00dbb3..6bee105 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## [0.2.0] - 2024-01-16 + +### Fixed + +* Fixed a caching issue which caused the loss of xml fragments. + +### Added + +* Added `H.H` to apply directly to expressions without the need for quotation wrapping. + ## [0.1.1] - 2023-12-25 ### Fixed diff --git a/README.md b/README.md index a67faaf..64854a2 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ Fsih ==== -Fsih provides you with the `h` function, meant to be used in the F# REPL [fsi](https://learn.microsoft.com/en-us/dotnet/fsharp/tools/fsharp-interactive/). +Fsih provides you with the `h` and `H.H` functions, meant to be used in the F# REPL [fsi](https://learn.microsoft.com/en-us/dotnet/fsharp/tools/fsharp-interactive/). It's modeled after the `h` function in the Elixir [iex](https://hexdocs.pm/iex/1.16.0/IEx.html) REPL. To use it, just start an fsi session with `dotnet fsi`. @@ -11,9 +11,30 @@ Load the package and open the namespace: open Fsih;; ``` -Apply h to any function wrapped in an FSharp [quotation](https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/code-quotations) to get its documentation: +Apply h to any expression wrapped in an FSharp [quotation](https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/code-quotations) to get its documentation: ```fsharp -h <@ fst @> +h <@ fst @>;; +``` + +``` +Description: +Return the first element of a tuple, fst (a,b) = a. + +Parameters: +- tuple: The input tuple. +Returns: +The first value. + +Examples: +fst ("first", 2) // Evaluates to "first" + +Full name: Microsoft.FSharp.Core.Operators.fst +Assembly: FSharp.Core.dll +``` + +Or apply H.H to any expression directly to get its documentation: +```fsharp +H.H fst;; ``` ``` diff --git a/src/Fsih.Tests/Tests.fs b/src/Fsih.Tests/Tests.fs index 47e9e28..f600d95 100644 --- a/src/Fsih.Tests/Tests.fs +++ b/src/Fsih.Tests/Tests.fs @@ -83,8 +83,8 @@ let ``full info is as expected for Seq.splitInto`` () = Assert.Equal("Microsoft.FSharp.Collections.SeqModule.splitInto", fullName) Assert.Equal("FSharp.Core.dll", assembly) - | Some _ -> Assert.False(true, sprintf "unexpected help") - | None -> Assert.False(true, sprintf "no docs for Seq.splitInto") + | Some _ -> Assert.False(true, "unexpected help") + | None -> Assert.False(true, "no docs for Seq.splitInto") [] let ``returns is as expected for HashIdentity.FromFunctions`` () = @@ -96,8 +96,8 @@ let ``returns is as expected for HashIdentity.FromFunctions`` () = "An object implementing System.Collections.Generic.IEqualityComparer using the given functions.", returns ) - | Some _ -> Assert.False(true, sprintf "unexpected help") - | None -> Assert.False(true, sprintf "no docs for Seq.splitInto") + | Some _ -> Assert.False(true, "unexpected help") + | None -> Assert.False(true, "no docs for HashIdentity.FromFunctions") [] let ``remarks is as expected for List.reduce`` () = @@ -105,8 +105,8 @@ let ``remarks is as expected for List.reduce`` () = match doc with | Some { Remarks = Some remarks } -> Assert.Equal("Raises System.ArgumentException if list is empty", remarks) - | Some _ -> Assert.False(true, sprintf "unexpected help") - | None -> Assert.False(true, sprintf "no docs for Seq.splitInto") + | Some _ -> Assert.False(true, "unexpected help") + | None -> Assert.False(true, "no docs for List.reduce") [] let ``summary is as expected for Array.sortDescending`` () = @@ -118,4 +118,13 @@ let ``summary is as expected for Array.sortDescending`` () = "Sorts the elements of an array, in descending order, returning a new array. Elements are compared using Microsoft.FSharp.Core.Operators.compare.", summary ) - | None -> Assert.False(true, sprintf "no docs for Seq.splitInto") + | None -> Assert.False(true, "no docs for Array.sortDescending") + +[] +let ``ReflectedDefinition works as expected`` () = + let docReflected = H.TryGetDocumentation(id) + let docQuoted = tryGetDocumentation <@ id @> + + match docReflected, docQuoted with + | Some r, Some q -> Assert.True((r = q)) + | _ -> Assert.False(true, "no docs for id") diff --git a/src/Fsih/Parser.fs b/src/Fsih/Parser.fs index 632a3aa..0d8fe68 100644 --- a/src/Fsih/Parser.fs +++ b/src/Fsih/Parser.fs @@ -65,19 +65,23 @@ let trimDotNet (s: string) = let s = if idx > 0 then s.Substring(0, idx) else s s -let xmlDocCache = Collections.Generic.Dictionary() +// WTF, seems like we loose inner xml (example content) if we cache an XmlDocument +let xmlDocCache = Collections.Generic.Dictionary() let getXmlDocument xmlPath = #if DEBUG printfn $"xml file: %s{xmlPath}" #endif match xmlDocCache.TryGetValue(xmlPath) with - | true, value -> value + | true, value -> + let xmlDocument = XmlDocument() + xmlDocument.LoadXml(value) + xmlDocument | _ -> let rawXml = File.ReadAllText(xmlPath) let xmlDocument = XmlDocument() xmlDocument.LoadXml(rawXml) - xmlDocCache.Add(xmlPath, xmlDocument) + xmlDocCache.Add(xmlPath, rawXml) xmlDocument let getTexts (node: Xml.XmlNode) = diff --git a/src/Fsih/Program.fs b/src/Fsih/Program.fs index cbac930..af2fdea 100644 --- a/src/Fsih/Program.fs +++ b/src/Fsih/Program.fs @@ -86,33 +86,17 @@ module Logic = | None -> printfn "unable to get documentation" | Some d -> d.Print() -module Program = + type H() = + static member H([] expr: Quotations.Expr<_>) = h expr + static member TryGetDocumentation([] expr: Quotations.Expr<_>) = tryGetDocumentation expr - open Logic +module Program = [] - let main argv = - // h <@ Option.isNone @> - // h <@ Option.defaultValue @> - // h <@ Seq.allPairs @> - // h <@ Seq.iter @> - // h <@ Seq.average [ 1. ] @> - // h <@ Seq.append @> - // h <@ Seq.average [ 1. ] @> - // h <@ printfn @> - // h <@ None @> - // h <@ System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes @> - // h <@ Collections.ResizeArray [] @> - // h <@ [] @> - // h <@ "" @> - // h <@ 1 :: List.empty @> - // h <@ Map @> - // h <@ [| 1 |] @> - // h <@ Array.Parallel.tryFind @> - // h <@ Seq.head @> - // h <@ Seq.delay @> - // h <@ Seq.countBy @> - // h <@ Microsoft.FSharp.Collections.HashIdentity.FromFunctions @> - // h <@ List.reduce @> + let main _argv = + // h <@ id @> + // H.H id + h <@ List.map @> + H.H List.map 0