1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 19:48:20 +02:00

Formatting options

This commit is contained in:
Brian Fiete 2022-05-16 11:01:30 -07:00
parent c73cf12f5e
commit 67329ac774
9 changed files with 193 additions and 94 deletions

View file

@ -540,6 +540,7 @@ namespace Beefy.widgets
public EditWidget mEditWidget; public EditWidget mEditWidget;
public float mTabSize; public float mTabSize;
public bool mWantsTabsAsSpaces;
public float mCharWidth = -1; public float mCharWidth = -1;
public int32 mTabLength = 4; public int32 mTabLength = 4;
public uint8 mExtendDisplayFlags; public uint8 mExtendDisplayFlags;
@ -1267,7 +1268,9 @@ namespace Beefy.widgets
{ {
int prevTabCount = (int)((textX + 0.5f) / mTabSize); int prevTabCount = (int)((textX + 0.5f) / mTabSize);
int wantTabCount = (int)((cursorX + 0.5f) / mTabSize); int wantTabCount = (int)((cursorX + 0.5f) / mTabSize);
int wantAddTabs = wantTabCount - prevTabCount; int wantAddTabs = 0;
if (!mWantsTabsAsSpaces)
wantAddTabs = wantTabCount - prevTabCount;
if (wantAddTabs > 0) if (wantAddTabs > 0)
textX = wantTabCount * mTabSize + mTextInsets.mLeft; textX = wantTabCount * mTabSize + mTextInsets.mLeft;
@ -3209,6 +3212,14 @@ namespace Beefy.widgets
mEditWidget.UpdateScrollbars(); mEditWidget.UpdateScrollbars();
} }
protected void GetTabString(String str, int tabCount = 1)
{
if (mWantsTabsAsSpaces)
str.Append(' ', mTabLength * tabCount);
else
str.Append('\t', tabCount);
}
public void BlockIndentSelection(bool unIndent = false) public void BlockIndentSelection(bool unIndent = false)
{ {
if (CheckReadOnly()) if (CheckReadOnly())
@ -3270,15 +3281,30 @@ namespace Beefy.widgets
} }
else else
{ {
startAdjust++; if (mWantsTabsAsSpaces)
startAdjust += mTabLength;
else
startAdjust++;
for (int lineIdx = minLineIdx; lineIdx <= maxLineIdx; lineIdx++) for (int lineIdx = minLineIdx; lineIdx <= maxLineIdx; lineIdx++)
{ {
int lineStart; int lineStart;
int lineEnd; int lineEnd;
GetLinePosition(lineIdx, out lineStart, out lineEnd); GetLinePosition(lineIdx, out lineStart, out lineEnd);
lineStart += endAdjust; lineStart += endAdjust;
indentTextAction.mInsertCharList.Add(((int32)lineStart, '\t')); if (mWantsTabsAsSpaces)
endAdjust++; {
for (int i < mTabLength)
{
indentTextAction.mInsertCharList.Add(((int32)lineStart, ' '));
endAdjust++;
}
}
else
{
indentTextAction.mInsertCharList.Add(((int32)lineStart, '\t'));
endAdjust++;
}
} }
indentTextAction.Redo(); indentTextAction.Redo();
@ -3413,17 +3439,16 @@ namespace Beefy.widgets
let prevSelection = mSelection.Value; let prevSelection = mSelection.Value;
mSelection = null; mSelection = null;
for (int32 i = 0; i < indentCount; i++) for (int32 i = 0; i < indentCount; i++)
InsertAtCursor("\t"); InsertAtCursor(GetTabString(.. scope .()));
GetLinePosition(minLineIdx, out lineStart, out lineEnd); GetLinePosition(minLineIdx, out lineStart, out lineEnd);
mSelection = EditSelection(prevSelection.mStartPos + indentCount, prevSelection.mEndPos + indentCount); mSelection = EditSelection(prevSelection.mStartPos + indentCount, prevSelection.mEndPos + indentCount);
} }
else else
InsertAtCursor("\t"); InsertAtCursor(GetTabString(.. scope .()));
} }
else else
{ {
for (int32 i = 0; i < indentCount; i++) InsertAtCursor(GetTabString(.. scope .(), indentCount));
InsertAtCursor("\t");
} }
} }
} }

View file

