scvim icon indicating copy to clipboard operation
scvim copied to clipboard

SCVim: Use vim native help system

Open madskjeldgaard opened this issue 7 years ago • 22 comments

So this one's been with me a while. The help browser in SCVim works pretty great but there's a few bugs at least on MacOS that are kind of crippling:

  1. It is not possible to copy-paste from the help browser window to anywhere ( I have no idea why at the moment)
  2. The search is case sensitive as opposed to the one on http://doc.sccode.org/ and in the IDE
  3. Internal links don't work in the help browser

I'm running SC 3.9.1 on High Sierra 10.13.4 but these bugs have been with me for a long time now.

Thanks a lot !

madskjeldgaard avatar May 05 '18 19:05 madskjeldgaard

It would be amazing if you could some how integrate the help browser into VIM natively and copy-paste from within there. I think I'll try and explore that possibility

madskjeldgaard avatar May 06 '18 09:05 madskjeldgaard

@datamads I would also be interested in resurrecting the vim help system as an alternative to the HelpBrowser. Pre-IDE days it was the way it was done in scvim, and maybe sc-el still uses the help system from within emacs?. Actually, I'm not sure how that was done for scvim in the first place. Might check the log to see where this changed.

Maybe one can think of a converter script which converts html (or .schelp) files to .scd. Here is a test[0] using pandoc SinOsc.html -t plain -o SinOsc.txt, it feels like it should be possible to come up with some kind of filter (regex) to get rid of the empty tags. Or, writing a new converter from scratch using the SCDoc format might prove to be even easier/faster.

[0]:

SinOsc:

Filter:

Description

Other sinewaves oscillators

Class methods

-   ar kr
-   Inherited class methods

Instance methods

-   Inherited instance methods

Examples

Classes | UGens > Generators > Deterministic



SINOSC : PUREUGEN : UGEN : ABSTRACTFUNCTION : OBJECT


Interpolating sine wavetable oscillator.

Source: Osc.sc

See also: Osc, FSinOsc, SinOscFB, PMOsc, Klang


Description

Generates a sine wave. Uses a wavetable lookup oscillator with linear
interpolation. Frequency and phase modulation are provided for
audio-rate modulation. Technically, SinOsc uses the same implementation
as Osc except that its table is fixed to be a sine wave made of 8192
samples.

Other sinewaves oscillators

-   FSinOsc – fast sinewave oscillator
-   SinOscFB – sinewave with phase feedback
-   PMOsc – phase modulation sine oscillator
-   Klang – bank of sinewave oscillators
-   DynKlang – modulable bank of sinewave oscillators


Class Methods

SinOsc.ar(freq: 440, phase: 0, mul: 1, add: 0)

SinOsc.kr(freq: 440, phase: 0, mul: 1, add: 0)

Arguments:

+-----------------------------------+-----------------------------------+
| freq                              | Frequency in Hertz. Sampled at    |
|                                   | audio-rate.                       |
+-----------------------------------+-----------------------------------+
| phase                             | Phase in radians. Sampled at      |
|                                   | audio-rate.                       |
|                                   |                                   |
|                                   | NOTE: phase values should be      |
|                                   | within the range +-8pi. If your   |
|                                   | phase values are larger then      |
|                                   | simply use .mod(2pi) to wrap      |
|                                   | them.                             |
+-----------------------------------+-----------------------------------+
| mul                               | Output will be multiplied by this |
|                                   | value.                            |
+-----------------------------------+-----------------------------------+
| add                               | This value will be added to the   |
|                                   | output.                           |
+-----------------------------------+-----------------------------------+

Inherited class methods


Instance Methods

Inherited instance methods


Examples

    // create an audio-rate sine wave at 200 Hz,
    // starting with phase 0 and an amplitude of 0.5
    { SinOsc.ar(200, 0, 0.5) }.play;

    // modulate the frequency with an exponential ramp
    { SinOsc.ar(XLine.kr(2000, 200), 0, 0.5) }.play;

    // more complex frequency modulation
    { SinOsc.ar(SinOsc.ar(XLine.kr(1, 1000, 9), 0, 200, 800), 0, 0.25) }.play;

    // phase modulation (see also PMOsc)
    { SinOsc.ar(800, SinOsc.ar(XLine.kr(1, 1000, 9), 0, 2pi), 0.25) }.play;

helpfile source:
/Applications/SuperCollider.app/Contents/Resources/HelpSource/Classes/SinOsc.schelp
link::Classes/SinOsc::

davidgranstrom avatar May 09 '18 12:05 davidgranstrom

Oh man that looks amazing!! I toyed with the idea of writing a .schelp to vim-help file-txt file converter last night in Python.

This is a very rough sketch and very particular to how I like things but still this could generally be one way of doing it. This one just converts one file for the moment. Bear in mind I rarely write python code.

# Rough idea for a .schelp to vim help file converter
#
# Use this script on the command line like so: python help_file_converter.py [SomeHelpFile.schelp]
#

import time
import datetime

import sys

# Find in a line the two colons used after tags in the schelp files
# And return the line after those colons
def afterColons(line):
    indexofcolons = line.find("::")
    indexofcolons += 3
    return line[indexofcolons:]

# Strip the schelp tags from a string and replace them with vim help file
# formatting
def cleanSCHelpString(instring):
    # Argument is a help file (as a) string

    newstring = ""

    docTitle=""

    for line in instring.split("\n"):
        # Go through specific lines in the sc doc file tag system
        # And do some kind of formatting with each of them
        if "TITLE::" in line or "title::" in line:
            docTitle = afterColons(line)
            newstring += "---------------------------------\n"
            newstring += "*" + afterColons(line) + "*" + "\n\n"

        elif "METHOD::" in line or "method::" in line:
            newstring += ".*" + afterColons(line) + "*" + "\n"

        elif "DESCRIPTION::" in line or "description::" in line:
            newstring += "Description:" + afterColons(line)  + "~\n"

        elif "CLASSMETHODS::" in line or "classmethods::" in line:
            newstring += "Class methods:" + afterColons(line)  + "~"

        elif "INSTANCEMETHODS::" in line or "instancemethods::" in line:
            newstring += "Class methods:" + afterColons(line)  + "~"

        elif "code::" in line:
            newstring += "// CODE EXAMPLES: " + docTitle + "\n\n"

        elif "returns::" in line:
            newstring += "\treturn: \n\t\t|" + afterColons(line)  + "|\n"

        elif "ARGUMENT::" in line or "argument::" in line:
            newstring +=  "\targ: \n\t\t"

        # All other tags get rinsed for their double colons
        elif "::" in line:
            newstring += afterColons(line) + "\n"

        else: newstring += line + "\n"

    return newstring

# MAIN
def main():
    
    # Setup header + footer text for the new vim help file
    changedate = datetime.datetime.now().strftime("%Y %B %d") 
    headertext = "scdoc.txt" + "\tFor Vim version 7.3" + "\tLast change: " + changedate + "\n \n \n"  
    footertext = "vim:tw=78:ts=4:ft=help:norl:"

    # Load a help file
    inputfile = sys.argv[1] 
    print("Converting {}".format(inputfile))

    with open(inputfile, "r") as schelpfile:
        inputHelpfileString = schelpfile.read()

    # Clean the string from the .schelp file and wrap it in header + footer text
    clean = headertext + cleanSCHelpString(inputHelpfileString) + footertext
    
    # Strip the suffix from the original help file and use the filename for the
    # new file
    outfilename = inputfile[:inputfile.find(".")] + ".txt"

    outfile = open(outfilename, "w")
    outfile.write(clean)
    outfile.close

    print("Done converting schelp files")

if __name__ == '__main__':
    main()

madskjeldgaard avatar May 09 '18 13:05 madskjeldgaard

This adds the help file formatting for plugins in Vim (see :help help-writing inside of vim) instead of the scdocs tags etc. Change the string in the input file variable to some .schelp file you have on hand

madskjeldgaard avatar May 09 '18 13:05 madskjeldgaard

The problem with using a python script like above is it needs paths to all help files somehow. Not sure if that's possible. But the advantage is the resulting vim help files work nicely inside of vim.

An alternative approach maybe would be to use the SCDoc class in conjunction with vim buffers some how? http://doc.sccode.org/Classes/SCDoc.html

madskjeldgaard avatar May 09 '18 13:05 madskjeldgaard

One way of doing the pandoc thing using strictly vimscript and supercollider could be this. Add it to your .vimrc to test it out. Hmm, but it'll add a dependency for pandoc, and open it in another pane in tmux / a new window. This is only unix for now.

" ALTERNATIVE WAY OF GETTING SC HELP
" Mapped to F10 for now

function! SChelp2(subject)
    let l:cmdpart1 = 'var helpDocForCurrentWord = SCDoc.findHelpFile("' .  a:subject .  '");'
    let l:cmdpart2 = 'var htmlfile  = helpDocForCurrentWord.replace("file://", "").absolutePath.quote;
                \"pandoc % -t plain %".format(htmlfile).unixCmd;'

    let l:cmd = l:cmdpart1 . l:cmdpart2 

    call SendToSCSilent(l:cmd) 
endfun

au Filetype supercollider nnoremap <buffer><F10> :call SChelp2(expand('<cword>'))<CR>

madskjeldgaard avatar May 10 '18 16:05 madskjeldgaard

Here's another idea: Open the help file in Firefox (or some other browser?) instead of the half broken file browser

function! SChelp3(subject)
    let l:cmdpart1 = 'var helpDocForCurrentWord = SCDoc.findHelpFile("' .  a:subject .  '");'
    let l:cmdpart2 = '"open -a Firefox %".format(helpDocForCurrentWord.quote).unixCmd;'

    let l:cmd = l:cmdpart1 . l:cmdpart2 

    call SendToSCSilent(l:cmd) 
endfun

au Filetype supercollider nnoremap <buffer><F10> :call SChelp3(expand('<cword>'))<CR>

madskjeldgaard avatar May 10 '18 19:05 madskjeldgaard

Very cool ideas! The last one could also be achieved by using scdoc.org online help system, bypassing the interpreter. :silent execute '!open http://doc.sccode.org/Classes/' . expand('<cword>') . '.html'

