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
impl Buffer
sourcepub fn delete(&mut self)
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");
sourcepub fn delete_range(&mut self, range: Range)
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
impl Buffer
sourcepub fn start_operation_group(&mut self)
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.
sourcepub fn end_operation_group(&mut self)
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
impl Buffer
sourcepub fn replace<T: Into<String> + AsRef<str>>(&mut self, content: T)
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.
§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
impl Buffer
sourcepub fn new() -> Buffer
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();
sourcepub fn from_file(path: &Path) -> Result<Buffer>
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");
sourcepub fn data(&self) -> String
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");
sourcepub fn save(&mut self) -> Result<()>
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();
sourcepub fn file_name(&self) -> Option<String>
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");
sourcepub fn undo(&mut self)
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());
sourcepub fn redo(&mut self)
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());
sourcepub fn read(&self, range: &Range) -> Option<String>
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());
sourcepub fn search(&self, needle: &str) -> Vec<Position>
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 }
]
);
sourcepub fn modified(&self) -> bool
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());
sourcepub fn line_count(&self) -> usize
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);
sourcepub fn reload(&mut self) -> Result<()>
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 });
sourcepub fn file_extension(&self) -> Option<String>
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());