Skip to content

Commit

Permalink
demo lsp hover method results (#31)
Browse files Browse the repository at this point in the history
  • Loading branch information
spacedragon authored Jun 30, 2018
1 parent 60ed615 commit 4ca28cf
Show file tree
Hide file tree
Showing 10 changed files with 243 additions and 678 deletions.
4 changes: 3 additions & 1 deletion kibana-extra/castro/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"@types/hapi": "^15.0.0",
"@types/nodegit": "^0.18.8",
"@types/react": "^16.3.16",
"@types/react-dom": "^16.0.6",
"@types/react-redux": "^6.0.2",
"@types/redux-actions": "^2.3.0",
"babel-eslint": "^8.0.2",
Expand All @@ -41,7 +42,8 @@
"highlights": "^3.1.1",
"javascript-typescript-langserver": "^2.10.0",
"lsp-proxy": "link:../../lsp-proxy",
"nodegit": "^0.22.1",
"popper.js": "^1.14.3",
"react-dom": "^16.4.1",
"react-redux": "^5.0.7",
"redux": "^4.0.0",
"redux-actions": "^2.4.0",
Expand Down
110 changes: 110 additions & 0 deletions kibana-extra/castro/public/components/main/FileCode.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import React, {DOMElement} from "react";
import ReactDOM from 'react-dom';

import {
EuiCode,
EuiGlobalToastList
} from '@elastic/eui';
import {LspRestClient, TextDocumentMethods} from "../../../common/LspClient";

interface Props {
file: string,
html: string
}

interface Toast {
title: string,
text: string
}

interface State {
toasts: Toast[],
}

let toastId = 0;

export default class FileCode extends React.Component<Props, State> {

private lspMethods: TextDocumentMethods;


constructor(props: Props, context: any) {
super(props, context);
let lspClient = new LspRestClient("/lsp", {"kbn-xsrf": "1"})
this.lspMethods = new TextDocumentMethods(lspClient);
this.mouseOut = this.mouseOut.bind(this);
this.mouseOver = this.mouseOver.bind(this);
this.state = {
toasts : []
}
}
addToast = (toast) => {
this.setState({
toasts: this.state.toasts.concat(toast),
});
};

mouseOver(e: Event) {
const target = e.target as Element;
let lineNum = target.getAttribute("data-line");
let range = target.getAttribute("data-range");
if (lineNum && range) {


this.lspMethods.hover.send({
position: {
line: parseInt(lineNum),
character: parseInt(range.split(",")[0])
},
textDocument: {
uri: `file://${this.props.file}`
}
}).then(hover => {
if(hover.contents.length >0) {
let content = hover.contents[0];
this.addToast({
id: toastId ++,
title: content.language,
text: content.value
})
}

}, err => {

});
}
}



mouseOut(e: Event) {
this.setState({
toasts: []
})
}
removeToast = (removedToast) => {
this.setState(prevState => ({
toasts: prevState.toasts.filter(toast => toast.id !== removedToast.id),
}));
};

componentDidMount(): void {
const el = ReactDOM.findDOMNode(this) as Element;
el.querySelectorAll(".code-line span").forEach(el => {
el.addEventListener('mouseover', this.mouseOver);
el.addEventListener('mouseout', this.mouseOut);
})

}

render() {
return <div>
<EuiCode dangerouslySetInnerHTML={{__html: this.props.html}}/>
<EuiGlobalToastList
toasts={this.state.toasts}
dismissToast={this.removeToast}
toastLifeTimeMs={6000}
/>
</div>
}
}
24 changes: 14 additions & 10 deletions kibana-extra/castro/public/components/main/code.css
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,36 @@



.string {
.code .string {
color: #DD0A73;
}

.numeric,
.variable {
.code .numeric,
.code .variable {
color: #00A69B;
}
.keyword,
.primitive,
.modifier {
.code .keyword,
.code .primitive,
.code .modifier {
color: #333;
font-weight: bold;
}

.type,
.class {
.code .type,
.code .class {
color: #0079a5;
font-weight: bold;
}

.symbol {
.code .symbol {
text-decoration: underline;
}

.code .annotation {
position: relative;
display: inline;
}

.parameter {
.code .parameter {
color: inherit;
}
8 changes: 4 additions & 4 deletions kibana-extra/castro/public/components/main/code.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ import {
EuiCode,
EuiCodeBlock,
} from '@elastic/eui';

import FileCode from './FileCode';
import "./code.css"

interface State {
path: string
content: string,
html? : string
html?: string
}

export default class Code extends React.Component<any, State> {
Expand Down Expand Up @@ -81,8 +81,8 @@ export default class Code extends React.Component<any, State> {
</EuiForm>
<EuiSpacer size="xl"/>
<EuiPanel paddingSize="l" hasShadow>
{ this.state.html &&
<EuiCode dangerouslySetInnerHTML={{ __html: this.state.html }} />
{this.state.html &&
<FileCode html={this.state.html} file={this.state.path}/>
}
</EuiPanel>
<EuiPanel paddingSize="l" hasShadow>
Expand Down
44 changes: 8 additions & 36 deletions kibana-extra/castro/public/components/main/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
} from "@elastic/eui";

import { Commit, Entry } from '../../../../../model/build/swagger-code-tsClient/api';

import FileCode from './FileCode';
import Code from './code';
import Counter from '../counter';

Expand All @@ -26,15 +26,15 @@ interface MainProps {
}

interface MainState {
workspace: string,
entries: Entry[],
commitInfo: Array<{title: string, description?: string | null }>
}

export class Main extends React.Component<MainProps, MainState> {
constructor(props: MainProps) {
super(props);
this.state = {
commitInfo: [],
workspace: "",
entries: []
};
}
Expand All @@ -46,28 +46,7 @@ export class Main extends React.Component<MainProps, MainState> {
*/
const {httpClient} = this.props;
httpClient.get("../api/castro/example").then((resp: any) => {
const data: Commit = resp.data;
const commitInfo = [
{
title: "Commit",
description: data.commit
},
{
title: "Date",
description: data.date
},
{
title: "Committer",
description: data.committer
},
{
title: "Message",
description: data.message
}
];
let entries = data.entries || [];

this.setState({commitInfo, entries: entries});
this.setState({...resp.data});
});
}

Expand All @@ -84,34 +63,27 @@ export class Main extends React.Component<MainProps, MainState> {
<EuiPageContent>
<EuiPageContentHeader>
<EuiTitle>
<h2>Current Commit</h2>
<h2>{this.state.workspace}</h2>
</EuiTitle>
</EuiPageContentHeader>
<EuiPageContentBody>
<Counter />

<EuiDescriptionList
type="column"
listItems={this.state.commitInfo}
style={{maxWidth: '800px'}}
/>
<EuiSpacer size="xl"/>
<Code httpClient={this.props.httpClient}/>
<EuiSpacer size="xl"/>
<EuiTitle>
<h2>Changed files</h2>
<h2>Files</h2>
</EuiTitle>
<EuiSpacer size="xs"/>
{
this.state.entries.map((entry, idx) =>
<EuiAccordion
id={"fid" + idx}
key={"fid" + idx}
buttonContent={entry.path}
>
buttonContent={entry.path}>
{
entry.html &&
<EuiCode dangerouslySetInnerHTML={{ __html: entry.html }} />
<FileCode html={entry.html} file={`${this.state.workspace}/${entry.path}`} />
}
</EuiAccordion>
)
Expand Down
27 changes: 10 additions & 17 deletions kibana-extra/castro/server/highlights.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
const Highlights = require('highlights');
const highlighter = new Highlights();
const Selector = require('first-mate-select-grammar');
import {DocumentSymbolParams, SymbolInformation} from "vscode-languageserver";

highlighter.loadGrammarsSync();

Expand All @@ -22,6 +21,10 @@ interface Range {
pos?: number // position in file
}

interface Node {
token: Token
children: Token[]
}

export function tokenizeLines(filePath: string, fileContents: string): CodeLine[] {
const grammar = selector.selectGrammar(highlighter.registry, filePath, fileContents);
Expand All @@ -33,10 +36,11 @@ export function tokenizeLines(filePath: string, fileContents: string): CodeLine[
}

export function computeRanges(lines: CodeLine[]) {

let pos = 0;
for (let line of lines) {
let start = 0;

let start = 0;
for (let token of line) {
let len = token.value.length;
token.range = {
Expand All @@ -51,30 +55,19 @@ export function computeRanges(lines: CodeLine[]) {
}
}

export function mergeSymbols(codeLines: CodeLine[], symbols: SymbolInformation[]) {
for (const symbol of symbols) {
const {start, end} = symbol.location.range;
const codeLine = codeLines[start.line];
if (codeLine) {
for (const token of codeLine) {
if (token.range.start == start.character && token.range.end == end.character) {
token.scopes.push('symbol')
}
}
}
}
}

export function render(lines: CodeLine[]) : string{
let output = "<pre class='code'>";
let lineNum = 0;
for(let line of lines) {

output += "<div class='code-line'>";
for(let token of line){
let lastScope = token.scopes[token.scopes.length - 1];
const clazz = lastScope.replace(/\./g, " ");
output += `<span class="${clazz}">${highlighter.escapeString(token.value)}</span>`
output += `<span data-line="${lineNum}" data-range="${token.range.start},${token.range.end}" class="${clazz}">${highlighter.escapeString(token.value)}</span>`
}
output += "\n</div>";
lineNum ++;
}

return output + "</pre>"
Expand Down
Loading

0 comments on commit 4ca28cf

Please sign in to comment.