|  | 
|  | 1 | +import { DocumentSymbolParams, LanguageClient, TextDocumentIdentifier } from "vscode-languageclient/node"; | 
|  | 2 | +import { getActiveLanguageClient } from "../extension"; | 
|  | 3 | +import { ExtendedDocumentSymbolRequest } from "./protocol"; | 
|  | 4 | +import { Location, Position, QuickPick, QuickPickItem, Uri, window, workspace } from "vscode"; | 
|  | 5 | +import { getLThemeIcon } from "../themeUtils"; | 
|  | 6 | + | 
|  | 7 | +export class ExtendedOutlineQuickPick { | 
|  | 8 | +	private api: QuickPick<QuickPickItem>; | 
|  | 9 | +	private client: LanguageClient; | 
|  | 10 | +	public initialized: boolean; | 
|  | 11 | + | 
|  | 12 | +	constructor() { | 
|  | 13 | +		this.initialized = false; | 
|  | 14 | +	} | 
|  | 15 | + | 
|  | 16 | +	async initialize() { | 
|  | 17 | +		this.api = window.createQuickPick(); | 
|  | 18 | +		this.api.ignoreFocusOut = true; | 
|  | 19 | +		this.api.onDidChangeActive((items: QuickPickItem[]) => { | 
|  | 20 | +			if (items.length > 0) { | 
|  | 21 | +				const active: QuickPickItem = items[0]; | 
|  | 22 | +				const uri = active["uri"]; | 
|  | 23 | +				const range = active["range"]; | 
|  | 24 | +				if (uri !== undefined) { | 
|  | 25 | +					workspace.openTextDocument(Uri.parse(uri)).then(doc => { | 
|  | 26 | +						window.showTextDocument(doc, {preserveFocus: true, selection: range}); | 
|  | 27 | +					}); | 
|  | 28 | +				} else { | 
|  | 29 | +					window.showTextDocument(window.activeTextEditor.document, {preserveFocus: true, selection: range}); | 
|  | 30 | +				} | 
|  | 31 | +			} | 
|  | 32 | +		}); | 
|  | 33 | +		this.api.onDidAccept(() => { | 
|  | 34 | +			this.api.hide(); | 
|  | 35 | +		}); | 
|  | 36 | +		this.client = await getActiveLanguageClient(); | 
|  | 37 | +		this.initialized = true; | 
|  | 38 | +	} | 
|  | 39 | + | 
|  | 40 | +	async open(uri: Uri) { | 
|  | 41 | +		if (!this.initialized) { | 
|  | 42 | +			await this.initialize(); | 
|  | 43 | +		} | 
|  | 44 | + | 
|  | 45 | +		if (!this.api) { | 
|  | 46 | +			return; | 
|  | 47 | +		} | 
|  | 48 | + | 
|  | 49 | +		const location = new Location(uri, new Position(0, 0)); | 
|  | 50 | +		const params: DocumentSymbolParams = { | 
|  | 51 | +			textDocument: TextDocumentIdentifier.create(location.uri.toString()) | 
|  | 52 | +		}; | 
|  | 53 | +		const symbols = await this.client.sendRequest(ExtendedDocumentSymbolRequest.type, params); | 
|  | 54 | +		let quickPickItems: QuickPickItem[] = []; | 
|  | 55 | +		for (const s of symbols) { | 
|  | 56 | +			const icon = getLThemeIcon(s.kind).id; | 
|  | 57 | +			const item = { | 
|  | 58 | +				label: `$(${icon}) ${s.name}`, | 
|  | 59 | +				description: s.detail.trim(), | 
|  | 60 | +				uri: s.uri, | 
|  | 61 | +				range: s.range | 
|  | 62 | +			}; | 
|  | 63 | +			quickPickItems.push(item); | 
|  | 64 | +			if (icon === 'symbol-class') { | 
|  | 65 | +				const items: QuickPickItem[] = s.children.map(s => ({ | 
|  | 66 | +					label: `$(${getLThemeIcon(s.kind).id}) ${s.name}`, | 
|  | 67 | +					// custom quick pick has automatic space between label & description | 
|  | 68 | +					description: s.detail.trim(), | 
|  | 69 | +					uri: s.uri, | 
|  | 70 | +					range: s.range | 
|  | 71 | +				})); | 
|  | 72 | +				quickPickItems = quickPickItems.concat(items); | 
|  | 73 | +			} | 
|  | 74 | +		} | 
|  | 75 | +		this.api.items = quickPickItems; | 
|  | 76 | +		this.api.activeItems = []; | 
|  | 77 | +		this.api.show(); | 
|  | 78 | +	} | 
|  | 79 | +} | 
|  | 80 | + | 
|  | 81 | +export const extendedOutlineQuickPick: ExtendedOutlineQuickPick = new ExtendedOutlineQuickPick(); | 
0 commit comments