Back to godoc.org
github.com/godoctor/godoctor/text

package text

v0.0.0 (362e1ca)
Latest Go to latest
Published: Oct 29, 2019 | License: BSD-3-Clause | Module: github.com/godoctor/godoctor

Overview

Package text provides the text manipulation infrastructure used for refactoring, including the definition of EditSet (a set of changes to be made to a text file) and functions for creating unified diffs.

Index

func ApplyToReader

func ApplyToReader(es *EditSet, in io.Reader) ([]byte, error)

ApplyToReader reads bytes from an io.Reader, applying the edits in an EditSet and returning the result as a slice of bytes.

func ApplyToString

func ApplyToString(es *EditSet, s string) (string, error)

ApplyToString reads bytes from a string, applying the edits in an EditSet and returning the result as a string.

type EditSet

type EditSet struct {
	// contains filtered or unexported fields
}

An EditSet is a collection of changes to be made to a text file. Each edit is comprised of an offset, a length, and a replacement string.

Each edit replaces 0 or more characters at a given offset with a given string. Characters can be inserted by using a position with length 0; characters can be deleted by using an empty replacement string.

Edits are added to an EditSet via the Add method, and the edits in an EditSet can be applied to an input by invoking the ApplyTo method or one of the utility functions ApplyToString, ApplyToFile, or ApplyToReader.

func Diff

func Diff(a []string, b []string) *EditSet

Diff creates an EditSet containing the minimum number of line additions and deletions necessary to change a into b. Typically, both a and b will be slices containing \n-terminated lines of a larger string, although it is also possible compute character-by-character diffs by splitting a string on UTF-8 boundaries. The resulting EditSet is constructed so that it can be applied to the string produced by strings.Join(a, "").

Every edit in the resulting EditSet starts at an offset corresponding to the first character on a line. Every edit in the EditSet is either (1) a deletion, i.e., its length is the length of the current line and its replacement text is the empty string, or (2) an addition, i.e., its length is 0 and its replacement text is a single line to insert.

The implementation follows the pseudocode in Myers' paper (cited above) fairly closely.

func NewEditSet

func NewEditSet() *EditSet

NewEditSet returns a new, empty EditSet.

func (*EditSet) Add

func (e *EditSet) Add(pos *Extent, replacement string) error

Add inserts an edit into this EditSet, returning an error if the edit has a negative offset or overlaps an edit previously added to this EditSet.

func (*EditSet) ApplyTo

func (e *EditSet) ApplyTo(in io.Reader, out io.Writer) error

ApplyTo reads from the given reader, applying the edits in this EditSet as it reads, and writes the output to the given writer. It returns an error if there are edits with offsets beyond the end of the input or some other error occurs, such as an I/O error.

func (*EditSet) CreatePatch

func (e *EditSet) CreatePatch(in io.Reader) (result *Patch, err error)

CreatePatch creates a Patch from this EditSet. A Patch can be output as a unified diff by invoking the Patch's Write method.

func (*EditSet) Iterate

func (e *EditSet) Iterate(callback func(*Extent, string) bool)

Iterate executes the given callback on each of the edits in this EditSet, traversing the edits in ascending order by offset. Iteration stops immediately after the callback returns false.

func (*EditSet) NewOffset

func (e *EditSet) NewOffset(offset int) int

NewOffset returns the offset that will contain the "same" byte as the given offset after this edit has been applied. If the given offset occurs within a region of the text file that will be modified by this EditSet, a "close enough" offset is returned (specifically, the offset corresponding to the start of the first overlapping edit). This is intended to be used to position error messages.

func (*EditSet) OldOffset

func (e *EditSet) OldOffset(offset int) int

OldOffset takes an offset in the string that would result if this EditSet were applied and returns the corresponding offset in the unedited string. If the given offset occurs within a region of the text file that will be modified by this EditSet, a "close enough" offset is returned (specifically, the offset corresponding to the start of the first overlapping edit). This is intended to be used to position error messages.

func (*EditSet) SizeChange

func (e *EditSet) SizeChange() int64

SizeChange returns the total number of bytes that will be added or removed when this EditSet is applied. A positive value indicates that bytes will be added; negative, bytes will be removed. A zero value indicates that the total number of bytes will stay the same after the EditSet is applied.

func (*EditSet) String

func (e *EditSet) String() string

String returns a human-readable description of this EditSet (for debugging).

type Extent

type Extent struct {
	// Byte offset of the first character (0-based)
	Offset int
	// Length in bytes (nonnegative)
	Length int
}

An Extent consists of two integers: a 0-based byte offset and a nonnegative length. An Extent is used to specify a region of a string or file. For example, given the string "ABCDEFG", the substring CDE could be specified by Extent{offset: 2, length: 3}.

