Setting up Snd with Neovim


Published on 2023-07-21 by Kenneth Flak

Back to Tech Research


Table of Contents

The more I am learning about Snd, the more amazed I am. The learning curve is steep, though, so I was very happy when someone on the mailing list made me aware of this tutorial on CCRMA's website.

In order for me to be a happy sound hacker I needed to get snd working with my favorite text editor, neovim. This turned out to be much more complicated than I thought, but it has now become considerably simpler due to the heroic efforts of Russ Tokuyama in implementing a snd client for the excellent conjure plugin.

Installation

In order to get this to work, you first need to install snd on your computer. On Arch Linux this is as simple as:

sudo pacman -S snd

On other distros you need to check if snd exists in the repos, otherwise download the source code and follow the compilation instructions in the included README file.

The website claims snd will also run on macOS, but I haven't tested this myself.

You will also need to install conjure. Follow the instructions on the github page to do so.

Setup

In order to make conjure start snd whenever you launch a scheme file, you need to set the following variable somewhere in your init file (lua version):

vim.g['conjure#filetype#scheme'] = 'conjure.client.snd-s7.stdio'

or, if you are still using vimlang:

let g:conjure#filetype#scheme = "conjure.client.snd-s7.stdio"

My complete lazy.nvim configuration looks like this:


{
    'Olical/conjure',
    init = function()
        vim.g['conjure#filetype#scheme'] = 'conjure.client.snd-s7.stdio'
    end,
}

Code Completion

Coding is not much fun without completion. Luckily there is a way to generate the keywords on startup, including all your loaded files. For this we are going to use nvim-cmp and cmp-dictionary

Install these two as per instructions, and set cmp-dictionary as a source for nvim-cmp.

This is the relevant part of my nvim-cmp setup, also in lazy. Yours will look different if you use a different plugin manager.


{
    'hrsh7th/nvim-cmp',
    config = function()
        local cmp = require'cmp'
        cmp.setup {
            sources = {
                { name = 'dictionary' },
            },
            local dict = require("cmp_dictionary")
                dict.switcher({
                    filetype = {
                        scheme = "~/.local/share/snd/keywords.txt",
                    }
                })
        }
    end
    dependencies = {
        'uga-rosa/cmp-dictionary',
    }
}

Next step is to make sure that cmp-dictionary has an actual dictionary to load. I created the ~/.local/share/snd directory to hold this, but it could exist anywhere on your harddrive. Just make sure the dict.switcher key points to the correct one.

The final step of the process is to make sure snd generates the dictionary file on startup. Add this to the bottom of your ~/.snd_prefs_s7 file, after any (load foo.scm) directives:


(let ((p (open-output-file "/home/kf/.local/share/snd/keywords.txt")))
  (let f ((ls (vector->list (symbol-table))))
    (display ls)
    (if (not (null? ls))
      (begin
        (write (car ls) p)
        (newline p)
        (f (cdr ls)))))
  (close-output-port p))

Notice that the file referred to in the dict setup and the snd initialization needs to be the same. Also notice that the scheme code doesn't seem to expand ~ to your home directory, so you will have to give this an absolute file path.