Skip to content

Commit

Permalink
Add vscode extension support
Browse files Browse the repository at this point in the history
  • Loading branch information
chriscerie committed Oct 15, 2023
1 parent 31bf18e commit e145e82
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 6 deletions.
53 changes: 51 additions & 2 deletions selene-vscode/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ import * as selene from "./selene"
import * as timers from "timers"
import * as util from "./util"
import * as vscode from "vscode"
import { Diagnostic, Severity, Label } from "./structures/diagnostic"
import {
Diagnostic,
Severity,
Label,
SeleneDiagnostic,
} from "./structures/diagnostic"
import { Output } from "./structures/output"
import { lintConfig } from "./configLint"
import { byteToCharMap } from "./byteToCharMap"
Expand All @@ -18,6 +23,42 @@ enum RunType {
OnIdle = "onIdle",
}

class SeleneCodeActionProvider implements vscode.CodeActionProvider {
public provideCodeActions(
document: vscode.TextDocument,
_range: vscode.Range | vscode.Selection,
context: vscode.CodeActionContext,
_token: vscode.CancellationToken,
): vscode.ProviderResult<vscode.Command[] | vscode.CodeAction[]> {
// You can retrieve the diagnostic from the context, then decide what action to provide.
const codeActions: vscode.CodeAction[] = []

for (const diagnostic of context.diagnostics) {
if (
diagnostic instanceof SeleneDiagnostic &&
diagnostic.fixed_code
) {
const action = new vscode.CodeAction(
`fix: ${diagnostic.message}`,
vscode.CodeActionKind.QuickFix,
)
action.diagnostics = [diagnostic]

action.edit = new vscode.WorkspaceEdit()
action.edit.replace(
document.uri,
diagnostic.range,
diagnostic.fixed_code,
)

codeActions.push(action)
}
}

return codeActions
}
}

function labelToRange(
document: vscode.TextDocument,
label: Label,
Expand Down Expand Up @@ -73,6 +114,13 @@ export async function activate(

await trySelene

context.subscriptions.push(
vscode.languages.registerCodeActionsProvider(
"lua",
new SeleneCodeActionProvider(),
),
)

context.subscriptions.push(
vscode.commands.registerCommand("selene.reinstall", () => {
trySelene = util
Expand Down Expand Up @@ -204,12 +252,13 @@ export async function activate(
message += `\n${data.notes.map((note) => `note: ${note}\n`)}`
}

const diagnostic = new vscode.Diagnostic(
const diagnostic = new SeleneDiagnostic(
labelToRange(document, data.primary_label, byteOffsetMap),
message,
data.severity === Severity.Error
? vscode.DiagnosticSeverity.Error
: vscode.DiagnosticSeverity.Warning,
data.fixed_code,
)

diagnostic.source = `selene::${data.code}`
Expand Down
12 changes: 12 additions & 0 deletions selene-vscode/src/structures/diagnostic.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import * as vscode from "vscode"

export interface Label {
message: string
span: {
Expand All @@ -18,4 +20,14 @@ export interface Diagnostic {
notes: string[]
primary_label: Label
secondary_labels: Label[]
fixed_code: string
}

export class SeleneDiagnostic extends vscode.Diagnostic {
fixed_code?: string;

constructor(range: vscode.Range, message: string, severity: vscode.DiagnosticSeverity, fixed_code?: string) {
super(range, message, severity);
this.fixed_code = fixed_code;
}
}
3 changes: 3 additions & 0 deletions selene/src/json_output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ pub struct JsonDiagnostic {
primary_label: Label,
notes: Vec<String>,
secondary_labels: Vec<Label>,
fixed_code: Option<String>,
}

#[derive(Serialize)]
Expand Down Expand Up @@ -77,6 +78,7 @@ fn label_to_serializable(
pub fn diagnostic_to_json(
diagnostic: &CodespanDiagnostic<codespan::FileId>,
files: &codespan::Files<&str>,
fixed_code: Option<String>,
) -> JsonDiagnostic {
let label = diagnostic.labels.first().expect("no labels passed");
let filename = files.name(label.file_id).to_string_lossy().into_owned();
Expand All @@ -93,6 +95,7 @@ pub fn diagnostic_to_json(
.filter(|label| label.style == LabelStyle::Secondary)
.map(|label| label_to_serializable(&filename, label, files))
.collect(),
fixed_code,
}
}

Expand Down
13 changes: 9 additions & 4 deletions selene/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ fn emit_codespan(
writer: &mut impl termcolor::WriteColor,
files: &codespan::Files<&str>,
diagnostic: &CodespanDiagnostic<codespan::FileId>,
fixed_code: Option<String>,
) {
let lock = OPTIONS.read().unwrap();
let opts = lock.as_ref().unwrap();
Expand All @@ -148,7 +149,10 @@ fn emit_codespan(
writeln!(
writer,
"{}",
serde_json::to_string(&json_output::diagnostic_to_json(diagnostic, files)).unwrap()
serde_json::to_string(&json_output::diagnostic_to_json(
diagnostic, files, fixed_code
))
.unwrap()
)
.unwrap();
}
Expand All @@ -158,7 +162,7 @@ fn emit_codespan(
writer,
"{}",
serde_json::to_string(&json_output::JsonOutput::Diagnostic(
json_output::diagnostic_to_json(diagnostic, files)
json_output::diagnostic_to_json(diagnostic, files, fixed_code)
))
.unwrap()
)
Expand All @@ -179,7 +183,7 @@ fn emit_codespan_locked(
let stdout = termcolor::StandardStream::stdout(get_color());
let mut stdout = stdout.lock();

emit_codespan(&mut stdout, files, diagnostic);
emit_codespan(&mut stdout, files, diagnostic, None);
}

fn replace_code_range(code: &str, start: usize, end: usize, replacement: &str) -> String {
Expand Down Expand Up @@ -491,6 +495,7 @@ fn read<R: Read>(
write(&mut stack, new_start).unwrap();
}
} else {
let fixed_code = diagnostic.diagnostic.fixed_code.clone();
let diagnostic = diagnostic.diagnostic.into_codespan_diagnostic(
source_id,
match diagnostic.severity {
Expand All @@ -500,7 +505,7 @@ fn read<R: Read>(
},
);

emit_codespan(&mut stdout, &files, &diagnostic);
emit_codespan(&mut stdout, &files, &diagnostic, fixed_code);
}
}
}
Expand Down

0 comments on commit e145e82

Please sign in to comment.