Originally Posted By: jaytea
however, it is interesting to know that there exist methods such as Thels's (which, by the way, is brilliant) to overcome these problems with pure mIRC script :P


Thanks for the compliment. smile

By the way, I modified the code to add some safety nets in case the script would bug out for one reason or another (in the earlier example, IF something would go wrong, all further input without ctrlenter would be eaten by the script :P).

I also used regular variables instead of a hash table. Since the number of variables is equal to 3 + number of lines posted, it shouldn't be a problem. This also shows better that the $chr(160) trick is not required for grabbing the input, but merely for the /say and /me commands at the very end of the code.

I might come up with a /play and /loadbuf alternative, to allow adjacent spaces to go from input to output without the need for spaces, but that would mostly be for academical reasons.

Code:
on *:input:*: {
  if !$ctrlenter {

    ;If there is already an input queue, simply add one additional line.
    ;(Checking the timer is merely a safety net. It should always be running while %inputlines is set).
    if %inputlines && $timer(grabinput) {
      haltdef
      inc %inputlines 1
      inc %inputlinem 1
      set %inputline [ $+ [ %inputlines ] ] $1-
      return
    }

    ;(Removing the variables is merely a safety net. They should always be removed at the end of an input run).
    unset %inputline*

    ;If there is no input queue, and the line is a command, stop processing unless it's /say, /me, /msg or /describe.
    set %inputlinec $readini($mircini, text, commandchar)
    if $left($1, 1) == / || $left($1, 1) == %inputlinec {
      if $right($1, -1) != say && $right($1, -1) != me && $right($1, -1) != msg && $right($1, -1) != describe {
        if $right($1, -1) != .say && $right($1, -1) != .me && $right($1, -1) != .msg && $right($1, -1) != .describe {
          return
        }
      }
    }

    ;If the primary editbox is empty, recall the last line for the primary editbox.
    if $editbox($active) == $null {
      haltdef
      set %inputlines 1
      set %inputlinem 1
      set %inputline1 $1-
      editbox -afn /
      .timergrabinput 1 0 grabinput 1
    }

    ;If the primary editbox is not empty, but the secondary editbox is, recall the last line for the secondary editbox.
    elseif $editbox($active, 1) == $null {
      haltdef
      set %inputlines 1
      set %inputlinem 1
      set %inputline1 $1-
      editbox -afno /
      .timergrabinput 1 0 grabinput
    }

    ;Catch the error in case the secondary editbox is unavailable.
    :error
    reseterror
  }
}

;Grab the input entries.
alias -l grabinput {

  ;Compare the value with a tokenized version of the editbox, to see if they match.
  if $1 {
    tokenize 32 $editbox($active)
    if %inputline [ $+ [ %inputlines ] ] == $1- {
      set %inputline [ $+ [ %inputlines ] ] $editbox($active)
      dec %inputlines 1

      ;If there are more lines in queue, request the next editbox line.
      if %inputlines {
        editbox -afn /
        .timergrabinput 1 0 grabinput 1
        return
      }

      ;Clear the editbox.
      editbox -a
    }
    else {
      editbox -a

      ;If the primary editbox does not match, but the secondary editbox is empty, recall the last line for the secondary editbox.
      if $editbox($active, 1) == $null {
        editbox -afno /
        .timergrabinput 1 0 grabinput
        return
      }
    }
  }
  else {
    tokenize 32 $editbox($active, 1)
    if %inputline [ $+ [ %inputlines ] ] == $1- {
      set %inputline [ $+ [ %inputlines ] ] $editbox($active, 1)
      dec %inputlines 1

      ;If there are more lines in queue, request the next editbox line.
      if %inputlines {
        editbox -afno /
        .timergrabinput 1 0 grabinput
        return
      }
    }

    ;If the result does not match, and the first editbox is empty, return the focus to the first editbox.
    elseif $editbox($active) == $null {
      editbox -af
    }

    ;Clear the editbox.
    editbox -ao
  }

  ;Catch the error in case the secondary editbox is unavailable.
  :error
  reseterror

  ;Send all input entries for evaluation.
  set %inputlines 0
  while %inputlines < %inputlinem {
    inc %inputlines 1
    noop $evalinput(%inputline [ $+ [ %inputlines ] ] )
  }
  unset %inputline*
}

;Evaluate the input entry.
alias -l evalinput {
  var %line $1
  tokenize 32 %line

  ;If the first parameter does not start with /, send the line to the channel.
  if $left($1, 1) != / && $left($1, 1) != %inputlinec {
    say $hardspace(%line)
    return
  }

  ;Remove the first parameter from the line.
  var %line $right(%line, $calc(0 - $pos(%line, $1, 1) - $len($1)))

  ;If the first parameter equals /say or /me, send the remaining line to the channel.
  if $right($1, -1) == say ||  $right($1, -1) == .say || $right($1, -1) == me || $right($1, -1) == .me {
    $right($1, -1) $hardspace(%line)
    return
  }

  ;Remove the second parameter from the line.
  var %line $right(%line, $calc(0 - $pos(%line, $2, 1) - $len($2)))

  ;If the first parameter equals /msg or /describe, send the remaining line to $2.
  if $right($1, -1) == msg || $right($1, -1) == .msg || $right($1, -1) == describe || $right($1, -1) == .describe {
    $right($1, -1) $2 $hardspace(%line)
    return
  }

  ;Execute the space tokenized version as a regular alias. Include an :error to allow further lines to execute.
  $1-
  :error
}

;Replace non breaking spaces by normal spaces. (Only required at the very end to output the line again.)
alias -l hardspace return $replace($+($chr(32), $1-), $+($chr(32), $chr(32)), $+($chr(32), $chr(160)), $+($chr(160), $chr(32)), $+($chr(160), $chr(160)))


Now, if I could only come up with a way to set the entrybox history position back to the very end. smile


Learning something new every day.