Merge remote-tracking branch 'lenormf/fix-2164'
This commit is contained in:
commit
6e635ea301
|
@ -288,30 +288,39 @@ void goto_commands(Context& context, NormalParams params)
|
||||||
}
|
}
|
||||||
case 'f':
|
case 'f':
|
||||||
{
|
{
|
||||||
auto filename = content(buffer, context.selections().main());
|
|
||||||
static constexpr char forbidden[] = { '\'', '\\', '\0' };
|
static constexpr char forbidden[] = { '\'', '\\', '\0' };
|
||||||
if (any_of(filename, [](char c){ return contains(forbidden, c); }))
|
const auto& paths_opt = context.options()["path"].get<Vector<String, MemoryDomain::Options>>();
|
||||||
return;
|
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));
|
||||||
|
|
||||||
auto paths = context.options()["path"].get<Vector<String, MemoryDomain::Options>>();
|
const StringView buffer_dir = split_path(buffer.name()).first;
|
||||||
const StringView buffer_dir = split_path(buffer.name()).first;
|
String path = find_file(filename, buffer_dir, paths_opt);
|
||||||
String path = find_file(filename, buffer_dir, paths);
|
if (path.empty())
|
||||||
if (path.empty())
|
throw runtime_error(format("unable to find file '{}'", filename));
|
||||||
throw runtime_error(format("unable to find file '{}'", filename));
|
|
||||||
|
|
||||||
Buffer* buffer = BufferManager::instance().get_buffer_ifp(path);
|
return path;
|
||||||
if (not buffer)
|
});
|
||||||
{
|
|
||||||
buffer = open_file_buffer(path, context.hooks_disabled() ?
|
Buffer* buffer_main = nullptr;
|
||||||
Buffer::Flags::NoHooks
|
for (auto&& [i, path] : paths | enumerate()) {
|
||||||
: Buffer::Flags::None);
|
Buffer* buffer = BufferManager::instance().get_buffer_ifp(path);
|
||||||
buffer->flags() &= ~Buffer::Flags::NoHooks;
|
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_main and buffer_main != &context.buffer())
|
||||||
if (buffer != &context.buffer())
|
|
||||||
{
|
{
|
||||||
context.push_jump();
|
context.push_jump();
|
||||||
context.change_buffer(*buffer);
|
context.change_buffer(*buffer_main);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
#include "constexpr_utils.hh"
|
#include "constexpr_utils.hh"
|
||||||
|
|
||||||
|
@ -155,6 +156,52 @@ inline auto filter(Filter f)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Range>
|
||||||
|
struct EnumerateView
|
||||||
|
{
|
||||||
|
using RangeIt = IteratorOf<Range>;
|
||||||
|
|
||||||
|
struct Iterator : std::iterator<std::forward_iterator_tag,
|
||||||
|
typename std::iterator_traits<RangeIt>::value_type>
|
||||||
|
{
|
||||||
|
Iterator(size_t index, RangeIt it)
|
||||||
|
: m_index{index}, m_it{std::move(it)} {}
|
||||||
|
|
||||||
|
decltype(auto) operator*() { return std::tuple<size_t, decltype(*m_it)>(m_index, *m_it); }
|
||||||
|
Iterator& operator++() { ++m_index; ++m_it; return *this; }
|
||||||
|
Iterator operator++(int) { auto copy = *this; ++(*this); return copy; }
|
||||||
|
|
||||||
|
friend bool operator==(const Iterator& lhs, const Iterator& rhs)
|
||||||
|
{
|
||||||
|
return lhs.m_it == rhs.m_it;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator!=(const Iterator& lhs, const Iterator& rhs)
|
||||||
|
{
|
||||||
|
return not (lhs == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
const RangeIt& base() const { return m_it; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
size_t m_index;
|
||||||
|
RangeIt m_it;
|
||||||
|
};
|
||||||
|
|
||||||
|
Iterator begin() const { return {0, std::begin(m_range)}; }
|
||||||
|
Iterator end() const { return {(size_t)-1, std::end(m_range)}; }
|
||||||
|
|
||||||
|
Range m_range;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline auto enumerate()
|
||||||
|
{
|
||||||
|
return make_view_factory([](auto&& range) {
|
||||||
|
using Range = decltype(range);
|
||||||
|
return EnumerateView<decay_range<Range>>{std::forward<Range>(range)};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
template<typename Range, typename Transform>
|
template<typename Range, typename Transform>
|
||||||
struct TransformView
|
struct TransformView
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user