0

Is there some way to display an identifier as something else? Imagine the following setup:

You have a readme file:

* <<123456>>
* <<789078>>

This readme file is inside of a directory

├── README.txt
├── 123456.txt
└── 789078.txt

But now instead of displaying 123456, it would instead the first line of the file 123456.txt. I now a decent amount of Vimscript, but I don't know of any way to accomplish this, and I'm led to believe it's impossible. I know of conceallevel, but that doesn't really help with it...

1
  • a hack would be, to use folding (even for single lines) and make the foldtext display the first line of the corresponding line. You would lose the ability to syntax highlighting. Another possibility would be to use custom match expressions, that would conceal the filename and add the first line of the corresponding line Commented Jan 29, 2019 at 7:40

1 Answer 1

1

I don't think you said whether a "destructive" approach was acceptable or not. That is, the change is not superficial in this solution (although you could "undo" out of it). In case a non-destructive option is not forthcoming I offer this...

If you're in a Unix-like environment1 (Linux, Mac, Windows+Cygwin) then you can send output from an appropriate shell command through a Vim filter like so...

:g/\* <<[^>]\+>>/ exe '.!head -1 "' . substitute(getline("."), "^\* <<\\([^>]\\+\\)>>", "\\1.txt", "") . '"'

Every line with the pattern you indicated will get processed so the proper filename is generated and then that is sent through a command (head -1 in this case) to get the first line. Thanks to the filter :.! the result will replace the current line.

You can either run this manually (probably want to map it to a shortcut, though) or you can put it in an autocommand if there's a particular file type(s) that you always want to apply it to.

I'll break it down in a bit more detail later.

1If you're on straight Windows and know some Windows console command that extracts the first line of a file this can be made to work there, too.

Update: Got to thinking how the above could be made non-destructive. Christian Brabandt mentioned use of conceal in a comment and that's where my thinking is, too.

The change to the above is to append the first line of text rather than have it replace the original line. The original part is hidden with conceal.

set conceallevel=3
syn match Conceal /^\* <<[^>]*>><</hs=s+2,he=e-2 conceal
" would prefer to do this with a single global but for now...
g/\* <<[^>]\+>>/ s/$/\='<<' . system('head -1 "' . substitute(getline("."), "^\* <<\\([^>]\\+\\)>>", "\\1.txt", "") . '"')
g/\* <<[^>]\+>>/ norm! gJA>>

(BTW, upon rereading the question I think the idea is to have the first line of text just replace the text between << >> rather than replace the entire line. This part assumes that's correct.)

To reverse the effect just use a global command to delete everything from the second "<<" to the end of the line. I can show those commands but I'm waiting to hear from OP if this is even what they have in mind.

1
  • @hgiesel There are a few reasons why folks put in the time/effort to answer hard questions here. Some people like rep. Some get satisfaction helping people in need of help. Some like both. When you flat out ignore someone's effort, as you've done here and at least one other recent question, chances are you're depriving them of those points or that satisfaction or whatever it may be. Fortunately, that doesn't happen that often because, for one, it's inconsiderate as hell. It also reduces your chances of getting help in the future. (Given amt of rep you have yourself how do you not grok this?)
    – B Layer
    Commented Feb 24, 2019 at 20:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.