From 494d38df16683030437480ab3bb2b9dc76e3dd1a Mon Sep 17 00:00:00 2001 From: Allan Odgaard Date: Sun, 30 Sep 2012 17:41:43 +0200 Subject: [PATCH] =?UTF-8?q?Cycle=20discontinuous=20selections=20when=20usi?= =?UTF-8?q?ng=20=E2=80=98transpose=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It performs a cyclic permutation. If there are only two selections, this is equivalent to swap, but with more discontinuous selections, it is possible to repeat the transpose until the selections are ordered as desired. --- Frameworks/editor/src/editor.cc | 113 ++++++++++++++++++-------------- 1 file changed, 65 insertions(+), 48 deletions(-) diff --git a/Frameworks/editor/src/editor.cc b/Frameworks/editor/src/editor.cc index 65e95081..9116f40a 100644 --- a/Frameworks/editor/src/editor.cc +++ b/Frameworks/editor/src/editor.cc @@ -68,6 +68,59 @@ namespace ng return res; } + template + _OutputIter transpose_selections (buffer_t const& _buffer, ranges_t const& _selections, _OutputIter out) + { + ranges_t sel; + iterate(range, _selections) + { + size_t from = range->min().index, to = range->max().index; + if(from == to) + { + text::pos_t const& pos = _buffer.convert(from); + + if(from == 0 || from == _buffer.size()) + { + } + else if(pos.column == 0) + { + from = _buffer.begin(pos.line - 1); + to = pos.line+1 == _buffer.lines() ? _buffer.size() : _buffer.begin(pos.line + 1); + } + else if(from == _buffer.eol(pos.line)) + { + from = _buffer.begin(pos.line); + to = pos.line+2 == _buffer.lines() ? _buffer.size() : _buffer.begin(pos.line + 2); + } + else + { + from = from - _buffer[from-1].size(); + to = to + _buffer[to].size(); + } + *out++ = std::make_pair(range_t(from, to), transform::transpose(_buffer.substr(from, to))); + } + else if(range->columnar) // TODO from.line != to.line + { + std::vector strings; + std::vector ranges; + + citerate(r, dissect_columnar(_buffer, *range)) + { + strings.push_back(_buffer.substr(r->min().index, r->max().index)); + ranges.push_back(*r); + } + + for(size_t i = 0; i < ranges.size(); ++i) + *out++ = std::make_pair(ranges[i], strings[ranges.size()-1 - i]); + } + else + { + *out++ = std::make_pair(range_t(from, to), transform::transpose(_buffer.substr(from, to))); + } + } + return out; + } + // ============================= // = Preserve Selection Helper = // ============================= @@ -973,56 +1026,20 @@ namespace ng case kTranspose: { std::multimap replacements; - - ranges_t sel; - iterate(range, _selections) + auto inserter = std::insert_iterator(replacements, replacements.begin()); + if(_selections.size() > 1 && not_empty(_buffer, _selections)) { - size_t from = range->min().index, to = range->max().index; - if(from == to) - { - text::pos_t const& pos = _buffer.convert(from); - - if(from == 0 || from == _buffer.size()) - { - } - else if(pos.column == 0) - { - from = _buffer.begin(pos.line - 1); - to = pos.line+1 == _buffer.lines() ? _buffer.size() : _buffer.begin(pos.line + 1); - } - else if(from == _buffer.eol(pos.line)) - { - from = _buffer.begin(pos.line); - to = pos.line+2 == _buffer.lines() ? _buffer.size() : _buffer.begin(pos.line + 2); - } - else - { - from = from - _buffer[from-1].size(); - to = to + _buffer[to].size(); - } - replacements.insert(std::make_pair(range_t(from, to), transform::transpose(_buffer.substr(from, to)))); - } - else if(range->columnar) // TODO from.line != to.line - { - std::vector strings; - std::vector ranges; - - citerate(r, dissect_columnar(_buffer, *range)) - { - strings.push_back(_buffer.substr(r->min().index, r->max().index)); - ranges.push_back(*r); - } - - for(size_t i = 0; i < ranges.size(); ++i) - replacements.insert(std::make_pair(ranges[i], strings[ranges.size()-1 - i])); - } - else - { - replacements.insert(std::make_pair(range_t(from, to), transform::transpose(_buffer.substr(from, to)))); - } + std::multiset ranges(_selections.begin(), _selections.end()); + std::vector strings; + std::transform(ranges.begin(), ranges.end(), back_inserter(strings), [this](range_t const& r){ return _buffer.substr(r.min().index, r.max().index); }); + std::next_permutation(strings.begin(), strings.end()); + std::transform(ranges.begin(), ranges.end(), strings.begin(), inserter, [](range_t const& r, std::string const& str){ return std::make_pair(r, str); }); } - - _selections = this->replace(replacements); + else + { + transpose_selections(_buffer, _selections, inserter); + } + _selections = this->replace(replacements, not_empty(_buffer, _selections)); } break;