private void HighlightOpcodeOnLine() { var lineSegment = Document.GetLineSegment(_caretLine); if (lineSegment == null) { return; } var word = lineSegment.Words.OfType <AsmWord>().FirstOrDefault(w => w.WordType == AsmWord.AsmWordType.Opcode); if (word == null) { return; } var opcode = OpcodeParser.GetOpcodeFromWord(word.Word, File.Project.Type); if (opcode != null) { ModuleEvents.HighlightOpcode(opcode); } }
public CodeEditor(AsmProjectFile file, Events events) { File = file; ModuleEvents = events; Document.FormattingStrategy = new Ca65Formatting(); _fileCompletionDataProvider = new FileCompletion(new[] { file.Project.Directory, file.File.Directory }, () => { _forcedAutoCompleteWindow = true; ShowIntellisense('/', 0); }); ActiveTextAreaControl.TextArea.InsertLeftMargin(1, new CpuAddressMargin(ActiveTextAreaControl.TextArea, GetDebugLine, file.Project.Type == ProjectType.Snes ? 6 : 4)); Menu = new CodeMenu(events); Menu.Enabled = true; Menu.Name = "Menu"; Menu.Size = new Size(108, 70); ActiveTextAreaControl.TextArea.ContextMenuStrip = Menu; Menu.Opening += (sender, e) => { var word = GetAsmWord(ActiveTextAreaControl.Caret.Position); Menu.CurrentWord = word; }; Menu.GoToDefinition = GoToSymbol; Menu.AddToWatch = () => { var word = GetAsmWord(ActiveTextAreaControl.Caret.Position); if (word == null) { return; } switch (word.WordType) { case AsmWord.AsmWordType.NumberWord: case AsmWord.AsmWordType.NumberByte: AddToWatch(word.Word, word.WordType == AsmWord.AsmWordType.NumberWord); break; case AsmWord.AsmWordType.LabelReference: case AsmWord.AsmWordType.LabelAbsolute: case AsmWord.AsmWordType.LabelDefinition: case AsmWord.AsmWordType.AddressReference: AddToWatch(word.Word, false); break; } }; Menu.BreakOnAccess = (type) => { var word = GetAsmWord(ActiveTextAreaControl.Caret.Position); if (word == null) { return; } switch (word.WordType) { case AsmWord.AsmWordType.NumberWord: case AsmWord.AsmWordType.NumberByte: AddAddressBreakpoint(AddressReference.ParseNumber(word.Word), type); break; case AsmWord.AsmWordType.LabelReference: case AsmWord.AsmWordType.LabelAbsolute: case AsmWord.AsmWordType.LabelDefinition: AddSymbolBreakpoint(word.Word, type); break; } }; Menu.ToggleBreakpoint = ToggleBreakpointAtCaret; Document.HighlightingStrategy = new Ca65Highlighting(File.Project.Type); var testMarker = new TextMarker(0, 0, TextMarkerType.SolidBlock, Document.HighlightingStrategy.GetColorFor("Highlighted word").BackgroundColor); Document.MarkerStrategy.AddMarker(testMarker); /*ActiveTextAreaControl.TextArea.MouseMove += (sender, e) => * { * //Document.MarkerStrategy.RemoveMarker(testMarker); * //ActiveTextAreaControl.TextArea.Invalidate(); * * var textPosition = new Point(e.Location.X - ActiveTextAreaControl.TextArea.LeftMargins.Where(m => m.IsVisible).Sum(m => m.Size.Width), e.Location.Y); * if (textPosition.X < 0 || textPosition.Y < 0) return; * * var position = ActiveTextAreaControl.TextArea.TextView.GetLogicalPosition(textPosition); * if (position.Line >= Document.TotalNumberOfLines) return; * * var line = Document.GetLineSegment(position.Line); * if (line == null) return; * var word = line.GetWord(position.Column); * if (word == null || word.IsWhiteSpace) return; * * return; * //word.SyntaxColor = new HighlightColor(word.Color, Color.DarkGray, true, false); * Document.MarkerStrategy.AddMarker(testMarker); * testMarker.Offset = word.Offset + line.Offset; * testMarker.Length = word.Length; * ActiveTextAreaControl.TextArea.Invalidate(); * };*/ var lineAddressToolTip = new ToolTip(); ActiveTextAreaControl.TextArea.ToolTipRequest += (s, e) => { Document.MarkerStrategy.RemoveMarker(testMarker); ActiveTextAreaControl.TextArea.Invalidate(); if (e.ToolTipShown || e.LogicalPosition.Line >= Document.TotalNumberOfLines) { return; } var line = Document.GetLineSegment(e.LogicalPosition.Line); if (line == null) { return; } lineAddressToolTip.Hide(FindForm()); var word = e.InDocument ? GetAsmWord(e.LogicalPosition) : null; if (word == null || word.IsWhiteSpace || word.WordType == AsmWord.AsmWordType.Comment) { var debugLine = GetDebugLine(line.LineNumber); if (debugLine == null || debugLine.CpuAddress == null) { return; } testMarker.Offset = line.Offset; testMarker.Length = line.Length; Document.MarkerStrategy.AddMarker(testMarker); //e.ShowToolTip(WatchValue.FormatHexAddress(debugLine.Address)); lineAddressToolTip.Show( WatchValue.FormatHexAddress(debugLine.CpuAddress.Value), FindForm(), PointToScreen(new Point(-60, e.MousePosition.Y)) , 3000 // TODO: Use a custom form object, not tooltips ); return; } testMarker.Offset = word.Offset + line.Offset; testMarker.Length = word.Length; Document.MarkerStrategy.AddMarker(testMarker); ActiveTextAreaControl.TextArea.Invalidate(); switch (word.WordType) { case AsmWord.AsmWordType.LabelAbsolute: case AsmWord.AsmWordType.LabelReference: case AsmWord.AsmWordType.LabelDefinition: case AsmWord.AsmWordType.Macro: e.ShowToolTip(GetSymbolDescription(word.Word)); break; case AsmWord.AsmWordType.AddressReference: e.ShowToolTip(GetParsedAddress(word.Word)); break; case AsmWord.AsmWordType.Command: var command = Ca65Parser.GetCommandFromWord(word.Word); if (command != null) { e.ShowToolTip(command.ToString()); } break; case AsmWord.AsmWordType.Opcode: var opcode = OpcodeParser.GetOpcodeFromWord(word.Word, File.Project.Type); if (opcode != null) { e.ShowToolTip(opcode.ToString()); } break; default: e.ShowToolTip(word.Word); break; } }; Document.DocumentAboutToBeChanged += (s, arts) => { _changedSinceLastCheck = true; }; //Document.LineCountChanged += (sender, args) => RefreshErrorInfo(); Document.LineLengthChanged += (s, args) => { if (Document.MarkerStrategy.GetMarkers(args.LineSegment.Offset).Any(m => m is ErrorMarker)) { RefreshErrorInfo(); } }; ActiveTextAreaControl.Caret.PositionChanged += (s, a) => { QueueCareInformation(); if (ActiveTextAreaControl.Caret.Line == _caretLine) { return; } _caretLine = ActiveTextAreaControl.Caret.Line; RefreshErrorInfo(); }; ActiveTextAreaControl.TextArea.KeyUp += delegate(object sender, KeyEventArgs e) { /*if (e.KeyCode == Program.Keys[Brewmaster.Settings.Feature.GoToDefinition]) * { * GoToSymbol(); * return; * }*/ //if (e.KeyCode == Keys.Escape) return; if (NavigationKeys.Contains(e.KeyCode)) { return; } ShowIntellisense((char)e.KeyValue, 1); _forcedAutoCompleteWindow = false; HighlightOpcodeOnLine(); }; ActiveTextAreaControl.TextArea.IconBarMargin.MouseDown += (sender, mousepos, buttons) => { if (buttons != MouseButtons.Left) { return; } var line = ActiveTextAreaControl.TextArea.TextView.GetLogicalLine(mousepos.Y); AddBreakpointMarker(line); RefreshBreakpointsInProject(); }; Document.DocumentChanged += (sender, args) => { var changed = false; foreach (var bp in Document.BookmarkManager.Marks.OfType <BreakpointMarker>()) { if (bp.GlobalBreakpoint.CurrentLine != bp.LineNumber + 1) { changed = true; } bp.GlobalBreakpoint.CurrentLine = bp.LineNumber + 1; } if (changed) { RefreshBreakpointsInProject(); } }; }
public override ICompletionData[] GenerateCompletionData(string fileName, TextArea textArea, char charTyped) { var preSelection = PreSelection.ToLower(); // TODO: Don't parse file in this method, do it async while editing file!! var symbols = new List <string>(); var importedSymbols = new List <string>(); var returnValues = new List <ICompletionData>(); using (var reader = new StringReader(textArea.Document.TextContent)) { string line; while ((line = reader.ReadLine()) != null) { var importMatch = AsmProjectFile.ImportSymbolRegex.Match(line); if (importMatch.Success) { importedSymbols.AddRange(importMatch.Groups[1].Value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(symbol => symbol.Trim())); continue; } var defineMatch = AsmProjectFile.DefineSymbolRegex.Match(line); if (!defineMatch.Success) { defineMatch = AsmProjectFile.DefineProcSymbolRegex.Match(line); } if (defineMatch.Success) { symbols.Add(defineMatch.Groups[1].Value); } } } foreach (var globalSymbol in GlobalSymbols) { if (!globalSymbol.Value.Text.ToLower().Contains(preSelection)) { continue; } /*if (symbols.Contains(globalSymbol.Key) && globalSymbol.Value.Source == fileName) * { * // TODO: This shouldn't be necessary when we're parsing include-files. Remove commenting if symbols are missing anywhere, but watch out for symbols appearing as duplicates * returnValues.Add(new Ca65SymbolData(globalSymbol.Value, 1, _getSymbolDescription)); * } * else*/if (globalSymbol.Value.Public || (importedSymbols.Contains(globalSymbol.Key) && globalSymbol.Value.Source != fileName)) { returnValues.Add(new Ca65SymbolData(globalSymbol.Value, 2, _getSymbolDescription)); } else if (!globalSymbol.Value.Public && globalSymbol.Value.LocalToFile == fileName) { returnValues.Add(new Ca65SymbolData(globalSymbol.Value, 2, _getSymbolDescription)); } } foreach (var opcode in OpcodeParser.GetOpcodes(_project.Type).Values) { if (!opcode.Command.StartsWith(preSelection, true, CultureInfo.InvariantCulture)) { continue; } returnValues.Add(new OpcodeData(opcode) { Focus = () => _events.HighlightOpcode(opcode) }); } if (PreSelection.StartsWith(".")) { var commands = Ca65Parser.GetCommands(); foreach (var command in commands.Keys.OrderBy(k => k)) { if (!command.StartsWith(preSelection, true, CultureInfo.InvariantCulture)) { continue; } returnValues.Add(new CommandData(commands[command], command.ToLower()) { Focus = () => _events.HighlightCommand(commands[command]) }); } } //CompletionData = returnValues.OrderBy(d => !d.Text.StartsWith(PreSelection)).ToArray(); CompletionData = returnValues.ToArray(); return(CompletionData); }