Interface TextDocument

All Superinterfaces:
AutoCloseable, Closeable

public interface TextDocument extends Closeable
Represents a textual document, providing methods to edit it incrementally and address regions of text. A text document delegates IO operations to a TextFile. It reflects some in-memory snapshot of the file, though the file may still be edited externally.

Note that the backing TextFile is purposefully not accessible from a text document. Exposing it here could lead to files being written to from within rules, while we want to eventually build an API that allows file edition based on AST manipulation.

Coordinates in TextDocument

This interface is an abstraction over a piece of text, which might not correspond to the backing source file. This allows the document to be a view on a piece of a larger document (eg, a Javadoc comment, or a string in which a language is injected). Another use case is to perform escape translation, while preserving the line breaks of the original source.

This complicates addressing within a text document. To explain it, consider that there is always *one* text document that corresponds to the backing text file, which we call the root text document. Logical documents built on top of it are called views.

Text documents use offsets and TextRegion to address their contents. These are always relative to the text of the document. Line and column information are provided by FileLocation (see toLocation(TextRegion)), and are always absolute (ie, represent actual source lines in the file).

For instance, say you have the following file (and root text document):


 l1
 l2 (* comment *)
 l3
 
and you create a view for just the section (* comment *). Then, that view's offset 0 (start of the document) will map to the ( character, while the root document's offset 0 maps to the start of l1. When calling toLocation(caretAt(0)), the view will however return line 2, column 4, ie, a line/column that can be found when inspecting the file.

To reduce the potential for mistakes, views do not provide access to their underlying text document. That way, nodes only have access to a single document, and their offsets can be assumed to be in the coordinate system of that document.

This interface does not provide a way to obtain line/column coordinates that are relative to a view's coordinate system. This would complicate the construction of views significantly.

  • Method Details

    • getLanguageVersion

      LanguageVersion getLanguageVersion()
      Returns the language version that should be used to parse this file.
    • getFileId

      FileId getFileId()
      Returns TextFile.getFileId() for the text file backing this document.
    • getText

      Chars getText()
      Returns the current text of this document. Note that this doesn't take external modifications to the TextFile into account.

      Line endings are normalized to TextFileContent.NORMALIZED_LINE_TERM.

      See Also:
    • sliceOriginalText

      Chars sliceOriginalText(TextRegion region)
      Returns a slice of the original text. Note that this is not the same as getText().subsequence, as if this document has translated escapes, the returned char slice will contain the untranslated escapes, whereas getText() would return the translated characters.
      Parameters:
      region - A region, in the coordinate system of this document
      Returns:
      The slice of the original text that corresponds to the region
      Throws:
      IndexOutOfBoundsException - If the region is not a valid range
    • sliceTranslatedText

      default Chars sliceTranslatedText(TextRegion region)
      Returns a slice of the source text. This is always equal to getText().slice(region), as the text is the translated text.
      Parameters:
      region - A region, in the coordinate system of this document
      Returns:
      The slice of the original text that corresponds to the region
      Throws:
      IndexOutOfBoundsException - If the region is not a valid range
    • getCheckSum

      long getCheckSum()
      Returns a checksum for the contents of the file.
      See Also:
    • newReader

      default Reader newReader()
      Returns a reader over the text of this document.
    • getLength

      default int getLength()
      Returns the length in characters of the text.
    • getEntireRegion

      default TextRegion getEntireRegion()
      Returns a text region that corresponds to the entire document, in the coordinate system of this document.
    • createLineRange

      TextRegion createLineRange(int startLineInclusive, int endLineInclusive)
      Returns a region that spans the text of all the given lines.

      Note that, as line numbers may only be obtained from toLocation(TextRegion), and hence are line numbers of the original source, both parameters must be line numbers of the source text and not the translated text that this represents.

      Parameters:
      startLineInclusive - Inclusive start line number (1-based)
      endLineInclusive - Inclusive end line number (1-based)
      Throws:
      IndexOutOfBoundsException - If the arguments do not identify a valid region in the source document
    • toLocation

      FileLocation toLocation(TextRegion region)
      Turn a text region into a FileLocation. This computes the line/column information for both start and end offset of the region.
      Parameters:
      region - A region, in the coordinate system of this document
      Returns:
      A new file position, with absolute coordinates
      Throws:
      IndexOutOfBoundsException - If the argument is not a valid region in this document
    • lineColumnAtOffset

      default TextPos2d lineColumnAtOffset(int offset)
      Returns the line and column at the given offset (inclusive).
      Parameters:
      offset - A source offset (0-based), can range in [0, length].
      Throws:
      IndexOutOfBoundsException - if the offset is out of bounds
      See Also:
    • lineColumnAtOffset

      TextPos2d lineColumnAtOffset(int offset, boolean inclusive)
      Returns the line and column at the given offset. Both the input offset and the output range are in the coordinates of this document.
      Parameters:
      offset - A source offset (0-based), can range in [0, length].
      inclusive - If the offset falls right after a line terminator, two behaviours are possible. If the parameter is true, choose the position at the start of the next line, otherwise choose the position at the end of the line.
      Returns:
      A position, in the coordinate system of the root document
      Throws:
      IndexOutOfBoundsException - if the offset is out of bounds
      See Also:
    • offsetAtLineColumn

      int offsetAtLineColumn(TextPos2d position)
      Calculates the offset from a given line/column.
      Parameters:
      position - the line/column
      See Also:
    • close

      void close() throws IOException
      Closing a document closes the underlying TextFile. New editors cannot be produced after that, and the document otherwise remains in its current state.
      Specified by:
      close in interface AutoCloseable
      Specified by:
      close in interface Closeable
      Throws:
      IOException - If TextFile.close() throws
      IllegalStateException - If an editor is currently open. In this case the editor is rendered ineffective before the exception is thrown. This indicates a programming mistake.
    • create

      static TextDocument create(TextFile textFile) throws IOException
      Create a new text document for the given text file. The document's coordinate system is the same as the original text file.
      Parameters:
      textFile - A text file
      Returns:
      A new text document
      Throws:
      IOException - If the file cannot be read (TextFile.readContents())
      NullPointerException - If the parameter is null
    • readOnlyString

      static TextDocument readOnlyString(CharSequence source, LanguageVersion lv)
      Returns a read-only document for the given text.
      See Also:
    • readOnlyString

      static TextDocument readOnlyString(@NonNull CharSequence source, @NonNull FileId filename, @NonNull LanguageVersion lv)
      Returns a read-only document for the given text. This works as if by calling create(TextFile) on a textfile produced by forString, but doesn't throw IOException, as such text files will not throw.
      See Also: