From 16dfe977b23e92d6317869bb4bcf4e3839516bd3 Mon Sep 17 00:00:00 2001 From: Frank LENORMAND Date: Wed, 20 Oct 2021 21:44:31 +0200 Subject: src: Make `gf` open all selected paths The buffer whose path is under the main selection will be focused after all others have been opened. Closes #2164 --- src/normal.cc | 45 +++++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 18 deletions(-) (limited to 'src/normal.cc') diff --git a/src/normal.cc b/src/normal.cc index af6a4459..64daabc6 100644 --- a/src/normal.cc +++ b/src/normal.cc @@ -288,30 +288,39 @@ void goto_commands(Context& context, NormalParams params) } case 'f': { - auto filename = content(buffer, context.selections().main()); static constexpr char forbidden[] = { '\'', '\\', '\0' }; - if (any_of(filename, [](char c){ return contains(forbidden, c); })) - return; + const auto& paths_opt = context.options()["path"].get>(); + const auto paths = context.selections() | transform([&](const auto& sel) { + auto filename = content(buffer, sel); + if (any_of(filename, [](char c){ return contains(forbidden, c); })) + throw runtime_error(format("filename contains invalid characters: '{}'", filename)); + + const StringView buffer_dir = split_path(buffer.name()).first; + String path = find_file(filename, buffer_dir, paths_opt); + if (path.empty()) + throw runtime_error(format("unable to find file '{}'", filename)); + + return path; + }); - auto paths = context.options()["path"].get>(); - const StringView buffer_dir = split_path(buffer.name()).first; - String path = find_file(filename, buffer_dir, paths); - if (path.empty()) - throw runtime_error(format("unable to find file '{}'", filename)); + Buffer* buffer_main = nullptr; + for (auto&& [i, path] : paths | enumerate()) { + Buffer* buffer = BufferManager::instance().get_buffer_ifp(path); + if (not buffer) + { + buffer = open_file_buffer(path, context.hooks_disabled() ? + Buffer::Flags::NoHooks + : Buffer::Flags::None); + buffer->flags() &= ~Buffer::Flags::NoHooks; + } - Buffer* buffer = BufferManager::instance().get_buffer_ifp(path); - if (not buffer) - { - buffer = open_file_buffer(path, context.hooks_disabled() ? - Buffer::Flags::NoHooks - : Buffer::Flags::None); - buffer->flags() &= ~Buffer::Flags::NoHooks; + if (i == context.selections().main_index()) + buffer_main = buffer; } - - if (buffer != &context.buffer()) + if (buffer_main and buffer_main != &context.buffer()) { context.push_jump(); - context.change_buffer(*buffer); + context.change_buffer(*buffer_main); } break; } -- cgit v1.2.3