2

I am building a YAML editor in a RichTextFX CodeArea (which I believe is a type of TextArea). I'd like to maintain the current level of indentation when I hit Enter. So for example:

- item1: foo
  item1A:
    subElement: A
<there should be 4 spaces here after I hit enter>

Alternatively, if somebody already has built a yaml editor in RichTextFX or JavaFX, I'd love a link to it.

When I hit enter after this, to add a subelement unde

Steve
  • 4,457
  • 12
  • 48
  • 89

2 Answers2

1

You can try the following:

Pattern whiteSpace = Pattern.compile( "^\\s+" );

codeArea.addEventFilter( KeyEvent.KEY_PRESSED, KE ->
{
    if ( KE.getCode() == KeyCode.ENTER )
    {
        Matcher m = whiteSpace.matcher( codeArea.getParagraph( codeArea.getCurrentParagraph() ).getSegments().get( 0 ) );
        if ( m.find() ) Platform.runLater( () -> codeArea.insertText( codeArea.getCaretPosition(), m.group() ) );
    }
});
Jurgen
  • 2,138
  • 12
  • 18
0

Here's a little helper class I wrote that will keep indentation or even increase indentation one level, if the current line ends in a given suffix. It uses the InputMap-API of RichTextFX.

import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.fxmisc.richtext.GenericStyledArea;
import org.fxmisc.wellbehaved.event.EventPattern;
import org.fxmisc.wellbehaved.event.InputMap;
import org.fxmisc.wellbehaved.event.Nodes;  
import javafx.scene.input.KeyCode;

public class RichTextFXAutoIndenter {
    
    private static final Pattern LEADING_WHITESPACE = Pattern.compile( "^\\s+" );

    public static void install(GenericStyledArea<?, String, ?> genericStyledArea, String ... indentSuffixes) {
        Nodes.addInputMap(genericStyledArea, InputMap.consume(EventPattern.keyPressed(KeyCode.ENTER), event -> enterPressed(genericStyledArea, indentSuffixes)));       
    }
    
    private static void enterPressed(GenericStyledArea<?, String, ?> genericStyledArea, String[] indentSuffixes) {
        genericStyledArea.replaceSelection("\n" + getIndentation(genericStyledArea, indentSuffixes));
    }
    
    private static String getIndentation(GenericStyledArea<?, String, ?> genericStyledArea, String[] indentSuffixes) {
        String currentLine = genericStyledArea.getParagraph(genericStyledArea.getCurrentParagraph()).getSegments().get(0);
        Matcher m = LEADING_WHITESPACE.matcher(currentLine);
        String indent = "";
        if (m.find()) {
            indent =  m.group();
        }
        if (Arrays.stream(indentSuffixes).anyMatch(suffix -> currentLine.trim().endsWith(suffix))) {
            indent += "\t";
        }
        return indent;
    }
}
rli
  • 1,745
  • 1
  • 14
  • 25
  • 1
    ```indent = '\t'+indent;``` would be better, if the previous line has spaces at the end to line something up - You don't want to have spaces before tabs. – swpalmer Dec 12 '22 at 18:40