Skip to content

Commit

Permalink
Support for pasting a java file in the file explorer
Browse files Browse the repository at this point in the history
Signed-off-by: Hope Hadfield <hhadfiel@redhat.com>
  • Loading branch information
hopehadfield authored and rgrunber committed Dec 14, 2023
1 parent 7bd5ded commit 72a6b03
Show file tree
Hide file tree
Showing 10 changed files with 77 additions and 7 deletions.
15 changes: 15 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -1487,6 +1487,11 @@
"command": "java.server.restart",
"title": "%java.server.restart%",
"category": "Java"
},
{
"command": "java.action.filesExplorerPasteAction",
"title": "%java.action.filesExplorerPasteAction%",
"category": "Java"
}
],
"keybindings": [
Expand All @@ -1504,6 +1509,12 @@
"key": "ctrl+shift+v",
"mac": "cmd+shift+v",
"when": "javaLSReady && editorLangId == java"
},
{
"command": "java.action.filesExplorerPasteAction",
"key": "ctrl+shift+v",
"mac": "cmd+shift+v",
"when": "explorerViewletFocus && config.editor.pasteAs.enabled"
}
],
"menus": {
Expand Down Expand Up @@ -1622,6 +1633,10 @@
{
"command": "java.server.restart",
"when": "javaLSReady"
},
{
"command": "java.action.filesExplorerPasteAction",
"when": "false"
}
],
"view/title": [
Expand Down
3 changes: 2 additions & 1 deletion package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@
"java.project.createModuleInfo.command": "Create module-info.java",
"java.clean.sharedIndexes": "Clean Shared Indexes",
"java.server.restart": "Restart Java Language Server",
"java.edit.smartSemicolonDetection": "Java Smart Semicolon Detection"
"java.edit.smartSemicolonDetection": "Java Smart Semicolon Detection",
"java.action.filesExplorerPasteAction": "Paste clipboard text into a file"
}
3 changes: 2 additions & 1 deletion package.nls.ko.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@
"java.action.showSupertypeHierarchy": "Supertype 계층 구조 표시",
"java.action.showSubtypeHierarchy": "Subtype 계층 구조 표시",
"java.action.changeBaseType": "이 유형을 기준으로",
"java.project.createModuleInfo.command": "module-info.java 생성"
"java.project.createModuleInfo.command": "module-info.java 생성",
"java.action.filesExplorerPasteAction": "클립보드 텍스트를 파일에 붙여넣기"
}
3 changes: 2 additions & 1 deletion package.nls.zh-cn.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@
"java.action.showSubtypeHierarchy": "显示子类层次结构",
"java.action.changeBaseType": "基于此类型",
"java.project.createModuleInfo.command": "创建 module-info.java",
"java.clean.sharedIndexes": "清理共享的索引文件"
"java.clean.sharedIndexes": "清理共享的索引文件",
"java.action.filesExplorerPasteAction": "将剪贴板文本粘贴到文件中"
}
3 changes: 2 additions & 1 deletion package.nls.zh-tw.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@
"java.action.showSupertypeHierarchy": "顯示父類別階層結構",
"java.action.showSubtypeHierarchy": "顯示子類別階層結構",
"java.action.changeBaseType": "以此型別為基礎",
"java.project.createModuleInfo.command": "創建 module-info.java"
"java.project.createModuleInfo.command": "創建 module-info.java",
"java.action.filesExplorerPasteAction": "將剪貼簿文字貼到文件中"
}
9 changes: 9 additions & 0 deletions src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,10 @@ export namespace Commands {
* Custom paste action (triggers auto-import)
*/
export const CLIPBOARD_ONPASTE = 'java.action.clipboardPasteAction';
/**
* Custom paste action in files explorer
*/
export const FILESEXPLORER_ONPASTE = 'java.action.filesExplorerPasteAction';
/**
* Choose type to import.
*/
Expand Down Expand Up @@ -341,4 +345,9 @@ export namespace Commands {
*/
export const SMARTSEMICOLON_DETECTION = "java.edit.smartSemicolonDetection";

/**
* Determine if pasted text is a java file and resolve packages
*/
export const RESOLVE_PASTED_TEXT = "java.project.resolveText";

}
11 changes: 10 additions & 1 deletion src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import { TelemetryService } from '@redhat-developer/vscode-redhat-telemetry/lib'
import { activationProgressNotification } from "./serverTaskPresenter";
import { loadSupportedJreNames } from './jdkUtils';
import { BuildFileSelector, PICKED_BUILD_FILES, cleanupProjectPickerCache } from './buildFilesSelector';
import { pasteFile } from './pasteAction';

const syntaxClient: SyntaxLanguageClient = new SyntaxLanguageClient();
const standardClient: StandardLanguageClient = new StandardLanguageClient();
Expand Down Expand Up @@ -93,6 +94,14 @@ function getHeapDumpFolderFromSettings(): string {

export async function activate(context: ExtensionContext): Promise<ExtensionAPI> {
await loadSupportedJreNames(context);
context.subscriptions.push(commands.registerCommand(Commands.FILESEXPLORER_ONPASTE, async () => {
const originalClipboard = await env.clipboard.readText();
// Hack in order to get path to selected folder if applicable (see https://github.com/microsoft/vscode/issues/3553#issuecomment-1098562676)
await commands.executeCommand('copyFilePath');
const folder = await env.clipboard.readText();
await env.clipboard.writeText(originalClipboard);
pasteFile(folder);
}));
context.subscriptions.push(markdownPreviewProvider);
context.subscriptions.push(commands.registerCommand(Commands.TEMPLATE_VARIABLES, async () => {
markdownPreviewProvider.show(context.asAbsolutePath(path.join('document', `${Commands.TEMPLATE_VARIABLES}.md`)), 'Predefined Variables', "", context);
Expand Down Expand Up @@ -650,7 +659,7 @@ function enableJavadocSymbols() {
});
}

function getTempWorkspace() {
export function getTempWorkspace() {
return path.resolve(os.tmpdir(), `vscodesws_${makeRandomHexString(5)}`);
}

Expand Down
34 changes: 32 additions & 2 deletions src/pasteAction.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
'use strict';

import { commands, env, ExtensionContext, Range, TextEditor, window } from 'vscode';
import { TextEncoder } from 'util';
import { commands, env, ExtensionContext, Range, TextEditor, Uri, window, workspace } from 'vscode';
import { LanguageClient } from 'vscode-languageclient/node';

import { apiManager } from './apiManager';
import { Commands } from './commands';
import fs = require('fs');

export function registerCommands(languageClient: LanguageClient, context: ExtensionContext) {
context.subscriptions.push(commands.registerCommand(Commands.CLIPBOARD_ONPASTE, () => {
Expand Down Expand Up @@ -48,4 +50,32 @@ export async function registerOrganizeImportsOnPasteCommand(): Promise<void> {
}
}
});
}

let serverReady = false;

export async function pasteFile(folder: fs.PathLike): Promise<void> {
const clipboardText: string = await env.clipboard.readText();
let filePath = folder.toString();
fs.stat(folder, async (err, stats) => {
// If given path to selected folder is invalid (no folder is selected)
if (filePath === clipboardText || stats.isFile() || (filePath === "." && workspace.workspaceFolders !== undefined)) {
filePath = workspace.workspaceFolders[0].uri.fsPath;
}
if (!serverReady) {
await apiManager.getApiInstance().serverReady().then( async () => {
serverReady = true;
});
}
const fileString: string = await commands.executeCommand(Commands.EXECUTE_WORKSPACE_COMMAND, Commands.RESOLVE_PASTED_TEXT, filePath, clipboardText);
const fileUri = fileString !== null ? Uri.file(fileString) : null;
if (fileUri !== null){
try {
await workspace.fs.writeFile(fileUri, new TextEncoder().encode(clipboardText));
window.showTextDocument(fileUri, { preview: false });
} catch (error: unknown) {
// Do nothing (file does not have write permissions)
}
}
});
}
1 change: 1 addition & 0 deletions test/lightweight-mode-suite/extension.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ suite('Java Language Extension - LightWeight', () => {
Commands.OPEN_FILE,
Commands.CLEAN_SHARED_INDEXES,
Commands.RESTART_LANGUAGE_SERVER,
Commands.FILESEXPLORER_ONPASTE
].sort();
const foundJavaCommands = commands.filter((value) => {
return JAVA_COMMANDS.indexOf(value)>=0 || value.startsWith('java.');
Expand Down
2 changes: 2 additions & 0 deletions test/standard-mode-suite/extension.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ suite('Java Language Extension - Standard', () => {
Commands.UPDATE_SOURCE_ATTACHMENT_CMD,
Commands.SMARTSEMICOLON_DETECTION,
Commands.RESOLVE_SOURCE_ATTACHMENT,
Commands.FILESEXPLORER_ONPASTE,
Commands.RESOLVE_PASTED_TEXT,
].sort();
const foundJavaCommands = commands.filter((value) => {
return JAVA_COMMANDS.indexOf(value)>=0 || value.startsWith('java.');
Expand Down

0 comments on commit 72a6b03

Please sign in to comment.