Skip to content

Commit

Permalink
feat(codeaction): add showDocumantaion action by client side (#16)
Browse files Browse the repository at this point in the history
  • Loading branch information
yaegassy authored Jun 21, 2023
1 parent 4813d1f commit 1121835
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ To use the built-in installation feature, execute the following command.
- `ruff.disableHover`: Disable hover only, default: `false`
- `ruff.useDetectRuffCommand`: Automatically detects the ruff command in the execution environment and sets `ruff.path`, default: `true`
- `ruff.autoFixOnSave`: Turns auto fix on save on or off, default: `false`
- `ruff.client.codeAction.showDocumantaion.enable`: Whether to display the code action for open the Ruff rule documentation web page included in the diagnostic information, default: `false`
- `ruff.serverPath`: Custom path to the `ruff-lsp` command. If not set, the `ruff-lsp` command found in the current Python environment or in the venv environment created for the extension will be used, default: `""`
- `ruff.builtin.pythonPath`: Python 3.x path (Absolute path) to be used for built-in install, default: `""`
- `ruff.trace.server`: Traces the communication between coc.nvim and the ruff-lsp, default: `"off"`
Expand Down
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@
"default": false,
"description": "Disable hover only."
},
"ruff.client.codeAction.showDocumantaion.enable": {
"type": "boolean",
"default": false,
"description": "Whether to display the code action for open the Ruff rule documentation web page included in the diagnostic information."
},
"ruff.useDetectRuffCommand": {
"type": "boolean",
"default": true,
Expand Down
114 changes: 114 additions & 0 deletions src/features/showDocumentation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import {
CodeAction,
CodeActionContext,
CodeActionProvider,
Diagnostic,
DocumentSelector,
ExtensionContext,
LanguageClient,
languages,
Range,
TextDocument,
workspace,
} from 'coc.nvim';

type AdditionalDiagnostic = {
codeDescription?: {
href?: string;
};
};

type RuffDiagnostic = Diagnostic & AdditionalDiagnostic;

type RuffRuleContents = {
id: string | number;
href: string;
};

export async function register(context: ExtensionContext, client: LanguageClient) {
await client.onReady();

if (!workspace.getConfiguration('ruff').get<boolean>('client.codeAction.showDocumantaion.enable', false)) return;

const documentSelector: DocumentSelector = [{ scheme: 'file', language: 'python' }];

context.subscriptions.push(
languages.registerCodeActionProvider(documentSelector, new ShowDocumentationCodeActionProvider(client), 'ruff')
);
}

class ShowDocumentationCodeActionProvider implements CodeActionProvider {
private readonly source = 'Ruff';
private client: LanguageClient;

constructor(client: LanguageClient) {
this.client = client;
}

public async provideCodeActions(document: TextDocument, range: Range, context: CodeActionContext) {
const doc = workspace.getDocument(document.uri);
const wholeRange = Range.create(0, 0, doc.lineCount, 0);
let whole = false;
if (
range.start.line === wholeRange.start.line &&
range.start.character === wholeRange.start.character &&
range.end.line === wholeRange.end.line &&
range.end.character === wholeRange.end.character
) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
whole = true;
}
const codeActions: CodeAction[] = [];

/** Show web documentation for [ruleId] */
if (this.lineRange(range) && context.diagnostics.length > 0) {
const line = doc.getline(range.start.line);
if (line && line.length) {
const ruffRuleContents: RuffRuleContents[] = [];
context.diagnostics.forEach((d) => {
if (d.source === this.source) {
if ('codeDescription' in d) {
const ruffDiagnostic = d as RuffDiagnostic;
if (ruffDiagnostic.codeDescription?.href) {
if (ruffDiagnostic.code) {
ruffRuleContents.push({
id: ruffDiagnostic.code,
href: ruffDiagnostic.codeDescription.href,
});
}
}
}
}
});

if (ruffRuleContents) {
ruffRuleContents.forEach((r) => {
const title = `Ruff (${r.id}): Show documentation [coc-ruff]`;

const command = {
title: '',
command: 'vscode.open',
arguments: [r.href],
};

const action: CodeAction = {
title,
command,
};

codeActions.push(action);
});
}
}
}

return codeActions;
}

private lineRange(r: Range): boolean {
return (
(r.start.line + 1 === r.end.line && r.start.character === 0 && r.end.character === 0) ||
(r.start.line === r.end.line && r.start.character === 0)
);
}
}
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import * as executeAutofixCommandFeature from './commands/executeAutofix';
import * as executeOrganizeImportsCommandFeature from './commands/executeOrganizeImports';
import * as restartCommandFeature from './commands/restart';
import * as autoFixOnSaveFeature from './features/autoFixOnSave';
import * as showDocumentationCodeActionFeature from './features/showDocumentation';
import { getRuffLspPath } from './tool';

let client: LanguageClient | undefined;
Expand Down Expand Up @@ -39,4 +40,5 @@ export async function activate(context: ExtensionContext): Promise<void> {
executeOrganizeImportsCommandFeature.activate(context, client);
restartCommandFeature.activate(context, client);
autoFixOnSaveFeature.register(client);
showDocumentationCodeActionFeature.register(context, client);
}

0 comments on commit 1121835

Please sign in to comment.