@ -145,7 +145,8 @@ namespace IDE.Compiler
static extern bool BfParser_Reduce(void* bfParser, void* bfPassInstance); static extern bool BfParser_Reduce(void* bfParser, void* bfPassInstance);
[CallingConvention(.Stdcall), CLink] [CallingConvention(.Stdcall), CLink]
static extern char8* BfParser_Format(void* bfParser, int32 formatEnd, int32 formatStart, out int32* outCharMapping, int32 maxCol); static extern char8* BfParser_Format(void* bfParser, int32 formatEnd, int32 formatStart, out int32* outCharMapping, int32 maxCol, int32 tabSize, bool wantsTabsAsSpaces,
bool indentCaseLabels);
[CallingConvention(.Stdcall), CLink] [CallingConvention(.Stdcall), CLink]
static extern char8* BfParser_GetDebugExpressionAt(void* bfParser, int32 cursorIdx); static extern char8* BfParser_GetDebugExpressionAt(void* bfParser, int32 cursorIdx);
@ -244,7 +245,8 @@ namespace IDE.Compiler
{ {
int32* charMappingPtr; int32* charMappingPtr;
var maxCol = gApp.mSettings.mEditorSettings.mWrapCommentsAt; var maxCol = gApp.mSettings.mEditorSettings.mWrapCommentsAt;
var stringPtr = BfParser_Format(mNativeBfParser, (int32)formatStart, (int32)formatEnd, out charMappingPtr, maxCol); var stringPtr = BfParser_Format(mNativeBfParser, (int32)formatStart, (int32)formatEnd, out charMappingPtr, maxCol,
gApp.mSettings.mEditorSettings.mTabSize, gApp.mSettings.mEditorSettings.mTabsOrSpaces == .Spaces, gApp.mSettings.mEditorSettings.mIndentCaseLabels);
str.Append(stringPtr); str.Append(stringPtr);
charMapping = new int32[str.Length]; charMapping = new int32[str.Length];

View file

@ -622,6 +622,12 @@ namespace IDE
BackupOnly BackupOnly
} }
public enum TabsOrSpaces
{
Tabs,
Spaces
}
public List<String> mFonts = new .() ~ DeleteContainerAndItems!(_); public List<String> mFonts = new .() ~ DeleteContainerAndItems!(_);
public float mFontSize = 12; public float mFontSize = 12;
public AutoCompleteShowKind mAutoCompleteShowKind = .PanelIfVisible; public AutoCompleteShowKind mAutoCompleteShowKind = .PanelIfVisible;
@ -641,9 +647,13 @@ namespace IDE
public bool mShowLineNumbers = true; public bool mShowLineNumbers = true;
public bool mFreeCursorMovement; public bool mFreeCursorMovement;
public FileRecoveryKind mEnableFileRecovery = .Yes; public FileRecoveryKind mEnableFileRecovery = .Yes;
public bool mFormatOnSave = false;
public bool mSyncWithWorkspacePanel = false; public bool mSyncWithWorkspacePanel = false;
public int32 mWrapCommentsAt = 0; public int32 mWrapCommentsAt = 0;
public bool mFormatOnSave = false;
public bool mIndentCaseLabels = false;
public bool mLeftAlignPreprocessor = true;
public TabsOrSpaces mTabsOrSpaces = .Tabs;
public int32 mTabSize = 4;
public void Serialize(StructuredData sd) public void Serialize(StructuredData sd)
{ {
@ -669,9 +679,13 @@ namespace IDE
sd.Add("ShowLineNumbers", mShowLineNumbers); sd.Add("ShowLineNumbers", mShowLineNumbers);
sd.Add("FreeCursorMovement", mFreeCursorMovement); sd.Add("FreeCursorMovement", mFreeCursorMovement);
sd.Add("EnableFileRecovery", mEnableFileRecovery); sd.Add("EnableFileRecovery", mEnableFileRecovery);
sd.Add("FormatOnSave", mFormatOnSave);
sd.Add("SyncWithWorkspacePanel", mSyncWithWorkspacePanel); sd.Add("SyncWithWorkspacePanel", mSyncWithWorkspacePanel);
sd.Add("WrapCommentsAt", mWrapCommentsAt); sd.Add("WrapCommentsAt", mWrapCommentsAt);
sd.Add("FormatOnSave", mFormatOnSave);
sd.Add("TabsOrSpaces", mTabsOrSpaces);
sd.Add("TabSize", mTabSize);
sd.Add("IndentCaseLabels", mIndentCaseLabels);
sd.Add("LeftAlignPreprocessor", mLeftAlignPreprocessor);
} }
public void Deserialize(StructuredData sd) public void Deserialize(StructuredData sd)
@ -701,9 +715,13 @@ namespace IDE
sd.Get("ShowLineNumbers", ref mShowLineNumbers); sd.Get("ShowLineNumbers", ref mShowLineNumbers);
sd.Get("FreeCursorMovement", ref mFreeCursorMovement); sd.Get("FreeCursorMovement", ref mFreeCursorMovement);
sd.GetEnum<FileRecoveryKind>("EnableFileRecovery", ref mEnableFileRecovery); sd.GetEnum<FileRecoveryKind>("EnableFileRecovery", ref mEnableFileRecovery);
sd.Get("FormatOnSave", ref mFormatOnSave);
sd.Get("SyncWithWorkspacePanel", ref mSyncWithWorkspacePanel); sd.Get("SyncWithWorkspacePanel", ref mSyncWithWorkspacePanel);
sd.Get("WrapCommentsAt", ref mWrapCommentsAt); sd.Get("WrapCommentsAt", ref mWrapCommentsAt);
sd.Get("FormatOnSave", ref mFormatOnSave);
sd.Get("TabsOrSpaces", ref mTabsOrSpaces);
sd.Get("TabSize", ref mTabSize);
sd.Get("IndentCaseLabels", ref mIndentCaseLabels);
sd.Get("LeftAlignPreprocessor", ref mLeftAlignPreprocessor);
} }
public void SetDefaults() public void SetDefaults()
@ -717,6 +735,8 @@ namespace IDE
public void Apply() public void Apply()
{ {
mTabSize = Math.Clamp(mTabSize, 1, 16);
if (mSpellCheckEnabled) if (mSpellCheckEnabled)
{ {
if (gApp.mSpellChecker == null) if (gApp.mSpellChecker == null)
@ -1197,6 +1217,7 @@ namespace IDE
gApp.mSettings.mEditorSettings.mFontSize = Math.Clamp(gApp.mSettings.mEditorSettings.mFontSize, 6.0f, 72.0f); gApp.mSettings.mEditorSettings.mFontSize = Math.Clamp(gApp.mSettings.mEditorSettings.mFontSize, 6.0f, 72.0f);
mUISettings.Apply(); mUISettings.Apply();
mEditorSettings.Apply();
Font.ClearFontNameCache(); Font.ClearFontNameCache();
gApp.PhysSetScale(gApp.mSettings.mUISettings.mScale / 100.0f, true); gApp.PhysSetScale(gApp.mSettings.mUISettings.mScale / 100.0f, true);
@ -1205,7 +1226,7 @@ namespace IDE
mKeySettings.Apply(); mKeySettings.Apply();
mDebuggerSettings.Apply(); mDebuggerSettings.Apply();
mEditorSettings.Apply();
for (var window in gApp.mWindows) for (var window in gApp.mWindows)
{ {

View file

@ -128,10 +128,18 @@ namespace IDE.ui
AddPropertiesItem(category, "Show Line Numbers", "mShowLineNumbers"); AddPropertiesItem(category, "Show Line Numbers", "mShowLineNumbers");
AddPropertiesItem(category, "Free Cursor Movement", "mFreeCursorMovement"); AddPropertiesItem(category, "Free Cursor Movement", "mFreeCursorMovement");
AddPropertiesItem(category, "Enable File Recovery", "mEnableFileRecovery"); AddPropertiesItem(category, "Enable File Recovery", "mEnableFileRecovery");
AddPropertiesItem(category, "Format on Save", "mFormatOnSave");
AddPropertiesItem(category, "Sync with Workspace Panel", "mSyncWithWorkspacePanel"); AddPropertiesItem(category, "Sync with Workspace Panel", "mSyncWithWorkspacePanel");
AddPropertiesItem(category, "Wrap Comments at Column", "mWrapCommentsAt"); category.Open(true, true);
(category, propEntry) = AddPropertiesItem(root, "Formatting");
category.mIsBold = true;
category.mTextColor = Color.Mult(DarkTheme.COLOR_TEXT, cHeaderColor);
AddPropertiesItem(category, "Format on Save", "mFormatOnSave");
AddPropertiesItem(category, "Tabs or Spaces", "mTabsOrSpaces");
AddPropertiesItem(category, "Tab Size", "mTabSize");
AddPropertiesItem(category, "Wrap Comments at Column", "mWrapCommentsAt");
AddPropertiesItem(category, "Indent Case Labels", "mIndentCaseLabels");
AddPropertiesItem(category, "Left Align Preprocessor", "mLeftAlignPreprocessor");
category.Open(true, true); category.Open(true, true);
} }

View file

@ -779,7 +779,9 @@ namespace IDE.ui
SetFont(IDEApp.sApp.mCodeFont, true, true); SetFont(IDEApp.sApp.mCodeFont, true, true);
//SetFont(DarkTheme.sDarkTheme.mSmallFont, false, false); //SetFont(DarkTheme.sDarkTheme.mSmallFont, false, false);
mTabSize = mFont.GetWidth(" "); mWantsTabsAsSpaces = gApp.mSettings.mEditorSettings.mTabsOrSpaces == .Spaces;
mTabLength = gApp.mSettings.mEditorSettings.mTabSize;
mTabSize = mFont.GetWidth(scope String(' ', gApp.mSettings.mEditorSettings.mTabSize));
mTextColors = sTextColors; mTextColors = sTextColors;
mExtendDisplayFlags = (uint8)(SourceElementFlags.SpellingError | SourceElementFlags.SymbolReference); mExtendDisplayFlags = (uint8)(SourceElementFlags.SpellingError | SourceElementFlags.SymbolReference);
mShowLineBottomPadding = 2; mShowLineBottomPadding = 2;
@ -793,7 +795,9 @@ namespace IDE.ui
public override void RehupScale(float oldScale, float newScale) public override void RehupScale(float oldScale, float newScale)
{ {
base.RehupScale(oldScale, newScale); base.RehupScale(oldScale, newScale);
mTabSize = mFont.GetWidth(" "); mWantsTabsAsSpaces = gApp.mSettings.mEditorSettings.mTabsOrSpaces == .Spaces;
mTabLength = gApp.mSettings.mEditorSettings.mTabSize;
mTabSize = mFont.GetWidth(scope String(' ', gApp.mSettings.mEditorSettings.mTabSize));
} }
protected override EditWidgetContent.Data CreateEditData() protected override EditWidgetContent.Data CreateEditData()
@ -1244,7 +1248,7 @@ namespace IDE.ui
else if (c == ' ') else if (c == ' ')
blockOpenSpaceCount++; blockOpenSpaceCount++;
else if (c == '\t') else if (c == '\t')
blockOpenSpaceCount += 4; // SpacesInTab blockOpenSpaceCount += gApp.mSettings.mEditorSettings.mTabSize; // SpacesInTab
else else
{ {
blockOpenSpaceCount = 0; blockOpenSpaceCount = 0;
@ -1332,7 +1336,7 @@ namespace IDE.ui
return spaceCount; return spaceCount;
} }
public int GetLineEndColumn(int line, bool openingBlock, bool force, bool ignoreLineText = false, bool insertingElseStmt = false, float* outWidth = null) public int GetLineEndColumn(int line, bool openingBlock, bool force, bool ignoreLineText = false, bool insertingElseStmt = false, bool ignoreCaseExpr = false, float* outWidth = null)
{ {
String curLineStr = scope String(); String curLineStr = scope String();
GetLineText(line, curLineStr); GetLineText(line, curLineStr);
@ -1404,6 +1408,8 @@ namespace IDE.ui
List<int32> ifCtlDepthStack = scope List<int32>(); List<int32> ifCtlDepthStack = scope List<int32>();
bool keepBlockIndented = false; bool keepBlockIndented = false;
bool inSwitchCaseBlock = false;
bool mayBeDefaultCase = false;
for (int checkIdx = foundBlockStartIdx + 1; checkIdx < endingPos; checkIdx++) for (int checkIdx = foundBlockStartIdx + 1; checkIdx < endingPos; checkIdx++)
{ {
char8 c = mData.mText[checkIdx].mChar; char8 c = mData.mText[checkIdx].mChar;
@ -1427,6 +1433,14 @@ namespace IDE.ui
skippingLine = true; skippingLine = true;
} }
if (mayBeDefaultCase)
{
if (c == ':')
inSwitchCaseBlock = true;
else if (!isWhitespace)
mayBeDefaultCase = false;
}
if ((inCaseExpr) && (c == ':') && (elementType == .Normal) && (parenDepth == 0)) if ((inCaseExpr) && (c == ':') && (elementType == .Normal) && (parenDepth == 0))
{ {
inCaseExpr = false; inCaseExpr = false;
@ -1499,9 +1513,12 @@ namespace IDE.ui
case "case": case "case":
if (parenDepth == 0) if (parenDepth == 0)
{ {
caseStartPos = checkIdx - 4; caseStartPos = checkIdx - gApp.mSettings.mEditorSettings.mTabSize;
inCaseExpr = true; inCaseExpr = true;
inSwitchCaseBlock = true;
} }
case "default":
mayBeDefaultCase = true;
case "switch": case "switch":
ifDepth = 0; ifDepth = 0;
} }
@ -1725,9 +1742,12 @@ namespace IDE.ui
if ((openingBlock) && (!keepBlockIndented) && (parenDepth == 0)) if ((openingBlock) && (!keepBlockIndented) && (parenDepth == 0))
extraTab = Math.Max(1, extraTab - 1); extraTab = Math.Max(1, extraTab - 1);
if ((inSwitchCaseBlock) && (!ignoreCaseExpr) && (gApp.mSettings.mEditorSettings.mIndentCaseLabels))
extraTab++;
int wantSpaceCount = blockOpenSpaceCount; int wantSpaceCount = blockOpenSpaceCount;
//if (!openingBlock) //if (!openingBlock)
wantSpaceCount += extraTab * 4; wantSpaceCount += extraTab * gApp.mSettings.mEditorSettings.mTabSize;
if (inCaseExprNextLine) if (inCaseExprNextLine)
wantSpaceCount++; wantSpaceCount++;
@ -1890,7 +1910,7 @@ namespace IDE.ui
int alignColumn = GetLineEndColumn(lineAndColumn.mLine, isBlock, true, true); int alignColumn = GetLineEndColumn(lineAndColumn.mLine, isBlock, true, true);
String linePrefix = scope String('\t', alignColumn / tabSpaceCount); String linePrefix = GetTabString(.. scope String(), alignColumn / tabSpaceCount);
CursorLineAndColumn = LineAndColumn(lineAndColumn.mLine, alignColumn); CursorLineAndColumn = LineAndColumn(lineAndColumn.mLine, alignColumn);
bool isFullSwitch = false; bool isFullSwitch = false;
@ -2080,7 +2100,7 @@ namespace IDE.ui
float x; float x;
float y; float y;
float wantWidth = 0; float wantWidth = 0;
int column = GetLineEndColumn(line, false, false, false, false, &wantWidth); int column = GetLineEndColumn(line, false, false, false, false, false, &wantWidth);
GetTextCoordAtLineAndColumn(line, column, out x, out y); GetTextCoordAtLineAndColumn(line, column, out x, out y);
if (wantWidth != 0) if (wantWidth != 0)
x = wantWidth + mTextInsets.mLeft; x = wantWidth + mTextInsets.mLeft;
@ -2285,7 +2305,7 @@ namespace IDE.ui
} }
} }
int indentCount = GetLineEndColumn(minLineIdx, true, true, true) / 4; int indentCount = GetLineEndColumn(minLineIdx, true, true, true) / gApp.mSettings.mEditorSettings.mTabSize;
bool wantsContentTab = indentCount == selectedIndentCount; bool wantsContentTab = indentCount == selectedIndentCount;
/*if (mAllowVirtualCursor) /*if (mAllowVirtualCursor)
@ -2339,25 +2359,39 @@ namespace IDE.ui
lineStart += endAdjust; lineStart += endAdjust;
lineEnd += endAdjust; lineEnd += endAdjust;
} }
String tabStr = scope .();
GetTabString(tabStr);
int32 i = 0;
void AddTab()
{
InsertText(lineStart + i, tabStr);
for (var c in tabStr.RawChars)
{
indentTextAction.mInsertCharList.Add(((int32)(lineStart + i), c));
endAdjust++;
i++;
}
}
if (lineIdx == minLineIdx) if (lineIdx == minLineIdx)
{ {
int32 i; for (int indentIdx < indentCount)
for (i = 0; i < indentCount; i++)
{ {
InsertText(lineStart + i, "\t"); AddTab();
indentTextAction.mInsertCharList.Add(((int32)(lineStart + i), '\t'));
endAdjust++;
} }
newSel.mStartPos = (int32)(lineStart + i); newSel.mStartPos = (int32)(lineStart + i);
if (wantsContentTab) if (wantsContentTab)
{ {
InsertText(lineStart + i, "{\n\t"); InsertText(lineStart + i, "{\n");
indentTextAction.mInsertCharList.Add(((int32)(lineStart + i), '{')); indentTextAction.mInsertCharList.Add(((int32)(lineStart + i), '{'));
indentTextAction.mInsertCharList.Add(((int32)(lineStart + i + 1), '\n')); indentTextAction.mInsertCharList.Add(((int32)(lineStart + i + 1), '\n'));
indentTextAction.mInsertCharList.Add(((int32)(lineStart + i + 2), '\t')); i += 2;
endAdjust += 3; endAdjust += 2;
AddTab();
} }
else else
{ {
@ -2381,12 +2415,10 @@ namespace IDE.ui
lineStart++; lineStart++;
} }
int32 i; for (int indentIdx < indentCount)
for (i = 0; i < indentCount; i++) {
{ AddTab();
InsertText(lineStart + i, "\t"); }
indentTextAction.mInsertCharList.Add(((int32)(lineStart + i), '\t'));
}
if (isEmbeddedEnd) if (isEmbeddedEnd)
{ {
@ -2409,9 +2441,7 @@ namespace IDE.ui
char8 c = mData.mText[lineStart].mChar; char8 c = mData.mText[lineStart].mChar;
if (c != '#') if (c != '#')
{ {
InsertText(lineStart, "\t"); AddTab();
indentTextAction.mInsertCharList.Add(((int32)(lineStart), '\t'));
endAdjust++;
} }
} }
} }
@ -2465,7 +2495,7 @@ namespace IDE.ui
int column = GetLineEndColumn(lineIdx, true, false, true); int column = GetLineEndColumn(lineIdx, true, false, true);
// If we're aligned with the previous line then do the 'block indent' logic, otherwise are are already indented // If we're aligned with the previous line then do the 'block indent' logic, otherwise are are already indented
if (indentCount == column / 4) if (indentCount == column / gApp.mSettings.mEditorSettings.mTabSize)
{ {
bool isExpr = false; bool isExpr = false;
bool mayBeExpr = false; bool mayBeExpr = false;
@ -2542,12 +2572,12 @@ namespace IDE.ui
if (isExpr) if (isExpr)
{ {
// Lambda opening or initializer expression // Lambda opening or initializer expression
column += 4; column += gApp.mSettings.mEditorSettings.mTabSize;
} }
} }
CursorLineAndColumn = LineAndColumn(lineIdx, column); CursorLineAndColumn = LineAndColumn(lineIdx, column);
indentCount = column / 4; indentCount = column / gApp.mSettings.mEditorSettings.mTabSize;
} }
if (lineIdx < GetLineCount() - 1) if (lineIdx < GetLineCount() - 1)
@ -2559,13 +2589,13 @@ namespace IDE.ui
for (int32 i = 0; i < nextLineText.Length; i++) for (int32 i = 0; i < nextLineText.Length; i++)
{ {
if (nextLineText[i] == '\t') if (nextLineText[i] == '\t')
spaceCount += 4; spaceCount += gApp.mSettings.mEditorSettings.mTabSize;
else if (nextLineText[i] == ' ') else if (nextLineText[i] == ' ')
spaceCount++; spaceCount++;
else else
break; break;
} }
if (spaceCount > indentCount * 4) if (spaceCount > indentCount * gApp.mSettings.mEditorSettings.mTabSize)
{ {
// Next line is indented? Just simple open // Next line is indented? Just simple open
InsertAtCursor("{"); InsertAtCursor("{");
@ -2581,15 +2611,14 @@ namespace IDE.ui
if ((lineText.Length > 0) && (String.IsNullOrWhiteSpace(lineText))) if ((lineText.Length > 0) && (String.IsNullOrWhiteSpace(lineText)))
{ {
ClearLine(); ClearLine();
CursorLineAndColumn = LineAndColumn(lineIdx, indentCount * 4); CursorLineAndColumn = LineAndColumn(lineIdx, indentCount * gApp.mSettings.mEditorSettings.mTabSize);
} }
// This will already insert at correct position // This will already insert at correct position
InsertAtCursor("{"); InsertAtCursor("{");
sb.Append("\n"); sb.Append("\n");
sb.Append("\n"); sb.Append("\n");
for (int32 i = 0; i < indentCount; i++) GetTabString(sb, indentCount);
sb.Append("\t");
sb.Append("}"); sb.Append("}");
InsertAtCursor(sb); InsertAtCursor(sb);
} }
@ -2607,11 +2636,9 @@ namespace IDE.ui
for (int i = lineText.Length; i < indentCount; i++) for (int i = lineText.Length; i < indentCount; i++)
sb.Append("\t"); sb.Append("\t");
sb.Append("{\n"); sb.Append("{\n");
for (int i = 0; i < indentCount; i++) GetTabString(sb, indentCount);
sb.Append("\t");
sb.Append("\t\n"); sb.Append("\t\n");
for (int i = 0; i < indentCount; i++) GetTabString(sb, indentCount);
sb.Append("\t");
sb.Append("}"); sb.Append("}");
InsertAtCursor(sb); InsertAtCursor(sb);
} }
@ -2771,7 +2798,7 @@ namespace IDE.ui
InsertAtCursor("*/"); InsertAtCursor("*/");
if (doComment != null) if (doComment != null)
mSelection = EditSelection(firstCharPos, lastCharPos + 4); mSelection = EditSelection(firstCharPos, lastCharPos + gApp.mSettings.mEditorSettings.mTabSize);
} }
if (undoBatchStart != null) if (undoBatchStart != null)
@ -2877,7 +2904,7 @@ namespace IDE.ui
continue; continue;
} }
if (c == '\t') if (c == '\t')
lineStartCol += 4; lineStartCol += gApp.mSettings.mEditorSettings.mTabSize;
else if (c == ' ') else if (c == ' ')
lineStartCol++; lineStartCol++;
else else
@ -2911,7 +2938,7 @@ namespace IDE.ui
commentNow = true; commentNow = true;
if (c == '\t') if (c == '\t')
lineStartCol += 4; lineStartCol += gApp.mSettings.mEditorSettings.mTabSize;
else if (c == ' ') else if (c == ' ')
lineStartCol++; lineStartCol++;
else else
@ -2921,9 +2948,9 @@ namespace IDE.ui
{ {
CursorTextPos = i; CursorTextPos = i;
String str = scope .(); String str = scope .();
while (lineStartCol + 4 <= wantLineCol) while (lineStartCol + gApp.mSettings.mEditorSettings.mTabSize <= wantLineCol)
{ {
lineStartCol += 4; lineStartCol += gApp.mSettings.mEditorSettings.mTabSize;
str.Append("\t"); str.Append("\t");
} }
str.Append("//"); str.Append("//");
@ -3927,13 +3954,13 @@ namespace IDE.ui
int column = GetLineEndColumn(line, isBlockOpen, true, true); int column = GetLineEndColumn(line, isBlockOpen, true, true);
if (lineTextAtCursor.StartsWith("}")) if (lineTextAtCursor.StartsWith("}"))
{ {
column -= 4; // SpacesInTab column -= gApp.mSettings.mEditorSettings.mTabSize; // SpacesInTab
} }
if (column > 0) if (column > 0)
{ {
String tabStr = scope String(); String tabStr = scope String();
tabStr.Append('\t', column / 4); tabStr.Append('\t', column / gApp.mSettings.mEditorSettings.mTabSize);
tabStr.Append(' ', column % 4); tabStr.Append(' ', column % gApp.mSettings.mEditorSettings.mTabSize);
InsertAtCursor(tabStr); InsertAtCursor(tabStr);
} }
@ -4076,7 +4103,7 @@ namespace IDE.ui
int closeLineChar; int closeLineChar;
GetLineCharAtIdx(checkPos, out closeLine, out closeLineChar); GetLineCharAtIdx(checkPos, out closeLine, out closeLineChar);
int expectedColumn = GetLineEndColumn(closeLine, true, true, true) - 4; int expectedColumn = GetLineEndColumn(closeLine, true, true, true) - gApp.mSettings.mEditorSettings.mTabSize;
int actualColumn = GetActualLineStartColumn(closeLine); int actualColumn = GetActualLineStartColumn(closeLine);
if (expectedColumn == actualColumn) if (expectedColumn == actualColumn)
@ -4145,7 +4172,7 @@ namespace IDE.ui
String lineText = scope String(); String lineText = scope String();
GetLineText(line, lineText); GetLineText(line, lineText);
lineText.Trim(); lineText.Trim();
if ((lineText.Length == 0) && (mAllowVirtualCursor)) if ((lineText.Length == 0) && (mAllowVirtualCursor) && (gApp.mSettings.mEditorSettings.mLeftAlignPreprocessor))
CursorLineAndColumn = LineAndColumn(line, 0); CursorLineAndColumn = LineAndColumn(line, 0);
doChar = true; doChar = true;
} }
@ -4162,7 +4189,7 @@ namespace IDE.ui
if (lineText.Length == 0) if (lineText.Length == 0)
{ {
ClearLine(); ClearLine();
CursorLineAndColumn = LineAndColumn(line, Math.Max(0, GetLineEndColumn(line, false, false) - 4)); CursorLineAndColumn = LineAndColumn(line, Math.Max(0, GetLineEndColumn(line, false, false) - gApp.mSettings.mEditorSettings.mTabSize));
CursorMoved(); CursorMoved();
} }
base.KeyChar(keyChar); base.KeyChar(keyChar);
@ -4282,7 +4309,11 @@ namespace IDE.ui
if ((isLabel) && (trimmedLineText != "default:")) if ((isLabel) && (trimmedLineText != "default:"))
wantLineColumn = GetLineEndColumn(line, true, true, true); wantLineColumn = GetLineEndColumn(line, true, true, true);
else else
wantLineColumn = GetLineEndColumn(line, false, true, true) - 4; {
wantLineColumn = GetLineEndColumn(line, false, true, true, false, true);
if (!gApp.mSettings.mEditorSettings.mIndentCaseLabels)
wantLineColumn -= gApp.mSettings.mEditorSettings.mTabSize;
}
} }
// Move "case" back to be inline with switch statement // Move "case" back to be inline with switch statement
@ -4291,7 +4322,7 @@ namespace IDE.ui
String tabStartStr = scope String(); String tabStartStr = scope String();
tabStartStr.Append(lineText, 0, lineChar - trimmedLineText.Length); tabStartStr.Append(lineText, 0, lineChar - trimmedLineText.Length);
int32 columnPos = (int32)(GetTabbedWidth(tabStartStr, 0) / mCharWidth + 0.001f); int32 columnPos = (int32)(GetTabbedWidth(tabStartStr, 0) / mCharWidth + 0.001f);
if (columnPos >= wantLineColumn + 4) if (columnPos >= wantLineColumn + gApp.mSettings.mEditorSettings.mTabSize)
{ {
mSelection = EditSelection(); mSelection = EditSelection();
mSelection.ValueRef.mEndPos = (int32)(cursorTextIdx - trimmedLineText.Length); mSelection.ValueRef.mEndPos = (int32)(cursorTextIdx - trimmedLineText.Length);
@ -5193,7 +5224,7 @@ namespace IDE.ui
GetCursorLineChar(out line, out lineChar); GetCursorLineChar(out line, out lineChar);
float wantWidth = 0; float wantWidth = 0;
int virtualEnd = GetLineEndColumn(line, false, false, false, false, &wantWidth); int virtualEnd = GetLineEndColumn(line, false, false, false, false, false, &wantWidth);
String curLineStr = scope String(); String curLineStr = scope String();
GetLineText(line, curLineStr); GetLineText(line, curLineStr);

View file

@ -6873,7 +6873,8 @@ namespace IDE.ui
{ {
int idx = embedEWC.GetTextIdx(mQueuedEmitShowData.mLine, mQueuedEmitShowData.mColumn); int idx = embedEWC.GetTextIdx(mQueuedEmitShowData.mLine, mQueuedEmitShowData.mColumn);
emitEmbed.mView.mSourceViewPanel.FocusEdit(); emitEmbed.mView.mSourceViewPanel.FocusEdit();
emitEmbed.mView.mSourceViewPanel.ShowFileLocation(idx, .Always); if (idx >= 0)
emitEmbed.mView.mSourceViewPanel.ShowFileLocation(idx, .Always);
DeleteAndNullify!(mQueuedEmitShowData); DeleteAndNullify!(mQueuedEmitShowData);
} }
} }

View file

@ -3940,7 +3940,8 @@ BF_EXPORT bool BF_CALLTYPE BfParser_Reduce(BfParser* bfParser, BfPassInstance* b
} }
static Array<int> gCharMapping; static Array<int> gCharMapping;
BF_EXPORT const char* BF_CALLTYPE BfParser_Format(BfParser* bfParser, int formatStart, int formatEnd, int** outCharMapping, int maxCol) BF_EXPORT const char* BF_CALLTYPE BfParser_Format(BfParser* bfParser, int formatStart, int formatEnd, int** outCharMapping, int maxCol, int tabSize, bool wantsTabsAsSpaces,
bool indentCaseLabels)
{ {
BP_ZONE("BfParser_Reduce"); BP_ZONE("BfParser_Reduce");
String& outString = *gTLStrReturn.Get(); String& outString = *gTLStrReturn.Get();
@ -3948,6 +3949,9 @@ BF_EXPORT const char* BF_CALLTYPE BfParser_Format(BfParser* bfParser, int format
gCharMapping.Clear(); gCharMapping.Clear();
BfPrinter bfPrinter(bfParser->mRootNode, bfParser->mSidechannelRootNode, bfParser->mErrorRootNode); BfPrinter bfPrinter(bfParser->mRootNode, bfParser->mSidechannelRootNode, bfParser->mErrorRootNode);
bfPrinter.mMaxCol = maxCol; bfPrinter.mMaxCol = maxCol;
bfPrinter.mTabSize = tabSize;
bfPrinter.mWantsTabsAsSpaces = wantsTabsAsSpaces;
bfPrinter.mIndentCaseLabels = indentCaseLabels;
bfPrinter.mFormatStart = formatStart; bfPrinter.mFormatStart = formatStart;
bfPrinter.mFormatEnd = formatEnd; bfPrinter.mFormatEnd = formatEnd;
bfPrinter.mCharMapping = &gCharMapping; bfPrinter.mCharMapping = &gCharMapping;

View file

@ -45,6 +45,9 @@ BfPrinter::BfPrinter(BfRootNode *rootNode, BfRootNode *sidechannelRootNode, BfRo
mCurTypeDecl = NULL; mCurTypeDecl = NULL;
mCurCol = 0; mCurCol = 0;
mMaxCol = 120; mMaxCol = 120;
mTabSize = 4;
mWantsTabsAsSpaces = false;
mIndentCaseLabels = false;
} }
void BfPrinter::Write(const StringView& str) void BfPrinter::Write(const StringView& str)
@ -59,7 +62,7 @@ void BfPrinter::Write(const StringView& str)
{ {
char c = str[i]; char c = str[i];
if (c == '\t') if (c == '\t')
mCurCol = ((mCurCol + 1) & ~3) + 4; mCurCol = ((mCurCol / mTabSize) + 1) * mTabSize;
else else
mCurCol++; mCurCol++;
} }
@ -114,10 +117,10 @@ void BfPrinter::Write(const StringView& str)
void BfPrinter::FlushIndent() void BfPrinter::FlushIndent()
{ {
while (mQueuedSpaceCount >= 4) while ((mQueuedSpaceCount >= mTabSize) && (!mWantsTabsAsSpaces))
{ {
Write("\t"); Write("\t");
mQueuedSpaceCount -= 4; mQueuedSpaceCount -= mTabSize;
} }
while (mQueuedSpaceCount > 0) while (mQueuedSpaceCount > 0)
@ -141,15 +144,10 @@ void BfPrinter::Write(BfAstNode* node, int start, int len)
{ {
char c = parserData->mSrc[start + i]; char c = parserData->mSrc[start + i];
if (c == '\t') if (c == '\t')
mCurCol = ((mCurCol + 1) & ~3) + 4; mCurCol = ((mCurCol / mTabSize) + 1) * mTabSize;
else else
mCurCol++; mCurCol++;
} }
if ((mCurCol > mMaxCol) && (startCol != 0))
{
NOP;
}
} }
mOutString.Append(node->GetSourceData()->mSrc + start, len); mOutString.Append(node->GetSourceData()->mSrc + start, len);
@ -287,7 +285,7 @@ int BfPrinter::CalcOrigLineSpacing(BfAstNode* bfAstNode, int* lineStartIdx)
if (c == '\n') if (c == '\n')
break; break;
if (c == '\t') if (c == '\t')
origLineSpacing += 4; origLineSpacing += mTabSize;
else if (c == ' ') else if (c == ' ')
origLineSpacing += 1; origLineSpacing += 1;
else else
@ -539,7 +537,7 @@ void BfPrinter::WriteIgnoredNode(BfAstNode* node)
} }
else if (c == '\t') else if (c == '\t')
{ {
mQueuedSpaceCount += 4; mQueuedSpaceCount += mTabSize;
emitChar = false; emitChar = false;
} }
else else
@ -548,7 +546,7 @@ void BfPrinter::WriteIgnoredNode(BfAstNode* node)
if ((c != '#') || (mQueuedSpaceCount > 0)) if ((c != '#') || (mQueuedSpaceCount > 0))
mQueuedSpaceCount = std::max(0, mQueuedSpaceCount + mLastSpaceOffset); mQueuedSpaceCount = std::max(0, mQueuedSpaceCount + mLastSpaceOffset);
else else
mQueuedSpaceCount = mCurIndentLevel * 4; // Do default indent mQueuedSpaceCount = mCurIndentLevel * mTabSize; // Do default indent
isNewLine = false; isNewLine = false;
} }
} }
@ -581,7 +579,7 @@ void BfPrinter::WriteIgnoredNode(BfAstNode* node)
if ((mCurCol + len > mMaxCol) && (lineEmittedChars >= 8)) if ((mCurCol + len > mMaxCol) && (lineEmittedChars >= 8))
{ {
Write("\n"); Write("\n");
mQueuedSpaceCount = mCurIndentLevel * 4; mQueuedSpaceCount = mCurIndentLevel * mTabSize;
FlushIndent(); FlushIndent();
if (isStarredBlockComment) if (isStarredBlockComment)
@ -674,7 +672,7 @@ void BfPrinter::CheckRawNode(BfAstNode* node)
{ {
ExpectSpace(); ExpectSpace();
if (inLineStart) if (inLineStart)
spaceCount += 4; spaceCount += mTabSize;
} }
else if (c == ' ') else if (c == ' ')
{ {
@ -690,7 +688,7 @@ void BfPrinter::CheckRawNode(BfAstNode* node)
if ((spaceCount > 0) && (mCurBlockState != NULL)) if ((spaceCount > 0) && (mCurBlockState != NULL))
{ {
int indentCount = spaceCount / 4; int indentCount = spaceCount / mTabSize;
mNextStateModify.mWantVirtualIndent = BF_MAX(indentCount, mCurBlockState->mIndentStart + 1); mNextStateModify.mWantVirtualIndent = BF_MAX(indentCount, mCurBlockState->mIndentStart + 1);
} }
} }
@ -765,11 +763,11 @@ void BfPrinter::Visit(BfAstNode* bfAstNode)
if (c == ' ') if (c == ' ')
prevSpaceCount++; prevSpaceCount++;
else if (c == '\t') else if (c == '\t')
prevSpaceCount += 4; prevSpaceCount += mTabSize;
else if (c == '\n') else if (c == '\n')
{ {
// Found previous line // Found previous line
mCurIndentLevel = prevSpaceCount / 4; mCurIndentLevel = prevSpaceCount / mTabSize;
break; break;
} }
else else
@ -819,11 +817,11 @@ void BfPrinter::Visit(BfAstNode* bfAstNode)
if (c == ' ') if (c == ' ')
spaceCount++; spaceCount++;
else if (c == '\t') else if (c == '\t')
spaceCount += 4; spaceCount += mTabSize;
if (((c == '\n') || (i == bfAstNode->GetSrcStart() - 1)) && (hadPrevLineSpacing) && (prevSpaceCount > 0)) if (((c == '\n') || (i == bfAstNode->GetSrcStart() - 1)) && (hadPrevLineSpacing) && (prevSpaceCount > 0))
{ {
mQueuedSpaceCount += std::max(0, spaceCount - prevSpaceCount) - std::max(0, indentOffset * 4); mQueuedSpaceCount += std::max(0, spaceCount - prevSpaceCount) - std::max(0, indentOffset * mTabSize);
prevSpaceCount = -1; prevSpaceCount = -1;
hadPrevLineSpacing = false; hadPrevLineSpacing = false;
@ -840,18 +838,18 @@ void BfPrinter::Visit(BfAstNode* bfAstNode)
if (c == ' ') if (c == ' ')
prevSpaceCount++; prevSpaceCount++;
else if (c == '\t') else if (c == '\t')
prevSpaceCount += 4; prevSpaceCount += mTabSize;
if ((c == '\n') || (backIdx == 0)) if ((c == '\n') || (backIdx == 0))
{ {
// Found previous line // Found previous line
usedTrivia = true; usedTrivia = true;
Write("\n"); Write("\n");
mQueuedSpaceCount = mCurIndentLevel * 4; mQueuedSpaceCount = mCurIndentLevel * mTabSize;
// Indents extra if we have a statement split over multiple lines // Indents extra if we have a statement split over multiple lines
if (!mExpectingNewLine) if (!mExpectingNewLine)
mQueuedSpaceCount += 4; mQueuedSpaceCount += mTabSize;
break; break;
} }
@ -885,7 +883,7 @@ void BfPrinter::Visit(BfAstNode* bfAstNode)
if (!isspace((uint8)c)) if (!isspace((uint8)c))
{ {
Write("\n"); Write("\n");
mQueuedSpaceCount = mCurIndentLevel * 4; mQueuedSpaceCount = mCurIndentLevel * mTabSize;
if (!mNextStateModify.mDoingBlockClose) if (!mNextStateModify.mDoingBlockClose)
{ {
int origLineSpacing = CalcOrigLineSpacing(bfAstNode, NULL); int origLineSpacing = CalcOrigLineSpacing(bfAstNode, NULL);
@ -1958,6 +1956,9 @@ void BfPrinter::Visit(BfCaseExpression* caseExpr)
void BfPrinter::Visit(BfSwitchCase* switchCase) void BfPrinter::Visit(BfSwitchCase* switchCase)
{ {
if (mIndentCaseLabels)
ExpectIndent();
VisitChild(switchCase->mCaseToken); VisitChild(switchCase->mCaseToken);
for (int caseIdx = 0; caseIdx < (int) switchCase->mCaseExpressions.size(); caseIdx++) for (int caseIdx = 0; caseIdx < (int) switchCase->mCaseExpressions.size(); caseIdx++)
{ {
@ -1979,6 +1980,9 @@ void BfPrinter::Visit(BfSwitchCase* switchCase)
VisitChild(switchCase->mEndingSemicolonToken); VisitChild(switchCase->mEndingSemicolonToken);
ExpectNewLine(); ExpectNewLine();
} }
if (mIndentCaseLabels)
ExpectUnindent();
} }
void BfPrinter::Visit(BfWhenExpression* whenExpr) void BfPrinter::Visit(BfWhenExpression* whenExpr)

View file

@ -79,6 +79,9 @@ public:
bool mExpectingNewLine; bool mExpectingNewLine;
int mCurCol; int mCurCol;
int mMaxCol; int mMaxCol;
int mTabSize;
bool mWantsTabsAsSpaces;
bool mIndentCaseLabels;
bool mIsFirstStatementInBlock; bool mIsFirstStatementInBlock;
bool mForceUseTrivia; bool mForceUseTrivia;