setcommand problem...

Posted by Shadowfyr on Wed 30 Apr 2003 09:40 PM — 15 posts, 46,847 views.

USA #0
This doesn't seem to work. Is it a bug or am I missing something:

Macro Shift-F10 = ToggleMode

<aliases>
  <alias
   match="^ToggleMode$"
   enabled="y"
   regexp="y"
   send_to="12"
   sequence="100"
  >
  <send>mstemp = getvariable(&quot;TempCmd&quot;)
setvariable &quot;TempCmd&quot;, getcommand
setcommand mstemp
note mstemp
note getvariable(&quot;TempCmd&quot;)</send>
  </alias>
</aliases>


The note lines show that the variables get switched properly, but the contents of the actual input box never changes... :(
Amended on Wed 30 Apr 2003 09:42 PM by Shadowfyr
Australia Forum Administrator #1
See the documentation for SetCommand - it will not change the command window if there is something in it.
Canada #2
I use the following routine to set commands:

Sub SetCommandLine (CommandString)
	World.PushCommand
	World.SetCommand CommandString
	World.SelectCommand
End Sub

If my script sets a command unexpectedly, I can simply press delete and up arrow to recover what was previously on the command line. I highlight the new command as well, so that if I choose not to use it, I can just start typing a new command or press delete to clear the command box.
USA #3
So... I would need:
<aliases>
  <alias
   match="^ToggleMode$"
   enabled="y"
   regexp="y"
   send_to="12"
   sequence="100"
  >
  <send>mstemp = getvariable(&quot;TempCmd&quot;)
setvariable &quot;TempCmd&quot;, getcommand
docommand "KeysEscape"
setcommand mstemp
  </alias>
</aliases>

I assume that would work? docommand "Cut" would work too, but has the occationally unwanted side effect of destroying the clipboard contents.
USA #4
Ok.. Now this is a bug..

DoCommand "KeysEscape" will clear the contents of the input window, but does not clear whatever internal flag that SetCommand uses to determine if the input box is empty. The result is that my new version won't work either. :p
Australia Forum Administrator #5
It is not a bug *wipes brow*.

The release notes for a recent version clarified that DoCommand *queues* the command, otherwise things like DoCommand "close" crash the client because the window has been closed but the script is still trying to execute.

Thus, your example queues up a "KeysEscape" command to be executed *after* the script completes.

I have modified the description for the function DoCommand to make this much clearer.

I suggest you use Magnum's approach to empty the command window, that should work.
USA #6
Hmm. Actually I didn't really look at Magnum's. It would sort of work for the test case I was trying, but for the more complex issue I was looking at, it wouldn't quite cut it.

The original idea was to 'fake' the trick KMud has. Instead of using two seperate input windows, which can also have seperate command histories, the idea would have been to do:

  a = GetCommand
  ClearCommand '<--- It all hangs in not having this...
  b = GetVariable ("LastCmd")
  SetCommand a
  SetVariable "LastCmd", b
  c = split(GetVariable "CMDList",",")
  d = GetCommandList
  DeleteCommandHistory
  for each e in c
    PushCommand e
  next
  SetVariable "CMDList", join(d,",")
  if GetVariable ("Mode") = "1" then
    SetVariable "Mode", 2
    SetAlphaOption "input_background_colour","#400000"
  else
    SetVariable "Mode", 1
    SetAlphaOption "input_background_colour","#000000"
  end if


Other commands, such as activating an editor or the like could be included in the mode change as well and you could have theoretically as many 'input windows' as you could manage bofore they started slowing down the client.

I suppose I could generate a temporary timer to make the substitution, but it isn't exactly what would have been the obvious solution. ;) lol
Amended on Thu 01 May 2003 11:33 PM by Shadowfyr
Australia Forum Administrator #7
This seems to almost work for me. I say "almost" because I think it reverses the order of the saved commands, because GetCommandList gets them in starting at the most recent, but you need to push the with the oldest first. However with a bit of tweaking you should get it to work ...


'
'  get existing commands
'
cmdlist = GetCommandList (0)
'
'  delete them
'
DeleteCommandHistory
'
'  get earlier commands
'
oldList = Split (GetVariable ("Saved_Commands"), vbTab)
'
' save current ones for later
'
if VarType (cmdList) = (vbVariant + vbArray) then
  SetVariable "Saved_Commands", Join (cmdlist, vbTab)
else
  SetVariable "Saved_Commands", ""
end if

'
' put old commands back
'
for each c in oldList
  PushCommand
  SetCommand c
next

USA #8
Umm. Wait. Are you saying that the GetCommandList also reads what is 'currently' in the command window and that DeleteCommandHistory will nuke that too? If not, then you haven't actually fixed anything with the redesign, though knowing that the sequence of commands returned are reversed is useful.
Australia Forum Administrator #9
No, you spotted another flaw in it.

You want an initial PushCommand, which will add the current command window contents to the list, and delete it, which is surely what you want to do anyway.
Australia Forum Administrator #10
However I think my idea of using tabs as the command separator is much more sensible than commas, after all, commands are likely to have commas in them.
USA #11
Hmm. Yeah. Didn't think of that factor.. popping the last command off to set the line would work. As for using TAB as a seperator... I hadn't considered that, but since it is at least possible that a tab could exist in something copied into the command box, if not entered directly, I would consider using something less likely. One of the characters under 32 or even a pair of characters, like ^`, which are unlikely to occure in anything you copy, let alone type. Split and Join don't care what or how many letters you use, just that they are unique enough to function as a seperator. ;)

Like so:

  PushCommand
  c = split(GetVariable "CMDList",",,")
  d = GetCommandList
  DeleteCommandHistory
  dim e
  for e = ubound(c) - 1 to 0 step -1
    PushCommand c(e)
  next
  SetCommand c(unbound(c))
  SetVariable "CMDList", join(d,",,")
  if GetVariable ("Mode") = "1" then
    SetVariable "Mode", 2
    SetAlphaOption "input_background_colour","#400000"
  else
    SetVariable "Mode", 1
    SetAlphaOption "input_background_colour","#000000"
  end if


Using yours I would get a duplicate of the 'current' command, which wouldn't necessarilly hurt anything, but isn't needed and as you said, it also reversed the order.
Amended on Sat 03 May 2003 12:05 AM by Shadowfyr
Australia Forum Administrator #12
Why not be safe and use something like CHR(1)?


Two consecutive commas are not particularly unlikely, especially if have been entering script commands.
USA #13
You also run into the problem of muds with unusual colour escape chars, DoT's ` for instance. Or \ for internal speedwalk support. There are also codebases that use { and @@ for colour escape chars so what might be an 'obvious' delimiter choice for a particular codebase may be totally unusable on several others. Nick's last suggestion is actually pretty good and *should* be universally safe.
USA #14
Hmm. True. Probably a good idea to use char(1).

Also. I think I goofed again though. It should be

for e = ubound(c) to 1 step -1

and

SetCommand c(0)

Otherwise, since you say the sequence is reversed, I would have been 'setting' it to the wrong command. :p