파일이 열렸을 때, 닫혔을 때, 활성화 되었을 때 exporer의 tabs에 파일이 추가 될 수 있는 부분을 구현해보았습니다.
사용 API
현재 열려있는 파일의 정보를 가져오는 방법
https://code.visualstudio.com/api/references/vscode-api#TextDocument
vscode.workspace.textDocuments
절대 경로를 작업 공간 내의 상대 경로로 변환
vscode.workspace.asRelativePath("
d:\code\extendtions\TabAndGroup\src\TabProvider.ts")
//반환
//TabProvider.ts
트리 뷰에서 사용되는 항목을 생성하는 코드
https://code.visualstudio.com/api/extension-guides/tree-view
https://vshaxe.github.io/vscode-extern/vscode/TreeItem.html
첫번 째 매개변수 : 트리 아이템에 표시될 텍스트
두번 째 매개변수 : 이 항목이 접히거나 펼쳐질 수 있는지 여부를 정의, None은 해당 항목이 자식 요소 없이 고정된 상태로 표시
new vscode.TreeItem("TabProvider.ts", vscode.TreeItemCollapsibleState.None)
구현 기능 명세
- 파일이 열리는 경우, 닫히는 경우, 활성화 되는 경우 tabs에 파일 이름이 들어간다.
- tabs에서 파일을 누르면 파일이 열린다.
- git 관련된 파일은 Tabs에 포함되면 안된다.
구현
TabProvider.ts
//📃TabProvider.ts
import * as vscode from "vscode";
export class TabProvider implements vscode.TreeDataProvider<vscode.TreeItem> {
private _onDidChangeTreeData: vscode.EventEmitter<
vscode.TreeItem | undefined | void
> = new vscode.EventEmitter<vscode.TreeItem | undefined | void>();
readonly onDidChangeTreeData: vscode.Event<
vscode.TreeItem | undefined | void
> = this._onDidChangeTreeData.event;
// 트리 항목 반환(탭 목록)
getTreeItem(element: vscode.TreeItem): vscode.TreeItem {
return element;
}
// 열린 파일 목록을 자식 요소로 제공
getChildren(
element?: vscode.TreeItem
): vscode.ProviderResult<vscode.TreeItem[]> {
if (!element) {
// 현재 열린 파일 목록을 가져옴
const openFiles = [...vscode.workspace.textDocuments];
console.log(openFiles);
// Git 관련 파일 필터링
const filteredFiles = this.getFilterFiles(openFiles);
// 각 파일을 TreeItem으로 변환
const treeItem = this.createTreeItems(filteredFiles);
return Promise.resolve(treeItem);
}
return [];
}
//필터 목록 파일을 제외하고 파일 목록 반환
private getFilterFiles(
files: vscode.TextDocument[]
): vscode.TextDocument[] {
return files.filter((doc) => {
const filePath = doc.uri.fsPath.toLowerCase();
//1. git 관련 파일 필터
const gitPatterns = [
"/.git/",
".git/",
"\\.git\\",
"/git/",
"\\git\\",
"git\\",
".git",
];
return !gitPatterns.some((pattern) => filePath.includes(pattern));
});
}
private createTreeItems(files: vscode.TextDocument[]): vscode.TreeItem[] {
return files.map((doc) => {
const label = vscode.workspace.asRelativePath(doc.uri.fsPath);
const item = new vscode.TreeItem(
label,
vscode.TreeItemCollapsibleState.None
);
// 파일 경로와 명령어 설정을 메서드로 분리
this.openSelectFile(item, doc.uri);
return item;
});
}
//파일 클릭 시 파일 열기
private openSelectFile(item: vscode.TreeItem, uri: vscode.Uri) {
item.resourceUri = uri;
item.command = {
// 파일 클릭 시 해당 파일로 이동
command: "vscode.open",
title: "Open File",
arguments: [uri],
};
}
// 트리 뷰 새로고침
refresh(): void {
this._onDidChangeTreeData.fire();
}
}
extension.ts
onDidChangeActiveTextEditor(), onDidOpenTextDocument(), onDidCloseTextDocument() 를 통해 파일이 활성화, 열림, 닫힘 시 트리뷰를 새로고침 합니다.
//📃extension.ts
import * as vscode from "vscode";
import { TabProvider } from "./TabProvider";
import { BookmarkProvider } from "./BookmarkProvider";
export function activate(context: vscode.ExtensionContext) {
console.log("🎈🎈🎈🎈 확장 기능 활성화됨!");
const openFiles = vscode.workspace.textDocuments;
console.log("🎀2 현재 열린 파일 목록", openFiles);
// TabProvider 등록
const tabProvider = new TabProvider();
//views에 들어갈 id는 tab-view
vscode.window.registerTreeDataProvider("tab-view", tabProvider);
// BookmarkProvider 등록
const bookmarkProvider = new BookmarkProvider();
//views에 들어갈 id는 bookmark-view
vscode.window.registerTreeDataProvider("bookmark-view", bookmarkProvider);
// 이미 열린 파일들을 트리 뷰에 추가
tabProvider.refresh();
// 파일 변경될 때 새로고침
vscode.window.onDidChangeActiveTextEditor(() => {
tabProvider.refresh();
});
// 파일 열때 때 새로고침
vscode.workspace.onDidOpenTextDocument(() => {
tabProvider.refresh();
});
// 파일 닫을 때 새로고침
vscode.workspace.onDidCloseTextDocument(() => {
tabProvider.refresh();
});
// 명령어를 통해 트리 뷰 새로고침
const refreshCommand = vscode.commands.registerCommand(
"tabView.refresh",
() => {
tabProvider.refresh();
}
);
context.subscriptions.push(refreshCommand);
}
export function deactivate() {}
package.json
"tabView.refresh"라는 명령어를 정의하고, 이 명령어를 실행할 때 '열린 파일 목록 새로고침' 기능을 하도록 만듭니다.
"commands": [
{
"command": "tabView.refresh",
"title": "Refresh Open Files"
}
]
전체 package.json
{
"name": "vscode-tabgroup-and-bookmark",
"displayName": "grop tab",
"description": "",
"version": "0.0.1",
"engines": {
"vscode": "^1.94.0"
},
"categories": [
"Other"
],
"activationEvents": [
"*"
],
"main": "./out/extension.js",
"contributes": {
"viewsContainers": {
"activitybar": [
{
"id": "vscode-tabgroup-and-bookmark",
"title": "Package Explorer",
"icon": "images/my-icon.svg"
}
]
},
"views": {
"vscode-tabgroup-and-bookmark": [
{
"id": "tab-view",
"name": "Tabs",
"type": "tree"
},
{
"id": "bookmark-view",
"name": "Bookmarks",
"type": "tree"
}
]
},
"commands": [
{
"command": "tabView.refresh",
"title": "Refresh Open Files"
}
]
},
"scripts": {
"vscode:prepublish": "npm run compile",
"compile": "tsc -p ./",
"watch": "tsc -watch -p ./",
"pretest": "npm run compile && npm run lint",
"lint": "eslint src",
"test": "vscode-test"
},
"devDependencies": {
"@types/vscode": "^1.94.0",
"@types/mocha": "^10.0.8",
"@types/node": "20.x",
"@typescript-eslint/eslint-plugin": "^8.7.0",
"@typescript-eslint/parser": "^8.7.0",
"eslint": "^9.11.1",
"typescript": "^5.6.2",
"@vscode/test-cli": "^0.0.10",
"@vscode/test-electron": "^2.4.1"
}
}
git 폴더 같은 쓸모없는 목록이 있어서 이를 필터링 해주는 코드가 존재합니다.
동작
개선이 필요한 부분
- 이미 기존에 열려있는 파일은 tabs 목록에 들어가지 않는다
- 파일을 열고 아이콘을 눌러서 tabs 목록을 보니까 뭔가 불편하다.
- unsaved file? 여기에서도 보일 수 있게 추가되면 좋을 것 같다.
- git 부분만 필터링 하지 않고 추가적인 필터링이 더 필요할 것 같다.
- 필터링 할 수 있는 부분을 좀 확장성 있게 수정이 필요할 것 같다.
'vscode extension' 카테고리의 다른 글
vscode extension Tree view 추가 (0) | 2024.10.21 |
---|---|
vscode extension Activity Bar 아이콘 생성 (0) | 2024.10.21 |
vscode Extention 간단한 샘플 만들어보고 마켓플레이스에 등록하기 (3) | 2024.09.22 |