Lower indention on pressing backspace

Signed-off-by: Stefan Niedermann <info@niedermann.it>
This commit is contained in:
Stefan Niedermann 2021-07-23 09:14:17 +02:00 committed by Niedermann IT-Dienstleistungen
parent 37a01ce17c
commit 8e2264ea23
6 changed files with 86 additions and 24 deletions

View file

@ -184,19 +184,26 @@ public class MarkdownUtil {
return s.length();
}
public static String getListItemIfIsEmpty(@NonNull String line) {
public static Optional<String> getListItemIfIsEmpty(@NonNull String line) {
final String trimmedLine = line.trim();
// TODO use Java 11 String::repeat
final StringBuilder builder = new StringBuilder();
final int indention = line.indexOf(trimmedLine);
for (int i = 0; i < indention; i++) {
builder.append(" ");
}
for (EListType listType : EListType.values()) {
if (line.equals(listType.checkboxUncheckedWithTrailingSpace)) {
return listType.checkboxUncheckedWithTrailingSpace;
} else if (line.equals(listType.listSymbolWithTrailingSpace)) {
return listType.listSymbolWithTrailingSpace;
if (trimmedLine.equals(listType.checkboxUnchecked)) {
return Optional.of(builder.append(listType.checkboxUncheckedWithTrailingSpace).toString());
} else if (trimmedLine.equals(listType.listSymbol)) {
return Optional.of(builder.append(listType.listSymbolWithTrailingSpace).toString());
}
}
final Matcher matcher = PATTERN_ORDERED_LIST_ITEM_EMPTY.matcher(line);
final Matcher matcher = PATTERN_ORDERED_LIST_ITEM_EMPTY.matcher(line.substring(indention));
if (matcher.find()) {
return matcher.group();
return Optional.of(builder.append(matcher.group()).toString());
}
return null;
return Optional.empty();
}
public static CharSequence setCheckboxStatus(@NonNull String markdownString, int targetCheckboxIndex, boolean newCheckedState) {

View file

@ -85,9 +85,9 @@ public class AutoContinuationTextWatcher extends InterceptorTextWatcher {
final int startOfLine = getStartOfLine(s, start);
final String line = s.subSequence(startOfLine, getEndOfLine(s, start)).toString();
final String emptyListString = getListItemIfIsEmpty(line);
if (emptyListString != null) {
customText = emptyListString;
final Optional<String> emptyListString = getListItemIfIsEmpty(line);
if (emptyListString.isPresent()) {
customText = emptyListString.get();
isInsert = false;
sequenceStart = startOfLine;
} else {
@ -96,9 +96,10 @@ public class AutoContinuationTextWatcher extends InterceptorTextWatcher {
for (int i = 0; i < line.indexOf(line.trim()); i++) {
builder.append(" ");
}
final String trimmedLine = line.trim();
for (EListType listType : EListType.values()) {
final boolean isCheckboxList = lineStartsWithCheckbox(line, listType);
final boolean isPlainList = !isCheckboxList && line.startsWith(listType.listSymbolWithTrailingSpace);
final boolean isCheckboxList = lineStartsWithCheckbox(trimmedLine, listType);
final boolean isPlainList = !isCheckboxList && trimmedLine.startsWith(listType.listSymbolWithTrailingSpace);
if (isPlainList || isCheckboxList) {
builder.append(isPlainList ? listType.listSymbolWithTrailingSpace : listType.checkboxUncheckedWithTrailingSpace);
customText = builder;

View file

@ -12,7 +12,7 @@ import static it.niedermann.android.markdown.MarkdownUtil.getEndOfLine;
import static it.niedermann.android.markdown.MarkdownUtil.getStartOfLine;
/**
* Automatically continues lists and checkbox lists when pressing enter
* Automatically lowers indention when pressing <kbd>Backspace</kbd> on lists and check lists
*/
public class LowerIndentionTextWatcher extends InterceptorTextWatcher {
@ -41,7 +41,7 @@ public class LowerIndentionTextWatcher extends InterceptorTextWatcher {
@Override
public void afterTextChanged(Editable editable) {
if (backspacePressed) {
if(!handleBackspace(editable, cursor)) {
if (!handleBackspace(editable, cursor)) {
originalWatcher.afterTextChanged(editable);
}
backspacePressed = false;
@ -54,11 +54,20 @@ public class LowerIndentionTextWatcher extends InterceptorTextWatcher {
private boolean handleBackspace(@NonNull Editable editable, int cursor) {
final int lineStart = getStartOfLine(editable, cursor);
final int lineEnd = getEndOfLine(editable, cursor);
// The cursor must be at the end of the line to automatically continue
if (cursor != lineEnd) {
return false;
}
final String line = editable.subSequence(lineStart, lineEnd).toString();
final String trimmedLine = line.trim();
// There must be no content in this list item to automatically continue
if ((line.indexOf(trimmedLine) + trimmedLine.length()) < line.length()) {
return false;
}
for (EListType listType : EListType.values()) {
if (listType.listSymbol.equals(trimmedLine)) {
if (trimmedLine.length() == EListType.DASH.listSymbol.length()) {

View file

@ -586,18 +586,37 @@ public class MarkdownUtilTest extends TestCase {
}
}
@SuppressWarnings("OptionalGetWithoutIsPresent")
@Test
public void testGetListItemIfIsEmpty() {
assertEquals("- ", MarkdownUtil.getListItemIfIsEmpty("- "));
assertEquals("+ ", MarkdownUtil.getListItemIfIsEmpty("+ "));
assertEquals("* ", MarkdownUtil.getListItemIfIsEmpty("* "));
assertEquals("1. ", MarkdownUtil.getListItemIfIsEmpty("1. "));
assertEquals("- ", MarkdownUtil.getListItemIfIsEmpty("- ").get());
assertEquals("+ ", MarkdownUtil.getListItemIfIsEmpty("+ ").get());
assertEquals("* ", MarkdownUtil.getListItemIfIsEmpty("* ").get());
assertEquals("1. ", MarkdownUtil.getListItemIfIsEmpty("1. ").get());
assertEquals(" - ", MarkdownUtil.getListItemIfIsEmpty(" - ").get());
assertEquals(" + ", MarkdownUtil.getListItemIfIsEmpty(" + ").get());
assertEquals(" * ", MarkdownUtil.getListItemIfIsEmpty(" * ").get());
assertEquals(" 1. ", MarkdownUtil.getListItemIfIsEmpty(" 1. ").get());
assertEquals(" - ", MarkdownUtil.getListItemIfIsEmpty(" - ").get());
assertEquals(" + ", MarkdownUtil.getListItemIfIsEmpty(" + ").get());
assertEquals(" * ", MarkdownUtil.getListItemIfIsEmpty(" * ").get());
assertEquals(" 1. ", MarkdownUtil.getListItemIfIsEmpty(" 1. ").get());
assertNull(MarkdownUtil.getListItemIfIsEmpty("- Test"));
assertNull(MarkdownUtil.getListItemIfIsEmpty("+ Test"));
assertNull(MarkdownUtil.getListItemIfIsEmpty("* Test"));
assertNull(MarkdownUtil.getListItemIfIsEmpty("1. s"));
assertNull(MarkdownUtil.getListItemIfIsEmpty("1. "));
assertFalse(MarkdownUtil.getListItemIfIsEmpty("- Test").isPresent());
assertFalse(MarkdownUtil.getListItemIfIsEmpty("+ Test").isPresent());
assertFalse(MarkdownUtil.getListItemIfIsEmpty("* Test").isPresent());
assertFalse(MarkdownUtil.getListItemIfIsEmpty("1. s").isPresent());
assertFalse(MarkdownUtil.getListItemIfIsEmpty("1. ").isPresent());
assertFalse(MarkdownUtil.getListItemIfIsEmpty(" - Test").isPresent());
assertFalse(MarkdownUtil.getListItemIfIsEmpty(" + Test").isPresent());
assertFalse(MarkdownUtil.getListItemIfIsEmpty(" * Test").isPresent());
assertFalse(MarkdownUtil.getListItemIfIsEmpty(" 1. s").isPresent());
assertFalse(MarkdownUtil.getListItemIfIsEmpty(" 1. ").isPresent());
assertFalse(MarkdownUtil.getListItemIfIsEmpty(" - Test").isPresent());
assertFalse(MarkdownUtil.getListItemIfIsEmpty(" + Test").isPresent());
assertFalse(MarkdownUtil.getListItemIfIsEmpty(" * Test").isPresent());
assertFalse(MarkdownUtil.getListItemIfIsEmpty(" 1. s").isPresent());
assertFalse(MarkdownUtil.getListItemIfIsEmpty(" 1. ").isPresent());
}
@SuppressWarnings("OptionalGetWithoutIsPresent")

View file

@ -101,6 +101,14 @@ public class AutoContinuationTextWatcherTest extends TestCase {
assertText("- Foo\n\n", 7);
pressEnter(7);
assertText("- Foo\n\n\n", 8);
this.editText.setText("- Foo\n - Bar");
pressEnter(13);
assertText("- Foo\n - Bar\n - ", 18);
pressEnter(18);
assertText("- Foo\n - Bar\n\n", 15);
pressEnter(15);
assertText("- Foo\n - Bar\n\n\n", 16);
}
@Test

View file

@ -71,6 +71,24 @@ public class LowerIndentionTextWatcherTest extends TestCase {
assertText("- Foo\n ", 8);
}
@Test
public void shouldNotLowerIndentionIfThereIsAnyContentAfterTheList() {
this.editText.setText(" - ");
pressBackspace(4);
assertText(" - ", 3);
this.editText.setText(" - ");
pressBackspace(5);
assertText(" - ", 4);
}
@Test
public void shouldNotLowerIndentionIfBackspaceWasPressedInTheNextLine() {
this.editText.setText(" - \nFoo");
pressBackspace(5);
assertText(" - Foo", 4);
}
@Test
public void shouldDeleteLastCharacterWhenPressingBackspace() {
this.editText.setText("");