Indent/Undent Nodes

Hi,

I am trying to implement indent/undent nodes using tab for paragraphs.

For paragraphs I am just pre-pending 4 spaces for indent and removing 4 spaces (if they exist) for undent.

I have it working for single lines but for multi line selections I am not sure how to get the selected nodes.

Something like this would be great:

state.tr.getNodes($from, $to) 

Which could return an array of nodes based on the selection [node1, node2, …];

Once I have this i can apply the insertText of 4 spaces on each line.

Is there a way to get the selected nodes and iterate over them?

Also if there is a universal way to indent paragraphs that would be better than adding whitespace.

Also list items indent without creating a sublist would also be a great feature.

Eg just indent without any style change to the bullet.

Thanks

I was able to get access to the nodes in question using nodesAt(index)

Now I am struggling to combine multiple transactions for insertText() on multiple lines

It works fine on a single line but im not sure how to apply many transactions of insertText.

Any ideas how this would be done?

I tried:

tr.step(new ReplaceAroundStep(currentStart, currentStart, 0, 0, new Slice(newFragment, 0, 0), 0, false));

but I am not sure how to build the newFragment or if ReplaceAroundStep is the right approach

Thanks in advance

I think nodesBetween with a little filtering can be made to do what you want here.

I’d lean towards adding an indentation attribute on the nodes and changing their styling based on that.

1 Like

Hi @marijn. I am trying to implement indent/unindent too so I followed your advice. I added an indentation attribute to the node spec for paragraphs and it worked. When I hit Enter at the end of an indented paragraph though the new paragraph is not indented, that is it loses the attributes of the first paragraph. I fixed that by copying the splitBlock function and adding a few bits to it but overall it feels strange that the new paragraph does not keep the attributes of the one from which it was split.

If you split a paragraph in the middle, you’ll get a new paragraph with the same attributes. But when you press enter at the end splitBlock will create a fresh node (using the default content type at that position), so that when you press enter at the end of a heading or similar block, you get a plain paragraph.

Resurrecting yet another old thread :zombie:

I’m working on implementing indentation using an indentation attribute on the relevant blocks as suggested in this thread. To ensure that indentation is properly inherited, I’ve created a custom copy of the splitBlocks command with small modifications to that effect.

However, I’m beginning to worry about the number of similar commands I could end up with as I continue down this path for blocks beyond paragraph. I need all block content to be indentable – so headings, lists, etc. How will I ensure that, when I convert a series of indented paragraphs into a list, that the indentation is removed from the paragraphs and properly propagated to the list and list elements? Am I going to end up with custom copies of wrapIn and wrapInList as well? I can easily see this spiraling out of control to the point where the bug risks and maintenance burdens could threaten the feasibility of the feature.

Is the indentation attribute still the recommended approach for this functionality? Is anyone who has accomplished this willing to share their solution?

This is my solution: when the return of sinkListItem(‘listItem’) is false, insert ‘\t’ .