Skip to content

Commit

Permalink
#149 [Term] Text selection
Browse files Browse the repository at this point in the history
Text Selection (terminal) #149
Set default terminal colors using VT-sequence #191
Change selection mode using VT-sequence #149
Forward clipboard data (nested OSC 52) #186
  • Loading branch information
o-sdn-o authored Apr 21, 2022
2 parents 6297105 + b81f321 commit fab7192
Show file tree
Hide file tree
Showing 33 changed files with 3,043 additions and 1,360 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/.vs
/.vscode
/src/build
/src/.vs
/bin
4 changes: 2 additions & 2 deletions .resources/status/freebsd.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions .resources/status/linux.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions .resources/status/macos.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions .resources/status/netbsd.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions .resources/status/openbsd.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions .resources/status/windows.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 9 additions & 3 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,9 @@ No arguments | Run client (auto start server)
<td></td>
</tr>
<tr>
<th>Left+Right or MiddleClick</th>
<th>Left+Right</th>
<td colspan="3"></td>
<td colspan="5">Close app</td>
<td colspan="5">Clear clipboard</td>
<td></td>
</tr>
<tr>
Expand Down Expand Up @@ -214,17 +214,23 @@ No arguments | Run client (auto start server)
- Save/restore terminal window title `XTWINOPS 22/23`
- Mouse tracking `DECSET 1000/1002/1003/1006 SGR` mode
- Mouse tracking `DECSET 10060 Extended SGR` mode, mouse reporting outside of the terminal viewport (outside + negative arguments) #62
- Text selection by mouse #149
- Configurable using VT-sequences

Name | Sequence | Description
-------------|----------------------------------|-------------
`CCC_SBS` | `CSI` 24 : n : m `p` | Set scrollback buffer size, `int32_t`<br>`n` Initial buffer size in lines; 0 — grow step is used for initial size; _default (if omitted) is 20.000_<br>`m` Grow step for unlimited buffer; _default (if omitted) is 0_ — for fixed size buffer
`CCC_SGR` | `CSI` 28 : Pm `p` | Set terminal background using SGR parameters (one attribute at once)<br>`Pm` Colon-separated list of attribute parameters, 0 — reset all attributes, _default is 0_
`CCC_SEL` | `CSI` 29 : n `p` | Set selection mode, _default is 0_<br>`n = 0` Selection is off<br>`n = 1`Select and copy as plaintext<br>`n = 2` Select and copy as ANSI-text
`CCC_PAD` | `CSI` 30 : n `p` | Set scrollbuffer side padding<br>`n` Width in cells, _max = 255, default is 3_
`CCC_RST` | `CSI` 1 `p` | Reset all parameters to default
`CCC_TBS` | `CSI` 5 : n `p` | Set tabulation length<br>`n` Length in chars, _max = 256, default is 8_
`CCC_TBS` | `CSI` 5 : n `p` | Set tabulation length<br>`n` Length in cells, _max = 256, default is 8_
`CCC_JET` | `CSI` 11 : n `p` | Set text alignment, _default is Left_<br>`n = 0` default<br>`n = 1` Left<br>`n = 2` Right<br>`n = 3` Center
`CCC_WRP` | `CSI` 12 : n `p` | Set text autowrap mode, _default is On_<br>`n = 0` default<br>`n = 1` On<br>`n = 2` Off (_enable horizontal scrolling_)
`CCC_RTL` | `CSI` 13 : n `p` | Set text right-to-left mode, _default is Off_<br>`n = 0` default<br>`n = 1` On<br>`n = 2` Off

Note: It is possible to combine multiple command into a single sequence using a semicolon. For example, the following sequence disables wrapping, enables text selection, and sets the background to blue: `CSI 12 : 2 ; 29 : 1 ; 28 : 44 p` or `CSI 12 : 2 ; 29 : 1 ; 28 : 48 : 2 : 0 : 0 : 255 p`.

