[svn] r7555: vs-plugin/trunk: Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/Project.Refactoring.n N...

kliss svnadmin at nemerle.org
Wed Mar 28 13:07:23 CEST 2007


Log:
Done: ReSharper-like symbol highlighting. 
See Tools->Options->Keyboard for commands Nemerle.HighlightSymbol, Nemerle.RemoveLastHighlighting

Author: kliss
Date: Wed Mar 28 13:07:20 2007
New Revision: 7555

Modified:
   vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/Project.Refactoring.n
   vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/ScanLexer.n
   vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleLanguageService.cs
   vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleViewFilter.cs
   vs-plugin/trunk/Nemerle.VsIntegration/Nemerle.VisualStudio.csproj
   vs-plugin/trunk/Nemerle.VsIntegration/Project/ProjectInfo.cs

Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/Project.Refactoring.n
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/Project.Refactoring.n	(original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/Project.Refactoring.n	Wed Mar 28 13:07:20 2007
@@ -45,9 +45,25 @@
       }
     }
 
-    public HighlightUsages([NotNull] lexer : ScanLexer, [NotNull] filePath : string, line : int, col : int) : void
+	public HighlightUsages([NotNull] lexer : ScanLexer, 
+                           [NotNull] filePath : string, 
+                           line : int, 
+                           col : int,
+                           isPermanent : bool) : void
+    {
+		HighlightUsages(lexer, 
+						_compileUnits.GetFileIndex(filePath),
+						line, 
+						col, 
+						isPermanent);
+	}
+
+    public HighlightUsages([NotNull] lexer : ScanLexer, 
+                           [NotNull] fileIndex : int, 
+                           line : int, 
+                           col : int,
+                           isPermanent : bool) : void
     {
-      def fileIndex = _compileUnits.GetFileIndex(filePath);
       def decl      = GetActiveDecl(fileIndex, line, col);
       
       match (decl)
@@ -61,11 +77,19 @@
             | _ => (goto.Location, 1)
           }
         });
+        if(isPermanent)
+          lexer.AddHighlighting(highlights);
+        else
         lexer.SetHoverHighlights(highlights);
       | _          => ()
       }
     }
 
+    public RemoveLastHighlighting([NotNull] lexer : ScanLexer) : void
+    {
+      lexer.RemoveLastHighlighting();
+    }
+
     private GetDefinitionInsideType(typeDecl : Decl.Type, fileIndex : int, line : int, column : int) : list [GotoInfo]
     {
       def (_, parsedObject, tObj) = FindObject(typeDecl, fileIndex, line, column);

Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/ScanLexer.n
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/ScanLexer.n	(original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/ScanLexer.n	Wed Mar 28 13:07:20 2007
@@ -779,16 +779,17 @@
           location.Column <= tokenLocation.Column &&
           location.EndColumn >= tokenLocation.EndColumn
       }
-      def highlightColor =
-        match (hoverHighlightedLocations.Get(line))
+      // TODO: Refactor hoverHighlightedLocations usage to a method call
+      // that will also know about permanent highlight stack
+      def highlightColor = match (GetHighlightsForLine(line))
         {
-        | Some(highlights) =>
+        | x :: xs as highlights => // if this is a list
           match (highlights.Find(isInside))
           {
           | Some((_, colorNumber)) => colorNumber
           | None() => -1
           }
-        | None() => -1
+        | _ => -1
         };
       match (highlightColor)
       {
@@ -800,10 +801,37 @@
     }
 
     mutable hoverHighlightedLocations : Hashtable[int, list[Location * int]] = Hashtable();
+    mutable permanentHighlights : list[Hashtable[int, list[Location * int]]] = [];
+    
+    GetHighlightsForLine(line : int) : list[Location * int]
+    {
+      /* kliss: This method may be not very efficient, just tell me 
+        what is the most efficient way to merge several lists. */
+      def mergeWithResult(result, newValue)
+      {
+        match(newValue)
+        {
+        | Some(val) => result.Append(val);
+        | None => result;
+        }
+      }
+      // Getting hovered highlights
+      mutable result = mergeWithResult([], hoverHighlightedLocations.Get(line));
     
-    AddHighlightsOnTheLine(lineNumber : int, highlights : list[Location * int]) : void
+      // Getting permanent highlights
+      foreach(stackedHighlight in permanentHighlights)
     {
-      hoverHighlightedLocations[lineNumber] = highlights;
+        result = mergeWithResult(result, stackedHighlight.Get(line));
+      }
+      
+      result;
+    }
+    
+    AddHighlightsOnTheLine(table : Hashtable[int, list[Location * int]], 
+                           lineNumber : int, 
+                           highlights : list[Location * int]) : void
+    {
+      table[lineNumber] = highlights;
     }
     
     public SetHoverHighlights(highlights : list[Location * int]) : void
@@ -824,8 +852,37 @@
       {
         //def (first, _) = highlights.Head;
         //base.file_idx = first.FileIndex;  // HACK: otherwise it == 0
-        foreach (group in groups)
-          AddHighlightsOnTheLine(group);
+        foreach ((line, lineHighlihgts) in groups)
+          AddHighlightsOnTheLine(hoverHighlightedLocations, line, lineHighlihgts);
+      }
+    }
+    
+    public AddHighlighting(highlights : list[Location * int]) : void
+    {
+      def groups = highlights.Group(
+                (one : Location * int, two : Location * int) => {
+                                                                  def (locationOne, _) = one;
+                                                                  def (locationTwo, _) = two;
+                                                                  locationOne.Line - locationTwo.Line
+                                                                }
+                ).Map(locationsOnTheLine => 
+                        (locationsOnTheLine.Head[0].Line, locationsOnTheLine.Map(
+                                                (l, color) => (Location(0, l.Line, l.Column, l.EndLine, l.EndColumn), color))));
+      unless (groups.IsEmpty)
+      {
+        def newHighlight = Hashtable();
+        foreach ((line, lineHighlihgts) in groups)
+          AddHighlightsOnTheLine(newHighlight, line, lineHighlihgts);
+        permanentHighlights ::= newHighlight;
+      }
+    }
+    
+    public RemoveLastHighlighting() : void
+    {
+      match(permanentHighlights)
+      {
+      | x :: xs => permanentHighlights = xs;
+      | _ => ()
       }
     }
     

Modified: vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleLanguageService.cs
==============================================================================
--- vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleLanguageService.cs	(original)
+++ vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleLanguageService.cs	Wed Mar 28 13:07:20 2007
@@ -432,8 +432,24 @@
 
 			if (Settings.Default.HighlightUsages)
 				if (!Settings.Default.HighlightUsagesUnlessTerminalSession || !NowIsTerminalSession())
-					projectInfo.HighlightUsages(request.FileName, request.Line, request.Col,
-						new SourceTextManager(projectInfo.GetSource(request.FileName)));
+					projectInfo.HighlightUsages(request.FileName,
+					                            request.Line,
+					                            request.Col,
+					                            new SourceTextManager(projectInfo.GetSource(request.FileName)),
+												false);
+		}
+
+		// TODO: Find out how to call this method on Escape.
+		private void RemoveLastHighlighting(ParseRequest request)
+		{
+			ProjectInfo projectInfo = GetProjectInfo(request);
+
+			if (projectInfo == null)
+				return;
+
+			if (Settings.Default.HighlightUsages)
+				if (!Settings.Default.HighlightUsagesUnlessTerminalSession || !NowIsTerminalSession())
+					projectInfo.RemoveLastHighlighting(new SourceTextManager(projectInfo.GetSource(request.FileName)));
 		}
 
 		private AuthoringScope GetMethodScope(ParseRequest request)

Modified: vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleViewFilter.cs
==============================================================================
--- vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleViewFilter.cs	(original)
+++ vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleViewFilter.cs	Wed Mar 28 13:07:20 2007
@@ -82,8 +82,12 @@
 						source.ProjectInfo.ProjectNode.Package.OnAstToolWindowShow(null, null);
 
 					break;
-                case 0x3107: txt = "cmdIdAddHighlighting"; break;
-                case 0x3108: txt = "cmdIdRemoveLastHighlighting"; break;
+                case 0x3107: // Highlight symbol
+					HighlightSymbol();
+					break;
+                case 0x3108: // Remove last highlighting
+					RemoveLastHighlighting();
+					break;
             }
 
 			if (txt != null)
