LinuxQuestions.org
Visit Jeremy's Blog.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 10-08-2011, 12:30 PM   #1
porphyry5
Member
 
Registered: Jul 2010
Location: oregon usa
Distribution: Slackware 14.1, Arch, Lubuntu 18.04 OpenSUSE Leap 15.x
Posts: 518

Rep: Reputation: 24
Vimscript: using substitute() on a variable


If I paste the output of :ls into a buffer, the command
Code:
:%s/.*\(\".*\"\).*/\1/
reduces that output to just the file paths. Wanting to achieve that result in a variable, I did
Code:
:redir => x|silent :ls|redir END
:let y = substitute(x, ".*\(\".*\"\).*", "\1", "g")
which accomplished absolutely nothing, y is identical to x. I've tried umpteen variations on that substitute command, getting only the same result, or a bunch of error messages. How should I be specifying it?

I was following the examples used in :h substitute() which both use ". But if I do
Code:
:let y = substitute(x, '.*\(".*"\).*', '\1', "g")
I do get output, but only the match to the last line in the variable x. I tried concatenating the output by
Code:
:let y = y . substitute(x, '.*\(".*"\).*', '\1', "g")
but that just appended the same output again to variable y. But the question has changed. How do I get every line of output from that substitute() command?

Last edited by porphyry5; 10-08-2011 at 02:49 PM. Reason: partial progress
 
Old 10-08-2011, 08:50 PM   #2
rch
Member
 
Registered: Feb 2003
Location: Santa Clara,CA
Distribution: Mandriva
Posts: 909

Rep: Reputation: 48
I assume you surely meant :!ls. What I don't get is the regex that you are using. So, you are matching anything .* followed by quotation followed by anything .* followed by quotation and then match anything (.*). You are substituting whatever you are getting between the quotation marks. Just out of curiosity, could you please give me what/ how are you reducing the output from !ls to file paths?


Quote:
Originally Posted by porphyry5 View Post
If I paste the output of :ls into a buffer, the command
Code:
:%s/.*\(\".*\"\).*/\1/
reduces that output to just the file paths. Wanting to achieve that result in a variable, I did
Code:
:redir => x|silent :ls|redir END
:let y = substitute(x, ".*\(\".*\"\).*", "\1", "g")
which accomplished absolutely nothing, y is identical to x. I've tried umpteen variations on that substitute command, getting only the same result, or a bunch of error messages. How should I be specifying it?

I was following the examples used in :h substitute() which both use ". But if I do
Code:
:let y = substitute(x, '.*\(".*"\).*', '\1', "g")
I do get output, but only the match to the last line in the variable x. I tried concatenating the output by
Code:
:let y = y . substitute(x, '.*\(".*"\).*', '\1', "g")
but that just appended the same output again to variable y. But the question has changed. How do I get every line of output from that substitute() command?
 
0 members found this post helpful.
Old 10-09-2011, 04:54 AM   #3
porphyry5
Member
 
Registered: Jul 2010
Location: oregon usa
Distribution: Slackware 14.1, Arch, Lubuntu 18.04 OpenSUSE Leap 15.x
Posts: 518

Original Poster
Rep: Reputation: 24
Quote:
Originally Posted by rch View Post
I assume you surely meant :!ls. What I don't get is the regex that you are using. So, you are matching anything .* followed by quotation followed by anything .* followed by quotation and then match anything (.*). You are substituting whatever you are getting between the quotation marks. Just out of curiosity, could you please give me what/ how are you reducing the output from !ls to file paths?
No, I did not mean :!ls; that accesses the linux ls, which, at least on my system, delivers only the terminating name. I meant vim's ls, which, among other things, returns "the path used to open that file in vim". As I only ever use a single instance of vim, always started the same way in the same working directory, the file paths returned by vim's ls are sufficient for my purpose. The regex, used in the :substitute command, delivers the enquoted file path; used in the substitute() function it returns only the last occurrence of such.

Following is my solution.
The variable x contains
Code:
1 #    "~/Session.vim"                line 5
2      "~/.vimrc"                     line 34
3      ".vim/vscripts/makesess.vim"   line 4
4      "~/Documents/vimcht"           line 62
5      "~/.fluxbox/startup"           line 5
6      "~/Documents/Notes"            line 2604
7      "~/Documents/bashcht"          line 21
8 %a   "junk"                         line 10
By my reading of :h /[], particularly "...Without the "\_" or "\n" the collection does not match an end-of- line...", then
Code:
:let y = ""
:let y = substitute(x, '[.]*\("[.]*"\)[.]*', '\1', "g")
should have done the job. But it delivered
Code:
"junk"
just as it did without the [].
I then tried
Code:
:let y = ""
:let y = substitute(x, '[^\n]*\("[^\n]*"\)[^\n]*', '\1', "g")
and got exactly the same result.

Clearly vim does not use the actual newline character internally, for variables as well as registers. So it treats a variable as a single line. Which led me to this solution
Code:
:let y = substitute(x, '[^"]*\("[^"]\+"\)[^"]*', ':tabe \1\n', 'g')
yielding
Code:
:tabe "~/Session.vim"
:tabe "~/.vimrc"
:tabe ".vim/vscripts/makesess.vim"
:tabe "~/Documents/vimcht"
:tabe "~/.fluxbox/startup"
:tabe "~/Documents/Notes"
:tabe "~/Documents/bashcht"
:tabe "junk"
Then I discovered that vim is not bash, and won't write a file from a variable, only from a list. So my final solution became
Code:
:redir => x|silent :ls|redir END
:let ylist = eval('[' . substitute(x, '[^"]*"\([^"]\+\)"[^"]*', '":tabe \1", ', 'g') . '""]')
:call writefile(ylist, "/home/g/Session.vim", "")
This yields a Session.vim that will open all the files that were open when Session.vim was created.

Last edited by porphyry5; 10-09-2011 at 05:32 PM. Reason: Added final solution
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
problem while comparing awk field variable with input variable entered using keyboard vinay007 Programming 12 08-23-2011 12:44 AM
[SOLVED] substitute variable in bash dinakumar12 Linux - Newbie 8 03-21-2011 03:44 AM
bash: substitute parameter in a quoted string, stored in another variable GamerX Linux - General 5 01-31-2010 08:48 PM
Script to copy specific directory based on variable to folder with that variable name fluxburn Programming 7 01-07-2010 07:59 PM
AWK a variable Ouptut to a new variable and using the new variable with the old one alertroshannow Linux - Newbie 4 02-16-2009 12:08 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 04:17 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration