Struct scribe::buffer::Buffer

source ·
pub struct Buffer {
    pub id: Option<usize>,
    pub path: Option<PathBuf>,
    pub cursor: Cursor,
    pub syntax_definition: Option<SyntaxReference>,
    pub change_callback: Option<Box<dyn Fn(Position)>>,
    /* private fields */
}
Expand description

A feature-rich wrapper around an underlying gap buffer.

The buffer type wraps an in-memory buffer, providing file I/O, a bounds-checked moveable cursor, undo/redo history, simple type/format detection. When managed through a Workspace, its id field is populated with a unique value within the workspace, and its data can be lexed, producing categorized tokens suitable for syntax-highlighted display.

If the buffer is configured with a change_callback, it will be called with a position whenever the buffer is modified; it’s particularly useful for cache invalidation.

Fields§

§id: Option<usize>§path: Option<PathBuf>§cursor: Cursor§syntax_definition: Option<SyntaxReference>§change_callback: Option<Box<dyn Fn(Position)>>

Implementations§

source§

impl Buffer

source

pub fn delete(&mut self)

Deletes a character at the cursor position. If at the end of the current line, it’ll try to delete a newline character (joining the lines), succeeding if there’s a line below.

§Examples
use scribe::Buffer;

let mut buffer = Buffer::new();
buffer.insert("scribe");
buffer.delete();
assert_eq!(buffer.data(), "cribe");
source

pub fn delete_range(&mut self, range: Range)

Removes a range of characters from the buffer.

§Examples
use scribe::Buffer;
use scribe::buffer::{Position, Range};

// Set up an example buffer.
let mut buffer = Buffer::new();
buffer.insert("scribe library");

// Set up the range we'd like to delete.
let start = Position{ line: 0, offset: 6 };
let end = Position{ line: 0, offset: 14 };
let range = Range::new(start, end);

buffer.delete_range(range);

assert_eq!(buffer.data(), "scribe");
source§

impl Buffer

source

pub fn start_operation_group(&mut self)

Tells the buffer to start tracking operations as a single unit, until end_operation_group is called. Any calls to insert or delete occurring within these will be undone/applied together when calling undo/redo, respectively.

source

pub fn end_operation_group(&mut self)

Tells the buffer to stop tracking operations as a single unit, since start_operation_group was called. Any calls to insert or delete occurring within these will be undone/applied together when calling undo/redo, respectively.

source§

impl Buffer

source

pub fn insert<T: Into<String>>(&mut self, data: T)

Inserts data into the buffer at the cursor position.

§Examples
use scribe::Buffer;

let mut buffer = Buffer::new();
buffer.insert("scribe");
assert_eq!(buffer.data(), "scribe");
source§

impl Buffer

source

pub fn replace<T: Into<String> + AsRef<str>>(&mut self, content: T)

Replaces the buffer’s contents with the provided data. This method will make best efforts to retain the full cursor position, then cursor line, and will ultimately fall back to resetting the cursor to its initial (0,0) position if these fail. The buffer’s ID, syntax definition, and change callback are always persisted.

As this is a reversible operation, both the before and after buffer contents are kept in-memory, which for large buffers may be relatively expensive. To help avoid needless replacements, this method will ignore requests that don't actually change content. Despite this, use this operation judiciously; it is designed for wholesale replacements (e.g. external formatting tools) that cannot be broken down into selective delete/insert operations.
§Examples
use scribe::buffer::{Buffer, Position};

let mut buffer = Buffer::new();
buffer.insert("scribe\nlibrary\n");
buffer.cursor.move_to(Position { line: 1, offset: 1 });
buffer.replace("new\ncontent");

assert_eq!(buffer.data(), "new\ncontent");
assert_eq!(*buffer.cursor, Position{ line: 1, offset: 1 });
source§

impl Buffer

source

pub fn new() -> Buffer

Creates a new empty buffer. The buffer’s cursor is set to the beginning of the buffer.

§Examples
use scribe::Buffer;

let buffer = Buffer::new();
source

pub fn from_file(path: &Path) -> Result<Buffer>

Creates a new buffer by reading the UTF-8 interpreted file contents of the specified path. The buffer’s cursor is set to the beginning of the buffer. The buffer data’s type will be inferred based on its extension, and an appropriate lexer will be used, if available (see tokens method for further information on why this happens). The provided path is converted to its canonical, absolute equivalent, and stored alongside the buffer data.

§Examples
use scribe::Buffer;
use std::path::Path;

let file_path = Path::new("tests/sample/file");
let mut buffer = Buffer::from_file(file_path).unwrap();
assert_eq!(buffer.data(), "it works!\n");
source

pub fn data(&self) -> String

Returns the contents of the buffer as a string.

§Examples
use scribe::Buffer;

let mut buffer = Buffer::new();
buffer.insert("scribe");
assert_eq!(buffer.data(), "scribe");
source

pub fn save(&mut self) -> Result<()>

Writes the contents of the buffer to its path.