func Sort

func Sort(extents []*Extent) []*Extent

Sort receives a slice of Extents and returns a copy with the Extents sorted by increasing offset.

func (*Extent) Intersect

func (o *Extent) Intersect(other *Extent) *Extent

Intersect returns the intersection (i.e., the overlapping region) of two intervals, or nil iff the intervals do not overlap. A length-zero overlap is returned only if the two intervals are not adjacent.

func (*Extent) IsAdjacentTo

func (o *Extent) IsAdjacentTo(other *Extent) bool

IsAdjacentTo returns true iff two intervals describe regions immediately next to one another, such as (offset 2, length 3) and (offset 5, length 1). Specifically, [a,b) is adjacent to [c,d) iff b == c or d == a. Note that a length-zero interval is adjacent to itself.

func (*Extent) OffsetPastEnd

func (o *Extent) OffsetPastEnd() int

OffsetPastEnd returns the offset of the first byte immediately beyond the end of this region. For example, a region at offset 2 with length 3 occupies bytes 2 through 4, so this method would return 5.

func (*Extent) String

func (o *Extent) String() string

type LineColSelection

type LineColSelection struct {
	Filename  string
	StartLine int
	StartCol  int
	EndLine   int
	EndCol    int
}

A LineColSelection is a Selection consisting of a filename, the line/column where the selected text begins, and the line/column where the text selection ends. The end line and column must be greater than or equal to the start line and column, respectively. Line and column numbers are 1-based. The end position is inclusive, so a LineColSelection always represents a selection of at least one character.

func (*LineColSelection) Convert

func (lc *LineColSelection) Convert(fset *token.FileSet) (token.Pos, token.Pos, error)

Convert returns start and end positions corresponding to this selection. It returns an error if this selection corresponds to a file that is not in the given FileSet, or if the selected region is not in range.

func (*LineColSelection) GetFilename

func (lc *LineColSelection) GetFilename() string

GetFilename returns the file containing this selection. The returned filename may be an absolute or relative path and does is not guaranteed to correspond to a valid file.

func (*LineColSelection) String

func (lc *LineColSelection) String() string

type OffsetLengthSelection

type OffsetLengthSelection struct {
	Filename string
	Offset   int
	Length   int
}

An OffsetLengthSelection is a Selection consisting of a filename, an offset (a nonnegative byte offset where the text selection begins), and a length (a nonnegative integer describing the number of bytes in the selection). The first byte in a file is considered to be at offset 0. A selection of length 0 is permissible.

func (*OffsetLengthSelection) Convert

func (ol *OffsetLengthSelection) Convert(fset *token.FileSet) (token.Pos, token.Pos, error)

Convert returns start and end positions corresponding to this selection. It returns an error if this selection corresponds to a file that is not in the given FileSet, or if the selected region is not in range.

func (*OffsetLengthSelection) GetFilename

func (ol *OffsetLengthSelection) GetFilename() string

GetFilename returns the file containing this selection. The returned filename may be an absolute or relative path and does is not guaranteed to correspond to a valid file.

func (*OffsetLengthSelection) String

func (ol *OffsetLengthSelection) String() string

type Patch

type Patch struct {
	// contains filtered or unexported fields
}

A Patch is an object representing a unified diff. It can be created from an EditSet by invoking the CreatePatch method. To get the contents of the unified diff, invoke the Write method.

func (*Patch) IsEmpty

func (p *Patch) IsEmpty() bool

IsEmpty returns true iff this patch contains no hunks

func (*Patch) Write

func (p *Patch) Write(origFile, newFile string, origTime, newTime time.Time, out io.Writer) error

Write writes a unified diff to the given io.Writer. The given filenames are used in the diff output.

type Selection

type Selection interface {
	// Convert returns start and end positions corresponding to this
	// selection.  It returns an error if this selection corresponds to a
	// file that is not in the given FileSet, or if the selected region is
	// not in range.
	Convert(*token.FileSet) (token.Pos, token.Pos, error)
	// GetFilename returns the file containing this selection.  The
	// returned filename may be an absolute or relative path and does is
	// not guaranteed to correspond to a valid file.
	GetFilename() string
	// String returns a human-readable representation of this Selection.
	String() string
}

A Selection represents a range of text within a particular file. It is used to represent a selection in a text editor.

func NewSelection

func NewSelection(filename string, pos string) (Selection, error)

NewSelection takes an input string of the form "line,col:line,col" or "offset,length" and returns a Selection (either LineColSelection or OffsetLengthSelection) corresponding to that selection in the given file.

Documentation was rendered with GOOS=linux and GOARCH=amd64.

Jump to identifier

Keyboard shortcuts

? : This menu
f or F : Jump to identifier