MarkdownToolbar: Add buttons to navigate between words

This commit is contained in:
Vishesh Handa
2020-08-14 22:00:34 +02:00
parent 440ee96639
commit 745d59e570
2 changed files with 79 additions and 0 deletions

View File

@ -23,6 +23,14 @@ class MarkdownToolBar extends StatelessWidget {
icon: const Text('B'),
onPressed: () => _modifyCurrentWord('**'),
),
IconButton(
icon: const Icon(Icons.navigate_before),
onPressed: _navigateToPrevWord,
),
IconButton(
icon: const Icon(Icons.navigate_next),
onPressed: _navigateToNextWord,
),
],
);
}
@ -34,6 +42,16 @@ class MarkdownToolBar extends StatelessWidget {
void _modifyCurrentWord(String char) {
textController.value = modifyCurrentWord(textController.value, char);
}
void _navigateToPrevWord() {
var offset = nextWordPos(textController.value);
textController.selection = TextSelection.collapsed(offset: offset);
}
void _navigateToNextWord() {
var offset = prevWordPos(textController.value);
textController.selection = TextSelection.collapsed(offset: offset);
}
}
TextEditingValue modifyCurrentLine(
@ -146,3 +164,28 @@ TextEditingValue modifyCurrentWord(
selection: TextSelection.collapsed(offset: wordEndPos),
);
}
// FIXME: This will fail in non space delimited languages
int nextWordPos(TextEditingValue textEditingValue) {
var cursorPos = textEditingValue.selection.baseOffset;
var text = textEditingValue.text;
var nextSpacePos = text.indexOf(RegExp('\s'), cursorPos);
if (nextSpacePos == -1) {
return text.length;
}
return nextSpacePos;
}
int prevWordPos(TextEditingValue textEditingValue) {
var cursorPos = textEditingValue.selection.baseOffset;
var text = textEditingValue.text;
var lastSpacePos = text.lastIndexOf(RegExp('\s'), cursorPos);
if (lastSpacePos == -1) {
return 0;
}
return lastSpacePos;
}

View File

@ -166,4 +166,40 @@ void main() {
char: '**',
);
});
//
// Navigation
//
test('Navigation with only 1 word', () {
var val = const TextEditingValue(
text: 'Hello',
selection: TextSelection.collapsed(offset: 3),
);
expect(nextWordPos(val), 5);
val = const TextEditingValue(
text: 'Hello',
selection: TextSelection.collapsed(offset: 5),
);
expect(nextWordPos(val), 5);
val = const TextEditingValue(
text: 'Hello',
selection: TextSelection.collapsed(offset: 3),
);
expect(prevWordPos(val), 0);
val = const TextEditingValue(
text: 'Hello',
selection: TextSelection.collapsed(offset: 5),
);
expect(prevWordPos(val), 0);
});
// Test for navigating between punctuations
// Test for navigating between newlines
}