1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-09 03:52:19 +02:00

Feature: Multi-Cursors

This commit is contained in:
Chernyavsky Andrey 2025-05-04 07:59:10 +05:00
parent 1e528cba95
commit c6fa2b8e79
9 changed files with 1776 additions and 530 deletions

View file

@ -243,9 +243,9 @@ namespace Beefy.theme.dark
return mLineCoords[anchorLine + 1] == mLineCoords[checkLine + 1]; return mLineCoords[anchorLine + 1] == mLineCoords[checkLine + 1];
} }
protected override void AdjustCursorsAfterExternalEdit(int index, int ofs) protected override void AdjustCursorsAfterExternalEdit(int index, int ofs, int lineOfs)
{ {
base.AdjustCursorsAfterExternalEdit(index, ofs); base.AdjustCursorsAfterExternalEdit(index, ofs, lineOfs);
mWantsCheckScrollPosition = true; mWantsCheckScrollPosition = true;
} }
@ -775,6 +775,96 @@ namespace Beefy.theme.dark
} }
} }
if (mEditWidget.mHasFocus)
{
void DrawSelection(int line, int startColumn, int endColumn)
{
float x = startColumn * mCharWidth;
float y = mLineCoords[line];
float width = Math.Abs(startColumn - endColumn) * mCharWidth;
float height = mLineCoords[line + 1] - y;
using (g.PushColor(mHiliteColor))
g.FillRect(x, y, width, height);
}
void DrawSelection()
{
if (!HasSelection())
return;
mSelection.Value.GetAsForwardSelect(var startPos, var endPos);
GetLineColumnAtIdx(startPos, var startLine, var startColumn);
GetLineColumnAtIdx(endPos, var endLine, var endColumn);
// Selection is on the single line
if (startLine == endLine)
{
DrawSelection(startLine, startColumn, endColumn);
return;
}
// Selection goes across multiple lines
// First line
GetLinePosition(startLine, ?, var firstLineEndIdx);
GetLineColumnAtIdx(firstLineEndIdx, ?, var firstLineEndColumn);
DrawSelection(startLine, startColumn, firstLineEndColumn + 1);
for (var lineIdx = startLine + 1; lineIdx < endLine; lineIdx++)
{
GetLinePosition(lineIdx, var lineStart, var lineEnd);
GetLineColumnAtIdx(lineEnd, var line, var column);
if (column == 0)
{
// Blank line selected
var y = mLineCoords[line];
var height = mLineCoords[line + 1] - y;
using (g.PushColor(mHiliteColor))
g.FillRect(0, y, 4, height);
}
else
{
DrawSelection(line, 0, column + 1);
}
}
// Last line
DrawSelection(endLine, 0, endColumn);
}
var prevTextCursor = mCurrentTextCursor;
for (var cursor in mTextCursors)
{
if (cursor.mId == 0)
continue;
SetTextCursor(cursor);
DrawSelection();
float x = 0;
float y = 0;
if (cursor.mVirtualCursorPos.HasValue)
{
x = cursor.mVirtualCursorPos.Value.mColumn * mCharWidth;
y = mLineCoords[cursor.mVirtualCursorPos.Value.mLine];
}
else
{
GetLineCharAtIdx(cursor.mCursorTextPos, var eStartLine, var eStartCharIdx);
GetColumnAtLineChar(eStartLine, eStartCharIdx, var column);
x = column * mCharWidth;
y = mLineCoords[eStartLine];
}
using (g.PushColor(0xFF80FFB3))
DrawCursor(x, y);
}
SetTextCursor(prevTextCursor);
}
g.PopMatrix(); g.PopMatrix();
/*using (g.PushColor(0x4000FF00)) /*using (g.PushColor(0x4000FF00))

View file

@ -138,8 +138,47 @@ namespace Beefy.utils
mCurCost = 0; mCurCost = 0;
} }
bool TryMerge(UndoAction action)
{
var currentBatchEnd = action as UndoBatchEnd;
if (currentBatchEnd == null)
return false;
var currentBatchStart = currentBatchEnd.mBatchStart as UndoBatchStart;
var prevBatchEndIdx = mUndoList.IndexOf(currentBatchStart) - 1;
if (prevBatchEndIdx <= 0)
return false;
var prevBatchEnd = mUndoList[prevBatchEndIdx] as UndoBatchEnd;
if (prevBatchEnd == null)
return false;
var prevBatchStart = prevBatchEnd.mBatchStart as UndoBatchStart;
if (prevBatchStart == null)
return false;
if (prevBatchStart.Merge(currentBatchStart) == false)
return false;
mUndoList.Remove(currentBatchStart);
mUndoList.Remove(currentBatchEnd);
mUndoList.Remove(prevBatchEnd);
mUndoList.Add(prevBatchEnd);
delete currentBatchStart;
delete currentBatchEnd;
mUndoIdx = (.)mUndoList.Count;
Debug.WriteLine("SUCCESS: Merged");
return true;
}
public void Add(UndoAction action, bool allowMerge = true) public void Add(UndoAction action, bool allowMerge = true)
{ {
if ((allowMerge) && (TryMerge(action)))
return;
if (mFreezeDeletes == 0) if (mFreezeDeletes == 0)
mCurCost += action.GetCost(); mCurCost += action.GetCost();
if (action is IUndoBatchStart) if (action is IUndoBatchStart)

File diff suppressed because it is too large Load diff

View file

@ -340,6 +340,8 @@ namespace IDE
Add("Zoom Out", new => gApp.Cmd_ZoomOut); Add("Zoom Out", new => gApp.Cmd_ZoomOut);
Add("Zoom Reset", new => gApp.Cmd_ZoomReset); Add("Zoom Reset", new => gApp.Cmd_ZoomReset);
Add("Attach to Process", new => gApp.[Friend]DoAttach); Add("Attach to Process", new => gApp.[Friend]DoAttach);
Add("Select Next Match", new => gApp.Cmd_SelectNextMatch);
Add("Skip Current Match and Select Next", new => gApp.Cmd_SkipCurrentMatchAndSelectNext);
Add("Test Enable Console", new => gApp.Cmd_TestEnableConsole); Add("Test Enable Console", new => gApp.Cmd_TestEnableConsole);
} }

View file

@ -4290,6 +4290,7 @@ namespace IDE
var sourceViewPanel = GetActiveSourceViewPanel(); var sourceViewPanel = GetActiveSourceViewPanel();
if (sourceViewPanel != null) if (sourceViewPanel != null)
{ {
sourceViewPanel.EditWidget.Content.RemoveSecondaryTextCursors();
sourceViewPanel.GotoLine(); sourceViewPanel.GotoLine();
return; return;
} }
@ -5469,7 +5470,7 @@ namespace IDE
if (ewc.HasSelection()) if (ewc.HasSelection())
ewc.GetSelectionText(debugExpr); ewc.GetSelectionText(debugExpr);
else else
sourceViewPanel.GetDebugExpressionAt(ewc.CursorTextPos, debugExpr); sourceViewPanel.GetDebugExpressionAt(ewc.mTextCursors.Front.mCursorTextPos, debugExpr);
dialog.Init(debugExpr); dialog.Init(debugExpr);
} }
else if (let immediatePanel = activePanel as ImmediatePanel) else if (let immediatePanel = activePanel as ImmediatePanel)
@ -5951,6 +5952,18 @@ namespace IDE
ToggleCheck(ideCommand.mMenuItem, ref mTestEnableConsole); ToggleCheck(ideCommand.mMenuItem, ref mTestEnableConsole);
} }
[IDECommand]
public void Cmd_SelectNextMatch()
{
GetActiveSourceEditWidgetContent()?.SelectNextMatch();
}
[IDECommand]
public void Cmd_SkipCurrentMatchAndSelectNext()
{
GetActiveSourceEditWidgetContent()?.SkipCurrentMatchAndSelectNext();
}
public void UpdateMenuItem_HasActivePanel(IMenu menu) public void UpdateMenuItem_HasActivePanel(IMenu menu)
{ {
menu.SetDisabled(GetActivePanel() == null); menu.SetDisabled(GetActivePanel() == null);
@ -7852,6 +7865,7 @@ namespace IDE
if (!sourceViewPanel.[Friend]mWantsFullRefresh) if (!sourceViewPanel.[Friend]mWantsFullRefresh)
sourceViewPanel.UpdateQueuedEmitShowData(); sourceViewPanel.UpdateQueuedEmitShowData();
sourceViewPanel.EditWidget?.Content.RemoveSecondaryTextCursors();
return sourceViewPanel; return sourceViewPanel;
} }
} }
@ -7863,6 +7877,7 @@ namespace IDE
svTabButton.mIsTemp = true; svTabButton.mIsTemp = true;
sourceViewPanel.ShowHotFileIdx(showHotIdx); sourceViewPanel.ShowHotFileIdx(showHotIdx);
sourceViewPanel.ShowFileLocation(refHotIdx, Math.Max(0, line), Math.Max(0, column), hilitePosition); sourceViewPanel.ShowFileLocation(refHotIdx, Math.Max(0, line), Math.Max(0, column), hilitePosition);
sourceViewPanel.EditWidget?.Content.RemoveSecondaryTextCursors();
return sourceViewPanel; return sourceViewPanel;
} }
@ -8758,38 +8773,45 @@ namespace IDE
return; return;
var ewc = sourceViewPanel.mEditWidget.mEditWidgetContent; var ewc = sourceViewPanel.mEditWidget.mEditWidgetContent;
if (!ewc.HasSelection()) for (var cursor in ewc.mTextCursors)
return;
/*ewc.mSelection.Value.GetAsForwardSelect(var startPos, var endPos);
for (int i = startPos; i < endPos; i++)
{ {
var c = ref ewc.mData.mText[i].mChar; ewc.SetTextCursor(cursor);
if (!ewc.HasSelection())
continue;
/*ewc.mSelection.Value.GetAsForwardSelect(var startPos, var endPos);
for (int i = startPos; i < endPos; i++)
{
var c = ref ewc.mData.mText[i].mChar;
if (toUpper)
c = c.ToUpper;
else
c = c.ToLower;
}*/
var prevSel = ewc.mSelection.Value;
var str = scope String();
ewc.GetSelectionText(str);
var prevStr = scope String();
prevStr.Append(str);
if (toUpper) if (toUpper)
c = c.ToUpper; str.ToUpper();
else else
c = c.ToLower; str.ToLower();
}*/
var prevSel = ewc.mSelection.Value; if (str == prevStr)
continue;
var str = scope String(); ewc.CreateMultiCursorUndoBatch("IDEApp.ChangeCase()");
ewc.GetSelectionText(str); ewc.InsertAtCursor(str);
var prevStr = scope String(); ewc.mSelection = prevSel;
prevStr.Append(str); }
ewc.CloseMultiCursorUndoBatch();
if (toUpper) ewc.SetPrimaryTextCursor();
str.ToUpper();
else
str.ToLower();
if (str == prevStr)
return;
ewc.InsertAtCursor(str);
ewc.mSelection = prevSel;
} }
public bool IsFilteredOut(String fileName) public bool IsFilteredOut(String fileName)

