Repository: marktext/marktext
File: src/editor/contentState/tabCtrl.js (JavaScript)

Code before:
    const startBlock = this.getBlock(start.key)
    if (startBlock.type !== 'p' || !startBlock.parent) {
      return false
    }

    const listItem = this.getBlock(startBlock.parent)
    if (listItem.type !== 'li' || start.key !== end.key || start.offset !== end.offset) {
      return false
    }

    // Now we know it's a list item. Check whether we can indent the list item.
    const list = this.getParent(listItem)
    return list && /ol|ul/.test(list.type) && list.children.indexOf(listItem) >= 1
  }

  ContentState.prototype.indentListItem = function () {
    const { start } = this.cursor
    const startBlock = this.getBlock(start.key)
    const listItem = this.getBlock(startBlock.parent)
    const list = this.getBlock(listItem.parent)
    const prevListItem = list.children[list.children.indexOf(listItem) - 1]

    this.removeBlock(listItem)

    // Search for a list in previous block
    let newList = prevListItem.children.find(b => /ol|ul/.test(b.type))
    if (!newList) {
      newList = this.createBlock(list.type)
      this.appendChild(prevListItem, newList)
    }

    // Update item type only if we insert into an existing list
    if (newList.children.length !== 0) {
      listItem.isLooseListItem = newList.children[0].isLooseListItem
    }

    // TODO(fxha): Is it allowed to combine list items of different types?
    this.appendChild(newList, listItem)
    this.render()
  }

  // ContentState.prototype.insertTab = function () {
  //   // TODO(fxha): Tabs and all spaces with length > 1 are converted to a single space
  //                  in editor mode. Maybe write a HTML "tab" element
  //   // TODO(fxha): create setting entry "tabSize: <int>"
  //   const tabCharacter = new Array(4).join(' ')
  //   const { start, end } = this.cursor
  //   const startBlock = this.getBlock(start.key)
  //   const endBlock = this.getBlock(end.key)
  //   if (this.cursor.start.key === this.cursor.end.key) {
  //     startBlock.text = startBlock.text.substring(0, start.offset) + tabCharacter + endBlock.text.substring(end.offset)

Review comment (suggestion):
If the `newList` is the last child of its parent, we append listItem to its children.
else we should create a new list. eg.

```markdown
- hello world

  - nice to meet

  hello world

- nice to meet(Cursor)
```

After press tab:

```markdown
- hello world

  - nice to meet

  hello world

  - nice to meet
```


Code after:
    const startBlock = this.getBlock(start.key)
    if (startBlock.type !== 'p' || !startBlock.parent) {
      return false
    }

    const listItem = this.getParent(startBlock)
    if (listItem.type !== 'li' || start.key !== end.key || start.offset !== end.offset) {
      return false
    }

    // Now we know it's a list item. Check whether we can indent the list item.
    const list = this.getParent(listItem)
    return list && /ol|ul/.test(list.type) && list.children.indexOf(listItem) >= 1
  }

  ContentState.prototype.indentListItem = function () {
    const { start } = this.cursor
    const startBlock = this.getBlock(start.key)
    const listItem = this.getParent(startBlock)
    const list = this.getParent(listItem)
    const prevListItem = this.getPreSibling(listItem)

    this.removeBlock(listItem)

    // Search for a list in previous block
    let newList = this.getLastChild(prevListItem)
    if (!newList || !/ol|ul/.test(newList.type)) {
      newList = this.createBlock(list.type)
      this.appendChild(prevListItem, newList)
    }

    // Update item type only if we insert into an existing list
    if (newList.children.length !== 0) {
      listItem.isLooseListItem = newList.children[0].isLooseListItem
    }

    this.appendChild(newList, listItem)
    this.render()
  }

  // ContentState.prototype.insertTab = function () {
  //   // TODO(fxha): Tabs and all spaces with length > 1 are converted to a single space
  //                  in editor mode. Maybe write a HTML "tab" element
  //   // TODO(fxha): create setting entry "tabSize: <int>"
  //   const tabCharacter = new Array(4).join(' ')
  //   const { start, end } = this.cursor
  //   const startBlock = this.getBlock(start.key)
  //   const endBlock = this.getBlock(end.key)
  //   if (this.cursor.start.key === this.cursor.end.key) {
  //     startBlock.text = startBlock.text.substring(0, start.offset) + tabCharacter + endBlock.text.substring(end.offset)
  //     // workaround: see todo 1