Skip to content

Commit 0b7f622

Browse files
zhaogeJackWang032
authored andcommitted
feat: support hover provider feat
1 parent 9ec899c commit 0b7f622

File tree

11 files changed

+180
-16
lines changed

11 files changed

+180
-16
lines changed

src/languageFeatures.ts

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { ParseError } from 'dt-sql-parser';
2+
import { ColumnEntityContext, CommonEntityContext, EntityContextType } from 'dt-sql-parser';
23
import { EntityContext } from 'dt-sql-parser/dist/parser/common/entityCollector';
34
import { WordPosition } from 'dt-sql-parser/dist/parser/common/textAndWord';
45
import * as monaco from 'monaco-editor';
@@ -17,6 +18,16 @@ import {
1718
} from './fillers/monaco-editor-core';
1819
import type { CompletionSnippet, LanguageServiceDefaults } from './monaco.contribution';
1920

21+
export interface ColumnInfo {
22+
/** 字段名 */
23+
column: string;
24+
/** 字段类型 */
25+
type: string | undefined;
26+
/** 注释 */
27+
comment?: string;
28+
/** 别名 */
29+
alias?: string;
30+
}
2031
export interface WorkerAccessor<T extends BaseSQLWorker> {
2132
(...uris: Uri[]): Promise<T>;
2233
}
@@ -352,3 +363,105 @@ export class ReferenceAdapter<T extends BaseSQLWorker> implements languages.Refe
352363
});
353364
}
354365
}
366+
/**
367+
* The adapter is for the hover provider interface defines the contract between extensions and
368+
* the [hover](https://code.visualstudio.com/docs/editor/intellisense)-feature.
369+
**/
370+
export class HoverAdapter<T extends BaseSQLWorker> implements languages.HoverProvider {
371+
constructor(
372+
private readonly _worker: WorkerAccessor<T>,
373+
private readonly _defaults: LanguageServiceDefaults
374+
) {}
375+
provideHover(
376+
model: editor.IReadOnlyModel,
377+
position: Position,
378+
_token: CancellationToken
379+
): languages.ProviderResult<languages.Hover> {
380+
const resource = model.uri;
381+
const lineContent = model.getLineContent(position.lineNumber);
382+
if (lineContent.trim().startsWith('--')) return null;
383+
return this._worker(resource)
384+
.then((worker) => {
385+
let code = model?.getValue() || '';
386+
if (typeof this._defaults.preprocessCode === 'function') {
387+
code = this._defaults.preprocessCode(code);
388+
}
389+
return worker.getAllEntities(code, position);
390+
})
391+
.then((entities) => {
392+
if (!entities || !entities.length) return null;
393+
const curEntity = entities.find((entity: EntityContext) => {
394+
const p = entity.position;
395+
return (
396+
p.startColumn <= position.column &&
397+
p.endColumn >= position.column &&
398+
p.line === position.lineNumber
399+
);
400+
});
401+
if (!curEntity) return null;
402+
const tableCreate = curEntity ? findTableCreateEntity(curEntity, entities) : null;
403+
const columns = tableCreate ? toColumnsInfo(tableCreate) || [] : [];
404+
const columnsDesc = columns.reduce((res, cur) => {
405+
const { column, type, comment, alias } = cur;
406+
return (
407+
res +
408+
`\`${column}\` ${type ? `&nbsp;&nbsp; **${type}**` : ''} ${
409+
comment ? `&nbsp;&nbsp; *${comment}*` : ''
410+
} ${alias ? `&nbsp;&nbsp; *${alias}*` : ''} \n`
411+
);
412+
}, '');
413+
const pos = curEntity.position;
414+
const range = new monaco.Range(pos.line, pos.startColumn, pos.line, pos.endColumn);
415+
const contents: monaco.IMarkdownString[] = [
416+
{ value: `**${curEntity.text}**` },
417+
{ value: columnsDesc }
418+
];
419+
return { contents, range };
420+
});
421+
}
422+
}
423+
424+
export function isTableCreateEntity(en: EntityContext): en is CommonEntityContext {
425+
return en.entityContextType === EntityContextType.TABLE_CREATE;
426+
}
427+
/**
428+
* According to the table name or table entity field, get the corresponding create table information
429+
*/
430+
export function findTableCreateEntity(
431+
tableEntity: EntityContext | string,
432+
allEntities: EntityContext[]
433+
): CommonEntityContext | null {
434+
if (
435+
typeof tableEntity !== 'string' &&
436+
tableEntity.entityContextType !== EntityContextType.TABLE
437+
) {
438+
return null;
439+
}
440+
441+
const tableName: string = typeof tableEntity === 'string' ? tableEntity : tableEntity.text;
442+
return (
443+
allEntities.find(
444+
(en): en is CommonEntityContext =>
445+
en.entityContextType === EntityContextType.TABLE_CREATE && en.text === tableName
446+
) ?? null
447+
);
448+
}
449+
450+
/**
451+
* Transform table create entity to columns info
452+
*/
453+
export function toColumnsInfo(tableEntity: CommonEntityContext): ColumnInfo[] | null {
454+
if (!tableEntity) return null;
455+
if (tableEntity.entityContextType !== EntityContextType.TABLE_CREATE) return null;
456+
if (!tableEntity.columns?.length) return null;
457+
const columnsInfo: ColumnInfo[] = [];
458+
tableEntity.columns.forEach((col: ColumnEntityContext) => {
459+
columnsInfo.push({
460+
column: col.text,
461+
type: col._colType?.text,
462+
comment: col._comment?.text,
463+
alias: col._alias?.text
464+
});
465+
});
466+
return columnsInfo;
467+
}

