diff --git a/dev/quick-describe-test.html b/dev/quick-describe-test.html new file mode 100644 index 0000000..3ac946e --- /dev/null +++ b/dev/quick-describe-test.html @@ -0,0 +1,87 @@ + + + + + + Quick Describe Test - YASGUI + + + +
+

🧪 Quick Describe Feature Test

+

Instructions: Hold Ctrl (or Cmd on Mac) and click on any URI in the query below to trigger a quick describe query.

+

Test URIs:

+ +

Expected behavior: Clicking on these URIs should execute a CONSTRUCT query to describe the resource (even though the endpoint may not exist).

+
+
+ + + + diff --git a/packages/yasgui/src/Tab.ts b/packages/yasgui/src/Tab.ts index ea01557..25245f9 100644 --- a/packages/yasgui/src/Tab.ts +++ b/packages/yasgui/src/Tab.ts @@ -1445,14 +1445,38 @@ export class Tab extends EventEmitter { // Check if token is a URI (not a variable) // URIs typically have token.type of 'string-2' or might be in angle brackets - const tokenString = token.string.trim(); + let tokenString = token.string.trim(); // Skip if it's a variable (starts with ? or $) if (tokenString.startsWith("?") || tokenString.startsWith("$")) return; + // Handle prefixed names that may be split into multiple tokens by the tokenizer + // The tokenizer splits "prefix:localname" into two tokens: + // - PNAME_LN_PREFIX (e.g., "bnd:") with type "string-2" + // - PNAME_LN_LOCAL (e.g., "_subnetwork_bane_KVGB") with type "string" + // We need to combine them to get the full prefixed name + if (token.type === "string-2" && tokenString.endsWith(":")) { + // This is a prefix token, get the next token for the local name + const nextToken = this.yasqe.getTokenAt({ line: pos.line, ch: token.end + 1 }); + if (nextToken && nextToken.type === "string" && nextToken.start === token.end) { + tokenString = `${tokenString}${nextToken.string.trim()}`; + } + } else if (token.type === "string" && token.start > 0) { + // This might be a local name token, check if previous token is a prefix + const prevToken = this.yasqe.getTokenAt({ line: pos.line, ch: token.start - 1 }); + if ( + prevToken && + prevToken.type === "string-2" && + prevToken.string.trim().endsWith(":") && + prevToken.end === token.start + ) { + tokenString = `${prevToken.string.trim()}${tokenString}`; + } + } + // Check if it's a URI - either in angle brackets or a prefixed name const isFullUri = tokenString.startsWith("<") && tokenString.endsWith(">"); - const isPrefixedName = /^[\w-]+:[\w-]+/.test(tokenString); + const isPrefixedName = /^[\w-]+:/.test(tokenString); if (!isFullUri && !isPrefixedName) return; @@ -1467,7 +1491,8 @@ export class Tab extends EventEmitter { } else if (isPrefixedName) { // Expand prefixed name to full URI const prefixes = this.yasqe.getPrefixesFromQuery(); - const [prefix, localName] = tokenString.split(":"); + const [prefix, ...localParts] = tokenString.split(":"); + const localName = localParts.join(":"); const prefixUri = prefixes[prefix]; if (prefixUri) { uri = prefixUri + localName;