PDA

View Full Version : Autocomplete code in Maxscript editor POSSIBLE!!!


OZRay
06-06-2009, 03:03 PM
Yes your not dreaming! Ok some of you will tell me that this is not a real autocomplete but guys this is sooo nice that every scripters will use this... ;)

I have been inspired by a older post from Johan Boekhoven a.k.a JHN about a very powerfull feature that is unknown by many scripters. The abbreviation file in the MaxScript Editor..

What is this, go look here: http://forums.cgsociety.org/showthread.php?f=98&t=715312

After playing around with the abbreviation data I digged a bit more into the Editor.
Ok what about Complete Word in the Edit menu.... If you go read in the help file about it
you will see that this is to help retyping words that have been already written elsewhere in your script so for custom variable that is a nice help. But what about listing ALL the 3DSMAX functions/control name/argument/etc etc in a kind of header.?? Does it will slow down that feature to hell? OMG!!! SOO fast! You start typing a maxscript function then CTRL+ENTER and it instantly giving you a list of funtion starting with those letters! YES!

This is my suggested setup.
- Download my file and go put it in the abbreviation file (TOOLS - Open abbreviation file)
http://www.urbanimmersive.com/upload/autocomplete.zip
This file have been taken from the UltraEdit syntax hilight file and remanipulated to
fit the abbreviation file. This is not fully complet but that's a starting point.
- When starting a new script just wrote: autocomplete then CTRL+SHIFT+A and now you
have a custom header with all the possible functions.
- Now in that script every time you don't remember the syntax of a function you start typing then CTRL+ENTER Boom!

So try this out and let me know how much time your saving now! ;)

To easily maintaining the autocomplete file up to date I'm suggesting everyone that,
if you found something not in the autocomplete file just send me a email and I will update
the attached file for everyone. So that list will sometime be complete!

Regards!

OZRay

ZeBoxx2
06-06-2009, 07:45 PM
The funny thing is, the editor on which the new maxscript editor is based (scite) does, in fact, not only support autocomplete, but even the... the term has escaped me, it seems.. context-sensitive completion with the little popup of options you get in e.g. visual studio, Office scripting, etc. for a given command/method. Hopefully that will get added to Max eventually*, but this is pretty sweet right now :) Thanks!

* I suppose there's no reason it couldn't be added to this abbrevations file.. other than it being a *lot* of work indeed :)
Edit: Correction.. looks like it hates periods (probably because that's where that popup would normally get invoked. d'oh.
Edit 3: Err... and remove any strings with an underscore in them as well, it seems. That's silly - there's lots of items in MaxScript with underscores. hmpf.

Edit 2: Looks like there's one item in the list that has a typo, at least; exitrude

One way you could get a list of all the strings* would be using `apropos "*"`, then filter out the interface items and items with underscores, remove everything after a space / period, then remove duplicates, then remove the items starting with a % sign and items starting with a number or mathematical operator, and you should be all done.
* but whether that is wise or not is another thing altogether.. it's nearly 5,000 terms in 3ds Max 2009x32.

thatoneguy
06-06-2009, 10:04 PM
I would like to make a suggestion.

We open a wiki.

If we all start using the same autocomplete list then we'll run across missing terms and collectively build it up to completion.

Soooo... who knows how to setup a wiki? :)

ZeBoxx2
06-06-2009, 10:19 PM
well, the number of missing terms is staggering... I figure there's two ways you could approach this (and not via a wiki.. though tech artists already has a wiki-esque area, no?)..
1. include -all- the terms.. in which case, see my suggestion above of just dumping everything out, filter the bits that are bogus or just won't work. This works fine, doesn't slow things down much, but the header gets to be a good chunk of data (perhaps stick it at the bottom of the script instead so it's not in your face every time you open the file).

2. include only the most frequently used ones; which would be a combination of the above (to get valid terms), and parsing existing scripts (from your own collection), ranking the various key words by frequency encountered in the scripts.

OZRay
06-07-2009, 01:17 AM
Good suggestions.
Maybe I will extract everything as suggested and I will split the functions by kind of groups..
Ex.: uicontrols, animation, filemanipulation, etc etc... This way you just add the one you will need or those frequently used and let the other one on the side for exception.

I will sleep on that and find a good solution. :)

