http://www.perlmonks.org?node_id=605626

chargrill has asked for the wisdom of the Perl Monks concerning the following question:

Hello,

First, let me apologize, as I realize this may not strictly be a perl question, but perhaps an apache question or even a vim question. Having said that...

I'm trying to incorporate some syntax-colored code in a blog I'm writing, and stumbled across Text::VimColor. "Perfect!" I think - I just so happen to have my eyes trained to appreciate and be accustomed to the particular colorscheme I've selected for vim - "this should let everyone see my code the same way I do!"

Running a preliminary test or two from the command line to make sure I know how to use the module (and it worked great!), I felt a little confident that my syntax-highlighted HTML code would soon appear in my web browser.

Unfortunately, I was mistaken! I've boiled it down to the simplest of code:

#!/usr/bin/perl use strict; use warnings; use CGI q/:standard/; use Text::VimColor; my $perl=<<EOP; #!/usr/bin/perl use strict; use warnings; print "Hello, world!\n"; EOP # my vim is in /usr/local/bin $ENV{PATH}="/usr/local/bin:$ENV{PATH}"; my $vim = Text::VimColor->new( # line 18 string => $perl, ); print header(); print $vim->html;

... but much to my dismay, I keep getting these pesky few lines in my httpd-error.log:

vim returned an error code of '1' Vim wrote this error output: Vim: Warning: Output is not to a terminal Vim: Warning: Input is not from a terminal at /usr/local/www/data/path_to_cgi/html.cgi line 18

After reading some docs and man pages and a fair amount of googling, I see that vim likes to have a terminal. Running vi(m) via an ssh -c command produces similar errors, for which the fix is to pass the -t flag to ssh, to force the allocation of a psuedo-tty.

I'm willing to accept the fact that what I want to do just can't be done, however the fact that the existence of other modules that use Text::VimColor in an apache environment ... e.g. Apache::VimColor, Kwiki::VimMode ... forces me to think that maybe I'm just missing something.

Certainly, it's been a while since word of this module has appeared in the monastery ( On-the-fly all-languages syntax highlighting ) ... but I'm hoping that someone here may have run into this issue or at least offer some kind of solution, as I can't believe I'm the only one who's run into this issue.

N.B. I'm aware of the existence of Syntax::Highlight::Engine::Kate - and in fact have adopted that as my fall-back. It works fine for some code, however (perhaps understandably) it fails to syntax-highlight pieces of my .vimrc file :) I'm also looking for something capable of syntax highlighting bash, SQL, HTML, Perl, JavaScript, and .vimrc files, so the other syntax highlighting options (that I'm aware of) are out.

Update: I'd show my example of using a file which fails in exactly the same way with the same error message, but that's not quite as self contained as my above example.



--chargrill
s**lil*; $*=join'',sort split q**; s;.*;grr; &&s+(.(.)).+$2$1+; $; = qq-$_-;s,.*,ahc,;$,.=chop for split q,,,reverse;print for($,,$;,$*,$/)

Replies are listed 'Best First'.
Re: Text::VimColor in a CGI - possible?
by ikegami (Patriarch) on Mar 20, 2007 at 05:05 UTC

    As part of the process, vim is launched. Its STDIN and STDOUT are redirected to /dev/null, and its STDERR is redirected to a file. The contents of that file are discarded if vim returns successfully. However, vim is not exiting successfully in your case. vim claims an error happened by returning an exit code of 1. When a non-zero exit code is received, Text::VimColor croaks (displaying the exit code and the contents of the STDERR file). If vim is returning an error because of the warnings, then that's ... unfortunate. (And it's a bug in vim?)

    The best solution would be to replace Text::VimColor::_run with a version that creates pseudo TTYs. IPC::Run can help you there.

Re: Text::VimColor in a CGI - possible?
by toma (Vicar) on Mar 20, 2007 at 05:56 UTC
    After trying a few modules, I implemented a similar capability by writing a simple routine that called vim in backticks and had it generate colorized HTML. I use this in the documentation-generation phase of one of my software builds.

    It should work perfectly the first time! - toma
Re: Text::VimColor in a CGI - possible?
by quester (Vicar) on Mar 20, 2007 at 06:10 UTC
    This must be sensitive to the environment, because I don't get any errors running your example. This is on Knoppix 5.0 with Linux kernel 2.6.17, perl 5.8.8, vim 6.4.7, and Text::VimColor 0.11. Update: and thttpd 2.23beta1, rather than Apache. One oddity in your example:
    my $perl=<<EOP;
    
    really should be
    my $perl=<<'EOP';
    
    In your example, that only changes the \n in the print statement into a literal line feed. In a bigger test case variable substitution would remove all the variable names in the quoted script.
Re: Text::VimColor in a CGI - possible?
by chargrill (Parson) on Mar 20, 2007 at 16:45 UTC

    I think I stumbled onto the solution, partly due to the teddy bear principle, partly due to the answers from ikegami, toma. and quester.

    I think I was reading the documentation for vim a little incorrectly. The docs state:

    -T {terminal} Tells Vim the name of the terminal you are using. Only required when the automatic way doesn't work. Should be a terminal known to Vim (builtin) or defined in the termcap or terminfo file.

    Late last night I tried passing that argument with a known good termtype (xterm) and lo and behold, it worked!

    To bring this 'round back to the perlish solution (and in case anyone in the future runs into this), this is accomplished with the following modification:

    my $vim = Text::VimColor->new( string => $perl, vim_options => [ qw( -RXZ -i NONE -u NONE -N -T xterm ) ], );

    (Where qw( -RXZ -i NONE -u NONE -N ) is the default for vim_options, as according to cpan::Text::VimColor).

    And for the record, I'm using vim 7 - perhaps (inferring from quester's reply) vim 7 handles the need for a terminal differently.



    --chargrill
    s**lil*; $*=join'',sort split q**; s;.*;grr; &&s+(.(.)).+$2$1+; $; = qq-$_-;s,.*,ahc,;$,.=chop for split q,,,reverse;print for($,,$;,$*,$/)
Re: Text::VimColor in a CGI - possible?
by Anonymous Monk on Mar 20, 2007 at 04:43 UTC
    ... forces me to think that maybe I'm just missing something.

    You're missing the obvious, copy what Apache::VimColor is doing (use file, not string).

      When using string, a temporary file is created with the content of the string. Then, strings and files are handled identically. That's not the solution.