Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.

Due to spam on this forum, all posts now need moderator approval.

 Entire forum ➜ MUSHclient ➜ Plugins ➜ Plugin to show recent scrollback activity

Plugin to show recent scrollback activity

It is now over 60 days since the last post. This thread is closed.     Refresh page


Posted by Nick Gammon   Australia  (23,133 posts)  Bio   Forum Administrator
Date Sun 24 May 2009 04:42 AM (UTC)

Amended on Sun 24 May 2009 04:51 AM (UTC) by Nick Gammon

Message
There have been a few requests recently for a way of seeing current output in the output window, whilst at the same time scrolling back to review earlier output (eg. to check a map, or what a quest is for).

Without such a feature, it is possible that you are in combat, or someone is asking you a question, and you don't realize it.

There are a number of ways of doing this, one is to open a separate output window from the Window menu -> New Window. This new window can be resized and move around so you can have one window paused, and the other scrolls in the normal way.

The plugin below takes another approach. It uses the OnPluginScreendraw plugin callback to capture recent output (that is, output that has not been omitted by a trigger). It draws the most recent 20 lines (this number can be configured) in a miniwindow at the top of the screen. This miniwindow always shows recent output, even if you are scrolling back.

Based on the font size you choose, and your current output window width, the miniwindow size adjusts to exactly hold the number of lines you want (MAX_LINES = 20). You can configure the font name (FONT_NAME = "Lucida Console") and font size (FONT_SIZE = 9) by changing a couple of lines in the plugin.

A timer which fires every half second checks if the output window is paused. If so, it displays the miniwindow. If not, it hides it. Thus the miniwindow is only visible if you scroll back.

Below is the plugin.

Save between the lines as Current_Output_Window.xml and use the File menu -> Plugins to load that file as a plugin.


<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE muclient>

<muclient>
<plugin
   name="Current_Output_Window"
   author="Nick Gammon"
   id="391192793248409895090099"
   language="Lua"
   purpose="Redirects recent output to a miniwindow"
   date_written="2009-02-05 17:00"
   requires="4.37"
   version="1.0"
   >

</plugin>

<timers>
  <timer second="0.50" 
         enabled="y" 
         script="heartbeat"
         >
  </timer>
</timers>


<!--  Script  -->


