How can I use vim in a pipeline to colorize text?
Asked Answered
J

6

18

I'd like to have a command I can insert into a command pipeline that adds color escapes to its input according to vim's syntax highlighting capabilities.

For example:

cat somefile.js | vim - <???> | less

The resulting text would be that of somefile.js, but colorized according to how the current vim configuration would do it in-editor.

It occurs to me that this must be possible. I agree that the example up there isn't what a sane man might call exactly useful, but that doesn't mean the idea never is.

Jackinthepulpit answered 30/10, 2013 at 1:30 Comment(3)
There is a wide variety of software that does this, pygmentize is one. I've never seen vim do it.Sporocyst
Hrm.. This thread, though lowly rated, seems to suggest trying to use vim as a filter at all (essentially what I'm looking for here), is just a bad idea from the get-go. Is that true? Is this idea just a non-starter?Jackinthepulpit
+1 for out-of-the-box thinking.Rowen
R
5

I think your idea has one basic flaw: that nobody ever thought about allowing such a thing.

Clearly vim is capable of doing syntax highlighting. But I'll bet you an ice cream cone that if you can manage to get vim to stream text through and process it, that you won't like the results.

Consider what happens when you pipe text through more (or less if you prefer). When it goes to the terminal, these programs display one screenful and wait for you to hit the space bar. But if you redirect stdout to some other place than the terminal, these programs notice this and simply copy their input to their output unchanged.

If vim doesn't notice that you are piping text through, it is likely to send cursor-movement commands that you probably don't want in your output. If vim does notice, it is likely to just pass the text, and not syntax-color it. Only if vim does do the syntax-coloring but does not inject cursor-movement stuff will your idea work.

You could try it. Here's an answer that discusses piping stuff through vim:

Execute a command within Vim from the command line

But I say why not pipe your text through a program that was designed and intended to have text piped through it? Pygments can colorize every major programming language and markup format.

http://pygments.org/

The major advantage I see for your idea: you can customize the way vim does syntax coloring, get it the way you want it, and then also use vim to process your text. But it's probably not that hard to customize Pygments, and it might even be satisfactory out of the box, in which case it would definitely be the easiest way to go. And Pygments not only has ANSI sequence output, it also has HTML output, RTF, LaTeX, etc. So if you get Pygments working the way you want it to, it should be able to output whatever output format you need; vim will only have the ANSI sequence one.

Rowen answered 30/10, 2013 at 1:54 Comment(2)
You're right -- vim isn't designed as a filter, so use something that is. You're also right that the main motivator here is to colorize text the way I've set up vim to do so. But that's hardly a critical need -- I just wanna. :) I'll check out Pygments. Thanks for the recommendation. And thanks for a good explanation as to why I wasn't getting far with my approach. Cheers.Jackinthepulpit
Okay, pygmentize is pretty damn cool. I wish it had better lexer auto-detection, but then I could use a project..Jackinthepulpit
S
3

There's a Perl module called Text::VimColor that I've heard will do kinda what you're looking for.

http://search.cpan.org/dist/Text-VimColor/

But let me ask this: Why do want it to go through less? Why not use vim as a perfectly good file viewer? view - will read from standard input in read-only mode.

Sexual answered 30/10, 2013 at 2:53 Comment(1)
The idea is not that it go specifically through less, but that I can have something that applies syntax highlighting to text in such a way that I can process it further on the command line. Like, say, if I want to do cat file.js | grep function | <something>, it helps if <something> shows me highlighting, for easier readability.Jackinthepulpit
C
3

Use vimcat !

wget -O /usr/local/bin/vimcat "https://www.vim.org/scripts/download_script.php?src_id=23422"
chmod 755 /usr/local/bin/vimcat
vimcat /etc/passwd

See also: https://www.vim.org/scripts/script.php?script_id=4325

Coppage answered 21/3, 2022 at 1:6 Comment(1)
Perfect, works exactly as I want (upvote from me)Isborne
X
1

https://gist.github.com/echristopherson/4090959

Via https://superuser.com/a/554531/7198.

Tried on /etc/passwd and it works surprisingly well!

Xeric answered 30/10, 2013 at 3:44 Comment(0)
U
1

This might be what you're after

cat filename.sh | vim - -c 'syntax on; syn=bash'

This is ugly, but you could alias this:

alias vim.sh="vim -c 'syntax on; syn=bash'"

Then use like this:

cat filename.sh | vim.sh -
Unexpressed answered 11/2, 2017 at 11:11 Comment(4)
Doesn't work for me, it just opens vim as usual. FWIW, I am not quire sure which part in your code supposed to make vim exit. The - makes it read from stdin, and -c syntax on; syn=bash seems to just enable syntax highlight.Stocky
@Stocky need to use command like cat script.sh 2>&1 | vim - -c 'set ft=sh | set bt=nofile' . Explanation of it in my answer. Exit from vim with :q.Efficiency
@AntonSamokat judging by the question and my comment, I wanted vim to act like an intermediate layer between the input and less command, which isn't exactly what your answer does.Stocky
@Stocky In Russian we have proverb: Вам шашечки или ехать? English version of it is like: Do you look for the book or the cover? If I understand you correctly you want to find a way to pipe vim's highlighting to less. Why do you need this? Why not to open and highlight stdin either in vim or in less directly? I showed how this can be done with vim. How to open and highlight stdin with less shown here: How to syntax highlight via Less. Is it what you were looking for?Efficiency
E
0

Solution for opening and highlighting stdin in vim

vim can be used in a similar way as less with the following command example:

cat script.sh 2>&1 | vim - -c 'set ft=sh | set bt=nofile'
  • vim - opens in vim piping stdin, rather than file
  • vim -c 'set ft=sh | set bt=nofile' — opens vim with specified options. | is options delimiter.
  • ft (or filetype)=ext — specifies file type for corresponding highlighting. sh for shell syntax, json for json and so on.
  • bt (or buftype)=nofile — opens vim with the option that will prevent confirmation for further quitting from vim (E37: No write since last change (add ! to override)). This allows to exit from vim just with :q command as with quitting from less.
  • 2>&1 — shows corresponding error in vim if it occurred. For example, cat: capture.sh111: No such file or directory if the file is missing.

For convenient quit from vim you can add qq and/or Ctrl+q shortcuts to ~/.vimrc:

" quit from vim by qq or by Ctrl+q
nnoremap qq :quit<cr>
nnoremap <silent> <C-Q> :q<CR>
inoremap <silent> <C-Q> <Esc>:q<CR>
vnoremap <silent> <C-Q> <C-C><Esc>:q<CR>

Solution for opening and highlighting stdin in less: How to syntax highlight via Less

Additional helpful answer and comments under it: less command and syntax highlighting

Efficiency answered 10/7, 2024 at 14:23 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.