public static void Commit(SciCode doc, CiComplItem item, int codeLenDiff) { var snippet = item as _CiComplItemSnippet; string s, usingDir; var ci = item.ci; int pos = ci.Span.Start, endPos = pos + ci.Span.Length + codeLenDiff; //list of snippets? var x = snippet.x; if (x.HasElements) { var a = snippet.x.Elements("list").ToArray(); var m = new popupMenu(); foreach (var v in a) { m.Add(v.Attr("item")); } m.FocusedItem = m.Items.First(); int g = m.Show(MSFlags.ByCaret | MSFlags.Underline); if (g == 0) { return; } x = a[g - 1]; } s = x.Value; //##directive -> #directive if (s.Starts('#') && doc.zText.Eq(pos - 1, '#')) { s = s[1..];
public void Show(SciCode doc, int position, List <CiComplItem> a, List <string> groups) { if (a.NE_()) { Hide(); return; } _a = a; _groups = groups; _groupsEnabled = _groups != null && _groupButton.IsChecked == true; _doc = doc; foreach (var v in _kindButtons) { v.IsChecked = false; } _groupButton.Visibility = _groups != null ? Visibility.Visible : Visibility.Collapsed; UpdateVisibleItems(); var r = CiUtil.GetCaretRectFromPos(_doc, position, inScreen: true); r.left -= Dpi.Scale(50, _doc); _popup.ShowByRect(_doc, Dock.Bottom, r); }
public async void SciMouseDwellStarted(SciCode doc, int pos8, bool isDiag) { var pi = Panels.Info; if (!pi.Visible) { pi = null; } if (isDiag && pi == null) { return; } if (pos8 <= 0) { pi?.ZSetAboutInfo(); return; } //APerf.First(); int pos16 = doc.Pos16(pos8); if (!CodeInfo.GetContextAndDocument(out var cd, pos16)) { pi?.ZSetAboutInfo(cd.metaEnd > 0); return; } //APerf.Next(); var context = new QuickInfoContext(cd.document, pos16, default); //APerf.Next(); var provider = new CSharpSemanticQuickInfoProvider(); //var r = await provider.GetQuickInfoAsync(context); //not async var r = await Task.Run(async() => await provider.GetQuickInfoAsync(context)); //APerf.Next(); if (r == null) { pi?.ZSetAboutInfo(); return; } //AOutput.Write(r.Span, r.RelatedSpans); //AOutput.Write(r.Tags); var b = new StringBuilder("<body><div>"); //image CiUtil.TagsToKindAndAccess(r.Tags, out var kind, out var access); if (kind != CiItemKind.None) { if (access != default) { b.AppendFormat("<img src='@a{0}' style='padding-top: 6px' />", (int)access); } b.AppendFormat("<img src='@k{0}' style='padding-top: 2px' />", (int)kind); } //bool hasDocComm = false; //QuickInfoSection descr = null; POINT excRange = default, retRange = default;
/// <summary> /// Called when opening a document, when handle created but text still not loaded. /// </summary> public static void DocHandleCreated(SciCode doc) { Program.Settings.edit_styles.ToScintilla(doc); doc.Call(SCI_MARKERDEFINE, SciCode.c_markerUnderline, SC_MARK_UNDERLINE); doc.Call(SCI_MARKERSETBACK, SciCode.c_markerUnderline, 0xe0e0e0); _InitFolding(doc); }
public void Clear() { if (_activeDoc == null) { return; } _activeDoc = null; _oldTree = null; _modified = false; _tv.SetItems(null); }
public void Show(SciCode doc, int position) { _doc = doc; var r = CiUtil.GetCaretRectFromPos(doc, position); r.X -= _tb.Width + _TextHorzOffset + 6; _SetRect(r); _w.ZShow(doc); }
public void SciCharAdded(SciCode doc, char ch, bool methodCompletion = false) { switch (ch) { case '(' or '[' or '<' or ')' or ']' or '>' or ',': break; default: return; } _ShowSignature(doc, ch, methodCompletion); _afterCharAdded = true; }
/// <summary> /// Returns string with same indentation as of the document line from pos. /// Does not add indentation to the first line. /// The string must not contain multiline raw/verbatim strings; this func ignores it. /// </summary> public static string IndentStringForInsertSimple(string s, SciCode doc, int pos) { if (s.Contains('\n')) { int indent = doc.zLineIndentationFromPos(true, pos); if (indent > 0) { s = s.RxReplace(@"(?<=\n)", new string('\t', indent)); } } return(s); }
public SemanticModel semanticModel => document.GetSemanticModelAsync().Result; //only first time slow /// <summary> /// Initializes all fields except document. /// For <b>sci</b> uses <b>Panels.Editor.ZActiveDoc</b>. /// </summary> /// <param name="pos">If -1, gets current position. If -2, gets selection start.</param> public Context(int pos) { Debug.Assert(Environment.CurrentManagedThreadId == 1); sci = Panels.Editor.ZActiveDoc; code = sci.zText; this.pos = pos switch { -1 => sci.zCurrentPos16, -2 => sci.zSelectionStart16, _ => pos }; if (isCodeFile = sci.ZFile.IsCodeFile) { meta = MetaComments.FindMetaComments(code); } }
public void SciPositionChanged(SciCode doc) { if (_afterCharAdded) { _afterCharAdded = false; return; } if (_data == null) { return; } _ShowSignature(doc, default); }
void _DocChanged(SciCode doc, bool opened) { _doc = doc; _update = false; _folded = false; _visibleLines = default; _modTimer?.Stop(); _modStart = _modFromEnd = int.MaxValue; _diagCounter = 0; _Work(doc, cancel: true); //if (opened) { //} }
public static bool SciCmdKey(SciCode doc, Keys keyData) { #if NO_COMPL_CORR_SIGN return(false); #endif if (!_CanWork(doc)) { return(false); } switch (keyData) { case Keys.Control | Keys.Space: ShowCompletionList(doc); return(true); case Keys.Control | Keys.Shift | Keys.Space: ShowSignature(doc); return(true); case Keys.Escape: case Keys.Down: case Keys.Up: case Keys.PageDown: case Keys.PageUp: if (_compl.OnCmdKey_SelectOrHide(keyData)) { return(true); } if (_signature.OnCmdKey(keyData)) { return(true); } break; case Keys.Tab: case Keys.Enter: return(_compl.OnCmdKey_Commit(doc, keyData) != CiComplResult.None || _correct.SciBeforeKey(doc, keyData)); case Keys.Enter | Keys.Shift: case Keys.Enter | Keys.Control: case Keys.OemSemicolon | Keys.Control: var complResult = _compl.OnCmdKey_Commit(doc, keyData); //if(complResult == CiComplResult.Complex && !keyData.HasAny(Keys.Modifiers)) return true; return(_correct.SciBeforeKey(doc, keyData) | (complResult != CiComplResult.None)); case Keys.Back: case Keys.Delete: return(_correct.SciBeforeKey(doc, keyData)); } return(false); }
void _DocChanged(SciCode doc, bool opened) { _doc = doc; _update = false; _visibleLines = default; _modTimer?.Stop(); _modFromEnd = int.MaxValue; _diagCounter = 0; _cancelTS?.Cancel(); _cancelTS = null; if (opened) { _StylingAndFoldingVisibleFrom0(doc, firstTime: true); } }
void _DocTextAdded(SciCode doc, bool newFile) { if (CodeInfo.IsReadyForStyling) { doc.Dispatcher.InvokeAsync(() => _DocChanged(doc, true), System.Windows.Threading.DispatcherPriority.Loaded); //info: if Normal priority, scintilla says there is 0 visible lines, and will need to do styling again. Timer would be OK too. } else //at program startup { CodeInfo.ReadyForStyling += () => { if (!doc.Hwnd.Is0) { _DocChanged(doc, true); } }; } }
void _DocTextAdded(SciCode doc, bool newFile) { doc.ZFoldScriptHeader(setCaret: newFile); if (CodeInfo.IsReadyForStyling) { doc.BeginInvoke(new Action(() => _DocChanged(doc, true))); } else //at program startup { CodeInfo.ReadyForStyling += () => { if (doc.IsHandleCreated) { _DocChanged(doc, true); } }; } }
public void SciCharAdded(SciCode doc, char ch) { switch (ch) { case '(': case '[': case '<': case ')': case ']': case '>': case ',': break; default: return; } _ShowSignature(doc, ch); _afterCharAdded = true; }
public void KeysWindowShow(SciCode doc, string code, int pos16, TextSpan stringSpan) { if (_keysWindow == null) { _keysWindow = new KeysWindow(); _keysWindow.Window.Name = "Ci.Keys"; //prevent hiding when activated } var r = CiUtil.GetCaretRectFromPos(doc, pos16); int i = Au.Util.ADpi.ScaleInt(100); r.Width = i; r.Inflate(i, 0); _keysWindow.Show(doc, r, false, PopupAlignment.TPM_CENTERALIGN | PopupAlignment.TPM_VERTICAL); _keysWindow.InsertInControl = doc; int vi = _StringPrefixLength(code, stringSpan.Start); doc.ZTempRanges_Add(this, stringSpan.Start + vi + 1, stringSpan.End - 1, onLeave: () => _keysWindow.Hide()); }
static bool _CanWork(SciCode doc) { if (!_isWarm) { return(false); } if (doc == null) { return(false); } if (!doc.ZFile.IsCodeFile) { return(false); } if (doc != Panels.Editor.ZActiveDoc) { _Uncache(); return(false); } //maybe changed an inactive file that participates in current compilation //FUTURE: what if isn't open? return(true); }
public static bool SciBeforeCharAdded(SciCode doc, char ch) { #if NO_COMPL_CORR_SIGN return(false); #endif if (!_CanWork(doc)) { return(false); } if (_correct.SciBeforeCharAdded(doc, ch, out var b)) { if (b == null) { return(true); } if (_compl.IsVisibleUI) { int diff = b.newPosUtf8 - b.oldPosUtf8; _compl.SciCharAdding_Commit(doc, ch); b.newPosUtf8 = doc.Z.CurrentPos8 + diff; } doc.Z.CurrentPos8 = b.newPosUtf8; if (!b.dontSuppress) { return(true); } } else if (_compl.IsVisibleUI) { if (CiComplResult.Complex == _compl.SciCharAdding_Commit(doc, ch)) { return(true); } } return(false); }
public void RegexWindowShow(SciCode doc, string code, int pos16, TextSpan stringSpan, bool replace) { int j = stringSpan.Start, vi = _StringPrefixLength(code, j); if (!replace && (vi == 0 || !(code[j] == '@' || code[j + 1] == '@'))) { ADialog.ShowInfo(null, "Regular expression string should be like @\"text\", not like \"text\". The Regex tool will not escape \\ when inserting text."); } if (_regexWindow == null) { _regexWindow = new RegexWindow(); _regexWindow.Window.Name = "Ci.Regex"; //prevent hiding when activated } var r = CiUtil.GetCaretRectFromPos(doc, pos16); int i = Au.Util.ADpi.ScaleInt(100); r.Width = i; r.Inflate(i, 0); _regexWindow.Show(doc, r, false, PopupAlignment.TPM_CENTERALIGN | PopupAlignment.TPM_VERTICAL); _regexWindow.InsertInControl = doc; var s = _regexWindow.CurrentTopic; if (s == "replace") { if (!replace) { _regexWindow.CurrentTopic = _regexTopic; } } else if (replace) { _regexTopic = s; _regexWindow.CurrentTopic = "replace"; } doc.ZTempRanges_Add(this, stringSpan.Start + vi + 1, stringSpan.End - 1, onLeave: () => _regexWindow.Hide()); }
public static void SciKillFocus(SciCode doc) { if (!_CanWork(doc)) { return; } #if DEBUG if (Debugger.IsAttached) { return; } #endif //hide code info windows, except when a code info window is focused. Code info window names start with "Ci.". var aw = AWnd.ThisThread.Active; if (aw.Is0) { Stop(); } else if (!(Control.FromHandle(aw.Handle) is Form f && f.Name.Starts("Ci."))) { Cancel(); } }
/// <summary> /// Called every 250 ms while editor is visible. /// </summary> public void Timer250msWhenVisibleAndWarm(SciCode doc) { //We use SCLEX_NULL. If SCLEX_CONTANER, Scintilla sends too many notifications, particularly if folding used too. //To detect when need styling and folding we use 'opened' and 'modified' events and 250 ms timer. //When modified, we do styling for the modified line(s). It is faster but unreliable, eg does not update new/deleted identifiers. //The timer does styling and folding for all visible lines. It is slower but updates everything after modified, scrolled, resized, folded, etc. //When opened, we do styling for all visible lines; folding for all lines, because may need to restore saved contracted fold points. if (_cancelTS != null || (_modTimer?.IsRunning ?? false)) { return; } if (doc != _doc || _update) { if (doc != _doc) { _DocChanged(doc, false); } else { _update = false; } _StylingAndFoldingVisibleFrom0(doc); } else { Sci_GetStylingInfo(doc.SciPtr, 8 | 4, out var si); //fast if (si.visibleFromLine < _visibleLines.Start.Value || si.visibleToLine > _visibleLines.End.Value) { _StylingAndFolding(doc); //all visible } else if (_diagCounter > 0 && --_diagCounter == 0) { CodeInfo._diag.Indicators(doc.Pos16(si.visibleFrom), doc.Pos16(si.visibleTo)); } } }
/// <summary> /// Called every 250 ms while editor is visible. /// </summary> public void Timer250msWhenVisibleAndWarm(SciCode doc) { //We can't use Scintilla styling notifications, mostly because of Roslyn slowness. //To detect when need styling and folding we use 'opened' and 'modified' events and 250 ms timer. //When modified, we do styling for the modified line(s). Redraws faster, but unreliable, eg does not update new/deleted identifiers. //The timer does styling and folding for all visible lines. Redraws with a bigger delay, but updates everything after modified, scrolled, resized, folded, etc. if (_cancelTS != null || (_modTimer?.IsRunning ?? false)) { return; } if (doc != _doc || _update) { _update = false; if (doc != _doc) { _DocChanged(doc, false); } else { _Work(doc, cancel: true); } } else { //using var p1 = perf.local(); Sci_GetVisibleRange(doc.ZSciPtr, out var vr); //fast if (vr != _visibleLines) { _Work(doc); } else if (_diagCounter > 0 && --_diagCounter == 0) { CodeInfo._diag.Indicators(doc.zPos16(vr.posFrom), doc.zPos16(vr.posTo)); } } }
public _DragDrop(SciCode sci) { _sci = sci; }
void _RegexWindowShow(SciCode doc, string code, int pos16, in CiStringInfo si, bool replace, wnd dontCover = default)
/// <summary> /// Called after setting editor control text when a document opened (not just switched active document). /// </summary> public static void DocTextAdded(SciCode doc, bool newFile) => CodeInfo._styling._DocTextAdded(doc, newFile);
/// <summary> /// Called when opening a document, when handle created but text still not loaded. /// </summary> public static void DocHandleCreated(SciCode doc) { TStyles.Settings.ToScintilla(doc); CiFolding.InitFolding(doc); }
/// <summary> /// Called when editor text modified. /// </summary> public void SciModified(SciCode doc, in SCNotification n)
public void ShowSignature(SciCode doc) { _ShowSignature(doc, default); }
void _ShowSignature(SciCode doc, char ch) { //APerf.First(); if (!CodeInfo.GetContextAndDocument(out var cd, -2)) { return; //returns false if position is in meta comments } //APerf.Next(); var trigger = new SignatureHelpTriggerInfo(ch == default ? SignatureHelpTriggerReason.InvokeSignatureHelpCommand : SignatureHelpTriggerReason.TypeCharCommand, ch); var providers = _SignatureHelpProviders; //AOutput.Write(providers); //APerf.Next(); SignatureHelpItems r = null; foreach (var p in providers) { //APerf.First(); var r2 = p.GetItemsAsync(cd.document, cd.pos16, trigger, default).Result; //APerf.NW(); //quite fast, don't need async. But in the future can try to wrap this foreach+SignatureHelpProviders in async Task. Need to test with large files. if (r2 == null) { continue; } if (r == null || r2.ApplicableSpan.Start > r.ApplicableSpan.Start) { r = r2; } //Example: 'AOutput.Write(new Something())'. // The first provider probably is for Write (invocation). // Then the second is for Something (object creation). // We need the innermost, in this case Something. } if (r == null) { Cancel(); return; } //APerf.NW('s'); //AOutput.Write($"<><c orange>pos={de.position}, span={r.ApplicableSpan}, nItems={r.Items.Count}, argCount={r.ArgumentCount}, argIndex={r.ArgumentIndex}, argName={r.ArgumentName}, sel={r.SelectedItemIndex}, provider={provider}<>"); //var node = document.GetSyntaxRootAsync().Result; var span = new _Span(r.ApplicableSpan, cd.code); int iSel = _data?.GetUserSelectedItemIfSameSpan(span, r) ?? -1; //preserve user selection in same session _data = new _Data { r = r, span = span, iUserSelected = iSel, sciDoc = doc, }; if (iSel < 0) { iSel = r.SelectedItemIndex ?? (r.ArgumentCount == 0 ? 0 : -1); if (iSel < 0) { for (int i = 0; i < r.Items.Count; i++) { if (r.Items[i].Parameters.Length >= r.ArgumentCount) { iSel = i; break; } } if (iSel < 0) { for (int i = 0; i < r.Items.Count; i++) { if (r.Items[i].IsVariadic) { iSel = i; break; } } if (iSel < 0) { iSel = 0; } } } } string html = _FormatHtml(iSel, userSelected: false); doc.ZTempRanges_Add(this, r.ApplicableSpan.Start, r.ApplicableSpan.End, onLeave: () => { if (doc.ZTempRanges_Enum(doc.Z.CurrentPos8, this, utf8: true).Any()) { return; } Cancel(); }, SciCode.ZTempRangeFlags.NoDuplicate); var rect1 = CiUtil.GetCaretRectFromPos(doc, r.ApplicableSpan.Start); var rect2 = CiUtil.GetCaretRectFromPos(doc, cd.pos16); var rect = doc.RectangleToScreen(Rectangle.Union(rect1, rect2)); rect.Width += Au.Util.ADpi.ScaleInt(200); rect.X -= 6; _popupHtml ??= new CiPopupHtml(CiPopupHtml.UsedBy.Signature, onHiddenOrDestroyed: _ => _data = null) { OnLinkClick = (ph, e) => ph.Html = _FormatHtml(e.Link.ToInt(1), userSelected: true) }; _popupHtml.Html = html; _popupHtml.Show(Panels.Editor.ZActiveDoc, rect, PopupAlignment.TPM_VERTICAL); //APerf.NW(); }