[svn] r7795: vs-plugin/trunk:
Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/CodeFormattingStag...
kliss
svnadmin at nemerle.org
Tue Sep 11 02:10:43 CEST 2007
Log:
Work on formatter.
Highlight paired braces whenever possible (from inner/outer side, when navigating with mouse, when navigating from upper/lower line with arrow keys)
Automatically insert/remove paired tokens (round, square, curly braces, and single/double quotes)
Fix some typos.
Author: kliss
Date: Tue Sep 11 02:09:46 2007
New Revision: 7795
Modified:
vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/CodeFormattingStageBase.n
vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/CodeIndentationStage.n
vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/CodeLineBreakingStage.n
vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/Formatter.n
vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/FormatterResult.n
vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/NonEatingLexer.n
vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/ExprFinder.n
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/NemerleAuthoringScope.cs
vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleLanguageService.cs
vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleSource.cs
vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleTypeAndMemberDropdownBars .cs
vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleViewFilter.cs
vs-plugin/trunk/Nemerle.VsIntegration/Project/NemerleFileDocumentManager.cs
vs-plugin/trunk/Nemerle.VsIntegration/Project/NemerleIdeBuildLogger.cs
Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/CodeFormattingStageBase.n
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/CodeFormattingStageBase.n (original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/CodeFormattingStageBase.n Tue Sep 11 02:09:46 2007
@@ -90,8 +90,14 @@
protected _tokenFinder : TokenStreamHandler = TokenStreamHandler();
private results : SCG.List.[FormatterResult] = SCG.List.[FormatterResult]();
+
protected AddResult(result : FormatterResult) : void
{
+ // Ensure no conflicts
+ foreach(existingResult in results)
+ when(result.IntersectsWith(existingResult))
+ throw FormatterException($"Change $result conflicts with existing change $existingResult");
+
results.Add(result);
}
protected GetResults() : SCG.List.[FormatterResult]
Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/CodeIndentationStage.n
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/CodeIndentationStage.n (original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/CodeIndentationStage.n Tue Sep 11 02:09:46 2007
@@ -110,7 +110,7 @@
foreach(fr in results)
{
- when(fr.StartCol < col && fr.EndCol < col && fr.StartLine == fr.EndLine)
+ when(fr.StartCol < col && fr.EndCol <= col && fr.StartLine == fr.EndLine)
{
newCol += (fr.ReplacementString.Length - (fr.EndCol - fr.StartCol));
}
@@ -127,7 +127,7 @@
indentValue = " "; // TODO: make it configurable by user.
defaultIndentSize = 2;
- matchCasesIndentOffset = 2; // match cases will be indented by matchCasesIndentOffset * defaultIndentSize
+ matchCasesIndentOffset = 1; // match cases will be indented by matchCasesIndentOffset * defaultIndentSize
matchCasesBodyIndentOffset = 2;
variantOptionIndentOffset = 2;
@@ -174,7 +174,8 @@
using(GetIndentPusher(PeekIndent() + matchCasesBodyIndentOffset * defaultIndentSize))
{
- cases.Map(_.body).Iter(FormatPExpr);
+ FormatPExpr(matchCase.body);
+ //cases.Map(_.body).Iter(FormatPExpr);
}
}
@@ -259,7 +260,7 @@
def beginBrace = _tokenFinder.FindAt(seq.Location.Line, seq.Location.Column);
assert(beginBrace is Token.BeginBrace);
- using(GetIndentPusher(RecalcLocation(firstKeywordLoc.UnSome()).Column))
+ using(GetIndentPusher(Math.Max(PeekIndent(), RecalcLocation(firstKeywordLoc.UnSome()).Column)))
{
IndentLocation(beginBrace.Location);
using(GetIndentPusher())
@@ -270,7 +271,7 @@
}
| _ =>
- using(GetIndentPusher(RecalcLocation(firstKeywordLoc.UnSome()).Column + defaultIndentSize))
+ using(GetIndentPusher(Math.Max(PeekIndent(), RecalcLocation(firstKeywordLoc.UnSome()).Column + defaultIndentSize)))
{
FormatPExpr(pexpr);
}
@@ -287,12 +288,16 @@
| Token.Keyword as a when a.name == k => true
| _ => false;
});
+ mutable preferredColumn = 0;
match(firstKeywordLoc)
{
- | None => firstKeywordLoc = Some(kw.Location);
- | _ => ()
+ | None =>
+ firstKeywordLoc = Some(kw.Location);
+ preferredColumn = PeekIndent();
+ | _ => preferredColumn = Math.Max(PeekIndent(), RecalcLocation(firstKeywordLoc.UnSome()).Column);
+
}
- using(GetIndentPusher(RecalcLocation(firstKeywordLoc.UnSome()).Column))
+ using(GetIndentPusher(preferredColumn))
{
IndentLocation(kw.Location);
}
@@ -597,7 +602,8 @@
FormatField(fb : FieldBuilder) : void
{
- Debug.Assert(fb.Location.Line == fb.Location.EndLine, $"Declaration of field $(fb.Name) spans over several lines. Can't indent.");
+ //Debug.Assert(fb.Location.Line == fb.Location.EndLine, $"Declaration of field $(fb.Name) spans over several lines. Can't indent.");
+ when(fb.Location.Line == fb.Location.EndLine)
IndentLocation(fb.Location);
}
@@ -670,7 +676,7 @@
PushIndent();
- foreach(member in tb.GetDirectMembers())
+ foreach(member in tb.GetDirectMembers().Filter(mmbr => mmbr.Location.FileIndex == _fileIndex))
FormatTypeBuilderMember(member);
_ = PopIndent();
@@ -736,7 +742,7 @@
public override FormatRegion(startLine : int, startCol : int, endLine : int, endCol : int) : SCG.List.[FormatterResult]
{
_ = base.FormatRegion(startLine, startCol, endLine, endCol);
-// The call above sets "clipping" region, and FromatDocument will respect
+ // The call above sets "clipping" region, and FormatDocument will respect
// this and will not make any changes that are not inside of that region.
FormatDocument();
}
Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/CodeLineBreakingStage.n
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/CodeLineBreakingStage.n (original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/CodeLineBreakingStage.n Tue Sep 11 02:09:46 2007
@@ -126,7 +126,7 @@
def matchFinder = MatchingBrackerFinder().GetSearchFunc(typeof(Token.EndBrace));
def endBrace = _tokenFinder.FindNextIf(beginBrace.Location.Line, beginBrace.Location.EndColumn, matchFinder);
- AddResult(FormatterResult.Insert(endBrace.Location.Line, endBrace.Location.Column, "/*endBrace*/"));
+ //AddResult(FormatterResult.Insert(endBrace.Location.Line, endBrace.Location.Column, "/*endBrace*/"));
FormatBrace(endBrace);
SetExpectedLine(endBrace.Location.EndLine + 1);
Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/Formatter.n
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/Formatter.n (original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/Formatter.n Tue Sep 11 02:09:46 2007
@@ -12,6 +12,11 @@
namespace Nemerle.Completion2.CodeFormatting
{
+ /*
+ TODO: formatting stuff
+ format expression on semicolon
+ format block on closing curly brace
+ */
public class Formatter
{
mutable _fileIndex : int = 0;
@@ -30,7 +35,13 @@
Engine = engine;
_fileIndex = fileIndex;
_results = SCG.List.[FormatterResult]();
+ }
+ public this(engine : Engine, filePath : string)
+ {
+ Engine = engine;
+ _fileIndex = engine.Project.CompileUnits.GetFileIndex(filePath);
+ _results = SCG.List.[FormatterResult]();
}
@@ -106,8 +117,6 @@
CodeIndentationStage(engine, fileIndex)
];
- // TODO: After each stage send result to the VS,
- // and wait for changes to be applied.
foreach(stage in stages)
{
results.AddRange(stage.FormatDocument());
@@ -117,7 +126,6 @@
}
- // Here we have to find out what piece of AST to analyze
public static FormatSpan( startLine : int, startCol : int, endLine : int,
endCol : int, engine : Engine, filePath : string) : SCG.List[FormatterResult]
{
@@ -126,19 +134,26 @@
def stages : list[IFormattingStage] =
[
- //CodeLineBreakingStage(engine, fileIndex)
+ //CodeLineBreakingStage(engine, fileIndex),
CodeIndentationStage(engine, fileIndex)
];
- // TODO: After each stage send result to the VS,
- // and wait for changes to be applied.
foreach(stage in stages)
- {
-
results.AddRange(stage.FormatRegion(startLine, startCol, endLine, endCol));
- }
results;
}
+
+ public static FormatExpressionAt(engine : Engine, filepath : string, line : int, col : int) : SCG.List[FormatterResult]
+ {
+ def results = SCG.List();
+ def rootDecl = engine.Project.CompileUnits[filepath];
+ def (loc, foundExpr) = ExprFinder().Find(rootDecl, line, col, 1);
+ //results.Add(FormatterResult.Insert(line, col, foundExpr.ToString()));
+ when(foundExpr != null && !loc.IsEmpty)
+ results.AddRange(FormatSpan(loc.Line, loc.Column, loc.EndLine, loc.EndColumn, engine, filepath));
+ results
+ }
+
}
}
Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/FormatterResult.n
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/FormatterResult.n (original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/FormatterResult.n Tue Sep 11 02:09:46 2007
@@ -29,6 +29,12 @@
}
}
+ public IntersectsWith(other : FormatterResult) : bool
+ {
+ def thisLoc = Location(0, StartLine, StartCol, EndLine, EndCol);
+ thisLoc.Contains(other.StartLine, other.StartCol) || thisLoc.Contains(other.EndLine, other.EndCol);
+ }
+
public static Replace(loc : Location, replacement : string) : FormatterResult
{
FormatterResult(loc.Line, loc.Column, loc.EndLine, loc.EndColumn, replacement);
Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/NonEatingLexer.n
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/NonEatingLexer.n (original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/NonEatingLexer.n Tue Sep 11 02:09:46 2007
@@ -164,9 +164,9 @@
get_number (ch)
else
if (IsIdBeginning (ch))
- get_id (ch)
+ get_id (ch) // '
else
- throw Error ($"invalid character: `$ch'")
+ throw Error ($"invalid character: '$ch'")
}
}
Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/ExprFinder.n
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/ExprFinder.n (original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/ExprFinder.n Tue Sep 11 02:09:46 2007
@@ -81,7 +81,7 @@
{
def texpr = GetTypedObject(obj);
- when (texpr != null)
+ if (texpr != null)
{
when (_pexprObject == null || _location.Contains(loc))
{
@@ -97,13 +97,23 @@
{
| PExpr.Wildcard => info.Stop();
| PExpr.MacroCall(name, _, _) when IsIn(name.Location) =>
-
_location = name.Location;
info.Stop();
| _ => ()
}
}
+ // Making it possible to find empty Sequence.
+ else match(obj)
+ {
+ | PExpr.Sequence([]) =>
+ _parentObject = _pexprObject;
+ _location = loc;
+ _pexprObject = info.Node;
+ _texprObject = texpr;
+ info.Stop();
+ | _ => ()
+ }
}
else if (_line < loc.Line || _line == loc.Line && _col < loc.Column)
info.Stop()
@@ -155,23 +165,63 @@
}
}
- //// This method accepts Decl as a starting point.
- //public Find(pRoot : Decl, line : int, col : int) : Location * object
- //{
- // if(pRoot == null)
- // (Location.Default, null);
- // else
- // {
- // Init(line, col);
- // ExprWalker().Walk(pRoot, PFinder);
- // if(_pexprObject != null)
- // (_location, _pexprObject)
- // else if(_decl != null)
- // (_location, _decl);
- // else
- // (Location.Default, null);
- // }
- //}
+ // This method accepts Decl as a starting point.
+ public _Find(pRoot : Decl, line : int, col : int) : Location * object
+ {
+ if(pRoot == null)
+ (Location.Default, null);
+ else
+ {
+ Init(line, col);
+ ExprDeclWalker(this).Walk(pRoot, PFinder);
+ if(_pexprObject != null)
+ (_location, _pexprObject)
+ else if(_decl != null)
+ (_location, _decl);
+ else
+ (Location.Default, null);
+ }
+ }
+
+ // This method accepts Decl as a starting point.
+ public Find(pRoot : Decl, line : int, col : int, nthParentElement : int) : Location * object
+ {
+ def getLocation(obj : object)
+ {
+ if(obj is Located)
+ (obj :> Located).Location
+ else if(obj is IMember)
+ (obj :> IMember).Location
+ else if(obj is Decl)
+ (obj :> Decl).Location
+ else
+ Location.Default;
+ }
+
+ if(pRoot == null)
+ (Location.Default, null);
+ else
+ {
+ Init(line, col);
+ ExprDeclWalker(this).Walk(pRoot, PFinder);
+ if(_walkedNodes.Length < nthParentElement)
+ (Location.Default, null)
+ else
+ {
+ if(_pexprObject != null)
+ {
+ match(_walkedNodes.Nth(nthParentElement))
+ {
+ | obj when getLocation(obj) != Location.Default => (getLocation(obj), obj)
+ | _ => (Location.Default, null)
+ }
+ }
+ else
+ (Location.Default, null)
+ }
+
+ }
+ }
public Find(pRoot : PExpr, _tRoot : TExpr, line : int, col : int) : Location * object * object
{
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 Tue Sep 11 02:09:46 2007
@@ -284,7 +284,7 @@
{
Debug.WriteLine($"checking usage $usage for consistency");
Debug.WriteLine($"must be member:\n $mustBeMember");
- // phantom: strange, why it doesn't catch exeption on christianity.n, any interface member?
+ // phantom: strange, why it doesn't catch exception on christianity.n, any interface member?
try
{
match (GetActiveDecl(usage.FileIndex, usage.Line, usage.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 Tue Sep 11 02:09:46 2007
@@ -641,6 +641,7 @@
{
def tmp = _pendingToken;
_pendingToken = null;
+
tmp;
}
else
@@ -873,6 +874,7 @@
{
def chooseColor(str, regexList)
{
+
match(regexList)
{
| (color, regex) :: xs =>
@@ -957,6 +959,7 @@
{
def mergeWithResult(result, newValue)
{
+
match(newValue)
{
| x :: xs => result.Add(x); mergeWithResult(result, xs);
@@ -1049,6 +1052,7 @@
_debug(obj : object) : void
{
+
when (obj != null)
_ = obj.ToString();
}
Modified: vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleAuthoringScope.cs
==============================================================================
--- vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleAuthoringScope.cs (original)
+++ vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleAuthoringScope.cs Tue Sep 11 02:09:46 2007
@@ -407,7 +407,7 @@
return infos.ToArray();
}
- // TODO: implement other languages then nemerle
+ // TODO: implement other languages than Nemerle
if (_findExactLocation && Path.GetExtension(infos[0].FilePath) == ".n")
{
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 Tue Sep 11 02:09:46 2007
@@ -595,19 +595,6 @@
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)));
- }
-
#endregion
#region GetCompleteWord
@@ -1011,6 +998,10 @@
_preferences.Init();
_preferences.EnableFormatSelection = true;
+ // TODO: Find out how to enable "Smart" radio option in
+ // Tools->Options->Text editor->Nemerle->Tabs
+ _preferences.IndentStyle = IndentingStyle.Smart;
+
#if DEBUG
//VladD2: Switch on synchronous mode for debugging purpose!
//TODO: Comment it if necessary.
Modified: vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleSource.cs
==============================================================================
--- vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleSource.cs (original)
+++ vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleSource.cs Tue Sep 11 02:09:46 2007
@@ -1,7 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
-
+using System.Windows.Forms;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Package;
using Microsoft.VisualStudio.TextManager.Interop;
@@ -177,7 +177,7 @@
//ReformatSpan_internal(mgr, span, engine, filePath);
//base.ReformatSpan(mgr, span);
}
- private void ReformatSpan_internal(EditArray _mgr, TextSpan span, Engine engine, string filePath)
+ private static void ReformatSpan_internal(EditArray _mgr, TextSpan span, Engine engine, string filePath)
{
List<FormatterResult> results =
Formatter.FormatSpan(span.iStartLine + 1,
@@ -211,6 +211,72 @@
return _methodData = base.CreateMethodData();
}
+ #region Paired chars insertion and deletion
+
+ // TODO: maybe refactor this part so that it will share code with BracketFinder
+ private readonly char[][] _pairedChars = new char[][]
+ {
+ new char[] {'{', '}'},
+ new char[] {'(', ')'},
+ new char[] {'\'', '\''},
+ new char[] {'[', ']'},
+ new char[] {'"', '"'}
+ };
+
+ private bool IsOpeningPairedChar(char ch)
+ {
+ foreach (char[] charPair in _pairedChars)
+ {
+ if(charPair[0] == ch)
+ return true;
+ }
+ return false;
+ }
+
+ private bool IsClosingPairedChar(char ch)
+ {
+ foreach (char[] charPair in _pairedChars)
+ {
+ if(charPair[1] == ch)
+ return true;
+ }
+ return false;
+ }
+
+ private char GetClosingChar(char ch)
+ {
+ foreach (char[] charPair in _pairedChars)
+ {
+ if(charPair[0] == ch)
+ return charPair[1];
+ }
+ throw new ApplicationException("Paired char not found for '" + ch + "'");
+ }
+
+ private char _rememberedChar;
+
+ public void RememberCharBeforeCaret(IVsTextView textView)
+ {
+ int line;
+ int idx;
+ textView.GetCaretPos(out line, out idx);
+ if(idx > 0)
+ _rememberedChar = GetText(line, idx - 1, line, idx)[0];
+ }
+
+ public void ClearRememberedChar()
+ {
+ _rememberedChar = (char) 0;
+ }
+
+
+ #endregion
+
+ private void RemoveCharAt(int line, int idx)
+ {
+ SetText(line, idx, line, idx + 1, "");
+ }
+
public override void OnCommand(IVsTextView textView, VsCommands2K command, char ch)
{
if (textView == null || _service == null || !_service.Preferences.EnableCodeSense)
@@ -220,34 +286,88 @@
command == VsCommands2K.LEFT || command == VsCommands2K.LEFT_EXT);
int line, idx;
-
textView.GetCaretPos(out line, out idx);
- TokenInfo info = GetTokenInfo(line, idx);
- TokenTriggers triggerClass = info.Trigger;
+ TokenInfo tokenBeforeCaret = GetTokenInfo(line, idx);
+ TokenInfo tokenAfterCaret = GetTokenInfo(line, idx + 1);
- if ((triggerClass & TokenTriggers.MemberSelect) != 0 && (command == VsCommands2K.TYPECHAR))
+ HandlePairedSymbols(textView, command, line, idx, ch);
+
+ if ((tokenBeforeCaret.Trigger & TokenTriggers.MemberSelect) != 0 && (command == VsCommands2K.TYPECHAR))
{
- ParseReason reason = ((triggerClass & TokenTriggers.MatchBraces) == TokenTriggers.MatchBraces) ?
+ ParseReason reason = ((tokenBeforeCaret.Trigger & TokenTriggers.MatchBraces) == TokenTriggers.MatchBraces) ?
ParseReason.MemberSelectAndHighlightBraces :
ParseReason.MemberSelect;
- this.Completion(textView, info, reason);
+ Completion(textView, tokenBeforeCaret, reason);
+ }
+ TryHighlightBraces(textView, command, line, idx, tokenBeforeCaret, tokenAfterCaret);
+
+ if (!_methodData.IsDisplayed &&
+ (tokenBeforeCaret.Trigger & TokenTriggers.MethodTip) != 0 &&
+ command == VsCommands2K.TYPECHAR &&
+ _service.Preferences.ParameterInformation)
+ {
+ MethodTip(textView, line, idx, tokenBeforeCaret);
+ }
}
- else if ((triggerClass & TokenTriggers.MatchBraces) != 0 && _service.Preferences.EnableMatchBraces)
+
+ private void TryHighlightBraces(IVsTextView textView, VsCommands2K command, int line, int idx,
+ TokenInfo tokenInfo)
+ {
+ // Highlight brace to the left from the caret
+ if ((tokenInfo.Trigger & TokenTriggers.MatchBraces) != 0 && _service.Preferences.EnableMatchBraces)
{
- if ((command != VsCommands2K.BACKSPACE) && ((command == VsCommands2K.TYPECHAR) || _service.Preferences.EnableMatchBracesAtCaret))
+ if ( (command != VsCommands2K.BACKSPACE) &&
+ (/*(command == VsCommands2K.TYPECHAR) ||*/
+ _service.Preferences.EnableMatchBracesAtCaret))
{
- this.MatchBraces(textView, line, idx, info);
+ MatchBraces(textView, line, idx, tokenInfo);
}
}
+ }
+ private void TryHighlightBraces(IVsTextView textView, VsCommands2K command, int line, int idx,
+ TokenInfo tokenBeforeCaret, TokenInfo tokenAfterCaret)
+ {
+ TryHighlightBraces(textView, command, line, idx + 1, tokenAfterCaret);
+ TryHighlightBraces(textView, command, line, idx, tokenBeforeCaret);
+ }
- if (!_methodData.IsDisplayed &&
- (triggerClass & TokenTriggers.MethodTip) != 0 &&
- command == VsCommands2K.TYPECHAR &&
- _service.Preferences.ParameterInformation)
+ public void TryHighlightBraces(IVsTextView textView)
+ {
+ int line, idx;
+ textView.GetCaretPos(out line, out idx);
+
+ TokenInfo tokenBeforeCaret = GetTokenInfo(line, idx);
+ TokenInfo tokenAfterCaret = GetTokenInfo(line, idx + 1);
+ TryHighlightBraces(textView, VsCommands2K.UP, line, idx, tokenBeforeCaret, tokenAfterCaret);
+ }
+
+ private void HandlePairedSymbols(IVsTextView textView, VsCommands2K command, int line, int idx, char ch)
+ {
+ // insert paired symbols here
+ if(command == VsCommands2K.TYPECHAR)
+ {
+ if(IsOpeningPairedChar(ch))
+ {
+ SetText(line, idx, line, idx, GetClosingChar(ch).ToString());
+ textView.SetCaretPos(line, idx);
+ }
+ // if we just typed closing char and the char after caret is the same then we just remove
+ // one of them
+ if(IsClosingPairedChar(ch))
+ {
+ char charAfterCaret = GetText(line, idx, line, idx + 1)[0];
+ if (ch == charAfterCaret/*IsClosingPairedChar(charAfterCaret)*/)
+ RemoveCharAt(line, idx);
+ }
+ }
+ // delete closing char if opened char was just backspaced and closing one is right next
+ if(command == VsCommands2K.BACKSPACE)
{
- MethodTip(textView, line, idx, info);
+ char closingChar = GetText(line, idx, line, idx + 1)[0];
+ if(IsOpeningPairedChar(_rememberedChar) && IsClosingPairedChar(closingChar))
+ RemoveCharAt(line, idx);
}
}
Modified: vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleTypeAndMemberDropdownBars .cs
==============================================================================
--- vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleTypeAndMemberDropdownBars .cs (original)
+++ vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleTypeAndMemberDropdownBars .cs Tue Sep 11 02:09:46 2007
@@ -39,10 +39,10 @@
ref int selectedMember)
{
if (_source.ProjectInfo == null)
- //TODO: Use fake (cached) Project for parcing purpose
- // if file not in any project. It's allow show combo box
+ //TODO: Use fake (cached) Project for parsing purpose
+ // if file not in any project. It allows showing combo box
// for standalone files. We shold cache Project because
- // it creation is expensive operation.
+ // its creation is expensive operation.
return false;
bool ret = false;
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 Tue Sep 11 02:09:46 2007
@@ -12,6 +12,7 @@
using Nemerle.Completion2;
using Nemerle.Compiler;
+using Nemerle.Completion2.CodeFormatting;
using Nemerle.VisualStudio.Project;
using Nemerle.VisualStudio.GUI;
@@ -55,6 +56,7 @@
int iMinUnit, int iMaxUnits, int iVisibleUnits, int iFirstVisibleUnit)
{
base.OnChangeScrollInfo(view, iBar, iMinUnit, iMaxUnits, iVisibleUnits, iFirstVisibleUnit);
+ Source.TryHighlightBraces(view);
ShowAst(view, false);
}
@@ -306,7 +308,7 @@
// one extra line is added to the selection (where the caret is left)
TextSpan ts = new TextSpan();
TextView.GetSelection(out ts.iStartLine, out ts.iStartIndex, out ts.iEndLine, out ts.iEndIndex);
- if (ts.iEndIndex == 0)
+ if (ts.iEndIndex == 0 && ts.iEndLine - ts.iStartLine > 0)
ts.iEndLine--;
return ts;
}
@@ -314,6 +316,15 @@
public override bool HandlePreExec(
ref Guid guidCmdGroup, uint nCmdId, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
{
+ VsCommands2K cmd = (VsCommands2K)nCmdId;
+
+ // we're goona to erase some symbol from existence.
+ // In some cases we need to know what it was (auto-deletion of paired token)
+ if (cmd == VsCommands2K.BACKSPACE)
+ Source.RememberCharBeforeCaret(TextView);
+ else
+ Source.ClearRememberedChar();
+
_startLine = -1;
if (guidCmdGroup == VSConstants.VSStd2K)
@@ -321,12 +332,12 @@
if (Source.MethodData.IsDisplayed)
TextView.GetCaretPos(out _startLine, out _startPos);
- VsCommands2K cmd = (VsCommands2K)nCmdId;
+
switch (cmd)
{
case VsCommands2K.FORMATSELECTION:
- this.ReformatSelection();
+ ReformatSelection();
return true;
case VsCommands2K.INSERTSNIPPET:
@@ -338,10 +349,6 @@
return true; // Handled the command.
}
-
- case VsCommands2K.COMMENT_BLOCK:
- CommentSelection();
- return true;
case VsCommands2K.SURROUNDWITH:
{
ExpansionProvider ep = GetExpansionProvider();
@@ -359,7 +366,7 @@
if (count > 1)
{
- while (Source.MethodData.NextMethod() < count - 1) ;
+ while (Source.MethodData.NextMethod() < count - 1)
Source.MethodData.UpdateView();
return true;
@@ -375,7 +382,7 @@
if (count > 1 && Source.MethodData.GetCurMethod() == count - 1)
{
- while (Source.MethodData.PrevMethod() > 0) ;
+ while (Source.MethodData.PrevMethod() > 0)
Source.MethodData.UpdateView();
return true;
@@ -391,20 +398,52 @@
return base.HandlePreExec(ref guidCmdGroup, nCmdId, nCmdexecopt, pvaIn, pvaOut);
}
+ // TODO: Implement smart indention
+ // 1. When typing open curly brace (second is entered automatically) and
+ // then pressing enter
+ // 2. When typing enter between sentences.
+ // 3. When typing enter in the middle of expression.
+ public override bool HandleSmartIndent()
+ {
+ // TODO: Minimal functionality is to find what caret position should be,
+ // and to insert needed whitespace to move all the text that is after caret
+ // to the position after preferred caret position.
+
+ int line;
+ int idx;
+ TextView.GetCaretPos(out line, out idx);
+
+ string filePath = Source.GetFilePath();
+ ProjectInfo projectInfo = ProjectInfo.FindProject(filePath);
+ Engine engine = projectInfo.Engine;
+
+ List<FormatterResult> results = Formatter.FormatExpressionAt(engine, filePath, line + 1, idx + 1);
+ ApplyFormatterResults(results);
+
+ //MessageBox.Show("Caret pos in HandleSmartIndent: " + line + ":" + col);
+ return false;
+ }
+
public override void HandlePostExec(
ref Guid guidCmdGroup, uint nCmdId, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut, bool bufferWasChanged)
{
+ VsCommands2K cmd = (VsCommands2K)nCmdId;
// Special handling of "Toggle all outlining" command
- //if (guidCmdGroup == typeof(VsCommands2K).GUID)
- //{
- // if ((VsCommands2K)nCmdId == VsCommands2K.OUTLN_TOGGLE_ALL)
- // {
- // Source.CollapseAllRegions();
- // return;
- // }
- //}
+ /*if (guidCmdGroup == typeof(VsCommands2K).GUID)
+ {
+ if ((VsCommands2K)nCmdId == VsCommands2K.OUTLN_TOGGLE_ALL)
+ {
+ Source.CollapseAllRegions();
+ return;
+ }
+ }
+*/
base.HandlePostExec(ref guidCmdGroup, nCmdId, nCmdexecopt, pvaIn, pvaOut, bufferWasChanged);
+ // workaround: for some reason, UP and DOWN commands are not passed to Source in base.HandlePostExec
+ if (cmd == VsCommands2K.UP || cmd == VsCommands2K.DOWN)
+ Source.OnCommand(TextView, cmd, '\0');
+
if (_startLine >= 0 && Source.MethodData.IsDisplayed)
{
int line;
@@ -414,8 +453,6 @@
if (line != _startLine || pos != _startPos)
{
- VsCommands2K cmd = (VsCommands2K)nCmdId;
-
bool backward =
cmd == VsCommands2K.BACKSPACE ||
cmd == VsCommands2K.BACKTAB ||
@@ -437,6 +474,23 @@
}
}
+ private void ApplyFormatterResults(List<FormatterResult> results)
+ {
+ foreach (FormatterResult result in results)
+ {
+ if(result.StartLine == result.EndLine)
+ {
+ int line = result.StartLine - 1;
+ Debug.Assert(Source.GetLineLength(line) >= result.EndCol - 1, "Line must be GE that formatter result");
+ Source.SetText(line, result.StartCol - 1, line, result.EndCol - 1,
+ result.ReplacementString);
+ }
+ else
+ Source.SetText(result.StartLine, result.StartCol - 1, result.EndLine - 1, result.EndCol - 1,
+ result.ReplacementString);
+ }
+ }
+
/// <summary>
/// Here we will do our formatting...
/// </summary>
Modified: vs-plugin/trunk/Nemerle.VsIntegration/Project/NemerleFileDocumentManager.cs
==============================================================================
--- vs-plugin/trunk/Nemerle.VsIntegration/Project/NemerleFileDocumentManager.cs (original)
+++ vs-plugin/trunk/Nemerle.VsIntegration/Project/NemerleFileDocumentManager.cs Tue Sep 11 02:09:46 2007
@@ -14,7 +14,7 @@
public override int Open(bool newFile, bool openWith, ref Guid logicalView, IntPtr docDataExisting, out Microsoft.VisualStudio.Shell.Interop.IVsWindowFrame windowFrame, WindowFrameShowAction windowFrameAction)
{
- //TODO: It's not bast way to find project. NemerleFileDocumentManager must contains reference to ProjectInfo.
+ //TODO: It's not best way to find project. NemerleFileDocumentManager must contain reference to ProjectInfo.
ProjectInfo projectInfo = ProjectInfo.FindProject(GetFullPathForDocument());
if (projectInfo != null)
Modified: vs-plugin/trunk/Nemerle.VsIntegration/Project/NemerleIdeBuildLogger.cs
==============================================================================
--- vs-plugin/trunk/Nemerle.VsIntegration/Project/NemerleIdeBuildLogger.cs (original)
+++ vs-plugin/trunk/Nemerle.VsIntegration/Project/NemerleIdeBuildLogger.cs Tue Sep 11 02:09:46 2007
@@ -24,13 +24,13 @@
internal class NemerleIdeBuildLogger : Logger
{
#region fields
- // TODO: Remove these constants when we have a version that suppoerts
+ // TODO: Remove these constants when we have a version that supports
// getting the verbosity using automation.
private string _buildVerbosityRegistryRoot;
private const string BuildVerbosityRegistrySubKey = @"General";
private const string BuildVerbosityRegistryKey = "MSBuildLoggerVerbosity";
// TODO: Re-enable this constants when we have a version that
- // suppoerts getting the verbosity using automation.
+ // supports getting the verbosity using automation.
//private const string EnvironmentCategory = "Environment";
//private const string ProjectsAndSolutionSubCategory = "ProjectsAndSolution";
//private const string BuildAndRunPage = "BuildAndRun";
More information about the svn
mailing list