Skip to content

Commit

Permalink
Merge branch 'master' into default-formatter-8354
Browse files Browse the repository at this point in the history
Signed-off-by: Vitaliy Gulyy <vgulyy@redhat.com>
  • Loading branch information
vitaliy-guliy committed Sep 15, 2020
2 parents 984c59f + 525b4e6 commit add3986
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 86 deletions.
25 changes: 15 additions & 10 deletions packages/output/src/common/output-channel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ export class OutputChannelManager implements CommandContribution, Disposable, Re
this.textModelService.createModelReference(uri).then(ref => editorModelRef.resolve(ref));
}

const channel = new OutputChannel(resource, this.preferences);
const channel = this.createChannel(resource);
this.channels.set(name, channel);
this.toDisposeOnChannelDeletion.set(name, this.registerListeners(channel));
this.channelAddedEmitter.fire(channel);
Expand Down Expand Up @@ -306,6 +306,10 @@ export class OutputChannelManager implements CommandContribution, Disposable, Re
return new OutputResource(uri, editorModelRef);
}

protected createChannel(resource: OutputResource): OutputChannel {
return new OutputChannel(resource, this.preferences);
}

}

export enum OutputChannelSeverity {
Expand All @@ -316,20 +320,21 @@ export enum OutputChannelSeverity {

export class OutputChannel implements Disposable {

private readonly contentChangeEmitter = new Emitter<void>();
private readonly visibilityChangeEmitter = new Emitter<{ isVisible: boolean, preserveFocus?: boolean }>();
private readonly disposedEmitter = new Emitter<void>();
private readonly toDispose = new DisposableCollection(
protected readonly contentChangeEmitter = new Emitter<void>();
protected readonly visibilityChangeEmitter = new Emitter<{ isVisible: boolean, preserveFocus?: boolean }>();
protected readonly disposedEmitter = new Emitter<void>();
protected readonly textModifyQueue = new PQueue({ autoStart: true, concurrency: 1 });
protected readonly toDispose = new DisposableCollection(
Disposable.create(() => this.textModifyQueue.clear()),
this.contentChangeEmitter,
this.visibilityChangeEmitter,
this.disposedEmitter
);

private disposed = false;
private visible = true;
private _maxLineNumber: number;
private decorationIds = new Set<string>();
private textModifyQueue = new PQueue({ autoStart: true, concurrency: 1 });
protected disposed = false;
protected visible = true;
protected _maxLineNumber: number;
protected decorationIds = new Set<string>();

readonly onVisibilityChange: Event<{ isVisible: boolean, preserveFocus?: boolean }> = this.visibilityChangeEmitter.event;
readonly onContentChange: Event<void> = this.contentChangeEmitter.event;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,84 +15,39 @@
********************************************************************************/

import { injectable, inject } from 'inversify';
import { OutputWidget } from '@theia/output/lib/browser/output-widget';
import { OutputContribution } from '@theia/output/lib/browser/output-contribution';
import { OutputChannel, OutputChannelManager } from '@theia/output/lib/common/output-channel';
import { CommandService } from '@theia/core/lib/common/command';
import { OutputCommands } from '@theia/output/lib/browser/output-commands';
import { OutputChannelRegistryMain, PluginInfo } from '../../common/plugin-api-rpc';

@injectable()
export class OutputChannelRegistryMainImpl implements OutputChannelRegistryMain {

@inject(OutputChannelManager)
private outputChannelManager: OutputChannelManager;

@inject(OutputContribution)
private outputContribution: OutputContribution;

private commonOutputWidget: OutputWidget | undefined;

private channels: Map<string, OutputChannel> = new Map();

$append(channelName: string, value: string, pluginInfo: PluginInfo): PromiseLike<void> {
const outputChannel = this.getChannel(channelName);
if (outputChannel) {
outputChannel.append(value);
}
@inject(CommandService)
protected readonly commandService: CommandService;

$append(name: string, text: string, pluginInfo: PluginInfo): PromiseLike<void> {
this.commandService.executeCommand(OutputCommands.APPEND.id, { name, text });
return Promise.resolve();
}

$clear(channelName: string): PromiseLike<void> {
const outputChannel = this.getChannel(channelName);
if (outputChannel) {
outputChannel.clear();
}

$clear(name: string): PromiseLike<void> {
this.commandService.executeCommand(OutputCommands.CLEAR.id, { name });
return Promise.resolve();
}

$dispose(channelName: string): PromiseLike<void> {
this.outputChannelManager.deleteChannel(channelName);
if (this.channels.has(channelName)) {
this.channels.delete(channelName);
}

$dispose(name: string): PromiseLike<void> {
this.commandService.executeCommand(OutputCommands.DISPOSE.id, { name });
return Promise.resolve();
}

async $reveal(channelName: string, preserveFocus: boolean): Promise<void> {
const outputChannel = this.getChannel(channelName);
if (outputChannel) {
const activate = !preserveFocus;
const reveal = preserveFocus;
this.commonOutputWidget = await this.outputContribution.openView({ activate, reveal });
outputChannel.setVisibility(true);
}
async $reveal(name: string, preserveFocus: boolean): Promise<void> {
const options = { preserveFocus };
this.commandService.executeCommand(OutputCommands.SHOW.id, { name, options });
}

$close(channelName: string): PromiseLike<void> {
const outputChannel = this.getChannel(channelName);
if (outputChannel) {
outputChannel.setVisibility(false);
}
const channels = this.outputChannelManager.getChannels();
const isEmpty = channels.findIndex((channel: OutputChannel) => channel.isVisible) === -1;
if (isEmpty && this.commonOutputWidget) {
this.commonOutputWidget.close();
}

$close(name: string): PromiseLike<void> {
this.commandService.executeCommand(OutputCommands.HIDE.id, { name });
return Promise.resolve();
}

private getChannel(channelName: string): OutputChannel | undefined {
let outputChannel: OutputChannel | undefined;
if (this.channels.has(channelName)) {
outputChannel = this.channels.get(channelName);
} else {
outputChannel = this.outputChannelManager.getChannel(channelName);
this.channels.set(channelName, outputChannel);
}

return outputChannel;
}
}
5 changes: 4 additions & 1 deletion packages/plugin-ext/src/main/browser/workspace-main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,10 @@ export class WorkspaceMainImpl implements WorkspaceMain, Disposable {
for (const rootUri of rootUris) {
roots[rootUri] = {};
}
const opts: FileSearchService.Options = { rootOptions: roots };
const opts: FileSearchService.Options = {
rootOptions: roots,
useGitIgnore: excludePatternOrDisregardExcludes !== false
};
if (includePattern) {
opts.includePatterns = [includePattern];
}
Expand Down
22 changes: 20 additions & 2 deletions packages/plugin-ext/src/main/node/paths/plugin-paths-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export class PluginPathsServiceImpl implements PluginPathsService {
// if workspace is temporary
// then let create a storage path for each set of workspace roots
const rootsStr = rootUris.sort().join(',');
return crypto.createHash('md5').update(rootsStr).digest('hex');
return this.createHash(rootsStr);
} else {
let stat;
try {
Expand All @@ -95,10 +95,28 @@ export class PluginPathsServiceImpl implements PluginPathsService {
displayName = displayName.slice(0, displayName.lastIndexOf('.'));
}

return crypto.createHash('md5').update(workspaceUri).digest('hex');
return this.createHash(workspaceUri);
}
}

/**
* Creates a hash digest of the given string.
*/
protected createHash(str: string): string {
try {
// md5 is not FIPS-approved but we have to continue use it as there're existing storage folders based on it
return crypto.createHash('md5').update(str).digest('hex');
} catch (e) {
if (e.message.indexOf('disabled for FIPS') > -1) {
// SHA256 is FIPS-compliant
return crypto.createHash('sha256').update(str).digest('hex');
} else {
throw e;
}
}
// see more details in the issues 8378
}

/**
* Generate time folder name in format: YYYYMMDDTHHMMSS, for example: 20181205T093828
*/
Expand Down
31 changes: 19 additions & 12 deletions packages/plugin-ext/src/plugin/types-impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import { UUID } from '@phosphor/coreutils/lib/uuid';
import { illegalArgument } from '../common/errors';
import * as theia from '@theia/plugin';
import * as crypto from 'crypto';
import { URI } from 'vscode-uri';
import { relative } from '../common/paths-util';
import { startsWithIgnoreCase } from '@theia/core/lib/common/strings';
Expand Down Expand Up @@ -1401,6 +1400,14 @@ export enum ProgressLocation {
Notification = 15
}

function computeTaskExecutionId(values: string[]): string {
let id: string = '';
for (let i = 0; i < values.length; i++) {
id += values[i].replace(/,/g, ',,') + ',';
}
return id;
}

export class ProcessExecution {
private executionProcess: string;
private arguments: string[];
Expand Down Expand Up @@ -1457,17 +1464,17 @@ export class ProcessExecution {
}

public computeId(): string {
const hash = crypto.createHash('md5');
hash.update('process');
const props: string[] = [];
props.push('process');
if (this.executionProcess !== undefined) {
hash.update(this.executionProcess);
props.push(this.executionProcess);
}
if (this.arguments && this.arguments.length > 0) {
for (const arg of this.arguments) {
hash.update(arg);
props.push(arg);
}
}
return hash.digest('hex');
return computeTaskExecutionId(props);
}

public static is(value: theia.ShellExecution | theia.ProcessExecution): boolean {
Expand Down Expand Up @@ -1562,20 +1569,20 @@ export class ShellExecution {
}

public computeId(): string {
const hash = crypto.createHash('md5');
hash.update('shell');
const props: string[] = [];
props.push('shell');
if (this.shellCommandLine !== undefined) {
hash.update(this.shellCommandLine);
props.push(this.shellCommandLine);
}
if (this.shellCommand !== undefined) {
hash.update(typeof this.shellCommand === 'string' ? this.shellCommand : this.shellCommand.value);
props.push(typeof this.shellCommand === 'string' ? this.shellCommand : this.shellCommand.value);
}
if (this.arguments && this.arguments.length > 0) {
for (const arg of this.arguments) {
hash.update(typeof arg === 'string' ? arg : arg.value);
props.push(typeof arg === 'string' ? arg : arg.value);
}
}
return hash.digest('hex');
return computeTaskExecutionId(props);
}

public static is(value: theia.ShellExecution | theia.ProcessExecution): boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import {
import { CancellationTokenSource, Emitter, Event } from '@theia/core';
import { EditorManager, EditorDecoration, TrackedRangeStickiness, OverviewRulerLane, EditorWidget, ReplaceOperation, EditorOpenerOptions } from '@theia/editor/lib/browser';
import { WorkspaceService } from '@theia/workspace/lib/browser';
import { FileResourceResolver } from '@theia/filesystem/lib/browser';
import { FileResourceResolver, FileSystemPreferences } from '@theia/filesystem/lib/browser';
import { SearchInWorkspaceResult, SearchInWorkspaceOptions, SearchMatch } from '../common/search-in-workspace-interface';
import { SearchInWorkspaceService } from './search-in-workspace-service';
import { MEMORY_TEXT } from './in-memory-text-resource';
Expand Down Expand Up @@ -120,6 +120,7 @@ export class SearchInWorkspaceResultTreeWidget extends TreeWidget {
@inject(SearchInWorkspacePreferences) protected readonly searchInWorkspacePreferences: SearchInWorkspacePreferences;
@inject(ProgressService) protected readonly progressService: ProgressService;
@inject(ColorRegistry) protected readonly colorRegistry: ColorRegistry;
@inject(FileSystemPreferences) protected readonly filesystemPreferences: FileSystemPreferences;

constructor(
@inject(TreeProps) readonly props: TreeProps,
Expand Down Expand Up @@ -201,6 +202,10 @@ export class SearchInWorkspaceResultTreeWidget extends TreeWidget {
async search(searchTerm: string, searchOptions: SearchInWorkspaceOptions): Promise<void> {
this.searchTerm = searchTerm;
const collapseValue: string = this.searchInWorkspacePreferences['search.collapseResults'];
searchOptions = {
...searchOptions,
exclude: this.getExcludeGlobs(searchOptions.exclude)
};
this.resultTree.clear();
if (this.cancelIndicator) {
this.cancelIndicator.cancel();
Expand Down Expand Up @@ -773,6 +778,18 @@ export class SearchInWorkspaceResultTreeWidget extends TreeWidget {
return decorations;
}

/**
* Get the list of exclude globs.
* @param excludeOptions the exclude search option.
*
* @returns the list of exclude globs.
*/
protected getExcludeGlobs(excludeOptions?: string[]): string[] {
const excludePreferences = this.filesystemPreferences['files.exclude'];
const excludePreferencesGlobs = Object.keys(excludePreferences).filter(key => !!excludePreferences[key]);
return [...new Set([...excludePreferencesGlobs, ...excludeOptions])];
}

/**
* Compare two normalized strings.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -681,6 +681,20 @@ describe('ripgrep-search-in-workspace-server', function (): void {
ripgrepServer.search(pattern, [rootDirAUri], { include: ['*.txt'], matchWholeWord: true });
});

it('should return 1 result when searching for "test" while ignoring all ".txt" files', done => {
const pattern = 'test';

const client = new ResultAccumulator(() => {
const expected: SearchInWorkspaceExpectation[] = [
{ root: rootDirAUri, fileUri: 'glob', line: 1, character: 1, length: pattern.length, lineText: '' },
];
compareSearchResults(expected, client.results);
done();
});
ripgrepServer.setClient(client);
ripgrepServer.search(pattern, [rootDirAUri, rootDirBUri], { exclude: ['*.txt'] });
});

// Try searching in an UTF-8 file.
it('should search in a UTF-8 file', done => {
const pattern = ' jag';
Expand Down

0 comments on commit add3986

Please sign in to comment.