Copying output using keyboard shortcut (Ctrl+C) while all keys to command box on

Posted by Worstje on Tue 24 Jul 2007 12:41 AM — 34 posts, 137,488 views.

Netherlands #0
I've been happily upgrading along for quite a few versions, and at some point (I wish I had been paying attention but I haven't) the handling of Ctrl+C started to differ. My current version is 4.14.

I am unsure if I had 'All typing goes to command window' on in the past, but I am pretty sure I did since I used to click there and just start typing to have my output.

With it off, I can select text and Ctrl+C to have output copied to the clipboard. With it on, I can NOT use Ctrl+C to copy stuff and I end up copying nothing, which is quite annoying. Yes, I can rightclick the selected text, but since the popup menu is so large, I usually end up having to go back to the top of the screen which is slow and cumbersome.

I am 100% positive that I used to have these two 'features' work alongside eachother pre-v4.0, but that is as far as my knowledge or experiences go. Can this 'old' behavior be re-instated? (click on output and typing goes to command box while selecting output and Ctrl+C copies to clipboard)
USA #1
Nope, it's never worked. Because the Typing Window is always highlighted, you cannot Ctrl+C the output window because it is not highlighted.
Netherlands #2
I am pretty sure it worked. That or I did something really funky in the past. >_> Besides, it doesn't look like the caret is in the command box if you click on the output area with the option turned on.

Well, if it isn't a bug report, it is a feature request! ^_^
USA #3
I'm pretty sure it never worked. Look at my post I made 4 years ago.
http://www.gammon.com.au/forum/bbshowpost.php?id=2369
Netherlands #4
We'll settle on me doing funky stuff, then.
Australia Forum Administrator #5
The option "All typing goes to command window" does exactly what it claims to do. As soon as you type something, including Ctrl+C, the focus moves to the command window first.

If you RH-click, the very first menu option is "copy", so it should be easy enough to copy then. Or, you can click on the "copy" button on the button bar (about the 7th button).

Or, just turn off "All typing goes to command window" - if the focus is not in the command window all you have to do is hit <Tab> to move it there.

Another possibility, if you are just copying single words, is to turn on "double click pastes word". That way, if you double-click a word, it gets copied and pasted into the command window.

I don't think it ever worked the way you describe.

Quote:

Besides, it doesn't look like the caret is in the command box if you click on the output area with the option turned on.


The focus is in the output window until you type something.
Australia Forum Administrator #6
The "Copy selection to clipboard" option might be what you used to use. I was going to mention that but couldn't find it, as it was in the Output configuration and not the Command configuration.
USA #7
Is there any way to put in an option to have Ctrl+C check if there is highlighted text in the output window before checking the input window? Come to think of it, I can't seem to find a script function to check for highlighted text in the output windows when I did a quick scan. Does this function exist? I was going to make a plugin to deal with this, but hit a wall with checking for highlighted text.
Australia Forum Administrator #8
No, as that other post explained, Ctrl and C are separate keystrokes, and for the idea of switching focus to work at all, it has to be on the Ctrl keypress.

As for finding the selection, see:

http://www.gammon.com.au/scripts/doc.php?function=GetSelectionStartColumn

USA #9
But even if you press Ctrl-C, the text highlighted in the output window is still highlighted, at least for me it is. My idea is to add a flag could be added so that when you press Ctrl-C, the focus does switch to the command window like normal. The difference is that it checks the output window for any highlighted text first, then will either grab the highlighted output text, or if none exists go grab the highlighted text in the command window. Then, if you press Ctrl-P, the text will be placed as normal in the command window.
Australia Forum Administrator #10
This might work for you. Put this script into your script file:


function CopySelection ()

-- find the selection range

  local startline, endline, startcol, endcol = 
    GetSelectionStartLine (),
    GetSelectionEndLine (),
    GetSelectionStartColumn (),
    GetSelectionEndColumn ()

  -- if a single line selected, take that word  

  if startline > 0 and 
     endline == startline and
     startcol > 0 and
     endcol > 0 then

    local selection = string.sub (GetLineInfo (startline, 1), startcol, endcol - 1)

    SetClipboard (selection)

  else
    DoCommand ("copy")
  end -- if

