Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement buffer ordering #10077

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 34 additions & 4 deletions helix-term/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,8 @@ impl MappableCommand {
command_palette, "Open command palette",
goto_word, "Jump to a two-character label",
extend_to_word, "Extend to a two-character label",
buffer_order_increment, "Increment current buffer's order",
buffer_order_decrement, "Decrement current buffer's order",
);
}

Expand Down Expand Up @@ -800,16 +802,16 @@ fn goto_buffer(editor: &mut Editor, direction: Direction) {

let id = match direction {
Direction::Forward => {
let iter = editor.documents.keys();
let iter = editor.document_ordering.iter();
let mut iter = iter.skip_while(|id| *id != &current);
iter.next(); // skip current item
iter.next().or_else(|| editor.documents.keys().next())
iter.next().or_else(|| editor.document_ordering.first())
}
Direction::Backward => {
let iter = editor.documents.keys();
let iter = editor.document_ordering.iter();
let mut iter = iter.rev().skip_while(|id| *id != &current);
iter.next(); // skip current item
iter.next().or_else(|| editor.documents.keys().next_back())
iter.next().or_else(|| editor.document_ordering.last())
}
}
.unwrap();
Expand Down Expand Up @@ -5840,6 +5842,34 @@ fn extend_to_word(cx: &mut Context) {
jump_to_word(cx, Movement::Extend)
}

fn buffer_order_increment(cx: &mut Context) {
let current_doc_id = doc_mut!(cx.editor).id();
let doc_idx = cx
.editor
.document_ordering
.iter()
.position(|id| id == &current_doc_id)
.unwrap();

if doc_idx < cx.editor.document_ordering.len() - 1 {
cx.editor.document_ordering.swap(doc_idx, doc_idx + 1);
}
}

fn buffer_order_decrement(cx: &mut Context) {
let current_doc_id = doc_mut!(cx.editor).id();
let doc_idx = cx
.editor
.document_ordering
.iter()
.position(|id| id == &current_doc_id)
.unwrap();

if doc_idx > 0 {
cx.editor.document_ordering.swap(doc_idx, doc_idx - 1);
}
}

fn jump_to_label(cx: &mut Context, labels: Vec<Range>, behaviour: Movement) {
let doc = doc!(cx.editor);
let alphabet = &cx.editor.config().jump_label_alphabet;
Expand Down
50 changes: 28 additions & 22 deletions helix-term/src/ui/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -582,31 +582,37 @@ impl EditorView {
let mut x = viewport.x;
let current_doc = view!(editor).doc;

for doc in editor.documents() {
let fname = doc
.path()
.unwrap_or(&scratch)
.file_name()
.unwrap_or_default()
.to_str()
.unwrap_or_default();

let style = if current_doc == doc.id() {
bufferline_active
} else {
bufferline_inactive
};
for doc_id in &editor.document_ordering {
if let Some(doc) = editor.documents.get(doc_id) {
let fname = doc
.path()
.unwrap_or(&scratch)
.file_name()
.unwrap_or_default()
.to_str()
.unwrap_or_default();

let style = if current_doc == doc.id() {
bufferline_active
} else {
bufferline_inactive
};

let text = format!(" {}{} ", fname, if doc.is_modified() { "[+]" } else { "" });
let used_width = viewport.x.saturating_sub(x);
let rem_width = surface.area.width.saturating_sub(used_width);
let text = format!(" {}{} ", fname, if doc.is_modified() { "[+]" } else { "" });
let used_width = viewport.x.saturating_sub(x);
let rem_width = surface.area.width.saturating_sub(used_width);

x = surface
.set_stringn(x, viewport.y, text, rem_width as usize, style)
.0;
x = surface
.set_stringn(x, viewport.y, text, rem_width as usize, style)
.0;

if x >= surface.area.right() {
break;
if x >= surface.area.right() {
break;
}
} else {
log::error!(
"document id in document ordering not found in document list, ID: {doc_id}"
)
}
}
}
Expand Down
18 changes: 18 additions & 0 deletions helix-view/src/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -937,6 +937,8 @@ pub struct Editor {
pub next_document_id: DocumentId,
pub documents: BTreeMap<DocumentId, Document>,

pub document_ordering: Vec<DocumentId>,

// We Flatten<> to resolve the inner DocumentSavedEventFuture. For that we need a stream of streams, hence the Once<>.
// https://stackoverflow.com/a/66875668
pub saves: HashMap<DocumentId, UnboundedSender<Once<DocumentSavedEventFuture>>>,
Expand Down Expand Up @@ -1085,6 +1087,7 @@ impl Editor {
tree: Tree::new(area),
next_document_id: DocumentId::default(),
documents: BTreeMap::new(),
document_ordering: Vec::new(),
saves: HashMap::new(),
save_queue: SelectAll::new(),
write_count: 0,
Expand Down Expand Up @@ -1495,6 +1498,15 @@ impl Editor {
// borrow, invalidating direct access to `doc.id`.
let id = doc.id;
self.documents.remove(&id);
if let Some(d_idx) = self
.document_ordering
.iter()
.position(|doc_id| doc_id == &id)
{
self.document_ordering.remove(d_idx);
} else {
log::error!("closed document not found in document ordering, ID: {id}")
}

// Remove the scratch buffer from any jumplists
for (view, _) in self.tree.views_mut() {
Expand Down Expand Up @@ -1560,6 +1572,7 @@ impl Editor {
DocumentId(unsafe { NonZeroUsize::new_unchecked(self.next_document_id.0.get() + 1) });
doc.id = id;
self.documents.insert(id, doc);
self.document_ordering.push(id);

let (save_sender, save_receiver) = tokio::sync::mpsc::unbounded_channel();
self.saves.insert(id, save_sender);
Expand Down Expand Up @@ -1696,6 +1709,11 @@ impl Editor {
}

self.documents.remove(&doc_id);
if let Some(d_idx) = self.document_ordering.iter().position(|id| id == &doc_id) {
self.document_ordering.remove(d_idx);
} else {
log::error!("closed document not found in document ordering, ID: {doc_id}")
}

// If the document we removed was visible in all views, we will have no more views. We don't
// want to close the editor just for a simple buffer close, so we need to create a new view
Expand Down