Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 0 additions & 9 deletions lib/typings/cycle-core.d.ts

This file was deleted.

4 changes: 0 additions & 4 deletions lib/typings/cycle-dom.d.ts

This file was deleted.

53 changes: 34 additions & 19 deletions lib/utils/highlighter.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import * as CycleDOM from '@cycle/dom'
import * as Preact from 'preact'
import Logger from './Logger'

const highlightInfoListToOb = (list: any) => {
export type HighlightInformation = {
classes: Array<string>
word: string
description: string
}

const highlightInfoListToOb = (list: Array<any>) => {
const obj: { [key: string]: any } = {}
for (let x of list) {
const key = x[0].slice(1)
Expand All @@ -13,7 +19,7 @@ const highlightInfoListToOb = (list: any) => {

// Use the right CSS classes, so that we can use the
// syntax highlighting built into atom.
const decorToClasses = (decor: any) => {
const decorToClasses = (decor: string) => {
switch (decor) {
case ':type':
return ['syntax--storage', 'syntax--type']
Expand All @@ -36,7 +42,7 @@ const decorToClasses = (decor: any) => {
}
}

const highlightWord = (word: string, info: any) => {
const highlightWord = (word: string, info: any): HighlightInformation => {
const type = info.info.type || ''
const doc = info.info['doc-overview'] || ''

Expand All @@ -51,22 +57,26 @@ const highlightWord = (word: string, info: any) => {

// Build highlighting information that we can then pass to one
// of our serializers.
export const highlight = (code: string, highlightingInfo: any) => {
export const highlight = (
code: string,
highlightingInfo: Array<[number, number, Array<any>]>,
): Array<HighlightInformation> => {
const highlighted = highlightingInfo
.map(function ([start, length, info]: [any, any, any]) {
.map(function ([start, length, info]) {
return {
start,
length,
info: highlightInfoListToOb(info),
}
})
.filter((i: any) => i.info.decor != null)
.reduce(
([position, text]: any, info: any) => {
.filter((i) => i.info.decor != null)
.reduce<[number, Array<HighlightInformation>]>(
([position, text], info) => {
const newPosition = info.start + info.length
const unhighlightedText = {
const unhighlightedText: HighlightInformation = {
classes: [],
word: code.slice(position, info.start),
description: '',
}
const highlightedWord = highlightWord(
code.slice(info.start, newPosition),
Expand All @@ -79,10 +89,11 @@ export const highlight = (code: string, highlightingInfo: any) => {
[0, []],
)

const [position, text] = Array.from(highlighted)
const [position, text] = highlighted
const rest = {
classes: [],
word: code.slice(position),
description: '',
}
const higlightedWords = text.concat(rest)
return higlightedWords.filter(
Expand All @@ -91,9 +102,9 @@ export const highlight = (code: string, highlightingInfo: any) => {
}

// Applies the highlighting and returns the result as an html-string.
export const highlightToString = (highlights: any) =>
export const highlightToString = (highlights: Array<HighlightInformation>) =>
highlights
.map(function ({ classes, word }: any) {
.map(function ({ classes, word }) {
if (classes.length === 0) {
return word
} else {
Expand All @@ -103,8 +114,8 @@ export const highlightToString = (highlights: any) =>
.join('')

// Applies the highlighting and returns the result as a DOM-objects.
export const highlightToHtml = (highlights: any) => {
const spans = highlights.map(function ({ classes, word }: any) {
export const highlightToHtml = (highlights: Array<HighlightInformation>) => {
const spans = highlights.map(function ({ classes, word }) {
if (classes.length === 0) {
return document.createTextNode(word)
} else {
Expand All @@ -119,15 +130,19 @@ export const highlightToHtml = (highlights: any) => {
return container
}

export const highlightToCycle = (highlights: any) =>
highlights.map(({ classes, word, description }: any) => {
export const highlightToPreact = (
highlights: Array<HighlightInformation>,
): Preact.VNode => {
const highlighted = highlights.map(({ classes, word, description }) => {
if (classes.length === 0) {
return word
return word as string
} else {
return CycleDOM.h(
return Preact.h(
'span',
{ className: classes.join(' '), title: description },
word,
)
}
})
return Preact.h('div', {}, highlighted)
}
118 changes: 0 additions & 118 deletions lib/views/apropos-view.ts

This file was deleted.

95 changes: 95 additions & 0 deletions lib/views/apropos-view.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import * as Preact from 'preact'
import { useState, StateUpdater } from 'preact/hooks'
import * as highlighter from '../utils/highlighter'
import * as Rx from 'rx-lite'
import { fontOptions } from '../utils/dom'
import { IdrisController } from '../idris-controller'
import { IdrisModel } from '../idris-model'
import { HighlightInformation } from '../utils/highlighter'

const styles = fontOptions()

const ask = (
model: IdrisModel,
question: string,
setAnswer: StateUpdater<Array<HighlightInformation>>,
) => {
model
.apropos(question)
.map((e: any): {
code: string
highlightInfo: Array<[number, number, Array<any>]>
} => ({
code: e.msg[0],
highlightInfo: e.msg[1],
}))
.catch((e: any) =>
Rx.Observable.just({
code: e.message,
highlightInfo: e.highlightInformation,
}),
)
.subscribe(
({ code, highlightInfo }) => {
const answer = highlighter.highlight(code, highlightInfo)
setAnswer(answer)
},
(err) =>
setAnswer([
{ word: err.message, classes: [], description: '' },
]),
)
}

type AnswerProps = { highlightInfo: Array<HighlightInformation> }

const Answer: Preact.FunctionComponent<AnswerProps> = (props) => {
const { highlightInfo } = props
return (
<pre className="idris-apropos-output" style={styles}>
{highlighter.highlightToPreact(highlightInfo)}
</pre>
)
}

type AproposProps = { model: IdrisModel }

const Apropos: Preact.FunctionComponent<AproposProps> = (props) => {
const { model } = props
const [input, setInput] = useState<string>('')
const [answer, setAnswer] = useState<Array<HighlightInformation>>([])

return (
<div className="idris-panel-view">
<input
type="text"
className="native-key-bindings idris-repl-input-field"
onInput={(e) => {
setInput(e.currentTarget.value)
}}
onKeyPress={(e) => {
if (e.keyCode === 13) {
ask(model, input, setAnswer)
}
}}
>
{input}
</input>
<div className="idris-repl-lines">
<Answer highlightInfo={answer} />
</div>
</div>
)
}

export class AproposView {
0: HTMLDivElement = document.createElement('div')

constructor(params: { controller: IdrisController }) {
const hostElement = this[0]

const { model } = params.controller

Preact.render(<Apropos model={model} />, hostElement)
}
}
Loading