martroyx
06-07-2009, 09:58 AM
if it's already included with the scite editor then maybe Autodesk could try to make it work in a more convenient way?

also I don't know what the buzz but sometime the letter are disappearing at random in my editor on all the open script at the same time after a second they reappear and another set disappear at random then suddenly it stop doing that and come back to normal... it very weird or maybe I screw up something with my test, I don't know :-)

ZeBoxx2
06-07-2009, 04:38 PM
if it's already included with the scite editor then maybe Autodesk could try to make it work in a more convenient way?
Sure.. maybe for 3ds Max 2011, or 2012, or the things-that-follow :)

also I don't know what the buzz but sometime the letter are disappearing at random in my editor on all the open script at the same time after a second they reappear and another set disappear at random then suddenly it stop doing that and come back to normal... it very weird or maybe I screw up something with my test, I don't know :-)
No idea.. are you using a custom font?

========================================

Back to the words list... building a dictionary file is slooooooooooooooow with maxscript. I only ran it on my 3ds Max 2009 folder as there's tons more in my repository, but apparently my top 10 in that 2009 folder is...

1 (561) true
2 (412) append
3 (347) false
4 (293) undefined
5 (236) text
6 (218) value
7 (213) selection
8 (198) format
9 (173) name
10 (172) cbLogger

Number 10 is pretty biased - that script simply references itself a *lot* :) Might have to weight things by whether or not they're in the same script file or in different script files. Moreover, though, they're not very useful dictionary items :> So I'm abandoning that line of thought :)

martroyx
06-08-2009, 01:01 AM
Hi Richard,

no , I'm using default font but I modified the color anyways it don't happen very often so I can live with it but it's very scary when it happen:-)

Do you think you could class the list by alphabetical order, classed by word type like in the maxeditor ... as I need this to build a custom lexer for the scintilla.net wrapper ???

regard,
Martin

ZeBoxx2
06-08-2009, 01:05 AM
you could probably just do something like 'superClassOf (execute <term>)' to get the superClass of that term and categorize them accordingly.

martroyx
06-08-2009, 03:44 AM
yes I have an old list from gathered this way for max8 I think so it's not really up to date.
one nice function that auto-gather all the maxscript keyword and class them as you like would be very usefull does anyone have already made one ?

martroyx
06-08-2009, 06:39 AM
so I made a little one , couldn't resit :banghead:
I still need to remove the . from the word and class everything into separate array
do I gather all the keyword this way ???


(
fn GatherMaxscriptKeyword =
(
out_script=newscript()
n_stream=stringstream ""
--//--
afilter_1=#()
--//--
apropos "" to:n_stream
seek n_stream 0
--//--
while not eof n_stream do
(
mtrim=(dotnetobject "system.string" (readLine n_stream)).Split "("
--//--
if mtrim.count > 1 then
(
xtype=(dotnetobject "system.string" mtrim[2]).split ")"
--//--
if xtype.count > 1 then
(--redirect to the wanted array there ...
appendvalstr=((dotnetobject "system.string" mtrim[1]).Split " ")[1]
--//--
case xtype[1] of
(
"const Primitive":(appendifunique afilter_1 appendvalstr)
"const Class":(appendifunique afilter_1 appendvalstr)
"const MAXClass":(appendifunique afilter_1 appendvalstr)
"const MAXSuperClass":(appendifunique afilter_1 appendvalstr)
"const EmptyClass":(appendifunique afilter_1 appendvalstr)
"const Generic":(appendifunique afilter_1 appendvalstr)
"UndefinedClass":(appendifunique afilter_1 appendvalstr)
"const Primitive":(appendifunique afilter_1 appendvalstr)
"const Interface":(appendifunique afilter_1 appendvalstr)
"const NodeGeneric":(appendifunique afilter_1 appendvalstr)
"const SelectionSetArray":(appendifunique afilter_1 appendvalstr)
"MAXScriptFunction":(appendifunique afilter_1 appendvalstr)
"const MeditMaterialsClass":(appendifunique afilter_1 appendvalstr)
"StructDef":(appendifunique afilter_1 appendvalstr)
"Integer":(appendifunique afilter_1 appendvalstr)
"const StructDef":(appendifunique afilter_1 appendvalstr)
"Primitive":(appendifunique afilter_1 appendvalstr)
"const Point3":(appendifunique afilter_1 appendvalstr)
"const OkClass":(appendifunique afilter_1 appendvalstr)
"Array":(appendifunique afilter_1 appendvalstr)
"Point2":(appendifunique afilter_1 appendvalstr)
"MSPluginClass":(appendifunique afilter_1 appendvalstr)
"const MAXMeshClass":(appendifunique afilter_1 appendvalstr)
"StandardMaterialClass":(appendifunique afilter_1 appendvalstr)
"<internal>":(appendifunique afilter_1 appendvalstr)
"system UndefinedClass":(appendifunique afilter_1 appendvalstr)
"const BooleanClass":(appendifunique afilter_1 appendvalstr)
"RCMenu":(appendifunique afilter_1 appendvalstr)
"String":(appendifunique afilter_1 appendvalstr)
"BooleanClass":(appendifunique afilter_1 appendvalstr)
"RolloutClass":(appendifunique afilter_1 appendvalstr)
"const ObjectSet":(appendifunique afilter_1 appendvalstr)
"const Color":(appendifunique afilter_1 appendvalstr)
"const MappedGeneric":(appendifunique afilter_1 appendvalstr)
"system Name":(appendifunique afilter_1 appendvalstr)
"const MAXScriptFunction":(appendifunique afilter_1 appendvalstr)
"system Interval":(appendifunique afilter_1 appendvalstr)
"system Time":(appendifunique afilter_1 appendvalstr)
"system Integer":(appendifunique afilter_1 appendvalstr)
"const HKey":(appendifunique afilter_1 appendvalstr)
"system Float":(appendifunique afilter_1 appendvalstr)
"system String":(appendifunique afilter_1 appendvalstr)
"system BooleanClass":(appendifunique afilter_1 appendvalstr)
"system MaterialLibrary":(appendifunique afilter_1 appendvalstr)
"const BipedGeneric":(appendifunique afilter_1 appendvalstr)
"dotNetObject":(appendifunique afilter_1 appendvalstr)
"system WindowStream":(appendifunique afilter_1 appendvalstr)
"system Color":(appendifunique afilter_1 appendvalstr)
"system Array":(appendifunique afilter_1 appendvalstr)
"system Control":(appendifunique afilter_1 appendvalstr)
"system MAXTVNode":(appendifunique afilter_1 appendvalstr)
"const CurveCtlGeneric":(appendifunique afilter_1 appendvalstr)
"system MAXRootNode":(appendifunique afilter_1 appendvalstr)
"system Integer64":(appendifunique afilter_1 appendvalstr)
"const MappedPrimitive":(appendifunique afilter_1 appendvalstr)
"const CurveCtlGeneric":(appendifunique afilter_1 appendvalstr)
"Float":(appendifunique afilter_1 appendvalstr)
"TextureClass":(appendifunique afilter_1 appendvalstr)
"MSCustAttribDef":(appendifunique afilter_1 appendvalstr)
"persistent UndefinedClass":(appendifunique afilter_1 appendvalstr)
"const Float":(appendifunique afilter_1 appendvalstr)
"const UndefinedClass":(appendifunique afilter_1 appendvalstr)
"const UnsuppliedClass":(appendifunique afilter_1 appendvalstr)
default:(messagebox "New Class found, Please update the main function." title:"Warning" beep:false)
--default:(format(xtype[1]+"\n")to:out_script)
)

)

)

)
--//--
sort afilter_1
--//--
for f in afilter_1 do
(
evalstr=(dotnetobject "system.string" f).Split ("\""+"&"+"%")
--//--
if evalstr.count == 1 then
(
format (evalstr[1]+"\n") to:out_script
)
--//--
)
--//--
)
--//--
GatherMaxscriptKeyword()
ok
)

ZeBoxx2
06-08-2009, 11:55 AM
keep in mind that apropos would only list classes.. you'd probably miss, at least, for/when/if/then/else/etc. language constructs.

That's a lot of 'case of's for something that seems to be fed to the same array :o

JHN
06-08-2009, 02:43 PM
I'm using this list for some time now:
http://scripts.subd.nl/?f=maxscript.api
It's also extracted from a file Chris Johnson posted somewhere, I think on scriptspot. I think it's a bit more then what was posted here already. And the maxscript editor also has some more options for the autocomplete context sensitive stuff. I will try to post about it soon and the use of a .api file instead of the "abbreviation trick" which is the proper way to do it. Well in fact the autocompleet should reflect the same keywords there are exposed for the color coding, but for some strange reason just aren't.

-Johan

ZeBoxx2
06-08-2009, 05:43 PM
looking forward to the info, JHN :)

martroyx
06-08-2009, 08:04 PM
this one will filter by color type which is what I wanted :-)


(
fn GatherMaxscriptKeyword =
(
out_script=newscript()
n_stream=stringstream ""
--//--
afilter_black=#()
afilter_blue1=#()
afilter_blue2=#()
afilter_Brown=#()
afilter_Green=#()
afilter_Gold=#()
afilter_Red=#()
afilter_Italic=#()
--//--
apropos "" to:n_stream
seek n_stream 0
--//--
while not eof n_stream do
(
mtrim=(dotnetobject "system.string" (readLine n_stream)).Split "("
--//--
if mtrim.count > 1 then
(
xtype=(dotnetobject "system.string" mtrim[2]).split ")"
--//--
if xtype.count > 1 then
(--redirect to the wanted array there ...
appendvalstr=((dotnetobject "system.string" mtrim[1]).Split " ")[1]
--//--
case xtype[1] of
(
"<internal>":(appendifunique afilter_black appendvalstr)
"Array":(appendifunique afilter_black appendvalstr)
"BooleanClass":(appendifunique afilter_black appendvalstr)
"Float":(appendifunique afilter_black appendvalstr)
"Integer":(appendifunique afilter_black appendvalstr)
"MAXScriptFunction":(appendifunique afilter_black appendvalstr)
"MSCustAttribDef":(appendifunique afilter_black appendvalstr)
"MSPluginClass":(appendifunique afilter_black appendvalstr)
"Point2":(appendifunique afilter_black appendvalstr)
"Primitive":(appendifunique afilter_blue1 appendvalstr)
"RCMenu":(appendifunique afilter_black appendvalstr)
"RolloutClass":(appendifunique afilter_black appendvalstr)
"StandardMaterialClass":(appendifunique afilter_black appendvalstr)
"String":(appendifunique afilter_black appendvalstr)
"StructDef":(appendifunique afilter_Brown appendvalstr)
"TextureClass":(appendifunique afilter_black appendvalstr)
"UndefinedClass":(appendifunique afilter_black appendvalstr)
"const BipedGeneric":(appendifunique afilter_blue1 appendvalstr)
"const BooleanClass":(appendifunique afilter_Italic appendvalstr)
"const Class":(appendifunique afilter_blue2 appendvalstr)
"const Color":(appendifunique afilter_Italic appendvalstr)
"const CurveCtlGeneric":(appendifunique afilter_blue1 appendvalstr)
"const EmptyClass":(appendifunique afilter_Italic appendvalstr)
"const Float":(appendifunique afilter_Italic appendvalstr)
"const Generic":(appendifunique afilter_blue1 appendvalstr)
"const HKey":(appendifunique afilter_Italic appendvalstr)
"const Interface":(appendifunique afilter_Green appendvalstr)
"const MAXClass":(appendifunique afilter_blue2 appendvalstr)
"const MAXMeshClass":(appendifunique afilter_blue1 appendvalstr)
"const MAXScriptFunction":()--empty
"const MAXSuperClass":(appendifunique afilter_blue2 appendvalstr)
"const MappedGeneric":(appendifunique afilter_blue1 appendvalstr)
"const MappedPrimitive":(appendifunique afilter_blue1 appendvalstr)
"const MeditMaterialsClass":(appendifunique afilter_Italic appendvalstr)
"const NodeGeneric":(appendifunique afilter_blue1 appendvalstr)
"const ObjectSet":(appendifunique afilter_Gold appendvalstr)
"const OkClass":(appendifunique afilter_Italic appendvalstr)
"const Point3":(appendifunique afilter_Italic appendvalstr)
"const Primitive":(appendifunique afilter_blue1 appendvalstr)
"const Primitive":()--empty
"const SelectionSetArray":(appendifunique afilter_Italic appendvalstr)
"const StructDef":(appendifunique afilter_Brown appendvalstr)
"const UndefinedClass":(appendifunique afilter_Italic appendvalstr)
"const UnsuppliedClass":(appendifunique afilter_Italic appendvalstr)
"dotNetObject":(appendifunique afilter_black appendvalstr)
"persistent UndefinedClass":(appendifunique afilter_black appendvalstr)
"system Array":(appendifunique afilter_Red appendvalstr)
"system BooleanClass":(appendifunique afilter_Red appendvalstr)
"system Color":(appendifunique afilter_Red appendvalstr)
"system Control":(appendifunique afilter_Red appendvalstr)
"system Float":(appendifunique afilter_Red appendvalstr)
"system Integer":(appendifunique afilter_Red appendvalstr)
"system Integer64":(appendifunique afilter_Red appendvalstr)
"system Interval":(appendifunique afilter_Red appendvalstr)
"system MAXRootNode":(appendifunique afilter_Red appendvalstr)
"system MAXTVNode":(appendifunique afilter_Red appendvalstr)
"system MaterialLibrary":(appendifunique afilter_Red appendvalstr)
"system Name":(appendifunique afilter_Red appendvalstr)
"system String":(appendifunique afilter_Red appendvalstr)
"system Time":(appendifunique afilter_Red appendvalstr)
"system UndefinedClass":(appendifunique afilter_Red appendvalstr)
"system WindowStream":(appendifunique afilter_Red appendvalstr)
default:(messagebox "New Class found, Please update the main function." title:"Warning" beep:false)
--default:(format(xtype[1]+"\n")to:out_script)
)

)

)

)
--//--Black keyword
sort afilter_black
format ("-------------------------------------------------------------"+"\n") to:out_script
format ("Black"+"\n") to:out_script
format ("-------------------------------------------------------------"+"\n") to:out_script
--//--
for f in afilter_black do
(
evalstr=(dotnetobject "system.string" f).Split ("\""+"&"+"%")
--//--
if evalstr.count == 1 then
(
format (evalstr[1]+"\n") to:out_script
)
--//--
)
--//--blue1 keyword
sort afilter_blue1
format ("-------------------------------------------------------------"+"\n") to:out_script
format ("Blue1"+"\n") to:out_script
format ("-------------------------------------------------------------"+"\n") to:out_script
--//--
for f in afilter_blue1 do
(
evalstr=(dotnetobject "system.string" f).Split ("\""+"&"+"%")
--//--
if evalstr.count == 1 then
(
format (evalstr[1]+"\n") to:out_script
)
--//--
)
--//--blue2 keyword
sort afilter_blue2
format ("-------------------------------------------------------------"+"\n") to:out_script
format ("Blue2"+"\n") to:out_script
format ("-------------------------------------------------------------"+"\n") to:out_script
--//--
for f in afilter_blue2 do
(
evalstr=(dotnetobject "system.string" f).Split ("\""+"&"+"%")
--//--
if evalstr.count == 1 then
(
format (evalstr[1]+"\n") to:out_script
)
--//--
)
--//--Brown keyword
sort afilter_Brown
format ("-------------------------------------------------------------"+"\n") to:out_script
format ("Brown"+"\n") to:out_script
format ("-------------------------------------------------------------"+"\n") to:out_script
--//--
for f in afilter_Brown do
(
evalstr=(dotnetobject "system.string" f).Split ("\""+"&"+"%")
--//--
if evalstr.count == 1 then
(
format (evalstr[1]+"\n") to:out_script
)
--//--
)
--//--Green keyword
sort afilter_Green
format ("-------------------------------------------------------------"+"\n") to:out_script
format ("Green"+"\n") to:out_script
format ("-------------------------------------------------------------"+"\n") to:out_script
--//--
for f in afilter_Green do
(
evalstr=(dotnetobject "system.string" f).Split ("\""+"&"+"%")
--//--
if evalstr.count == 1 then
(
format (evalstr[1]+"\n") to:out_script
)
--//--
)
--//--Gold keyword
sort afilter_Gold
format ("-------------------------------------------------------------"+"\n") to:out_script
format ("Gold"+"\n") to:out_script
format ("-------------------------------------------------------------"+"\n") to:out_script
--//--
for f in afilter_Gold do
(
evalstr=(dotnetobject "system.string" f).Split ("\""+"&"+"%")
--//--
if evalstr.count == 1 then
(
format (evalstr[1]+"\n") to:out_script
)
--//--
)
--//--Red keyword
sort afilter_Red
format ("-------------------------------------------------------------"+"\n") to:out_script
format ("Red"+"\n") to:out_script
format ("-------------------------------------------------------------"+"\n") to:out_script
--//--
for f in afilter_Red do
(
evalstr=(dotnetobject "system.string" f).Split ("\""+"&"+"%")
--//--
if evalstr.count == 1 then
(
format (evalstr[1]+"\n") to:out_script
)
--//--
)
--//--Italic keyword
sort afilter_Italic
format ("-------------------------------------------------------------"+"\n") to:out_script
format ("Italic"+"\n") to:out_script
format ("-------------------------------------------------------------"+"\n") to:out_script
--//--
for f in afilter_Italic do
(
evalstr=(dotnetobject "system.string" f).Split ("\""+"&"+"%")
--//--
if evalstr.count == 1 then
(
format (evalstr[1]+"\n") to:out_script
)
--//--
)

)
--//--
GatherMaxscriptKeyword()
ok
)

ZeBoxx2
06-08-2009, 08:17 PM
ah, well, if you wanted them separated by the default syntax coloring, you could've stuck all the words, one per line, in a script file, exported to HTML, then parse the HTML ;)

martroyx
06-08-2009, 08:35 PM
Yes, I suppose it would be more accurate this way ...unfortunately, I don't know HTML well enough to do this :-)

j-man
06-09-2009, 01:32 PM
thanks Ozray, great stuff! thanks everyone else as well!

SyncViewS
06-09-2009, 07:42 PM
Hi guys,
some time ago I collected all keywords form MaxScript 2009 Reference in a textfile to make a synthax highlighter for PSPad, the editor I still use. In the attachment you can find the raw list sorted by argument with punctuation and symbols. I guess some passes through regular expressions could make it suitable for any use. It has indeed to be updated to 2010, but I hope it could be the same of some help.

- Enrico

martroyx
06-10-2009, 03:19 AM
Ho! just realized that "const Primitive" was duplicate ...that's why it was empty ...did you guy have noticed ? :-)

CGTalk Moderation
06-10-2009, 03:19 AM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.