Full Code of tidalcycles/vim-tidal for AI

master e440fe5bdfe0 cached
16 files
49.1 KB
14.6k tokens
1 requests
Download .txt
Repository: tidalcycles/vim-tidal
Branch: master
Commit: e440fe5bdfe0
Files: 16
Total size: 49.1 KB

Directory structure:
gitextract_odl0_omb/

├── .gitignore
├── CHANGELOG
├── CODE_OF_CONDUCT.md
├── LICENSE
├── Makefile
├── README.md
├── Tidal.ghci
├── bin/
│   ├── generate-completions
│   ├── tidal
│   ├── tidal.bat
│   └── tidalvim
├── boot.sc
├── ftdetect/
│   └── tidal.vim
├── ftplugin/
│   └── tidal.vim
├── plugin/
│   └── tidal.vim
└── syntax/
    └── tidal.vim

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
.dirt-samples


================================================
FILE: CHANGELOG
================================================
0.3.3

* Fix syntax highlighting issues with the `#` operator

0.3.2

* Update README

0.3.1

* Add <c-e> mapping for sending paragraphs, on Normal, Visual and Insert modes
* Flash text selection when sending text
* Force tmux to use 256 colors on tidalvim
* Add <c-h> maping as an alternative to <localleader>h
* Try to use getcurpos() if available when restoring cursor position

0.3.0

* Update bootstrap script for Tidal 0.9
* `tidalvim` now only creates 2 panes for Vim and GHCi
* Split `tidalvim` script in two scripts: `tidal` and `tidalvim`
* Better instructions for customizing Tidal bootstrap script

0.2.0

* Remove vim-slime dependency
* Preserve cursor position when sending to tmux
* Configure tmux automatically with defaults

0.1.0

* Use Slime to communicate via tmux
* Create "tidalvim" script for creating Dirt and Tidal instances
* Define more vim-like default bindings
* Add bindings to silence channels
* Add bindings for playing first occurrence of stream


================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct

## Our Pledge

In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level of experience,
nationality, personal appearance, race, religion, or sexual identity and
orientation.

## Our Standards

Examples of behavior that contributes to creating a positive environment
include:

* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members

Examples of unacceptable behavior by participants include:

* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
  address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
  professional setting

## Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.

## Scope

This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at munshkr@gmail.com. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.

Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at [http://contributor-covenant.org/version/1/4][version]

[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/


================================================
FILE: LICENSE
================================================
The MIT License (MIT)

Copyright (c) 2014 Damián Emiliano Silvani

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: Makefile
================================================
mkfile_path := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))

prefix=/usr/local

install:
	ln -fs $(mkfile_path)/bin/tidal $(prefix)/bin
	ln -fs $(mkfile_path)/bin/tidalvim $(prefix)/bin

uninstall:
	rm -f $(prefix)/bin/tidal $(prefix)/bin/tidalvim

.PHONY: install uninstall


================================================
FILE: README.md
================================================
# vim-tidal #

