Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/monodevelop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/main/src
diff options
context:
space:
mode:
Diffstat (limited to 'main/src')
-rw-r--r--main/src/addins/CSharpBinding/MonoDevelop.CSharp.Completion/CompletionProvider/ProtocolMemberCompletionProvider.cs36
-rw-r--r--main/src/addins/CSharpBinding/MonoDevelop.CSharp.Formatting/CSharpFormatter.cs90
-rw-r--r--main/src/addins/CSharpBinding/MonoDevelop.CSharp.OptionProvider/CSharpDocumentOptionsProvider.cs28
-rw-r--r--main/src/addins/MacPlatform/MacPlatform.cs15
-rw-r--r--main/src/addins/MonoDevelop.SourceEditor2/VSEditor/TextEditorInitializationService.cs14
-rw-r--r--main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor.Cocoa/Properties/MonoDevelop.TextEditor.Cocoa.addin.xml4
-rw-r--r--main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor/TextViewContent.cs6
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProject.cs4
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs13
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Components/IdeTheme.cs4
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Components/Mac/NativeToolkitHelper.cs65
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Desktop/PlatformService.cs4
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/DefaultSourceEditorOptions.cs14
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/TextEditorViewContent.cs5
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Documents/DocumentManager.cs7
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/CommentTasksProvider.Legacy.cs36
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/TextPolicyDocumentOptionsProvider.cs2
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.WelcomePage/IWelcomeWindowProvider.cs2
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.WelcomePage/WelcomePageService.cs14
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj1
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/Ide.cs26
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/IdeStartup.cs7
22 files changed, 277 insertions, 120 deletions
diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Completion/CompletionProvider/ProtocolMemberCompletionProvider.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Completion/CompletionProvider/ProtocolMemberCompletionProvider.cs
index e707916017..b52b291c29 100644
--- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Completion/CompletionProvider/ProtocolMemberCompletionProvider.cs
+++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Completion/CompletionProvider/ProtocolMemberCompletionProvider.cs
@@ -97,6 +97,22 @@ namespace MonoDevelop.CSharp.Completion.Provider
return;
var startToken = token.GetPreviousTokenIfTouchingWord (position);
+
+ // We're marking the context as exclusive, to resolve the
+ // regression in the new editor that appeared since introducing
+ // Roslyn's provider mechanism. The actual override completion
+ // provider took precedence and therefore this one was ignored.
+ // We submitted a PR for roslyn, that allows multiple providers,
+ // marked as exclusive, to render suggestions.
+ // See: https://github.com/dotnet/roslyn/pull/36088
+ //
+ // Important note, though, we should only set exclusivity when
+ // we are actually competing with an override provider - that
+ // is, if the token before this one is the override keyword. If
+ // it's not, we're not competing, and therefore shouldn't set
+ // this to true, as we'll be the ones stealing the spotlight.
+ context.IsExclusive = startToken.IsKind (SyntaxKind.OverrideKeyword);
+
TryDetermineReturnType (startToken, model, cancellationToken, out ITypeSymbol returnType, out SyntaxToken tokenBeforeReturnType);
if (returnType == null) {
var enclosingType = model.GetEnclosingSymbol (position, cancellationToken) as INamedTypeSymbol;
@@ -155,7 +171,7 @@ namespace MonoDevelop.CSharp.Completion.Provider
pDict = pDict.Add ("InsertionText", sb.ToString ());
pDict = pDict.Add ("DescriptionMarkup", "- <span foreground=\"darkgray\" size='small'>" + inlineDescription + "</span>");
pDict = pDict.Add ("Description", await GenerateQuickInfo (semanticModel, position, m, cancellationToken));
- pDict = pDict.Add ("DeclarationBegin", declarationBegin.ToString());
+ pDict = pDict.Add ("DeclarationBegin", declarationBegin.ToString ());
var tags = ImmutableArray<string>.Empty.Add ("NewMethod");
var completionData = CompletionItem.Create (m.Name, sortText: m.ToSignatureDisplayString (), properties: pDict, rules: ProtocolCompletionRules, tags: tags, inlineDescription: inlineDescription);
@@ -468,5 +484,23 @@ namespace MonoDevelop.CSharp.Completion.Provider
.WithIsSealed (isSealed);*/
return overrideToken.IsKind (SyntaxKind.OverrideKeyword) && IsOnStartLine (text, startLine, overrideToken.Parent.SpanStart);
}
+
+ public override bool ShouldTriggerCompletion (SourceText text, int position, CompletionTrigger trigger, Microsoft.CodeAnalysis.Options.OptionSet options)
+ {
+ // This method is overridden because Roslyn's Completion Service calls us, in cases
+ // where the change kind is an Insertion or Deletion. This mimics the behavior
+ // of the OverrideCompletionProvider provided by Roslyn, so we'll now get called
+ // in all the same cases as that one. The goal is to also display our protocol member
+ // completion suggestions, even when the user types "overrides" and presses space.
+ // See here: http://source.roslyn.io/#Microsoft.CodeAnalysis.Features/Completion/CompletionServiceWithProviders.cs,231
+ switch (trigger.Kind) {
+ case CompletionTriggerKind.Insertion when position > 0:
+ var insertedCharacterPosition = position - 1;
+ return Microsoft.CodeAnalysis.CSharp.Completion.Providers.CompletionUtilities.IsTriggerAfterSpaceOrStartOfWordCharacter (text, insertedCharacterPosition, options);
+
+ default:
+ return false;
+ }
+ }
}
} \ No newline at end of file
diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Formatting/CSharpFormatter.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Formatting/CSharpFormatter.cs
index 9b3b4ca8e4..bf0d3cbef8 100644
--- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Formatting/CSharpFormatter.cs
+++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Formatting/CSharpFormatter.cs
@@ -1,29 +1,29 @@
-//
-// CSharpFormatter.cs
-//
-// Author:
-// Mike Krüger <mkrueger@novell.com>
-//
-// Copyright (c) 2009 Novell, Inc (http://www.novell.com)
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
+//
+// CSharpFormatter.cs
+//
+// Author:
+// Mike Krüger <mkrueger@novell.com>
+//
+// Copyright (c) 2009 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
using System;
using System.Collections.Generic;
using System.Threading;
@@ -50,6 +50,7 @@ using MonoDevelop.CSharp.OptionProvider;
using Microsoft.VisualStudio.CodingConventions;
using System.Linq;
using System.Collections.Immutable;
+using System.Runtime.CompilerServices;
namespace MonoDevelop.CSharp.Formatting
{
@@ -81,7 +82,7 @@ namespace MonoDevelop.CSharp.Formatting
var endSegment = startLine != endLine ? editor.GetLine (endLine) : startSegment;
if (endSegment == null)
return;
-
+
try {
var document = context.AnalysisDocument;
@@ -93,15 +94,15 @@ namespace MonoDevelop.CSharp.Formatting
formattingRules.Add (ContainedDocumentPreserveFormattingRule.Instance);
formattingRules.AddRange (Formatter.GetDefaultFormattingRules (document));
- var workspace = document.Project.Solution.Workspace;
+ var workspace = document.Project.Solution.Workspace;
var root = await document.GetSyntaxRootAsync (cancellationToken).ConfigureAwait (false);
- var options = await document.GetOptionsAsync (cancellationToken).ConfigureAwait (false);
+ var options = await document.GetOptionsAsync (cancellationToken).ConfigureAwait (false);
var changes = Formatter.GetFormattedTextChanges (
root, new TextSpan [] { new TextSpan (startSegment.Offset, endSegment.EndOffset - startSegment.Offset) },
workspace, options, formattingRules, cancellationToken);
if (changes == null)
- return;
+ return;
await Runtime.RunInMainThread (delegate {
editor.ApplyTextChanges (changes);
editor.FixVirtualIndentation ();
@@ -159,6 +160,9 @@ namespace MonoDevelop.CSharp.Formatting
{
readonly OptionSet optionSet;
readonly ICodingConventionsSnapshot codingConventionsSnapshot;
+ private static readonly ConditionalWeakTable<IReadOnlyDictionary<string, object>, IReadOnlyDictionary<string, string>> s_convertedDictionaryCache =
+ new ConditionalWeakTable<IReadOnlyDictionary<string, object>, IReadOnlyDictionary<string, string>> ();
+
public DocumentOptions (OptionSet optionSet, ICodingConventionsSnapshot codingConventionsSnapshot)
{
@@ -166,20 +170,24 @@ namespace MonoDevelop.CSharp.Formatting
this.codingConventionsSnapshot = codingConventionsSnapshot;
}
- public bool TryGetDocumentOption (OptionKey option, OptionSet underlyingOptions, out object value)
+ public bool TryGetDocumentOption (OptionKey option, out object value)
{
if (codingConventionsSnapshot != null) {
var editorConfigPersistence = option.Option.StorageLocations.OfType<IEditorConfigStorageLocation> ().SingleOrDefault ();
if (editorConfigPersistence != null) {
-
- var tempRawConventions = codingConventionsSnapshot.AllRawConventions;
- // HACK: temporarly map our old Dictionary<string, object> to a Dictionary<string, string>. This will go away in a future commit.
- // see https://github.com/dotnet/roslyn/commit/6a5be42f026f8d0432cfe8ee7770ff8f6be01bd6#diff-626aa9dd2f6e07eafa8eac7ddb0eb291R34
- var allRawConventions = ImmutableDictionary.CreateRange (tempRawConventions.Select (c => Roslyn.Utilities.KeyValuePairUtil.Create (c.Key, c.Value.ToString ())));
+ // Temporarly map our old Dictionary<string, object> to a Dictionary<string, string>. This can go away once we either
+ // eliminate the legacy editorconfig support, or we change IEditorConfigStorageLocation.TryGetOption to take
+ // some interface that lets us pass both the Dictionary<string, string> we get from the new system, and the
+ // Dictionary<string, object> from the old system.
+ //
+ // We cache this with a conditional weak table so we're able to maintain the assumptions in EditorConfigNamingStyleParser
+ // that the instance doesn't regularly change and thus can be used for further caching
+ var allRawConventions = s_convertedDictionaryCache.GetValue (
+ codingConventionsSnapshot.AllRawConventions,
+ d => ImmutableDictionary.CreateRange (d.Select (c => KeyValuePairUtil.Create (c.Key, c.Value.ToString ()))));
try {
- var underlyingOption = underlyingOptions.GetOption (option);
- if (editorConfigPersistence.TryGetOption (underlyingOption, allRawConventions, option.Option.Type, out value))
+ if (editorConfigPersistence.TryGetOption (allRawConventions, option.Option.Type, out value))
return true;
} catch (Exception ex) {
LoggingService.LogError ("Error while getting editor config preferences.", ex);
@@ -188,10 +196,6 @@ namespace MonoDevelop.CSharp.Formatting
}
var result = optionSet.GetOption (option);
- if (result == underlyingOptions.GetOption (option)) {
- value = null;
- return false;
- }
value = result;
return true;
}
@@ -210,7 +214,7 @@ namespace MonoDevelop.CSharp.Formatting
public override object GetOption (OptionKey optionKey)
{
- if (optionsProvider.TryGetDocumentOption (optionKey, fallbackOptionSet, out object value))
+ if (optionsProvider.TryGetDocumentOption (optionKey, out object value))
return value;
return fallbackOptionSet.GetOption (optionKey);
}
diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.OptionProvider/CSharpDocumentOptionsProvider.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.OptionProvider/CSharpDocumentOptionsProvider.cs
index 0ff4f59c7f..b48aca4ce4 100644
--- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.OptionProvider/CSharpDocumentOptionsProvider.cs
+++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.OptionProvider/CSharpDocumentOptionsProvider.cs
@@ -29,6 +29,7 @@ using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Options;
+using Roslyn.Utilities;
using MonoDevelop.CSharp.Formatting;
using MonoDevelop.Ide.Gui.Content;
using MonoDevelop.Ide.TypeSystem;
@@ -40,6 +41,7 @@ using System.Linq;
using MonoDevelop.Ide.Editor;
using System.Collections.Generic;
using System.Collections.Immutable;
+using System.Runtime.CompilerServices;
namespace MonoDevelop.CSharp.OptionProvider
{
@@ -87,6 +89,8 @@ namespace MonoDevelop.CSharp.OptionProvider
TextStylePolicy TextPolicy => textpolicy ?? (textpolicy = policyBag?.Get<TextStylePolicy> (types) ?? PolicyService.InvariantPolicies?.Get<TextStylePolicy> (types));
readonly ICodingConventionsSnapshot codingConventionsSnapshot;
+ private static readonly ConditionalWeakTable<IReadOnlyDictionary<string, object>, IReadOnlyDictionary<string, string>> s_convertedDictionaryCache =
+ new ConditionalWeakTable<IReadOnlyDictionary<string, object>, IReadOnlyDictionary<string, string>> ();
public DocumentOptions (PolicyBag policyBag, ICodingConventionsSnapshot codingConventionsSnapshot)
{
@@ -94,20 +98,24 @@ namespace MonoDevelop.CSharp.OptionProvider
this.codingConventionsSnapshot = codingConventionsSnapshot;
}
- public bool TryGetDocumentOption (OptionKey option, OptionSet underlyingOptions, out object value)
+ public bool TryGetDocumentOption (OptionKey option, out object value)
{
if (codingConventionsSnapshot != null) {
var editorConfigPersistence = option.Option.StorageLocations.OfType<IEditorConfigStorageLocation> ().SingleOrDefault ();
if (editorConfigPersistence != null) {
-
- var tempRawConventions = codingConventionsSnapshot.AllRawConventions;
- // HACK: temporarly map our old Dictionary<string, object> to a Dictionary<string, string>. This will go away in a future commit.
- // see https://github.com/dotnet/roslyn/commit/6a5be42f026f8d0432cfe8ee7770ff8f6be01bd6#diff-626aa9dd2f6e07eafa8eac7ddb0eb291R34
- var allRawConventions = ImmutableDictionary.CreateRange (tempRawConventions.Select (c => Roslyn.Utilities.KeyValuePairUtil.Create (c.Key, c.Value.ToString ())));
+ // Temporarly map our old Dictionary<string, object> to a Dictionary<string, string>. This can go away once we either
+ // eliminate the legacy editorconfig support, or we change IEditorConfigStorageLocation.TryGetOption to take
+ // some interface that lets us pass both the Dictionary<string, string> we get from the new system, and the
+ // Dictionary<string, object> from the old system.
+ //
+ // We cache this with a conditional weak table so we're able to maintain the assumptions in EditorConfigNamingStyleParser
+ // that the instance doesn't regularly change and thus can be used for further caching
+ var allRawConventions = s_convertedDictionaryCache.GetValue (
+ codingConventionsSnapshot.AllRawConventions,
+ d => ImmutableDictionary.CreateRange (d.Select (c => KeyValuePairUtil.Create (c.Key, c.Value.ToString ()))));
try {
- var underlyingOption = Policy.OptionSet.GetOption (option);
- if (editorConfigPersistence.TryGetOption (underlyingOption, allRawConventions, option.Option.Type, out value))
+ if (editorConfigPersistence.TryGetOption (allRawConventions, option.Option.Type, out value))
return true;
} catch (Exception ex) {
LoggingService.LogError ("Error while getting editor config preferences.", ex);
@@ -141,10 +149,6 @@ namespace MonoDevelop.CSharp.OptionProvider
}
var result = Policy.OptionSet.GetOption (option);
- if (result == underlyingOptions.GetOption (option)) {
- value = null;
- return false;
- }
value = result;
return true;
}
diff --git a/main/src/addins/MacPlatform/MacPlatform.cs b/main/src/addins/MacPlatform/MacPlatform.cs
index 1629226be7..06754b11a1 100644
--- a/main/src/addins/MacPlatform/MacPlatform.cs
+++ b/main/src/addins/MacPlatform/MacPlatform.cs
@@ -286,11 +286,7 @@ namespace MonoDevelop.MacIntegration
public override Xwt.Toolkit LoadNativeToolkit ()
{
- var path = Path.GetDirectoryName (GetType ().Assembly.Location);
- Assembly.LoadFrom (Path.Combine (path, "Xwt.XamMac.dll"));
-
- // Also calls NSApplication.Init();
- var loaded = Xwt.Toolkit.Load (Xwt.ToolkitType.XamMac);
+ var loaded = NativeToolkitHelper.LoadCocoa ();
loaded.RegisterBackend<Xwt.Backends.IDialogBackend, ThemedMacDialogBackend> ();
loaded.RegisterBackend<Xwt.Backends.IWindowBackend, ThemedMacWindowBackend> ();
@@ -347,6 +343,15 @@ namespace MonoDevelop.MacIntegration
if (MacSystemInformation.OsVersion >= MacSystemInformation.Sierra)
NSWindow.AllowsAutomaticWindowTabbing = false;
+
+ // At this point, Cocoa should have been initialized; it is initialized along with Gtk+ at the beginning of IdeStartup.Run
+ // If LaunchReason is still Unknown at this point, it means we have missed the NSApplicationDidLaunch notification for some reason and
+ // we fall back to it being a Normal startup to unblock anything waiting for that notification.
+ if (IdeApp.LaunchReason == IdeApp.LaunchType.Unknown) {
+ LoggingService.LogWarning ("Missed NSApplicationDidLaunch notification, assuming normal startup");
+ IdeApp.LaunchReason = IdeApp.LaunchType.Normal;
+ }
+
return loaded;
}
diff --git a/main/src/addins/MonoDevelop.SourceEditor2/VSEditor/TextEditorInitializationService.cs b/main/src/addins/MonoDevelop.SourceEditor2/VSEditor/TextEditorInitializationService.cs
index e5e07bf5ee..6567740e6b 100644
--- a/main/src/addins/MonoDevelop.SourceEditor2/VSEditor/TextEditorInitializationService.cs
+++ b/main/src/addins/MonoDevelop.SourceEditor2/VSEditor/TextEditorInitializationService.cs
@@ -66,6 +66,9 @@ namespace Microsoft.VisualStudio.Text.Editor.Implementation
internal ITextSearchService2 TextSearchService { get; set; }
[Import]
+ internal IFeatureServiceFactory FeatureServiceFactory { get; set; }
+
+ [Import]
internal ITextStructureNavigatorSelectorService TextStructureNavigatorSelectorService { get; set; }
[Import]
@@ -140,6 +143,8 @@ namespace Microsoft.VisualStudio.Text.Editor.Implementation
view.Initialize(viewModel, roles, this.EditorOptionsFactoryService.GlobalOptions, this);
view.Properties.AddProperty(typeof(MonoDevelop.Ide.Editor.TextEditor), textEditor);
+ FeatureServiceFactory.GetOrCreate(view).Disable(PredefinedEditorFeatureNames.AsyncCompletion, EmptyFeatureController.Instance);
+
this.TextViewCreated?.Invoke(this, new TextViewCreatedEventArgs(view));
return view;
@@ -191,5 +196,14 @@ namespace Microsoft.VisualStudio.Text.Editor.Implementation
this.OrderedSpaceReservationManagerDefinitions.Add(orderedManagers[i].Metadata.Name, i);
}
}
+
+ sealed class EmptyFeatureController : IFeatureController
+ {
+ internal static readonly EmptyFeatureController Instance = new EmptyFeatureController();
+
+ private EmptyFeatureController()
+ {
+ }
+ }
}
}
diff --git a/main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor.Cocoa/Properties/MonoDevelop.TextEditor.Cocoa.addin.xml b/main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor.Cocoa/Properties/MonoDevelop.TextEditor.Cocoa.addin.xml
index 7ec39438a2..3295568c79 100644
--- a/main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor.Cocoa/Properties/MonoDevelop.TextEditor.Cocoa.addin.xml
+++ b/main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor.Cocoa/Properties/MonoDevelop.TextEditor.Cocoa.addin.xml
@@ -87,8 +87,10 @@
<StockIcon stockid="vs-signature-help-next" resource="go-down-16.png" size="Menu" imageid="{95fdedcb-dc13-48a8-8165-ed1fff877d9a}#2" />
</Extension>
<Extension path = "/MonoDevelop/TextEditor/CommandMapping">
+ <!--
+ Don't re-add this! See bug 937834 for more details. Basically let native editor handle this.
<Map id="MonoDevelop.Ide.Commands.EditCommands.DeleteKey" argsType="Microsoft.VisualStudio.Text.Editor.Commanding.Commands.BackspaceKeyCommandArgs" />
-
+ -->
<Map id="MonoDevelop.Ide.Commands.SearchCommands.Find" argsType="Microsoft.VisualStudio.Text.Editor.Commanding.Commands.FindCommandArgs" />
<Map id="MonoDevelop.Ide.Commands.SearchCommands.FindNext" argsType="Microsoft.VisualStudio.Text.Editor.Commanding.Commands.FindNextCommandArgs" />
<Map id="MonoDevelop.Ide.Commands.SearchCommands.FindPrevious" argsType="Microsoft.VisualStudio.Text.Editor.Commanding.Commands.FindPreviousCommandArgs" />
diff --git a/main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor/TextViewContent.cs b/main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor/TextViewContent.cs
index 45214893dc..5618666b3a 100644
--- a/main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor/TextViewContent.cs
+++ b/main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor/TextViewContent.cs
@@ -238,12 +238,6 @@ namespace MonoDevelop.TextEditor
textBufferRegistration = IdeServices.TypeSystemService.RegisterOpenDocument (Owner, FilePath, TextBuffer);
}
- protected override void OnGrabFocus (DocumentView view)
- {
- DefaultSourceEditorOptions.SetUseAsyncCompletion (true);
- base.OnGrabFocus (view);
- }
-
protected override void OnFileNameChanged ()
{
base.OnFileNameChanged ();
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProject.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProject.cs
index d103fe3864..b971b89aa9 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProject.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProject.cs
@@ -1091,7 +1091,7 @@ namespace MonoDevelop.Projects
context.LogVerbosity = MSBuildVerbosity.Quiet;
context.GlobalProperties.SetValue ("Silent", true);
- var result = await RunTarget (monitor, "ResolveAssemblyReferences", configuration, context);
+ var result = await RunTargetInternal (monitor, "ResolveAssemblyReferences", configuration, context);
refs = result.Items.Select (i => new AssemblyReference (i.Include, i.Metadata)).ToList ();
@@ -1152,7 +1152,7 @@ namespace MonoDevelop.Projects
context.LoadReferencedProjects = false;
context.LogVerbosity = MSBuildVerbosity.Quiet;
- var result = await RunTarget (monitor, "ResolvePackageDependenciesDesignTime", configuration, context);
+ var result = await RunTargetInternal (monitor, "ResolvePackageDependenciesDesignTime", configuration, context);
if (result == null)
return new List<PackageDependency> ();
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs
index e53cda474c..7e62055fe7 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs
@@ -706,7 +706,7 @@ namespace MonoDevelop.Projects
ctx.BuilderQueue = BuilderQueue.ShortOperations;
ctx.LogVerbosity = MSBuildVerbosity.Quiet;
- var evalResult = await project.RunTarget (monitor, dependsList, config.Selector, ctx);
+ var evalResult = await project.RunTargetInternal (monitor, dependsList, config.Selector, ctx);
if (evalResult != null && evalResult.Items != null) {
result = ProcessMSBuildItems (evalResult.Items, project);
}
@@ -1251,6 +1251,13 @@ namespace MonoDevelop.Projects
/// </param>
public Task<TargetEvaluationResult> RunTarget (ProgressMonitor monitor, string target, ConfigurationSelector configuration, TargetEvaluationContext context = null)
{
+ return BindTask<TargetEvaluationResult> (cancelToken => {
+ return RunTargetInternal (monitor.WithCancellationToken (cancelToken), target, configuration, context);
+ });
+ }
+
+ internal Task<TargetEvaluationResult> RunTargetInternal (ProgressMonitor monitor, string target, ConfigurationSelector configuration, TargetEvaluationContext context = null)
+ {
// Initialize the evaluation context. This initialization is shared with FastCheckNeedsBuild.
// Extenders will override OnConfigureTargetEvaluationContext to add custom properties and do other
// initializations required by MSBuild.
@@ -1865,7 +1872,7 @@ namespace MonoDevelop.Projects
protected override async Task<BuildResult> OnBuild (ProgressMonitor monitor, ConfigurationSelector configuration, OperationContext operationContext)
{
var newContext = operationContext as TargetEvaluationContext ?? new TargetEvaluationContext (operationContext);
- return (await RunTarget (monitor, "Build", configuration, newContext)).BuildResult;
+ return (await RunTargetInternal (monitor, "Build", configuration, newContext)).BuildResult;
}
async Task<TargetEvaluationResult> RunBuildTarget (ProgressMonitor monitor, ConfigurationSelector configuration, TargetEvaluationContext context)
@@ -2250,7 +2257,7 @@ namespace MonoDevelop.Projects
protected override async Task<BuildResult> OnClean (ProgressMonitor monitor, ConfigurationSelector configuration, OperationContext buildSession)
{
var newContext = buildSession as TargetEvaluationContext ?? new TargetEvaluationContext (buildSession);
- return (await RunTarget (monitor, "Clean", configuration, newContext)).BuildResult;
+ return (await RunTargetInternal (monitor, "Clean", configuration, newContext)).BuildResult;
}
Task<TargetEvaluationResult> RunCleanTarget (ProgressMonitor monitor, ConfigurationSelector configuration, TargetEvaluationContext context)
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/IdeTheme.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/IdeTheme.cs
index 04f317bced..49299ad156 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/IdeTheme.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/IdeTheme.cs
@@ -71,9 +71,7 @@ namespace MonoDevelop.Components
#if MAC
// Early init Cocoa through xwt
- var path = Path.GetDirectoryName (typeof (IdeTheme).Assembly.Location);
- System.Reflection.Assembly.LoadFrom (Path.Combine (path, "Xwt.XamMac.dll"));
- var loaded = Xwt.Toolkit.Load (Xwt.ToolkitType.XamMac);
+ var loaded = NativeToolkitHelper.LoadCocoa ();
var disableA11y = Environment.GetEnvironmentVariable ("DISABLE_ATKCOCOA");
if (Platform.IsMac && (NSUserDefaults.StandardUserDefaults.BoolForKey ("com.monodevelop.AccessibilityEnabled") && string.IsNullOrEmpty (disableA11y))) {
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/Mac/NativeToolkitHelper.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/Mac/NativeToolkitHelper.cs
new file mode 100644
index 0000000000..b20bb6c584
--- /dev/null
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/Mac/NativeToolkitHelper.cs
@@ -0,0 +1,65 @@
+//
+// NativeToolkitHelper.cs
+//
+// Author:
+// iain <iaholmes@microsoft.com>
+//
+// Copyright (c) 2019
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#if MAC
+using System;
+using System.IO;
+
+using AppKit;
+using Foundation;
+
+using MonoDevelop.Core;
+using MonoDevelop.Ide;
+
+namespace MonoDevelop.Components.Mac
+{
+ internal static class NativeToolkitHelper
+ {
+ static Xwt.Toolkit toolkit;
+ internal static Xwt.Toolkit LoadCocoa ()
+ {
+ if (toolkit != null) {
+ return toolkit;
+ }
+
+ var path = Path.GetDirectoryName (typeof (IdeTheme).Assembly.Location);
+ System.Reflection.Assembly.LoadFrom (Path.Combine (path, "Xwt.XamMac.dll"));
+ toolkit = Xwt.Toolkit.Load (Xwt.ToolkitType.XamMac);
+
+ NSNotificationCenter.DefaultCenter.AddObserver (NSApplication.DidFinishLaunchingNotification, (note) => {
+ if (note.UserInfo.TryGetValue (NSApplication.LaunchIsDefaultLaunchKey, out var val)) {
+ if (val is NSNumber num) {
+ IdeApp.LaunchReason = num.BoolValue ? IdeApp.LaunchType.Normal : IdeApp.LaunchType.LaunchedFromFileManager;
+ LoggingService.LogDebug ($"Startup was {IdeApp.LaunchReason}");
+ }
+ }
+ });
+
+ return toolkit;
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Desktop/PlatformService.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Desktop/PlatformService.cs
index f7ba28cf59..f7c685f6e4 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Desktop/PlatformService.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Desktop/PlatformService.cs
@@ -107,7 +107,9 @@ namespace MonoDevelop.Ide.Desktop
if (Path.IsPathRooted (uri) && File.Exists (uri) && !Core.Text.TextFileUtility.IsBinary (uri)) {
return "text/plain";
}
- } catch (IOException) {}
+ }
+ catch (UnauthorizedAccessException) {}
+ catch (IOException) {}
return "application/octet-stream";
}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/DefaultSourceEditorOptions.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/DefaultSourceEditorOptions.cs
index 2757ac63c8..3d812dfa67 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/DefaultSourceEditorOptions.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/DefaultSourceEditorOptions.cs
@@ -993,20 +993,6 @@ namespace MonoDevelop.Ide.Editor
}
public event EventHandler Changed;
-
- /// <summary>
- /// This is to allow setting UseAsyncCompletion to true for the Cocoa editor and to false for the Gtk editor.
- /// Currently Roslyn doesn't allow setting this option per view, so we have to work around.
- /// See here for details: https://github.com/dotnet/roslyn/issues/33807
- /// </summary>
- internal static void SetUseAsyncCompletion(bool useAsyncCompletion)
- {
- var asyncCompletionService = Composition.CompositionManager.Instance.GetExportedValue<Microsoft.CodeAnalysis.Editor.IAsyncCompletionService> ();
- var field = asyncCompletionService.GetType ().GetField (
- "_newCompletionAPIEnabled",
- System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
- field.SetValue (asyncCompletionService, useAsyncCompletion);
- }
}
}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/TextEditorViewContent.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/TextEditorViewContent.cs
index 62b604c931..b262e0c3cf 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/TextEditorViewContent.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/TextEditorViewContent.cs
@@ -409,11 +409,6 @@ namespace MonoDevelop.Ide.Editor
protected override void OnGrabFocus (DocumentView view)
{
textEditor.GrabFocus ();
- try {
- DefaultSourceEditorOptions.SetUseAsyncCompletion (false);
- } catch (Exception e) {
- LoggingService.LogInternalError ("Error while setting up async completion.", e);
- }
}
}
} \ No newline at end of file
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Documents/DocumentManager.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Documents/DocumentManager.cs
index ef1f5c361f..c01448bdb4 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Documents/DocumentManager.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Documents/DocumentManager.cs
@@ -658,10 +658,11 @@ namespace MonoDevelop.Ide.Gui.Documents
var offset = info.Offset;
if (offset < 0) {
var line = textView.TextSnapshot.GetLineFromLineNumber (info.Line - 1);
- if (info.Column >= 1)
- offset = line.Start + info.Column - 1;
- else
+ if (info.Column >= 1) {
+ offset = line.Start + Math.Min (info.Column - 1, line.Length);
+ } else {
offset = line.Start;
+ }
}
if (editorOperationsFactoryService != null) {
var editorOperations = editorOperationsFactoryService.GetEditorOperations (textView);
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/CommentTasksProvider.Legacy.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/CommentTasksProvider.Legacy.cs
index 044917dd90..b0fa0146e3 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/CommentTasksProvider.Legacy.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/CommentTasksProvider.Legacy.cs
@@ -156,21 +156,27 @@ namespace MonoDevelop.Ide.Tasks
void Context_DocumentParsed (object sender, EventArgs e)
{
- var pd = context.ParsedDocument;
- var project = Controller.Owner as Project;
- if (project == null || !(Controller is FileDocumentController fileController))
- return;
- ProjectCommentTags tags;
- if (!CommentTasksProvider.Legacy.ProjectTags.TryGetValue (project, out tags))
- return;
- var token = CommentTasksProvider.Legacy.CancellationToken;
- var file = fileController.FilePath;
- Task.Run (async () => {
- try {
- tags.UpdateTags (project, file, await pd.GetTagCommentsAsync (token).ConfigureAwait (false));
- } catch (OperationCanceledException) {
- }
- });
+ try {
+ var pd = context.ParsedDocument;
+ if (pd == null)
+ return;
+ if (!(Controller is FileDocumentController fileController) || !(Controller.Owner is Project project))
+ return;
+ if (!CommentTasksProvider.Legacy.ProjectTags.TryGetValue (project, out var tags))
+ return;
+ var token = CommentTasksProvider.Legacy.CancellationToken;
+ var file = fileController.FilePath;
+ Task.Run (async () => {
+ try {
+ tags.UpdateTags (project, file, await pd.GetTagCommentsAsync (token).ConfigureAwait (false));
+ } catch (OperationCanceledException) {
+ } catch (Exception ex) {
+ LoggingService.LogError ("Error while updating comment tags.", ex);
+ }
+ }).Ignore ();
+ } catch (Exception ex) {
+ LoggingService.LogInternalError (ex);
+ }
}
}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/TextPolicyDocumentOptionsProvider.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/TextPolicyDocumentOptionsProvider.cs
index 1b05fd4fe9..5bc70be2cf 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/TextPolicyDocumentOptionsProvider.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/TextPolicyDocumentOptionsProvider.cs
@@ -68,7 +68,7 @@ namespace MonoDevelop.Ide.TypeSystem
this.policy = policy;
}
- public bool TryGetDocumentOption (OptionKey option, OptionSet underlyingOptions, out object value)
+ public bool TryGetDocumentOption (OptionKey option, out object value)
{
if (option.Option == FormattingOptions.UseTabs) {
value = !policy.TabsToSpaces;
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.WelcomePage/IWelcomeWindowProvider.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.WelcomePage/IWelcomeWindowProvider.cs
index 32ffa1fed5..87cc92387a 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.WelcomePage/IWelcomeWindowProvider.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.WelcomePage/IWelcomeWindowProvider.cs
@@ -52,7 +52,7 @@ namespace MonoDevelop.Ide.WelcomePage
public interface IWelcomeWindowProvider
{
Task ShowWindow (WelcomeWindowShowOptions options);
- void HideWindow ();
+ Task HideWindow ();
bool IsWindowVisible { get; }
Window WindowInstance { get; }
}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.WelcomePage/WelcomePageService.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.WelcomePage/WelcomePageService.cs
index 31e09571d6..8699251b76 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.WelcomePage/WelcomePageService.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.WelcomePage/WelcomePageService.cs
@@ -81,7 +81,14 @@ namespace MonoDevelop.Ide.WelcomePage
if (!hideWelcomePage && HasWindowImplementation) {
await Runtime.GetService<DesktopService> ();
var commandManager = await Runtime.GetService<CommandManager> ();
- await ShowWelcomeWindow (new WelcomeWindowShowOptions (false));
+
+ var reason = await IdeApp.LaunchCompletionSource.Task;
+
+ if (IdeApp.LaunchReason == IdeApp.LaunchType.Normal) {
+ await ShowWelcomeWindow (new WelcomeWindowShowOptions (false));
+ } else if (IdeApp.LaunchReason == IdeApp.LaunchType.Unknown) {
+ LoggingService.LogInternalError ("LaunchCompletion is still Unknown", new Exception ());
+ }
}
}
@@ -105,14 +112,13 @@ namespace MonoDevelop.Ide.WelcomePage
}
}
- public static void HideWelcomePageOrWindow ()
+ public static async void HideWelcomePageOrWindow ()
{
if (WelcomeWindowProvider != null) {
- WelcomeWindowProvider.HideWindow ();
+ await WelcomeWindowProvider.HideWindow ();
} else {
HideWelcomePage (true);
}
-
visible = false;
}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj
index eea0b0b9c2..35329ccb92 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj
@@ -4251,6 +4251,7 @@
<Compile Include="MonoDevelop.Components.Docking\SplitterWidgetWrapper.cs" />
<Compile Include="MonoDevelop.Components.Docking\SplitterMacHostWidget.cs" />
<Compile Include="MonoDevelop.Components\Mac\DragEventTrapView.cs" />
+ <Compile Include="MonoDevelop.Components\Mac\NativeToolkitHelper.cs" />
</ItemGroup>
<ItemGroup Condition="'$(Configuration)' == 'DebugMac' OR '$(Configuration)' == 'ReleaseMac'">
<Compile Include="MonoDevelop.Components\Mac\KeyCodes.cs" />
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/Ide.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/Ide.cs
index 6be545748b..da8982d467 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/Ide.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/Ide.cs
@@ -180,6 +180,27 @@ namespace MonoDevelop.Ide
}
}
+ public enum LaunchType
+ {
+ Unknown,
+ Normal,
+ LaunchedFromFileManager
+ }
+
+ static LaunchType launchType = LaunchType.Unknown;
+ public static LaunchType LaunchReason {
+ get => launchType;
+ internal set {
+ launchType = value;
+
+ if (!LaunchCompletionSource.TrySetResult (value)) {
+ LoggingService.LogWarning ($"LaunchReason is already set to {launchType}.");
+ }
+ }
+ }
+
+ internal static TaskCompletionSource<LaunchType> LaunchCompletionSource { get; } = new TaskCompletionSource<LaunchType>();
+
public static async Task Initialize (ProgressMonitor monitor, bool hideWelcomePage = false)
{
// Already done in IdeSetup, but called again since unit tests don't use IdeSetup.
@@ -295,6 +316,11 @@ namespace MonoDevelop.Ide
AddinManager.AddExtensionNodeHandler ("/MonoDevelop/Ide/StartupHandlers", OnExtensionChanged);
}
+ public static Task EnsureInitializedAsync ()
+ {
+ return initializationTask.Task;
+ }
+
public static void BringToFront ()
{
Initialized += (sender, e) => {
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/IdeStartup.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/IdeStartup.cs
index 0a1444164a..e4318f6f7b 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/IdeStartup.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/IdeStartup.cs
@@ -117,6 +117,13 @@ namespace MonoDevelop.Ide
IdeTheme.InitializeGtk (BrandingService.ApplicationName, ref args);
startupInfo = new StartupInfo (options, args);
+ if (startupInfo.HasFiles) {
+ // If files are present, consider started from the commandline as being the same as file manager.
+ // On macOS, we need to wait until the DidFinishLaunching notification to find out we were launched from the Finder
+ IdeApp.LaunchReason = IdeApp.LaunchType.LaunchedFromFileManager;
+ } else if (!Platform.IsMac) {
+ IdeApp.LaunchReason = IdeApp.LaunchType.Normal;
+ }
IdeApp.Customizer = options.IdeCustomizer ?? new IdeCustomizer ();
try {