Qirky / Troop

Real-time Live Coding collaboration app
306 stars 37 forks source link

Client in SuperCollider mode chokes on lines beginning with a slash #39

Closed jamshark70 closed 4 years ago

jamshark70 commented 4 years ago
  1. In one terminal window, run the server.

    $ python run-server.py 
    Password (leave blank for no password): 
    Server running @ 192.168.255.253 on port 57890. Ver. 0.9.6
  2. In another terminal window, run the client.

    $ python run-client.py --mode SuperCollider

    The Troop window appears, no problem.

  3. In sclang, Troop.start.

  4. Load my live coding environment "cll": \loadAllCl.eval; s.boot; alt-return (which won't work for you unless you install it... but you might not have to, read on first).

  5. Cll commands start with a slash, so, on a new line, start typing:

    /drum.(\tightsnr);

    The first slash ends up displaying two slashes. As you continue to type, characters are entered into the code window in reverse order: )rnsthgit\(.murd/

  6. Deleting the faulty text causes the client backend to crash ("Connection lost").

To reproduce the issue, you don't need to install my libraries. Just type /abc into the client window.

The client terminal window has a lot of errors:

Exception in Tkinter callback
Traceback (most recent call last):
  File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1550, in __call__
    return self.func(*args)
  File "/media/dlm/7D53-8744/Docs/xinghai/19-20-spring/yuetuan/Troop/src/interface/interface.py", line 675, in key_press
    self.apply_operation(operation, index_offset)
  File "/media/dlm/7D53-8744/Docs/xinghai/19-20-spring/yuetuan/Troop/src/interface/interface.py", line 736, in apply_operation
    self.text.apply_local_operation(operation, index_offset, **kwargs)
  File "/media/dlm/7D53-8744/Docs/xinghai/19-20-spring/yuetuan/Troop/src/interface/textbox.py", line 186, in apply_local_operation
    self.apply_operation(operation, peer=self.marker, undo=undo)
  File "/media/dlm/7D53-8744/Docs/xinghai/19-20-spring/yuetuan/Troop/src/interface/textbox.py", line 170, in apply_operation
    self.refresh()
  File "/media/dlm/7D53-8744/Docs/xinghai/19-20-spring/yuetuan/Troop/src/interface/textbox.py", line 678, in refresh
    self.apply_language_formatting()
  File "/media/dlm/7D53-8744/Docs/xinghai/19-20-spring/yuetuan/Troop/src/interface/textbox.py", line 698, in apply_language_formatting
    self.colour_line(line + 1)
  File "/media/dlm/7D53-8744/Docs/xinghai/19-20-spring/yuetuan/Troop/src/interface/textbox.py", line 716, in colour_line
    for match_start, match_end in tag_finding_func(string):
  File "/media/dlm/7D53-8744/Docs/xinghai/19-20-spring/yuetuan/Troop/src/interpreter.py", line 532, in find_comment
    if not instring and i < len(string) and string[i + 1] == "/":
IndexError: string index out of range

So it seems that the Troop editor is trying to do something fancy based on assumptions about SC syntax that don't necessarily hold true about live-coding dialects. (As a workaround I'll enable # as a command delimiter in my system -- some muscle memory to overcome, then.)

If there is a way to disable the editor's syntax handling, and just use it as a simple text editor, that would be nice.

jamshark70 commented 4 years ago

Oh, it's worse: it also dies on valid standard SC expressions like TempoClock.tempo = 128/60.

That special slash handling needs to go away.

jamshark70 commented 4 years ago

Worked around by making SuperColliderInterpreter find_comment() always return empty:

    def find_comment(cls, string):        
        """ instring, instring_char = False, ""
        for i, char in enumerate(string):
            if char in ('"', "'"):
                if instring:
                    if char == instring_char:
                        instring = False
                        instring_char = ""
                else:
                    instring = True
                    instring_char = char
            elif char == "/":
                if not instring and i < len(string) and string[i + 1] == "/":
                    return [(i, len(string))]
        """
        return []

But there's probably a better fix.

Qirky commented 4 years ago

Good catch, turns out it's a really simple fix, just changing

if not instring and i < len(string) and string[i + 1] == "/":

to

if not instring and (i + 1) < len(string) and string[i + 1] == "/":

It was just not checking if the current character was at the end of the line correctly, which it now is. Should work ok for you now.

jamshark70 commented 4 years ago

Confirmed, yes, that fixes it. Thanks!