Skip to content

Commit

Permalink
feat: support search from extension input
Browse files Browse the repository at this point in the history
  • Loading branch information
HerringtonDarkholme committed Feb 12, 2024
1 parent c607b14 commit d313d02
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 47 deletions.
100 changes: 56 additions & 44 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import {
TextDocumentShowOptions,
Uri,
ThemeIcon,
EventEmitter
EventEmitter,
Position
} from 'vscode'

import {
Expand All @@ -21,6 +22,7 @@ import {
} from 'vscode-languageclient/node'

import { activate as activateWebview } from './view'
import { SgSearch } from './types'

let client: LanguageClient
const diagnosticCollectionName = 'ast-grep-diagnostics'
Expand All @@ -45,11 +47,11 @@ function getExecutable(isDebug: boolean): Executable {
}

interface FileItem {
uri: string
file: string
}

interface SearchItem {
uri: string
file: string
source: string
range: Range
}
Expand All @@ -60,7 +62,7 @@ class AstGrepScanTreeItem extends TreeItem {
if ('source' in item) {
label = item.source
} else {
label = workspace.asRelativePath(Uri.parse(item.uri))
label = item.file
collapsibleState = TreeItemCollapsibleState.Expanded
}
super(label, collapsibleState)
Expand All @@ -69,7 +71,7 @@ class AstGrepScanTreeItem extends TreeItem {
title: 'ast-grep',
command: 'vscode.open',
arguments: [
item.uri,
this.uri,
<TextDocumentShowOptions>{
selection: item.range
}
Expand All @@ -78,16 +80,24 @@ class AstGrepScanTreeItem extends TreeItem {
}
}

get uri() {
// Get the current workspace folder
const workspaceFolder = workspace.workspaceFolders![0]
// Join the workspace folder path with the relative path
const filePath = Uri.joinPath(workspaceFolder.uri, this.item.file)
return filePath
}

static isSearchItem(item: FileItem | SearchItem): item is SearchItem {
return 'source' in item
}
}

type Dictionary<T> = { [key: string]: T }
class NodeDependenciesProvider
export class AstGrepSearchResultProvider
implements TreeDataProvider<AstGrepScanTreeItem>
{
private scanResultDict: Dictionary<ScanResult[]> = {}
private scanResultDict: Dictionary<SgSearch[]> = {}
private emitter = new EventEmitter<undefined>()
onDidChangeTreeData = this.emitter.event

Expand All @@ -97,72 +107,70 @@ class NodeDependenciesProvider
element.contextValue = 'file-item'
element.description = true
element.iconPath = ThemeIcon.File
element.resourceUri = Uri.parse(element.item.uri)
element.resourceUri = element.uri
}
return element
}

getChildren(element?: AstGrepScanTreeItem): Thenable<AstGrepScanTreeItem[]> {
if (!element) {
let list = Object.keys(this.scanResultDict).map(uri => {
return new AstGrepScanTreeItem({ uri })
let list = Object.keys(this.scanResultDict).map(file => {
return new AstGrepScanTreeItem({ file })
})
return Promise.resolve(list)
}
if (AstGrepScanTreeItem.isSearchItem(element.item)) {
return Promise.resolve([])
}
let uri = element.item.uri
let list = this.scanResultDict[uri].map(item => {
let file = element.item.file
let list = this.scanResultDict[file].map(item => {
const { start, end } = item.range
return new AstGrepScanTreeItem({
uri: item.uri,
source: item.content,
range: item.position
file: item.file,
source: item.text,
range: new Range(
new Position(start.line, start.column),
new Position(end.line, end.column)
)
})
})
return Promise.resolve(list)
}

updateResult(res: ScanResult[]) {
let grouped = groupBy(res, 'uri')
updateResult(res: SgSearch[]) {
let grouped = groupBy(res, 'file')
this.scanResultDict = grouped
this.emitter.fire(undefined)
}
}

interface ScanResult {
uri: string
// Same as vscode.Range but all zero-based
position: Range
content: string
}

function activateLsp(context: ExtensionContext) {
let provider = new NodeDependenciesProvider()
let provider = new AstGrepSearchResultProvider()

window.createTreeView('ast-grep.search.result', {
treeDataProvider: provider,
showCollapseAll: false
})
context.subscriptions.push(
commands.registerCommand('ast-grep.search', async _uri => {
let curWorkspace = workspace.workspaceFolders?.[0]
if (!curWorkspace) {
return
}
let pattern
try {
pattern = await window.showInputBox({})
} catch {
return
}
if (!pattern) {
return
}
let res = await client.sendRequest<ScanResult[]>('ast-grep/search', {
pattern: pattern
})
provider.updateResult(res)
// TODO: change impl
// let curWorkspace = workspace.workspaceFolders?.[0]
// if (!curWorkspace) {
// return
// }
// let pattern
// try {
// pattern = await window.showInputBox({})
// } catch {
// return
// }
// if (!pattern) {
// return
// }
// let res = await client.sendRequest<ScanResult[]>('ast-grep/search', {
// pattern: pattern
// })
// provider.updateResult(res)
}),
commands.registerCommand('ast-grep.restartLanguageServer', async () => {
console.log(
Expand Down Expand Up @@ -206,11 +214,15 @@ function activateLsp(context: ExtensionContext) {

// Start the client. This will also launch the server
client.start()

// TODO: fix shit code
return provider
}

export function activate(context: ExtensionContext) {
activateLsp(context)
activateWebview(context)
const provider = activateLsp(context)
// TODO: fix shit code
activateWebview(context, provider)
}

async function restart(): Promise<void> {
Expand Down
14 changes: 11 additions & 3 deletions src/view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@ import { execa } from 'execa'
import { Unport, ChannelMessage } from 'unport'
import * as vscode from 'vscode'
import { workspace } from 'vscode'
import { AstGrepSearchResultProvider } from './extension'

export function activate(context: vscode.ExtensionContext) {
const provider = new SearchSidebarProvider(context.extensionUri)
export function activate(
context: vscode.ExtensionContext,
search: AstGrepSearchResultProvider
) {
const provider = new SearchSidebarProvider(context.extensionUri, search)

context.subscriptions.push(
vscode.window.registerWebviewViewProvider(
Expand Down Expand Up @@ -46,7 +50,10 @@ class SearchSidebarProvider implements vscode.WebviewViewProvider {
// @ts-expect-error
private _view?: vscode.WebviewView

constructor(private readonly _extensionUri: vscode.Uri) {}
constructor(
private readonly _extensionUri: vscode.Uri,
private search: AstGrepSearchResultProvider
) {}

public resolveWebviewView(
webviewView: vscode.WebviewView,
Expand Down Expand Up @@ -85,6 +92,7 @@ class SearchSidebarProvider implements vscode.WebviewViewProvider {

parentPort.onMessage('search', async payload => {
const res = (await getPatternRes(payload.inputValue)) ?? []
this.search.updateResult(res)
parentPort.postMessage('search', { ...payload, searchResult: res })
})
}
Expand Down

0 comments on commit d313d02

Please sign in to comment.