diff --git a/doc/pages/commands.asciidoc b/doc/pages/commands.asciidoc index e6bf5804c..e83cdf40a 100644 --- a/doc/pages/commands.asciidoc +++ b/doc/pages/commands.asciidoc @@ -14,6 +14,12 @@ command *q!* has to be used). Aliases are mentionned below each commands. For the following *write* commands, the *-sync* switch forces the synchronization of the file onto the filesystem +*arrange-buffers* ...:: + Reorder the buffers in the buffers list. + The named buffers will be moved to the front of the buffer list, in the order + given. Buffers that do not appear in the parameters will remain at the + end of the list, keeping their current order. + *change-directory* []:: *alias* cd + change the current directory to *directory*, or the home directory if @@ -338,7 +344,7 @@ but not really useful in that context. *-title* ::: set the title of the message box - + *-markup*::: parse markup in both title (if provided) and text. (See <>) @@ -369,7 +375,7 @@ but not really useful in that context. *select* [] .,....:: replace the current selections with the ones described in the arguments - + *-timestamp* ::: specify which buffer timestamp those coordinates apply to. Uses current buffer timestamp if not specified. diff --git a/src/buffer_manager.cc b/src/buffer_manager.cc index d8d4da26c..8d17cc76f 100644 --- a/src/buffer_manager.cc +++ b/src/buffer_manager.cc @@ -105,4 +105,29 @@ void BufferManager::clear_buffer_trash() m_buffer_trash.clear(); } +void BufferManager::arrange_buffers(ConstArrayView first_ones) +{ + Vector indices; + for (const auto& name : first_ones) + { + auto it = find_if(m_buffers, [&](auto& buf) { return buf->name() == name or buf->display_name() == name; }); + if (it == m_buffers.end()) + throw runtime_error{format("no such buffer '{}'", name)}; + size_t index = it - m_buffers.begin(); + if (contains(indices, index)) + throw runtime_error{format("buffer '{}' appears more than once", name)}; + indices.push_back(index); + } + + BufferList res; + for (size_t index : indices) + res.push_back(std::move(m_buffers[index])); + for (auto& buf : m_buffers) + { + if (buf) + res.push_back(std::move(buf)); + } + m_buffers = std::move(res); +} + } diff --git a/src/buffer_manager.hh b/src/buffer_manager.hh index 0abb64154..e89fa1837 100644 --- a/src/buffer_manager.hh +++ b/src/buffer_manager.hh @@ -30,6 +30,8 @@ public: Buffer* get_buffer_ifp(StringView name); Buffer& get_buffer(StringView name); + void arrange_buffers(ConstArrayView first_ones); + Buffer& get_first_buffer(); void backup_modified_buffers(); diff --git a/src/commands.cc b/src/commands.cc index 09e73ce3d..3a14457d5 100644 --- a/src/commands.cc +++ b/src/commands.cc @@ -925,6 +925,25 @@ static void redraw_relevant_clients(Context& context, StringView highlighter_pat } } +const CommandDesc arrange_buffers_cmd = { + "arrange-buffers", + nullptr, + "arrange-buffers ...: reorder the buffers in the buffers list\n" + " the named buffers will be moved to the front of the buffer list, in the order given\n" + " buffers that do not appear in the parameters will remain at the end of the list, keeping their current order", + ParameterDesc{{}, ParameterDesc::Flags::None, 1}, + CommandFlags::None, + CommandHelper{}, + [](const Context& context, CompletionFlags flags, CommandParameters params, size_t, ByteCount cursor_pos) + { + return complete_buffer_name(context, flags, params.back(), cursor_pos); + }, + [](const ParametersParser& parser, Context&, const ShellContext&) + { + BufferManager::instance().arrange_buffers(parser.positionals_from(0)); + } +}; + const CommandDesc add_highlighter_cmd = { "add-highlighter", "addhl", @@ -2608,6 +2627,7 @@ void register_commands() register_command(delete_buffer_cmd); register_command(force_delete_buffer_cmd); register_command(rename_buffer_cmd); + register_command(arrange_buffers_cmd); register_command(add_highlighter_cmd); register_command(remove_highlighter_cmd); register_command(add_hook_cmd);