- `▀▄ Logs`
- Debug output console. Use double `RightClick` to clear scrollback.

Expand Down
22 changes: 11 additions & 11 deletions src/netxs/abstract/duplet.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

namespace netxs
{
using fifo = netxs::generics::fifo<iota>;
using fifo = netxs::generics::fifo<si32>;

template<class T = int>
struct duplet
Expand Down Expand Up @@ -129,7 +129,7 @@ namespace netxs
}
};

using twod = duplet<iota>;
using twod = duplet<si32>;

static constexpr const twod dot_00{ 0,0 };
static constexpr const twod dot_01{ 0,1 };
Expand All @@ -138,22 +138,22 @@ namespace netxs
static constexpr const twod dot_22{ 2,2 };
static constexpr const twod dot_21{ 2,1 };
static constexpr const twod dot_33{ 3,3 };
static constexpr const twod dot_mx{ std::numeric_limits<iota>::max() / 2,
std::numeric_limits<iota>::max() / 2 };
static constexpr const twod dot_mx{ std::numeric_limits<si32>::max() / 2,
std::numeric_limits<si32>::max() / 2 };

static twod divround(twod const& p, iota n ) { return { divround(p.x, n ), divround(p.y, n ) }; }
static twod divround(iota n , twod const& p) { return { divround(n , p.x), divround(n , p.y) }; }
static twod divround(twod const& p, si32 n ) { return { divround(p.x, n ), divround(p.y, n ) }; }
static twod divround(si32 n , twod const& p) { return { divround(n , p.x), divround(n , p.y) }; }
static twod divround(twod const& n, twod const& p) { return { divround(n.x, p.x), divround(n.y, p.y) }; }
static twod divupper(twod const& n, twod const& p) { return { divupper(n.x, p.x), divupper(n.y, p.y) }; }
} // namespace netxs

namespace std
{
template<class T = netxs::iota> static netxs::duplet<T> min (netxs::duplet<T> const& p1, netxs::duplet<T> const& p2) { return { std::min(p1.x, p2.x), std::min(p1.y, p2.y) }; }
template<class T = netxs::iota> static netxs::duplet<T> max (netxs::duplet<T> const& p1, netxs::duplet<T> const& p2) { return { std::max(p1.x, p2.x), std::max(p1.y, p2.y) }; }
template<class T = netxs::iota> static netxs::duplet<T> round(netxs::duplet<T> const& p) { return { std::round(p.x), std::round(p.y) }; }
template<class T = netxs::iota> static netxs::duplet<T> abs (netxs::duplet<T> const& p) { return { std:: abs(p.x), std:: abs(p.y) }; }
template<class T = netxs::iota> static netxs::duplet<T> clamp(netxs::duplet<T> const& p, netxs::duplet<T> const& p1, netxs::duplet<T> const& p2) { return { std::clamp(p.x, p1.x, p2.x), std::clamp(p.y, p1.y, p2.y) }; }
template<class T = netxs::si32> static netxs::duplet<T> min (netxs::duplet<T> const& p1, netxs::duplet<T> const& p2) { return { std::min(p1.x, p2.x), std::min(p1.y, p2.y) }; }
template<class T = netxs::si32> static netxs::duplet<T> max (netxs::duplet<T> const& p1, netxs::duplet<T> const& p2) { return { std::max(p1.x, p2.x), std::max(p1.y, p2.y) }; }
template<class T = netxs::si32> static netxs::duplet<T> round(netxs::duplet<T> const& p) { return { std::round(p.x), std::round(p.y) }; }
template<class T = netxs::si32> static netxs::duplet<T> abs (netxs::duplet<T> const& p) { return { std:: abs(p.x), std:: abs(p.y) }; }
template<class T = netxs::si32> static netxs::duplet<T> clamp(netxs::duplet<T> const& p, netxs::duplet<T> const& p1, netxs::duplet<T> const& p2) { return { std::clamp(p.x, p1.x, p2.x), std::clamp(p.y, p1.y, p2.y) }; }
} // namespace std

