summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbscan <10503608+bscan@users.noreply.github.com>2023-10-29 18:45:17 -0400
committerbscan <10503608+bscan@users.noreply.github.com>2023-10-29 18:45:17 -0400
commite28bf30c15f49f8ecbac61fd642d071023b8b6f8 (patch)
treea6df58d5af42c3e44b5fe268235cbf58da37a1ba
parentf27a20640166a964558994857bfba5713db4f50a (diff)
downloadPerlNavigator-e28bf30c15f49f8ecbac61fd642d071023b8b6f8.zip
Adding ability to look up pod in .pod files, as well as find pod files by module name. Also, fixing minor Moose related regex
-rw-r--r--server/src/completion.ts4
-rw-r--r--server/src/hover.ts2
-rw-r--r--server/src/navigation.ts11
-rw-r--r--server/src/perl/Inquisitor.pm2
-rw-r--r--server/src/pod.ts106
-rw-r--r--server/src/server.ts5
-rw-r--r--server/src/utils.ts11
7 files changed, 101 insertions, 40 deletions
diff --git a/server/src/completion.ts b/server/src/completion.ts
index fa99c41..dded519 100644
--- a/server/src/completion.ts
+++ b/server/src/completion.ts
@@ -41,8 +41,8 @@ export function getCompletions(
}
-export async function getCompletionDoc(elem: PerlElem, perlDoc: PerlDocument): Promise<string | undefined> {
- let docs = await getPod(elem, perlDoc);
+export async function getCompletionDoc(elem: PerlElem, perlDoc: PerlDocument, modMap: Map<string, string>): Promise<string | undefined> {
+ let docs = await getPod(elem, perlDoc, modMap);
return docs;
}
diff --git a/server/src/hover.ts b/server/src/hover.ts
index 591d320..3509342 100644
--- a/server/src/hover.ts
+++ b/server/src/hover.ts
@@ -30,7 +30,7 @@ export async function getHover(params: TextDocumentPositionParams, perlDoc: Perl
let merged = title;
- let docs = await getPod(elem, perlDoc);
+ let docs = await getPod(elem, perlDoc, modMap);
if(docs){
merged += "\n" + docs;
diff --git a/server/src/navigation.ts b/server/src/navigation.ts
index 0bded54..688d615 100644
--- a/server/src/navigation.ts
+++ b/server/src/navigation.ts
@@ -3,7 +3,7 @@ import { TextDocument } from "vscode-languageserver-textdocument";
import { PerlDocument, PerlElem, NavigatorSettings, ElemSource, ParseType } from "./types";
import Uri from "vscode-uri";
import { realpathSync, existsSync, realpath, promises } from "fs";
-import { getIncPaths, async_execFile, getSymbol, lookupSymbol, nLog } from "./utils";
+import { getIncPaths, async_execFile, getSymbol, lookupSymbol, nLog, isFile } from "./utils";
import { dirname, join } from "path";
import { getPerlAssetsPath } from "./assets";
import { refineElement } from "./refinement";
@@ -53,15 +53,6 @@ export async function getDefinition(params: DefinitionParams, perlDoc: PerlDocum
return locationsFound;
}
-async function isFile(file: string): Promise<boolean> {
- try {
- const stats = await promises.stat(file);
- return stats.isFile();
- } catch (err) {
- // File or directory doesn't exist
- return false;
- }
-}
async function resolveElemForNav(perlDoc: PerlDocument, elem: PerlElem, symbol: string): Promise<PerlElem | undefined> {
let refined = await refineElement(elem, perlDoc);
diff --git a/server/src/perl/Inquisitor.pm b/server/src/perl/Inquisitor.pm
index af09bd9..027dffb 100644
--- a/server/src/perl/Inquisitor.pm
+++ b/server/src/perl/Inquisitor.pm
@@ -167,7 +167,7 @@ sub resolve_file {
}
# Moose (but not Moo) attributes return this for a file.
- if ($file =~ /^accessor [\w:]+ \(defined at ([\w\\\/\.\s]+) line (\d+)\)$/){
+ if ($file =~ /^accessor [\w:]+ \(defined at (.+) line (\d+)\)$/){
$file = $1;
$line = $2;
$subType = 'd';
diff --git a/server/src/pod.ts b/server/src/pod.ts
index 8e0efdb..672c9fb 100644
--- a/server/src/pod.ts
+++ b/server/src/pod.ts
@@ -1,11 +1,13 @@
import fs = require("fs");
import { PerlDocument, PerlElem, PerlSymbolKind } from "./types";
import Uri from "vscode-uri";
+import { isFile } from "./utils";
-export async function getPod(elem: PerlElem, perlDoc: PerlDocument): Promise<string | undefined> {
+export async function getPod(elem: PerlElem, perlDoc: PerlDocument, modMap: Map<string, string>): Promise<string | undefined> {
// File may not exists. Return nothing if it doesn't
- const absolutePath = resolvePathForDoc(elem, perlDoc);
+ const absolutePath = await resolvePathForDoc(elem, perlDoc, modMap);
+
if(!absolutePath) return;
try {
@@ -64,41 +66,91 @@ export async function getPod(elem: PerlElem, perlDoc: PerlDocument): Promise<str
}
}
- if(meaningFullContent){
+ if(meaningFullContent && podBuffer != ""){
podContent += podBuffer;
podBuffer = "";
}
}
-
+
const markDown = convertPODToMarkdown(podContent);
return markDown;
}
-const resolvePathForDoc = (elem: PerlElem, perlDoc: PerlDocument): string | undefined => {
+
+async function resolvePathForDoc(elem: PerlElem, perlDoc: PerlDocument, modMap: Map<string, string>): Promise<string | undefined> {
let absolutePath = Uri.parse(elem.uri).fsPath;
- const badFile = (c: string) => /\w+\.c$/.test(c);
-
- if(badFile(absolutePath)){
- // Lookup by package or module?
- if (elem.package) {
- const elemResolved = perlDoc.elems.get(elem.package);
- if (elemResolved) {
- for (let potentialElem of elemResolved) {
- const potentialPath = Uri.parse(potentialElem.uri).fsPath;
- if (potentialPath.length > 1 && !badFile(potentialPath)) {
- absolutePath = potentialPath;
- break;
- }
+ const foundPath = await fsPathOrAlt(absolutePath);
+ if(foundPath){
+ return foundPath;
+ }
+
+ if (elem.package) {
+ let elemResolved = perlDoc.elems.get(elem.package);
+
+ if(!elemResolved){
+
+ // Looking up a module by the package name is only convention, but helps for things like POSIX
+ const modUri = modMap.get(elem.package);
+ if(modUri){
+ let modPath = await fsPathOrAlt(Uri.parse(modUri).fsPath);
+ if(modPath){
+ return modPath;
}
}
- }
- if(badFile(absolutePath)){
return;
}
+
+
+ for (let potentialElem of elemResolved) {
+ const potentialPath = Uri.parse(potentialElem.uri).fsPath;
+ const foundPackPath = await fsPathOrAlt(potentialPath);
+ if (foundPackPath) {
+ return foundPackPath;
+ }
+ }
+ }
+ if(await badFile(absolutePath)){
+ return;
+ }
+
+}
+
+async function fsPathOrAlt(fsPath: string | undefined): Promise<string | undefined>{
+
+ if(!fsPath){
+ return;
+ }
+
+ if(/\.pm$/.test(fsPath)){
+ let podPath = fsPath.replace(/\.pm$/, ".pod");
+ if(!await badFile(podPath)){
+ return podPath;
+ }
}
- return absolutePath;
+ if(!await badFile(fsPath)){
+ return fsPath;
+ }
+ return;
+
+}
+
+async function badFile(fsPath: string): Promise<boolean> {
+
+ if (!fsPath || fsPath.length <= 1) {
+ return true;
+ }
+
+ if( /\w+\.c$/.test(fsPath) ){
+ return true;
+ }
+
+ if(!(await isFile(fsPath))){
+ return true;
+ }
+
+ return false;
}
type ConversionState = {
@@ -147,9 +199,9 @@ const convertPODToMarkdown = (pod: string): string => {
else if (line.startsWith("=head")) {
const output = processHeadings(line);
- if(output != "\n## NAME\n" && /\w/.test(finalMarkdown)){
+ if(/\w/.test(finalMarkdown) || !/^\n##+ NAME\n$/.test(output)){
// I find it a waste of space to include the headline "NAME". We're short on space in the hover
- finalMarkdown += processHeadings(line);
+ finalMarkdown += output;
}
}
// List markers and items
@@ -345,9 +397,13 @@ const processInlineElements = (line: string): string => {
// Handle italics (I<italic>)
line = line.replace(/I<([^>]+)>/g, "*$1*");
+ line = line.replace(/I<< (.+?) >>>/g, "*$1*");
+
+ // Handle links (L<name>), URLS auto-link in vscode's markdown
+ line = line.replace(/L<(http[^>]+)>/g, " $1 ");
- // Handle links (L<name>), we'll just keep the name for now
- line = line.replace(/L<([^>]+)>/g, "[$1]");
+ line = line.replace(/L<([^>]+)>/g, "`$1`");
+ line = line.replace(/L<< (.*?) >>/g, "`$1`");
// Handle non-breaking spaces (S<text>)
line = line.replace(/S<([^>]+)>/g, "$1");
diff --git a/server/src/server.ts b/server/src/server.ts
index eabe144..943516e 100644
--- a/server/src/server.ts
+++ b/server/src/server.ts
@@ -348,7 +348,10 @@ connection.onCompletionResolve(async (item: CompletionItem): Promise<CompletionI
let perlDoc = navSymbols.get(item.data?.docUri);
if (!perlDoc) return item;
- const docs = await getCompletionDoc(perlElem, perlDoc);
+ let mods = availableMods.get("default");
+ if (!mods) mods = new Map();
+
+ const docs = await getCompletionDoc(perlElem, perlDoc, mods);
if (docs?.match(/\w/)) {
item.documentation = { kind: "markdown", value: docs };;
}
diff --git a/server/src/utils.ts b/server/src/utils.ts
index 91ed4fa..61d5509 100644
--- a/server/src/utils.ts
+++ b/server/src/utils.ts
@@ -5,6 +5,7 @@ import { promisify } from "util";
import { TextDocument, Position } from "vscode-languageserver-textdocument";
import { PerlDocument, PerlElem, NavigatorSettings, PerlSymbolKind, ElemSource } from "./types";
import * as path from "path";
+import { promises } from "fs";
export const async_execFile = promisify(execFile);
@@ -258,3 +259,13 @@ export function getPerlimportsProfile(settings: NavigatorSettings): string[] {
}
return profileCmd;
}
+
+export async function isFile(file: string): Promise<boolean> {
+ try {
+ const stats = await promises.stat(file);
+ return stats.isFile();
+ } catch (err) {
+ // File or directory doesn't exist
+ return false;
+ }
+} \ No newline at end of file