<script>
<![CDATA[

-- configuration

-- window size in pixels
MAX_LINES = 20

-- font
FONT_NAME = "Lucida Console"
FONT_SIZE = 9

-- where to put the window
WINDOW_POSITION = 6  -- see below (6 is top right)

--[[
Useful positions:

4 = top left
5 = center left-right at top
6 = top right
7 = on right, center top-bottom
8 = on right, at bottom
9 = center left-right at bottom
--]]


-- colours
WINDOW_BACKGROUND_COLOUR = ColourNameToRGB ("khaki")
WINDOW_TEXT_COLOUR = ColourNameToRGB ("black")

-- offset of text from edge
TEXT_INSET = 5

-- where to store the scrollback line
lines = {}  -- table of recent scrollback lines

-- display one line
function Display_Line (line, text)

  local left = TEXT_INSET
  local top = (line - 1) * font_height + TEXT_INSET
  
  WindowText (win, "f", text, left, top, window_width - TEXT_INSET, 0, WINDOW_TEXT_COLOUR)
  
end -- Display_Line

function add_line (line)
  -- remove first line if filled up
  if #lines >= MAX_LINES then
    table.remove (lines, 1)
  end -- if 

  -- add new line
  table.insert (lines, line)

end -- add_line

-- here on new output
function OnPluginScreendraw (type, log, line)

  -- blank existing window contents
  WindowRectOp (win, 2, 0, 0, 0, 0, WINDOW_BACKGROUND_COLOUR)
  
  -- wrap long lines
  while #line > wrap_column do
    add_line (line:sub (1, wrap_column))
    line = line:sub (wrap_column + 1) 
  end -- while line > max
  
  -- add remainder of line
  add_line (line)
  
  -- display all lines
  for k, v in ipairs (lines) do
    Display_Line (k, v)
  end -- for
  
end -- end OnPluginScreendraw


-- hide window on removal
function OnPluginClose ()
  WindowShow (win,  false)  -- hide it
end -- OnPluginClose

-- hide window on disable
function OnPluginDisable ()
  WindowShow (win,  false)  -- hide it
end -- OnPluginDisable

-- show window on enable
function OnPluginEnable ()
  if #lines > 0 then
    WindowShow (win,  true)  -- show it
  end -- if
end -- OnPluginEnable

function heartbeat (timername)
  
  -- display window if output window paused and we have something to show
  WindowShow (win,  GetInfo (114) and #lines > 0)

end -- heartbeat

-- startup stuff

win = GetPluginID ()  -- get a unique name

-- make the window
WindowCreate (win, 0, 0, 1, 1, WINDOW_POSITION, 0, 
                         WINDOW_BACKGROUND_COLOUR)  -- create window
               
-- grab a font
WindowFont (win, "f", FONT_NAME, FONT_SIZE) -- define font

-- work out how high and wide it is
font_height = WindowFontInfo (win, "f", 1)   -- height of the font  
wrap_column = GetOption ("wrap_column")

window_width = wrap_column * WindowFontInfo (win, "f", 6) + TEXT_INSET * 2
window_height = MAX_LINES * font_height + TEXT_INSET * 2 

-- remake the window with the correct width
WindowCreate (win, 0, 0, window_width, window_height, WINDOW_POSITION, 0, 
                         WINDOW_BACKGROUND_COLOUR)  -- create window

]]>
</script>

</muclient>

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Nick Gammon   Australia  (23,133 posts)  Bio   Forum Administrator
Date Reply #1 on Sun 24 May 2009 04:42 AM (UTC)
Message

Example of it in operation:


- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Nick Gammon   Australia  (23,133 posts)  Bio   Forum Administrator
Date Reply #2 on Sun 24 May 2009 04:45 AM (UTC)
Message
In the example above you can see the output window is paused (because you can see MORE in reverse font). As soon as you scroll to the bottom of the output window (eg. Ctrl+End) then MORE disappears, and the yellow window disappears too.

The colours are configurable by changing these two lines:


WINDOW_BACKGROUND_COLOUR = ColourNameToRGB ("khaki")
WINDOW_TEXT_COLOUR = ColourNameToRGB ("black")


Note that since the plugin callback OnPluginScreendraw is not given colour information, the miniwindow is monochrome (although you can choose the foreground and background colours).

You can also change the position the window appears (eg. top left). See (WINDOW_POSITION = 6).

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by LupusFatalis   (154 posts)  Bio
Date Reply #3 on Mon 25 May 2009 04:20 PM (UTC)
Message
When the MUSHclient window loses focus the miniwindow disappears. Could it be made so that it stays?

Aside from that, it works beautifully.
Top

Posted by Nick Gammon   Australia  (23,133 posts)  Bio   Forum Administrator
Date Reply #4 on Mon 25 May 2009 08:57 PM (UTC)

Amended on Tue 26 May 2009 10:28 PM (UTC) by Nick Gammon

Message
Hmm, it seems the check for if we are paused does not apply if the world is not active. You could replace the heartbeat function with this:


function heartbeat (timername)
  
  if GetInfo (113) then
    -- display window if output window paused and we have something to show
    WindowShow (win,  GetInfo (114) and #lines > 0)
  end -- if world active
  
end -- heartbeat


What that does is only show or hide the window if the world is active, so if it was visible and loses the focus, it will stay visible.

[EDIT] - fixed problem where the first GetInfo should be 113 ('World is active' flag) and the second one 114 ('Output window paused' flag).

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by LupusFatalis   (154 posts)  Bio
Date Reply #5 on Tue 26 May 2009 12:21 AM (UTC)
Message
Made that replacement. It now works properly when the window is inactive, however, it no longer hides when you aren't scrolled back.
Top

Posted by Nick Gammon   Australia  (23,133 posts)  Bio   Forum Administrator
Date Reply #6 on Tue 26 May 2009 10:28 PM (UTC)
Message
I accidentally used GetInfo (114) twice - the first one should be 113, I have amended the post.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by LupusFatalis   (154 posts)  Bio
Date Reply #7 on Wed 27 May 2009 06:40 PM (UTC)
Message
Beautiful, thanks.
Top

Posted by LupusFatalis   (154 posts)  Bio
Date Reply #8 on Mon 15 Jun 2009 05:05 AM (UTC)
Message
As a suggestion... Think this script can be edited to search for a space for where it makes a new line, rather than cutting words up? And if that is the case, possibly delineate the lines formed that way by indenting them slightly? Basically, like the client itself does.
Top

Posted by Nick Gammon   Australia  (23,133 posts)  Bio   Forum Administrator
Date Reply #9 on Mon 15 Jun 2009 05:36 AM (UTC)
Message
That was supposed to be an exercise for the reader, but oh well ...

In the plugin, change:


  -- wrap long lines
  while #line > wrap_column do
    add_line (line:sub (1, wrap_column))
    line = line:sub (wrap_column + 1) 
  end -- while line > max


to:


  -- wrap long lines, at a space if possible
  while #line > wrap_column do
  
    local col = wrap_column
    if line:match (' ', 3) then  -- if a space past column 2
      while line:sub (col, col) ~= ' ' do  -- find a space
        col = col - 1
      end -- while finding a space, going backwards
      col = col - 1  -- use space in new line, to indent it
    end -- any spaces

    add_line (line:sub (1, col))
    line = line:sub (col + 1) 
    
  end -- while line > max


- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Nick Gammon   Australia  (23,133 posts)  Bio   Forum Administrator
Date Reply #10 on Mon 15 Jun 2009 05:55 AM (UTC)
Message
To save the loop, I think this regexp will do it:


  -- wrap long lines, at a space if possible
  while #line > wrap_column do
  
    -- find a space not followed by a space, closest to the end of the line
    local col = string.find (line:sub (1, wrap_column), "%s%S*$")
    
    if col and col > 2 then
      col = col - 1  -- use the space to indent
    else
      col = wrap_column  -- just cut off at wrap_column
    end -- if

    add_line (line:sub (1, col))
    line = line:sub (col + 1) 
    
  end -- while line > max


- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by LupusFatalis   (154 posts)  Bio
Date Reply #11 on Mon 15 Jun 2009 07:45 PM (UTC)
Message
Second one works perfectly it looks like, didn't try the first. Man, if you keep writing all this good stuff in Lua, I'm going to have to learn it as well just to use it all ;)
Top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


33,304 views.

It is now over 60 days since the last post. This thread is closed.     Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.