vscode-tidalcycles icon indicating copy to clipboard operation
vscode-tidalcycles copied to clipboard

[WIP] evaluate selected range using shift-enter and ctrl-enter

Open lopho opened this issue 6 years ago • 8 comments

  • [x] evaluate multiple single-line statements using selection and shift-enter
  • [x] evaluate multiple multi-line statements using selection and ctrl-enter
  • [ ] check unit tests, and expand if required ... HELP! HELP! It's killing me. :(

lopho avatar Feb 09 '19 22:02 lopho

fixes #7

lopho avatar Feb 09 '19 22:02 lopho

If I find the time in the next few days, I would also take a look at ctrl+enter selection evaluation for multiple single line statements. As shift+enter evaluation only works with "single" line statements broken in multiple lines.

Works using selection shift-enter (single statement multiple lines):

d1 $ s "hh*8"    -- selected
  # up "1 2 3 4" -- selected

Does not (multiple statements multiple lines), but hopefully with a selection-type ctrl-enter:

d1 $ s "hh*8" -- selected
d2 $ s "bd*4" -- selected

This would really improve usability, at least for me. Selecting entire sections to execute, maybe even giving the do block idiom for sync a run for it's money.

lopho avatar Feb 09 '19 23:02 lopho

Functionality is implemented.

The mocking system of the unit tests irritate me a bit. I don't have the time to dive into those right now. Using manual testing everything seems to work as intended.

My problems with the mocks:

  • selection in mock editor is unreliable
    • returns loads of [object Objects] in empty and non empty lines
    • skips lines altogether
    • see Multi-line expression from split selection and Multi-line expression retrieved before selection (those two test still expect the old behaviour, but still, selection is weird)
  • the mock repl in Single-line expression evaluated in .tidal file does not seem to correctly count invocations on single line statements, always counting 0

I'm not sure if I can take this on right now. Aside from that, everythings seems to work.

shift+enter evaluates single line statements: the line with the caret if nothing is selected, or all lines being at least partially selected. ctrl+enter evaluates multi-line statements: the statement with the caret if nothing is selected, or all lines being at least partially selected. This keeps the old behavior of evaluating entire do blocks as long as nothing is selected (well, it evaluates everything until it encounters an empty line on the way up the document).

For multiple single line statements, I prefix the statements with a do. This way single line and multi line statements can be evaluated together, as the :{ operator expects multi line statements (like do).

lopho avatar Feb 12 '19 17:02 lopho

Welp. I done goof'd. The do block wrapping was a stupid idea, as it made evaluating single line non-expressions, like let a = 0 impossible and it messed up scoping. Now I've implemented a more involved method, keeping track of the current and next indentation level.

  • ctr+enter it is just like before. Wrapping everything in :{ ... :} operators.
  • evaluating a single line foregoes the multiline ops and just writes the line to ghci (both shift and ctrl)
  • shift+enter is where the magic happens
    • it allows for mixing multi- and single-line statements, as long as multiline is following an indentation scheme
    • if the next line has a deeper indentation than the current line, :{ is prepended before writing the current line
    • if a multiline op is opened and the next line has a shallower indentation :} will be appended to the current line.

Using this method everything is evaluatable. Function definitions like:

f :: a -> a
f a
    | a < 0 = 0
    | otherwise = a

with ctrl+enter (because of the missing indentation on the second line)

Single statements over multiple lines:

d1 $ s "hh*8"
    # up "1 2 3 4"

with shift+enter

let do where case blocks with indentation with shift+enter, otherwise with ctrl+enter. Anything mixed like statements, blocks, etc. with shift+enter, again, as long as indentation makes sense.

I really hope I got everything right this time. But I've got a good feeling about it.

lopho avatar Feb 12 '19 21:02 lopho

@lopho are the tests broken in this PR or should they run successfully?

kindohm avatar Feb 21 '19 18:02 kindohm

Yes, they are broken. But I'm fairly certain that the mocking system is at fault here.

I tried to fix it, but the values returned by the editor mock objects are absurd when selecting.

https://github.com/tidalcycles/vscode-tidalcycles/pull/8#issuecomment-462853626

The mocking system of the unit tests irritate me a bit. I don't have the time to dive into those right now. Using manual testing everything seems to work as intended.

My problems with the mocks:

  • selection in mock editor is unreliable

    • returns loads of [object Objects] in empty and non empty lines

    • skips lines altogether

    • see Multi-line expression from split selection and Multi-line expression retrieved before selection (those two test still expect the old behaviour, but still, selection is weird)

    • the mock repl in Single-line expression evaluated in .tidal file does not seem to correctly count invocations on single line statements, always counting 0

If you have the time, could you please take a look at those tests, especially the behavior of tests when checking the content of expressions. There seems to be some concurrency issues as well, as lines get returned in mixed order and such (in the tests/mocking objects, not the real thing).

lopho avatar Feb 21 '19 23:02 lopho

Did you get evaluating multiple statements in one go working in the end? e.g.

d1 $ s "hh*8"
d2 $ s "bd*4"
  # vowel "a e"

I'm not a vscode user but am interested because we tried (and failed) to get this working in emacs

yaxu avatar Feb 22 '19 09:02 yaxu

@yaxu Yes, your example works (using shift+enter). As long as your code follows some (hierarchical) indentation, it should evaluate correctly.

lopho avatar Feb 22 '19 09:02 lopho