diff options
Diffstat (limited to 'main/src/core/MonoDevelop.Ide')
9 files changed, 283 insertions, 89 deletions
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands/CommandManager.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands/CommandManager.cs index f2bafbd922..c1be68eb9e 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands/CommandManager.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands/CommandManager.cs @@ -2304,10 +2304,18 @@ namespace MonoDevelop.Components.Commands Window GetActiveWindow (Window win) { - Gtk.Window [] wins = Gtk.Window.ListToplevels (); - - bool hasFocus = false; bool lastFocusedExists = lastFocused == null; + bool hasFocus = false; +#if MAC + var nsWindow = AppKit.NSApplication.SharedApplication.KeyWindow; + hasFocus = nsWindow != null; + if (hasFocus) { + lastFocusedExists |= lastFocused?.nativeWidget == nsWindow; + lastFocused = win = nsWindow; + } else { +#endif + + Gtk.Window [] wins = Gtk.Window.ListToplevels (); Gtk.Window newFocused = null; foreach (Gtk.Window w in wins) { if (w.Visible) { @@ -2324,18 +2332,9 @@ namespace MonoDevelop.Components.Commands } } + lastFocused = newFocused; #if MAC - if (!hasFocus) { - var nsWindow = AppKit.NSApplication.SharedApplication.KeyWindow; - hasFocus = nsWindow != null; - if (hasFocus) { - lastFocused = win = nsWindow; - } - } else { - lastFocused = newFocused; } -#else - lastFocused = newFocused; #endif UpdateAppFocusStatus (hasFocus, lastFocusedExists); @@ -2343,8 +2342,7 @@ namespace MonoDevelop.Components.Commands if (win != null && win.IsRealized) { RegisterTopWindow (win); return win; - } - else + } else return null; } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/Control.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/Control.cs index 842593a939..3a9f8409ed 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/Control.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/Control.cs @@ -55,7 +55,7 @@ namespace MonoDevelop.Components { throw new NotSupportedException (); } - + public T GetNativeWidget<T> () where T : class { if (nativeWidget == null) { @@ -92,6 +92,16 @@ namespace MonoDevelop.Components throw new NotSupportedException ($"Cannot get native widget {typeof (T)}"); } + public bool TryGetNativeWidget<T> (out T widget) where T : class + { + if (nativeWidget is T) { + widget = GetNativeWidget<T> (); + return true; + } + widget = null; + return false; + } + void OnGtkDestroyed (object sender, EventArgs args) { GC.SuppressFinalize (this); diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/Window.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/Window.cs index bd3012bef4..8446f68609 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/Window.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/Window.cs @@ -218,8 +218,7 @@ namespace MonoDevelop.Components { try { #if MAC - var nsWindow = parent.GetNativeWidget<NSWindow> (); - if (nsWindow != null) { + if (parent.TryGetNativeWidget<NSWindow> (out var nsWindow)) { var myNSWindow = MonoDevelop.Components.Mac.GtkMacInterop.GetNSWindow (window); myNSWindow.ParentWindow = nsWindow; } else { diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/ProjectFileNodeBuilder.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/ProjectFileNodeBuilder.cs index 4fe44f4e70..b5d291af29 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/ProjectFileNodeBuilder.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/ProjectFileNodeBuilder.cs @@ -285,35 +285,51 @@ namespace MonoDevelop.Ide.Gui.Pads.ProjectPad } string question; - bool allLinkedFiles = CheckAllLinkedFile (files); + bool fileExists = CheckAnyFileExists(files); - if (allLinkedFiles) { + if (CheckAllLinkedFile (files)) { RemoveFilesFromProject (false, files); } else { - - bool filesExist = CheckAnyFileExists (files); - if (hasChildren) { - if (files.Count == 1) - question = GettextCatalog.GetString ("Are you sure you want to delete the file {0} and " + + if (files.Count == 1) { + if (fileExists) + question = GettextCatalog.GetString ("Are you sure you want to delete the file {0} and " + + "its code-behind children from project {1}?", + Path.GetFileName (files [0].Name), files [0].Project.Name); + else + question = GettextCatalog.GetString ("Are you sure you want to remove the file {0} and " + "its code-behind children from project {1}?", Path.GetFileName (files [0].Name), files [0].Project.Name); - else - question = GettextCatalog.GetString ("Are you sure you want to delete the selected files and " + + } else { + if (fileExists) + question = GettextCatalog.GetString ("Are you sure you want to delete the selected files and " + "their code-behind children from the project?"); + else + question = GettextCatalog.GetString ("Are you sure you want to remove the selected files and " + + "their code-behind children from the project?"); + } } else { - if (files.Count == 1) - question = GettextCatalog.GetString ("Are you sure you want to delete file {0} from project {1}?", + if (files.Count == 1) { + if (fileExists) + question = GettextCatalog.GetString ("Are you sure you want to delete file {0} from project {1}?", Path.GetFileName (files [0].Name), files [0].Project.Name); - else - question = GettextCatalog.GetString ("Are you sure you want to delete the selected files from the project?"); + else + question = GettextCatalog.GetString ("Are you sure you want to remove file {0} from project {1}?", + Path.GetFileName (files [0].Name), files [0].Project.Name); + + } else { + if (fileExists) + question = GettextCatalog.GetString ("Are you sure you want to delete the selected files from the project?"); + else + question = GettextCatalog.GetString ("Are you sure you want to remove the selected files from the project?"); + } } - - var result = MessageService.AskQuestion (question, GetDeleteConfirmationButtons (filesExist)); - if (result != AlertButton.Delete) - return; - RemoveFilesFromProject (true, files); + var result = MessageService.AskQuestion (question, new [] { AlertButton.Cancel, fileExists ? AlertButton.Delete : AlertButton.Remove }); + if (result == AlertButton.Cancel) + return; + else + RemoveFilesFromProject (fileExists, files); } IdeApp.ProjectOperations.SaveAsync (projects); @@ -323,18 +339,13 @@ namespace MonoDevelop.Ide.Gui.Pads.ProjectPad [AllowMultiSelection] void OnUpdateDeleteMultipleItems (CommandInfo info) { + var files = new List<ProjectFile> (); foreach (var node in CurrentNodes) { var pf = (ProjectFile)node.DataItem; - if (pf.IsLink) - info.Text = GettextCatalog.GetString ("Remove"); + files.Add (pf); } - } - - static AlertButton [] GetDeleteConfirmationButtons (bool includeDelete) - { - if (includeDelete) - return new [] { AlertButton.Cancel, AlertButton.Delete }; - return new [] { AlertButton.Cancel }; + if (!CheckAnyFileExists(files)) + info.Text = GettextCatalog.GetString ("Remove"); } [CommandHandler (ProjectCommands.ExcludeFromProject)] @@ -379,7 +390,7 @@ namespace MonoDevelop.Ide.Gui.Pads.ProjectPad // Delete file before removing them from the project to avoid Remove items being added // if the project is currently being saved in memory or to disk. - if (delete && !file.IsLink) + if (delete && !file.IsLink && File.Exists (file.Name)) FileService.DeleteFile (file.Name); project.Files.Remove (file); } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/IMonoDevelopHostDocument.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/IMonoDevelopHostDocument.cs index 0cf42cb198..62cac4ad7c 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/IMonoDevelopHostDocument.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/IMonoDevelopHostDocument.cs @@ -32,7 +32,12 @@ namespace MonoDevelop.Ide.TypeSystem textBuffer?.Properties.RemoveProperty (typeof (IMonoDevelopHostDocument));
}
- internal static IMonoDevelopHostDocument FromDocument(Document document)
+ internal static IMonoDevelopHostDocument FromDocument (Document document)
+ {
+ return FromDocument ((TextDocument)document);
+ }
+
+ internal static IMonoDevelopHostDocument FromDocument(TextDocument document)
{
IMonoDevelopHostDocument containedDocument = null;
if (document.TryGetText (out SourceText sourceText)) {
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.MetadataReferenceHandler.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.MetadataReferenceHandler.cs index 30d2903c51..ea3fa26e76 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.MetadataReferenceHandler.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.MetadataReferenceHandler.cs @@ -107,6 +107,8 @@ namespace MonoDevelop.Ide.TypeSystem async Task<bool> AddReferences (AddReferencesData data) { try { + if (data.Project.ParentSolution == null) + return false; var referencedAssemblies = await data.Project.GetReferencedAssemblies (data.ConfigurationSelector, true).ConfigureAwait (false); foreach (var file in referencedAssemblies) { if (file.IsProjectReference) { diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.cs index 0032dd5951..da13412e27 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.cs @@ -486,7 +486,7 @@ namespace MonoDevelop.Ide.TypeSystem return await TryLoadSolution (cancellationToken).ConfigureAwait (false);
}
- async Task ReloadProjects (CancellationToken cancellationToken)
+ internal async Task ReloadProjects (CancellationToken cancellationToken)
{
try {
using var cts = CancellationTokenSource.CreateLinkedTokenSource (cancellationToken, src.Token);
@@ -731,9 +731,9 @@ namespace MonoDevelop.Ide.TypeSystem tryApplyState_documentTextChangedTasks.Add (ApplyDocumentTextChangedCore (id, text));
}
- async Task ApplyDocumentTextChangedCore (DocumentId id, SourceText text)
+ async Task ApplyDocumentTextChangedCore (DocumentId id, SourceText text, bool isAnalyzerConfigFile = false)
{
- var document = GetDocument (id);
+ TextDocument document = isAnalyzerConfigFile ? GetAnalyzerConfigDocument (id) : GetDocument (id);
if (document == null)
return;
@@ -750,12 +750,21 @@ namespace MonoDevelop.Ide.TypeSystem return; } }
- var (projection, filePath) = Projections.Get (document.FilePath);
- var data = TextFileProvider.Instance.GetTextEditorData (filePath, out bool isOpen);
- // Guard against already done changes in linked files.
- // This shouldn't happen but the roslyn merging seems not to be working correctly in all cases :/
- if (document.GetLinkedDocumentIds ().Length > 0 && isOpen && !(text.GetType ().FullName == "Microsoft.CodeAnalysis.Text.ChangedText")) {
- return;
+ Projection projection = null;
+ FilePath filePath;
+ ITextDocument data = null;
+ bool isOpen;
+ if (isAnalyzerConfigFile) {
+ filePath = document.FilePath;
+ data = TextFileProvider.Instance.GetTextEditorData (filePath, out isOpen);
+ } else {
+ (projection, filePath) = Projections.Get (document.FilePath);
+ data = TextFileProvider.Instance.GetTextEditorData (filePath, out isOpen);
+ // Guard against already done changes in linked files.
+ // This shouldn't happen but the roslyn merging seems not to be working correctly in all cases :/
+ if (((Document)document).GetLinkedDocumentIds ().Length > 0 && isOpen && !(text.GetType ().FullName == "Microsoft.CodeAnalysis.Text.ChangedText")) {
+ return;
+ }
}
lock (tryApplyState_documentTextChangedContents) {
@@ -799,20 +808,29 @@ namespace MonoDevelop.Ide.TypeSystem }
data.Save ();
if (projection != null) {
- await UpdateProjectionsDocuments (document, data);
+ await UpdateProjectionsDocuments ((Document)document, data);
+ } else if (isAnalyzerConfigFile) {
+ OnAnalyzerConfigDocumentTextChanged (id, new MonoDevelopSourceText (data), PreservationMode.PreserveValue);
} else {
OnDocumentTextChanged (id, new MonoDevelopSourceText (data), PreservationMode.PreserveValue);
}
} else {
var formatter = CodeFormatterService.GetFormatter (data.MimeType);
var documentContext = documentManager.Documents.FirstOrDefault (d => FilePath.PathComparer.Compare (d.FileName, filePath) == 0)?.DocumentContext;
- var root = await projectChanges.NewProject.GetDocument (id).GetSyntaxRootAsync ();
- var annotatedNode = root.DescendantNodesAndSelf ().FirstOrDefault (n => n.HasAnnotation (typeSystemService.InsertionModeAnnotation));
- SyntaxToken? renameTokenOpt = root.GetAnnotatedNodesAndTokens (Microsoft.CodeAnalysis.CodeActions.RenameAnnotation.Kind)
- .Where (s => s.IsToken)
- .Select (s => s.AsToken ())
- .Cast<SyntaxToken?> ()
- .FirstOrDefault ();
+
+ SyntaxNode root = null;
+ SyntaxNode annotatedNode = null;
+ SyntaxToken? renameTokenOpt = null;
+
+ if (!isAnalyzerConfigFile) {
+ root = await projectChanges.NewProject.GetDocument (id).GetSyntaxRootAsync ();
+ annotatedNode = root.DescendantNodesAndSelf ().FirstOrDefault (n => n.HasAnnotation (typeSystemService.InsertionModeAnnotation));
+ renameTokenOpt = root.GetAnnotatedNodesAndTokens (Microsoft.CodeAnalysis.CodeActions.RenameAnnotation.Kind)
+ .Where (s => s.IsToken)
+ .Select (s => s.AsToken ())
+ .Cast<SyntaxToken?> ()
+ .FirstOrDefault ();
+ }
if (documentContext != null) {
var editor = (TextEditor)data;
@@ -936,12 +954,21 @@ namespace MonoDevelop.Ide.TypeSystem }
if (projection != null) {
- await UpdateProjectionsDocuments (document, data);
+ await UpdateProjectionsDocuments ((Document)document, data);
+ } else if (isAnalyzerConfigFile) {
+ OnAnalyzerConfigDocumentTextChanged (id, new MonoDevelopSourceText (data), PreservationMode.PreserveValue);
} else {
OnDocumentTextChanged (id, new MonoDevelopSourceText (data), PreservationMode.PreserveValue);
}
}
}
+
+ protected override void ApplyAnalyzerConfigDocumentTextChanged (DocumentId id, SourceText text)
+ {
+ lock (projectModifyLock)
+ tryApplyState_documentTextChangedTasks.Add (ApplyDocumentTextChangedCore (id, text, isAnalyzerConfigFile: true));
+ } +
internal static Func<TextEditor, int, Task<List<InsertionPoint>>> GetInsertionPoints;
internal static Action<TextEditor, DocumentContext, ITextSourceVersion, SyntaxToken?> StartRenameSession;
@@ -992,6 +1019,7 @@ namespace MonoDevelop.Ide.TypeSystem HashSet<MonoDevelop.Projects.Project> tryApplyState_changedProjects = new HashSet<MonoDevelop.Projects.Project> ();
List<Task> tryApplyState_documentTextChangedTasks = new List<Task> ();
Dictionary<string, SourceText> tryApplyState_documentTextChangedContents = new Dictionary<string, SourceText> ();
+ HashSet<MonoDevelop.Projects.Project> tryApplyState_modifiedProjects = new HashSet<MonoDevelop.Projects.Project> ();
/// <summary>
/// Used by tests to validate that project has been saved.
@@ -1036,17 +1064,36 @@ namespace MonoDevelop.Ide.TypeSystem tryApplyState_documentTextChangedTasks.Clear ();
tryApplyState_changedProjects.Clear ();
freezeProjectModify = false;
+ if (tryApplyState_modifiedProjects.Count > 0)
+ NotifyProjectsModified ();
FileService.ThawEvents ();
}
}
- }
-
+ } + + void NotifyProjectsModified () + { + try { + foreach (var project in tryApplyState_modifiedProjects) { + // New .editorconfig file added so we need to update the project info. + project.NotifyModified ("CoreCompileFiles"); + } + } catch (Exception ex) { + LoggingService.LogError ("tryApplyState_modifiedProjects NotifyModifed error", ex); + } finally { + tryApplyState_modifiedProjects.Clear (); + } + } + public override bool CanApplyChange (ApplyChangesKind feature)
{
switch (feature) {
case ApplyChangesKind.AddDocument:
case ApplyChangesKind.RemoveDocument:
- case ApplyChangesKind.ChangeDocument:
+ case ApplyChangesKind.ChangeDocument: + case ApplyChangesKind.AddAnalyzerConfigDocument: + case ApplyChangesKind.RemoveAnalyzerConfigDocument: + case ApplyChangesKind.ChangeAnalyzerConfigDocument:
//HACK: we don't actually support adding and removing metadata references from project
//however, our MetadataReferenceCache currently depends on (incorrectly) using TryApplyChanges
case ApplyChangesKind.AddMetadataReference:
@@ -1068,24 +1115,88 @@ namespace MonoDevelop.Ide.TypeSystem protected override void ApplyDocumentAdded (DocumentInfo info, SourceText text)
{
- var id = info.Id;
- MonoDevelop.Projects.Project mdProject = null;
+ var mdProject = GetMonoProject (info);
+
+ var path = DetermineFilePath (info, mdProject, true);
+ // If file is already part of project don't re-add it, example of this is .cshtml
+ if (mdProject?.IsFileInProject (path) == true) {
+ this.OnDocumentAdded (info);
+ return;
+ }
+ info = info.WithFilePath (path).WithTextLoader (new MonoDevelopTextLoader (path));
+
+ FormatFile (text, mdProject, path);
+
+ if (mdProject != null) {
+ var data = ProjectMap.GetData (info.Id.ProjectId);
+ data.DocumentData.Add (info.Id, path);
+ var file = new MonoDevelop.Projects.ProjectFile (path);
+ mdProject.Files.Add (file);
+ tryApplyState_changedProjects.Add (mdProject);
+ }
+ this.OnDocumentAdded (info);
+ }
+
+ MonoDevelop.Projects.Project GetMonoProject (DocumentInfo info)
+ {
+ var id = info.Id;
if (id.ProjectId != null) {
var project = CurrentSolution.GetProject (id.ProjectId);
- mdProject = GetMonoProject (project);
+ var mdProject = GetMonoProject (project);
if (mdProject == null)
- LoggingService.LogWarning ("Couldn't find project for newly generated file {0} (Project {1}).", info.Name, info.Id.ProjectId);
+ LoggingService.LogWarning ("Couldn't find project for document {0} (Project {1}).", info.Name, id.ProjectId);
+ return mdProject;
}
+ return null;
+ }
- var path = DetermineFilePath (info.Id, info.Name, info.FilePath, info.Folders, mdProject?.FileName.ParentDirectory, true);
- // If file is already part of project don't re-add it, example of this is .cshtml
- if (mdProject?.IsFileInProject (path) == true) {
- this.OnDocumentAdded (info);
+ protected override void ApplyAnalyzerConfigDocumentAdded (DocumentInfo info, SourceText text)
+ {
+ var mdProject = GetMonoProject (info);
+
+ var path = DetermineFilePath (info, mdProject, true);
+ // If file is already part of project don't re-add it unless it does not exist.
+ if (mdProject?.IsFileInProject (path) == true && File.Exists (path)) {
+ OnAnalyzerConfigDocumentAdded (info);
return;
}
- info = info.WithFilePath (path).WithTextLoader (new MonoDevelopTextLoader (path));
+ info = info.WithFilePath (path).WithTextLoader (new MonoDevelopTextLoader (path)); + + FormatFile (text, mdProject, path);
+ if (mdProject != null) {
+ var data = ProjectMap.GetData (info.Id.ProjectId);
+ data.DocumentData.Add (info.Id, path);
+
+ var file = new MonoDevelop.Projects.ProjectFile (path, MonoDevelop.Projects.BuildAction.None);
+ if (!file.FilePath.IsChildPathOf (mdProject.BaseDirectory)) {
+ // Outside project directory - add it as a solution folder item.
+ var solutionFolder = GetSolutionItemsFolder (mdProject);
+ if (!solutionFolder.Files.Contains (path)) {
+ solutionFolder.Files.Add (path);
+ mdProject.ParentSolution.SaveAsync (new ProgressMonitor ()).Ignore ();
+ }
+ }
+ if (!mdProject.IsFileInProject (file.FilePath)) {
+ mdProject.Files.Add (file);
+ }
+ // Need to trigger Project.Modified event after TryApp is run so project is reloaded by the type system
+ // service. Adding the file to the Files collection will not trigger the modified event since
+ // the build action is not EditorConfigFiles. Also this event would be ignored anyway during TryApply.
+ // Also handles if the link already existed. Need to refresh all projects since the document added
+ // method will only be called once.
+ foreach (var affectedProject in mdProject.ParentSolution.GetAllProjects ()) {
+ tryApplyState_modifiedProjects.Add (affectedProject);
+ }
+ tryApplyState_changedProjects.Add (mdProject);
+ }
+
+ OnAnalyzerConfigDocumentAdded (info);
+ }
+
+ void FormatFile (SourceText text, MonoDevelop.Projects.Project mdProject, string path)
+ {
string formattedText;
var formatter = CodeFormatterService.GetFormatter (desktopService.GetMimeTypeForUri (path));
if (formatter != null && mdProject != null) {
@@ -1100,16 +1211,22 @@ namespace MonoDevelop.Ide.TypeSystem } catch (Exception e) {
LoggingService.LogError ("Exception while saving file to " + path, e);
}
+ }
- if (mdProject != null) {
- var data = ProjectMap.GetData (id.ProjectId);
- data.DocumentData.Add (info.Id, path);
- var file = new MonoDevelop.Projects.ProjectFile (path);
- mdProject.Files.Add (file);
- tryApplyState_changedProjects.Add (mdProject);
+ MonoDevelop.Projects.SolutionFolder GetSolutionItemsFolder (MonoDevelop.Projects.Project project)
+ {
+ string name = GettextCatalog.GetString ("Solution Items");
+ var folder = project.ParentSolution.RootFolder.Items
+ .OfType <MonoDevelop.Projects.SolutionFolder> ()
+ .FirstOrDefault (item => StringComparer.CurrentCultureIgnoreCase.Equals (item.Name, name));
+ if (folder != null) {
+ return folder;
}
- this.OnDocumentAdded (info);
+ folder = new MonoDevelop.Projects.SolutionFolder ();
+ folder.Name = name;
+ project.ParentSolution.RootFolder.Items.Add (folder);
+ return folder;
}
protected override void ApplyDocumentRemoved (DocumentId documentId)
@@ -1139,16 +1256,23 @@ namespace MonoDevelop.Ide.TypeSystem tryApplyState_changedProjects.Add (mdProject);
}
- string DetermineFilePath (DocumentId id, string name, string filePath, IReadOnlyList<string> docFolders, string defaultFolder, bool createDirectory = false)
+ protected override void ApplyAnalyzerConfigDocumentRemoved (DocumentId documentId)
+ {
+ LoggingService.LogInfo ("ApplyAnalyzerConfigDocumentRemoved {0}", documentId);
+ base.ApplyAnalyzerConfigDocumentRemoved (documentId);
+ }
+
+ string DetermineFilePath (DocumentInfo info, MonoDevelop.Projects.Project mdProject, bool createDirectory = false)
{
- var path = filePath;
+ var path = info.FilePath;
if (string.IsNullOrEmpty (path)) {
- var monoProject = GetMonoProject (id.ProjectId);
+ var monoProject = GetMonoProject (info.Id.ProjectId);
// If the first namespace name matches the name of the project, then we don't want to
// generate a folder for that. The project is implicitly a folder with that name.
IEnumerable<string> folders;
+ var docFolders = info.Folders;
if (docFolders != null && monoProject != null && docFolders.FirstOrDefault () == monoProject.Name) {
folders = docFolders.Skip (1);
} else {
@@ -1163,9 +1287,9 @@ namespace MonoDevelop.Ide.TypeSystem } catch (Exception e) {
LoggingService.LogError ("Error while creating directory for a new file : " + baseDirectory, e);
}
- path = Path.Combine (baseDirectory, name);
+ path = Path.Combine (baseDirectory, info.Name);
} else {
- path = Path.Combine (defaultFolder, name);
+ path = Path.Combine (mdProject?.FileName.ParentDirectory, info.Name);
}
}
return path;
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/TypeSystemService.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/TypeSystemService.cs index 334d8b88cc..6a7abb20e1 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/TypeSystemService.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/TypeSystemService.cs @@ -116,6 +116,7 @@ namespace MonoDevelop.Ide.TypeSystem } FileService.FileChanged += FileService_FileChanged; + FileService.FileRemoved += FileService_FileRemoved; desktopService = await serviceProvider.GetService<DesktopService> (); @@ -125,6 +126,7 @@ namespace MonoDevelop.Ide.TypeSystem protected override Task OnDispose () { FileService.FileChanged -= FileService_FileChanged; + FileService.FileRemoved -= FileService_FileRemoved; if (rootWorkspace != null) rootWorkspace.ActiveConfigurationChanged -= HandleActiveConfigurationChanged; FinalizeTrackedProjectHandling (); @@ -173,6 +175,48 @@ namespace MonoDevelop.Ide.TypeSystem }); } + void FileService_FileRemoved (object sender, FileEventArgs e) + { + try { + foreach (var file in e) { + if (file.FileName.FileName == ".editorconfig") { + OnEditorConfigDocumentRemoved (file.FileName); + } + } + } catch (Exception ex) { + LoggingService.LogError ("TypeSystemService.FileService_FileRemoved error", ex); + } + } + + void OnEditorConfigDocumentRemoved (FilePath fileName) + { + foreach (var workspace in AllWorkspaces) { + var mdWorkspace = workspace as MonoDevelopWorkspace; + if (mdWorkspace == null) + continue; + + var projects = new HashSet<Project> (); + foreach (var mdProject in mdWorkspace.MonoDevelopSolution.GetAllProjects ()) { + foreach (var projectId in mdWorkspace.GetProjectIds (mdProject)) { + var docId = mdWorkspace.GetDocumentId (projectId, fileName); + if (docId != null) { + projects.Add (mdProject); + try { + mdWorkspace.OnAnalyzerConfigDocumentRemoved (docId); + } catch (Exception ex) { + // Ignore error so other projects can be updated. + LoggingService.LogError ("OnAnalyzerConfigDocumentRemoved error", ex); + } + } + } + } + + foreach (var mdProject in projects) { + mdProject.NotifyModified ("CoreCompileFiles"); + } + } + } + internal async Task<MonoDevelopWorkspace> CreateEmptyWorkspace () { var ws = new MonoDevelopWorkspace (compositionManager.HostServices, null, this); diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ProjectOperations.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ProjectOperations.cs index 190e9db83b..4b49c09c4d 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ProjectOperations.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ProjectOperations.cs @@ -426,6 +426,7 @@ namespace MonoDevelop.Ide try { await entry.SaveAsync (monitor); monitor.ReportSuccess (GettextCatalog.GetString ("Project saved.")); + } catch (OperationCanceledException) { } catch (Exception ex) { monitor.ReportError (GettextCatalog.GetString ("Save failed."), ex); } finally { |