src/languages/flink/flink.contribution.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ registerLanguage({
1717
setupLanguageFeatures(LanguageIdEnum.FLINK, {
1818
completionItems: true,
1919
diagnostics: true,
20-
references: true,
21-
definitions: true
20+
references: false,
21+
definitions: false,
22+
hover: false
2223
});

src/languages/hive/hive.contribution.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ registerLanguage({
1717
setupLanguageFeatures(LanguageIdEnum.HIVE, {
1818
completionItems: true,
1919
diagnostics: true,
20-
references: true,
21-
definitions: true
20+
references: false,
21+
definitions: false,
22+
hover: false
2223
});

src/languages/impala/impala.contribution.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ registerLanguage({
1717
setupLanguageFeatures(LanguageIdEnum.IMPALA, {
1818
completionItems: true,
1919
diagnostics: true,
20-
references: true,
21-
definitions: true
20+
references: false,
21+
definitions: false,
22+
hover: false
2223
});

src/languages/mysql/mysql.contribution.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ registerLanguage({
1717
setupLanguageFeatures(LanguageIdEnum.MYSQL, {
1818
completionItems: true,
1919
diagnostics: true,
20-
references: true,
21-
definitions: true
20+
references: false,
21+
definitions: false,
22+
hover: false
2223
});

src/languages/pgsql/pgsql.contribution.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ registerLanguage({
1717
setupLanguageFeatures(LanguageIdEnum.PG, {
1818
completionItems: true,
1919
diagnostics: true,
20-
references: true,
21-
definitions: true
20+
references: false,
21+
definitions: false,
22+
hover: false
2223
});

src/languages/spark/spark.contribution.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ registerLanguage({
1717
setupLanguageFeatures(LanguageIdEnum.SPARK, {
1818
completionItems: true,
1919
diagnostics: true,
20-
references: true,
21-
definitions: true
20+
references: false,
21+
definitions: false,
22+
hover: false
2223
});

src/monaco.contribution.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,10 @@ export interface ModeConfiguration {
9090
* Defines whether the built-in references provider is enabled.
9191
*/
9292
readonly references?: boolean;
93+
/**
94+
* Defines whether the built-in hover provider is enabled.
95+
*/
96+
readonly hover?: boolean;
9397
}
9498

9599
/**
@@ -205,6 +209,7 @@ export const modeConfigurationDefault: Required<ModeConfiguration> = {
205209
triggerCharacters: ['.', ' ']
206210
},
207211
diagnostics: true,
208-
definitions: true,
209-
references: true
212+
definitions: false,
213+
references: false,
214+
hover: false
210215
};

src/setupLanguageFeatures.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ export interface FeatureConfiguration {
2929
* Defines whether the built-in references provider is enabled.
3030
*/
3131
references?: boolean;
32+
/**
33+
* Defines whether the built-in hover provider is enabled.
34+
*/
35+
hover?: boolean;
3236
/**
3337
* Define a function to preprocess code.
3438
* By default, do not something.
@@ -148,6 +152,10 @@ function processConfiguration(
148152
typeof configuration.definitions === 'boolean'
149153
? configuration.definitions
150154
: (defaults?.modeConfiguration.definitions ?? modeConfigurationDefault.definitions);
155+
const hover =
156+
typeof configuration.hover === 'boolean'
157+
? configuration.hover
158+
: (defaults?.modeConfiguration.hover ?? modeConfigurationDefault.hover);
151159

152160
const snippets =
153161
typeof configuration.completionItems !== 'boolean' &&
@@ -165,6 +173,7 @@ function processConfiguration(
165173
snippets
166174
},
167175
references,
168-
definitions
176+
definitions,
177+
hover
169178
};
170179
}

src/setupLanguageMode.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,14 @@ export function setupLanguageMode<T extends BaseSQLWorker>(
5151
)
5252
);
5353
}
54+
if (modeConfiguration.hover) {
55+
providers.push(
56+
languages.registerHoverProvider(
57+
languageId,
58+
new languageFeatures.HoverAdapter(worker, defaults)
59+
)
60+
);
61+
}
5462
}
5563

5664
registerProviders();

0 commit comments

Comments
 (0)