Closed danshryock closed 7 years ago
Yes,you are right.There are some convenient API of Electron to handle clipboard,but vscode only provide the node environment to plugin.A plugin can't access Electron API throught vscode for now.
You can browse:
Ah! That makes sense!
What about creating a small electron app, and then invoking it from your extension?
For a proof of concept I did this:
Add Electron dependency to the extension (sadly a big download, but it works!)
npm install --save electron
in your extension you launch a custom standalone Electron app to save the png:
var child_process = require('child_process')
var pathToElectron = require('electron'); //when run from node this returns the path to the executable
var output = [];
function collect(data) { output.push(""+data); }
var proc = child_process.spawn(
pathToElectron,
[
"/path/to/extension/custom-electron-app",
"/path/to/destination.png"
]
)
proc.stdout.on('data',collect);
proc.stderr.on('data',collect);
proc.on( 'close', function(){ console.log(output.join("")) } )
and then in /path/to/extension/custom-electron-app/index.js
const {app, clipboard, BrowserWindow} = require('electron')
const fs = require("fs")
app.on('ready', captureClipboard)
function captureClipboard(){
var destination = process.argv[2];
console.log(destination)
var clipboardContents = clipboard.availableFormats() // probably ["image/png"] for a screenshot on the clipboard
var clipboardImage = clipboard.readImage();
var uriImage = clipboardImage.toDataURL(); //if you wanted to embed the entire image in the markdown
var pngBuffer = clipboardImage.toPng() //returns a node Buffer that contains a png that you
//could write to disk: https://nodejs.org/api/buffer.html#buffer_class_buffer
fs.writeFile(destination,pngBuffer, function(err){
if(err) {
console.error("Error",err);
} else {
console.log("done")
}
});
app.quit()
}
You'd obviously need to add in proper error handling and communication from the sub process to the extension, but it should all work in theory.
Thanks!
+1 for Linux support! Cheers!
@danshryock very very thank you for your research!
Issue #3011 had mentioned the method that use child process to start up a electron and call electron api from this child process. It sounds feasible,but I feel it is not a good or a elegance way.Because a electron environment is very big to a plugin and start a electron cost a lot of time.
As vscode is build on electron, so the best way is that vscode expose the lower api to plugin environment. We have to wait.
But I really holp every can use this plugin, so I plan use this method when user is using win/linux.But When I finish code,I found a new problem....
If not use electron, the size of packaged plugin is 1.6M, after add electron, it become 64MB....
And it cause I can't publish plugin to vscode marketplace....(marketplace only accept plugin that limit to 20MB,see cannot publish no request found. · Issue #92 · Microsoft/vscode-vsce)
So....
Ah, I suppose that makes sense. Thank you for trying! I really appreciate it!
Hopefully examples like this will help the VSCode team to realize that they need to provide some sort of support to the extension community for things like this.
Maybe via enhanced APIs provided by them, or maybe even a simple way to run a sandboxed electron instance for extensions. It could be a shell exec of the electron provided with VSCode, or maybe a custom background electron that they provide for extension authors to use.
https://github.com/Microsoft/vscode/issues/3011 https://github.com/Microsoft/vscode/issues/4972
@danshryock @viniciusarcanjo plugin support windows now! @kivle add the support of window by powershell.
Great news! Thanks!
@danshryock @viniciusarcanjo support Linux now! I use xclip to implement this feature. And I add featrue that use selected text as the image file name.
I saw that you have Windows and Linux support on your TODO list, so I took a look at what APIs would be most helpful to support those platforms.
Because VSCode uses Electron, I think this would be the easiest to hit all supported platforms at once: