Git Product home page Git Product logo

sublimeksp's Introduction

SublimeKSP

A Sublime Text 3/4 plugin for working with and compiling KSP (Kontakt Script Processor) code.

Changes

This fork is based on Nils Liberg's official SublimeKSP plugin, v1.11, and supports all Kontakt versions. However, there are a number of additions and changes:

  • Available in Package Control, which supports automatic updates
  • Updates to the syntax highlighting
  • Support for Creator Tools GUI Designer
  • Numerous additions to the preprocessor, allowing for UI arrays, new macro types and much more
  • See the Added Features section of the Wiki for more information

Installation

  • Install Package Control
  • After installing Package Control and restarting Sublime Text:
    • Open the Command Palette from the Tools menu, or by pressing CmdShiftP (macOS) or CtrlShiftP (Windows)
    • Type "Install Package"
    • Type "KSP" and select "KSP (Kontakt Script Processor)"
    • Press Enter to install
    • Restart Sublime Text

Manual Installation

To use features of SublimeKSP before official package releases:

  • If you already had SublimeKSP installed via Package Control, uninstall it before continuing further!
  • Locate Sublime Text's Packagesfolder by selecting Preferences > Browse Packages from the main menu
  • Clone SublimeKSP repository into this folder via Git (git clone https://github.com/nojanath/SublimeKSP.git "KSP (Kontakt Script Processor")
  • After pulling the latest changes (git pull), reload Sublime Text
  • If you wish to pull in latest changes without restarting Sublime Text, we recommend installing Automatic​Package​Reloader

Running From Command Line

SublimeKSP compiler can also be ran from command line, by simply executing ksp_compiler.py with the appropriate source (and optionally output) file path(s), along with optional compiler switches. For this, you need to use the manual installation of SublimeKSP, in order to have direct access to ksp_compiler.py file. To execute a compilation of a file, it is as simple as typing:

> python ksp_compiler.py "<source-file-path>"

However, various compiler options from SublimeKSP's Tools menu are also available. All of them are set to false if not used, and by including them in the command line, they are set to true:

ksp_compiler.py [-h] [-c] [-v] [-e] [-o] [-t] [-d] source_file [output_file]

positional arguments:
  source_file
  output_file

optional arguments:
  -h, --help                   show this help message and exit
  -f, --force                  force all specified compiler options, overriding any compile_with pragma directives from the script
  -c, --compact                remove indents and empty lines in compiled code
  -v, --compact_variables      shorten and obfuscate variable names in compiled code
  -d, --combine_callbacks      combines duplicate callbacks - but not functions or macros
  -e, --extra_syntax_checks    additional syntax checks during compilation
  -o, --optimize               optimize the compiled code
  -t, --add_compile_date       adds the date and time comment atop the compiled code
  -x, --sanitize_exit_command  adds a dummy no-op command before every exit function call


> python ksp_compiler.py --force -c -e -o "<source-file-path>" "<target-file-path>"

Updates

  • Updates to the plugin will be automatically installed via Package Control.
  • Pull requests are welcome for bugfixes/updates/changes. If you aren't familiar with pull requests, just open an issue here.

Documentation

See the Wiki on GitHub.

sublimeksp's People

Contributors

bineferg avatar eitherys avatar francescosabatini avatar gregjazz avatar jackwilliams-fracturesounds avatar magneto538 avatar mkruselj avatar nojanath avatar samwindell avatar teskdop avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sublimeksp's Issues

Bad compilation bug

Let's take some operations involving real and integers:

int_to_real(100) / 2.0
int_to_real(80) / 2.0
int_to_real(60) / 2.0
int_to_real(40) / 2.0
int_to_real(20) / 2.0
int_to_real(800) / 20.0

All these operations return a compilation error. It appears that any operation involving int_to_real(), when applied to constant values, is compiled in exponential notation. Let's take the first operation:

int_to_real(100) / 2.0

This operation should return 50.0, or, in exponential notation, 5.0e1.
SublimeKSP compiles this as 5e1, not 5.0e1, so the script won't apply. The compilation happens successfully, but the script won't be applied. I tried to manually add the missing ".0" and everything works just fine. This happens with any value that can be represented as ne1, where n is a number smaller than 10. This happens ONLY when using int_to_real, so 100.0 / 2.0 will work fine.

ui_xy not working

declare ui_xy ?myXY[4]

This does not work. A syntax error is returned. Are there any news about an official release for Kontakt 5.6.5?

Throw Error if START_INC occurs twice

Hey guys, we got hit by a nasty script malfunction working on a library today, and it took us a couple hours to debug it, under layers and layers of functions and branches and whatnot... it turns out in the very beginning, when we used START_INC(N, 0, 1) to fill some 2D tables, a slight misstep happened and someone forgot an END_INC for one of the rows. (START_INC -> END_INC blocks are used in rapid succession to fill rows of the tables)

It sent the entire indexing of the tables haywire, and made the rest of the script go bonkers. The lesson learned was that NEVER forget to close START_INC() with END_INC() before starting a new one again.

So my request is, as a nicety, is it possible you can make the compiler throw an error if START_INC() is not closed with END_INC() before another START_INC() is called? Probably check if it's the same replacement text too (so you can still do multiple different START_INC()'s with different text).

Suggestion: Add ability to move some auto-generate code to persistence callback

Consider the following extreme example:

on init
    declare read ui_button MyButtons[256]
    declare read ui_switch MySwitches[256]
    declare read ui_label MyLabels[256](1,1)
    declare read ui_menu MyMenus[256]
    declare read ui_slider MySliders[256](1,1)
end on

These seven lines when compiled will create the "parser stack overflow" error we've all come to love in Kontakt. However, if the assignments of the ui_ids to the arrays (1280 lines) were instead moved to the top of the on_persistence_changed callback the script would compile properly and run.

Granted, this is not always ideal or the expected behavior, so it would require a unique keyword or other symbol to create such a behavior. But I think it would be useful.

This above example is of course not practical or realistic, but it's a very easy limit to run into when UIs become complex and especially when dealing with a lot of persistence string variables that eat up lines of init code.

Anyway, just a thought.

no shortcut (declare pers ...) for make_instr_persistent

Hello, one cannot declare an array of variables or gui elements that are instrument persistent rather than also snapshot persistent (if snapshots are enabled in the script). I would suggest an extension like

declare instr_pers ...
declare instr_read ...

best,
Andreas

Simplified syntax and ui_xy

The simplified syntax ui_ctrl -> cursor_picture := "picture_name" doesn't work.

Actually, this syntax is missing a parameter in order to be used correctly, as CONTROL_PAR_CURSOR_PICTURE uses the new set_control_par_str_arr to work: this function needs to be fed with an additional parameter which is the index of the string array in question (page 120 on KSP manual).

The output of this should be
set_control_par_str_arr( get_ui_id(?ui_ctrl), $CONTROL_PAR_CURSOR_PICTURE, "picture_name", ???idx???)
while at the moment it is
set_control_par( get_ui_id(?ui_ctrl), $CONTROL_PAR_CURSOR_PICTURE, ...)

Syntax checking too restrict for set_engine_par

According to

http://vi-control.net/community/threads/additions-to-the-sublimeksp-compiler.53496/page-2#post-3966055

the plugin disallows assignment of a return value of set_engine_par. Normally that function does not return a value. But for ENGINE_PAR_EFFECT_SUBTYPE as in e.g.

filter_load_id := set_engine_par(ENGINE_PAR_EFFECT_SUBTYPE,FILTER_TYPE_SV_LP4,-1,2,NI_BUS_OFFSET+1)

it does and the plugin rejects this with

Expected expression of integer type, got None

Add syntactic sugar for binary numbers

This would be SO useful!

Something like 0100101011b would compile to 299 in base 10.

Should be pretty easy to add? Benefits are quite obvious, I would say :)

VERY bad bug with multi-dimensional arrays

It seems that we cannot set multi-dimensional arrays as persistent!

Whenever I try to set a multi-dim array as persistent using the syntax array[5, 7], the following error is returned:

Wrong number of parameters to array.get. Expected 2, got 0. (line xxx)
make_persistent(array)

This is a very bad bug, effectively limiting the usability of multi-dim arrays.

Macro library and text substitution feature request

Really appreciate your work on this, and adding it PackageControl, I found it just by chance. I've recently put together a macro and function KSP library, which I think could be useful to you if you do scripting work. It's main feature is the addition of UI arrays and the ability to execute a macro a given number of times, kind of like a for-loop. You can find it on my github: https://github.com/SamWindell/KSEL

I have an idea for a feature request for SublimeKSP. Apologies if this is better suited to send to Nils direct, just wondering what you thought about it.

A pre-compile text substitution would be really helpful. Kind of how the C preprocessor #define works. At the top of the document you could define some constants:

#define NUM 1
#define TEXT string

Then when you hit F5 all occurrences of NUM or TEXT will just be replaced by their value, after this has happened, then the compiler proceeds and builds macros, functions, etc.

Especially in the pseudo arrays that I have made in my macro library, this feature would be really useful.

Issue with async IDs and effect changes

The following code is currently not compiling using your latest version (but does work in KT):

on init
    declare ui_button $loadAChorus
    declare $LOAD_ID
end on

on ui_control($loadAChorus)
    $LOAD_ID := set_engine_par($ENGINE_PAR_EFFECT_TYPE, $EFFECT_TYPE_CHORUS, -1, 0, $NI_BUS_OFFSET)
end on

on async_complete
    if ($NI_ASYNC_ID = $LOAD_ID)
        message($NI_ASYNC_EXIT_STATUS)
    end if
end on

I believe the issue is the actual async assignment to the set_engine_par being rejected.

Thanks.

'->'-like shorthand for event pars

Hey guys!

I was just wondering. We have '->' which is a great way to get and set control pars. I was wondering, why not extend this functionality to event parameters? I understand using the same symbol for two different functionality translations could cause parsing issues and take a lot of effort to resolve, so I would suggest maybe an alternate symbol, like '~>' or
'-e>' or something. Not sure! Up to you guys.

So example

e := play_note(EVENT_NOTE, EVENT_VELOCITY, b, c)
e ~> 0 := some_data
e ~> 1 := some_other_data

//later, on release
if e ~> source = -1 //physical key release
    //do stuff
else
    if e ~> 0 = some_value
        ...
end if

Passing a string with commas as a macro argument confuses the parser

If you have a macro that accepts an argument that's used as a string and then pass a string containing a comma, the parser confuses the commas as separate arguments and complains about incorrect number of arguments.

Test case:

macro test(msg)
    message(msg)
end macro

test("this, breaks, the, parser")

Functions don't have this problem, and in fact can mask the macro issue through indirection:

macro _test(msg)
    message(msg)
end macro

function test(msg)
    _test(msg)
end function

test("this, works, fine")

Function declarations do not accept args with dots in them

function func(a.b)
    message(a.b)
end function

This will cause an error, while if you changed a.b to a_b it will work. This is really only a minor inconvenience at best. Fixing this will likely not be easy as it will involve diving into the workings of the parser.

SublimeKSP no longer pre-processing declare const???

Hi guys,

SublimeKSP is no longer processing declare const values as text literals. It's compiling and declaring the consts still in the base KSP. I have "Optimize Compiled Code" on.

This seems to be happening after I reinstalled SublimeKSP. Can someone look into this?

EDIT: I didn't have Extra Syntax Checks turned on.

activate_logger needs a slight change

Currently the file name is automatically called logger.nka. This should be changed so that the user can name the file themselves, for two reasons. Firstly, it will allow for better organising of log files. And secondly the activate_logger system currently conflicts with itself when you are using multiple scripts because they are sharing the same PGS variables. Giving each a unique name will allow the compiler to generate unique PGS variables.

Here is how it might look.
activate_logger("C:/Users/Sam/Desktop/Script1_LogFile.nka")

When there is no specific file name declared, the compiler will automatically generate are generic one in order to keep backwards compatibility.

Const symbols in 5.6.5

on init
    declare const ~PI := ~NI_MATH_PI
end on

This doesn't work. This problem is deeper down in the compiler and it's probably best to wait for Nils to release his next official version.

No fancy "read_persistent_var" in SublimeKSP

The new
"declare pers"

Is pretty dope! My only complaint while it does make_persistent, it does not do "read_persistent_var". Is there any plan to have a similar shorthand for reading, or no?

Especially for a ui control array, since it generates control names automatically, we'd be forced to use an iterate macro for reading persistent ui control values. It would be nice if we had an equal shorthand for reading like "read " or "read ". So that reading persistent values is not this big task of writing extraction macros for different sets of controls.

Missing get_key_type and load_array snippets

See above.

BTW...
Is someone still taking care of this fork of SublimeKSP? We haven't seen updates in a while now. Most of our work is based on this compiler, so it'd be amazing if you guys could tell us if this project is still on or not 😃

Multi-dim arrays

Hey folks,
After shedding some light on the pers thing for multi-dimensional arrays, I hope you will give me feedback this matter too.

on init
	declare foo[2, 5]
	load_array(foo, 1)
end on 

I'm getting this error:

Wrong number of parameters to foo.get. Expected 2, got 0. (line 16)
load_array(foo, 1)

:3

XOR operator

When I type .xor., SublimeKSP highlights it as if it was an actual operator, but Kontakt does not support it, thus the compilation fails.

Might be a good idea to add the operator to the compiler so that if I write .xor. it would be compiled as .and. .not. (which is exactly the same thing).

Real numeric constants aren't colored properly

Anything after the decimal point isn't syntax colored. To fix that, regexp for numerical constant needs to be updated from this:

match: '(\s+-|(?<=[=,])-)?((0x)[0-9a-fA-F]*|[0-9][0-9a-fA-F]*[hH]|[0-9]+)\b'

to this:

match: '(\s+-|(?<=[=,])-)?((0x)[0-9a-fA-F]*|[0-9][0-9a-fA-F]*[hH]|[0-9.]+)\b'

list compilation

As of now, typing

list array_name
    array_entry_1
    array_entry_2
    array_entry_3
end list

is being compiled as

declare %array_name[3]
%array_name[0] := array_entry_1
%array_name[1] := array_entry_2
%array_name[2] := array_entry_3

In order to save lines of code and reduce overhead, it would be better to compile the array inline. So the result of compilation would be

declare %array_name[3] := (array_entry_1, array_entry_2, array_entry_3)

This works only with numeric variables and constants. Text arrays need to be unrolled on separate lines.

Single line macro argument

This is purely a quality of life syntactic sugar feature, but it would be really nice and elegant to use.

Right now we have single line macros like:

define DEFINES.IS_FX_DESTINATION := #in_range(i, 14, 56)#

for i := 0 to 60
    if DEFINES.IS_FX_DESTINATION
        blah blah
    end if
end for

but as you can see, the maintainability issue here is creating the condition with an assumed variable baked in. Makes it hard to re-use without careful thought.

Would be awesome if I could do something like:

define DEFINES.IS_FX_DESTINATION(*input*) := #in_range(*input*, 14, 56)#

for i := 0 to 60
    if DEFINES.IS_FX_DESTINATION(i)
        blah blah
    end if
end for

Like I said, super quality of life heavy, low priority. It's not something I need, just giving ideas for ways to improve SublimeKSP, something that I've thought about when coding.

Remove Behavior For Restricting Autocomplete

Right now the compiler has separate auto-completion behaviors for functions based on if they're being assigned as return values or if they're on a line of their own. This doesn't make any sense and extends beyond the scope of what an autocomplete feature intends to do.

How to use activate_logger on Mac?

Trying to test your debugging function... the compiler won't accept Mac OS directory, like

activate_logger("/Users/me/Desktop/Log File.nka")

Is there a syntactic workaround? If I edit the appropriate line in the compiled code to Mac OS format it does work.

KEY_COLOR_FUCHSIA not defined

Hey guys!

We're doing some keyswitch coloring, but KEY_COLOR_FUCHSIA (added in 5.5) is popping up errors in the compiler.

mf_set_export_area error

In ksp_builtins_data.py:
mf_set_export_area(,,,,):integer

a) message(mf_set_export_area("name",-1,-1,-1,-1))
compiles without error
b) area_status := mf_set_export_area("name",-1,-1,-1,-1)
compilation aborts with error message "Expected expression of integer type, got None.
c) in case of an error (b) the reported error line is sometimes wrong (pointing to the prev. line).

[FEATURE REQUEST] Implement "Literal" Iteration For Macros

This has been something I wanted to do for a long time, and now that this is public and open source, I should write it down! If no one can get to this, I may do it myself.

Basically I have a macro, like:

macro doSomething(#prefix#)
    code on #prefix#_CONTROL
end macro

Now, Sublime only allows literals in there, because it's text replacement. What I want do is something like this:

define literals fx_literals := (CHORUS, EQ, COMPRESSOR, REVERB, DELAY, LOFI, TRANSIENT)
literate_macro(doSomething) on fx_literals

which compiles to

code on CHORUS_CONTROL
code on EQ_CONTROL
code on COMPRESSOR_CONTROL
etc.

I imagine this isn't terribly difficult, just parse the literal lists into python and keep them in memory during compilation process. When the "literate_macro()" command is invoked, simply expand the macros iteratively using the elements of the specified literals list as an argument to each one.

define literals deprecated? Question on new usage

I'm not quite certain how the new define functionality handles the old define literals usage case.

Before we had define literals such that I could write:

define literals names := (Bobby, Sam, Ashley)

macro doStuffOnPerson(#name#)
    message(#name#Slider)
end macro

literate_macro(doStuffOnPerson) on names

//compiles to

message(BobbySlider)
message(SamSlider)
message(AshleySlider)

How can I use the new define statement in this same way? It doesn't appear to document how, it simply says the old way (written above) is now deprecated. I would like to know because define literals is powering an important subcomponent of Super Audio Cart and I'd like to port it out of using deprecated features.

Syntax highlighting bug

Great work with the new syntax highlighting file. This is clearly a much nicer system.

However, for me any regex matches in the sublime-syntax file that spanned multiple lines were not read properly. As a quick fix I have made them all single lines. This seems to have done the trick for me.

Transfer/Grant Access Rights for Repository?

Hey,

I'm thinking since this isn't seeing any activity, for the future of this plugin it would be good to have someone who's still active in Kontakt development to have access to pushing out updates via this repository to package control. It's not just about feature additions, but also keeping up with new KSP syntax including new engine par constants. The latter is a baseline requirement, and we can not develop for new Kontakt versions if the SublimeKSP plugin fails compilation on undefined builtin constants.

I would like to volunteer myself, since I have a working knowledge of how to manage git version control and branching, 2 years of extensive experience in advanced KSP (I'm the Software Architect at Impact Soundworks) as well as an advanced understanding of python, and ideas for many cool features to improve the SublimeKSP experience. I studied computer science courses in school and having a working knowledge of the concepts in abstract models and expression parsing. I'm also in close contact with EvilDragon, who has provided already many helpful modifications to continue keeping the plugin up to date, and also has ideas for things he'd like to see in the plugin.

New Comment Style Parsing Corrupts KSP String Literals With URLS

Hey Sam,

set_control_par_str($INST_LIB_DESCRIPTION_ID, $CONTROL_PAR_TEXTLINE, "http://ocremix.org/")

This line gives me trouble compiling. The compilation seems to get hung up on the string "http:"
image

Additionally the compilation of this script started hanging on "post-processing (15%)" at the bottom and the entire application froze up for a few seconds.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.