#endif // NETXS_DUPLET_HPP
8 changes: 4 additions & 4 deletions src/netxs/abstract/hash.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ namespace netxs
struct iter
{
using it_t = decltype(IMAP{}.forward.begin());
using iota = typename std::iterator_traits<it_t>::difference_type; //todo "typename" keyword is required by FreeBSD clang 11.0.1
using type = typename std::iterator_traits<it_t>::difference_type; //todo "typename" keyword is required by FreeBSD clang 11.0.1

IMAP& buff;
it_t addr;
Expand All @@ -69,8 +69,8 @@ namespace netxs
addr{ addr }
{ }

auto operator - (iota n) const { return iter<IMAP>{ buff, addr - n }; }
auto operator + (iota n) const { return iter<IMAP>{ buff, addr + n }; }
auto operator - (type n) const { return iter<IMAP>{ buff, addr - n }; }
auto operator + (type n) const { return iter<IMAP>{ buff, addr + n }; }
auto operator ++ (int) { return iter<IMAP>{ buff, addr++ }; }
auto operator -- (int) { return iter<IMAP>{ buff, addr-- }; }
auto& operator ++ () { ++addr; return *this; }
Expand All @@ -95,7 +95,7 @@ namespace netxs
template<class K>
auto erase(K&& key )
{
iota test = 0;
si32 test = 0;
auto iter = storage.find(std::forward<K>(key));
if (iter != storage.end())
{
Expand Down
52 changes: 27 additions & 25 deletions src/netxs/abstract/ring.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,33 +13,33 @@ namespace netxs::generics
{
using type = typename vect::value_type;

iota step; // ring: Unlimited buffer increment step (zero for fixed size buffer).
iota head; // ring: Front index.
iota tail; // ring: Back index.
iota peak; // ring: Limit of the ring buffer.
si32 step; // ring: Unlimited buffer increment step (zero for fixed size buffer).
si32 head; // ring: Front index.
si32 tail; // ring: Back index.
si32 peak; // ring: Limit of the ring buffer.
vect buff; // ring: Inner container.
iota size; // ring: Elements count.
iota cart; // ring: Active item position.
iota mxsz; // ring: Max unlimited buffer size.
si32 size; // ring: Elements count.
si32 cart; // ring: Active item position.
si32 mxsz; // ring: Max unlimited buffer size.

void inc(iota& a) const { if (++a == peak) a = 0; }
void dec(iota& a) const { if (--a < 0 ) a = peak - 1; }
auto mod(iota a) const { return a < 0 ? ++a % peak - 1 + peak
void inc(si32& a) const { if (++a == peak) a = 0; }
void dec(si32& a) const { if (--a < 0 ) a = peak - 1; }
auto mod(si32 a) const { return a < 0 ? ++a % peak - 1 + peak
: a % peak; }
auto dst(iota a, iota b) const
auto dst(si32 a, si32 b) const
{ return b < a ? b - a + peak
: b - a; }
template<class RING>
struct iter
{
RING& buff;
iota addr;
iter(RING& buff, iota addr)
si32 addr;
iter(RING& buff, si32 addr)
: buff{ buff },
addr{ addr }
{ }
auto operator - (iota n) const { return iter<RING>{ buff, buff.mod(addr - n) }; }
auto operator + (iota n) const { return iter<RING>{ buff, buff.mod(addr + n) }; }
auto operator - (si32 n) const { return iter<RING>{ buff, buff.mod(addr - n) }; }
auto operator + (si32 n) const { return iter<RING>{ buff, buff.mod(addr + n) }; }
auto operator ++ (int) { auto temp = iter<RING>{ buff, addr }; buff.inc(addr); return temp; }
auto operator -- (int) { auto temp = iter<RING>{ buff, addr }; buff.dec(addr); return temp; }
auto& operator ++ () { buff.inc(addr); return *this; }
Expand All @@ -50,15 +50,15 @@ namespace netxs::generics
auto operator == (iter const& m) const { return addr == m.addr; }
};

ring(iota ring_size, iota grow_by = 0)
ring(si32 ring_size, si32 grow_by = 0)
: step{ grow_by },
head{ 0 },
tail{ ring_size ? ring_size : step },
peak{ tail + 1 },
buff( peak ), // Rounded brackets! Not curly! In oreder to call T::ctor().
size{ 0 },
cart{ 0 },
mxsz{ maxiota - step }
mxsz{ maxsi32 - step }
{ }

virtual void undock_base_front(type&) { };
Expand All @@ -71,14 +71,16 @@ namespace netxs::generics
auto end() const { return iter<const ring>{ *this, mod(tail + 1) }; }
auto& length() const { return size; }
auto& back() { return buff[tail]; }
auto& back() const { return buff[tail]; }
auto& front() { return buff[head]; }
auto& front() const { return buff[head]; }
auto& current () { return buff[cart]; }
auto& operator * () { return buff[cart]; }
auto operator -> () { return buff.begin() + cart; }
auto& at (iota i) { assert(i >= 0 && i < size); return buff[mod(head + i)]; }
auto& operator[] (iota i) { return at(i); }
auto& at (si32 i) { assert(i >= 0 && i < size); return buff[mod(head + i)]; }
auto& operator[] (si32 i) { return at(i); }
auto index() const { return dst(head, cart); }
void index(iota i) { assert(i >= 0 && i < size); cart = mod(head + i); }
void index(si32 i) { assert(i >= 0 && i < size); cart = mod(head + i); }
void prev() { dec(cart); test(); }
void next() { inc(cart); test(); }

Expand Down Expand Up @@ -122,7 +124,7 @@ namespace netxs::generics
}
// ring: Insert an item before the specified position. Pop front when full. Return an iterator pointing to the new item.
template<class ...Args>
auto insert_impl(iota at, Args&&... args) // Pop front always if ring is full.
auto insert_impl(si32 at, Args&&... args) // Pop front always if ring is full.
{
if (at == 0)
{
Expand Down Expand Up @@ -208,7 +210,7 @@ namespace netxs::generics
void pop_back () { undock_back(); --size; }
// ring: Insert an item before the specified position. Pop front when full. Return an iterator pointing to the new item.
template<class ...Args>
auto insert(iota at, Args&&... args) // Pop front always if ring is full.
auto insert(si32 at, Args&&... args) // Pop front always if ring is full.
{
assert(at >= 0 && at <= size);
auto temp = index();
Expand All @@ -224,7 +226,7 @@ namespace netxs::generics
index(temp);
return iter;
}
auto remove(iota at, iota n)
auto remove(si32 at, si32 n)
{
assert(at >= 0 && at < size);

Expand Down Expand Up @@ -265,7 +267,7 @@ namespace netxs::generics
tail = peak - 1;
}
template<bool BOTTOM_ANCHORED = true>
void resize(iota new_size, iota grow_by = 0)
void resize(si32 new_size, si32 grow_by = 0)
{
if (new_size > 0)
{
Expand Down Expand Up @@ -315,7 +317,7 @@ namespace netxs::generics
else step = grow_by;
}
template<class P>
void for_each(iota from, iota upto, P proc)
void for_each(si32 from, si32 upto, P proc)
{
auto head = begin() + from;
auto tail = begin() + upto;
Expand Down
3 changes: 2 additions & 1 deletion src/netxs/abstract/tree.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,10 @@ namespace netxs::generics
bulk::resize(newsize);
return *this;
}
template<bool NOMULTIARG = faux>
void enable_multi_arg()
{
for (auto& rec : *this) rec.stop = faux;
for (auto& rec : *this) rec.stop = NOMULTIARG;
}
operator bool () const
{
Expand Down
Loading

0 comments on commit fab7192

Please sign in to comment.