2

I've run into a strange problem with Ruby that I can't explain. I have the following script that grabs whatever code is currently in the clipboard, runs it through a syntax highlighter, then puts the new version BACK into the clipboard:

#!/usr/bin/ruby1.9.1

require 'coderay'

language = "auto";
if(ARGV.length > 0)
    language = ARGV[0];
end

print("Using language: #{language} \n");

codeToHighlight = `xsel --clipboard`

highlightedCode = CodeRay.scan(codeToHighlight, language.intern()).div

IO.popen("xsel --clipboard", mode='w') do |io|
  io.write highlightedCode
  io.flush
end

The odd part is that if I run it directly within a terminal, it works fine. If I run it via "xterm -e", however, it doesn't work. I found this thread on another site that asked the same question, but the person never got an answer: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/138423

That person found that if they added a pause at the end of the script like so...

10000.times do
   puts ""
end

...it works. Why is this? Is there a way to fix this? I tried rewriting the script so that the popen returns an IO object and I could manually call close, but that doesn't make a difference.

Matthew
  • 685
  • 8
  • 18
  • 1
    I've determined that, whatever the problem is, it's in xsel. I tried adding a line to the end of the file (without the crazy puts "" loop) that just dumps the highlighted code to a file, and it's contents are right no matter _how_ I run the script. I tried xclip instead and it seems to work in more situations, though I've only ever gotten the primary (aka, middle-click) clipboard to work with it. xclip works when called from another script where xsel wouldn't, but xclip still doesn't work via xterm -e either. – Matthew Feb 23 '11 at 14:14

1 Answers1

1

How about if you execute it with gnome-terminal -e instead of xterm -e?

UPDATE:

OK, here is my best guess. You know how if you send a terminal program to the background (either with & after the command or with ctl-z) and then you close the terminal it kills the program, right? Well, xsel forks a child process to write to the clipboard, but it must be getting killed when the ruby wrapper script finishes and and xterm closes.

That would explain why the pause at the end allows it to work - it just gives enough time for the child process to finish before the terminal quits. It also explains why it works when run manually - you leave the terminal open long enough for the child process to finish.

Try adding the -n option to your xsel command, and I bet it works. -n keeps xsel from forking.

James
  • 385
  • 3
  • 11
  • Nope, that doesn't seem to work either...with xclip _or_ with xsel. Thanks anyway, though. I rarely use this script anymore so it's not too big of a deal but it would be nice to know why it's doing this just for the sake of the knowing. – Matthew May 09 '11 at 13:09
  • ah, shucks. My thinking was maybe it was an issue with the terminal emulator and _maybe_ you were opening gnome-terminal when running it manually. – James May 10 '11 at 16:07
  • Sorry it took me so long to accept this. I hadn't used the script for a long time and so I did notice you'd updated your answer. I can't duplicate it now (different versions of everything, right?) so I'll go ahead and accept since your answer has a valid explanation for the behavior. – Matthew Jan 30 '12 at 22:43
  • ah man, now I wish I knew for sure if I was right or not. Oh well, thanks for the acceptance! – James Mar 01 '12 at 22:46
  • I know, right? Sorry about that. I really appreciate your help, though. – Matthew Mar 02 '12 at 15:16