A Vim/NeoVim plugin for [TidalCycles](http://tidalcycles.org), the language for
live coding musical patterns written in Haskell.

This plugin by default uses [tmux](https://tmux.github.io/), a known and loved
terminal multiplexer, for communicating with between Vim and the Tidal
interpreter.  It was originally based on
[vim-slime](https://github.com/jpalardy/vim-slime).

![](http://i.imgur.com/frOLFFI.gif)

If you are using Vim8 or NeoVim, you can use the native Terminal feature instead
of tmux. Read the Configuration section on how to enable it.

[![asciicast](https://asciinema.org/a/224891.svg)](https://asciinema.org/a/224891)

## Getting Started ##

1. Start livecoding with Vim by simply running:

   ```bash
   $ tidalvim
   ```

   This creates a tmux session with Vim and Tidal running on different panes.

2. Write something like this:

   ```haskell
   d1 $ sound "bd sn"
   ```

3. While being on that line, press `<c-e>` (Control + E) to evaluate it.

   You should see Vim flash that line for a second and a chunk of text appear on
   your Tidal interpreter.  If you already have SuperDirt or other synth running,
   you should hear a kick and a snare :)

## Install ##

Make sure you have TidalCycles installed, with SuperDirt running. See [the Tidal wiki](https://tidalcycles.org/index.php/Userbase) for more information.

### Install tmux ###

#### Ubuntu/Debian ####

You can install it from the main repos:

    $ sudo apt-get install tmux

#### OSX ####

    $ brew install tmux

#### Windows ####

There seems to be [a Cygwin package for
tmux](https://cygwin.com/cgi-bin2/package-cat.cgi?file=x86%2Ftmux%2Ftmux-1.9a-1&grep=tmux),
but at present it is [not working](https://github.com/microsoft/terminal/issues/5132#issuecomment-604560893) with any known terminal emulator for Windows. As such, this plugin has only been tested with the *Windows native* build of [Neovim](https://github.com/tidalcycles/vim-tidal#neovim-terminal-target).


### Install plugin ###

I recommend using a Vim plugin manager like
[Plug](https://github.com/junegunn/vim-plug).  Check the link for instructions
on installing and configuring.  If you don't want a plugin manager, you can
also download the latest release
[here](https://github.com/tidalcycles/vim-tidal/releases) and extract the
contents on your Vim directory (usually `~/.vim/`).

For example, with Plug you need to:

  * Edit your `.vimrc` file and add these lines:

```vim
Plug 'tidalcycles/vim-tidal'
```

  * Restart Vim and execute `:PlugInstall` to automatically download and
    install the plugins.

#### UNIX-based Systems ####

If you are on a UNIX-based operating system (Linux distributions, MacOS, etc.), go to the plugin repository and run `make install`:

(if you are using NeoVim and you won't run tmux then you don't need to run `make install` to be able to load the plugin inside NeoVim)

    $ cd ~/.vim/plugged/vim-tidal
    $ sudo make install

This creates symlinks on `/usr/local/bin` for `tidal` and `tidalvim` scripts.
You can remove them later if you want with `make uninstall`.

#### Windows ####

:warning: **This plugin has only been tested on Windows 10 using Neovim >0.5**

If you are on Windows, add the `vim-tidal\bin` directory to your `PATH` user environment variable:

    1. Click the `Start` button
    2. Type "Edit the system environment variables" and hit `enter` or click on the search result
    3. Click the button labeled `Environment variables...`
    4. In the `User variables for [username]` table, click the entry for the `Path` variable, followed by the `Edit...` button beneath the same table
    5. Click the `New` button in the following dialog, enter the *full path* to the `vim-tidal\bin` directory, and click `OK` until all the preceding dialogs are closed.

Note: The full path to the `vim-tidal\bin` directory, will look something like `C:\Users\[username]\AppData\Local\nvim\plugged\vim-tidal\bin`, assuming you are using vim-plug as this document recommends.

#### Final Installation Note ####

Make sure to have the `filetype plugin on` setting on your .vimrc, otherwise
plugin won't be loaded when opening a .tidal file.

### Older Tidal versions (pre 1.0) ###

Tidal 1.0 introduces some breaking changes, so if haven't upgraded yet, you can
still use this plugin with an older version. Just point your Plug entry to use
the `tidal-0.9` branch.

First change your Plug line on your `.vimrc` to:

```vim
Plug 'tidalcycles/vim-tidal', {'branch': 'tidal-0.9'}
```

Then on Vim run `:PlugInstall` to update your plugin.


## Usage

This plugin comes bundled with two Bash scripts: `tidalvim` and `tidal`.

### `tidalvim`

`tidalvim` starts a tmux session with the screen horizontally splitted, having
Vim on the upper pane and the Tidal interpreter on the lower pane.  This is the
simplest way to start using Tidal with Vim.

You don't have to use `tidalvim` necessarily. If you have a more complex setup
or just want to use Vim outside of tmux, you can use `tidal`.  See below.

### `tidal`

`tidal` fires up GHCi (the Glasgow Haskell interpreter) and runs a bootstrap
file that loads Tidal up. `tidalvim` uses this script to start the Tidal
interpreter on the lower pane.  You can even use it standalone (without Vim) by
simply running `tidal` from your shell.

```haskell
$ tidal
GHCi, version 7.10.3: http://www.haskell.org/ghc/  :? for help
tidal> d1 $ sound "bd sn"
tidal> :t density 2 $ n "0 1"
density 2 $ n "0 1" :: Pattern ParamMap
```

So, in case you don't want to use `tidalvim`, just run the following on another
terminal:

```bash
tmux new-session -s tidal tidal
```

What `tidal` does is actually run `ghci` with the argument `-ghci-script
Tidal.ghci`.  [Tidal.ghci](Tidal.ghci) is found at the root of the repository,
and is responsible for bootstraping Tidal.  See Configure section for more on
how to customize Tidal bootstraping process.  Any extra arguments when running
`tidal` will be delegated to `ghci`.

### Commands

These are some of the commands that can be run from Vim command line:

* `:<range>TidalSend`: Send a `[range]` of lines. If no range is provided the
  current line is sent.

* `:TidalSend1 {text}`: Send a single line of text specified on the command
  line.

* `:TidalConfig`: Configure tmux socket name and target pane

* `:TidalSilence [num]`: Silence stream number `[num]` by sending `d[num]
  silence`.

* `:TidalPlay [num]`: Send first ocurrence of stream number `[num`] from the
  current cursor position.

* `:TidalHush`: Silences all streams by sending `hush`.

* `:TidalGenerateCompletions {path}`: Generate dictionary for Dirt-Samples
  completion (path is optional).

### Default bindings

Using one of these key bindings you can send lines to Tidal:

* `<c-e>` (Control+E), `<localleader>ss`: Send current inner paragraph.
* `<localleader>s`: Send current line or current visually selected block.

`<c-e>` can be called on either Normal, Visual, Select or Insert mode, so it is
probably easier to type than `<localleader>ss` or `<localleader>s`.

There are other bindings to control Tidal like:

* `<localleader>s[num]`: Call `:TidalPlay [num]`
* `<localleader>[num]`: Call `:TidalSilence [num]`
* `<localleader>h`, `<c-h>`: Call `:TidalHush`

#### About `<localleader>`

The `<leader>` key is a special key used to perform commands with a sequence of
keys.  The `<localleader>` key behaves as the `<leader>` key, but is *local* to
a buffer.  In particular, the above bindings only work in buffers with the
"tidal" file type set, e.g. files whose file type is `.tidal`

By default, there is no `<localleader>` set.  To define one, e.g. for use with
a comma (`,`), write this on your `.vimrc` file:

```vim
let maplocalleader=","
```

Reload your configuration (or restart Vim), and after typing `,ss` on a few
lines of code, you should see those being copied onto the Tidal interpreter on
the lower pane.


## Configure ##

### GHCI

By default, `vim-tidal` uses the globally installed GHCI to launch the REPL.
If you have installed Tidal through Stack (`stack install tidal`) or some other
means, you can specify another command to use with `g:tidal_ghci`.

For example, if one installed Tidal with Stack, they would use:

```vim
let g:tidal_ghci = "stack exec ghci --"
```

### Tidal Boot File

A "Tidal boot file" is a file that may be used to initialise Tidal within GHCI.
A custom boot file can be specified using the `g:tidal_boot` variable.

In the case that `g:tidal_boot` is unspecified, vim-tidal will traverse parent
directories until one of either `BootTidal.hs`, `Tidal.ghci` or `boot.tidal` are
found.

If no tidal boot file can be found by traversing parent directories, tidal will
check the `g:tidal_boot_fallback` variable for a fallback boot file. This
variable is useful for specifying a default user-wide tidal boot file on your
system, while still allowing each tidal project to optionally use their own
dedicated, local tidal boot file. By default, `g:tidal_boot_fallback` will point
to the `Tidal.ghci` file provided with this plugin.

### Default bindings ###

By default, there are two normal keybindings and one for visual blocks using
your `<localleader>` key.  If you don't have one defined, set it on your
`.vimrc` script with `let maplocalleader=","`, for example.

If you don't like some of the bindings or want to change them, add this line to
disable them:

```vim
let g:tidal_no_mappings = 1
```

See section Mappings on [ftplugin/tidal.vim](ftplugin/tidal.vim) and copy the
bindings you like to your `.vimrc` file and modify them.

### Vim Terminal

On both Vim (version 8 or above) and NeoVim, the default target in which we boot
Tidal with GHCi is the native terminal.

While it is the default, it can also be specified manually with the following:

```vim
let g:tidal_target = "terminal"
```

Open a file with a `.tidal` suffix, write and send a line of code to tidal, and
the tidal terminal will open in a window below your editor.

Use standard vim window navigation controls to focus the terminal (ie `<C-w> down/up`)

You can learn more about the native Vim terminal here:

https://vimhelp.org/terminal.txt.html

### tmux (alternative to Vim terminal)

Before Vim had native terminal support, this plugin provided a "tmux" target in
order to allow for multiplexing the user's terminal via the 3rd party CLI tool.
If you have `tmux` installed and you wish to use it instead of the native Vim
terminal, you can enable this target with the following:

```vim
let g:tidal_target = "tmux"
```

This target will be enabled automatically in the case that the version of Vim in
use does not have native terminal support.

You can configure tmux socket name and target pane by typing `<localleader>c`
or `:TidalConfig`.  This will prompt you first for the socket name, then for
the target pane.

About the target pane:

* `":"` means current window, current pane (a reasonable default)
* `":i"` means the ith window, current pane
* `":i.j"` means the ith window, jth pane
* `"h:i.j"` means the tmux session where h is the session identifier (either
  session name or number), the ith window and the jth pane

When you exit Vim you will lose that configuration. To make this permanent, set
`g:tidal_default_config` on your `.vimrc`.  For example, suppose you want to run
Tidal on a tmux session named `omg`, and the GHCi interpreter will be running
on the window 1 and pane 0.  In that case you would need to add this line:

```vim
let g:tidal_default_config = {"socket_name": "default", "target_pane": "omg:1.0"}
```

### Optional Supercollider Terminal

Vim-tidal provides an option for automatically running the supercollider
command-line tool `sclang` alongside the Tidal GCHI terminal. By default this
terminal is disabled, however it can be enabled with the following:

```vim
let g:tidal_sc_enable = 1
```

This can be useful to avoid the need to manually run sclang in a separate
terminal or to open the supercollider IDE.

A custom supercollider boot file can be specified by assigning its path to the
`g:tidal_sc_boot` variable.

In the case that `g:tidal_sc_boot` is unspecified, vim-tidal will traverse
parent directories until one of either `boot.sc` or `boot.scd` are found.

If no supercollider boot file can be found by traversing parent directories,
tidal will check the `g:tidal_sc_boot_fallback` variable for a fallback boot
file. This variable is useful for specifying a default user-wide supercollider
boot file on your system, while still allowing each tidal project to optionally
use their own dedicated, local supercollider boot file.

By default, `g:tidal_sc_boot_fallback` will point to the `boot.sc` file provided
with this plugin which simply starts SuperDirt with the default settings.

### Miscellaneous ###

When sending a paragraph or a single line, vim-tidal will "flash" the selection
for some milliseconds.  By default duration is set to 150ms, but you can modify
it by setting the `g:tidal_flash_duration` variable.

Write the paste buffer to an external text file:

```vim
let g:tidal_paste_file = "/tmp/tidal_paste_file.txt"
```

For customizing the startup script for defining helper functions, see below.


## `tidalvim` and `tidal` ##

`tidalvim`  is just an example script.  You can copy and customize it as much
as you want.  See `man tmux` if you want to know more about its options.

For example, if you want to split horizontally instead of vertically, change
the `-v` for `-h` option in the `split-window` line:

```diff
- split-window -v -t $SESSION   \; \
+ split-window -h -t $SESSION   \; \
```

Both scripts have some options that you can specify as environment variables.
For example:

```
TIDAL_TEMPO_IP=192.168.0.15 SESSION=whatever tidalvim
```

This would start Tidal synced to another Tidal on 192.168.0.15, and it would
try to attach or create a tmux sesssion called `whatever`.

The following is a list of all variables that can be changed:

* `FILE`: File name to open with Vim (default: `$(date +%F).tidal`, e.g.
  `2017-03-09.tidal`).  The `.tidal` extension is important (you can run
  `:setfiletype haskell.tidal` in case you won't use a .tidal file here).

* `SESSION`: tmux session name (default: `tidal`)

* `TIDAL_BOOT_PATH`: Tidal Bootstrap file, a .ghci file (default: `Tidal.ghci`)

* `TIDAL_TEMPO_IP`: Tells Tidal to sync tempo with another Tidal instance on
  the specified IP (default: `127.0.0.1`, i.e. use local)

* `VIM`: Vim command (default: `vim`)

* `GHCI`: GHCi command (default: `ghci`)

* `TMUX`: tmux command (default: `tmux`)

### Customizing Tidal startup ###

In case you have defined some helper functions, and/or you want to import other
modules into Tidal, you can edit the `Tidal.ghci` found at the root of the
repository.

However doing this could eventually cause conflicts when trying to upgrade
vim-tidal, so instead I recommend that you define a different `.ghci` file that
first loads `Tidal.ghci` and includes all your custom definitions.

Here is an example.  Suppose you define a `myStuff.ghci` file on your home
directory like this:

```haskell
--file: ~/myStuff.ghci

-- Bootstrap Tidal
-- Replace this path if you have vim-tidal installed elsewhere
:script ~/.vim/bundle/vim-tidal/Tidal.ghci

:{
let foo = every 4 $ within (0.75, 1) (density 4)
    bar = n "<0 1 2 4>"
:}
```

Then, you would run `tidal` or `tidalvim` with `TIDAL_BOOT_PATH` pointing to
your new script file:

```bash
TIDAL_BOOT_PATH=~/myStuff.ghci tidalvim
```

Please note that this a `.ghci` script, not a Haskell module. So multiline
definitions need to be wrapped around `:{` and `:}`, as shown in the example
above.


## Troubleshooting

Here is a list of common problems.

> I press `<c-e>` but it moves the screen down by one line, and nothing else happens

Usually `<c-e>` is used to move the screen forward by one line, but vim-tidal remaps
this to sending current paragraph. If this is happening you either:

1. Opened a file without `.tidal` extension, or changed file type accidentally.
   *Solution*: Reopen Vim or set filetype for current buffer with `:set
   ft=tidal`.
2. Have `g:tidal_no_mappings` setting on your `.vimrc`. This disables all
   mappings.
   *Solution*: Remove `<c-e>` binding, or rebind to something else.

It could also be that you do not have `filetype plugin on` setting in your
.vimrc.  Make sure you have that setting defined.

> I press `<c-e>` and nothing else happens

This means that vim-tidal is sending text to tmux, but to the wrong
session/window/pane.
*Solution*: Check that you have configure the socket name and target pane
correctly.  See the Configure section above for more information.

If you have any question or something does not work as expected, there are many
channels you can go to:

* [Chat](https://talk.lurk.org/): Reach out at the `#tidal` and `#vim` channels
* [GitHub issues](https://github.com/tidalcycles/vim-tidal/issues/new)
* [Official Tidal forum](https://we.lurk.org/postorius/lists/tidal.we.lurk.org/)


## Contributing

Bug reports and pull requests are welcome on GitHub at
<https://github.com/tidalcycles/vim-tidal>.  This project is intended to be a
safe, welcoming space for collaboration, and contributors are expected to
adhere to the [Contributor Covenant](http://contributor-covenant.org) code of
conduct.


## License

Refer to the [LICENSE](LICENSE) file


================================================
FILE: Tidal.ghci
================================================
:set -XOverloadedStrings
:set prompt ""

import Sound.Tidal.Context

import System.IO (hSetEncoding, stdout, utf8)
hSetEncoding stdout utf8

-- total latency = oLatency + cFrameTimespan
tidal <- startTidal (superdirtTarget {oLatency = 0.1, oAddress = "127.0.0.1", oPort = 57120}) (defaultConfig {cVerbose = True, cFrameTimespan = 1/20})

:{
let only = (hush >>)
    p = streamReplace tidal
    hush = streamHush tidal
    panic = do hush
               once $ sound "superpanic"
    list = streamList tidal
    mute = streamMute tidal
    unmute = streamUnmute tidal
    unmuteAll = streamUnmuteAll tidal
    unsoloAll = streamUnsoloAll tidal
    solo = streamSolo tidal
    unsolo = streamUnsolo tidal
    once = streamOnce tidal
    first = streamFirst tidal
    asap = once
    nudgeAll = streamNudgeAll tidal
    all = streamAll tidal
    resetCycles = streamResetCycles tidal
    setcps = asap . cps
    getcps = streamGetcps tidal
    getnow = streamGetnow tidal
    xfade i = transition tidal True (Sound.Tidal.Transition.xfadeIn 4) i
    xfadeIn i t = transition tidal True (Sound.Tidal.Transition.xfadeIn t) i
    histpan i t = transition tidal True (Sound.Tidal.Transition.histpan t) i
    wait i t = transition tidal True (Sound.Tidal.Transition.wait t) i
    waitT i f t = transition tidal True (Sound.Tidal.Transition.waitT f t) i
    jump i = transition tidal True (Sound.Tidal.Transition.jump) i
    jumpIn i t = transition tidal True (Sound.Tidal.Transition.jumpIn t) i
    jumpIn' i t = transition tidal True (Sound.Tidal.Transition.jumpIn' t) i
    jumpMod i t = transition tidal True (Sound.Tidal.Transition.jumpMod t) i
    jumpMod' i t p = transition tidal True (Sound.Tidal.Transition.jumpMod' t p) i
    mortal i lifespan release = transition tidal True (Sound.Tidal.Transition.mortal lifespan release) i
    interpolate i = transition tidal True (Sound.Tidal.Transition.interpolate) i
    interpolateIn i t = transition tidal True (Sound.Tidal.Transition.interpolateIn t) i
    clutch i = transition tidal True (Sound.Tidal.Transition.clutch) i
    clutchIn i t = transition tidal True (Sound.Tidal.Transition.clutchIn t) i
    anticipate i = transition tidal True (Sound.Tidal.Transition.anticipate) i
    anticipateIn i t = transition tidal True (Sound.Tidal.Transition.anticipateIn t) i
    forId i t = transition tidal False (Sound.Tidal.Transition.mortalOverlay t) i
    d1 = p 1 . (|< orbit 0)
    d2 = p 2 . (|< orbit 1)
    d3 = p 3 . (|< orbit 2)
    d4 = p 4 . (|< orbit 3)
    d5 = p 5 . (|< orbit 4)
    d6 = p 6 . (|< orbit 5)
    d7 = p 7 . (|< orbit 6)
    d8 = p 8 . (|< orbit 7)
    d9 = p 9 . (|< orbit 8)
    d10 = p 10 . (|< orbit 9)
    d11 = p 11 . (|< orbit 10)
    d12 = p 12 . (|< orbit 11)
    d13 = p 13
    d14 = p 14
    d15 = p 15
    d16 = p 16
:}

:{
let getState = streamGet tidal
    setI = streamSetI tidal
    setF = streamSetF tidal
    setS = streamSetS tidal
    setR = streamSetR tidal
    setB = streamSetB tidal
:}

:set prompt "tidal> "
:set prompt-cont ""

default (Pattern String, Integer, Double)


================================================
FILE: bin/generate-completions
================================================
#!/usr/bin/env sh

samplepath=$1
outputpath=$2

ls "$samplepath" | sed 's/README.md//; s/Dirt-Samples.quark//;' | sed '/^\s*$/d' > "$outputpath"


================================================
FILE: bin/tidal
================================================
#!/usr/bin/env bash
set -euf -o pipefail

GHCI=${GHCI:-"ghci"}
TIDAL_DATA_DIR=$($GHCI -e Paths_tidal.getDataDir | sed 's/"//g')
TIDAL_BOOT_PATH=${TIDAL_BOOT_PATH:-"$TIDAL_DATA_DIR/BootTidal.hs"}

# Run GHCI and load Tidal bootstrap file
$GHCI -ghci-script $TIDAL_BOOT_PATH "$@"


================================================
FILE: bin/tidal.bat
================================================
@ECHO OFF

REM Store the directory containing the script in a variable
SET "source=%~dp0"

REM Get path to vim-tidal bootfile
SET "TIDAL_BOOT_PATH=%SOURCE%\..\Tidal.ghci"

REM Launch Tidal Cycles
ghci -ghci-script "%TIDAL_BOOT_PATH%"

================================================
FILE: bin/tidalvim
================================================
#!/usr/bin/env bash
set -euf -o pipefail

VIM=${VIM:-"vim"}
TMUX=${TMUX:-"tmux"}

FILE=${FILE:-"$(date +%F).tidal"}
SESSION=${SESSION:-"tidal"}

TIDAL_BOOT_PATH=${TIDAL_BOOT_PATH:-""}
GHCI=${GHCI:-""}

args=${@:-$FILE}

# Check if tmux session "tidal" is running, attach only
# else, create new session, split windows and run processes
$TMUX -2 attach-session -t $SESSION || $TMUX -2 \
  new-session -s $SESSION   \; \
  split-window -v -t $SESSION   \; \
  send-keys -t 0 "$VIM $args" C-m   \; \
  send-keys -t 1 "TIDAL_BOOT_PATH=$TIDAL_BOOT_PATH GHCI=$GHCI tidal" C-m   \; \
  select-pane -t 0


================================================
FILE: boot.sc
================================================
SuperDirt.start;


================================================
FILE: ftdetect/tidal.vim
================================================
autocmd BufRead,BufNewFile *.tidal setfiletype tidal


================================================
FILE: ftplugin/tidal.vim
================================================
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Functions
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

let s:not_prefixable_keywords = [ "import", "data", "instance", "class", "{-#", "type", "case", "do", "let", "default", "foreign", "--"]

" guess correct number of spaces to indent
" (tabs are not allowed)
function! Get_indent_string()
    return repeat(" ", 4)
endfunction

" replace tabs by spaces
function! Tab_to_spaces(text)
    return substitute(a:text, "	", Get_indent_string(), "g")
endfunction

" Wrap in :{ :} if there's more than one line
function! Wrap_if_multi(lines)
    if len(a:lines) > 1
        return [":{"] + a:lines + [":}"]
    else
        return a:lines
    endif
endfunction

" change string into array of lines
function! Lines(text)
    return split(a:text, "\n")
endfunction

" change lines back into text
function! Unlines(lines)
    if g:tidal_target == "tmux"
        " Without this, the user has to manually submit a newline each time
        " they evaluate an expression with `ctrl e`.
        return join(a:lines, "\n") . "\n"
    else
        return join(a:lines, "\n")
    endif
endfunction

" vim slime handler
function! _EscapeText_tidal(text)
    let l:lines = Lines(Tab_to_spaces(a:text))
    let l:lines = Wrap_if_multi(l:lines)
    return Unlines(l:lines)
endfunction

""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Mappings
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

if !exists("g:tidal_no_mappings") || !g:tidal_no_mappings
  if !hasmapto('<Plug>TidalConfig', 'n')
    nmap <buffer> <localleader>c <Plug>TidalConfig
  endif

  if !hasmapto('<Plug>TidalRegionSend', 'x')
    xmap <buffer> <localleader>s  <Plug>TidalRegionSend
    xmap <buffer> <c-e> <Plug>TidalRegionSend
  endif

  if !hasmapto('<Plug>TidalLineSend', 'n')
    nmap <buffer> <localleader>s  <Plug>TidalLineSend
  endif

  if !hasmapto('<Plug>TidalParagraphSend', 'n')
    nmap <buffer> <localleader>ss <Plug>TidalParagraphSend
    nmap <buffer> <c-e> <Plug>TidalParagraphSend
  endif

  imap <buffer> <c-e> <Esc><Plug>TidalParagraphSend<Esc>i<Right>

  nnoremap <buffer> <localleader>h :TidalHush<cr>
  nnoremap <buffer> <c-h> :TidalHush<cr>
  let i = 1
  while i <= 9
    execute 'nnoremap <buffer> <localleader>'.i.'  :TidalSilence '.i.'<cr>'
    execute 'nnoremap <buffer> <c-'.i.'>  :TidalSilence '.i.'<cr>'
    execute 'nnoremap <buffer> <localleader>s'.i.' :TidalPlay '.i.'<cr>'
    let i += 1
  endwhile
endif


================================================
FILE: plugin/tidal.vim
================================================
if exists("g:loaded_tidal") || &cp || v:version < 700
  finish
endif
let g:loaded_tidal = 1
let s:parent_path = fnamemodify(expand("<sfile>"), ":p:h:s?/plugin??")

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Default config
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

" Attempts to find a tidal boot file in this or any parent directory.
function s:FindTidalBoot()
  for name in ["BootTidal.hs", "Tidal.ghci", "boot.tidal"]
    let tidal_boot_file = findfile(name, ".".';')
    if !empty(tidal_boot_file)
      return tidal_boot_file
    endif
  endfor
endfunction

" Attempts to find a supercollider startup file in this or any parent dir.
function s:FindScBoot()
  for name in ["boot.sc", "boot.scd"]
    let sc_boot_file = findfile(name, ".".';')
    if !empty(sc_boot_file)
      return sc_boot_file
    endif
  endfor
endfunction

if !exists("g:tidal_target")
  if has('nvim') || has('terminal')
    let g:tidal_target = "terminal"
  else
    let g:tidal_target = "tmux"
  endif
endif

if !exists("g:tidal_paste_file")
  let g:tidal_paste_file = tempname()
endif

if !exists("g:tidal_default_config")
  let g:tidal_default_config = { "socket_name": "default", "target_pane": ":0.1" }
endif

if !exists("g:tidal_preserve_curpos")
  let g:tidal_preserve_curpos = 1
endif

if !exists("g:tidal_flash_duration")
  let g:tidal_flash_duration = 150
endif

if !exists("g:tidal_ghci")
  let g:tidal_ghci = "ghci"
endif

if !exists("g:tidal_boot_fallback")
  let g:tidal_boot_fallback = s:parent_path . "/Tidal.ghci"
endif

if !exists("g:tidal_boot")
  let g:tidal_boot = s:FindTidalBoot()
  if empty(g:tidal_boot)
    let g:tidal_boot = g:tidal_boot_fallback
  endif
endif

if !exists("g:tidal_superdirt_enable")
  " Allow vim-tidal to automatically start SuperDirt. Disabled by default.
  let g:tidal_superdirt_enable = 0
endif

if !exists("g:tidal_sclang")
  let g:tidal_sclang = "sclang"
endif

" Allow vim-tidal to automatically start supercollider. Disabled by default.
if !exists("g:tidal_sc_enable")
  let g:tidal_sc_enable = 0
endif

if !exists("g:tidal_sc_boot_fallback")
  let g:tidal_sc_boot_fallback = s:parent_path . "/boot.sc"
endif

if !exists("g:tidal_sc_boot")
  let g:tidal_sc_boot = s:FindScBoot()
  if empty(g:tidal_sc_boot)
    let g:tidal_sc_boot = g:tidal_sc_boot_fallback
  endif
endif

if !exists("g:tidal_sc_boot_cmd")
  " A command that can be run from the terminal to start supercollider.
  " The default assumes `SuperDirt` is installed.
  let g:tidal_sc_boot_cmd = g:tidal_sclang . " " . g:tidal_sc_boot
endif

if filereadable(s:parent_path . "/.dirt-samples")
  let &l:dictionary .= ',' . s:parent_path . "/.dirt-samples"
endif

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Tmux
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

function! s:TmuxSend(config, text)
  let l:prefix = "tmux -L " . shellescape(a:config["socket_name"])
  " use STDIN unless configured to use a file
  if !exists("g:tidal_paste_file")
    call system(l:prefix . " load-buffer -", a:text)
  else
    call s:WritePasteFile(a:text)
    call system(l:prefix . " load-buffer " . g:tidal_paste_file)
  end
  call system(l:prefix . " paste-buffer -d -t " . shellescape(a:config["target_pane"]))
endfunction

function! s:TmuxPaneNames(A,L,P)
  let format = '#{pane_id} #{session_name}:#{window_index}.#{pane_index} #{window_name}#{?window_active, (active),}'
  return system("tmux -L " . shellescape(b:tidal_config['socket_name']) . " list-panes -a -F " . shellescape(format))
endfunction

function! s:TmuxConfig() abort
  if !exists("b:tidal_config")
    let b:tidal_config = {"socket_name": "default", "target_pane": ":"}
  end

  let b:tidal_config["socket_name"] = input("tmux socket name: ", b:tidal_config["socket_name"])
  let b:tidal_config["target_pane"] = input("tmux target pane: ", b:tidal_config["target_pane"], "custom,<SNR>" . s:SID() . "_TmuxPaneNames")
  if b:tidal_config["target_pane"] =~ '\s\+'
    let b:tidal_config["target_pane"] = split(b:tidal_config["target_pane"])[0]
  endif
endfunction


"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Terminal
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

let s:tidal_term_ghci = -1
let s:tidal_term_sc = -1

" NVim and VIM8 Terminal Implementation
" =====================================
function! s:TerminalOpen()
  if has('nvim')
    let current_win = winnr()

    if s:tidal_term_ghci == -1
        " force terminal split to open below current pane
        :exe "set splitbelow"
        execute "split term://" . g:tidal_ghci . " -ghci-script=" . g:tidal_boot
        let s:tidal_term_ghci = b:terminal_job_id

        " Give tidal a moment to start up so following commands can take effect
        sleep 500m

        " Make terminal scroll to follow output
        :exe "normal G"
        :exe "normal 10\<c-w>_"
    endif

    if g:tidal_sc_enable == 1 && s:tidal_term_sc == -1
        execute "vsplit term://" . g:tidal_sc_boot_cmd
        let s:tidal_term_sc = b:terminal_job_id

        " Make terminal scroll to follow output
        :exe "normal G"
    endif

    execute current_win .. "wincmd w"
  elseif has('terminal')
    " Keep track of the current window number so we can switch back.
    let current_win = winnr()

    " Open a Terminal with GHCI with tidal booted.
    if s:tidal_term_ghci == -1
      execute "below split"
      let s:tidal_term_ghci = term_start((g:tidal_ghci . " -ghci-script=" . g:tidal_boot), #{
            \ term_name: 'tidal',
            \ term_rows: 10,
            \ norestore: 1,
            \ curwin: 1,
            \ })
    endif

    " Open a terminal with supercollider running.
    if g:tidal_sc_enable == 1 && s:tidal_term_sc == -1
      execute "vert split"
      let s:tidal_term_sc = term_start(g:tidal_sc_boot_cmd, #{
           \ term_name: 'supercollider',
           \ term_rows: 10,
           \ norestore: 1,
           \ curwin: 1,
           \ })
    endif

    " Return focus to the original window.
    execute current_win .. "wincmd w"
  endif
endfunction

function! s:TerminalSend(config, text)
  call s:TerminalOpen()
  if has('nvim')
    call jobsend(s:tidal_term_ghci, a:text . "\<CR>")
  elseif has('terminal')
    call term_sendkeys(s:tidal_term_ghci, a:text . "\<CR>")
  endif
endfunction

" These two are unnecessary AFAIK.
function! s:TerminalPaneNames(A,L,P)
endfunction
function! s:TerminalConfig() abort
endfunction

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Helpers
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

function! s:SID()
  return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze_SID$')
endfun

function! s:WritePasteFile(text)
  " could check exists("*writefile")
  call system("cat > " . g:tidal_paste_file, a:text)
endfunction

function! s:_EscapeText(text)
  if exists("&filetype")
    let custom_escape = "_EscapeText_" . substitute(&filetype, "[.]", "_", "g")
    if exists("*" . custom_escape)
      let result = call(custom_escape, [a:text])
    end
  end

  " use a:text if the ftplugin didn't kick in
  if !exists("result")
    let result = a:text
  end

  " return an array, regardless
  if type(result) == type("")
    return [result]
  else
    return result
  end
endfunction

function! s:TidalGetConfig()
  if !exists("b:tidal_config")
    if exists("g:tidal_default_config")
      let b:tidal_config = g:tidal_default_config
    else
      call s:TidalDispatch('Config')
    end
  end
endfunction

function! s:TidalFlashVisualSelection()
  " Redraw to show current visual selection, and sleep
  redraw
  execute "sleep " . g:tidal_flash_duration . " m"
  " Then leave visual mode
  silent exe "normal! vv"
endfunction

function! s:TidalSendOp(type, ...) abort
  call s:TidalGetConfig()

  let sel_save = &selection
  let &selection = "inclusive"
  let rv = getreg('"')
  let rt = getregtype('"')

  if a:0  " Invoked from Visual mode, use '< and '> marks.
    silent exe "normal! `<" . a:type . '`>y'
  elseif a:type == 'line'
    silent exe "normal! '[V']y"
  elseif a:type == 'block'
    silent exe "normal! `[\<C-V>`]\y"
  else
    silent exe "normal! `[v`]y"
  endif

  call setreg('"', @", 'V')
  call s:TidalSend(@")

  " Flash selection
  if a:type == 'line'
    silent exe "normal! '[V']"
    call s:TidalFlashVisualSelection()
  endif

  let &selection = sel_save
  call setreg('"', rv, rt)

  call s:TidalRestoreCurPos()
endfunction

function! s:TidalSendRange() range abort
  call s:TidalGetConfig()

  let rv = getreg('"')
  let rt = getregtype('"')
  silent execute a:firstline . ',' . a:lastline . 'yank'
  call s:TidalSend(@")
  call setreg('"', rv, rt)
endfunction

function! s:TidalSendLines(count) abort
  call s:TidalGetConfig()

  let rv = getreg('"')
  let rt = getregtype('"')

  silent execute "normal! " . a:count . "yy"

  call s:TidalSend(@")
  call setreg('"', rv, rt)

  " Flash lines
  silent execute "normal! V"
  if a:count > 1
    silent execute "normal! " . (a:count - 1) . "\<Down>"
  endif
  call s:TidalFlashVisualSelection()
endfunction

function! s:TidalStoreCurPos()
  if g:tidal_preserve_curpos == 1
    if exists("*getcurpos")
      let s:cur = getcurpos()
    else
      let s:cur = getpos('.')
    endif
  endif
endfunction

function! s:TidalRestoreCurPos()
  if g:tidal_preserve_curpos == 1
    call setpos('.', s:cur)
  endif
endfunction

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Public interface
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

function! s:TidalSend(text)
  call s:TidalGetConfig()

  let pieces = s:_EscapeText(a:text)
  for piece in pieces
    call s:TidalDispatch('Send', b:tidal_config, piece)
  endfor
endfunction

function! s:TidalConfig() abort
  call inputsave()
  call s:TidalDispatch('Config')
  call inputrestore()
endfunction

" delegation
function! s:TidalDispatch(name, ...)
  let target = substitute(tolower(g:tidal_target), '\(.\)', '\u\1', '') " Capitalize
  return call("s:" . target . a:name, a:000)
endfunction

function! s:TidalHush()
  execute 'TidalSend1 hush'
endfunction

function! s:TidalSilence(stream)
  silent execute 'TidalSend1 d' . a:stream . ' silence'
endfunction

function! s:TidalPlay(stream)
  let res = search('^\s*d' . a:stream)
  if res > 0
    silent execute "normal! vip:TidalSend\<cr>"
    silent execute "normal! vip"
    call s:TidalFlashVisualSelection()
  else
    echo "d" . a:stream . " was not found"
  endif
endfunction

function! s:TidalGenerateCompletions(path)
  let l:exe = s:parent_path . "/bin/generate-completions"
  let l:output_path = s:parent_path . "/.dirt-samples"

  if !empty(a:path)
    let l:sample_path = a:path
  else
    if has('macunix')
      let l:sample_path = "~/Library/Application Support/SuperCollider/downloaded-quarks/Dirt-Samples"
    elseif has('unix')
      let l:sample_path = "~/.local/share/SuperCollider/downloaded-quarks/Dirt-Samples"
    endif
  endif
  " generate completion file
  silent execute '!' . l:exe shellescape(expand(l:sample_path)) shellescape(expand(l:output_path))
  echo "Generated dictionary of dirt-samples"
  " setup completion
  let &l:dictionary .= ',' . l:output_path
endfunction

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Setup key bindings
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

command -bar -nargs=0 TidalConfig call s:TidalConfig()
command -range -bar -nargs=0 TidalSend <line1>,<line2>call s:TidalSendRange()
command -nargs=+ TidalSend1 call s:TidalSend(<q-args>)

command! -nargs=0 TidalHush call s:TidalHush()
command! -nargs=1 TidalSilence call s:TidalSilence(<args>)
command! -nargs=1 TidalPlay call s:TidalPlay(<args>)
command! -nargs=? TidalGenerateCompletions call s:TidalGenerateCompletions(<q-args>)

noremap <SID>Operator :<c-u>call <SID>TidalStoreCurPos()<cr>:set opfunc=<SID>TidalSendOp<cr>g@

noremap <unique> <script> <silent> <Plug>TidalRegionSend :<c-u>call <SID>TidalSendOp(visualmode(), 1)<cr>
noremap <unique> <script> <silent> <Plug>TidalLineSend :<c-u>call <SID>TidalSendLines(v:count1)<cr>
noremap <unique> <script> <silent> <Plug>TidalMotionSend <SID>Operator
noremap <unique> <script> <silent> <Plug>TidalParagraphSend <SID>Operatorip
noremap <unique> <script> <silent> <Plug>TidalConfig :<c-u>TidalConfig<cr>


================================================
FILE: syntax/tidal.vim
================================================
" syntax highlighting for tidal/haskell
"
" Very minor modifications from syntax file of
" https://github.com/neovimhaskell/haskell-vim
"
" Heavily modified version of the haskell syntax
" highlighter to support haskell.
"
" author: raichoo (raichoo@googlemail.com)

if version < 600
  syn clear
elseif exists("b:current_syntax")
  finish
endif

if get(g:, 'haskell_backpack', 0)
  syn keyword haskellBackpackStructure unit signature
  syn keyword haskellBackpackDependency dependency
endif

syn spell notoplevel
syn match haskellRecordField contained containedin=haskellBlock
  \ "[_a-z][a-zA-Z0-9_']*\(,\s*[_a-z][a-zA-Z0-9_']*\)*\_s\+::\_s"
  \ contains=
  \ haskellIdentifier,
  \ haskellOperators,
  \ haskellSeparator,
  \ haskellParens
syn match haskellTypeSig
  \ "^\s*\(where\s\+\|let\s\+\|default\s\+\)\?[_a-z][a-zA-Z0-9_']*#\?\(,\s*[_a-z][a-zA-Z0-9_']*#\?\)*\_s\+::\_s"
  \ contains=
  \ haskellWhere,
  \ haskellLet,
  \ haskellDefault,
  \ haskellIdentifier,
  \ haskellOperators,
  \ haskellSeparator,
  \ haskellParens
syn keyword haskellWhere where
syn keyword haskellLet let
syn match HaskellDerive "\<deriving\>\(\s\+\<\(anyclass\|instance\|newtype\|stock\)\>\)\?"
syn keyword haskellDeclKeyword module class instance newtype in
syn match haskellDecl "\<\(type\|data\)\>\s\+\(\<family\>\)\?"
syn keyword haskellDefault default
syn keyword haskellImportKeywords import qualified safe as hiding contained
syn keyword haskellForeignKeywords foreign export import ccall safe unsafe interruptible capi prim contained
syn region haskellForeignImport start="\<foreign\>" end="\_s\+::\s" keepend
  \ contains=
  \ haskellString,
  \ haskellOperators,
  \ haskellForeignKeywords,
  \ haskellIdentifier
syn match haskellImport "^\s*\<import\>\s\+\(\<safe\>\s\+\)\?\(\<qualified\>\s\+\)\?.\+\(\s\+\<as\>\s\+.\+\)\?\(\s\+\<hiding\>\)\?"
  \ contains=
  \ haskellParens,
  \ haskellOperators,
  \ haskellImportKeywords,
  \ haskellType,
  \ haskellLineComment,
  \ haskellBlockComment,
  \ haskellString,
  \ haskellPragma
syn keyword haskellKeyword do case of
if get(g:, 'haskell_enable_static_pointers', 0)
  syn keyword haskellStatic static
endif
syn keyword haskellConditional if then else
syn match haskellNumber "\<[0-9]\+\>\|\<0[xX][0-9a-fA-F]\+\>\|\<0[oO][0-7]\+\>\|\<0[bB][10]\+\>"
syn match haskellFloat "\<[0-9]\+\.[0-9]\+\([eE][-+]\=[0-9]\+\)\=\>"
syn match haskellSeparator  "[,;]"
syn region haskellParens matchgroup=haskellDelimiter start="(" end=")" contains=TOP,haskellTypeSig,@Spell
syn region haskellBrackets matchgroup=haskellDelimiter start="\[" end="]" contains=TOP,haskellTypeSig,@Spell
syn region haskellBlock matchgroup=haskellDelimiter start="{" end="}" contains=TOP,@Spell
syn keyword haskellInfix infix infixl infixr
syn keyword haskellBottom undefined error
syn match haskellOperators "[-!#$%&\*\+/<=>\?@\\^|~:.]\+\|\<_\>"
syn match haskellQuote "\<'\+" contained
syn match haskellQuotedType "[A-Z][a-zA-Z0-9_']*\>" contained
syn region haskellQuoted start="\<'\+" end="\>"
  \ contains=
  \ haskellType,
  \ haskellQuote,
  \ haskellQuotedType,
  \ haskellSeparator,
  \ haskellParens,
  \ haskellOperators,
  \ haskellIdentifier
syn match haskellLineComment "---*\([^-!#$%&\*\+./<=>\?@\\^|~].*\)\?$"
  \ contains=
  \ haskellTodo,
  \ @Spell
syn match haskellBacktick "`[A-Za-z_][A-Za-z0-9_\.']*#\?`"
syn region haskellString start=+"+ skip=+\\\\\|\\"+ end=+"+
  \ contains=@Spell
syn match haskellIdentifier "[_a-z][a-zA-z0-9_']*" contained
syn match haskellChar "\<'[^'\\]'\|'\\.'\|'\\u[0-9a-fA-F]\{4}'\>"
syn match haskellType "\<[A-Z][a-zA-Z0-9_']*\>"
syn region haskellBlockComment start="{-" end="-}"
  \ contains=
  \ haskellBlockComment,
  \ haskellTodo,
  \ @Spell
syn region haskellPragma start="{-#" end="#-}"
syn region haskellLiquid start="{-@" end="@-}"
"syn match haskellPreProc "^#.*$"
syn keyword haskellTodo TODO FIXME contained
" Treat a shebang line at the start of the file as a comment
syn match haskellShebang "\%^#!.*$"
if !get(g:, 'haskell_disable_TH', 0)
    syn match haskellQuasiQuoted "." containedin=haskellQuasiQuote contained
    syn region haskellQuasiQuote matchgroup=haskellTH start="\[[_a-zA-Z][a-zA-z0-9._']*|" end="|\]"
    syn region haskellTHBlock matchgroup=haskellTH start="\[\(d\|t\|p\)\?|" end="|]" contains=TOP
    syn region haskellTHDoubleBlock matchgroup=haskellTH start="\[||" end="||]" contains=TOP
endif
if get(g:, 'haskell_enable_typeroles', 0)
  syn keyword haskellTypeRoles phantom representational nominal contained
  syn region haskellTypeRoleBlock matchgroup=haskellTypeRoles start="type\s\+role" end="$" keepend
    \ contains=
    \ haskellType,
    \ haskellTypeRoles
endif
if get(g:, 'haskell_enable_quantification', 0)
  syn keyword haskellForall forall
endif
if get(g:, 'haskell_enable_recursivedo', 0)
  syn keyword haskellRecursiveDo mdo rec
endif
if get(g:, 'haskell_enable_arrowsyntax', 0)
  syn keyword haskellArrowSyntax proc
endif
if get(g:, 'haskell_enable_pattern_synonyms', 0)
  syn keyword haskellPatternKeyword pattern
endif

highlight def link haskellBottom Macro
highlight def link haskellTH Boolean
highlight def link haskellIdentifier Identifier
highlight def link haskellForeignKeywords Structure
highlight def link haskellKeyword Keyword
highlight def link haskellDefault Keyword
highlight def link haskellConditional Conditional
highlight def link haskellNumber Number
highlight def link haskellFloat Float
highlight def link haskellSeparator Delimiter
highlight def link haskellDelimiter Delimiter
highlight def link haskellInfix Keyword
highlight def link haskellOperators Operator
highlight def link haskellQuote Operator
highlight def link haskellShebang Comment
highlight def link haskellLineComment Comment
highlight def link haskellBlockComment Comment
highlight def link haskellPragma SpecialComment
highlight def link haskellLiquid SpecialComment
highlight def link haskellString String
highlight def link haskellChar String
highlight def link haskellBacktick Operator
highlight def link haskellQuasiQuoted String
highlight def link haskellTodo Todo
"highlight def link haskellPreProc PreProc
highlight def link haskellAssocType Type
highlight def link haskellQuotedType Type
highlight def link haskellType Type
highlight def link haskellImportKeywords Include
if get(g:, 'haskell_classic_highlighting', 0)
  highlight def link haskellDeclKeyword Keyword
  highlight def link HaskellDerive Keyword
  highlight def link haskellDecl Keyword
  highlight def link haskellWhere Keyword
  highlight def link haskellLet Keyword
else
  highlight def link haskellDeclKeyword Structure
  highlight def link HaskellDerive Structure
  highlight def link haskellDecl Structure
  highlight def link haskellWhere Structure
  highlight def link haskellLet Structure
endif

if get(g:, 'haskell_enable_quantification', 0)
  highlight def link haskellForall Operator
endif
if get(g:, 'haskell_enable_recursivedo', 0)
  highlight def link haskellRecursiveDo Keyword
endif
if get(g:, 'haskell_enable_arrowsyntax', 0)
  highlight def link haskellArrowSyntax Keyword
endif
if get(g:, 'haskell_enable_static_pointers', 0)
  highlight def link haskellStatic Keyword
endif
if get(g:, 'haskell_classic_highlighting', 0)
  if get(g:, 'haskell_enable_pattern_synonyms', 0)
    highlight def link haskellPatternKeyword Keyword
  endif
  if get(g:, 'haskell_enable_typeroles', 0)
    highlight def link haskellTypeRoles Keyword
  endif
else
  if get(g:, 'haskell_enable_pattern_synonyms', 0)
    highlight def link haskellPatternKeyword Structure
  endif
  if get(g:, 'haskell_enable_typeroles', 0)
    highlight def link haskellTypeRoles Structure
  endif
endif

if get(g:, 'haskell_backpack', 0)
  highlight def link haskellBackpackStructure Structure
  highlight def link haskellBackpackDependency Include
endif

let b:current_syntax = "tidal"
Download .txt
gitextract_odl0_omb/

├── .gitignore
├── CHANGELOG
├── CODE_OF_CONDUCT.md
├── LICENSE
├── Makefile
├── README.md
├── Tidal.ghci
├── bin/
│   ├── generate-completions
│   ├── tidal
│   ├── tidal.bat
│   └── tidalvim
├── boot.sc
├── ftdetect/
│   └── tidal.vim
├── ftplugin/
│   └── tidal.vim
├── plugin/
│   └── tidal.vim
└── syntax/
    └── tidal.vim
Condensed preview — 16 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (55K chars).
[
  {
    "path": ".gitignore",
    "chars": 14,
    "preview": ".dirt-samples\n"
  },
  {
    "path": "CHANGELOG",
    "chars": 979,
    "preview": "0.3.3\n\n* Fix syntax highlighting issues with the `#` operator\n\n0.3.2\n\n* Update README\n\n0.3.1\n\n* Add <c-e> mapping for se"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 3225,
    "preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, w"
  },
  {
    "path": "LICENSE",
    "chars": 1090,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2014 Damián Emiliano Silvani\n\nPermission is hereby granted, free of charge, to any "
  },
  {
    "path": "Makefile",
    "chars": 288,
    "preview": "mkfile_path := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))\n\nprefix=/usr/local\n\ninstall:\n\tln -fs $(mkfile_p"
  },
  {
    "path": "README.md",
    "chars": 17344,
    "preview": "# vim-tidal #\n\nA Vim/NeoVim plugin for [TidalCycles](http://tidalcycles.org), the language for\nlive coding musical patte"
  },
  {
    "path": "Tidal.ghci",
    "chars": 3067,
    "preview": ":set -XOverloadedStrings\n:set prompt \"\"\n\nimport Sound.Tidal.Context\n\nimport System.IO (hSetEncoding, stdout, utf8)\nhSetE"
  },
  {
    "path": "bin/generate-completions",
    "chars": 145,
    "preview": "#!/usr/bin/env sh\n\nsamplepath=$1\noutputpath=$2\n\nls \"$samplepath\" | sed 's/README.md//; s/Dirt-Samples.quark//;' | sed '/"
  },
  {
    "path": "bin/tidal",
    "chars": 278,
    "preview": "#!/usr/bin/env bash\nset -euf -o pipefail\n\nGHCI=${GHCI:-\"ghci\"}\nTIDAL_DATA_DIR=$($GHCI -e Paths_tidal.getDataDir | sed 's"
  },
  {
    "path": "bin/tidal.bat",
    "chars": 233,
    "preview": "@ECHO OFF\n\nREM Store the directory containing the script in a variable\nSET \"source=%~dp0\"\n\nREM Get path to vim-tidal boo"
  },
  {
    "path": "bin/tidalvim",
    "chars": 596,
    "preview": "#!/usr/bin/env bash\nset -euf -o pipefail\n\nVIM=${VIM:-\"vim\"}\nTMUX=${TMUX:-\"tmux\"}\n\nFILE=${FILE:-\"$(date +%F).tidal\"}\nSESS"
  },
  {
    "path": "boot.sc",
    "chars": 17,
    "preview": "SuperDirt.start;\n"
  },
  {
    "path": "ftdetect/tidal.vim",
    "chars": 53,
    "preview": "autocmd BufRead,BufNewFile *.tidal setfiletype tidal\n"
  },
  {
    "path": "ftplugin/tidal.vim",
    "chars": 2570,
    "preview": "\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\n\" Functions\n\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\""
  },
  {
    "path": "plugin/tidal.vim",
    "chars": 12517,
    "preview": "if exists(\"g:loaded_tidal\") || &cp || v:version < 700\n  finish\nendif\nlet g:loaded_tidal = 1\nlet s:parent_path = fnamemod"
  },
  {
    "path": "syntax/tidal.vim",
    "chars": 7842,
    "preview": "\" syntax highlighting for tidal/haskell\n\"\n\" Very minor modifications from syntax file of\n\" https://github.com/neovimhask"
  }
]

About this extraction

This page contains the full source code of the tidalcycles/vim-tidal GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 16 files (49.1 KB), approximately 14.6k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!