Evaluator/Functions: How to reference current file?

This code works just fine:

@nodeselect
@nofilenamequoting

@output:{=source=}
@output:{=Left(source, 1)=}

CreateFolder NAME={=Left(source, 1)=}

But how can I create the folder based on the current filename?

This still looks good...

@nodeselect
@nofilenamequoting

@output:{=file=}
@output:{=Left(file, 1)=}

... but all of these throw errors ("Unknown value"):

CreateFolder NAME={=Left(file, 1)=}
CreateFolder NAME={=Left(filepath, 1)=}
CreateFolder NAME={=Left({filepath}, 1)=}

This will bring up the standard create folder dialog:

CreateFolder NAME={=Left({$filepath}, 1)=}
Button as XML
<?xml version="1.0"?>
<button backcol="none" display="both" label_pos="right" textcol="none">
	<label>Demo Evaluator2</label>
	<icon1>#newcommand</icon1>
	<function type="normal">
		<instruction>@nodeselect</instruction>
		<instruction>@nofilenamequoting</instruction>
		<instruction />
		<instruction>@output:{=source=}</instruction>
		<instruction>@output:{=Left(source, 1)=}</instruction>
		<instruction />
		<instruction>CreateFolder NAME={=Left(source, 1)=}</instruction>
		<instruction />
		<instruction>@output:{=file=}</instruction>
		<instruction>@output:{=Left(file, 1)=}</instruction>
		<instruction />
		<instruction>// CreateFolder NAME={=Left(file, 1)=}</instruction>
		<instruction>// CreateFolder NAME={=Left(filepath, 1)=}</instruction>
		<instruction>// CreateFolder NAME={=Left({filepath}, 1)=}</instruction>
		<instruction>// CreateFolder NAME={=Left({$filepath}, 1)=}</instruction>
		<instruction />
		<instruction>@output:---</instruction>
	</function>
</button>

@lxp can you try this for the command line:

=return "CreateFolder NAME="+Left(file, 1)

This brings up the standard dialog as well.

Luckily, I might add, because I would have been totally confused had it worked :smiley:


Update: It works for filenames that don't contain spaces. Now I am confused!

I think file is a string including quotes, if it contains spaces. So left(file, 1) will be the quote character.

Adding @nofilenamequoting fixes that without having to check for the quotes explicitly.

Probably not worth worrying about, but a filename may also start with a space, in a pathological case. Trim can deal with that without much extra code:

@nofilenamequoting
=return "CreateFolder NAME="+Left(Trim(file), 1)

Yes, of course, like in the original code :blush:

But I still don't get why this works

@nofilenamequoting
CreateFolder NAME={=Left(source, 1)=}

and this does not:

@nofilenamequoting
CreateFolder NAME={=Left(file, 1)=}

Yeah, that is unexpected.

It looks like the file variable isn't being fed into the {= ... =} context, which causes the button to error when used like that.

Yes, but it works when invoked via @output.

@output:{=file=}
@output:{=Left(file, 1)=}

I suspect there are some behind-the-scenes shenanigans with how different commands are flagged to use/require files/arguments, but will wait for Jon's opinion, as he knows much more about this than I.

Definitely a bug we need to fix, in any case!

2 Likes

Should be ok in the next beta.

2 Likes

Yes, much better in 13.0.38, but I stumbled onto another quirk:

This will create new folders based on the first character of the selected files (Note: no quotes used):

@nodeselect
@nofilenamequoting
CreateFolder NAME={=UCase(Left(file, 1))=}

This will move files into new folders. But it only works for the first selected file, the others are ignored:

@nodeselect
@nofilenamequoting
Copy MOVE HERE CREATEFOLDER={=UCase(Left(file, 1))=} WHENEXISTS=replace

Quotes aren't needed for a single character, but adding them helps, surprisingly:

@nodeselect
@nofilenamequoting
Copy MOVE HERE CREATEFOLDER="{=UCase(Left(file, 1))=}" WHENEXISTS=replace

However, if we use an evaluator-generated command instead of an insertion code, everything is fine again. All files will be moved into new folders. No quotes needed:

@nodeselect
@nofilenamequoting
=return "Copy MOVE HERE CREATEFOLDER=" + UCase(Left(file, 1)) + " WHENEXISTS=replace"
Button as XML
<?xml version="1.0"?>
<button backcol="none" display="both" hotkey_label="yes" label_pos="right" textcol="none">
	<label>46372</label>
	<icon1>#move</icon1>
	<function type="normal">
		<instruction>@nodeselect</instruction>
		<instruction>@nofilenamequoting</instruction>
		<instruction />
		<instruction>// =return &quot;Copy MOVE HERE CREATEFOLDER=&quot;&quot;&quot; + Left(file, 1) + &quot;&quot;&quot; WHENEXISTS=replace&quot;</instruction>
		<instruction>// =return &quot;Copy MOVE HERE CREATEFOLDER=&quot; + UCase(Left(file, 1)) + &quot; WHENEXISTS=replace&quot;</instruction>
		<instruction />
		<instruction>Copy MOVE HERE CREATEFOLDER={=UCase(Left(file, 1))=} WHENEXISTS=replace</instruction>
		<instruction>// Copy MOVE HERE CREATEFOLDER=&quot;{=UCase(Left(file, 1))=}&quot; WHENEXISTS=replace</instruction>
		<instruction />
		<instruction>// CreateFolder NAME={=UCase(Left(file, 1))=}</instruction>
	</function>
</button>

I did not look at Evaluator things yet, but used like this, do they really help to make things more easy?
I would go straight for the JScript solution in a case like this, it can be debugged step by step and outcome is a lot more predictable, no?

Combining the old button codes with the new evaluators, to me this seems to be stuff for the brave! o)

I'm not a programmer and I think this is really much simpler. Because the code is relatively short. . .

Well, people have asked for string operations in buttons for awhile, so here we go :slight_smile:

Nonetheless, your question is valid. In buttons access to metadata is (still?) unavailable, so a script is needed for these cases.

/dopusdata\userdata.omd describes me as "beta warrior" so I guess I am ok :wink:

1 Like

I can see why this looks tempting with the short syntax, but expressing things as short as possible is not necessarily a solution for more complex tinkering.
Assembly language is short as well, is it easier to understand than C#, C++, Java etc.? I'd say not really, but yes, you have to learn some more basic aspects of the language as always initialising some things first e.g., but then you are way more free in what you can do and what approach you take. Just my 2 cents of course! o)

What kind of file is this? o) Look's like I'm a "beta warrior" too! o)

That was the key; it's not the evaluator, it's the parser getting confused by the = sign in the {= =} code. Putting quotes around it solves it.

Should be fixed in the next beta!

3 Likes

With 13.0.39, the command can be reduced to

Copy MOVE HERE CREATEFOLDER={=UCase(Left(Trim(file), 1))=} WHENEXISTS=replace

Even the modifier isn't needed anymore - I'd say this is as neat as it gets :slight_smile:

3 Likes

Well.. yes, this does not look to bad! o)

From experience there are a lot of special cases with button codes and things, I don't really wanna hate on them or the new evaluator functionality, you can surely manage the different syntax at some point, but the challenges may be in the unexpected, like here.

I read some more on the evaluators, if they are quicker than using jscript for generating simple column values e.g., why not! Every language and syntax can be a tool, and there's always the right and the wrong tool for a job.

@Jon
When reading about Evaluators, I had the impression these are also used internally for handling GUI updates / conditions etc.? Is it some kind of functionality that already existed in some state and you decided to make it available to the user as well? Or is this a complete new invention for the user in v13?