From 69c97c11142a4df30fd5f5a73031297998e2cfd9 Mon Sep 17 00:00:00 2001 From: Mindaugas Greibus Date: Sat, 30 Dec 2023 13:23:22 +0200 Subject: [PATCH] Added navigation for request Body files --- src/extension.ts | 1 + src/provider/httpDefinitionProvider.ts | 102 +++++++++++++++++++++++++ src/provider/index.ts | 1 + 3 files changed, 104 insertions(+) create mode 100644 src/provider/httpDefinitionProvider.ts diff --git a/src/extension.ts b/src/extension.ts index 2a817e2..1f61350 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -32,6 +32,7 @@ export function activate(context: vscode.ExtensionContext): HttpYacExtensionApi new provider.VariablesHoverProvider(documentStore, storeController.environmentChanged), new provider.VariablesTreeDataProvider(documentStore, storeController.environmentChanged), new provider.TestController(documentStore, responseStore, storeController), + vscode.languages.registerDefinitionProvider(config.allHttpDocumentSelector, new provider.HttpDefinitionProvider(documentStore)), vscode.languages.registerDocumentSymbolProvider( config.allHttpDocumentSelector, new provider.HttpDocumentSymbolProvider(documentStore) diff --git a/src/provider/httpDefinitionProvider.ts b/src/provider/httpDefinitionProvider.ts new file mode 100644 index 0000000..9de52c2 --- /dev/null +++ b/src/provider/httpDefinitionProvider.ts @@ -0,0 +1,102 @@ + +import * as vscode from 'vscode' +import { DocumentStore } from '../documentStore'; + +import * as fs from 'fs'; +import * as path from 'path'; + +// thanks to https://github.com/abierbaum/vscode-file-peek + +export class HttpDefinitionProvider implements vscode.DefinitionProvider { + + protected fileSearchExtensions: string[] = ['json']; + + constructor(readonly documentStore: DocumentStore){ + + } + + provideDefinition(document: vscode.TextDocument, + position: vscode.Position, + token: vscode.CancellationToken): vscode.ProviderResult { + let working_dir = path.dirname(document.fileName); + let word = document.getText(document.getWordRangeAtPosition(position)); + let line = document.lineAt(position); + + //console.log('====== peek-file definition lookup ==========='); + console.log('word: ' + word); + console.log('line: ' + line.text); + + // We are looking for strings with filenames + // - simple hack for now we look for the string with our current word in it on our line + // and where our cursor position is inside the string + let re_str = `^<@?\\w*\\s+(.*?${word}.*?)\\s*$` + let match = line.text.match(re_str); + + this.log_debug('re_str: ', re_str); + this.log_debug(" Match: ", match); + + if (match){ + let potential_fname = match[1] || match[2]; + let match_index:number = match.index || 0; + let match_start:number = match_index; + let match_end:number = match_index + potential_fname.length; + + // Verify the match string is at same location as cursor + if((position.character >= match_start) && + (position.character <= match_end)) + { + let full_path = path.resolve(working_dir, potential_fname); + this.log_debug(" Match: ", match); + this.log_debug(" Fname: ", potential_fname); + this.log_debug(" Full: ", full_path); + + // Find all potential paths to check and return the first one found + let potential_fnames = this.getPotentialPaths(full_path); + this.log_debug(" potential fnames: ", potential_fnames); + + let found_fname = potential_fnames.find((fname_full) => { + this.log_debug(" checking: ", fname_full); + return fs.existsSync(fname_full); + }); + if (found_fname != null) { + this.log_debug('found: ', found_fname); + return new vscode.Location(vscode.Uri.file(found_fname), new vscode.Position(0, 1)); + } + } + } + + return null; + } + + private log_debug(message:string, obj:any):void{ + console.log(message, obj); + } + + getPotentialPaths(lookupPath: string): string[] { + let potential_paths: string[] = [lookupPath]; + + // Add on list where we just add the file extension directly + this.fileSearchExtensions.forEach((extStr) => { + potential_paths.push(lookupPath + extStr); + }); + + // if we have an extension, then try replacing it. + let parsed_path = path.parse(lookupPath); + if (parsed_path.ext !== "") { + this.fileSearchExtensions.forEach((extStr) => { + const new_path = path.format({ + base: parsed_path.name + extStr, + dir: parsed_path.dir, + ext: extStr, + name: parsed_path.name, + root: parsed_path.root + }); + potential_paths.push(new_path); + }); + } + + return potential_paths; + } + + +} \ No newline at end of file diff --git a/src/provider/index.ts b/src/provider/index.ts index facadef..c0f41b8 100644 --- a/src/provider/index.ts +++ b/src/provider/index.ts @@ -13,4 +13,5 @@ export * from './storeController'; export * from './variablesHoverProvider'; export * from './variablesTreeDataProvider'; export * from './userSessionTreeDataProvider'; +export * from './httpDefinitionProvider'; export * from './test';