-
-
Notifications
You must be signed in to change notification settings - Fork 236
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Suggestion: Extend configuration to open current file with external editor #947
Comments
I'm not adding this. Open With... is a reasonable way to get to other documents. If you need more control, you can create a Command Script or an Addin. Here's a commander script that lets you do what you want: var docFile = Model.ActiveDocument.Filename;
if (string.IsNullOrEmpty(docFile))
return null;
var exe = @"C:\Program Files\Microsoft VS Code\Code.exe";
exe = Environment.ExpandEnvironmentVariables(exe);
Process pi = null;
try {
var lineNo = await Model.ActiveEditor.GetLineNumber();
pi = Process.Start(exe,"-g \"" + docFile + $":{lineNo}\"");
}
catch(Exception ex) {
Model.Window.ShowStatusError("Couldn't open editor: " + ex.Message);
return null;
}
if (pi != null)
Model.Window.ShowStatus($"VS Code started with: {docFile}",5000);
else
Model.Window.ShowStatusError("Failed to start VS Code."); |
Some of this functionality will be added in 2.7.8. |
Hmmm... I can duplicate the failure. I have to take a look - probably has to do with accessing the file to copy to clipboard. {ToClipboardText} copies the current files content to the clipboard assuming the file is a text file (I check for known file types from the file extension list). I like the idea of saving before but it definitely has to be a flag or else we'd get unexpted behavior potentially. I'll add that! |
You can give this another try with
Also updated the docs with a little more information on parameters. |
Your thought is not complete. If you copied the selection manually (Ctrl-C) then you cannot apply an ExternalPrograms-command using
|
That dialog is specific to the close operation on shutdown so it's not a simple matter to display it on save. However easy enough to add to the operation for the open document explicitly here by checking dirty status if the document has pending changes. Wasn't it you who suggested the SaveOperation flag in the settings 😄 This is the better route though - I agree... |
{CopySelectedTextToClipboard} is more flexible than {ToClipboardText} because when you have defined an ExternalPrograms-command using {CopySelectedTextToClipboard} then you can: I'm not sure I understand what you mean here. If you don't specify any arguments (or other arguments) and you manually copy to clipboard (ie. select and copy (ctrl-a / ctrl-c) the text is there anyway. Taking the selection seems more intrusive as it potentially blows away another clipboard selection that you might paste into the external app. I just don't see how this gains anything if the selection has to be made manually anyway - it's one extra key (ctrl-c) to press. |
Thank you.
No, it did not suggest the SaveOperation flag.
Although the dialog has the title "Save Document" it is specific to the Two days ago I briefly restated my suggestion by:
Then you came up with the SaveOperation flag. |
You are right. If the external program is invoked without passing |
Ok so here is what I have now 😄 For the active editor document the logic now goes like this:
Here's what this looks like in code: ci.Click += async (o, args) =>
{
AcePosition pos = new AcePosition();
if (model.ActiveEditor != null)
{
pos = await model.ActiveEditor.GetCursorPosition();
}
var menuItem = o as MenuItem;
var path = menuItem.CommandParameter as string;
var program = menuItem.Tag as ExternalProgramItem;
program.DocumentText = Model.ActiveDocument.CurrentText;
if (Model.ActiveDocument.IsUntitled)
{
bool saveToFile = await Model.Window.Dispatcher.InvokeAsync(() =>
MessageBox.Show(Model.Window, "This 'Untitled' document " +
"hasn't been saved yet.\n" +
"Do you want to save it to file now?\n\n" +
"If you don't save now, a temporary file " +
"will be created and then deleted after a few seconds, " +
"to allow opening the file externally.",
"Save Document",
MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.Yes) ==
MessageBoxResult.Yes);
if (saveToFile)
{
saveToFile = await Model.Window.SaveAsFile();
}
if (!saveToFile) // create a temporary file and delete after 3 secs
{
var tfile = Path.Combine(Path.GetTempPath(),
"_mm_untitled_" + DataUtils.GenerateUniqueId() + ".md");
var text = await model.ActiveEditor.GetMarkdown();
File.WriteAllText(tfile, text);
path = tfile;
Model.Window.Dispatcher.Delay(3000, () => File.Delete(tfile));
}
}
else
{
await Model.Window.SaveFile(promptForSaveIfDirty: !program.SaveBeforeActivation);
}
if (program.CanExecute(path))
program.Execute(path, pos.row + 1, pos.column + 1);
else
Model.Window.ShowStatusError("Couldn't execute " + program.Name + " with " + path);
};
mi.Items.Add(ci); I ended up creating a new method on the I left in the This turning into a bit of Refactor 😄 Simple thing that isn't so simple once you dig into it... |
The new logic looks very comfortable. Until now I missed the case where the current document is untitled (not yet existent as file). In this case I would not allow the document to be opened with an external program. This makes the code simpler and avoids the awkward situation where the temporary file is deleted while it is being used by the external program. |
Yeah I agree on the untitled behavior:
|
Can you take a look at your log file and look for this error message: mmApp.Log("Document Save Failed: " + filename + " - " + Encoding?.EncodingName, ex, false,
LogLevels.Warning); Curious why that would happen - I don't see that here. Could be an a location where the file can't be saved due to permissions? |
The problem seems to be that mm does not check which button of the "Save As" dialog has been clicked. So it tries to save the current document even when the user clicked
|
Argh - yup that's it. Thank you. Fixed. I lifted that block of code from somewhere else but had to modify it heavily to fit in this simpler context and I missed the result processing from the save operation. |
Currently the context menu of the mm editor contains the command
Open With...
which pops up the same dialog as the equally named command of the Windows File Explorer (explorer.exe). This is far from optimal if you want to edit the current file with another editor because of the following shortcomings:If the current file is modified then you are not asked whether you want to save it before switching to the other editor.
Forgetting to do so can cause a lot of trouble.
You have to select and run the other app in the mentioned dialog.
The selection is annoying work if mm is the default app for *.md files which is the most likely case for mm users.
The current position (line and column) is not passed to the other app.
It would be time-saving if the user could configure one or more external editors that can be invoked by clicking on a corresponding command in the context menu (eg:
Edit With Notepad++
) or even more convenient by pressing a shortcut key (eg: Ctrl+E).Before invoking the external editor mm should offer a
Save Document
dialog if the current file is modified, that is:The settings for an external editor in MarkdownMonster.json could be:
EXAMPLE:
mm would expand the placeholders related to the position of the cursor in the mm editor as follows:
The option
Shortcut
may be too expensive for now because it implies that mm needs a shortcut manager. This is actually a proposal of its own.The text was updated successfully, but these errors were encountered: