From 021155b12a0eae1504032e94bd26cd1eb7680d5c Mon Sep 17 00:00:00 2001 From: Vadim Lopatin Date: Tue, 24 Feb 2015 12:32:32 +0300 Subject: [PATCH] smart indents support --- src/dlangui/core/editable.d | 35 +++++++++++++++++++++++++++++++++-- src/dlangui/widgets/editors.d | 26 ++++++++++++++++++++++++-- 2 files changed, 57 insertions(+), 4 deletions(-) diff --git a/src/dlangui/core/editable.d b/src/dlangui/core/editable.d index 3af95e39..7a7da7ae 100644 --- a/src/dlangui/core/editable.d +++ b/src/dlangui/core/editable.d @@ -341,6 +341,16 @@ class EditOperation { _oldEditMarks[i] = EditStateMark.changed; } } + + /// return true if it's insert new line operation + @property bool isInsertNewLine() { + return content.length == 2 && content[0].length == 0 && content[1].length == 0; + } + + /// if new content is single char, return it, otherwise return 0 + @property dchar singleChar() { + return content.length == 1 && content[0].length == 1 ? content[0][0] : 0; + } } /// Undo/Redo buffer @@ -435,7 +445,7 @@ alias TokenProp = ubyte; /// TokenCategory string alias TokenPropString = TokenProp[]; -/// interface for custom syntax highlight +/// interface for custom syntax highlight, comments toggling, smart indents, and other language dependent features for source code editors interface SyntaxSupport { /// returns editable content @@ -445,13 +455,14 @@ interface SyntaxSupport { /// categorize characters in content by token types void updateHighlight(dstring[] lines, TokenPropString[] props, int changeStartLine, int changeEndLine); + /// return true if toggle line comment is supported for file type @property bool supportsToggleLineComment(); /// return true if can toggle line comments for specified text range bool canToggleLineComment(TextRange range); - /// toggle line comments for specified text range void toggleLineComment(TextRange range, Object source); + /// return true if toggle block comment is supported for file type @property bool supportsToggleBlockComment(); /// return true if can toggle block comments for specified text range @@ -461,6 +472,11 @@ interface SyntaxSupport { /// returns paired bracket {} () [] for char at position p, returns paired char position or p if not found or not bracket TextPosition findPairedBracket(TextPosition p); + + /// returns true if smart indent is supported + bool supportsSmartIndents(); + /// apply smart indent after edit operation, if needed + void applySmartIndent(EditOperation op, Object source); } /// measure line text (tabs, spaces, and nonspace positions) @@ -554,6 +570,21 @@ class EditableContent { return this; } + /// true if smart indents are supported + @property bool supportsSmartIndents() { return _syntaxSupport && _syntaxSupport.supportsSmartIndents; } + + protected bool _smartIndents; + /// true if smart indents are enabled + @property bool smartIndents() { return _smartIndents; } + /// set smart indents enabled flag + @property EditableContent smartIndents(bool enabled) { _smartIndents = enabled; return this; } + + protected bool _smartIndentsAfterPaste; + /// true if smart indents are enabled + @property bool smartIndentsAfterPaste() { return _smartIndentsAfterPaste; } + /// set smart indents enabled flag + @property EditableContent smartIndentsAfterPaste(bool enabled) { _smartIndentsAfterPaste = enabled; return this; } + /// listeners for edit operations Signal!EditableContentListener contentChangeListeners; diff --git a/src/dlangui/widgets/editors.d b/src/dlangui/widgets/editors.d index e918e2ad..dc7e4251 100644 --- a/src/dlangui/widgets/editors.d +++ b/src/dlangui/widgets/editors.d @@ -590,6 +590,19 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction return this; } + /// true if smart indents are supported + @property bool supportsSmartIndents() { return _content.supportsSmartIndents; } + /// true if smart indents are enabled + @property bool smartIndents() { return _content.smartIndents; } + /// set smart indents enabled flag + @property EditWidgetBase smartIndents(bool enabled) { _content.smartIndents = enabled; return this; } + + /// true if smart indents are enabled + @property bool smartIndentsAfterPaste() { return _content.smartIndentsAfterPaste; } + /// set smart indents enabled flag + @property EditWidgetBase smartIndentsAfterPaste(bool enabled) { _content.smartIndentsAfterPaste = enabled; return this; } + + /// editor content object @property EditableContent content() { return _content; @@ -627,11 +640,19 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction protected void updateMaxLineWidth() { } + protected void processSmartIndent(EditOperation operation) { + if (!supportsSmartIndents) + return; + if (!smartIndents && !smartIndentsAfterPaste) + return; + _content.syntaxSupport.applySmartIndent(operation, this); + } + override void onContentChange(EditableContent content, EditOperation operation, ref TextRange rangeBefore, ref TextRange rangeAfter, Object source) { //Log.d("onContentChange rangeBefore=", rangeBefore, " rangeAfter=", rangeAfter, " text=", operation.content); + _contentChanged = true; if (source is this) { if (operation.action == EditAction.ReplaceContent) { - _contentChanged = true; // fully replaced, e.g., loaded from file or text property is assigned _caretPos = rangeAfter.end; _selectionRange.start = _caretPos; @@ -645,7 +666,7 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction } else if (operation.action == EditAction.SaveContent) { // saved } else { - _contentChanged = true; + // modified _caretPos = rangeAfter.end; _selectionRange.start = _caretPos; _selectionRange.end = _caretPos; @@ -653,6 +674,7 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction measureVisibleText(); ensureCaretVisible(); requestActionsUpdate(); + processSmartIndent(operation); } } else { updateMaxLineWidth();