View file

@ -995,7 +995,7 @@ namespace IDE.ui
List<StringView> textSections = scope List<StringView>(selectedEntry.mText.Split('\x01')); List<StringView> textSections = scope List<StringView>(selectedEntry.mText.Split('\x01'));
int cursorPos = mAutoComplete.mTargetEditWidget.Content.CursorTextPos; int cursorPos = mAutoComplete.mTargetEditWidget.Content.mTextCursors.Front.mCursorTextPos;
for (int sectionIdx = 0; sectionIdx < mAutoComplete.mInvokeSrcPositions.Count - 1; sectionIdx++) for (int sectionIdx = 0; sectionIdx < mAutoComplete.mInvokeSrcPositions.Count - 1; sectionIdx++)
{ {
if (cursorPos > mAutoComplete.mInvokeSrcPositions[sectionIdx]) if (cursorPos > mAutoComplete.mInvokeSrcPositions[sectionIdx])
@ -1441,7 +1441,7 @@ namespace IDE.ui
if ((mInvokeWindow != null) && (!mInvokeWidget.mIsAboveText)) if ((mInvokeWindow != null) && (!mInvokeWidget.mIsAboveText))
{ {
int textIdx = mTargetEditWidget.Content.CursorTextPos; int textIdx = mTargetEditWidget.Content.mTextCursors.Front.mCursorTextPos;
int line = 0; int line = 0;
int column = 0; int column = 0;
if (textIdx >= 0) if (textIdx >= 0)
@ -1559,7 +1559,11 @@ namespace IDE.ui
{ {
if ((mInsertEndIdx != -1) && (mInsertStartIdx != -1)) if ((mInsertEndIdx != -1) && (mInsertStartIdx != -1))
{ {
mTargetEditWidget.Content.ExtractString(mInsertStartIdx, Math.Max(mInsertEndIdx - mInsertStartIdx, 0), outFilter); var length = Math.Abs(mInsertEndIdx - mInsertStartIdx);
if (length == 0)
return;
var start = Math.Min(mInsertStartIdx, mInsertEndIdx);
mTargetEditWidget.Content.ExtractString(start, length, outFilter);
} }
} }
@ -1567,13 +1571,33 @@ namespace IDE.ui
{ {
//Debug.WriteLine("GetAsyncTextPos start {0} {1}", mInsertStartIdx, mInsertEndIdx); //Debug.WriteLine("GetAsyncTextPos start {0} {1}", mInsertStartIdx, mInsertEndIdx);
mInsertEndIdx = (int32)mTargetEditWidget.Content.CursorTextPos; mInsertEndIdx = (int32)mTargetEditWidget.Content.mTextCursors.Front.mCursorTextPos;
while ((mInsertStartIdx != -1) && (mInsertStartIdx < mInsertEndIdx)) /*while ((mInsertStartIdx != -1) && (mInsertStartIdx < mInsertEndIdx))
{ {
char8 c = (char8)mTargetEditWidget.Content.mData.mText[mInsertStartIdx].mChar; char8 c = (char8)mTargetEditWidget.Content.mData.mText[mInsertStartIdx].mChar;
if ((c != ' ') && (c != ',')) Debug.WriteLine("StartIdx: {}, EndIdx: {}, mData.mText[startIdx]: '{}'", mInsertStartIdx, mInsertEndIdx, c);
if ((c != ' ') && (c != ',') && (c != '('))
break; break;
mInsertStartIdx++; mInsertStartIdx++;
}*/
mInsertStartIdx = mInsertEndIdx-1;
while ((mInsertStartIdx <= mInsertEndIdx) && (mInsertStartIdx > 0))
{
var data = mTargetEditWidget.Content.mData.mText[mInsertStartIdx - 1];
var type = (SourceElementType)data.mDisplayTypeId;
var char = data.mChar;
// Explicit delimeters
if ((char == '\n') || (char == '}') || (char == ';') || (char == '.'))
break;
if (char.IsWhiteSpace)
break;
if ((!char.IsLetterOrDigit) && (char != '_') && (type != .Keyword) && (!char.IsWhiteSpace) && (data.mChar != '@'))
break;
mInsertStartIdx--;
} }
/*mInsertStartIdx = mInsertEndIdx; /*mInsertStartIdx = mInsertEndIdx;
@ -2398,6 +2422,11 @@ namespace IDE.ui
} }
continue; continue;
} }
else if (entryDisplay.Length == 0)
{
// Skip entry that has no name
continue;
}
switch (entryType) switch (entryType)
{ {
@ -2545,7 +2574,7 @@ namespace IDE.ui
}*/ }*/
} }
if (changedAfterInfo) if ((changedAfterInfo) || (mTargetEditWidget.Content.mTextCursors.Count > 1))
{ {
GetAsyncTextPos(); GetAsyncTextPos();
} }
@ -2557,7 +2586,7 @@ namespace IDE.ui
mTargetEditWidget.Content.GetLineCharAtIdx(mInvokeSrcPositions[0], out invokeLine, out invokeColumn); mTargetEditWidget.Content.GetLineCharAtIdx(mInvokeSrcPositions[0], out invokeLine, out invokeColumn);
int insertLine = 0; int insertLine = 0;
int insertColumn = 0; int insertColumn = 0;
mTargetEditWidget.Content.GetLineCharAtIdx(mTargetEditWidget.Content.CursorTextPos, out insertLine, out insertColumn); mTargetEditWidget.Content.GetLineCharAtIdx(mTargetEditWidget.Content.mTextCursors.Front.mCursorTextPos, out insertLine, out insertColumn);
if ((insertLine != invokeLine) && ((insertLine - invokeLine) * gApp.mCodeFont.GetHeight() < GS!(40))) if ((insertLine != invokeLine) && ((insertLine - invokeLine) * gApp.mCodeFont.GetHeight() < GS!(40)))
mInvokeWidget.mIsAboveText = true; mInvokeWidget.mIsAboveText = true;
@ -2565,7 +2594,7 @@ namespace IDE.ui
mInfoFilter = new String(); mInfoFilter = new String();
GetFilter(mInfoFilter); GetFilter(mInfoFilter);
UpdateData(selectString, changedAfterInfo); UpdateData(selectString, changedAfterInfo);
mPopulating = false; mPopulating = false;
//Debug.WriteLine("SetInfo {0} {1}", mInsertStartIdx, mInsertEndIdx); //Debug.WriteLine("SetInfo {0} {1}", mInsertStartIdx, mInsertEndIdx);
@ -2716,7 +2745,7 @@ namespace IDE.ui
var targetSourceEditWidgetContent = mTargetEditWidget.Content as SourceEditWidgetContent; var targetSourceEditWidgetContent = mTargetEditWidget.Content as SourceEditWidgetContent;
var sourceEditWidgetContent = targetSourceEditWidgetContent; var sourceEditWidgetContent = targetSourceEditWidgetContent;
var prevCursorPosition = sourceEditWidgetContent.CursorTextPos; var prevCursorPosition = sourceEditWidgetContent.mTextCursors.Front.mCursorTextPos;
var prevScrollPos = mTargetEditWidget.mVertPos.mDest; var prevScrollPos = mTargetEditWidget.mVertPos.mDest;
UndoBatchStart undoBatchStart = null; UndoBatchStart undoBatchStart = null;
@ -2797,7 +2826,7 @@ namespace IDE.ui
return; return;
} }
sourceEditWidgetContent.CursorTextPos = fixitIdx; sourceEditWidgetContent.mTextCursors.Front.mCursorTextPos = fixitIdx;
if (focusChange) if (focusChange)
sourceEditWidgetContent.EnsureCursorVisible(true, true); sourceEditWidgetContent.EnsureCursorVisible(true, true);
@ -2814,7 +2843,7 @@ namespace IDE.ui
else else
InsertImplText(sourceEditWidgetContent, fixitInsert); InsertImplText(sourceEditWidgetContent, fixitInsert);
fixitIdx = (.)sourceEditWidgetContent.CursorTextPos; fixitIdx = (.)sourceEditWidgetContent.mTextCursors.Front.mCursorTextPos;
insertCount++; insertCount++;
} }
} }
@ -2822,9 +2851,9 @@ namespace IDE.ui
if (!focusChange) if (!focusChange)
{ {
mTargetEditWidget.VertScrollTo(prevScrollPos, true); mTargetEditWidget.VertScrollTo(prevScrollPos, true);
sourceEditWidgetContent.CursorTextPos = prevCursorPosition; sourceEditWidgetContent.mTextCursors.Front.mCursorTextPos = prevCursorPosition;
int addedSize = sourceEditWidgetContent.mData.mTextLength - prevTextLength; int addedSize = sourceEditWidgetContent.mData.mTextLength - prevTextLength;
sourceEditWidgetContent.[Friend]AdjustCursorsAfterExternalEdit(fixitIdx, addedSize); sourceEditWidgetContent.[Friend]AdjustCursorsAfterExternalEdit(fixitIdx, addedSize, 0);
} }
if (historyEntry != null) if (historyEntry != null)
@ -2887,9 +2916,9 @@ namespace IDE.ui
} }
if (!sourceEditWidgetContent.IsLineWhiteSpace(sourceEditWidgetContent.CursorLineAndColumn.mLine)) if (!sourceEditWidgetContent.IsLineWhiteSpace(sourceEditWidgetContent.CursorLineAndColumn.mLine))
{ {
int prevPos = sourceEditWidgetContent.CursorTextPos; int prevPos = sourceEditWidgetContent.mTextCursors.Front.mCursorTextPos;
sourceEditWidgetContent.InsertAtCursor("\n"); sourceEditWidgetContent.InsertAtCursor("\n");
sourceEditWidgetContent.CursorTextPos = prevPos; sourceEditWidgetContent.mTextCursors.Front.mCursorTextPos = (int32)prevPos;
} }
sourceEditWidgetContent.CursorToLineEnd(); sourceEditWidgetContent.CursorToLineEnd();
} }
@ -2906,7 +2935,7 @@ namespace IDE.ui
} }
else if (c == '\b') // Close block else if (c == '\b') // Close block
{ {
int cursorPos = sourceEditWidgetContent.CursorTextPos; int cursorPos = sourceEditWidgetContent.mTextCursors.Front.mCursorTextPos;
while (cursorPos < sourceEditWidgetContent.mData.mTextLength) while (cursorPos < sourceEditWidgetContent.mData.mTextLength)
{ {
char8 checkC = sourceEditWidgetContent.mData.mText[cursorPos].mChar; char8 checkC = sourceEditWidgetContent.mData.mText[cursorPos].mChar;
@ -2914,7 +2943,7 @@ namespace IDE.ui
if (checkC == '}') if (checkC == '}')
break; break;
} }
sourceEditWidgetContent.CursorTextPos = cursorPos; sourceEditWidgetContent.mTextCursors.Front.mCursorTextPos = (int32)cursorPos;
} }
else else
{ {
@ -2946,31 +2975,66 @@ namespace IDE.ui
} }
} }
public void InsertSelection(char32 keyChar, String insertType = null, String insertStr = null) public void InsertSelection(char32 keyChar, String insertType = null, String insertStr = null)
{ {
//Debug.WriteLine("InsertSelection"); var sewc = mTargetEditWidget.Content as SourceEditWidgetContent;
Debug.Assert(sewc.IsPrimaryTextCursor());
var isExplicitInsert = (keyChar == '\0') || (keyChar == '\t') || (keyChar == '\n') || (keyChar == '\r');
EditSelection editSelection = EditSelection(); AutoCompleteListWidget.EntryWidget GetEntry()
editSelection.mStartPos = mInsertStartIdx; {
if (mInsertEndIdx != -1) var entry = mAutoCompleteListWidget.mEntryList[mAutoCompleteListWidget.mSelectIdx];
editSelection.mEndPos = mInsertEndIdx; if ((keyChar == '!') && (!entry.mEntryDisplay.EndsWith("!")))
else {
editSelection.mEndPos = mInsertStartIdx; // Try to find one that DOES end with a '!'
for (var checkEntry in mAutoCompleteListWidget.mEntryList)
{
if (checkEntry.mEntryDisplay.EndsWith("!"))
return checkEntry;
}
}
var entry = mAutoCompleteListWidget.mEntryList[mAutoCompleteListWidget.mSelectIdx]; return entry;
if (keyChar == '!') }
{
if (!entry.mEntryDisplay.EndsWith("!"))
{
// Try to find one that DOES end with a '!'
for (var checkEntry in mAutoCompleteListWidget.mEntryList)
{
if (checkEntry.mEntryDisplay.EndsWith("!"))
entry = checkEntry;
}
}
}
EditSelection CalculateSelection(String implText)
{
var endPos = (int32)sewc.CursorTextPos;
var startPos = endPos;
var wentOverWhitespace = false;
while ((startPos <= endPos) && (startPos > 0))
{
var data = sewc.mData.mText[startPos - 1];
var type = (SourceElementType)data.mDisplayTypeId;
// Explicit delimeters
if ((data.mChar == '\n') || (data.mChar == '}') || (data.mChar == ';') || (data.mChar == '.'))
break;
var isWhiteSpace = data.mChar.IsWhiteSpace;
var isLetterOrDigit = data.mChar.IsLetterOrDigit;
// When it's not a override method for example
// we break right after we find a non-letter-or-digit character
// So we would only select last word
if ((implText == null) && (!isLetterOrDigit) && (data.mChar != '_') && (data.mChar != '@'))
break;
// This is for cases, when we are searching for
if ((!isLetterOrDigit) && (type != .Keyword) && (!isWhiteSpace) && (data.mChar != '_'))
break;
wentOverWhitespace = isWhiteSpace;
startPos--;
}
if (wentOverWhitespace)
startPos++;
return EditSelection(startPos, endPos);
}
var entry = GetEntry();
if (insertStr != null) if (insertStr != null)
insertStr.Append(entry.mEntryInsert ?? entry.mEntryDisplay); insertStr.Append(entry.mEntryInsert ?? entry.mEntryDisplay);
@ -2978,38 +3042,33 @@ namespace IDE.ui
{ {
if (insertType != null) if (insertType != null)
insertType.Append(entry.mEntryType); insertType.Append(entry.mEntryType);
sewc.RemoveSecondaryTextCursors();
ApplyFixit(entry.mEntryInsert); ApplyFixit(entry.mEntryInsert);
return; return;
} }
bool isExplicitInsert = (keyChar == '\0') || (keyChar == '\t') || (keyChar == '\n') || (keyChar == '\r'); var insertText = scope String(entry.mEntryInsert ?? entry.mEntryDisplay);
String insertText = entry.mEntryInsert ?? entry.mEntryDisplay;
if ((!isExplicitInsert) && (insertText.Contains('\t'))) if ((!isExplicitInsert) && (insertText.Contains('\t')))
{ {
// Don't insert multi-line blocks unless we have an explicit insert request (click, tab, or enter) // Don't insert multi-line blocks unless we have an explicit insert request (click, tab, or enter)
return; return;
} }
if ((keyChar == '=') && (insertText.EndsWith("="))) if ((keyChar == '=') && (insertText.EndsWith("=")))
insertText.RemoveToEnd(insertText.Length - 1); insertText.RemoveToEnd(insertText.Length - 1);
//insertText = insertText.Substring(0, insertText.Length - 1);
String implText = null;
int tabIdx = insertText.IndexOf('\t');
int splitIdx = tabIdx;
int crIdx = insertText.IndexOf('\r');
if ((crIdx != -1) && (tabIdx != -1) && (crIdx < tabIdx))
splitIdx = crIdx;
if (splitIdx != -1)
{
implText = scope:: String();
implText.Append(insertText, splitIdx);
insertText.RemoveToEnd(splitIdx);
}
String prevText = scope String();
mTargetEditWidget.Content.ExtractString(editSelection.mStartPos, editSelection.mEndPos - editSelection.mStartPos, prevText);
//sAutoCompleteMRU[insertText] = sAutoCompleteIdx++; // Save persistent text positions
PersistentTextPosition[] persistentInvokeSrcPositons = null;
if (mInvokeSrcPositions != null)
{
persistentInvokeSrcPositons = scope:: PersistentTextPosition[mInvokeSrcPositions.Count];
for (int32 i = 0; i < mInvokeSrcPositions.Count; i++)
{
persistentInvokeSrcPositons[i] = new PersistentTextPosition(mInvokeSrcPositions[i]);
sewc.PersistentTextPositions.Add(persistentInvokeSrcPositons[i]);
}
}
String* keyPtr; String* keyPtr;
int32* valuePtr; int32* valuePtr;
if (sAutoCompleteMRU.TryAdd(entry.mEntryDisplay, out keyPtr, out valuePtr)) if (sAutoCompleteMRU.TryAdd(entry.mEntryDisplay, out keyPtr, out valuePtr))
@ -3019,63 +3078,67 @@ namespace IDE.ui
} }
*valuePtr = sAutoCompleteIdx++; *valuePtr = sAutoCompleteIdx++;
if (insertText == prevText) String implText = null;
return; int tabIdx = insertText.IndexOf('\t');
int splitIdx = tabIdx;
int crIdx = insertText.IndexOf('\r');
if ((crIdx != -1) && (tabIdx != -1) && (crIdx < tabIdx))
splitIdx = crIdx;
if (splitIdx != -1)
{
implText = scope:: String();
implText.Append(insertText, splitIdx);
insertText.RemoveToEnd(splitIdx);
}
var sourceEditWidgetContent = mTargetEditWidget.Content as SourceEditWidgetContent; for (var cursor in sewc.mTextCursors)
{
sewc.SetTextCursor(cursor);
var editSelection = CalculateSelection(implText);
PersistentTextPosition[] persistentInvokeSrcPositons = null; var prevText = scope String();
if (mInvokeSrcPositions != null) sewc.ExtractString(editSelection.MinPos, editSelection.Length, prevText);
{ if ((prevText.Length > 0) && (insertText == prevText))
persistentInvokeSrcPositons = scope:: PersistentTextPosition[mInvokeSrcPositions.Count]; continue;
for (int32 i = 0; i < mInvokeSrcPositions.Count; i++)
{
persistentInvokeSrcPositons[i] = new PersistentTextPosition(mInvokeSrcPositions[i]);
sourceEditWidgetContent.PersistentTextPositions.Add(persistentInvokeSrcPositons[i]);
}
}
mTargetEditWidget.Content.mSelection = editSelection; sewc.mSelection = editSelection;
//bool isMethod = (entry.mEntryType == "method"); sewc.mCursorTextPos = (int32)editSelection.MaxPos;
if (insertText.EndsWith("<>"))
{ if (insertText.EndsWith("<>"))
if (keyChar == '\t')
mTargetEditWidget.Content.InsertCharPair(insertText);
else if (keyChar == '<')
{ {
String str = scope String(); if (keyChar == '\t')
str.Append(insertText, 0, insertText.Length - 2); sewc.InsertCharPair(insertText);
mTargetEditWidget.Content.InsertAtCursor(str, .NoRestoreSelectionOnUndo); else if (keyChar == '<')
{
var str = scope String();
str.Append(insertText, 0, insertText.Length - 2);
sewc.InsertAtCursor(str, .NoRestoreSelectionOnUndo);
}
else
sewc.InsertAtCursor(insertText, .NoRestoreSelectionOnUndo);
} }
else else
mTargetEditWidget.Content.InsertAtCursor(insertText, .NoRestoreSelectionOnUndo); sewc.InsertAtCursor(insertText, .NoRestoreSelectionOnUndo);
}
else
mTargetEditWidget.Content.InsertAtCursor(insertText, .NoRestoreSelectionOnUndo);
/*if (mIsAsync) if (implText != null)
UpdateAsyncInfo();*/ InsertImplText(sewc, implText);
}
if (implText != null) // Load persistent text positions back
InsertImplText(sourceEditWidgetContent, implText); if (persistentInvokeSrcPositons != null)
{
if (persistentInvokeSrcPositons != null) for (int32 i = 0; i < mInvokeSrcPositions.Count; i++)
{ {
for (int32 i = 0; i < mInvokeSrcPositions.Count; i++)
{
//TEST
//var persistentTextPositon = persistentInvokeSrcPositons[i + 100];
var persistentTextPositon = persistentInvokeSrcPositons[i]; var persistentTextPositon = persistentInvokeSrcPositons[i];
mInvokeSrcPositions[i] = persistentTextPositon.mIndex; mInvokeSrcPositions[i] = persistentTextPositon.mIndex;
sourceEditWidgetContent.PersistentTextPositions.Remove(persistentTextPositon); sewc.PersistentTextPositions.Remove(persistentTextPositon);
delete persistentTextPositon; delete persistentTextPositon;
} }
} }
mTargetEditWidget.Content.EnsureCursorVisible(); sewc.SetPrimaryTextCursor();
if ((insertType != null) && (insertText.Length > 0)) sewc.EnsureCursorVisible();
insertType.Append(entry.mEntryType); }
}
public void MarkDirty() public void MarkDirty()
{ {

View file

@ -225,6 +225,13 @@ namespace IDE.ui
if (evt.mKeyCode == KeyCode.Return) if (evt.mKeyCode == KeyCode.Return)
{ {
var keyFlags = mWidgetWindow.GetKeyFlags(true);
if (keyFlags.HasFlag(.Alt))
{
SelectAllMatches(keyFlags.HasFlag(.Shift));
Close();
return;
}
if (evt.mSender == mFindEditWidget) if (evt.mSender == mFindEditWidget)
{ {
FindNext(1, true); FindNext(1, true);
@ -249,6 +256,108 @@ namespace IDE.ui
DoReplace(true); DoReplace(true);
} }
bool SelectAllMatches(bool caseSensitive)
{
var ewc = mEditWidget.Content;
var sewc = ewc as SourceEditWidgetContent;
ewc.SetPrimaryTextCursor();
String findText = scope String();
mFindEditWidget.GetText(findText);
sLastSearchString.Set(findText);
if (findText.Length == 0)
return false;
String findTextLower = scope String(findText);
findTextLower.ToLower();
String findTextUpper = scope String(findText);
findTextUpper.ToUpper();
int32 selStart = (mSelectionStart != null) ? mSelectionStart.mIndex : 0;
int32 selEnd = (mSelectionEnd != null) ? mSelectionEnd.mIndex : ewc.mData.mTextLength;
bool Matches(int32 idx)
{
if (idx + findText.Length >= ewc.mData.mTextLength)
return false;
for (var i = 0; i < findText.Length; i++)
{
var char = ewc.mData.mText[idx+i].mChar;
if (caseSensitive)
{
if (findText[i] != char)
return false;
}
else if ((findTextLower[i] != char) && (findTextUpper[i] != char))
{
return false;
}
}
return true;
}
var primaryCursor = ewc.mTextCursors.Front;
var initialCursorPos = primaryCursor.mCursorTextPos;
EditWidgetContent.TextCursor swapCursor = null;
ewc.RemoveSecondaryTextCursors();
primaryCursor.mJustInsertedCharPair = false;
primaryCursor.mCursorImplicitlyMoved = false;
primaryCursor.mVirtualCursorPos = null;
var isFirstMatch = true;
for (var idx = selStart; idx < selEnd; idx++)
{
if (!Matches(idx))
continue;
if (!isFirstMatch)
{
var cursor = ewc.mTextCursors.Add(.. new EditWidgetContent.TextCursor(-1, primaryCursor));
if (cursor.mCursorTextPos == initialCursorPos)
swapCursor = cursor;
}
isFirstMatch = false;
primaryCursor.mCursorTextPos = (int32)(idx + findText.Length);
primaryCursor.mSelection = EditSelection(idx, primaryCursor.mCursorTextPos);
idx += (int32)findText.Length;
}
// Remove selection when at least one match has been found
if ((sewc != null) && (!isFirstMatch))
{
if (mSelectionStart != null)
{
sewc.PersistentTextPositions.Remove(mSelectionStart);
DeleteAndNullify!(mSelectionStart);
}
if (mSelectionEnd != null)
{
sewc.PersistentTextPositions.Remove(mSelectionEnd);
DeleteAndNullify!(mSelectionEnd);
}
}
// Making sure that primary cursor is at the position where QuickFind found first match.
if (swapCursor != null)
{
Swap!(primaryCursor.mCursorTextPos, swapCursor.mCursorTextPos);
Swap!(primaryCursor.mSelection.Value, swapCursor.mSelection.Value);
}
return (!isFirstMatch);
}
void EditWidgetSubmit(EditEvent editEvent) void EditWidgetSubmit(EditEvent editEvent)
{ {
//FindNext(true); //FindNext(true);

View file

@ -776,6 +776,7 @@ namespace IDE.ui
public SourceViewPanel mSourceViewPanel; public SourceViewPanel mSourceViewPanel;
//public bool mAsyncAutocomplete; //public bool mAsyncAutocomplete;
public bool mIsInKeyChar; public bool mIsInKeyChar;
public bool mDidAutoComplete;
public bool mDbgDoTest; public bool mDbgDoTest;
public int32 mCursorStillTicks; public int32 mCursorStillTicks;
public static bool sReadOnlyErrorShown; public static bool sReadOnlyErrorShown;
@ -1893,6 +1894,7 @@ namespace IDE.ui
bool startsWithNewline = (forceMatchIndent) && (str.StartsWith("\n")); bool startsWithNewline = (forceMatchIndent) && (str.StartsWith("\n"));
bool isMultiline = str.Contains("\n"); bool isMultiline = str.Contains("\n");
CreateMultiCursorUndoBatch("SEWC.PasteText(str, forceMatchIndent)");
if (startsWithNewline || isMultiline) if (startsWithNewline || isMultiline)
{ {
var undoBatchStart = new UndoBatchStart("pasteText"); var undoBatchStart = new UndoBatchStart("pasteText");
@ -2222,6 +2224,7 @@ namespace IDE.ui
public void ScopePrev() public void ScopePrev()
{ {
RemoveSecondaryTextCursors();
int pos = CursorTextPos - 1; int pos = CursorTextPos - 1;
int openCount = 0; int openCount = 0;
@ -2254,6 +2257,7 @@ namespace IDE.ui
public void ScopeNext() public void ScopeNext()
{ {
RemoveSecondaryTextCursors();
int pos = CursorTextPos; int pos = CursorTextPos;
int openCount = 0; int openCount = 0;
@ -2297,6 +2301,7 @@ namespace IDE.ui
public bool OpenCodeBlock() public bool OpenCodeBlock()
{ {
CreateMultiCursorUndoBatch("SEWC.OpenCodeBlock()");
int lineIdx; int lineIdx;
if (HasSelection()) if (HasSelection())
@ -2843,78 +2848,73 @@ namespace IDE.ui
public bool CommentBlock() public bool CommentBlock()
{ {
bool? doComment = true;
if (CheckReadOnly()) if (CheckReadOnly())
return false; return false;
var startLineAndCol = CursorLineAndColumn; for (var cursor in mTextCursors)
int startTextPos = CursorTextPos;
var prevSelection = mSelection;
bool hadSelection = HasSelection();
if ((!HasSelection()) && (doComment != null))
{ {
CursorToLineEnd(); SetTextCursor(cursor);
int cursorEndPos = CursorTextPos;
CursorToLineStart(false);
mSelection = .(CursorTextPos, cursorEndPos);
}
if ((HasSelection()) && (mSelection.Value.Length > 1)) var startLineAndCol = CursorLineAndColumn;
{ int startTextPos = CursorTextPos;
UndoBatchStart undoBatchStart = new UndoBatchStart("embeddedCommentBlock"); var prevSelection = mSelection;
mData.mUndoManager.Add(undoBatchStart); bool hadSelection = HasSelection();
var setCursorAction = new SetCursorAction(this); if (!HasSelection())
setCursorAction.mSelection = prevSelection;
setCursorAction.mCursorTextPos = (.)startTextPos;
mData.mUndoManager.Add(setCursorAction);
int minPos = mSelection.GetValueOrDefault().MinPos;
int maxPos = mSelection.GetValueOrDefault().MaxPos;
mSelection = null;
var str = scope String();
ExtractString(minPos, maxPos - minPos, str);
var trimmedStr = scope String();
trimmedStr.Append(str);
int32 startLen = (int32)trimmedStr.Length;
trimmedStr.TrimStart();
int32 afterTrimStart = (int32)trimmedStr.Length;
trimmedStr.TrimEnd();
int32 afterTrimEnd = (int32)trimmedStr.Length;
int firstCharPos = minPos + (startLen - afterTrimStart);
int lastCharPos = maxPos - (afterTrimStart - afterTrimEnd);
if (doComment != false)
{ {
CursorToLineEnd();
int cursorEndPos = CursorTextPos;
CursorToLineStart(false);
mSelection = EditSelection(CursorTextPos, cursorEndPos);
}
if (HasSelection())
{
CreateMultiCursorUndoBatch("SEWC.CommentBlock()");
var setCursorAction = new SetCursorAction(this);
setCursorAction.mSelection = prevSelection;
setCursorAction.mCursorTextPos = (int32)startTextPos;
mData.mUndoManager.Add(setCursorAction);
int minPos = mSelection.GetValueOrDefault().MinPos;
int maxPos = mSelection.GetValueOrDefault().MaxPos;
mSelection = null;
var str = scope String();
ExtractString(minPos, maxPos - minPos, str);
var trimmedStr = scope String();
trimmedStr.Append(str);
int32 startLen = (int32)trimmedStr.Length;
trimmedStr.TrimStart();
int32 afterTrimStart = (int32)trimmedStr.Length;
trimmedStr.TrimEnd();
int32 afterTrimEnd = (int32)trimmedStr.Length;
int firstCharPos = minPos + (startLen - afterTrimStart);
int lastCharPos = maxPos - (afterTrimStart - afterTrimEnd);
CursorTextPos = firstCharPos; CursorTextPos = firstCharPos;
InsertAtCursor("/*"); InsertAtCursor("/*");
CursorTextPos = lastCharPos + 2; CursorTextPos = lastCharPos + 2;
InsertAtCursor("*/"); InsertAtCursor("*/");
if (doComment != null) mSelection = EditSelection(firstCharPos, lastCharPos + 4);
mSelection = EditSelection(firstCharPos, lastCharPos + 4);
if (startTextPos <= minPos)
CursorLineAndColumn = startLineAndCol;
else if (startTextPos < maxPos)
CursorTextPos = startTextPos + 2;
if (!hadSelection)
mSelection = null;
} }
if (undoBatchStart != null)
mData.mUndoManager.Add(undoBatchStart.mBatchEnd);
if (startTextPos <= minPos)
CursorLineAndColumn = startLineAndCol;
else if (startTextPos < maxPos)
CursorTextPos = startTextPos + 2;
if ((doComment == null) || (!hadSelection))
mSelection = null;
return true;
} }
return false; CloseMultiCursorUndoBatch();
SetPrimaryTextCursor();
return true;
} }
public bool CommentLines() public bool CommentLines()
@ -2922,157 +2922,167 @@ namespace IDE.ui
if (CheckReadOnly()) if (CheckReadOnly())
return false; return false;
int startTextPos = CursorTextPos; var sortedCursors = mTextCursors;
var prevSelection = mSelection; if (mTextCursors.Count > 1)
bool hadSelection = HasSelection(); sortedCursors = GetSortedCursors(.. scope :: List<TextCursor>());
var startLineAndCol = CursorLineAndColumn;
if (!HasSelection()) // Forcing creation of undo batch, because even single cursor has
// multiple undo-actions.
CreateMultiCursorUndoBatch("SEWC.CommentLines()", force: true);
for (var cursor in sortedCursors)
{ {
CursorToLineEnd(); SetTextCursor(cursor);
int cursorEndPos = CursorTextPos;
CursorToLineStart(false);
mSelection = .(CursorTextPos, cursorEndPos);
}
UndoBatchStart undoBatchStart = new UndoBatchStart("embeddedCommentLines"); var startTextPos = CursorTextPos;
mData.mUndoManager.Add(undoBatchStart); var prevSelection = mSelection;
var hadSelection = HasSelection();
var setCursorAction = new SetCursorAction(this); var startLineAndCol = CursorLineAndColumn;
setCursorAction.mSelection = prevSelection; if (!HasSelection())
setCursorAction.mCursorTextPos = (.)startTextPos;
mData.mUndoManager.Add(setCursorAction);
int minPos = mSelection.GetValueOrDefault().MinPos;
int maxPos = mSelection.GetValueOrDefault().MaxPos;
mSelection = null;
while (minPos > 0)
{
var c = mData.mText[minPos - 1].mChar;
if (c == '\n')
break;
minPos--;
}
bool hadMaxChar = false;
int checkMaxPos = maxPos;
while (checkMaxPos > 0)
{
var c = mData.mText[checkMaxPos - 1].mChar;
if (c == '\n')
break;
if ((c != '\t') && (c != ' '))
{ {
hadMaxChar = true; CursorToLineEnd();
break; int cursorEndPos = CursorTextPos;
CursorToLineStart(false);
mSelection = .(CursorTextPos, cursorEndPos);
} }
checkMaxPos--;
}
if (!hadMaxChar) var setCursorAction = new SetCursorAction(this);
{ setCursorAction.mSelection = prevSelection;
checkMaxPos = maxPos; setCursorAction.mCursorTextPos = (int32)startTextPos;
while (checkMaxPos < mData.mTextLength) mData.mUndoManager.Add(setCursorAction);
int minPos = mSelection.Value.MinPos;
int maxPos = mSelection.Value.MaxPos;
mSelection = null;
while (minPos > 0)
{ {
var c = mData.mText[checkMaxPos].mChar; var c = mData.mText[minPos - 1].mChar;
if (c == '\n')
break;
minPos--;
}
bool hadMaxChar = false;
int checkMaxPos = maxPos;
while (checkMaxPos > 0)
{
var c = mData.mText[checkMaxPos - 1].mChar;
if (c == '\n') if (c == '\n')
break; break;
if ((c != '\t') && (c != ' ')) if ((c != '\t') && (c != ' '))
{ {
maxPos = checkMaxPos + 1; hadMaxChar = true;
break; break;
} }
checkMaxPos++; checkMaxPos--;
} }
}
int wantLineCol = -1; if (!hadMaxChar)
int lineStartCol = 0;
bool didLineComment = false;
for (int i = minPos; i < maxPos; i++)
{
var c = mData.mText[i].mChar;
if (didLineComment)
{ {
if (c == '\n') checkMaxPos = maxPos;
while (checkMaxPos < mData.mTextLength)
{ {
didLineComment = false; var c = mData.mText[checkMaxPos].mChar;
lineStartCol = 0; if (c == '\n')
break;
if ((c != '\t') && (c != ' '))
{
maxPos = checkMaxPos + 1;
break;
}
checkMaxPos++;
} }
continue;
} }
if (c == '\t')
lineStartCol += gApp.mSettings.mEditorSettings.mTabSize;
else if (c == ' ')
lineStartCol++;
else
{
if (wantLineCol == -1)
wantLineCol = lineStartCol;
else
wantLineCol = Math.Min(wantLineCol, lineStartCol);
didLineComment = true;
}
}
wantLineCol = Math.Max(0, wantLineCol);
didLineComment = false; int wantLineCol = -1;
lineStartCol = 0; int lineStartCol = 0;
int appendedCount = 0; bool didLineComment = false;
for (int i = minPos; i < maxPos; i++)
{ for (int i = minPos; i < maxPos; i++)
var c = mData.mText[i].mChar;
if (didLineComment)
{ {
if (c == '\n') var c = mData.mText[i].mChar;
if (didLineComment)
{ {
didLineComment = false; if (c == '\n')
lineStartCol = 0; {
didLineComment = false;
lineStartCol = 0;
}
continue;
} }
continue; if (c == '\t')
}
bool commentNow = false;
if ((wantLineCol != -1) && (lineStartCol >= wantLineCol))
commentNow = true;
if (c == '\t')
lineStartCol += gApp.mSettings.mEditorSettings.mTabSize;
else if (c == ' ')
lineStartCol++;
else
commentNow = true;
if (commentNow)
{
CursorTextPos = i;
String str = scope .();
while (lineStartCol + gApp.mSettings.mEditorSettings.mTabSize <= wantLineCol)
{
lineStartCol += gApp.mSettings.mEditorSettings.mTabSize; lineStartCol += gApp.mSettings.mEditorSettings.mTabSize;
str.Append("\t"); else if (c == ' ')
lineStartCol++;
else
{
if (wantLineCol == -1)
wantLineCol = lineStartCol;
else
wantLineCol = Math.Min(wantLineCol, lineStartCol);
didLineComment = true;
} }
str.Append("//");
InsertAtCursor(str);
didLineComment = true;
maxPos += str.Length;
if (i <= startTextPos + appendedCount)
appendedCount += str.Length;
} }
wantLineCol = Math.Max(0, wantLineCol);
didLineComment = false;
lineStartCol = 0;
int appendedCount = 0;
for (int i = minPos; i < maxPos; i++)
{
var c = mData.mText[i].mChar;
if (didLineComment)
{
if (c == '\n')
{
didLineComment = false;
lineStartCol = 0;
}
continue;
}
bool commentNow = false;
if ((wantLineCol != -1) && (lineStartCol >= wantLineCol))
commentNow = true;
if (c == '\t')
lineStartCol += gApp.mSettings.mEditorSettings.mTabSize;
else if (c == ' ')
lineStartCol++;
else
commentNow = true;
if (commentNow)
{
CursorTextPos = i;
String str = scope .();
while (lineStartCol + gApp.mSettings.mEditorSettings.mTabSize <= wantLineCol)
{
lineStartCol += gApp.mSettings.mEditorSettings.mTabSize;
str.Append("\t");
}
str.Append("//");
InsertAtCursor(str);
didLineComment = true;
maxPos += str.Length;
if (i <= startTextPos + appendedCount)
appendedCount += str.Length;
}
}
mSelection = EditSelection(minPos, maxPos);
if (appendedCount > 0)
CursorTextPos = startTextPos + appendedCount;
else
CursorLineAndColumn = startLineAndCol;
if (!hadSelection)
mSelection = null;
} }
mSelection = EditSelection(minPos, maxPos);
if (undoBatchStart != null) CloseMultiCursorUndoBatch();
mData.mUndoManager.Add(undoBatchStart.mBatchEnd); SetPrimaryTextCursor();
if (appendedCount > 0)
CursorTextPos = startTextPos + appendedCount;
else
CursorLineAndColumn = startLineAndCol;
if (!hadSelection)
mSelection = null;
return true; return true;
} }
@ -3095,142 +3105,166 @@ namespace IDE.ui
if (CheckReadOnly()) if (CheckReadOnly())
return false; return false;
int startTextPos = CursorTextPos; var sortedCursors = mTextCursors;
bool doLineComment = false; if (mTextCursors.Count > 1)
var prevSelection = mSelection; sortedCursors = GetSortedCursors(.. scope :: List<TextCursor>());
LineAndColumn? startLineAndCol = CursorLineAndColumn; var didComment = false;
if (!HasSelection()) for (var cursor in sortedCursors)
{ {
CursorToLineEnd(); SetTextCursor(cursor);
int cursorEndPos = CursorTextPos;
CursorToLineStart(false);
mSelection = .(CursorTextPos, cursorEndPos);
doLineComment = true;
}
if ((HasSelection()) && (mSelection.Value.Length > 0)) int startTextPos = CursorTextPos;
{ bool doLineComment = false;
UndoBatchStart undoBatchStart = new UndoBatchStart("embeddedToggleComment"); var prevSelection = mSelection;
mData.mUndoManager.Add(undoBatchStart); var cursorAtEndPos = true;
var setCursorAction = new SetCursorAction(this); LineAndColumn? startLineAndCol = CursorLineAndColumn;
setCursorAction.mSelection = prevSelection; if (!HasSelection())
setCursorAction.mCursorTextPos = (.)startTextPos;
mData.mUndoManager.Add(setCursorAction);
int minPos = mSelection.GetValueOrDefault().MinPos;
int maxPos = mSelection.GetValueOrDefault().MaxPos;
mSelection = null;
var str = scope String();
ExtractString(minPos, maxPos - minPos, str);
var trimmedStr = scope String();
trimmedStr.Append(str);
int32 startLen = (int32)trimmedStr.Length;
trimmedStr.TrimStart();
int32 afterTrimStart = (int32)trimmedStr.Length;
trimmedStr.TrimEnd();
int32 afterTrimEnd = (int32)trimmedStr.Length;
trimmedStr.Append('\n');
int firstCharPos = minPos + (startLen - afterTrimStart);
int lastCharPos = maxPos - (afterTrimStart - afterTrimEnd);
if (afterTrimEnd == 0)
{ {
if (undoBatchStart != null)
mData.mUndoManager.Add(undoBatchStart.mBatchEnd);
CursorLineAndColumn = startLineAndCol.Value;
if (doComment == null)
mSelection = null;
return false; // not sure if this should be false in blank/only whitespace selection case
}
else if ((doComment != true) && (trimmedStr.StartsWith("//")))
{
for (int i = firstCharPos; i <= lastCharPos; i++)
{
if (((minPos == 0) && (i == 0)) ||
((minPos >= 0) && (SafeGetChar(i - 1) == '\n') || (SafeGetChar(i - 1) == '\t') || (SafeGetChar(i - 1) == ' ')))
{
if (SafeGetChar(i - 0) == '/' && SafeGetChar(i + 1) == '/')
{
mSelection = EditSelection(i - 0, i + 2);
DeleteSelection();
lastCharPos -= 2;
while (i < maxPos && SafeGetChar(i) != '\n')
{
i++;
}
}
}
}
startLineAndCol = null;
CursorToLineEnd(); CursorToLineEnd();
int cursorEndPos = CursorTextPos; int cursorEndPos = CursorTextPos;
mSelection = .(minPos, cursorEndPos); CursorToLineStart(false);
} mSelection = EditSelection(CursorTextPos, cursorEndPos);
else if ((doComment != true) && (trimmedStr.StartsWith("/*"))) doLineComment = true;
{
if (trimmedStr.EndsWith("*/\n"))
{
mSelection = EditSelection(firstCharPos, firstCharPos + 2);
DeleteChar();
mSelection = EditSelection(lastCharPos - 4, lastCharPos - 2);
DeleteChar();
if (prevSelection != null)
mSelection = EditSelection(firstCharPos, lastCharPos - 4);
}
}
else if (doComment != false)
{
//if selection is from beginning of the line then we want to use // comment, that's why the check for line count and ' ' and tab
if (doLineComment)
{
CursorTextPos = minPos;
InsertAtCursor("//"); //goes here if no selection
}
else
{
CursorTextPos = firstCharPos;
InsertAtCursor("/*");
CursorTextPos = lastCharPos + 2;
InsertAtCursor("*/");
}
mSelection = EditSelection(firstCharPos, lastCharPos + 4);
if (startTextPos <= minPos)
CursorLineAndColumn = startLineAndCol.Value;
else
CursorTextPos = startTextPos + 2;
startLineAndCol = null;
} }
else else
{ {
mSelection = prevSelection; cursorAtEndPos = (mSelection.Value.mStartPos == mCursorTextPos);
} }
if (undoBatchStart != null) if (HasSelection())
mData.mUndoManager.Add(undoBatchStart.mBatchEnd); {
CreateMultiCursorUndoBatch("SEWC.ToggleComment()", force: true);
if (startLineAndCol != null) var setCursorAction = new SetCursorAction(this);
CursorLineAndColumn = startLineAndCol.Value; setCursorAction.mSelection = prevSelection;
setCursorAction.mCursorTextPos = (int32)startTextPos;
mData.mUndoManager.Add(setCursorAction);
if (prevSelection == null) var minPos = mSelection.GetValueOrDefault().MinPos;
var maxPos = mSelection.GetValueOrDefault().MaxPos;
mSelection = null; mSelection = null;
ClampCursor(); var str = scope String();
FixSelection(); ExtractString(minPos, (maxPos - minPos), str);
var trimmedStr = scope String();
trimmedStr.Append(str);
int32 startLen = (int32)trimmedStr.Length;
trimmedStr.TrimStart();
int32 afterTrimStart = (int32)trimmedStr.Length;
trimmedStr.TrimEnd();
int32 afterTrimEnd = (int32)trimmedStr.Length;
trimmedStr.Append('\n');
int firstCharPos = minPos + (startLen - afterTrimStart);
int lastCharPos = maxPos - (afterTrimStart - afterTrimEnd);
if (afterTrimEnd == 0)
{
CursorLineAndColumn = startLineAndCol.Value;
if (doComment == null)
mSelection = null;
//return false; // not sure if this should be false in blank/only whitespace selection case
continue;
}
else if ((doComment != true) && (trimmedStr.StartsWith("//")))
{
didComment = true;
for (int i = firstCharPos; i <= lastCharPos; i++)
{
if (((minPos == 0) && (i == 0)) ||
((minPos >= 0) && (SafeGetChar(i - 1) == '\n') || (SafeGetChar(i - 1) == '\t') || (SafeGetChar(i - 1) == ' ')))
{
if (SafeGetChar(i - 0) == '/' && SafeGetChar(i + 1) == '/')
{
mSelection = EditSelection(i - 0, i + 2);
DeleteSelection();
lastCharPos -= 2;
while (i < maxPos && SafeGetChar(i) != '\n')
{
i++;
}
}
}
}
startLineAndCol = null;
CursorToLineEnd();
int cursorEndPos = CursorTextPos;
mSelection = .(minPos, cursorEndPos);
}
else if ((doComment != true) && trimmedStr.StartsWith("/*"))
{
didComment = true;
if (trimmedStr.EndsWith("*/\n"))
{
mSelection = EditSelection(firstCharPos, firstCharPos + 2);
DeleteChar();
mSelection = EditSelection(lastCharPos - 4, lastCharPos - 2);
DeleteChar();
if (prevSelection != null)
mSelection = EditSelection(firstCharPos, lastCharPos - 4);
}
}
else if (doComment != false)
{
didComment = true;
//if selection is from beginning of the line then we want to use // comment, that's why the check for line count and ' ' and tab
if (doLineComment)
{
CursorTextPos = minPos;
InsertAtCursor("//"); //goes here if no selection
}
else
{
CursorTextPos = firstCharPos;
InsertAtCursor("/*");
CursorTextPos = lastCharPos + 2;
InsertAtCursor("*/");
}
mSelection = EditSelection(firstCharPos, lastCharPos + 4);
if (startTextPos <= minPos)
CursorLineAndColumn = startLineAndCol.Value;
else
CursorTextPos = startTextPos + 2;
startLineAndCol = null;
}
else
{
mSelection = prevSelection;
}
if (startLineAndCol != null)
CursorLineAndColumn = startLineAndCol.Value;
if (prevSelection == null)
mSelection = null;
ClampCursor();
FixSelection();
if (mSelection.HasValue)
{
// Placing cursor where it was before, meaning
// at the start or at the end of the selection.
mCursorTextPos = (cursorAtEndPos)
? (int32)mSelection.Value.mStartPos
: (int32)mSelection.Value.mEndPos
;
}
}
return true;
} }
return false; CloseMultiCursorUndoBatch();
SetPrimaryTextCursor();
return (didComment);
} }
public void DeleteAllRight() public void DeleteAllRight()
@ -3273,22 +3307,45 @@ namespace IDE.ui
if ((CheckReadOnly()) || (!mAllowVirtualCursor)) if ((CheckReadOnly()) || (!mAllowVirtualCursor))
return; return;
UndoBatchStart undoBatchStart = new UndoBatchStart("duplicateLine"); var lineText = scope String();
mData.mUndoManager.Add(undoBatchStart); var sortedCursors = mTextCursors;
if (mTextCursors.Count > 1)
sortedCursors = GetSortedCursors(.. scope :: List<TextCursor>());
mData.mUndoManager.Add(new SetCursorAction(this)); // Forcing creation of undo batch, because even single cursor has
// multiple undo-actions (SetCursorAction + InsertTextAction).
CreateMultiCursorUndoBatch("SEWC.DuplicateLine()", force: true);
var prevCursorLineAndColumn = CursorLineAndColumn; for (var cursor in sortedCursors.Reversed)
int lineNum = CursorLineAndColumn.mLine; {
GetLinePosition(lineNum, var lineStart, var lineEnd); SetTextCursor(cursor);
var str = scope String(); mData.mUndoManager.Add(new SetCursorAction(this));
GetLineText(lineNum, str);
mSelection = null;
CursorLineAndColumn = LineAndColumn(lineNum, 0);
PasteText(str, "line");
CursorLineAndColumn = LineAndColumn(prevCursorLineAndColumn.mLine + 1, prevCursorLineAndColumn.mColumn);
mData.mUndoManager.Add(undoBatchStart.mBatchEnd); var line = CursorLineAndColumn.mLine;
var column = CursorLineAndColumn.mColumn;
var prevCursorPos = mCursorTextPos;
lineText.Clear();
GetLineText(line, lineText);
mSelection = null;
CursorLineAndColumn = LineAndColumn(line+1, 0);
InsertAtCursor("\n");
CursorLineAndColumn = LineAndColumn(line+1, 0);
InsertAtCursor(lineText);
CursorLineAndColumn = LineAndColumn(line+1, column);
// Forcing calculation of CursorTextPos,
// if this cursor had one before.
if (prevCursorPos != -1)
var _ = CursorTextPos;
}
CloseMultiCursorUndoBatch();
SetPrimaryTextCursor();
EnsureCursorVisible();
} }
enum StatementRangeFlags enum StatementRangeFlags
@ -3529,6 +3586,7 @@ namespace IDE.ui
void MoveSelection(int toLinePos, bool isStatementAware) void MoveSelection(int toLinePos, bool isStatementAware)
{ {
RemoveSecondaryTextCursors();
/*if (GetStatementRange(CursorTextPos, var startIdx, var endIdx)) /*if (GetStatementRange(CursorTextPos, var startIdx, var endIdx))
{ {
mSelection = .(startIdx, endIdx); mSelection = .(startIdx, endIdx);
@ -3685,6 +3743,7 @@ namespace IDE.ui
public void MoveLine(VertDir dir) public void MoveLine(VertDir dir)
{ {
RemoveSecondaryTextCursors();
int lineNum = CursorLineAndColumn.mLine; int lineNum = CursorLineAndColumn.mLine;
if ((dir == .Up && lineNum < 1) || (dir == .Down && lineNum >= GetLineCount() - 1)) if ((dir == .Up && lineNum < 1) || (dir == .Down && lineNum >= GetLineCount() - 1))
@ -3713,6 +3772,7 @@ namespace IDE.ui
public void MoveStatement(VertDir dir) public void MoveStatement(VertDir dir)
{ {
RemoveSecondaryTextCursors();
int lineNum = CursorLineAndColumn.mLine; int lineNum = CursorLineAndColumn.mLine;
int origLineNum = lineNum; int origLineNum = lineNum;
GetLinePosition(lineNum, var lineStart, var lineEnd); GetLinePosition(lineNum, var lineStart, var lineEnd);
@ -3795,6 +3855,7 @@ namespace IDE.ui
void InsertCharPair(String charPair) void InsertCharPair(String charPair)
{ {
CreateMultiCursorUndoBatch("SEWC.InsertCharPair()");
base.InsertCharPair(charPair); base.InsertCharPair(charPair);
mCurParenPairIdSet.Add(mData.mNextCharId - 2); mCurParenPairIdSet.Add(mData.mNextCharId - 2);
} }
@ -3803,12 +3864,18 @@ namespace IDE.ui
{ {
scope AutoBeefPerf("SEWC.KeyChar"); scope AutoBeefPerf("SEWC.KeyChar");
if (IsPrimaryTextCursor())
mDidAutoComplete = false;
var keyChar; var keyChar;
if (mIgnoreKeyChar) if (mIgnoreKeyChar)
{ {
mIgnoreKeyChar = false; // Only flip the flag when we are processing last cursor
if (mTextCursors.Back.mId == mCurrentTextCursor.mId)
mIgnoreKeyChar = false;
return; return;
} }
@ -3825,6 +3892,10 @@ namespace IDE.ui
((keyChar == '\r') && (autoCompleteOnEnter))) && ((keyChar == '\r') && (autoCompleteOnEnter))) &&
(!mWidgetWindow.IsKeyDown(.Shift)); (!mWidgetWindow.IsKeyDown(.Shift));
// Skip completion-char for secondary cursors when AutoComplete just happened
if ((isCompletionChar) && (!IsPrimaryTextCursor()) && (mDidAutoComplete))
return;
if ((gApp.mSymbolReferenceHelper != null) && (gApp.mSymbolReferenceHelper.IsRenaming)) if ((gApp.mSymbolReferenceHelper != null) && (gApp.mSymbolReferenceHelper.IsRenaming))
{ {
if ((keyChar == '\r') || (keyChar == '\n')) if ((keyChar == '\r') || (keyChar == '\n'))
@ -3883,7 +3954,7 @@ namespace IDE.ui
} }
bool forceAutoCompleteInsert = false; bool forceAutoCompleteInsert = false;
if (isEndingChar) if ((IsPrimaryTextCursor()) && (isEndingChar))
{ {
bool forceAsyncFinish = false; bool forceAsyncFinish = false;
if (mCursorTextPos > 0) if (mCursorTextPos > 0)
@ -3927,11 +3998,11 @@ namespace IDE.ui
} }
else else
{ {
if ((doAutocomplete) && (mOnFinishAsyncAutocomplete != null)) if ((IsPrimaryTextCursor()) && (doAutocomplete) && (mOnFinishAsyncAutocomplete != null))
mOnFinishAsyncAutocomplete(); mOnFinishAsyncAutocomplete();
} }
if ((mAutoComplete != null) && (mAutoComplete.mAutoCompleteListWidget != null)) if ((IsPrimaryTextCursor()) && (mAutoComplete != null) && (mAutoComplete.mAutoCompleteListWidget != null))
{ {
if ((mAutoComplete.mInsertEndIdx != -1) && (mAutoComplete.mInsertEndIdx != mCursorTextPos) && (keyChar != '\t') && (keyChar != '\r') && (keyChar != '\n')) if ((mAutoComplete.mInsertEndIdx != -1) && (mAutoComplete.mInsertEndIdx != mCursorTextPos) && (keyChar != '\t') && (keyChar != '\r') && (keyChar != '\n'))
doAutocomplete = false; doAutocomplete = false;
@ -3965,6 +4036,8 @@ namespace IDE.ui
if (mOnFinishAsyncAutocomplete != null) if (mOnFinishAsyncAutocomplete != null)
mOnFinishAsyncAutocomplete(); mOnFinishAsyncAutocomplete();
mDidAutoComplete = true;
CreateMultiCursorUndoBatch("SEWC.KeyChar(autocomplete)");
UndoBatchStart undoBatchStart = new UndoBatchStart("autocomplete"); UndoBatchStart undoBatchStart = new UndoBatchStart("autocomplete");
mData.mUndoManager.Add(undoBatchStart); mData.mUndoManager.Add(undoBatchStart);
@ -4033,6 +4106,7 @@ namespace IDE.ui
if (((keyChar == '\n') || (keyChar == '\r')) && (!HasSelection()) && (mIsMultiline) && (!CheckReadOnly())) if (((keyChar == '\n') || (keyChar == '\r')) && (!HasSelection()) && (mIsMultiline) && (!CheckReadOnly()))
{ {
CreateMultiCursorUndoBatch("SEWC.KeyChar(\n||\r)");
UndoBatchStart undoBatchStart = new UndoBatchStart("newline"); UndoBatchStart undoBatchStart = new UndoBatchStart("newline");
mData.mUndoManager.Add(undoBatchStart); mData.mUndoManager.Add(undoBatchStart);
@ -4133,7 +4207,7 @@ namespace IDE.ui
} }
} }
if ((mAutoComplete != null) && (mAutoComplete.mInvokeWidget != null)) if ((IsPrimaryTextCursor()) && (mAutoComplete != null) && (mAutoComplete.mInvokeWidget != null))
{ {
// Update the position of the invoke widget // Update the position of the invoke widget
if (IsCursorVisible(false)) if (IsCursorVisible(false))
@ -4149,11 +4223,13 @@ namespace IDE.ui
} }
else else
{ {
if (mAutoComplete != null) if (IsPrimaryTextCursor() && mAutoComplete != null)
mAutoComplete.CloseListWindow(); mAutoComplete.CloseListWindow();
//shouldCloseAutoComplete = true;
} }
mAutoComplete?.UpdateAsyncInfo(); if (IsPrimaryTextCursor())
mAutoComplete?.UpdateAsyncInfo();
return; return;
} }
@ -4176,6 +4252,7 @@ namespace IDE.ui
(mData.mText[cursorTextPos - 1].mChar == '*') && (mData.mText[cursorTextPos - 1].mChar == '*') &&
(mData.mText[cursorTextPos].mChar == '\n')) (mData.mText[cursorTextPos].mChar == '\n'))
{ {
CreateMultiCursorUndoBatch("SEWC.KeyChar(comment)");
InsertAtCursor("*"); InsertAtCursor("*");
let prevLineAndColumn = mEditWidget.mEditWidgetContent.CursorLineAndColumn; let prevLineAndColumn = mEditWidget.mEditWidgetContent.CursorLineAndColumn;
int column = GetLineEndColumn(prevLineAndColumn.mLine, false, true, true); int column = GetLineEndColumn(prevLineAndColumn.mLine, false, true, true);
@ -4290,6 +4367,7 @@ namespace IDE.ui
} }
else if ((keyChar == '{') || (keyChar == '(')) else if ((keyChar == '{') || (keyChar == '('))
{ {
CreateMultiCursorUndoBatch("SEWC.KeyChar(blockSurround)");
UndoBatchStart undoBatchStart = new UndoBatchStart("blockSurround"); UndoBatchStart undoBatchStart = new UndoBatchStart("blockSurround");
mData.mUndoManager.Add(undoBatchStart); mData.mUndoManager.Add(undoBatchStart);
@ -4385,7 +4463,7 @@ namespace IDE.ui
mIsInKeyChar = false; mIsInKeyChar = false;
} }
if ((keyChar == '\b') || (keyChar == '\r') || (keyChar >= (char8)32)) if (IsPrimaryTextCursor() && ((keyChar == '\b') || (keyChar == '\r') || (keyChar >= (char8)32)))
{ {
bool isHighPri = (keyChar == '(') || (keyChar == '.'); bool isHighPri = (keyChar == '(') || (keyChar == '.');
bool needsFreshAutoComplete = ((isHighPri) /*|| (!mAsyncAutocomplete)*/ || (mAutoComplete == null) || (mAutoComplete.mAutoCompleteListWidget == null)); bool needsFreshAutoComplete = ((isHighPri) /*|| (!mAsyncAutocomplete)*/ || (mAutoComplete == null) || (mAutoComplete.mAutoCompleteListWidget == null));
@ -4414,7 +4492,7 @@ namespace IDE.ui
} }
else if (mData.mCurTextVersionId != startRevision) else if (mData.mCurTextVersionId != startRevision)
{ {
if (mAutoComplete != null) if (IsPrimaryTextCursor() && mAutoComplete != null)
mAutoComplete.CloseListWindow(); mAutoComplete.CloseListWindow();
} }
@ -4487,6 +4565,7 @@ namespace IDE.ui
mSelection.ValueRef.mStartPos = mSelection.Value.mEndPos - 1; mSelection.ValueRef.mStartPos = mSelection.Value.mEndPos - 1;
if (mSelection.Value.mStartPos > 0) if (mSelection.Value.mStartPos > 0)
{ {
CreateMultiCursorUndoBatch("SEWC.KeyChar(case)");
DeleteSelection(); DeleteSelection();
CursorToLineEnd(); CursorToLineEnd();
} }
@ -4509,6 +4588,7 @@ namespace IDE.ui
int32 columnPos = (int32)(GetTabbedWidth(tabStartStr, 0) / mCharWidth + 0.001f); int32 columnPos = (int32)(GetTabbedWidth(tabStartStr, 0) / mCharWidth + 0.001f);
if (wantLineColumn > columnPos) if (wantLineColumn > columnPos)
{ {
CreateMultiCursorUndoBatch("SEWC.KeyChar(else)");
String insertStr = scope String(' ', wantLineColumn - columnPos); String insertStr = scope String(' ', wantLineColumn - columnPos);
insertStr.Append("else"); insertStr.Append("else");
@ -4707,7 +4787,7 @@ namespace IDE.ui
int prevTextLength = mData.mTextLength; int prevTextLength = mData.mTextLength;
base.KeyDown(keyCode, isRepeat); base.KeyDown(keyCode, isRepeat);
if ((mAutoComplete != null) && if ((IsPrimaryTextCursor()) && (mAutoComplete != null) &&
(keyCode != .Control) && (keyCode != .Control) &&
(keyCode != .Shift)) (keyCode != .Shift))
{ {
@ -5020,6 +5100,7 @@ namespace IDE.ui
menuItem = menu.AddItem("Cut|Ctrl+X"); menuItem = menu.AddItem("Cut|Ctrl+X");
menuItem.mOnMenuItemSelected.Add(new (menu) => menuItem.mOnMenuItemSelected.Add(new (menu) =>
{ {
SetPrimaryTextCursor();
CutText(); CutText();
}); });
menuItem.SetDisabled(!hasSelection); menuItem.SetDisabled(!hasSelection);
@ -5034,6 +5115,7 @@ namespace IDE.ui
menuItem = menu.AddItem("Paste|Ctrl+V"); menuItem = menu.AddItem("Paste|Ctrl+V");
menuItem.mOnMenuItemSelected.Add(new (menu) => menuItem.mOnMenuItemSelected.Add(new (menu) =>
{ {
SetPrimaryTextCursor();
PasteText(); PasteText();
}); });

View file

@ -1323,7 +1323,7 @@ namespace IDE.ui
embedSource.mTypeName = new .(useTypeName); embedSource.mTypeName = new .(useTypeName);
if (embedHasFocus) if (embedHasFocus)
embedSource.mCursorIdx = (.)embedSourceViewPanel.mEditWidget.mEditWidgetContent.CursorTextPos; embedSource.mCursorIdx = (.)embedSourceViewPanel.mEditWidget.mEditWidgetContent.mTextCursors.Front.mCursorTextPos;
else else
embedSource.mCursorIdx = -1; embedSource.mCursorIdx = -1;
resolveParams.mEmitEmbeds.Add(embedSource); resolveParams.mEmitEmbeds.Add(embedSource);
@ -1385,7 +1385,7 @@ namespace IDE.ui
{ {
if ((useResolveType == .Autocomplete) || (useResolveType == .GetSymbolInfo) || (mIsClang)) if ((useResolveType == .Autocomplete) || (useResolveType == .GetSymbolInfo) || (mIsClang))
{ {
resolveParams.mOverrideCursorPos = (.)mEditWidget.Content.CursorTextPos; resolveParams.mOverrideCursorPos = (.)mEditWidget.Content.mTextCursors.Front.mCursorTextPos;
/*if (useResolveType == .Autocomplete) /*if (useResolveType == .Autocomplete)
resolveParams.mOverrideCursorPos--;*/ resolveParams.mOverrideCursorPos--;*/
} }
@ -2042,7 +2042,7 @@ namespace IDE.ui
ProjectSource projectSource = FilteredProjectSource; ProjectSource projectSource = FilteredProjectSource;
int cursorPos = mEditWidget.mEditWidgetContent.CursorTextPos; int cursorPos = mEditWidget.mEditWidgetContent.mTextCursors.Front.mCursorTextPos;
if ((resolveParams != null) && (resolveParams.mOverrideCursorPos != -1)) if ((resolveParams != null) && (resolveParams.mOverrideCursorPos != -1))
cursorPos = resolveParams.mOverrideCursorPos; cursorPos = resolveParams.mOverrideCursorPos;
@ -5254,7 +5254,10 @@ namespace IDE.ui
var sourceEditWidgetContent = (SourceEditWidgetContent)mEditWidget.Content; var sourceEditWidgetContent = (SourceEditWidgetContent)mEditWidget.Content;
if (!sourceEditWidgetContent.CheckReadOnly()) if (!sourceEditWidgetContent.CheckReadOnly())
{
sourceEditWidgetContent.RemoveSecondaryTextCursors();
ShowSymbolReferenceHelper(SymbolReferenceHelper.Kind.Rename); ShowSymbolReferenceHelper(SymbolReferenceHelper.Kind.Rename);
}
} }
public void FindAllReferences() public void FindAllReferences()