From 96d9a227e0076fa63f9aa9d051fe7c659efd0a98 Mon Sep 17 00:00:00 2001 From: Nicolas Gagliani Date: Thu, 22 Oct 2015 00:00:02 +0200 Subject: [PATCH 01/10] Add a repl that opens in an atom tab --- keymaps/language-idris.json | 1 + lib/idris-controller.coffee | 20 +++++++ lib/language-idris.coffee | 12 ++++ lib/utils/highlighter.coffee | 9 +++ lib/views/panel-view.coffee | 20 +++++++ lib/views/repl-view.coffee | 112 +++++++++++++++++++++++++++++++++++ package.json | 4 +- styles/repl.less | 26 ++++++++ 8 files changed, 203 insertions(+), 1 deletion(-) create mode 100644 lib/views/panel-view.coffee create mode 100644 lib/views/repl-view.coffee create mode 100644 styles/repl.less diff --git a/keymaps/language-idris.json b/keymaps/language-idris.json index 63964a2..c52549b 100644 --- a/keymaps/language-idris.json +++ b/keymaps/language-idris.json @@ -5,6 +5,7 @@ "ctrl-alt-a": "language-idris:add-clause", "ctrl-alt-s": "language-idris:proof-search", "ctrl-alt-d": "language-idris:docs-for", + "ctrl-alt-enter": "language-idris:open-repl", "ctrl-alt-w": "language-idris:make-with", "ctrl-alt-l": "language-idris:make-lemma", "ctrl-alt-r": "language-idris:typecheck", diff --git a/lib/idris-controller.coffee b/lib/idris-controller.coffee index 393e718..165a027 100644 --- a/lib/idris-controller.coffee +++ b/lib/idris-controller.coffee @@ -6,6 +6,9 @@ Logger = require './Logger' IdrisModel = require './idris-model' Ipkg = require './utils/ipkg' Symbol = require './utils/symbol' +Cycle = require '@cycle/core' +PanelView = require './views/panel-view' +REPLView = require './views/repl-view' editorHelper = require './utils/editor' class IdrisController @@ -23,6 +26,7 @@ class IdrisController 'language-idris:typecheck': @runCommand @typecheckFile 'language-idris:print-definition': @runCommand @printDefinition 'language-idris:stop-compiler': @stopCompiler + 'language-idris:open-repl': @runCommand @openREPL isIdrisFile: (uri) -> uri?.match? /\.idr$/ @@ -337,6 +341,22 @@ class IdrisController .printDefinition word .subscribe successHandler, @displayErrors + openREPL: ({ target }) => + editor = target.model + uri = editor.getURI() + + successHandler = ({ responseType, msg }) => + options = + split: 'right' + searchAllPanes: true + + atom.workspace.open "idris://repl", options + + @model + .load uri + .filter ({ responseType }) -> responseType == 'return' + .subscribe successHandler, @displayErrors + displayErrors: (err) => @messages.show() @messages.clear() diff --git a/lib/language-idris.coffee b/lib/language-idris.coffee index d5d49be..07aa7ca 100644 --- a/lib/language-idris.coffee +++ b/lib/language-idris.coffee @@ -1,5 +1,7 @@ IdrisController = require './idris-controller' { CompositeDisposable } = require 'atom' +url = require 'url' +{ IdrisPanel } = require './views/panel-view' module.exports = config: @@ -28,6 +30,16 @@ module.exports = @subscriptions = new CompositeDisposable @subscriptions.add subscription + atom.workspace.addOpener (uriToOpen, options) => + try + { protocol, host, pathname } = url.parse uriToOpen + catch error + return + + return unless protocol is 'idris:' + + new IdrisPanel @controller, host + deactivate: -> @subscriptions.dispose() this.controller.destroy() diff --git a/lib/utils/highlighter.coffee b/lib/utils/highlighter.coffee index 4788b70..f70414c 100644 --- a/lib/utils/highlighter.coffee +++ b/lib/utils/highlighter.coffee @@ -1,6 +1,8 @@ # Applies the highlighting we get from the idris compiler to our source code. # http://docs.idris-lang.org/en/latest/reference/ide-protocol.html#output-highlighting +CycleDOM = require '@cycle/dom' + highlightInfoListToOb = (list) -> obj = { } for x in list @@ -80,8 +82,15 @@ highlightToHtml = (highlights) -> container.appendChild span container +highlightToCycle = (highlights) -> + highlights.map ({classes, word}) -> + if classes.length == 0 + word + else + CycleDOM.h 'span', { className: classes.join(' ') }, word module.exports = highlight: highlight highlightToString: highlightToString highlightToHtml: highlightToHtml + highlightToCycle: highlightToCycle diff --git a/lib/views/panel-view.coffee b/lib/views/panel-view.coffee new file mode 100644 index 0000000..06224e2 --- /dev/null +++ b/lib/views/panel-view.coffee @@ -0,0 +1,20 @@ +REPLView = require './repl-view' + +class IdrisPanel + constructor: (@controller, @panel) -> + + getTitle: -> + switch @panel + when "repl" then "Idris Repl" + else "Idris ?" + + getViewClass: -> + switch @panel + when "repl" then REPLView + + getURI: -> + switch @panel + when "repl" then "idris://repl" + +module.exports = + IdrisPanel: IdrisPanel diff --git a/lib/views/repl-view.coffee b/lib/views/repl-view.coffee new file mode 100644 index 0000000..0004de3 --- /dev/null +++ b/lib/views/repl-view.coffee @@ -0,0 +1,112 @@ +Cycle = require '@cycle/core' +CycleDOM = require '@cycle/dom' +highlighter = require '../utils/highlighter' + +fontOptions = () -> + fontSize = atom.config.get 'language-idris.panelFontSize' + fontSizeAttr = "#{fontSize}px" + enableLigatures = atom.config.get 'language-idris.panelFontLigatures' + webkitFontFeatureSettings = + if enableLigatures + '"liga"' + else + '"inherit"' + + fontFamily = atom.config.get 'language-idris.panelFontFamily' + if fontFamily != '' + fontFamily + else + '"inherit"' + + 'font-size': fontSizeAttr + '-webkit-font-feature-settings': webkitFontFeatureSettings + 'font-family': fontFamily + +REPLCycle = + # highlight : forall a. + # { code : String, highlightInformation : HighlightInformation } -> + # CycleDOM + highlight: ({ code, highlightInformation }) -> + highlights = highlighter.highlight code, highlightInformation + highlighter.highlightToCycle highlights + + # view : Observable State -> Observable CycleDOM + view: (state$) -> + styles = fontOptions() + + state$.map (lines) -> + lines = lines.map (line) -> + highlightedCode = REPLCycle.highlight line + CycleDOM.h 'div', + { + className: 'idris-repl-line' + style: styles + }, + [ + CycleDOM.h 'div', { className: 'idris-repl-input' }, + [ + CycleDOM.h 'span', { className: 'idris-repl-input-prompt' }, '> ' + line.input + ] + CycleDOM.h 'pre', + { + className: 'idris-repl-output' + style: styles + }, + [ + highlightedCode + ] + ] + + CycleDOM.h 'div', + { + className: 'idris-panel-view' + }, + [ + CycleDOM.h 'input', { type: 'text', className: 'native-key-bindings idris-repl-input-field' }, 'toggle' + CycleDOM.h 'div', lines + ] + + main: (responses) -> + input = responses.DOM.select('input').events('keydown') + .filter (ev) -> ev.keyCode == 13 + .map (ev) -> ev.target.value + .startWith '' + + DOM: REPLCycle.view responses.CONTENT + CONTENT: input + + # driver : forall a. + # IdrisModel -> Observable String -> + # Observable (List { a | code : String, highlightInformation : highlightInformation }) + driver: + (options) -> + DOM: CycleDOM.makeDOMDriver options.hostElement + CONTENT: (inp) -> + inp + .filter (line) -> line != '' + .flatMap (line) -> + escapedLine = line.replace(/"/g, '\\"') + options.model.interpret escapedLine + .map (e) -> + input: line + code: e.msg[0] + highlightInformation: e.msg[1] + .scan ((acc, x) -> [x].concat acc), [] + .startWith [] + +class REPLView + constructor: (params) -> + hostElement = document.createElement 'div' + @[0] = hostElement + + model = params.controller.model + + drivers = + REPLCycle.driver + hostElement: hostElement + model: model + + Cycle.run REPLCycle.main, drivers + +module.exports = REPLView diff --git a/package.json b/package.json index 1f1d764..5806b24 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,8 @@ "atom-message-panel": ">=0.1.0", "bennu": "17.3.0", "nu-stream": "3.3.1", - "rx-lite": "2.5.2" + "rx-lite": "4.0.0", + "@cycle/core": "3.1.0", + "@cycle/dom": "5.3.0" } } diff --git a/styles/repl.less b/styles/repl.less new file mode 100644 index 0000000..de7fe5a --- /dev/null +++ b/styles/repl.less @@ -0,0 +1,26 @@ +@import "ui-variables"; + +.idris-repl-input-field +{ + width: 100%; + padding-left: 10px; + padding-top: 5px; + padding-bottom: 5px; +} + +.repl.idris +{ + font-size: 1.3em; + min-height: 150px; + background-color: @pane-item-background-color; +} + +.idris-repl-line +{ + margin: 10px; + + .idris-repl-input + { + margin-bottom: 10px; + } +} From 7f44aca57b427c32a72273b61bf1ccca6ede221f Mon Sep 17 00:00:00 2001 From: Nicolas Gagliani Date: Thu, 22 Oct 2015 01:50:28 +0200 Subject: [PATCH 02/10] Added an "apropos" panel --- lib/idris-controller.coffee | 17 +++++++ lib/idris-model.coffee | 3 ++ lib/views/apropos-view.coffee | 94 +++++++++++++++++++++++++++++++++++ lib/views/panel-view.coffee | 6 ++- 4 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 lib/views/apropos-view.coffee diff --git a/lib/idris-controller.coffee b/lib/idris-controller.coffee index 165a027..7ececf1 100644 --- a/lib/idris-controller.coffee +++ b/lib/idris-controller.coffee @@ -27,6 +27,7 @@ class IdrisController 'language-idris:print-definition': @runCommand @printDefinition 'language-idris:stop-compiler': @stopCompiler 'language-idris:open-repl': @runCommand @openREPL + 'language-idris:apropos': @runCommand @apropos isIdrisFile: (uri) -> uri?.match? /\.idr$/ @@ -357,6 +358,22 @@ class IdrisController .filter ({ responseType }) -> responseType == 'return' .subscribe successHandler, @displayErrors + apropos: ({ target }) => + editor = target.model + uri = editor.getURI() + + successHandler = ({ responseType, msg }) => + options = + split: 'right' + searchAllPanes: true + + atom.workspace.open "idris://apropos", options + + @model + .load uri + .filter ({ responseType }) -> responseType == 'return' + .subscribe successHandler, @displayErrors + displayErrors: (err) => @messages.show() @messages.clear() diff --git a/lib/idris-model.coffee b/lib/idris-model.coffee index dff337b..25551bd 100644 --- a/lib/idris-model.coffee +++ b/lib/idris-model.coffee @@ -127,4 +127,7 @@ class IdrisModel printDefinition: (name) -> @prepareCommand [':print-definition', name] + apropos: (name) -> + @prepareCommand [':apropos', name] + module.exports = IdrisModel diff --git a/lib/views/apropos-view.coffee b/lib/views/apropos-view.coffee new file mode 100644 index 0000000..6adb402 --- /dev/null +++ b/lib/views/apropos-view.coffee @@ -0,0 +1,94 @@ +Cycle = require '@cycle/core' +CycleDOM = require '@cycle/dom' +highlighter = require '../utils/highlighter' + +fontOptions = () -> + fontSize = atom.config.get 'language-idris.panelFontSize' + fontSizeAttr = "#{fontSize}px" + enableLigatures = atom.config.get 'language-idris.panelFontLigatures' + webkitFontFeatureSettings = + if enableLigatures + '"liga"' + else + '"inherit"' + + fontFamily = atom.config.get 'language-idris.panelFontFamily' + if fontFamily != '' + fontFamily + else + '"inherit"' + + 'font-size': fontSizeAttr + '-webkit-font-feature-settings': webkitFontFeatureSettings + 'font-family': fontFamily + +AproposCycle = + # highlight : forall a. + # { code : String, highlightInformation : HighlightInformation } -> + # CycleDOM + highlight: ({ code, highlightInformation }) -> + highlights = highlighter.highlight code, highlightInformation + highlighter.highlightToCycle highlights + + # view : Observable State -> Observable CycleDOM + view: (state$) -> + styles = fontOptions() + + state$.map (apropos) -> + aproposAnswer = + if apropos.code + highlightedCode = AproposCycle.highlight apropos + CycleDOM.h 'pre', { className: 'idris-apropos-output', style: styles }, highlightedCode + else + CycleDOM.h 'span', '' + + CycleDOM.h 'div', + { + className: 'idris-panel-view' + }, + [ + CycleDOM.h 'input', { type: 'text', className: 'native-key-bindings idris-repl-input-field' }, 'toggle' + CycleDOM.h 'div', aproposAnswer + ] + + main: (responses) -> + input = responses.DOM.select('input').events('keydown') + .filter (ev) -> ev.keyCode == 13 + .map (ev) -> ev.target.value + .startWith '' + + DOM: AproposCycle.view responses.CONTENT + CONTENT: input + + # driver : forall a. + # IdrisModel -> Observable String -> + # Observable (List { a | code : String, highlightInformation : highlightInformation }) + driver: + (options) -> + DOM: CycleDOM.makeDOMDriver options.hostElement + CONTENT: (inp) -> + inp + .filter (line) -> line != '' + .flatMap (line) -> + escapedLine = line.replace(/"/g, '\\"') + options.model.apropos escapedLine + .map (e) -> + code: e.msg[0] + highlightInformation: e.msg[1] + .startWith {} + +class AproposView + constructor: (params) -> + hostElement = document.createElement 'div' + @[0] = hostElement + + model = params.controller.model + + drivers = + AproposCycle.driver + hostElement: hostElement + model: model + + Cycle.run AproposCycle.main, drivers + +module.exports = AproposView diff --git a/lib/views/panel-view.coffee b/lib/views/panel-view.coffee index 06224e2..230df85 100644 --- a/lib/views/panel-view.coffee +++ b/lib/views/panel-view.coffee @@ -1,20 +1,24 @@ REPLView = require './repl-view' +AproposView = require './apropos-view' class IdrisPanel constructor: (@controller, @panel) -> getTitle: -> switch @panel - when "repl" then "Idris Repl" + when "repl" then "Idris: REPL" + when "apropos" then "Idris: Apropos" else "Idris ?" getViewClass: -> switch @panel when "repl" then REPLView + when "apropos" then AproposView getURI: -> switch @panel when "repl" then "idris://repl" + when "apropos" then "idris://apropos" module.exports = IdrisPanel: IdrisPanel From 022208a6c4041c55090fa9ddf9130a4b933733e9 Mon Sep 17 00:00:00 2001 From: Nicolas Gagliani Date: Sat, 24 Oct 2015 01:57:50 +0200 Subject: [PATCH 03/10] Don't crash when handling errors --- lib/views/repl-view.coffee | 58 ++++++++++++++++++++++++++------------ 1 file changed, 40 insertions(+), 18 deletions(-) diff --git a/lib/views/repl-view.coffee b/lib/views/repl-view.coffee index 0004de3..7b471c4 100644 --- a/lib/views/repl-view.coffee +++ b/lib/views/repl-view.coffee @@ -1,6 +1,7 @@ Cycle = require '@cycle/core' CycleDOM = require '@cycle/dom' highlighter = require '../utils/highlighter' +Rx = require 'rx-lite' fontOptions = () -> fontSize = atom.config.get 'language-idris.panelFontSize' @@ -22,21 +23,41 @@ fontOptions = () -> '-webkit-font-feature-settings': webkitFontFeatureSettings 'font-family': fontFamily -REPLCycle = - # highlight : forall a. - # { code : String, highlightInformation : HighlightInformation } -> - # CycleDOM - highlight: ({ code, highlightInformation }) -> - highlights = highlighter.highlight code, highlightInformation - highlighter.highlightToCycle highlights +styles = fontOptions() + +# highlight : forall a. +# { code : String, highlightInformation : HighlightInformation } -> +# CycleDOM +highlight = ({ code, highlightInformation }) -> + highlights = highlighter.highlight code, highlightInformation + highlighter.highlightToCycle highlights + +displaySuccess = (line) -> + highlightedCode = highlight line + + CycleDOM.h 'pre', + { + className: 'idris-repl-output' + style: styles + }, + [ + highlightedCode + ] + +displayError = (line) -> + CycleDOM.h 'pre', { }, line.message +REPLCycle = # view : Observable State -> Observable CycleDOM view: (state$) -> - styles = fontOptions() - state$.map (lines) -> lines = lines.map (line) -> - highlightedCode = REPLCycle.highlight line + answer = + if line.type == 'success' + displaySuccess line + else + displayError line + CycleDOM.h 'div', { className: 'idris-repl-line' @@ -48,14 +69,7 @@ REPLCycle = CycleDOM.h 'span', { className: 'idris-repl-input-prompt' }, '> ' line.input ] - CycleDOM.h 'pre', - { - className: 'idris-repl-output' - style: styles - }, - [ - highlightedCode - ] + answer ] CycleDOM.h 'div', @@ -89,9 +103,17 @@ REPLCycle = escapedLine = line.replace(/"/g, '\\"') options.model.interpret escapedLine .map (e) -> + type: 'success' input: line code: e.msg[0] highlightInformation: e.msg[1] + .catch (e) -> + error = + input: line + type: 'error' + message: e.message + warnings: e.warnings + Rx.Observable.just error .scan ((acc, x) -> [x].concat acc), [] .startWith [] From 4e24529fccc945b5c34a7a0c6be164023ef71b8a Mon Sep 17 00:00:00 2001 From: Nicolas Gagliani Date: Sat, 24 Oct 2015 02:09:51 +0200 Subject: [PATCH 04/10] Highlight errors too --- lib/idris-model.coffee | 1 + lib/views/repl-view.coffee | 14 ++++++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/lib/idris-model.coffee b/lib/idris-model.coffee index 25551bd..b88ac43 100644 --- a/lib/idris-model.coffee +++ b/lib/idris-model.coffee @@ -48,6 +48,7 @@ class IdrisModel subject.onError message: ret[1] warnings: @warnings[id] + highlightInformation: ret[2] subject.onCompleted() delete @subjects[id] when ':write-string' diff --git a/lib/views/repl-view.coffee b/lib/views/repl-view.coffee index 7b471c4..cadd9d7 100644 --- a/lib/views/repl-view.coffee +++ b/lib/views/repl-view.coffee @@ -29,8 +29,11 @@ styles = fontOptions() # { code : String, highlightInformation : HighlightInformation } -> # CycleDOM highlight = ({ code, highlightInformation }) -> - highlights = highlighter.highlight code, highlightInformation - highlighter.highlightToCycle highlights + if highlightInformation + highlights = highlighter.highlight code, highlightInformation + highlighter.highlightToCycle highlights + else + code displaySuccess = (line) -> highlightedCode = highlight line @@ -45,7 +48,9 @@ displaySuccess = (line) -> ] displayError = (line) -> - CycleDOM.h 'pre', { }, line.message + highlightedCode = highlight line + + CycleDOM.h 'pre', { }, highlightedCode REPLCycle = # view : Observable State -> Observable CycleDOM @@ -111,8 +116,9 @@ REPLCycle = error = input: line type: 'error' - message: e.message + code: e.message warnings: e.warnings + highlightInformation: e.highlightInformation Rx.Observable.just error .scan ((acc, x) -> [x].concat acc), [] .startWith [] From e73c8657a3e23d769e9ea2032d9666479f6ce9e2 Mon Sep 17 00:00:00 2001 From: Nicolas Gagliani Date: Sat, 24 Oct 2015 02:46:40 +0200 Subject: [PATCH 05/10] Trick the sexp-formatter so that i can send commands like ":help" in the REPL --- lib/utils/sexp-formatter.coffee | 2 +- lib/views/repl-view.coffee | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/utils/sexp-formatter.coffee b/lib/utils/sexp-formatter.coffee index eabd8ff..65d7027 100644 --- a/lib/utils/sexp-formatter.coffee +++ b/lib/utils/sexp-formatter.coffee @@ -27,7 +27,7 @@ formatSexp = (sexp) -> else if isSymbol sexp sexp else if isString sexp - '"' + sexp + '"' + '"' + sexp.trim() + '"' else if isBoolean sexp if sexp ':True' diff --git a/lib/views/repl-view.coffee b/lib/views/repl-view.coffee index cadd9d7..41ece2a 100644 --- a/lib/views/repl-view.coffee +++ b/lib/views/repl-view.coffee @@ -106,7 +106,9 @@ REPLCycle = .filter (line) -> line != '' .flatMap (line) -> escapedLine = line.replace(/"/g, '\\"') - options.model.interpret escapedLine + # append a space to trick the formatter, so that it wont turn + # the input into a symbol + options.model.interpret "#{escapedLine} " .map (e) -> type: 'success' input: line From 5fae7dbc7822182d0a8bcf47b047446f3708618d Mon Sep 17 00:00:00 2001 From: Nicolas Gagliani Date: Sat, 24 Oct 2015 02:47:04 +0200 Subject: [PATCH 06/10] Add scrolling to the REPL output --- lib/views/repl-view.coffee | 2 +- styles/repl.less | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/views/repl-view.coffee b/lib/views/repl-view.coffee index 41ece2a..9490991 100644 --- a/lib/views/repl-view.coffee +++ b/lib/views/repl-view.coffee @@ -83,7 +83,7 @@ REPLCycle = }, [ CycleDOM.h 'input', { type: 'text', className: 'native-key-bindings idris-repl-input-field' }, 'toggle' - CycleDOM.h 'div', lines + CycleDOM.h 'div', { className: 'idris-repl-lines' }, lines ] main: (responses) -> diff --git a/styles/repl.less b/styles/repl.less index de7fe5a..ccfcf4a 100644 --- a/styles/repl.less +++ b/styles/repl.less @@ -8,6 +8,17 @@ padding-bottom: 5px; } +.idris-panel-view +{ + height: 100%; + + .idris-repl-lines + { + height: 100%; + overflow: scroll; + } +} + .repl.idris { font-size: 1.3em; From 32b9389324aa34ade1c02f371b00d128a2905b32 Mon Sep 17 00:00:00 2001 From: Nicolas Gagliani Date: Sat, 24 Oct 2015 18:35:15 +0200 Subject: [PATCH 07/10] Clean up for the merge into master --- lib/idris-controller.coffee | 24 +++++++++++------------ lib/utils/dom.coffee | 22 +++++++++++++++++++++ lib/views/apropos-view.coffee | 36 ++++++++++++----------------------- lib/views/repl-view.coffee | 26 ++----------------------- 4 files changed, 48 insertions(+), 60 deletions(-) diff --git a/lib/idris-controller.coffee b/lib/idris-controller.coffee index 7ececf1..1d28c43 100644 --- a/lib/idris-controller.coffee +++ b/lib/idris-controller.coffee @@ -346,7 +346,7 @@ class IdrisController editor = target.model uri = editor.getURI() - successHandler = ({ responseType, msg }) => + successHandler = ({ responseType, msg }) -> options = split: 'right' searchAllPanes: true @@ -359,20 +359,20 @@ class IdrisController .subscribe successHandler, @displayErrors apropos: ({ target }) => - editor = target.model - uri = editor.getURI() + editor = target.model + uri = editor.getURI() - successHandler = ({ responseType, msg }) => - options = - split: 'right' - searchAllPanes: true + successHandler = ({ responseType, msg }) -> + options = + split: 'right' + searchAllPanes: true - atom.workspace.open "idris://apropos", options + atom.workspace.open "idris://apropos", options - @model - .load uri - .filter ({ responseType }) -> responseType == 'return' - .subscribe successHandler, @displayErrors + @model + .load uri + .filter ({ responseType }) -> responseType == 'return' + .subscribe successHandler, @displayErrors displayErrors: (err) => @messages.show() diff --git a/lib/utils/dom.coffee b/lib/utils/dom.coffee index 533a3e7..1d3d06c 100644 --- a/lib/utils/dom.coffee +++ b/lib/utils/dom.coffee @@ -16,6 +16,28 @@ createCodeElement = -> pre.style.webkitFontFeatureSettings = '"liga"' pre +fontOptions = -> + fontSize = atom.config.get 'language-idris.panelFontSize' + fontSizeAttr = "#{fontSize}px" + enableLigatures = atom.config.get 'language-idris.panelFontLigatures' + webkitFontFeatureSettings = + if enableLigatures + '"liga"' + else + '"inherit"' + + fontFamily = atom.config.get 'language-idris.panelFontFamily' + if fontFamily != '' + fontFamily + else + '"inherit"' + + 'font-size': fontSizeAttr + '-webkit-font-feature-settings': webkitFontFeatureSettings + 'font-family': fontFamily + + module.exports = joinHtmlElements: joinHtmlElements createCodeElement: createCodeElement + fontOptions: fontOptions diff --git a/lib/views/apropos-view.coffee b/lib/views/apropos-view.coffee index 6adb402..2bc7c70 100644 --- a/lib/views/apropos-view.coffee +++ b/lib/views/apropos-view.coffee @@ -1,26 +1,10 @@ Cycle = require '@cycle/core' CycleDOM = require '@cycle/dom' highlighter = require '../utils/highlighter' +Rx = require 'rx-lite' +{ fontOptions } = require '../utils/dom' -fontOptions = () -> - fontSize = atom.config.get 'language-idris.panelFontSize' - fontSizeAttr = "#{fontSize}px" - enableLigatures = atom.config.get 'language-idris.panelFontLigatures' - webkitFontFeatureSettings = - if enableLigatures - '"liga"' - else - '"inherit"' - - fontFamily = atom.config.get 'language-idris.panelFontFamily' - if fontFamily != '' - fontFamily - else - '"inherit"' - - 'font-size': fontSizeAttr - '-webkit-font-feature-settings': webkitFontFeatureSettings - 'font-family': fontFamily +styles = fontOptions() AproposCycle = # highlight : forall a. @@ -47,7 +31,7 @@ AproposCycle = className: 'idris-panel-view' }, [ - CycleDOM.h 'input', { type: 'text', className: 'native-key-bindings idris-repl-input-field' }, 'toggle' + CycleDOM.h 'input', { type: 'text', className: 'native-key-bindings idris-repl-input-field' }, '' CycleDOM.h 'div', aproposAnswer ] @@ -72,10 +56,14 @@ AproposCycle = .flatMap (line) -> escapedLine = line.replace(/"/g, '\\"') options.model.apropos escapedLine - .map (e) -> - code: e.msg[0] - highlightInformation: e.msg[1] - .startWith {} + .map (e) -> + code: e.msg[0] + highlightInformation: e.msg[1] + .catch (e) -> + Rx.Observable.just + code: e.message + highlightInformation: e.highlightInformation + .startWith { } class AproposView constructor: (params) -> diff --git a/lib/views/repl-view.coffee b/lib/views/repl-view.coffee index 9490991..29035c0 100644 --- a/lib/views/repl-view.coffee +++ b/lib/views/repl-view.coffee @@ -2,26 +2,7 @@ Cycle = require '@cycle/core' CycleDOM = require '@cycle/dom' highlighter = require '../utils/highlighter' Rx = require 'rx-lite' - -fontOptions = () -> - fontSize = atom.config.get 'language-idris.panelFontSize' - fontSizeAttr = "#{fontSize}px" - enableLigatures = atom.config.get 'language-idris.panelFontLigatures' - webkitFontFeatureSettings = - if enableLigatures - '"liga"' - else - '"inherit"' - - fontFamily = atom.config.get 'language-idris.panelFontFamily' - if fontFamily != '' - fontFamily - else - '"inherit"' - - 'font-size': fontSizeAttr - '-webkit-font-feature-settings': webkitFontFeatureSettings - 'font-family': fontFamily +{ fontOptions } = require '../utils/dom' styles = fontOptions() @@ -82,7 +63,7 @@ REPLCycle = className: 'idris-panel-view' }, [ - CycleDOM.h 'input', { type: 'text', className: 'native-key-bindings idris-repl-input-field' }, 'toggle' + CycleDOM.h 'input', { type: 'text', className: 'native-key-bindings idris-repl-input-field' }, '' CycleDOM.h 'div', { className: 'idris-repl-lines' }, lines ] @@ -95,9 +76,6 @@ REPLCycle = DOM: REPLCycle.view responses.CONTENT CONTENT: input - # driver : forall a. - # IdrisModel -> Observable String -> - # Observable (List { a | code : String, highlightInformation : highlightInformation }) driver: (options) -> DOM: CycleDOM.makeDOMDriver options.hostElement From 68b8500d8a8d1497e6fe39d4d3249a493149d5d0 Mon Sep 17 00:00:00 2001 From: Nicolas Gagliani Date: Sat, 24 Oct 2015 19:11:03 +0200 Subject: [PATCH 08/10] Use tooltips to display more information on the highlighted words --- lib/utils/highlighter.coffee | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/utils/highlighter.coffee b/lib/utils/highlighter.coffee index f70414c..8ce7057 100644 --- a/lib/utils/highlighter.coffee +++ b/lib/utils/highlighter.coffee @@ -23,8 +23,18 @@ decorToClasses = (decor) -> else [] highlightWord = (word, info) -> + type = info.info.type || "" + doc = info.info['doc-overview'] || "" + + description = + if info.info.type? + "#{type}\n\n#{doc}".trim() + else + "" + classes: decorToClasses(info.info.decor).concat 'idris' word: word + description: description # Build highlighting information that we can then pass to one # of our serializers. @@ -83,11 +93,11 @@ highlightToHtml = (highlights) -> container highlightToCycle = (highlights) -> - highlights.map ({classes, word}) -> + highlights.map ({ classes, word, description }) -> if classes.length == 0 word else - CycleDOM.h 'span', { className: classes.join(' ') }, word + CycleDOM.h 'span', { className: classes.join(' '), title: description }, word module.exports = highlight: highlight From e9ab5dce565e84e49c54ce49b6a517a8fd496948 Mon Sep 17 00:00:00 2001 From: Nicolas Gagliani Date: Sat, 24 Oct 2015 19:11:26 +0200 Subject: [PATCH 09/10] Add the two new features to the changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 76e6ee2..2cbc38d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ ### Added +- Added a REPL [#80](https://github.com/idris-hackers/atom-language-idris/pull/80) +- Added a panel for the `apropos` command + ### Fixed ## v0.3.4 From dc2a0414ff614e40c37b6be34cd9386723955f11 Mon Sep 17 00:00:00 2001 From: Nicolas Gagliani Date: Sat, 24 Oct 2015 19:23:43 +0200 Subject: [PATCH 10/10] Last cleanup before the merge --- lib/idris-controller.coffee | 3 --- lib/views/apropos-view.coffee | 2 -- lib/views/repl-view.coffee | 7 +++---- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/lib/idris-controller.coffee b/lib/idris-controller.coffee index 1d28c43..d9dd42c 100644 --- a/lib/idris-controller.coffee +++ b/lib/idris-controller.coffee @@ -6,9 +6,6 @@ Logger = require './Logger' IdrisModel = require './idris-model' Ipkg = require './utils/ipkg' Symbol = require './utils/symbol' -Cycle = require '@cycle/core' -PanelView = require './views/panel-view' -REPLView = require './views/repl-view' editorHelper = require './utils/editor' class IdrisController diff --git a/lib/views/apropos-view.coffee b/lib/views/apropos-view.coffee index 2bc7c70..28b4a8b 100644 --- a/lib/views/apropos-view.coffee +++ b/lib/views/apropos-view.coffee @@ -16,8 +16,6 @@ AproposCycle = # view : Observable State -> Observable CycleDOM view: (state$) -> - styles = fontOptions() - state$.map (apropos) -> aproposAnswer = if apropos.code diff --git a/lib/views/repl-view.coffee b/lib/views/repl-view.coffee index 29035c0..85a10d6 100644 --- a/lib/views/repl-view.coffee +++ b/lib/views/repl-view.coffee @@ -93,13 +93,12 @@ REPLCycle = code: e.msg[0] highlightInformation: e.msg[1] .catch (e) -> - error = - input: line + Rx.Observable.just type: 'error' + input: line code: e.message - warnings: e.warnings highlightInformation: e.highlightInformation - Rx.Observable.just error + warnings: e.warnings .scan ((acc, x) -> [x].concat acc), [] .startWith []