mirror of https://github.com/buggins/dlangui.git
indent/unindent editor actions improved
This commit is contained in:
parent
9fba7e6cfa
commit
6bb69b2471
|
@ -280,6 +280,8 @@ extern (C) int UIAppMain(string[] args) {
|
||||||
editItem.add(new Action(EditorActions.Cut, "MENU_EDIT_CUT"c, "edit-cut", KeyCode.KEY_X, KeyFlag.Control));
|
editItem.add(new Action(EditorActions.Cut, "MENU_EDIT_CUT"c, "edit-cut", KeyCode.KEY_X, KeyFlag.Control));
|
||||||
editItem.add(new Action(EditorActions.Undo, "MENU_EDIT_UNDO"c, "edit-undo", KeyCode.KEY_Z, KeyFlag.Control));
|
editItem.add(new Action(EditorActions.Undo, "MENU_EDIT_UNDO"c, "edit-undo", KeyCode.KEY_Z, KeyFlag.Control));
|
||||||
editItem.add(new Action(EditorActions.Redo, "MENU_EDIT_REDO"c, "edit-redo", KeyCode.KEY_Y, KeyFlag.Control));
|
editItem.add(new Action(EditorActions.Redo, "MENU_EDIT_REDO"c, "edit-redo", KeyCode.KEY_Y, KeyFlag.Control));
|
||||||
|
editItem.add(new Action(EditorActions.Indent, "MENU_EDIT_INDENT"c, "edit-indent", KeyCode.TAB, 0));
|
||||||
|
editItem.add(new Action(EditorActions.Unindent, "MENU_EDIT_UNINDENT"c, "edit-unindent", KeyCode.TAB, KeyFlag.Control));
|
||||||
editItem.add(new Action(20, "MENU_EDIT_PREFERENCES"));
|
editItem.add(new Action(20, "MENU_EDIT_PREFERENCES"));
|
||||||
|
|
||||||
MenuItem editPopupItem = new MenuItem(null);
|
MenuItem editPopupItem = new MenuItem(null);
|
||||||
|
@ -288,6 +290,8 @@ extern (C) int UIAppMain(string[] args) {
|
||||||
editPopupItem.add(new Action(EditorActions.Cut, "MENU_EDIT_CUT"c, "edit-cut", KeyCode.KEY_X, KeyFlag.Control));
|
editPopupItem.add(new Action(EditorActions.Cut, "MENU_EDIT_CUT"c, "edit-cut", KeyCode.KEY_X, KeyFlag.Control));
|
||||||
editPopupItem.add(new Action(EditorActions.Undo, "MENU_EDIT_UNDO"c, "edit-undo", KeyCode.KEY_Z, KeyFlag.Control));
|
editPopupItem.add(new Action(EditorActions.Undo, "MENU_EDIT_UNDO"c, "edit-undo", KeyCode.KEY_Z, KeyFlag.Control));
|
||||||
editPopupItem.add(new Action(EditorActions.Redo, "MENU_EDIT_REDO"c, "edit-redo", KeyCode.KEY_Y, KeyFlag.Control));
|
editPopupItem.add(new Action(EditorActions.Redo, "MENU_EDIT_REDO"c, "edit-redo", KeyCode.KEY_Y, KeyFlag.Control));
|
||||||
|
editPopupItem.add(new Action(EditorActions.Indent, "MENU_EDIT_INDENT"c, "edit-indent", KeyCode.TAB, 0));
|
||||||
|
editPopupItem.add(new Action(EditorActions.Unindent, "MENU_EDIT_UNINDENT"c, "edit-unindent", KeyCode.TAB, KeyFlag.Control));
|
||||||
|
|
||||||
MenuItem viewItem = new MenuItem(new Action(60, "MENU_VIEW"));
|
MenuItem viewItem = new MenuItem(new Action(60, "MENU_VIEW"));
|
||||||
MenuItem langItem = new MenuItem(new Action(61, "MENU_VIEW_LANGUAGE"));
|
MenuItem langItem = new MenuItem(new Action(61, "MENU_VIEW_LANGUAGE"));
|
||||||
|
|
|
@ -10,6 +10,8 @@ MENU_EDIT_PASTE=&Paste
|
||||||
MENU_EDIT_CUT=Cu&t
|
MENU_EDIT_CUT=Cu&t
|
||||||
MENU_EDIT_UNDO=&Undo
|
MENU_EDIT_UNDO=&Undo
|
||||||
MENU_EDIT_REDO=&Redo
|
MENU_EDIT_REDO=&Redo
|
||||||
|
MENU_EDIT_INDENT=Indent block
|
||||||
|
MENU_EDIT_UNINDENT=Unindent block
|
||||||
MENU_EDIT_PREFERENCES=&Preferences
|
MENU_EDIT_PREFERENCES=&Preferences
|
||||||
MENU_VIEW=&View
|
MENU_VIEW=&View
|
||||||
MENU_VIEW_LANGUAGE=Interface &Language
|
MENU_VIEW_LANGUAGE=Interface &Language
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 413 B |
Binary file not shown.
After Width: | Height: | Size: 367 B |
|
@ -9,8 +9,10 @@ res/mdpi/document-save-as.png
|
||||||
res/mdpi/document-save.png
|
res/mdpi/document-save.png
|
||||||
res/mdpi/edit-copy.png
|
res/mdpi/edit-copy.png
|
||||||
res/mdpi/edit-cut.png
|
res/mdpi/edit-cut.png
|
||||||
|
res/mdpi/edit-indent.png
|
||||||
res/mdpi/edit-paste.png
|
res/mdpi/edit-paste.png
|
||||||
res/mdpi/edit-redo.png
|
res/mdpi/edit-redo.png
|
||||||
res/mdpi/edit-undo.png
|
res/mdpi/edit-undo.png
|
||||||
|
res/mdpi/edit-unindent.png
|
||||||
res/mdpi/tx_fabric.jpg
|
res/mdpi/tx_fabric.jpg
|
||||||
res/theme_custom1.xml
|
res/theme_custom1.xml
|
||||||
|
|
|
@ -598,8 +598,10 @@ class EditableContent {
|
||||||
return TextPosition(lineIndex, lineLength(lineIndex));
|
return TextPosition(lineIndex, lineLength(lineIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// returns text position for begin of line lineIndex
|
/// returns text position for begin of line lineIndex (if lineIndex > number of lines, returns end of last line)
|
||||||
TextPosition lineBegin(int lineIndex) {
|
TextPosition lineBegin(int lineIndex) {
|
||||||
|
if (lineIndex >= _lines.length)
|
||||||
|
return lineEnd(lineIndex - 1);
|
||||||
return TextPosition(lineIndex, 0);
|
return TextPosition(lineIndex, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -134,6 +134,10 @@ enum EditorActions : int {
|
||||||
Tab,
|
Tab,
|
||||||
/// Tab (unindent text, or remove whitespace before cursor, usually Shift+Tab)
|
/// Tab (unindent text, or remove whitespace before cursor, usually Shift+Tab)
|
||||||
BackTab,
|
BackTab,
|
||||||
|
/// Indent text block or single line
|
||||||
|
Indent,
|
||||||
|
/// Unindent text
|
||||||
|
Unindent,
|
||||||
|
|
||||||
/// Select whole content (usually, Ctrl+A)
|
/// Select whole content (usually, Ctrl+A)
|
||||||
SelectAll,
|
SelectAll,
|
||||||
|
@ -414,6 +418,8 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction
|
||||||
case EditorActions.ToggleLineComment:
|
case EditorActions.ToggleLineComment:
|
||||||
case EditorActions.Tab:
|
case EditorActions.Tab:
|
||||||
case EditorActions.BackTab:
|
case EditorActions.BackTab:
|
||||||
|
case EditorActions.Indent:
|
||||||
|
case EditorActions.Unindent:
|
||||||
return enabled;
|
return enabled;
|
||||||
case EditorActions.Copy:
|
case EditorActions.Copy:
|
||||||
return !_selectionRange.empty;
|
return !_selectionRange.empty;
|
||||||
|
@ -910,6 +916,8 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction
|
||||||
case EditorActions.ToggleLineComment:
|
case EditorActions.ToggleLineComment:
|
||||||
case EditorActions.Tab:
|
case EditorActions.Tab:
|
||||||
case EditorActions.BackTab:
|
case EditorActions.BackTab:
|
||||||
|
case EditorActions.Indent:
|
||||||
|
case EditorActions.Unindent:
|
||||||
if (isActionEnabled(a))
|
if (isActionEnabled(a))
|
||||||
a.state = ACTION_STATE_ENABLED;
|
a.state = ACTION_STATE_ENABLED;
|
||||||
else
|
else
|
||||||
|
@ -1108,6 +1116,12 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction
|
||||||
return true;
|
return true;
|
||||||
_content.redo(this);
|
_content.redo(this);
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
case EditorActions.Indent:
|
||||||
|
indentRange(false);
|
||||||
|
return true;
|
||||||
|
case EditorActions.Unindent:
|
||||||
|
indentRange(true);
|
||||||
return true;
|
return true;
|
||||||
case EditorActions.Tab:
|
case EditorActions.Tab:
|
||||||
{
|
{
|
||||||
|
@ -1126,7 +1140,7 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction
|
||||||
} else {
|
} else {
|
||||||
if (wholeLinesSelected()) {
|
if (wholeLinesSelected()) {
|
||||||
// indent range
|
// indent range
|
||||||
indentRange(false);
|
return handleAction(new Action(EditorActions.Indent));
|
||||||
} else {
|
} else {
|
||||||
// insert tab
|
// insert tab
|
||||||
if (_useSpacesForTabs) {
|
if (_useSpacesForTabs) {
|
||||||
|
@ -1157,7 +1171,7 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction
|
||||||
} else {
|
} else {
|
||||||
if (wholeLinesSelected()) {
|
if (wholeLinesSelected()) {
|
||||||
// unindent range
|
// unindent range
|
||||||
indentRange(true);
|
return handleAction(new Action(EditorActions.Unindent));
|
||||||
} else {
|
} else {
|
||||||
// remove space before selection
|
// remove space before selection
|
||||||
TextRange r = spaceBefore(_selectionRange.start);
|
TextRange r = spaceBefore(_selectionRange.start);
|
||||||
|
@ -1224,10 +1238,11 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction
|
||||||
}
|
}
|
||||||
|
|
||||||
/// change line indent
|
/// change line indent
|
||||||
protected dstring indentLine(dstring src, bool back) {
|
protected dstring indentLine(dstring src, bool back, TextPosition * cursorPos) {
|
||||||
int firstNonSpace = -1;
|
int firstNonSpace = -1;
|
||||||
int x = 0;
|
int x = 0;
|
||||||
int unindentPos = -1;
|
int unindentPos = -1;
|
||||||
|
int cursor = cursorPos ? cursorPos.pos : 0;
|
||||||
for (int i = 0; i < src.length; i++) {
|
for (int i = 0; i < src.length; i++) {
|
||||||
dchar ch = src[i];
|
dchar ch = src[i];
|
||||||
if (ch == ' ') {
|
if (ch == ' ') {
|
||||||
|
@ -1247,14 +1262,23 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction
|
||||||
// unindent
|
// unindent
|
||||||
if (unindentPos == -1)
|
if (unindentPos == -1)
|
||||||
return src; // no change
|
return src; // no change
|
||||||
if (unindentPos == src.length)
|
if (unindentPos == src.length) {
|
||||||
|
if (cursorPos)
|
||||||
|
cursorPos.pos = 0;
|
||||||
return ""d;
|
return ""d;
|
||||||
|
}
|
||||||
|
if (cursor >= unindentPos)
|
||||||
|
cursorPos.pos -= unindentPos;
|
||||||
return src[unindentPos .. $].dup;
|
return src[unindentPos .. $].dup;
|
||||||
} else {
|
} else {
|
||||||
// indent
|
// indent
|
||||||
if (_useSpacesForTabs) {
|
if (_useSpacesForTabs) {
|
||||||
|
if (cursor > 0)
|
||||||
|
cursorPos.pos += tabSize;
|
||||||
return spacesForTab(0) ~ src;
|
return spacesForTab(0) ~ src;
|
||||||
} else {
|
} else {
|
||||||
|
if (cursor > 0)
|
||||||
|
cursorPos.pos++;
|
||||||
return "\t"d ~ src;
|
return "\t"d ~ src;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1262,20 +1286,28 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction
|
||||||
|
|
||||||
/// indent / unindent range
|
/// indent / unindent range
|
||||||
protected void indentRange(bool back) {
|
protected void indentRange(bool back) {
|
||||||
int lineCount = _selectionRange.end.line - _selectionRange.start.line;
|
TextRange r = _selectionRange;
|
||||||
|
r.start.pos = 0;
|
||||||
|
if (r.end.pos > 0)
|
||||||
|
r.end = _content.lineBegin(r.end.line + 1);
|
||||||
|
if (r.end.line <= r.start.line)
|
||||||
|
r = TextRange(_content.lineBegin(_caretPos.line), _content.lineBegin(_caretPos.line + 1));
|
||||||
|
int lineCount = r.end.line - r.start.line;
|
||||||
|
if (r.end.pos > 0)
|
||||||
|
lineCount++;
|
||||||
dstring[] newContent = new dstring[lineCount + 1];
|
dstring[] newContent = new dstring[lineCount + 1];
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
for (int i = 0; i < lineCount; i++) {
|
for (int i = 0; i < lineCount; i++) {
|
||||||
dstring srcline = _content.line(_selectionRange.start.line + i);
|
dstring srcline = _content.line(r.start.line + i);
|
||||||
dstring dstline = indentLine(srcline, back);
|
dstring dstline = indentLine(srcline, back, r.start.line + i == _caretPos.line ? &_caretPos : null);
|
||||||
newContent[i] = dstline;
|
newContent[i] = dstline;
|
||||||
if (dstline.length != srcline.length)
|
if (dstline.length != srcline.length)
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
if (changed) {
|
if (changed) {
|
||||||
TextRange saveRange = _selectionRange;
|
TextRange saveRange = r;
|
||||||
TextPosition saveCursor = _caretPos;
|
TextPosition saveCursor = _caretPos;
|
||||||
EditOperation op = new EditOperation(EditAction.Replace, _selectionRange, newContent);
|
EditOperation op = new EditOperation(EditAction.Replace, r, newContent);
|
||||||
_content.performOperation(op, this);
|
_content.performOperation(op, this);
|
||||||
_selectionRange = saveRange;
|
_selectionRange = saveRange;
|
||||||
_caretPos = saveCursor;
|
_caretPos = saveCursor;
|
||||||
|
|
|
@ -34,6 +34,7 @@ class SourceEdit : EditBox {
|
||||||
showModificationMarks = true;
|
showModificationMarks = true;
|
||||||
|
|
||||||
_showLineNumbers = true;
|
_showLineNumbers = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
this() {
|
this() {
|
||||||
this("SRCEDIT");
|
this("SRCEDIT");
|
||||||
|
|
Loading…
Reference in New Issue