Another approach I'm thinking about would be to write a new SCDocRenderer, there is now SCDocHTMLRenderer but maybe it would not be to hard to write a SCDocVimRenderer reusing the much of the same structure but to render vim help file output instead?

davidgranstrom avatar May 10 '18 20:05 davidgranstrom

I'd love to see a native .schelp in-vim solution, instead of an external software dependency (and without compiling to a different format). This could in theory be done with a filetype exte sion for .schelp, not sure how feature complete such a solution would be. One of the problems with the current system is that the singleton HelpBrowser is destroyed on Class recompile. This gets very annoying when writing classes.

dvzrv avatar May 10 '18 20:05 dvzrv

I started working on a SCDocVimRenderer. It is still a long way to go, but I managed to render the help as .txt files and remove some of the HTML markup. Still not sure if using an external script would be a faster way to go about this.. But it would be really nice to reuse the logic from the HTML renderer so that one could convert the links to vim-style help system links for instance.

davidgranstrom avatar May 10 '18 22:05 davidgranstrom

Hi,

Curious to find out what the status is on this! I have been having major problems with my help browser on Linux lately, and I am trying to get away from html... I used @davidgranstrom's excellent idea to pandoc all the help files, stripped the suffix from the resulting files and added the directory to vim's path. This now allows me to gf on any class and have vim open up the help file in a separate buffer. Pretty f***ing far from ideal, but it's something....

kflak avatar Dec 11 '18 09:12 kflak

For me on MacOS the new version (3.10) of SC has helped immensely, now the default help browser window almost works fine!

I also did a backup solution of stripping all help files and converting them to vimhelp-files to have them open inside of Vim. Might share that progress

madskjeldgaard avatar Dec 11 '18 11:12 madskjeldgaard

OK, reading through the thread once more, to assimilate all the great ideas ;-) So far, what works best for me is to use my browser to read the help files, while I'm waiting for vim-native help to become available. On linux/qutebrowser, this now looks like this:

    function! SChelp3(subject)
        let l:cmdpart1 = 'var helpDocForCurrentWord = SCDoc.findHelpFile("' .  a:subject .  '");'
        let l:cmdpart2 = '"qutebrowser %".format(helpDocForCurrentWord.quote).unixCmd;'
        let l:cmd = l:cmdpart1 . l:cmdpart2 
        call SendToSCSilent(l:cmd) 
    endfun
    au Filetype supercollider nnoremap <buffer><F10> :call SChelp3(expand('<cword>'))<CR>

Almost the same as @madskjeldgaard's solution, but on Linux. Thanks a lot! This has been bugging me for a while :-)

kflak avatar Dec 11 '18 13:12 kflak

The help browser isn't really part of scvim but of sclang, and it's nice to hear things have improved with the new SC.

I'll keep this around as a go-to issue for implementing a vim based help system- especially since this is reported to have worked on the older scvim, @davidgranstrom, this could possibly be considered a regression.

I suspect the answer is to be found way back in old history, after all, this is based on the original work by Alex Norman.

capocasa avatar Nov 07 '19 22:11 capocasa

Hi @capocasa, since my last comment @davidgranstrom has made a native help system work in his scnvim plugin. This now works perfectly for my needs.

kflak avatar Nov 08 '19 06:11 kflak

[OT] It would be great to have https://github.com/davidgranstrom/scnvim be part of official https://github.com/supercollider :space_invader:

gusano avatar Nov 08 '19 08:11 gusano

i agree, i have been meaning to contact david and see if they are interested in that.

mossheim avatar Nov 08 '19 14:11 mossheim

Yes it should definitely be official. I have used it on a daily basis since the beginning and it is top notch

Get Outlook for Android

On Fri, Nov 8, 2019 at 3:18 PM +0100, "Brian Heim" [email protected] wrote:

i agree, i have been meaning to contact david and see if they are interested in that.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

madskjeldgaard avatar Nov 08 '19 14:11 madskjeldgaard

Amen to that! I can't imagine my life without this tool.

kflak avatar Nov 08 '19 14:11 kflak

i will talk to them about it (unless someone else does first)

mossheim avatar Nov 08 '19 14:11 mossheim

So scnvim's pandoc based help browser looks like it's reasonably portable to scvim. Any volunteers?

I'm a neovim user myself, but I usually tend to have a more minimalist environment than scnvim offers (but the features that are there are very very cool indeed). So I think it would make sense to selectively port some features to scvim.

capocasa avatar Nov 18 '19 14:11 capocasa

@davidgranstrom

@datamads I would also be interested in resurrecting the vim help system as an alternative to the HelpBrowser. Pre-IDE days it was the way it was done in scvim, and maybe sc-el still uses the help system from within emacs?. Actually, I'm not sure how that was done for scvim in the first place. Might check the log to see where this changed.

I had a batch process that converted all the old rtf and, then html, help docs to plain text format (scd) and also created a tags file so they could be found with vim's help system. It was pretty simple but worked pretty well I thought.

x37v avatar Mar 15 '20 16:03 x37v