Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 45 additions & 9 deletions src/gitignore-hider.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
import { commands, ExtensionContext, workspace } from 'vscode';
import { spawn } from "child_process";
import { join } from "path";
import { homedir } from "os";
Comment thread
matusf marked this conversation as resolved.
import { commands, ExtensionContext, workspace, Uri } from 'vscode';

import { GitignoreReader } from './gitignore-reader';
import { PatternConverter } from './pattern-converter';
import { SettingsAccessor } from './settings-accessor';
import { Pattern } from "./pattern.model";

function expandHome(path: string): string {
if (!path) return path;
if (path == '~') return homedir();
if (path.slice(0, 2) != '~/') return path;
return join(homedir(), path.slice(2));
}

export class GitignoreHider {
constructor(
private _reader: GitignoreReader,
private _converter: PatternConverter,
private _settings: SettingsAccessor,
) {}
) { }

public registerCommands(context: ExtensionContext): void {
const hideDisposable = commands.registerCommand('extension.hideGitignored', () => {
Expand All @@ -23,25 +34,50 @@ export class GitignoreHider {
context.subscriptions.push(showDisposable);
}

private async getGlobalGitignore(): Promise<string> {
return new Promise<string>((resolve, reject) => {
const commandExecuter = spawn('git', ['config', '--global', 'core.excludesfile']);
let stdOutData = '';
let stderrData = '';

commandExecuter.stdout.on('data', (data) => stdOutData += data);
commandExecuter.stderr.on('data', (data) => stderrData += data);
commandExecuter.on('close', (code) => {
code != 0 ? reject(stderrData.toString()) : resolve(stdOutData.toString().trim())
})
})
}

private async getGlobalPatterns(): Promise<Pattern[]> {
try {
const globalGitIgnore = expandHome(await this.getGlobalGitignore());
const doc = await workspace.openTextDocument(Uri.file(globalGitIgnore));
return this._converter.convert(this._reader.read(doc, true));
} catch (error) {
console.log('Unable to get global gitignore', error);
return [];
}
}

public async run(show = false): Promise<void> {
const files = await workspace.findFiles('**/.gitignore');
const globalPatterns = await this.getGlobalPatterns();

if (files.length < 1) {
if (files.length == 0 && globalPatterns.length == 0) {
return;
}

const handlers = files.map((file) => workspace.openTextDocument(file));
const handlers = files.map(file => workspace.openTextDocument(file));
const docs = await Promise.all(handlers);

const patterns = docs
.map((doc) => this._reader.read(doc))
.map((gitignore) => this._converter.convert(gitignore))
.map(doc => this._reader.read(doc))
.map(gitignore => this._converter.convert(gitignore))
.reduce((prev, cur) => cur.concat(prev), []);

if (show) {
await this._settings.show(patterns);
await this._settings.show(patterns.concat(globalPatterns));
} else {
await this._settings.hide(patterns);
await this._settings.hide(patterns.concat(globalPatterns));
}
}
}
4 changes: 2 additions & 2 deletions src/gitignore-reader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ export class GitignoreReader {
* @returns {Gitignore}
* @memberof GitignoreReader
*/
public read(document: TextDocument): Gitignore {
public read(document: TextDocument, isGlobal: boolean = false): Gitignore {
const lineCount = document.lineCount;
const lines: string[] = [];
for (let index = 0; index < lineCount; index++) {
lines.push(document.lineAt(index).text);
}
const path = dirname(workspace.asRelativePath(document.fileName));
return { lines, path };
return { lines, path, isGlobal };
}
}
1 change: 1 addition & 0 deletions src/gitignore.model.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export interface Gitignore {
lines: string[];
path: string;
isGlobal: boolean;
}
6 changes: 3 additions & 3 deletions src/pattern-converter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export class PatternConverter {
*/
public convert(gitignore: Gitignore): Pattern[] {
return gitignore.lines
.map((line) => this._convertToPattern(line, gitignore.path))
.map((line) => this._convertToPattern(line, gitignore.path, gitignore.isGlobal))
.filter((line) => line !== void 0) as Pattern[];
}

Expand All @@ -30,7 +30,7 @@ export class PatternConverter {
* @returns {(Pattern | void)}
* @memberof PatternConverter
*/
private _convertToPattern(line: string, path: string): Pattern | void {
private _convertToPattern(line: string, path: string, isGlobalGitignore: boolean): Pattern | void {
if (this._canBeIgnored(line)) {
return;
}
Expand All @@ -54,7 +54,7 @@ export class PatternConverter {
}

// prefix with path
glob = path !== '.' ? `${path}/${glob}` : glob;
glob = path === '.' || isGlobalGitignore ? glob : `${path}/${glob}`;

return { glob, hide, line };
}
Expand Down