Persistent folding

So here's my take on persistent folding, mixed from code at the first posting and Persistent folding: how to use space-style to hide a particular attribute? - #10 by Platinum :

Similar to Tom I add the marker :down_arrow:, but by using the editor:fold and editor:unfold events, so I do not need to remember a separate shortcut and it works independently of the type of the item to be folded.

Platinums code to restore the state worked fine, I just added await to editor.getCursor() to fix the issue with nil

persFold = persFold or {} -- define namespace for persistent fold supporting functions

persFold.marker = "⬇️"

function persFold.lineStart(pageText, pos)
    -- Return the starting position of the line of the current page containing position pos
  
    -- Get the content of the page text up to pos  
    local pageTextToPos = string.sub(pageText, 1, pos)
    -- Reverse it
    local pageTextToPosReversed = string.reverse(pageTextToPos)
    -- Find the number of characters before the first new line character
    local posPositionInLine, _ = string.find(pageTextToPosReversed, "\n")
    
    -- Subtract that number from pos
    --local startOfLine = pos - posPositionInLine

    if posPositionInLine then
      return pos - (posPositionInLine - 2)
    else 
      return 1
    end
  
end

function persFold.lineLength(pageText, startOfLine)

    local pageTextFromStartOfLine = string.sub(pageText, startOfLine)
    local lineLength, _ = string.find(pageTextFromStartOfLine, "\n") - 1

    return lineLength
end

function persFold.lineText(pageText, pos)
    -- Return the text of the line of the current page containing position pos

    -- Find the end of the current line, or the end of the page if it's the last line
    local startOfLine = persFold.lineStart(pageText, pos)
    local lineLength = persFold.lineLength(pageText, startOfLine)

  
    if lineLength == -1 then
        lineLength = string.len(pageText) - startOfLine + 1
    end

    local lineText = string.sub(pageText, startOfLine, startOfLine + lineLength - 1)
  
    return lineText  
end

function persFold.togglerMarker(toggleOn)
    local pageText = editor.getText()
    if not pageText then
      return
    end

    local cursorPositionInPage = editor.getCursor()

    -- Get the text, starting position and length of the current line
    local currentLineText = persFold.lineText(pageText, cursorPositionInPage)
    local currentLineStart = persFold.lineStart(pageText,cursorPositionInPage)
    local currentLineLength = persFold.lineLength(pageText,currentLineStart)
    local nextLineStart = currentLineStart + currentLineLength

    local marked = string.sub(currentLineText,currentLineLength - string.len(persFold.marker) + 1, currentLineLength) == persFold.marker
  
    if toggleOn == 1 and not marked then
      -- add marker
      editor.insertAtPos(persFold.marker, nextLineStart - 1)
    elseif toggleOn == 0 and marked then
      -- If yes, remove marker
      editor.replaceRange(nextLineStart - 1 - string.len(persFold.marker), nextLineStart - 1, "")
    end 
  
end

-- add marker when folding (Ctl-. Ctl-.)
event.listen{
  name = "editor:fold",
  run = function()
    persFold.togglerMarker(1)
  end  
}

-- remove marker when folding (Ctl-. Ctl-.)
event.listen{
  name = "editor:unfold",
  run = function()
    persFold.togglerMarker(0)
  end  
}

-- Event listener to fold up marked bullets on page load
event.listen{
  name = "editor:pageLoaded",
  run = function()
    local text = editor.getText()
    if not text then
      return
    end
  
    -- Save cursor position
    local originalCursor = await editor.getCursor()
  
    local lineNum = 0
    for line in (text .. "\n"):gmatch("(.-)\n") do
      lineNum = lineNum + 1
  
      -- Simple substring match
      if line:find(persFold.marker .. "$", 1) then
        -- Move cursor to the line so the folding can be done
        editor.moveCursorToLine(lineNum, 1, false)
        
        -- Fold the block at cursor
        editor.fold()
      end
    end

    -- Restore cursor
    if originalCursor != nil then
      editor.setCursor(originalCursor)
    end
  end
}