Add support for paste all (on <a-[pP]>)

Paste all pastes all yanked text at all selections, selecting each
pasted text.

Replace paste moves to R, and concat yank/concat delete (Y and D)
are removed.

Fixes #161
This commit is contained in:
Maxime Coste 2014-07-03 00:25:39 +01:00
parent 8795efdf19
commit d181a40a91
4 changed files with 51 additions and 34 deletions

View File

@ -179,7 +179,6 @@ Changes
* _i_: insert before current selection * _i_: insert before current selection
* _a_: insert after current selection * _a_: insert after current selection
* _d_: yank and delete current selection * _d_: yank and delete current selection
* _D_: yank concatenated and delete current selection (see _Y_)
* _c_: yank and delete current selection and insert * _c_: yank and delete current selection and insert
* _._: repeat last insert mode change (_i_, _a_, or _c_, including * _._: repeat last insert mode change (_i_, _a_, or _c_, including
the inserted text) the inserted text)
@ -190,11 +189,15 @@ Changes
* _O_: insert in a new line above current selection begin * _O_: insert in a new line above current selection begin
* _y_: yank selections * _y_: yank selections
* _Y_: yank selections concatenated (only one yank, containing
all selection concatenated)
* _p_: paste after current selection end * _p_: paste after current selection end
* _P_: paste before current selection begin * _P_: paste before current selection begin
* _alt-p_: replace current selection with yanked text * _alt-p_: paste all after current selection end, and
select each pasted string.
* _alt-P_: paste all before current selection begin, and
select each pasted string.
* _R_: replace current selection with yanked text
* _r_: replace each character with the next entered one
* _alt-j_: join selected lines * _alt-j_: join selected lines
* _alt-J_: join selected lines and select spaces inserted * _alt-J_: join selected lines and select spaces inserted
@ -215,7 +218,6 @@ Changes
* _u_: undo last change * _u_: undo last change
* _U_: redo last change * _U_: redo last change
* _r_: replace each character with the next entered one
* _&_: align selection, align the cursor of selections by inserting * _&_: align selection, align the cursor of selections by inserting
spaces before the first character of the selection spaces before the first character of the selection
* _alt-&_: copy indent, copy the indentation of the main selection * _alt-&_: copy indent, copy the indentation of the main selection

View File

@ -446,17 +446,6 @@ void yank(Context& context, int)
" selections", get_color("Information") }); " selections", get_color("Information") });
} }
void cat_yank(Context& context, int)
{
auto sels = context.selections_content();
String str;
for (auto& sel : sels)
str += sel;
RegisterManager::instance()['"'] = memoryview<String>(str);
context.print_status({ "concatenated and yanked " +
to_string(sels.size()) + " selections", get_color("Information") });
}
void erase_selections(Context& context, int) void erase_selections(Context& context, int)
{ {
RegisterManager::instance()['"'] = context.selections_content(); RegisterManager::instance()['"'] = context.selections_content();
@ -465,18 +454,6 @@ void erase_selections(Context& context, int)
context.selections().avoid_eol(); context.selections().avoid_eol();
} }
void cat_erase_selections(Context& context, int)
{
auto sels = context.selections_content();
String str;
for (auto& sel : sels)
str += sel;
RegisterManager::instance()['"'] = memoryview<String>(str);
context.selections().erase();
context.selections().avoid_eol();
}
void change(Context& context, int param) void change(Context& context, int param)
{ {
RegisterManager::instance()['"'] = context.selections_content(); RegisterManager::instance()['"'] = context.selections_content();
@ -510,6 +487,42 @@ void paste(Context& context, int)
context.selections().insert(strings, effective_mode); context.selections().insert(strings, effective_mode);
} }
template<InsertMode mode>
void paste_all(Context& context, int)
{
auto strings = RegisterManager::instance()['"'].values(context);
InsertMode effective_mode = mode;
String all;
std::vector<ByteCount> offsets;
for (auto& str : strings)
{
if (not str.empty() and str.back() == '\n')
effective_mode = adapt_for_linewise(mode);
all += str;
offsets.push_back(all.length());
}
auto& selections = context.selections();
{
ScopedEdition edition(context);
selections.insert(all, effective_mode, true);
}
const Buffer& buffer = context.buffer();
std::vector<Selection> result;
for (auto& selection : selections)
{
ByteCount pos = 0;
for (auto offset : offsets)
{
result.push_back({ buffer.advance(selection.min(), pos),
buffer.advance(selection.min(), offset-1) });
pos = offset;
}
}
selections = std::move(result);
}
template<typename T> template<typename T>
void regex_prompt(Context& context, const String prompt, T func) void regex_prompt(Context& context, const String prompt, T func)
{ {
@ -1250,7 +1263,6 @@ KeyMap keymap =
{ alt('F'), select_to_next_char<SelectFlags::Inclusive | SelectFlags::Extend | SelectFlags::Reverse> }, { alt('F'), select_to_next_char<SelectFlags::Inclusive | SelectFlags::Extend | SelectFlags::Reverse> },
{ 'd', erase_selections }, { 'd', erase_selections },
{ 'D', cat_erase_selections },
{ 'c', change }, { 'c', change },
{ 'i', enter_insert_mode<InsertMode::Insert> }, { 'i', enter_insert_mode<InsertMode::Insert> },
{ 'I', enter_insert_mode<InsertMode::InsertAtLineBegin> }, { 'I', enter_insert_mode<InsertMode::InsertAtLineBegin> },
@ -1266,10 +1278,11 @@ KeyMap keymap =
{ 'v', view_commands }, { 'v', view_commands },
{ 'y', yank }, { 'y', yank },
{ 'Y', cat_yank },
{ 'p', repeated(paste<InsertMode::Append>) }, { 'p', repeated(paste<InsertMode::Append>) },
{ 'P', repeated(paste<InsertMode::Insert>) }, { 'P', repeated(paste<InsertMode::Insert>) },
{ alt('p'), paste<InsertMode::Replace> }, { alt('p'), paste_all<InsertMode::Append> },
{ alt('P'), paste_all<InsertMode::Insert> },
{ 'R', paste<InsertMode::Replace> },
{ 's', select_regex }, { 's', select_regex },
{ 'S', split_regex }, { 'S', split_regex },

View File

@ -463,7 +463,8 @@ BufferIterator prepare_insert(Buffer& buffer, const Selection& sel, InsertMode m
return {}; return {};
} }
void SelectionList::insert(memoryview<String> strings, InsertMode mode) void SelectionList::insert(memoryview<String> strings, InsertMode mode,
bool select_inserted)
{ {
if (strings.empty()) if (strings.empty())
return; return;
@ -496,7 +497,7 @@ void SelectionList::insert(memoryview<String> strings, InsertMode mode)
changes_tracker.update(change); changes_tracker.update(change);
m_timestamp = m_buffer->timestamp(); m_timestamp = m_buffer->timestamp();
if (mode == InsertMode::Replace) if (select_inserted or mode == InsertMode::Replace)
{ {
sel.anchor() = change.begin; sel.anchor() = change.begin;
sel.cursor() = m_buffer->char_prev(change.end); sel.cursor() = m_buffer->char_prev(change.end);

View File

@ -124,7 +124,8 @@ struct SelectionList
size_t timestamp() const { return m_timestamp; } size_t timestamp() const { return m_timestamp; }
void update_timestamp() { m_timestamp = m_buffer->timestamp(); } void update_timestamp() { m_timestamp = m_buffer->timestamp(); }
void insert(memoryview<String> strings, InsertMode mode); void insert(memoryview<String> strings, InsertMode mode,
bool select_inserted = false);
void erase(); void erase();
private: private: