Non-indentation based text editor line folding?


#1

Hello atom community,

I want to write a package to fold sections of markdown by markdown headers.

From what I understand, Atom text editors fold lines by indentation only.

Is it possible to define a range of lines to fold that doesn’t use indentation? I’ve been trying to get my head around the Folds section in the text editor api docs but to me it looks like it’s just folding by indentation.

If anybody’s able to provide any guidance or suggestions to help me get started that’d be much appreciated!

My current thoughts about the package are that a command would fold text between two markdown section headers of the same level. What would be even nicer would be if we can somehow insert these fold buttons next to the line numbers, currently they only seem to pop up for indentation0-based folding: image

Thanks in advance!


#2

Hello.

If multi-level folding is possible is not clear,
but folding is possible for non-indented lines using the command foldSelectedLines

It would be possible to have some keybinding to represent heading level to fold to or some other variation on the theme.

The following code demonstrates what the Atom API can give us ->

# init.coffee
atom.commands.add 'atom-text-editor', 'test command', ->
  return false unless _editor = atom.workspace.getActiveTextEditor() # fail returns FALSE
  _buffer = _editor.buffer
  # _checkpoint = _editor.createCheckpoint()  # does not work!
  _search = /^# /g  # This would change according to what marks a heading
  _lineNr = [] # empty array saves row numbers
  
  console.log 'started: test command'

  # GET ROWS WHERE SEARCH TERM CAN BE REACHED
  _buffer.scan _search, (_grab) ->
    # ..this does a buffer wide search, 
    # but a limited search can be used instead
    # using scanInRange()
    _lineNr.push _grab.range.start.row
    
  _lineNr.push _buffer.getLastRow()  # assume until last row in buffer
  _isFirst = true  # handling first iteration as special case
  P1 = []

  # ITERATE THROUGH ROW LINE LIST
  for x in _lineNr
    if not _isFirst
      P2 = _buffer.clipPosition([x-1, 1000])  # `clip` ensures legal position point
      # console.log [P1,P2]  # ..for testing
      _editor.setSelectedBufferRange([P1,P2])  # MAKE SELECTION FOR FOLDING
      _editor.foldSelectedLines()  # INVOKE FOLDING
    P1 = _buffer.clipPosition([x, 1000])
    _isFirst = false
      
  # _editor.groupChangesSinceCheckpoint(_checkpoint) # does not work!
  return true  # feedback TRUE

Does this help to push your cause further?
- Dan Padric


Fold everything under a comment in Atom
#3

thanks for that, that’s great! learnt some stuff too :slight_smile:


#4

Mind if I turn this into the start of a package?


#5

started package markdown-fold


#6

I wrote a similar package with a few more features including fold/unfold current row. Just leaving this here in case anyone is interested