Skip to content

Commit

Permalink
add new code lens and grammar for SF APIs
Browse files Browse the repository at this point in the history
  • Loading branch information
Codeneos committed Dec 16, 2023
1 parent 7381203 commit 80289b8
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 18 deletions.
16 changes: 16 additions & 0 deletions packages/vscode-extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -1275,6 +1275,11 @@
"language": "vldp",
"scopeName": "source.json",
"path": "./syntax/datapack.tmLanguage.json"
},
{
"language": "sfhttp",
"scopeName": "source.sfhttp",
"path": "./syntax/sfhttp.tmLanguage.json"
}
],
"languages": [
Expand All @@ -1290,6 +1295,16 @@
],
"configuration": "./syntax/datapack-language.json"
},
{
"id": "sfhttp",
"aliases": [
"Salesforce HTTP API"
],
"extensions": [
".sfhttp",
".http"
]
},
{
"id": "xml",
"extensions": [
Expand Down Expand Up @@ -1578,6 +1593,7 @@
"vsce": "^2.15.0",
"vscode-languageclient": "^8.1.0",
"vscode-test": "^1.6.1",
"vscode-tmgrammar-test": "^0.1.2",
"webpack": "^5.88.2",
"webpack-cli": "^5.1.4",
"webpack-glob-entry": "^2.1.1",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import * as vscode from 'vscode';

import VlocodeService from "../lib/vlocodeService";
import { container, injectable } from "@vlocode/core";

@injectable()
export class ExecuteApiLensProvider implements vscode.CodeLensProvider {

private regex = /^(GET|POST|PUT|DELETE|PATCH) (.*)$/i

public static register(service: VlocodeService) {
const lens = container.get(ExecuteApiLensProvider);
vscode.languages.registerCodeLensProvider({ pattern: '**/*.{api,http,sfhttp,sfapi}' }, lens);
vscode.languages.registerCodeLensProvider({ language: 'sfhttp' }, lens);
}

public provideCodeLenses(document: vscode.TextDocument): vscode.CodeLens[] {
for (let i = 0; i < document.lineCount; i++) {
const line = document.lineAt(i);
const match = line.text.match(this.regex);
if (match) {
return [
new vscode.CodeLens(line.range, {
title: `Execute as Salesforce API Request (${match[1].toLowerCase()})`,
tooltip: "Execute the API request described in this file on the selected Salesforce org",
command: "vlocode.api.execute",
arguments: [ document ]
})
];
} else if (line.text) {
break;
}
}
return [];
}
}
7 changes: 5 additions & 2 deletions packages/vscode-extension/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { VlocityNamespaceService } from '@vlocode/vlocity';
import { SfdxConfigWatcher } from './lib/sfdxConfigWatcher';

import './commands';
import { ExecuteApiLensProvider } from './codeLensProviders/executeApiLensProvider';

/**
* Start time of the extension set when the extension is packed by webpack when the entry point is loaded
Expand Down Expand Up @@ -205,16 +206,18 @@ class Vlocode {

// Add apex LOG symbol provider
try {
this.service.registerDisposable(vscode.languages.registerDocumentSymbolProvider({ language: 'apexlog' }, new ApexLogSymbolProvider()));
ApexLogSymbolProvider.register(this.service);
} catch(err) {
this.logger.warn(`Unable to register symbol provider for APEX logs: ${err}`);
}

ExecuteApiLensProvider.register(this.service);

// Watch conditionalContextMenus for changes
ConfigurationManager.onConfigChange(this.service.config, 'conditionalContextMenus',
config => vscode.commands.executeCommand('setContext', `${constants.CONTEXT_PREFIX}.conditionalContextMenus`, config.conditionalContextMenus), { initial: true });

// watch for changes
// watch for changes
void this.service.registerDisposable(container.create(WorkspaceContextDetector, 'datapacks', DatapackDetector.filter()).initialize());
void this.service.registerDisposable(container.create(WorkspaceContextDetector, 'metadata', MetadataDetector.filter()).initialize());
void this.service.registerDisposable(container.create(SfdxConfigWatcher).initialize());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
import * as vscode from 'vscode';

/**
*
09:41:19.369 (369138479)|METHOD_ENTRY|[1]|01p0Y00000O9SLP|OrderRepository.OrderRepository()
09:41:19.369 (369244047)|METHOD_EXIT|[1]|OrderRepository
09:41:19.369 (369309631)|CONSTRUCTOR_ENTRY|[17]|01p0Y00000O9SLP|<init>()|OrderRepository
09:41:19.369 (369582949)|CONSTRUCTOR_EXIT|[17]|01p0Y00000O9SLP|<init>()|OrderRepository
09:41:19.369 (369616240)|CONSTRUCTOR_ENTRY|[17]|01p5E000001BvvA|<init>(IOrderRepository)|OrderItemsController
09:41:19.369 (369653962)|METHOD_ENTRY|[4]|01p5E000001FJwa|VlocityController.VlocityController()
09:41:19.369 (369667080)|METHOD_EXIT|[4]|VlocityController
09:41:19.369 (369616240)|CONSTRUCTOR_EXIT|[17]|01p5E000001BvvA|<init>(IOrderRepository)|OrderItemsController
*/
import { container, injectable } from '@vlocode/core';
import VlocodeService from '../lib/vlocodeService';

/**
* Provides Symbol and Outline information for Salesforce APEX logs
*/
@injectable()
export class ApexLogSymbolProvider implements vscode.DocumentSymbolProvider {

readonly functionPattern = /^(?<time>[\d+:.]+) \(\d+\)\|(?<type>CONSTRUCTOR|METHOD|SYSTEM_METHOD)_(?<mode>ENTRY|EXIT)\|\[\d+\]\|(?<name>.*)$/;
readonly assignmentPattern = /^(?<time>[\d+:.]+) \(\d+\)\|VARIABLE_ASSIGNMENT\|\[\d+\]\|(?<name>.*)$/;

public static register(service: VlocodeService) {
const symbolProvider = container.get(ApexLogSymbolProvider);
service.registerDisposable(
vscode.languages.registerDocumentSymbolProvider({ language: 'apexlog' }, symbolProvider)
);
}

public provideDocumentSymbols(document: vscode.TextDocument): vscode.DocumentSymbol[] {
const symbols = this.parseSymbols(this.getDocumentLineIterator(document));
return symbols;
Expand Down
36 changes: 36 additions & 0 deletions packages/vscode-extension/syntax/sfhttp.tmLanguage.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"name": "Salesforce http API",
"scopeName": "source.sfhttp",
"patterns": [{ "include": "#method-and-headers" }],
"repository": {
"method-and-headers": {
"patterns": [{ "include": "#method-and-url" }, { "include": "#header" }],
"end": "\\r?\\n\\r?\\n"
},
"method-and-url": {
"captures": {
"1": { "name": "http.sf.method" },
"2": { "name": "http.sf.url" }
},
"match": "(?i)^(GET|POST|PUT|DELETE|PATCH) (.*)$\\n?",
"name": "meta.http.sf.method-url"
},
"header": {
"captures": {
"1": { "name": "http.sf.header.name" },
"2": { "name": "http.sf.header.value" }
},
"match": "(?i)^([a-z]+)[ ]*:[ ]*([a-z]+)$\\n?",
"name": "meta.http.sf.header"
},
"comment": {
"captures": {
"1": {
"name": "http.sf.method.comment"
}
},
"match": "(//).*$\\n?",
"name": "comment.line.double-slash"
}
}
}
33 changes: 28 additions & 5 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 80289b8

Please sign in to comment.