end -- function CopySelection 



Then make an accelerator:


/Accelerator ("Ctrl+C", "/CopySelection ()")


What this will do, on a Ctrl+C, is try to find the selected text in the output window, and if found, copy it to the clipboard, otherwise execute the DoCommand ("copy") function, which will copy the "normal" selection.

The code above only handles a single-line selection, but you could modify it a bit to handle multiple lines.
Amended on Tue 24 Jul 2007 03:15 AM by Nick Gammon
USA #11
Here's the script I've been poking with:
function Copy2()
  local line1, line2 = GetSelectionStartLine (), GetSelectionEndLine ()
  local col1, col2 = GetSelectionStartColumn (), GetSelectionEndColumn ()
  if line1 == 0 then
    -- copy command window if output window has nothing
    DoCommand( "copy" )
  else
    local copystring = ""
    local x = col1
    local i = line1
    while i <= line2 do
      if i < line2 then
        copystring = copystring..string.sub(GetLineInfo(i).text, x).."\n"
	x = 1
      else
        copystring = copystring..string.sub(GetLineInfo(i).text, x, col2-1)
        -- subtract 1 from col2 or you get an extra character for some reason
      end
      i = i + 1
      SetClipboard( copystring )
    end
  end
end -- function Copy2

I haven't had any issues so far with it with nearly an hour of testing it out. Everyone feel free to let me know if you can make it break or make the code a bit more smooth than this quick hack job.
USA #12
Accelerator ("Ctrl+C", "/Copy2()")
function Copy2()
  local line1, line2 = GetSelectionStartLine (), GetSelectionEndLine ()
  local col1, col2 = GetSelectionStartColumn (), GetSelectionEndColumn ()
  if line1 == 0 then
    DoCommand( "copy" )
  else
    local copystring = ""
    while line1 <= line2 do
      if line1 < line2 then
        copystring = copystring..string.sub(GetLineInfo(line1).text, col1).."\n"
	col1 = 1
      else
        copystring = copystring..string.sub(GetLineInfo(line1).text, col1, col2-1)
      end
      line1 = line1 + 1
    end
    SetClipboard( copystring )
  end
end -- function Copy2

bah, stupid redundant variables... got rid of x and i, since they just mirrored other variables in there anyway. Also moved SetClipboard to the right spot so it doesn't repeatedly copying everything to the clipboard each time it grabs a new line.
Amended on Tue 24 Jul 2007 05:05 AM by Shaun Biggs
USA #13
Is anyone else using my copy function here? I've noticed that it does have one really weird quirk. It only copies on every other press of ctrl-C for some odd reason. Doesn't matter if there is anything in the command window or not, but it will only grab things off the output window on the second try.

I can't really find any reason for this to happen, and I've been testing it for a good three days now that it finally clicked in my head that this was happening.
Netherlands #14
I wasn't using it yet. I've been a bit too busy as of late. It looks very useful, but that quirk is rather depressing; I'd sooner stick with the built-in copying and no focus to command box.

