Change +
command not to duplicate identical selections more than once
The current exponential behaviour does not seem that useful, it seems more predictible that pressing `+` twice would end up with 3 copies of the original selections instead of 4. Fixes #4533
This commit is contained in:
parent
0a06d9acbd
commit
6942a4c0c9
|
@ -3,6 +3,11 @@
|
||||||
This changelog contains major and/or breaking changes to Kakoune between
|
This changelog contains major and/or breaking changes to Kakoune between
|
||||||
released versions.
|
released versions.
|
||||||
|
|
||||||
|
== Development version
|
||||||
|
|
||||||
|
* `+` only duplicates identical selections a single time to avoid surprising
|
||||||
|
and slow exponential growth in the number of selections.
|
||||||
|
|
||||||
== Kakoune 2023.08.08
|
== Kakoune 2023.08.08
|
||||||
|
|
||||||
* Fix compilation errors on FreeBSD and MacOS using clang
|
* Fix compilation errors on FreeBSD and MacOS using clang
|
||||||
|
|
|
@ -45,6 +45,9 @@ struct {
|
||||||
unsigned int version;
|
unsigned int version;
|
||||||
StringView notes;
|
StringView notes;
|
||||||
} constexpr version_notes[] = { {
|
} constexpr version_notes[] = { {
|
||||||
|
0,
|
||||||
|
"» {+b}+{} only duplicates identical selections a single time\n"
|
||||||
|
}, {
|
||||||
20230805,
|
20230805,
|
||||||
"» Fix FreeBSD/MacOS clang compilation\n"
|
"» Fix FreeBSD/MacOS clang compilation\n"
|
||||||
}, {
|
}, {
|
||||||
|
|
|
@ -2191,9 +2191,17 @@ void duplicate_selections(Context& context, NormalParams params)
|
||||||
SelectionList& sels = context.selections();
|
SelectionList& sels = context.selections();
|
||||||
Vector<Selection> new_sels;
|
Vector<Selection> new_sels;
|
||||||
const int count = params.count ? params.count : 2;
|
const int count = params.count ? params.count : 2;
|
||||||
|
BasicSelection last{BufferCoord{-1,-1}};
|
||||||
|
size_t index = 0;
|
||||||
|
size_t main_index = 0;
|
||||||
for (const auto& sel : sels)
|
for (const auto& sel : sels)
|
||||||
new_sels.insert(new_sels.end(), count, sel);
|
{
|
||||||
context.selections().set(std::move(new_sels), sels.main_index() * count);
|
new_sels.insert(new_sels.end(), sel != last ? count : 1, sel);
|
||||||
|
last = sel;
|
||||||
|
if (index++ == sels.main_index())
|
||||||
|
main_index = new_sels.size() - 1;
|
||||||
|
}
|
||||||
|
context.selections().set(std::move(new_sels), main_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void force_redraw(Context& context, NormalParams)
|
void force_redraw(Context& context, NormalParams)
|
||||||
|
|
|
@ -13,17 +13,14 @@ using CaptureList = Vector<String, MemoryDomain::Selections>;
|
||||||
constexpr ColumnCount max_column{std::numeric_limits<int>::max()};
|
constexpr ColumnCount max_column{std::numeric_limits<int>::max()};
|
||||||
constexpr ColumnCount max_non_eol_column{max_column-1};
|
constexpr ColumnCount max_non_eol_column{max_column-1};
|
||||||
|
|
||||||
// A selection is a Selection, associated with a CaptureList
|
struct BasicSelection
|
||||||
struct Selection
|
|
||||||
{
|
{
|
||||||
static constexpr MemoryDomain Domain = MemoryDomain::Selections;
|
static constexpr MemoryDomain Domain = MemoryDomain::Selections;
|
||||||
|
|
||||||
Selection() = default;
|
BasicSelection() = default;
|
||||||
Selection(BufferCoord pos) : Selection(pos,pos) {}
|
BasicSelection(BufferCoord pos) : BasicSelection(pos,pos) {}
|
||||||
Selection(BufferCoord anchor, BufferCoordAndTarget cursor,
|
BasicSelection(BufferCoord anchor, BufferCoordAndTarget cursor)
|
||||||
CaptureList captures = {})
|
: m_anchor{anchor}, m_cursor{cursor} {}
|
||||||
: m_anchor{anchor}, m_cursor{cursor},
|
|
||||||
m_captures(std::move(captures)) {}
|
|
||||||
|
|
||||||
BufferCoord& anchor() { return m_anchor; }
|
BufferCoord& anchor() { return m_anchor; }
|
||||||
BufferCoordAndTarget& cursor() { return m_cursor; }
|
BufferCoordAndTarget& cursor() { return m_cursor; }
|
||||||
|
@ -39,13 +36,7 @@ struct Selection
|
||||||
|
|
||||||
void set(BufferCoord coord) { set(coord, coord); }
|
void set(BufferCoord coord) { set(coord, coord); }
|
||||||
|
|
||||||
CaptureList& captures() { return m_captures; }
|
friend bool operator==(const BasicSelection&, const BasicSelection&) = default;
|
||||||
const CaptureList& captures() const { return m_captures; }
|
|
||||||
|
|
||||||
bool operator== (const Selection& other) const
|
|
||||||
{
|
|
||||||
return m_anchor == other.m_anchor and m_cursor == other.m_cursor;
|
|
||||||
}
|
|
||||||
|
|
||||||
// When selections are single char, we want the anchor to be considered min, and cursor max
|
// When selections are single char, we want the anchor to be considered min, and cursor max
|
||||||
const BufferCoord& min() const { return m_anchor <= m_cursor ? m_anchor : m_cursor; }
|
const BufferCoord& min() const { return m_anchor <= m_cursor ? m_anchor : m_cursor; }
|
||||||
|
@ -57,11 +48,23 @@ struct Selection
|
||||||
private:
|
private:
|
||||||
BufferCoord m_anchor;
|
BufferCoord m_anchor;
|
||||||
BufferCoordAndTarget m_cursor;
|
BufferCoordAndTarget m_cursor;
|
||||||
|
};
|
||||||
|
;
|
||||||
|
|
||||||
|
struct Selection : BasicSelection
|
||||||
|
{
|
||||||
|
Selection() = default;
|
||||||
|
Selection(BufferCoord pos) : BasicSelection(pos,pos) {}
|
||||||
|
Selection(BufferCoord anchor, BufferCoordAndTarget cursor, CaptureList captures = {})
|
||||||
|
: BasicSelection{anchor, cursor}, m_captures(std::move(captures)) {}
|
||||||
|
CaptureList& captures() { return m_captures; }
|
||||||
|
const CaptureList& captures() const { return m_captures; }
|
||||||
|
|
||||||
|
private:
|
||||||
CaptureList m_captures;
|
CaptureList m_captures;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool overlaps(const Selection& lhs, const Selection& rhs)
|
inline bool overlaps(const BasicSelection& lhs, const BasicSelection& rhs)
|
||||||
{
|
{
|
||||||
return lhs.min() <= rhs.min() ? lhs.max() >= rhs.min()
|
return lhs.min() <= rhs.min() ? lhs.max() >= rhs.min()
|
||||||
: lhs.min() <= rhs.max();
|
: lhs.min() <= rhs.max();
|
||||||
|
|
1
test/normal/duplicate-selections/cmd
Normal file
1
test/normal/duplicate-selections/cmd
Normal file
|
@ -0,0 +1 @@
|
||||||
|
++ao<esc>
|
1
test/normal/duplicate-selections/in
Normal file
1
test/normal/duplicate-selections/in
Normal file
|
@ -0,0 +1 @@
|
||||||
|
%(f) %(b) %(t)
|
1
test/normal/duplicate-selections/out
Normal file
1
test/normal/duplicate-selections/out
Normal file
|
@ -0,0 +1 @@
|
||||||
|
fooo booo tooo
|
Loading…
Reference in New Issue
Block a user