diff --git a/IfSharp.sln b/IfSharp.sln index 664c435..267202e 100644 --- a/IfSharp.sln +++ b/IfSharp.sln @@ -52,6 +52,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ipython-profile", "ipython- ProjectSection(SolutionItems) = preProject ipython-profile\static\custom\ifsharp_logo.png = ipython-profile\static\custom\ifsharp_logo.png ipython-profile\ipython_config.py = ipython-profile\ipython_config.py + ipython-profile\ipython_qtconsole_config.py = ipython-profile\ipython_qtconsole_config.py + ipython-profile\kernel.js = ipython-profile\kernel.js EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IfSharpConsole", "src\IfSharpConsole\IfSharpConsole.csproj", "{6BD0E996-0AEE-4FC7-8FB9-46E033D0C7F1}" @@ -60,8 +62,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "static", "static", "{45519D EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "custom", "custom", "{3AAFA64D-CBB6-488E-B395-6A1E7CB554CE}" ProjectSection(SolutionItems) = preProject - ipython-profile\static\custom\custom.css = ipython-profile\static\custom\custom.css - ipython-profile\static\custom\custom.js = ipython-profile\static\custom\custom.js + ipython-profile\static\custom\fsharp.css = ipython-profile\static\custom\fsharp.css ipython-profile\static\custom\fsharp.js = ipython-profile\static\custom\fsharp.js ipython-profile\static\custom\ifsharp_logo.png = ipython-profile\static\custom\ifsharp_logo.png ipython-profile\static\custom\webintellisense-codemirror.js = ipython-profile\static\custom\webintellisense-codemirror.js diff --git a/README.md b/README.md index dbdab73..e14d2fc 100644 --- a/README.md +++ b/README.md @@ -1,41 +1,48 @@ # IfSharp -F# implementation for [iPython](http://ipython.org). View the [Feature Notebook](http://nbviewer.ipython.org/github/BayardRock/IfSharp/blob/master/Feature%20Notebook.ipynb) for some of the features that are included. -For more information view the [documenation](http://bayardrock.github.io/IfSharp/). IfSharp is 64-bit *ONLY*. +F# implementation for [Jupyter](http://jupyter.org/). View the [Feature Notebook](http://nbviewer.jupyter.org/github/fsprojects/IfSharp/blob/master/Feature%20Notebook.ipynb) for some of the features that are included. +For more information view the [documentation](http://fsprojects.github.io/IfSharp/). IfSharp is 64-bit *ONLY*. # Compatibility -IfSharp works with iPython Notebook 1.x and 2.x +IfSharp works with Jupyter 4.0 and 4.1 and works with both Python 2.X and Python 3.X # Automatic Installation -See our [release repository](https://github.com/BayardRock/IfSharp/releases). Also, [installation documentation](http://bayardrock.github.io/IfSharp/installation.html). +Previous releases for the IPython notebook are here: [release repository](https://github.com/fsprojects/IfSharp/releases). +Automatic installs for Jupyter will be provided in the future. -# Manual Installation +# Manual Installation (Windows) 1. Install [Anaconda](http://continuum.io/downloads) -2. Install [IPython](http://ipython.org/install.html) -3. Run: "ipython profile create ifsharp" in your user directory -4. Open the iF# solution file, restore nuget packages, and compile it -5. Copy the files from IfSharp\ipython-profile to the iFSharp profile directory -6. Open up the copied "ipython_config.py" file and replace "%s" with the path of your compiled ifsharp executable. E.g. "C:\\git\\ifsharp\\bin\\Release\\ifsharp.exe" -7. Run: "ipython notebook --profile ifsharp" to launch the notebook process with the F# kernel. +2. Install [Jupyter](http://jupyter.readthedocs.org/en/latest/install.html) +3. Checkout the repository +4. Open the IfSharp solution file, restore nuget packages, and compile it +5. Run the IfSharpConsole project, this will register IfSharp and launch Jupyter + +Jupyter with IfSharp can be run via "jupyter notebook" in future + +# Manual Installation (Mac) +TODO + +# Manual Installation (Ubuntu) +TODO # Screens ## Intellisense -![Intellisense Example #1](https://raw.github.com/BayardRock/IfSharp/master/docs/files/img/intellisense-1.png "Intellisense Example #1") +![Intellisense Example #1](/docs/files/img/intellisense-1.png?raw=true "Intellisense Example #1") *** -![Intellisense Example #2](https://raw.github.com/BayardRock/IfSharp/master/docs/files/img/intellisense-2.png "Intellisense Example #2") +![Intellisense Example #2](docs/files/img/intellisense-2.png?raw=true "Intellisense Example #2") *** -![Intellisense Example #3 With Chart](https://raw.github.com/BayardRock/IfSharp/master/docs/files/img/intellisense-3.png "Intellisense Example #3 With Chart") +![Intellisense Example #3 With Chart](docs/files/img/intellisense-3.png?raw=true "Intellisense Example #3 With Chart") *** -![Intellisense Example #4 #r Directive](https://raw.github.com/BayardRock/IfSharp/master/docs/files/img/intellisense-reference.gif "Intellisense Example #3 #r Directive") +![Intellisense Example #4 #r Directive](docs/files/img/intellisense-reference.gif?raw=true "Intellisense Example #3 #r Directive") *** -![Intellisense Example #5 #load Directive](https://raw.github.com/BayardRock/IfSharp/master/docs/files/img/intellisense-5.png "Intellisense Example #load Directive") +![Intellisense Example #5 #load Directive](docs/files/img/intellisense-5.png?raw=true "Intellisense Example #load Directive") *** ## Integrated NuGet -![NuGet Example](https://raw.github.com/BayardRock/IfSharp/master/docs/files/img/NuGet-1.png "NuGet example") +![NuGet Example](docs/files/img/NuGet-1.png?raw=true "NuGet example") ## Inline Error Messages -![Inline Error Message](https://raw.github.com/BayardRock/IfSharp/master/docs/files/img/errors-1.png "Inline error message") +![Inline Error Message](docs/files/img/errors-1.png?raw=true "Inline error message") diff --git a/ipython-profile/ipython_config.py b/ipython-profile/ipython_config.py index 63b4d78..c399197 100644 --- a/ipython-profile/ipython_config.py +++ b/ipython-profile/ipython_config.py @@ -1,4 +1,3 @@ c = get_config() -c.KernelManager.kernel_spec = [r"%s", "{connection_file}"] -c.Session.key = b'' -c.Session.keyfile = '' \ No newline at end of file +c.KernelManager.kernel_spec = [ "mono", r"%kexe", "{connection_file}"] +c.NotebookApp.extra_static_paths = [ r"%kstatic" ] \ No newline at end of file diff --git a/ipython-profile/kernel.js b/ipython-profile/kernel.js new file mode 100644 index 0000000..1c3bcf9 --- /dev/null +++ b/ipython-profile/kernel.js @@ -0,0 +1,164 @@ +define(function () { + + var link = document.createElement("link"); + link.type = "text/css"; + link.rel = "stylesheet"; + link.href = "/static/custom/fsharp.css"; + document.getElementsByTagName("head")[0].appendChild(link); + + require(['codemirror/addon/mode/loadmode']); + + var onload = function () { + + var md = IPython.notebook.metadata; + if (md.language) { + console.log('language already defined and is :', md.language); + } + else { + md.language = 'fsharp'; + console.log('add metadata hint that language is fsharp...'); + } + + require(['/static/custom/fsharp.js']); + + IPython.CodeCell.options_default.cm_config.mode = 'fsharp'; + + // callback called by the end-user + function updateMarkers(data) { + // applies intellisense hooks onto all cells + var cells = getCodeCells(); + data.forEach(function (err) { + var cell = cells.cells[err.CellNumber] + var editor = cell.code_mirror; + + // clear our error marks + editor.doc.getAllMarks() + .forEach(function (m) { + if (m.className === 'br-errormarker') { + m.clear(); + } + }); + + var from = { line: err.StartLine, ch: err.StartColumn }; + var to = { line: err.EndLine, ch: err.EndColumn }; + editor.doc.markText(from, to, { title: err.Message, className: 'br-errormarker' }); + }); + } + + function getCodeCells() { + var results = { codes: [], cells: [], selectedCell: null, selectedIndex: 0 }; + IPython.notebook.get_cells() + .forEach(function (c) { + if (c.cell_type === 'code') { + if (c.selected === true) { + results.selectedCell = c; + results.selectedIndex = results.cells.length; + } + results.cells.push(c); + results.codes.push(c.code_mirror.getValue()); + } + }); + + return results; + } + + require(['/static/custom/webintellisense.js', '/static/custom/webintellisense-codemirror.js'], function () { + // applies intellisense hooks onto a cell + function applyIntellisense(cell) { + if (cell.cell_type !== 'code') { return; } + + var editor = cell.code_mirror; + if (editor.intellisense == null) { + var intellisense = new CodeMirrorIntellisense(editor); + cell.force_highlight('fsharp'); + cell.code_mirror.setOption('theme', 'neat'); + editor.intellisense = intellisense; + + intellisense.addDeclarationTrigger({ keyCode: 190 }); // `.` + intellisense.addDeclarationTrigger({ keyCode: 32, ctrlKey: true, preventDefault: true, type: 'down' }); // `ctrl+space` + intellisense.addDeclarationTrigger({ keyCode: 191 }); // `/` + intellisense.addDeclarationTrigger({ keyCode: 220 }); // `\` + intellisense.addDeclarationTrigger({ keyCode: 222 }); // `"` + intellisense.addDeclarationTrigger({ keyCode: 222, shiftKey: true }); // `"` + intellisense.addMethodsTrigger({ keyCode: 57, shiftKey: true }); // `(` + intellisense.addMethodsTrigger({ keyCode: 48, shiftKey: true });// `)` + intellisense.onMethod(function (item, position) { + + }); + intellisense.onDeclaration(function (item, position) { + var cells = getCodeCells(); + var codes = cells.codes; + var cursor = cells.selectedCell.code_mirror.doc.getCursor(); + var callbacks = { shell: {}, iopub: {} }; + var line = editor.getLine(cursor.line); + var isSlash = item.keyCode === 191 || item.keyCode === 220; + var isQuote = item.keyCode === 222; + + var isLoadOrRef = line.indexOf('#load') === 0 + || line.indexOf('#r') === 0; + + var isStartLoadOrRef = line === '#load "' + || line === '#r "' + || line === '#load @"' + || line === '#r @"'; + + if (isSlash && !isLoadOrRef) { + return; + } + if (isQuote && !isStartLoadOrRef) { + return; + } + + // v2 + callbacks.shell.reply = function (msg) { + intellisense.setDeclarations(msg.content.matches); + if (msg.content.filter_start_index) + intellisense.setStartColumnIndex(msg.content.filter_start_index); + }; + + callbacks.iopub.output = function (msg) { + updateMarkers(msg.content.data.errors); + }; + + // v1 + callbacks.complete_reply = function (data) { + intellisense.setDeclarations(data.matches); + intellisense.setStartColumnIndex(data.filter_start_index); + }; + + callbacks.output = function (msgType, content, metadata) { + updateMarkers(content.data.errors); + }; + + var content = { + text: JSON.stringify(codes), + line: '', + block: JSON.stringify({ selectedIndex: cells.selectedIndex, ch: cursor.ch, line: cursor.line }), + cursor_pos: cursor.ch + }; + + IPython.notebook.kernel.send_shell_message("intellisense_request", content, callbacks, null, null); + }); + } + } + + // applies intellisense hooks onto all cells + IPython.notebook.get_cells() + .forEach(function (cell) { + applyIntellisense(cell); + }); + + // applies intellisense hooks onto cells that are selected + $([IPython.events]).on('create.Cell', function (event, data) { + applyIntellisense(data.cell); + }); + }); + + // replace the image + var img = $('.container img')[0]; + img.src = "/static/custom/ifsharp_logo.png"; + + } + + return { onload: onload } +}) \ No newline at end of file diff --git a/ipython-profile/static/custom/custom.js b/ipython-profile/static/custom/custom.js deleted file mode 100644 index c1b4467..0000000 --- a/ipython-profile/static/custom/custom.js +++ /dev/null @@ -1,177 +0,0 @@ -$([IPython.events]).on('notebook_loaded.Notebook', function () -{ - var md = IPython.notebook.metadata; - if (md.language) - { - console.log('language already defined and is :', md.language); - } - else - { - md.language = 'fsharp'; - console.log('add metadata hint that language is fsharp...'); - } -}); - -$([IPython.events]).on('app_initialized.NotebookApp', function () -{ - require(['custom/fsharp']); - - IPython.CodeCell.options_default.cm_config.mode = 'fsharp'; - - // callback called by the end-user - function updateMarkers(data) - { - // applies intellisense hooks onto all cells - var cells = getCodeCells(); - data.forEach(function (err) - { - var cell = cells.cells[err.CellNumber] - var editor = cell.code_mirror; - - // clear our error marks - editor.doc.getAllMarks() - .forEach(function (m) - { - if (m.className === 'br-errormarker') - { - m.clear(); - } - }); - - var from = { line: err.StartLine, ch: err.StartColumn }; - var to = { line: err.EndLine, ch: err.EndColumn }; - editor.doc.markText(from, to, { title: err.Message, className: 'br-errormarker' }); - }); - } - - function getCodeCells() - { - var results = { codes: [], cells: [], selectedCell: null, selectedIndex: 0 }; - IPython.notebook.get_cells() - .forEach(function (c) - { - if (c.cell_type === 'code') - { - if (c.selected === true) - { - results.selectedCell = c; - results.selectedIndex = results.cells.length; - } - results.cells.push(c); - results.codes.push(c.code_mirror.getValue()); - } - }); - - return results; - } - - require(['custom/webintellisense', 'custom/webintellisense-codemirror'], function () - { - // applies intellisense hooks onto a cell - function applyIntellisense(cell) - { - if (cell.cell_type !== 'code') { return; } - - var editor = cell.code_mirror; - if (editor.intellisense == null) - { - var intellisense = new CodeMirrorIntellisense(editor); - cell.force_highlight('fsharp'); - cell.code_mirror.setOption('theme', 'neat'); - editor.intellisense = intellisense; - - intellisense.addDeclarationTrigger({ keyCode: 190 }); // `.` - intellisense.addDeclarationTrigger({ keyCode: 32, ctrlKey: true, preventDefault: true, type: 'down' }); // `ctrl+space` - intellisense.addDeclarationTrigger({ keyCode: 191 }); // `/` - intellisense.addDeclarationTrigger({ keyCode: 220 }); // `\` - intellisense.addDeclarationTrigger({ keyCode: 222 }); // `"` - intellisense.addDeclarationTrigger({ keyCode: 222, shiftKey: true }); // `"` - intellisense.addMethodsTrigger({ keyCode: 57, shiftKey: true }); // `(` - intellisense.addMethodsTrigger({ keyCode: 48, shiftKey: true });// `)` - intellisense.onMethod(function (item, position) - { - - }); - intellisense.onDeclaration(function (item, position) - { - var cells = getCodeCells(); - var codes = cells.codes; - var cursor = cells.selectedCell.code_mirror.doc.getCursor(); - var callbacks = { shell: {}, iopub: {} }; - var line = editor.getLine(cursor.line); - var isSlash = item.keyCode === 191 || item.keyCode === 220; - var isQuote = item.keyCode === 222; - - var isLoadOrRef = line.indexOf('#load') === 0 - || line.indexOf('#r') === 0; - - var isStartLoadOrRef = line === '#load "' - || line === '#r "' - || line === '#load @"' - || line === '#r @"'; - - if (isSlash && !isLoadOrRef) - { - return; - } - if (isQuote && !isStartLoadOrRef) - { - return; - } - - // v2 - callbacks.shell.reply = function (msg) - { - intellisense.setDeclarations(msg.content.matches); - intellisense.setStartColumnIndex(data.filter_start_index); - }; - - callbacks.iopub.output = function (msg) - { - updateMarkers(msg.content.data.errors); - }; - - // v1 - callbacks.complete_reply = function (data) - { - intellisense.setDeclarations(data.matches); - intellisense.setStartColumnIndex(data.filter_start_index); - }; - - callbacks.output = function (msgType, content, metadata) - { - updateMarkers(content.data.errors); - }; - - var content = { - text: JSON.stringify(codes), - line: '', - block: JSON.stringify({ selectedIndex: cells.selectedIndex, ch: cursor.ch, line: cursor.line }), - cursor_pos: cursor.ch - }; - debugger; - var msg = IPython.notebook.kernel._get_msg("intellisense_request", content); - IPython.notebook.kernel.shell_channel.send(JSON.stringify(msg)); - IPython.notebook.kernel.set_callbacks_for_msg(msg.header.msg_id, callbacks); - }); - } - } - - // applies intellisense hooks onto all cells - IPython.notebook.get_cells() - .forEach(function (cell) - { - applyIntellisense(cell); - }); - - // applies intellisense hooks onto cells that are selected - $([IPython.events]).on('create.Cell', function (event, data) - { - applyIntellisense(data.cell); - }); - }); - - // replace the image - var img = $('.container img')[0]; - img.src = "/static/custom/ifsharp_logo.png"; -}); \ No newline at end of file diff --git a/ipython-profile/static/custom/custom.css b/ipython-profile/static/custom/fsharp.css similarity index 100% rename from ipython-profile/static/custom/custom.css rename to ipython-profile/static/custom/fsharp.css diff --git a/src/IfSharp.Kernel/App.fs b/src/IfSharp.Kernel/App.fs index afa597c..3471f2c 100644 --- a/src/IfSharp.Kernel/App.fs +++ b/src/IfSharp.Kernel/App.fs @@ -142,30 +142,27 @@ module App = // add to the payload Kernel.Value.AddPayload(text.ToString()) - /// Installs the ifsharp files if they do not exist, then starts ipython with the ifsharp profile + /// Installs the ifsharp files if they do not exist, then starts jupyter with the ifsharp profile let InstallAndStart(forceInstall) = let thisExecutable = Assembly.GetEntryAssembly().Location - let appData = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) - let ipythonDir = Path.Combine(appData, ".ipython") - let profileDir = Path.Combine(ipythonDir, "profile_ifsharp") - let kernelDir = Path.Combine([| ipythonDir; "kernels" ; "ifsharp" |] ) - let staticDir = Path.Combine(profileDir, "static") + let userDir = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); + let kernelDir = Config.KernelDir + let staticDir = Config.StaticDir + let tempDir = Config.TempDir let customDir = Path.Combine(staticDir, "custom") let createDir(str) = if Directory.Exists(str) = false then Directory.CreateDirectory(str) |> ignore - createDir appData - createDir ipythonDir - createDir profileDir + createDir kernelDir createDir staticDir + createDir tempDir createDir customDir - createDir kernelDir - let configFile = Path.Combine(profileDir, "ipython_config.py") - let configqtFile = Path.Combine(profileDir, "ipython_qtconsole_config.py") + let configFile = Path.Combine(kernelDir, "ipython_config.py") + let configqtFile = Path.Combine(kernelDir, "ipython_qtconsole_config.py") let kernelFile = Path.Combine(kernelDir, "kernel.json") if forceInstall || (File.Exists(configFile) = false) then @@ -175,10 +172,10 @@ module App = let codeTemplate = IfSharpResources.ipython_config() let code = match Environment.OSVersion.Platform with - | PlatformID.Win32Windows -> codeTemplate.Replace("\"mono\",", "") - | PlatformID.Win32NT -> codeTemplate.Replace("\"mono\",", "") + | PlatformID.Win32Windows | PlatformID.Win32NT -> codeTemplate.Replace("\"mono\",", "") | _ -> codeTemplate - let code = code.Replace("%s", thisExecutable) + let code = code.Replace("%kexe", thisExecutable) + let code = code.Replace("%kstatic", staticDir) printfn "Saving custom config file [%s]" configFile File.WriteAllText(configFile, code) @@ -191,27 +188,27 @@ module App = printfn "Saving custom logo [%s]" logoFile IfSharpResources.ifsharp_logo().Save(logoFile) - // write custom css file - let cssFile = Path.Combine(customDir, "custom.css") - printfn "Saving custom css [%s]" cssFile - File.WriteAllText(cssFile, IfSharpResources.custom_css()) + // write fsharp css file + let cssFile = Path.Combine(customDir, "fsharp.css") + printfn "Saving fsharp css [%s]" cssFile + File.WriteAllText(cssFile, IfSharpResources.fsharp_css()) - // write custom js file - let jsFile = Path.Combine(customDir, "custom.js") - printfn "Saving custom js [%s]" jsFile - File.WriteAllText(jsFile, IfSharpResources.custom_js()) + // write kernel js file + let jsFile = Path.Combine(kernelDir, "kernel.js") + printfn "Saving kernel js [%s]" jsFile + File.WriteAllText(jsFile, IfSharpResources.kernel_js()) // write fsharp js file let jsFile = Path.Combine(customDir, "fsharp.js") printfn "Saving fsharp js [%s]" jsFile File.WriteAllText(jsFile, IfSharpResources.fsharp_js()) - // write fsharp js file + // write webintellisense js file let jsFile = Path.Combine(customDir, "webintellisense.js") printfn "Saving webintellisense js [%s]" jsFile File.WriteAllText(jsFile, IfSharpResources.webintellisense_js()) - // write fsharp js file + // write webintellisense-codemirror js file let jsFile = Path.Combine(customDir, "webintellisense-codemirror.js") printfn "Saving webintellisense-codemirror js [%s]" jsFile File.WriteAllText(jsFile, IfSharpResources.webintellisense_codemirror_js()) @@ -237,12 +234,12 @@ module App = printfn "Starting ipython..." let p = new Process() - p.StartInfo.FileName <- "ipython" - p.StartInfo.Arguments <- "notebook --profile ifsharp" - p.StartInfo.WorkingDirectory <- appData + p.StartInfo.FileName <- "jupyter" + p.StartInfo.Arguments <- "notebook --config=" + configFile + p.StartInfo.WorkingDirectory <- userDir // tell the user something bad happened - if p.Start() = false then printfn "Unable to start ipython, please install ipython first" + if p.Start() = false then printfn "Unable to start jupyter, please install jupyter first" /// First argument must be an ipython connection file, blocks forever let Start (args : array) = @@ -252,11 +249,14 @@ module App = InstallAndStart(true) else + // Clear the temporary folder + try + if Directory.Exists(Config.TempDir) then Directory.Delete(Config.TempDir, true) + with exc -> Console.Out.Write(exc.ToString()) // adds the default display printers Printers.addDefaultDisplayPrinters() - // get connection information let fileName = args.[0] let json = File.ReadAllText(fileName) diff --git a/src/IfSharp.Kernel/Config.fs b/src/IfSharp.Kernel/Config.fs index cccf015..79e31c9 100644 --- a/src/IfSharp.Kernel/Config.fs +++ b/src/IfSharp.Kernel/Config.fs @@ -2,6 +2,7 @@ open System open System.Configuration +open System.IO /// Convenience method for getting a setting with a default value let defaultConfig (name : string, defaultValue) = @@ -9,4 +10,22 @@ let defaultConfig (name : string, defaultValue) = if value = null then defaultValue else value // the configuration properties -let DefaultNuGetSource = defaultConfig("DefaultNuGetSource", "") \ No newline at end of file +let DefaultNuGetSource = defaultConfig("DefaultNuGetSource", "") + +let KernelDir = + let thisExecutable = System.Reflection.Assembly.GetEntryAssembly().Location + let userDir = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); + let appData = + match Environment.OSVersion.Platform with + | PlatformID.Win32Windows | PlatformID.Win32NT -> Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + | PlatformID.MacOSX -> Path.Combine(userDir, "Library") + | _ -> Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) // PlatformID.Unix + let jupyterDir = + match Environment.OSVersion.Platform with + | PlatformID.Unix -> Path.Combine(appData, "jupyter") + | _ -> Path.Combine(appData, "Jupyter") + let kernelsDir = Path.Combine(jupyterDir, "kernels") + let kernelDir = Path.Combine(kernelsDir, "ifsharp") + kernelDir +let StaticDir = Path.Combine(KernelDir, "static") +let TempDir = Path.Combine(StaticDir, "temp"); \ No newline at end of file diff --git a/src/IfSharp.Kernel/IfSharp.Kernel.fsproj b/src/IfSharp.Kernel/IfSharp.Kernel.fsproj index 2553332..8011468 100644 --- a/src/IfSharp.Kernel/IfSharp.Kernel.fsproj +++ b/src/IfSharp.Kernel/IfSharp.Kernel.fsproj @@ -100,7 +100,6 @@ ..\..\packages\FSharp.Charting.0.90.5\lib\net40\FSharp.Charting.dll - True ..\..\packages\FSharp.Compiler.Service.0.0.81\lib\net45\FSharp.Compiler.Service.dll @@ -128,6 +127,7 @@ +