@@ -132,6 +136,28 @@
 				CurrentSelection++;
 		}
 
+		private void HighlightSymbol()
+		{
+			NemerleSource source = Source as NemerleSource;
+			if (source != null)
+			{
+				TextSpan span = GetSelection();
+				source.ProjectInfo.HighlightUsages(source.FileIndex,
+				                                   span.iStartLine,
+				                                   span.iStartIndex,
+				                                   new SourceTextManager(source),
+				                                   true);
+			}
+		}
+		private void RemoveLastHighlighting()
+		{
+			NemerleSource source = Source as NemerleSource;
+			if (source != null)
+			{
+				source.ProjectInfo.RemoveLastHighlighting(new SourceTextManager(source));
+			}
+		}
+
 		private bool SelectionIsInStack(TextSpan selection)
 		{
 			// perhaps, using OnSelectChange routine would be better

Modified: vs-plugin/trunk/Nemerle.VsIntegration/Nemerle.VisualStudio.csproj
==============================================================================
--- vs-plugin/trunk/Nemerle.VsIntegration/Nemerle.VisualStudio.csproj	(original)
+++ vs-plugin/trunk/Nemerle.VsIntegration/Nemerle.VisualStudio.csproj	Wed Mar 28 13:07:20 2007
@@ -290,6 +290,7 @@
     <Compile Include="RegistrationAttributes\SingleFileGeneratorSupportRegistrationAttribute.cs" />
     <None Include="app.config" />
     <Compile Include="Project\NemerleIdeBuildLogger.cs" />
+    <Compile Include="StringOrInt.cs" />
     <None Include="Properties\Settings.settings">
       <Generator>SettingsSingleFileGenerator</Generator>
       <LastGenOutput>Settings.Designer.cs</LastGenOutput>

Modified: vs-plugin/trunk/Nemerle.VsIntegration/Project/ProjectInfo.cs
==============================================================================
--- vs-plugin/trunk/Nemerle.VsIntegration/Project/ProjectInfo.cs	(original)
+++ vs-plugin/trunk/Nemerle.VsIntegration/Project/ProjectInfo.cs	Wed Mar 28 13:07:20 2007
@@ -463,19 +463,38 @@
 			return result;
 		}
 
-		internal void HighlightUsages(string filePath, int line, int column, ISource source)
+		internal void HighlightUsages(StringOrInt filePathOrIndex, int line, int column, ISource source, bool isPermanent)
 		{
 			Trace.WriteLine(">>>> ##### HighlightUsages!");
-			ErrorHelper.ThrowIfPathNullOrEmpty(filePath, "filePath");
+			if(filePathOrIndex.IsString)
+				ErrorHelper.ThrowIfPathNullOrEmpty(filePathOrIndex.StringValue, "filePath");
 			SourceTextManager manager = source as SourceTextManager;
 			if (manager == null)
 				return;
 			ScanLexer lexer = manager.Source.Scanner.GetLexer();
 			if (lexer == null)
 				return;
-			Project.HighlightUsages(lexer, filePath, line + 1, column + 1);
+			if(filePathOrIndex.IsString)
+				Project.HighlightUsages(lexer, filePathOrIndex.StringValue, line + 1, column + 1, isPermanent);
+			else
+				Project.HighlightUsages(lexer, filePathOrIndex.IntValue, line + 1, column + 1, isPermanent);
 			manager.Source.Recolorize(1, source.LineCount);
 			Trace.WriteLine("<<<< ##### HighlightUsages!");
 		}
+
+		internal void RemoveLastHighlighting(ISource source)
+		{
+			Trace.WriteLine(">>>> ##### RemoveLastHighlighting!");
+			SourceTextManager manager = source as SourceTextManager;
+			if (manager == null)
+				return;
+			ScanLexer lexer = manager.Source.Scanner.GetLexer();
+			if (lexer == null)
+				return;
+			lexer.RemoveLastHighlighting();
+			manager.Source.Recolorize(1, source.LineCount);
+			Trace.WriteLine("<<<< ##### HighlightUsages!");
+		}
+
 	}
 }



More information about the svn mailing list