§Examples
use scribe::Buffer;

// Set up a buffer and point it to a path.
let mut buffer = Buffer::new();
let write_path = PathBuf::from("my_doc");
buffer.path = Some(write_path.clone());

// Put some data into the buffer and save it.
buffer.insert("scribe");
buffer.save();

source

pub fn file_name(&self) -> Option<String>

Returns the file name portion of the buffer’s path, if the path is set and its file name is a valid UTF-8 sequence.

§Examples
use scribe::Buffer;
use std::path::Path;

let file_path = Path::new("tests/sample/file");
let buffer = Buffer::from_file(file_path).unwrap();
assert_eq!(buffer.file_name().unwrap(), "file");
source

pub fn undo(&mut self)

Reverses the last modification to the buffer.

§Examples
use scribe::Buffer;
use scribe::buffer::Position;

let mut buffer = Buffer::new();
// Run an initial insert operation.
buffer.insert("scribe");
buffer.cursor.move_to(Position{ line: 0, offset: 6});

// Run a second insert operation.
buffer.insert(" library");
assert_eq!("scribe library", buffer.data());

// Undo the second operation.
buffer.undo();
assert_eq!("scribe", buffer.data());

// Undo the first operation.
buffer.undo();
assert_eq!("", buffer.data());
source

pub fn redo(&mut self)

Re-applies the last undone modification to the buffer.

§Examples
use scribe::Buffer;

let mut buffer = Buffer::new();
buffer.insert("scribe");

buffer.undo();
assert_eq!("", buffer.data());

buffer.redo();
assert_eq!("scribe", buffer.data());
source

pub fn read(&self, range: &Range) -> Option<String>

Tries to read the specified range from the buffer.

§Examples
use scribe::Buffer;
use scribe::buffer::{Position, Range};

let mut buffer = Buffer::new();
buffer.insert("scribe");

let range = Range::new(
    Position{ line: 0, offset: 1 },
    Position{ line: 0, offset: 5 }
);
assert_eq!("crib", buffer.read(&range).unwrap());
source

pub fn search(&self, needle: &str) -> Vec<Position>

Searches the buffer for (and returns positions associated with) occurrences of needle.

§Examples
use scribe::Buffer;
use scribe::buffer::Position;

let mut buffer = Buffer::new();
buffer.insert("scribe\nlibrary");

assert_eq!(
    buffer.search("ib"),
    vec![
        Position{ line: 0, offset: 3 },
        Position{ line: 1, offset: 1 }
    ]
);
source

pub fn modified(&self) -> bool

Whether or not the buffer has been modified since being read from or written to disk. Buffers without paths are always considered modified.

§Examples
use scribe::Buffer;
use std::path::Path;

let file_path = Path::new("tests/sample/file");
let mut buffer = Buffer::from_file(file_path).unwrap();

assert!(!buffer.modified());

// Inserting data into a buffer will flag it as modified.
buffer.insert("scribe");
assert!(buffer.modified());

// Undoing the modification reverses the flag.
buffer.undo();
assert!(!buffer.modified());

// Buffers without paths are always modified.
buffer = Buffer::new();
assert!(buffer.modified());
source

pub fn line_count(&self) -> usize

The number of lines in the buffer, including trailing newlines.

§Examples
use scribe::Buffer;

let mut buffer = Buffer::new();
buffer.insert("scribe\nlibrary\n");

assert_eq!(buffer.line_count(), 3);
source

pub fn reload(&mut self) -> Result<()>

Reloads the buffer from disk, discarding any in-memory modifications and history. This method will make best efforts to retain the full cursor position, then cursor line, and will ultimately fall back to resetting the cursor to its initial (0,0) position if these fail. The buffer’s ID, syntax definition, and change_callback are always persisted.

§Examples
use scribe::buffer::{Buffer, Position};
use std::path::Path;

let file_path = Path::new("tests/sample/file");
let mut buffer = Buffer::from_file(file_path).unwrap();
buffer.insert("scribe\nlibrary\n");
buffer.cursor.move_to(Position { line: 1, offset: 0 });
buffer.reload();

assert_eq!(buffer.data(), "it works!\n");
assert_eq!(*buffer.cursor, Position{ line: 1, offset: 0 });
source

pub fn file_extension(&self) -> Option<String>

Returns the buffer path’s file extension.

If the buffer has no path configured, or if the filename portion of the path contains no extension, it returns None.

§Examples
use scribe::buffer::Buffer;
use std::path::PathBuf;

let mut buffer = Buffer::new();

buffer.path = Some(PathBuf::from("file.txt"));
assert_eq!(buffer.file_extension().unwrap(), "txt");

buffer.path = Some(PathBuf::from("Makefile"));
assert!(buffer.file_extension().is_none());

Trait Implementations§

source§

impl Default for Buffer

source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl !RefUnwindSafe for Buffer

§

impl !Send for Buffer

§

impl !Sync for Buffer

§

impl Unpin for Buffer

§

impl !UnwindSafe for Buffer

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.