Skip to content

Commit

Permalink
navigator-decorator: add symlink icon and tooltip to linked files
Browse files Browse the repository at this point in the history
This commit adds a new decorator for the file navigator. It displays a
downward right curved arrow at the tail of a file node if that file
contains a symbolic link. A tooltip is also added displaying "Symbolic
Link" when hovering over a symbolic linked file node.
  • Loading branch information
Archie27376 committed Nov 19, 2021
1 parent fa3147f commit 9e386f0
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 0 deletions.
4 changes: 4 additions & 0 deletions packages/navigator/src/browser/navigator-frontend-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import { bindContributionProvider } from '@theia/core/lib/common';
import { OpenEditorsTreeDecorator } from './open-editors-widget/navigator-open-editors-decorator-service';
import { OpenEditorsWidget } from './open-editors-widget/navigator-open-editors-widget';
import { NavigatorTreeDecorator } from './navigator-decorator-service';
import { NavigatorSymlinkDecorator } from './navigator-symlink-decorator';

export default new ContainerModule(bind => {
bindFileNavigatorPreferences(bind);
Expand Down Expand Up @@ -78,4 +79,7 @@ export default new ContainerModule(bind => {
bind(NavigatorTabBarDecorator).toSelf().inSingletonScope();
bind(FrontendApplicationContribution).toService(NavigatorTabBarDecorator);
bind(TabBarDecorator).toService(NavigatorTabBarDecorator);

bind(NavigatorSymlinkDecorator).toSelf().inSingletonScope();
bind(NavigatorTreeDecorator).toService(NavigatorSymlinkDecorator);
});
65 changes: 65 additions & 0 deletions packages/navigator/src/browser/navigator-symlink-decorator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/********************************************************************************
* Copyright (C) 2021 Ericsson and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/

import { inject, injectable } from '@theia/core/shared/inversify';
import { Emitter, Event, nls } from '@theia/core';
import { TreeDecorator, Tree, TreeDecoration, DepthFirstTreeIterator } from '@theia/core/lib/browser';
import { FileStatNode } from '@theia/filesystem/lib/browser';
import { DecorationsService } from '@theia/core/lib/browser/decorations-service';

@injectable()
export class NavigatorSymlinkDecorator implements TreeDecorator {

readonly id = 'theia-navigator-symlink-decorator';

constructor(@inject(DecorationsService) protected readonly decorationsService: DecorationsService) {
this.decorationsService.onDidChangeDecorations(() => {
this.fireDidChangeDecorations((tree: Tree) => this.collectDecorator(tree));
});
}

async decorations(tree: Tree): Promise<Map<string, TreeDecoration.Data>> {
return this.collectDecorator(tree);
}

protected collectDecorator(tree: Tree): Map<string, TreeDecoration.Data> {
const result = new Map<string, TreeDecoration.Data>();
if (tree.root === undefined) {
return result;
}
for (const node of new DepthFirstTreeIterator(tree.root)) {
if (FileStatNode.is(node) && node.fileStat.isSymbolicLink) {
const decorations: TreeDecoration.Data = {
tooltip: nls.localizeByDefault('Symbolic Link'),
tailDecorations: [{ data: '\u2937' }]
};
result.set(node.id, decorations);
}
}
return result;
}

protected readonly emitter = new Emitter<(tree: Tree) => Map<string, TreeDecoration.Data>>();

get onDidChangeDecorations(): Event<(tree: Tree) => Map<string, TreeDecoration.Data>> {
return this.emitter.event;
}

fireDidChangeDecorations(event: (tree: Tree) => Map<string, TreeDecoration.Data>): void {
this.emitter.fire(event);
}

}

0 comments on commit 9e386f0

Please sign in to comment.