Skip to content

Commit

Permalink
F# HoverText (#714)
Browse files Browse the repository at this point in the history
* sketched RequestHoverText

* added modified FsAutoComplete.Core for getting Tooltips

* removed unused files from FsAutoComplete.Core

* added basic tests for `RequestHoverText` in FSharp.Tests

* prettier Hover-Messages including current value when possible

* HoverText tests now including F#

* fixed broken build
  • Loading branch information
krauthaufen authored Sep 16, 2020
1 parent 056fb6e commit 741215f
Show file tree
Hide file tree
Showing 19 changed files with 5,158 additions and 5 deletions.
15 changes: 15 additions & 0 deletions dotnet-interactive.sln
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{4DD50BCA-1
docs\variable-sharing.md = docs\variable-sharing.md
EndProjectSection
EndProject
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FsAutoComplete.Core", "src\FsAutoComplete\FsAutoComplete.Core.fsproj", "{9C68BBE5-145F-4E6A-968E-E58F53EABA8C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -360,6 +362,18 @@ Global
{89672116-94E4-4F17-A64A-AA049410F595}.Release|x64.Build.0 = Release|Any CPU
{89672116-94E4-4F17-A64A-AA049410F595}.Release|x86.ActiveCfg = Release|Any CPU
{89672116-94E4-4F17-A64A-AA049410F595}.Release|x86.Build.0 = Release|Any CPU
{9C68BBE5-145F-4E6A-968E-E58F53EABA8C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9C68BBE5-145F-4E6A-968E-E58F53EABA8C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9C68BBE5-145F-4E6A-968E-E58F53EABA8C}.Debug|x64.ActiveCfg = Debug|Any CPU
{9C68BBE5-145F-4E6A-968E-E58F53EABA8C}.Debug|x64.Build.0 = Debug|Any CPU
{9C68BBE5-145F-4E6A-968E-E58F53EABA8C}.Debug|x86.ActiveCfg = Debug|Any CPU
{9C68BBE5-145F-4E6A-968E-E58F53EABA8C}.Debug|x86.Build.0 = Debug|Any CPU
{9C68BBE5-145F-4E6A-968E-E58F53EABA8C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9C68BBE5-145F-4E6A-968E-E58F53EABA8C}.Release|Any CPU.Build.0 = Release|Any CPU
{9C68BBE5-145F-4E6A-968E-E58F53EABA8C}.Release|x64.ActiveCfg = Release|Any CPU
{9C68BBE5-145F-4E6A-968E-E58F53EABA8C}.Release|x64.Build.0 = Release|Any CPU
{9C68BBE5-145F-4E6A-968E-E58F53EABA8C}.Release|x86.ActiveCfg = Release|Any CPU
{9C68BBE5-145F-4E6A-968E-E58F53EABA8C}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -388,6 +402,7 @@ Global
{8017943B-B591-49C8-B957-40141B427AD9} = {979A5022-09CA-4258-B76D-CFDC31DA71E0}
{9A091E80-D5EB-4DEF-8E38-B24B128393DF} = {B95A8485-8C53-4F56-B0CE-19C0726B5805}
{89672116-94E4-4F17-A64A-AA049410F595} = {B95A8485-8C53-4F56-B0CE-19C0726B5805}
{9C68BBE5-145F-4E6A-968E-E58F53EABA8C} = {B95A8485-8C53-4F56-B0CE-19C0726B5805}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {6D05A9AF-CFFB-4187-8599-574387B76727}
Expand Down
833 changes: 833 additions & 0 deletions src/FsAutoComplete/DocumentationFormatter.fs

Large diffs are not rendered by default.

22 changes: 22 additions & 0 deletions src/FsAutoComplete/FsAutoComplete.Core.fsproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<LangVersion>preview</LangVersion>
<DefineConstants>NO_EXTENSIONTYPING;$(DefineConstants);DOTNET_SPAWN;NETCORE_FSI</DefineConstants>
</PropertyGroup>
<ItemGroup>
<Compile Include="Utils.fs" />
<Compile Include="TypedAstUtils.fs" />
<Compile Include="TypedAstPatterns.fs" />
<Compile Include="Lexer.fs" />
<Compile Include="SignatureFormatter.fs" />
<Compile Include="TipFormatter.fs" />
<Compile Include="DocumentationFormatter.fs" />
<Compile Include="KeywordList.fs" />
<Compile Include="InteractiveDirectives.fs" />
<Compile Include="ParseAndCheckResults.fs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="FSharp.Compiler.Private.Scripting" />
</ItemGroup>
</Project>
114 changes: 114 additions & 0 deletions src/FsAutoComplete/InteractiveDirectives.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
module FsAutoComplete.InteractiveDirectives

open System
open System.Text.RegularExpressions

/// Remove escaping from standard (non verbatim & non triple quotes) string
let private unescapeStandardString (s: string) =
let mutable result = ""
let mutable escaped = false
let mutable unicodeHeaderChar = '?'
let mutable remainingUnicodeChars = 0
let mutable currentUnicodeChars = ""

for i in [ 0 .. s.Length - 1 ] do
let c = s.[i]
if remainingUnicodeChars > 0 then
if (c >= 'A' && c <= 'Z')
|| (c >= 'a' && c <= 'z')
|| (c >= '0' && c <= '9') then
currentUnicodeChars <- currentUnicodeChars + string (c)
remainingUnicodeChars <- remainingUnicodeChars - 1

if remainingUnicodeChars = 0 then
result <-
result
+ string (char (Convert.ToUInt32(currentUnicodeChars, 16)))
else
// Invalid unicode sequence, bail out
result <-
result
+ "\\"
+ string (unicodeHeaderChar)
+ currentUnicodeChars
+ string (c)
remainingUnicodeChars <- 0
else if escaped then
escaped <- false
match c with
| 'b' -> result <- result + "\b"
| 'n' -> result <- result + "\n"
| 'r' -> result <- result + "\r"
| 't' -> result <- result + "\t"
| '\\' -> result <- result + "\\"
| '"' -> result <- result + "\""
| ''' -> result <- result + "'"
| 'u' ->
unicodeHeaderChar <- 'u'
currentUnicodeChars <- ""
remainingUnicodeChars <- 4
| 'U' ->
unicodeHeaderChar <- 'U'
currentUnicodeChars <- ""
remainingUnicodeChars <- 8
| _ -> result <- result + "\\" + string (c)
else if c = '\\' then
escaped <- true
else
result <- result + string (c)

if remainingUnicodeChars > 0 then
result <-
result
+ "\\"
+ string (unicodeHeaderChar)
+ currentUnicodeChars
else if escaped then
result <- result + "\\"

result


let private loadRegex = Regex(@"#load\s+")
let private standardStringRegex = Regex(@"^""(((\\"")|[^""])*)""")
let private verbatimStringRegex = Regex(@"^@""((""""|[^""])*)""")
let private tripleStringRegex = Regex(@"^""""""(.*?)""""""")

// The following function can be probably moved to general Utils, as it's general purpose.
// Or is there already such function?

/// Get the string starting at index in any of the string forms (standard, verbatim or triple quotes)
let private tryParseStringFromStart (s: string) (index: int) =
let s = s.Substring(index)
let verbatim = verbatimStringRegex.Match(s)
if verbatim.Success then
let s = verbatim.Groups.[1].Value
Some(s.Replace("\"\"", "\""))
else
let triple = tripleStringRegex.Match(s)
if triple.Success then
let s = triple.Groups.[1].Value
Some s
else
let standard = standardStringRegex.Match(s)
if standard.Success then
let s = standard.Groups.[1].Value
Some(unescapeStandardString s)
else
None

/// Parse the content of a "#load" instruction at the given line. Returns the script file name on success.
let tryParseLoad (line: string) (column: int) =
let potential =
seq {
let matches = loadRegex.Matches(line)
for i in [ 0 .. matches.Count - 1 ] do
let m = matches.[i]
if m.Index <= column then yield m
}

match potential |> Seq.tryLast with
| Some m ->
let stringIndex = m.Index + m.Length
tryParseStringFromStart line stringIndex
| None -> None
33 changes: 33 additions & 0 deletions src/FsAutoComplete/KeywordList.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
namespace FsAutoComplete

open FSharp.Compiler.SourceCodeServices

module KeywordList =

let keywordDescriptions =
FSharp.Compiler.SourceCodeServices.Keywords.KeywordsWithDescription
|> dict

let keywordTooltips =
keywordDescriptions
|> Seq.map (fun kv ->
let tip = FSharpToolTipText [FSharpToolTipElement.Single(kv.Key, FSharpXmlDoc.Text kv.Value)]
kv.Key, tip)
|> dict

let hashDirectives =
[ "r", "References an assembly"
"load", "Reads a source file, compiles it, and runs it."
"I", "Specifies an assembly search path in quotation marks."
"light", "Enables or disables lightweight syntax, for compatibility with other versions of ML"
"if", "Supports conditional compilation"
"else", "Supports conditional compilation"
"endif", "Supports conditional compilation"
"nowarn", "Disables a compiler warning or warnings"
"line", "Indicates the original source code line"]
|> dict


let allKeywords : string list =
FSharp.Compiler.SourceCodeServices.Keywords.KeywordsWithDescription
|> List.map fst
Loading

0 comments on commit 741215f

Please sign in to comment.