sty icon indicating copy to clipboard operation
sty copied to clipboard

Shortcut Register

Open feluxe opened this issue 6 years ago • 0 comments

Suggestion for a Shortcut Register:

Version A


from sty import s

# Mix with fg red + bg blue + italic

s.red            # fg.red
s.red_i          # fg.red + ef.italic
s._blue          # bg.blue
s._blue_i        # bg.blue + ef.italic
s.red_blue       # fg.red + bg.blue
s.red_blue_i     # fg.red + bg.blue + ef.italic

# Mix with fg red + bg da_blue + italic

s.red
s.red_i
s._dblue
s._dblue_i
s.red_dblue
s.red_dblue_i

# Mix with fg red + bg li_blue + italic

s.red
s.red_i
s._lblue
s._lblue_i
s.red_lblue
s.red_lblue_i

# resetters

s.rs_all    # rs.all

s.rs        # rs.fg
s.rs_i      # rs.fg + rs.italic
s._rs       # rs.bg
s._rs_i     # rs.bg + rs.italic
s.rs_rs     # rs.fg + rs.bg
s.rs_rs_i   # rs.fg + rs.bg + rs.italic

Result


# Shortcut version

a = f"{s.red_i}Hello World!{s.rs_i}"
b = f"{s.red_blue_i}Hello World!{s.rs_rs_i}"

# Default version

a = f"{fg.red}{ef.i}Hello World!{fg.rs}{rs.i}"
b = f"{fg.red}{bg.blue}{ef.i}Hello World!{fg.rs}{bg.rs}{rs.i}"

Contra

Limited Composability

The composability of this implementation is somewhat limited. E.g. what if you need a string with: fg.red + bg.blue + ef.i + ef.b?

You would end up with this s.red_blue_i + s.b

A solution for this would be Version B.

Version B

Fixes composability issue of Version A.

s.red + 'foo' + r.fg                   # fg.red
s.red.i + 'foo' + r.fg.i               # fg.red + ef.i
s._.blue + 'foo' + r.bg                # bg.blue
s._.blue.i + 'foo' + r.bg.i            # bg.blue + ef.i
s.red.blue + 'foo' + r.fg.bg           # fg.red + bg.blue
s.red.blue.i + 'foo' + r.fg.bg.i       # fg.red + bg.blue + ef.i
s.red.blue.i.u + 'foo' + r.fg.bg.i.u   # fg.red + bg.blue + ef.i + ef.u

Result

# Shortcut version

a = f"{s.red.i}Hello World!{r.fg.i}"
b = f"{s.red.blue.i}Hello World!{r.fg.bg.i}"
c = f"{s.red.blue.i.u}Hello World!{r.fg.bg.i.u}"

# Default version

a = f"{fg.red}{ef.i}Hello World!{fg.rs}{rs.i}"
b = f"{fg.red}{bg.blue}{ef.i}Hello World!{fg.rs}{bg.rs}{rs.i}"
c = f"{fg.red}{bg.blue}{ef.i}{ef.u}Hello World!{fg.rs}{bg.rs}{rs.i}{rs.u}"

Pro

Less verbose

It's less verbose and it looks very clear.

Better access performance

a is more than twice as fast as b:

a = f"{s.red.blue.i}foo{r.fg.bg.i}foo"  # 5.7 Sec

b = f"{fg.red}{bg.blue}{ef.i}foo{fg.rs}{bg.rs}{rs.i}foo"  # 12.3 Sec

Contra

Complicated (implementation)

Making this compatible with sty could be complicated and may require deep changes. Implementing this without loosing customizability and editor support can be tricky.

Implementation (sketch)

This implementation is able to parse the example above:

from sty import ef, fg, bg, rs 
from collections import UserString



class Shortcut():

    def __init__(self, fg, bg, ef):

        class Ef(UserString):
            def __init__(self, seq, i=0):
                if i > 5:
                    return
                super().__init__(seq)
                self.i = Ef(self.data + ef.i, i+1)
                self.u = Ef(self.data + ef.u, i+1)
                self.b = Ef(self.data + ef.b, i+1)
                # ...

        class BgEf(UserString):

            def __init__(self, seq):
                super().__init__(seq)
                self.red = Ef(self.data + bg.red)
                self.blue = Ef(self.data +bg.blue)
                self.green = Ef(self.data +bg.green)
                self.i = Ef(self.data + ef.i)
                self.u = Ef(self.data + ef.u)
                self.b = Ef(self.data + ef.b)
                # ...

        self._ = BgEf('')
        
        for k, v in {**fg, **ef}.items():
            if k not in ['eightbit_call', 'rgb_call']:
                try:
                    setattr(self, k, BgEf(fg(k)))
                except KeyError:
                    setattr(self, k, BgEf(ef(k)))


class ShortcutRs:

    def __init__(self, rs):

        class Rs(UserString):
            def __init__(self, seq, i=0):
                if i > 5:
                    return
                super().__init__(seq)
                self.fg = Rs(self.data + rs.fg, i+1)
                self.bg = Rs(self.data + rs.bg, i+1)
                self.i = Rs(self.data + rs.i, i+1)
                self.u = Rs(self.data + rs.u, i+1)
                self.bold_dim = Rs(self.data + rs.bold_dim, i+1)
                # ...


        for k, v in rs.items():
            setattr(self, k, Rs(v))


s = Shortcut(fg, bg, ef)
r = ShortcutRs(rs)

feluxe avatar Feb 13 '19 11:02 feluxe