parent
9cdfa4a81c
commit
986c91a835
|
@ -60,7 +60,7 @@ endif
|
||||||
# Picking the right name is done in the system detection switch above
|
# Picking the right name is done in the system detection switch above
|
||||||
A2X ?= a2x
|
A2X ?= a2x
|
||||||
|
|
||||||
CXXFLAGS += -std=gnu++11 -g -Wall -Wno-reorder -Wno-sign-compare
|
CXXFLAGS += -std=gnu++11 -g -Wall -Wno-reorder -Wno-sign-compare -Wno-address
|
||||||
|
|
||||||
kak : $(objects)
|
kak : $(objects)
|
||||||
$(CXX) $(LDFLAGS) $(CXXFLAGS) $(objects) $(LIBS) -o $@
|
$(CXX) $(LDFLAGS) $(CXXFLAGS) $(objects) $(LIBS) -o $@
|
||||||
|
|
22
src/main.cc
22
src/main.cc
|
@ -178,15 +178,27 @@ void register_registers()
|
||||||
register_manager.add_register('_', make_unique<NullRegister>());
|
register_manager.add_register('_', make_unique<NullRegister>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void check_positive(const int& val)
|
||||||
|
{
|
||||||
|
if (val < 1)
|
||||||
|
throw runtime_error{"value should be strictly positive"};
|
||||||
|
}
|
||||||
|
|
||||||
|
static void check_scrolloff(const CharCoord& so)
|
||||||
|
{
|
||||||
|
if (so.line < 0 or so.column < 0)
|
||||||
|
throw runtime_error{"scroll offset must be positive or zero"};
|
||||||
|
}
|
||||||
|
|
||||||
void register_options()
|
void register_options()
|
||||||
{
|
{
|
||||||
OptionsRegistry& reg = GlobalScope::instance().option_registry();
|
OptionsRegistry& reg = GlobalScope::instance().option_registry();
|
||||||
|
|
||||||
reg.declare_option("tabstop", "size of a tab character", 8);
|
reg.declare_option<int, check_positive>("tabstop", "size of a tab character", 8);
|
||||||
reg.declare_option("indentwidth", "indentation width", 4);
|
reg.declare_option<int, check_positive>("indentwidth", "indentation width", 4);
|
||||||
reg.declare_option("scrolloff",
|
reg.declare_option<CharCoord, check_scrolloff>(
|
||||||
"number of lines and columns to keep visible main cursor when scrolling",
|
"scrolloff", "number of lines and columns to keep visible main cursor when scrolling",
|
||||||
CharCoord{0,0});
|
{0,0});
|
||||||
reg.declare_option("eolformat", "end of line format: crlf or lf", EolFormat::Lf);
|
reg.declare_option("eolformat", "end of line format: crlf or lf", EolFormat::Lf);
|
||||||
reg.declare_option("BOM", "insert a byte order mark when writing buffer (none or utf8)",
|
reg.declare_option("BOM", "insert a byte order mark when writing buffer (none or utf8)",
|
||||||
ByteOrderMark::None);
|
ByteOrderMark::None);
|
||||||
|
|
|
@ -115,6 +115,7 @@ public:
|
||||||
|
|
||||||
void set(T value, bool notify = true)
|
void set(T value, bool notify = true)
|
||||||
{
|
{
|
||||||
|
validate(value);
|
||||||
if (m_value != value)
|
if (m_value != value)
|
||||||
{
|
{
|
||||||
m_value = std::move(value);
|
m_value = std::move(value);
|
||||||
|
@ -141,11 +142,6 @@ public:
|
||||||
m_manager.on_option_changed(*this);
|
m_manager.on_option_changed(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Option* clone(OptionManager& manager) const override
|
|
||||||
{
|
|
||||||
return new TypedOption{manager, m_desc, m_value};
|
|
||||||
}
|
|
||||||
|
|
||||||
using Alloc = Allocator<TypedOption, MemoryDomain::Options>;
|
using Alloc = Allocator<TypedOption, MemoryDomain::Options>;
|
||||||
static void* operator new (std::size_t sz)
|
static void* operator new (std::size_t sz)
|
||||||
{
|
{
|
||||||
|
@ -158,9 +154,23 @@ public:
|
||||||
return Alloc{}.deallocate(reinterpret_cast<TypedOption*>(ptr), 1);
|
return Alloc{}.deallocate(reinterpret_cast<TypedOption*>(ptr), 1);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
|
virtual void validate(const T& value) const {}
|
||||||
T m_value;
|
T m_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename T, void (*validator)(const T&)>
|
||||||
|
class TypedCheckedOption : public TypedOption<T>
|
||||||
|
{
|
||||||
|
using TypedOption<T>::TypedOption;
|
||||||
|
|
||||||
|
Option* clone(OptionManager& manager) const override
|
||||||
|
{
|
||||||
|
return new TypedCheckedOption{manager, this->m_desc, this->get()};
|
||||||
|
}
|
||||||
|
|
||||||
|
void validate(const T& value) const override { if (validator != nullptr) validator(value); }
|
||||||
|
};
|
||||||
|
|
||||||
template<typename T> const T& Option::get() const
|
template<typename T> const T& Option::get() const
|
||||||
{
|
{
|
||||||
auto* typed_opt = dynamic_cast<const TypedOption<T>*>(this);
|
auto* typed_opt = dynamic_cast<const TypedOption<T>*>(this);
|
||||||
|
@ -199,7 +209,7 @@ class OptionsRegistry
|
||||||
public:
|
public:
|
||||||
OptionsRegistry(OptionManager& global_manager) : m_global_manager(global_manager) {}
|
OptionsRegistry(OptionManager& global_manager) : m_global_manager(global_manager) {}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T, void (*validator)(const T&) = nullptr>
|
||||||
Option& declare_option(const String& name, const String& docstring,
|
Option& declare_option(const String& name, const String& docstring,
|
||||||
const T& value,
|
const T& value,
|
||||||
OptionFlags flags = OptionFlags::None)
|
OptionFlags flags = OptionFlags::None)
|
||||||
|
@ -213,7 +223,7 @@ public:
|
||||||
throw runtime_error(format("option '{}' already declared with different type or flags", name));
|
throw runtime_error(format("option '{}' already declared with different type or flags", name));
|
||||||
}
|
}
|
||||||
m_descs.emplace_back(new OptionDesc{name, docstring, flags});
|
m_descs.emplace_back(new OptionDesc{name, docstring, flags});
|
||||||
opts.emplace_back(new TypedOption<T>{m_global_manager, *m_descs.back(), value});
|
opts.emplace_back(new TypedCheckedOption<T, validator>{m_global_manager, *m_descs.back(), value});
|
||||||
return *opts.back();
|
return *opts.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user