Thanks for your hard work though, I am sure someone has a use for it. (I'll be testing it of course!)
Australia Forum Administrator #15
I can't reproduce that. It seems to work every time for me. You are using Linux aren't you? Perhaps the quirk is in there?

Try making a test case where you do SetClipboard twice in a row, and check the clipboard after each time. Maybe Wine is not handling SetClipboard correctly.
Amended on Thu 02 Aug 2007 05:26 PM by Nick Gammon
USA #16
SetClipboard works perfectly fine. I've used it in many other scripts before, and I just tested it manually. Seems to be in working order. I'll test it out on my old laptop to see if I can get it working in a win98 install, but if it's just on my computer, I guess I can live with it.
Netherlands #17
It's not Linux. I'm suffering from the 'double Ctrl+C' problem too, and I am using WXP.

Funnily enough, it only happens when the focus box is -NOT- in the command box, which in turn only becomes an issue if 'All typing goes to command box' is turned OFF.

After I turned it on, it started working properly.

On a side note though... it is quite annoying that after using this Ctrl+C, the selection immediately disappears. I am not sure what causes it, but personally I think that somehow the alias I use with Accelerator is what indirectly causes the selection to be lost. I seem to notice some 'flickering' on the last line of the output area.

On the other hand, I could get used to it. Maybe. ^_^

Thanks, Shaun Biggs, for the nice script! I changed the "\n" to "\r\n" though, that plays a bit nicer in Windows.
Amended on Fri 03 Aug 2007 12:31 AM by Worstje
Australia Forum Administrator #18
If you aren't forcing input to the command window, you don't need the script do you?
Netherlands #19
I don't. I found out halfway my post I forgot to set the setting before loading the script. I think Shaun Biggs forgot just like I did. :)
USA #20
I just tried it with typing sent to output only toggled on and off. You're right Worstje, the function only works if it's needed, and it screws up the normal copy when it's not needed. Probably why I missed it before.

Is there anything in GetInfo or a similar function to tell if output is going only to the command window? That would fix the script with a simple or in the first if statement.

if GetInfo( foo ) == false or line1 == 0 then
  DoCommand( "copy" )
else
Netherlands #21
I had some kind of request for a feature until I remembered GetLineInfo(), which was precisely what I needed. (It's strange how you can't ever figure out what name to give a certain feature until you are ready to click 'Save' on this forum...)

Anyhow, I threw the stuff into a plugin and adjusted it to suit my needs. Use it as you like! (And thanks again, Shaun Biggs!)

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE muclient>
<!-- Saved on vrijdag, augustus 03, 2007, 2:06  -->
<!-- MuClient version 4.14 -->

<!-- Plugin "CopyScript" generated by Plugin Wizard -->

<muclient>
<plugin
   name="CopyScript"
   author="Mygale"
   id="eebb80f374370f77176cb2ed"
   language="Lua"
   purpose="Allows you to use CTRL+C for the output if 'All typing goes to command window' is turned on."
   save_state="n"
   date_written="2007-08-03 02:04:12"
   requires="4.00"
   version="1.0"
   >

</plugin>

<aliases>
  <alias
    match="^CopyScript:Copy$"
    enabled="y"
    regexp="y"
    omit_from_output="y"
    sequence="100"
    script="CopyScript"
  >
  </alias>
</aliases>


<!--  Script  -->

<script>
<![CDATA[

-- Thank you, Shaun Biggs, for taking your time to write the CopyScript
-- (formerly Copy2) function below. It was slightly altered by me to suit
-- my usage (wordwrapped lines and no \r\n at start of selection).

Accelerator ("Ctrl+C", "CopyScript:Copy")

function CopyScript(name, line, wildcs)
	local line1, line2 = GetSelectionStartLine(), GetSelectionEndLine()
	local col1, col2 = GetSelectionStartColumn(), GetSelectionEndColumn()
	if line1 == 0 then
		DoCommand("copy")
	else
		local copystring = ""
		while line1 <= line2 do
			if line1 < line2 then
				copystring = copystring..string.sub(GetLineInfo(line1).text, col1)
				col1 = 1
			else
				copystring = copystring..string.sub(GetLineInfo(line1).text, col1, col2-1)
			end
			
			-- Is this a new line or merely the continuation of a paragraph?
			if (world.GetLineInfo(line1, 3) == true) then
				copystring = copystring .. "\r\n"
			end
			
			line1 = line1 + 1
		end
		
		if (string.sub(copystring, 1, 2) == "\r\n") then
			-- Get rid of a spurious extra new line at the start.
			copystring = string.sub(copystring, 3, -1)
		end
		
		SetClipboard(copystring)
	end
end -- function CopyScript
]]>
</script>

</muclient>
USA #22
Heh, didn't even notice the weird issue with wrapped lines. Good bug catch and a good solution However, this is where I but that bit of code:

    while line1 <= line2 do
      if line1 < line2 then
        copystring = copystring..string.sub(GetLineInfo(line1).text, col1)
	if GetLineInfo(line1, 3) == true then
	  copystring = copystring.."\r\n"
	end
	col1 = 1
      else
        copystring = copystring..string.sub(GetLineInfo(line1).text, col1, col2-1)
      end
      line1 = line1 + 1
    end

This prevents an extra "\r\n" from being added if you just highlight part of a line that's a continuation of the previous line.

ex:
CLAN: Trumpets sound in the Emerald stronghold as Knight Balaam returns from
afar.
capturing the underlined word above winds up with the "afar\r\n" in the clipboard with your version. Getting rid of a linefeed at the beginning would drive me batty if I were to actually want that there (copying a blank line for some reason), but I could see why many people would want that in as well.
USA #23
And yet another fun fix, since not everyone has "/" set for the script prefix.
Accelerator ("Ctrl+C", GetAlphaOption("script_prefix").."Copy2()")


I still can't find anything under GetInfo, GetOption, or GetAlphaOption to check to see if all typing goes to the command window. I can't seem to find any other global options listed where scripting languages can check the values. Perhaps a GetGlobalOption function would help out with that issue. SetGlobalOption could be kind of annoying if two scripts for different worlds start to compete for who has control over the whole client, but there's no harm in checking what's been selected by the user.
Netherlands #24
Oooh, good catch on your turn with the spurious \r\n issue. I hadn't noticed that. The thing with the script accelerator I already took care of; hence the 'CopyScript:Copy' alias. That avoids the issue of what the seperator is all together.

Last of all, the reason I kill any leading new-lines is pretty simple. Take a look at the following 'example'

Courtyard of Valor.       X
A sturdy iron forge stands here, cold and dark. Clutching a
golden blade, a plated arm rises up from a massive square 
slab of iron as homage to the God of Valor. A solemn looking
chaplain rests the base of his tower shield on the ground 
and hefts his mace. Tossing her august mane, a sprightly 
white mare stands here.             X
You see exits leading north(closed), northeast(open),
east, southeast and west.


Suppose I want to drag this room description. Most of the time, I won't bother with going precisely to the start of the line at 'A sturdy iron force'. Rather, I'll click at the lower X, drag up and stop at the top X. Without the fix, this means I get stuck with an extra newline at the start of my copied paragraph (which always annoyed me with the built-in copying mechanism).
Amended on Wed 08 Aug 2007 02:32 PM by Worstje
USA #25
The alias does get around people not having set their script prefix yet. I'd just rather have a way for an Accelerator to call a script directly. Possibly have the same send to list as an alias.

And for the extra new line, as I said, I could see why many people would want it. I just expect the copy function to grab exactly what I highlighted. If I released the plugin, I'd probably have a flag that can be set to give people the option erase that extra newline or not. A good example of this is a script that I have to condense the output of dropping multiple items and putting them in or taking them out of a bag. A few people wanted a blank line after the output script to separate it and make it easier to read, but I like really condensed output. So I made the extra line an option to make everyone happy.
Amended on Wed 08 Aug 2007 03:16 PM by Shaun Biggs
Australia Forum Administrator #26
Quote:

I can't seem to find any other global options listed where scripting languages can check the values. Perhaps a GetGlobalOption function would help out with that issue.


Added GetGlobalOption to version 4.18.
Australia Forum Administrator #27
I have played with this a bit as the problem with Ctrl+C was beginning to get on my nerves. There was a problem with the earlier version, that if you copied a single letter on a line that ended with a linefeed, the linefeed ended up on the clipboard. Here is my amended version:


<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE muclient>
<!-- Saved on vrijdag, augustus 03, 2007, 2:06  -->
<!-- MuClient version 4.14 -->

<!-- Plugin "CopyScript" generated by Plugin Wizard -->

<!-- Amended slightly by Nick Gammon, from Worstje's version, on 17 Feb 2008 -->

<muclient>
<plugin
   name="Copy_Output"
   author="Worstje"
   id="a0df42a8e796d974f4364245"
   language="Lua"
   purpose="Allows you to use CTRL+C for the output window if 'All typing goes to command window' is turned on."
   save_state="n"
   date_written="2007-08-03 02:04:12"
   requires="4.00"
   version="1.0"
   >

</plugin>

<aliases>
  <alias
    match="^Copy_Output:Copy:1bb75c016bc3e2b9d4c292db$"
    enabled="y"
    regexp="y"
    omit_from_output="y"
    sequence="100"
    script="CopyScript"
  >
  </alias>
</aliases>


<!--  Script  -->

<script>
<![CDATA[

-- Thank you, Shaun Biggs, for taking your time to write the CopyScript
-- (formerly Copy2) function below. It was slightly altered by me to suit
-- my usage (wordwrapped lines and no \r\n at start of selection).

-- See forum: http://www.gammon.com.au/forum/bbshowpost.php?id=8052

-- some long alias that no-one will ever want to type
Accelerator ("Ctrl+C", "Copy_Output:Copy:1bb75c016bc3e2b9d4c292db")

function CopyScript(name, line, wildcs)

  -- find selection in output window, if any
  local first_line, last_line = GetSelectionStartLine(), 
                                math.min (GetSelectionEndLine(), GetLinesInBufferCount ())

  local first_column, last_column = GetSelectionStartColumn(), GetSelectionEndColumn()
  
  -- nothing selected, do normal copy
  if first_line <= 0 then
    DoCommand("copy")
    return
  end -- if nothing to copy from output window
  
  local copystring = ""
  
  -- iterate to build up copy text
  for line = first_line, last_line do
  
    if line < last_line then
      copystring = copystring .. GetLineInfo(line).text:sub (first_column)  -- copy rest of line
      first_column = 1
      
      -- Is this a new line or merely the continuation of a paragraph?
      if GetLineInfo (line, 3) then
        copystring = copystring .. "\r\n"
      end  -- new line
      
    else
      copystring = copystring .. GetLineInfo(line).text:sub (first_column, last_column - 1)
    end -- if
        
  end  -- for loop
  
  -- Get rid of a spurious extra new line at the start.
  if copystring:sub (1, 2) == "\r\n" then
    copystring = copystring:sub (3)
  end   -- if newline at start
  
  -- finally can set clipboard contents
  SetClipboard(copystring)
  
end -- function CopyScript
]]>
</script>

</muclient>

Amended on Sun 17 Feb 2008 02:40 AM by Nick Gammon
Australia Forum Administrator #28
This plugin is now available on the plugins page:

http://www.gammon.com.au/mushclient/plugins/

Specifically, right-click to download this file:

http://www.mushclient.com/plugins/Copy_Output.xml

Save that to disk and install it into MUSHclient using the File menu -> Plugins.
Australia Forum Administrator #29
Amended plugin to add:


math.min (GetSelectionEndLine(), GetLinesInBufferCount ())


It was failing if you did a "select all" because the selection end line was actually past the end of the buffer.
#30
Just popping in my two cents here. On older versions of MC, specifically a version 3.42 copy I had buried in the old corners of my computer, the behavior is just as originally described with the exception that the "all keys" tickbox was not checked. Shortcut keys would operate normally and normal typing would shift focus to the command window.

During a recent reinstall of my system, I downloaded a new copy of MC and ran into this same issue.
USA #31
Yeah, I finally found that out myself.
http://www.gammon.com.au/forum/?id=8901

No replies from Nick yet though.
Australia Forum Administrator #32
Ah yes, I just installed 3.42 and I agree it appears to do what you said. Why it does, I am not sure. Let me look into it.
Australia Forum Administrator #33
See: http://www.gammon.com.au/forum/?id=8901