From 036098e7c7695887ef479ff34f531376b3199223 Mon Sep 17 00:00:00 2001 From: Christian Jorgensen Date: Sat, 6 Jul 2024 23:05:17 +0200 Subject: [PATCH 1/3] Add tooltips to find results --- src/api/IBMiContent.ts | 12 +++++++++++- src/api/Search.ts | 24 +++++++++++++++++++----- src/typings.ts | 3 +++ src/views/searchView.ts | 5 +++-- 4 files changed, 36 insertions(+), 8 deletions(-) diff --git a/src/api/IBMiContent.ts b/src/api/IBMiContent.ts index 202e9122c..268597370 100644 --- a/src/api/IBMiContent.ts +++ b/src/api/IBMiContent.ts @@ -5,7 +5,7 @@ import tmp from 'tmp'; import util from 'util'; import { MarkdownString, window } from 'vscode'; import { ObjectTypes } from '../filesystems/qsys/Objects'; -import { AttrOperands, CommandResult, IBMiError, IBMiMember, IBMiObject, IFSFile, QsysPath } from '../typings'; +import { AttrOperands, CommandResult, IBMiError, IBMiMember, IBMiObject, IFSFile, QsysPath, SearchHit } from '../typings'; import { ConnectionConfiguration } from './Configuration'; import { FilterType, parseFilter, singleGenericName } from './Filter'; import { default as IBMi } from './IBMi'; @@ -1021,4 +1021,14 @@ export default class IBMiContent { tooltip.supportHtml = true; return tooltip; } + + searchHitToToolTip(path: string, hit: SearchHit) { + const tooltip = new MarkdownString(Tools.generateTooltipHtmlTable(path, { + size: hit.size, + modified: hit.modified ? new Date(hit.modified.getTime() - hit.modified.getTimezoneOffset() * 60 * 1000).toISOString().slice(0, 19).replace(`T`, ` `) : ``, + owner: hit.owner ? hit.owner.toUpperCase() : `` + })); + tooltip.supportHtml = true; + return tooltip; + } } \ No newline at end of file diff --git a/src/api/Search.ts b/src/api/Search.ts index 92fae0944..875a4f17a 100644 --- a/src/api/Search.ts +++ b/src/api/Search.ts @@ -83,6 +83,7 @@ export namespace Search { const connection = instance.getConnection(); if (connection) { const find = connection.remoteFeatures.find; + const stat = connection.remoteFeatures.stat; if (find) { const dirsToIgnore = GlobalConfiguration.get(`grepIgnoreDirs`) || []; @@ -92,14 +93,15 @@ export namespace Search { ignoreString = dirsToIgnore.map(dir => `-type d -path '*/${dir}' -prune -o`).join(` `); } + const findExec = stat ? `-exec stat --printf="%A\t%h\t%U\t%G\t%s\t%Y\t%n\n" {} +` : `-print`; const findRes = await connection.sendCommand({ - command: `${find} ${Tools.escapePath(path)} ${ignoreString} -type f -iname '*${findTerm}*' -print` + command: `${find} ${Tools.escapePath(path)} ${ignoreString} -type f -iname '*${findTerm}*' ${findExec}` }); if (findRes.code == 0 && findRes.stdout) { return { term: findTerm, - hits: parseFindOutput(findRes.stdout) + hits: parseFindOutput(findRes.stdout, undefined, (stat !== undefined)) } } } else { @@ -111,11 +113,23 @@ export namespace Search { } } - function parseFindOutput(output: string, readonly?: boolean, pathTransformer?: (path: string) => string): SearchHit[] { + function parseFindOutput(output: string, readonly?: boolean, statOutput?: boolean, pathTransformer?: (path: string) => string): SearchHit[] { const results: SearchHit[] = []; for (const line of output.split('\n')) { - const path = pathTransformer?.(line) || line; - results.push(results.find(r => r.path === path) || { path, readonly, lines: [] }); + if (statOutput) { + let auth: string, hardLinks: string, owner: string, group: string, size: string, modified: string, name: string; + [auth, hardLinks, owner, group, size, modified, name] = line.split(`\t`); + results.push({ + path: name, + lines: [], + size: Number(size), + modified: new Date(Number(modified) * 1000), + owner: owner + }); + } else { + const path = pathTransformer?.(line) || line; + results.push(results.find(r => r.path === path) || { path, readonly, lines: [] }); + } } return results; } diff --git a/src/typings.ts b/src/typings.ts index 838939edf..e95016661 100644 --- a/src/typings.ts +++ b/src/typings.ts @@ -233,6 +233,9 @@ export type SearchHit = { lines: SearchHitLine[] readonly?: boolean label?: string + size?: Number + modified?: Date + owner?: string } export type SearchHitLine = { diff --git a/src/views/searchView.ts b/src/views/searchView.ts index 6952f2cab..1482e1068 100644 --- a/src/views/searchView.ts +++ b/src/views/searchView.ts @@ -3,6 +3,7 @@ import vscode from "vscode"; import { DefaultOpenMode } from "../api/Configuration"; import { t } from '../locale'; import { SearchHit, SearchHitLine, SearchResults } from "../typings"; +import { instance } from "../instantiate"; export function initializeSearchView(context: vscode.ExtensionContext) { const searchView = new SearchView(); @@ -80,13 +81,13 @@ class HitSource extends vscode.TreeItem { this.iconPath = vscode.ThemeIcon.File; this.path = result.path; this._readonly = result.readonly; - this.tooltip = result.path; + this.tooltip = instance.getContent()?.searchHitToToolTip(this.path, result); if (hits) { this.description = `${hits} hit${hits === 1 ? `` : `s`}`; } else { - this.description = result.path; + this.description = !result.size ? result.path : ``; this.command = { command: `code-for-ibmi.openWithDefaultMode`, title: `Open`, From 5805d97d915320d1b869a661b1827a75f5394a3c Mon Sep 17 00:00:00 2001 From: Christian Jorgensen Date: Tue, 9 Jul 2024 18:11:17 +0200 Subject: [PATCH 2/3] Only stat what's used in tooltip --- src/api/Search.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/api/Search.ts b/src/api/Search.ts index 875a4f17a..e00a8f948 100644 --- a/src/api/Search.ts +++ b/src/api/Search.ts @@ -93,7 +93,7 @@ export namespace Search { ignoreString = dirsToIgnore.map(dir => `-type d -path '*/${dir}' -prune -o`).join(` `); } - const findExec = stat ? `-exec stat --printf="%A\t%h\t%U\t%G\t%s\t%Y\t%n\n" {} +` : `-print`; + const findExec = stat ? `-exec stat --printf="%U\t%s\t%Y\t%n\n" {} +` : `-print`; const findRes = await connection.sendCommand({ command: `${find} ${Tools.escapePath(path)} ${ignoreString} -type f -iname '*${findTerm}*' ${findExec}` }); @@ -117,8 +117,8 @@ export namespace Search { const results: SearchHit[] = []; for (const line of output.split('\n')) { if (statOutput) { - let auth: string, hardLinks: string, owner: string, group: string, size: string, modified: string, name: string; - [auth, hardLinks, owner, group, size, modified, name] = line.split(`\t`); + let owner: string, size: string, modified: string, name: string; + [owner, size, modified, name] = line.split(`\t`); results.push({ path: name, lines: [], From c68aa1bd41445f95c3b23b4697586604cff88dc2 Mon Sep 17 00:00:00 2001 From: Christian Jorgensen Date: Tue, 9 Jul 2024 18:45:44 +0200 Subject: [PATCH 3/3] Use qualified stat command in find --- src/api/Search.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/Search.ts b/src/api/Search.ts index e00a8f948..3d5ee039a 100644 --- a/src/api/Search.ts +++ b/src/api/Search.ts @@ -93,7 +93,7 @@ export namespace Search { ignoreString = dirsToIgnore.map(dir => `-type d -path '*/${dir}' -prune -o`).join(` `); } - const findExec = stat ? `-exec stat --printf="%U\t%s\t%Y\t%n\n" {} +` : `-print`; + const findExec = stat ? `-exec ${stat} --printf="%U\t%s\t%Y\t%n\n" {} +` : `-print`; const findRes = await connection.sendCommand({ command: `${find} ${Tools.escapePath(path)} ${ignoreString} -type f -iname '*${findTerm}*' ${findExec}` });