Vim: How to open a file whose name is determined by running a shell command - linux

Suppose that I have a command, say find ABCD | grep text1 which outputs full-path of a file to be opened. I know I can send this output to vim using xargs and open the file, but this is possible only in command line.
How can I do this from inside vim editor?

Assuming COMMAND returns exactly the path of your file, then something like this should be ok from the command line:
$ vi $(COMMAND)
and this should be ok from within vim:
:e `COMMAND`

Related

Vim, custom tab and vertical split organization on open

Say the files in my working directory are src/example.c src/second.c src/third.c include/example.h include/second.h include/third.h.
I want to open vim in a way that automatically opens three tabs (example, second and third), where each tab contains a vertical split screen between a .c and corresponding .h file. Like the following commands would.
:tabnew include/example.h | vs src/example.c
:tabnew include/second.h | vs src/second.c
:tabnew include/third.h | vs src/third.c
Is there a way I can make a special script that will do this when I open vim?
It is safe to assume files will have the same name.
Ideally, this would happen from a shell script rather than modifying my .vimrc, if that is possible.
well if you want to do that, you clearly need a way to execute vim commands from your shell. Lets see if the vim application supplies that, by using the help command which we should ask first for every shell command:
?> vim --help | grep cmd
--cmd <cmd> Execute <cmd> before any config
+<cmd>, -c <cmd> Execute <cmd> after config and first file
So all that is needed is to chain these commands:
vim -c 'tabnew include/example.h' -c 'vs src/example.c' -c 'tabnew include/second.h' -c 'vs src/second.c' -c 'tabnew include/third.h' -c 'vs src/third.c'
as #Enlico pointed out in the comment, you should use edit or e instead of tabnew in the first command, else you will get 4 tabs. But I used your commands so you can see how easily you would have been able to solve this by reading the --help output.

Cygwin terminal input disappearing after quitting vim

Using Cygwin, I tried creating and editing a file in Vim:
touch test | vim
This is obviously a mistake; something like vim "$(touch test)" has a better chance of actually working. Nevertheless, this command throws the error:
Vim: Warning: Input is not from a terminal.
And after this, Vim opens and I exit the program with :q. Any subsequent commands I enter into the terminal are hidden from view until I restart Cygwin.
Why is this?
You don't understand what does a pipe | do in shell.
Pipe will take the pervious command's stdout as stdin to next command, in a subshell.
Your touch foo doesn't generate any output, what do you expect to happen? same for vim "$(touch test)".
If you want to create a file and open it in vim in one shot, you can try:
touch foo && vim foo
If you want to edit it with vim anyway, actually, you can simply just:
vim foo
then save the buffer after your editing.

store all the data in terminal to text file by tee command or equivalent tool

I learnt that a tee command will store the STDOUT to a file as well as outputs to terminal.
But, here the problem is every time I have to give tee command, for every command I give.
Is there any way or tool in linux, so that what ever I run in terminal, it should store the command as well as output. (I used tee command in MySQL, where it will store all the commands and outputs to a file of that entire session. I am expecting a tool similar to this.)
Edit:
When I run script -a log.txt, I see ^M characters as well as ^[ and ^] characters in log.txt file. I used various dos2unix, :set ff=unix, :set ff=dos commands, but they didn't helped me in removing these ^[, ^] characters.
Is there any method, I can directly get the plain text file (with out these extra chars).
OS: RHEL 5
You can use script command which writes everything on file
script -f log.txt
you could use aliases like such alias ls="ls;echo ls >>log" so every time you run ls it runs echo ls >>log too.
But script would probably be better in this case, just dont go into vi while you are in script.

Execute an external command on startup

I use vim regularily for all my needs. On very rare occasions I need to open binary files via a hex editor look, and for that I start vim on the file and then run it through xxd via the command: %!xxd
My question is, how can I have my command line open a file directly in this manner, if the option exists? something like typing: gvimbin <file> and then it opens in the right manner.
Edit: to be clear, I am looking for a complete solution that allows running vim exec commands on startup.
You can execute commands after Vim startup by passing them via -c:
$ gvim -c '%!xxd' file.bin
This can even be simplified so that when Vim is started in binary mode (-b argument), it'll automatically convert the file. Put the following into your ~/.vimrc:
if &binary
%!xxd
endif
and start with:
$ gvim -b file.bin
Also have a look at the hexman.vim - Simpler Hex viewing and editing plugin; it makes it easier to deal with hexdumps.
Like Felix say:
xxd <file> | vim -
You can put this into script for example vimxxd:
#!/bin/sh
xxd $1 | vim -
and use like: vimxxd file.txt

Open Vim from within a Bash shell script

I want to write a Bash shell script that does the following:
Opens a file using Vim;
Writes something into the file;
Saves the file and exits.
echo 'About to open a file'
vim file.txt # I need to use vim application to open a file
# Now write something into file.txt
...
# Then close the file.
...
echo 'Done'
Is that possible? I found something called Vimscript, but not sure how to use it.
Or something like a here document can be used for this?
Update: I need to verify that Vim is working fine over our file
system. So I need to write script that invokes Vim, executes some
command, and closes it. My requirements do not fit into doing stuffs
like echo 'something' > file.txt. I got to open the file using Vim.
ex is the commandline version for vi, and much easier to use in scripts.
ex $yourfile <<EOEX
:%s/$string_to_replace/$string_to_replace_it_with/g
:x
EOEX
Vim has several options:
-c => pass ex commands. Example: vim myfile.txt -c 'wq' to force the last line of a file to be newline terminated (unless binary is set in some way by a script)
-s => play a scriptout that was recorded with -W. For example, if your file contains ZZ, then vim myfile.txt -s the_file_containing_ZZ will do the same as previously.
Also note that, invoked as ex, vim will start in ex mode ; you can try ex my_file.txt <<< wq
You asked how to write "something" into a text file via vim and no answer has necessarily covered that yet.
To insert text:
ex $yourfile <<EOEX
:i
my text to insert
.
:x
EOEX
:i enters insert mode. All following lines are inserted text until . is seen appearing by itself on its own line.
Here is how to search and insert as well. You can do something such as:
ex $yourfile <<EOEX
:/my search query\zs
:a
my text to insert
.
:x
EOEX
This will find the first selection that matches regex specified by :/, place the cursor at the location specified by \zs, and enter insert mode after the cursor.
You can move \zs to achieve different results. For example:
ex $yourfile <<EOEX
:/start of match \zs end of match
:a
my text to insert
.
:x
EOEX
This will change the first occurrence of "start of match end of match" to "start of match my text to insert end of match".
If you want to allow any amount of whitespace in your searches between keywords, use \_s*. For example, searching for a function that returns 0: :/\_s*return\_s*0}
If you are wanting to see the work being done inside vim or gvim you can use --remote-send
gvim --servername SHELL_DRIVER
bashpromt# cat mybash.sh
#!/bin/bash
echo "about to open $1"
gvim --servername SHELL_DRIVER $1 #I need to use vim application to open a file
#now write something into file.txt and close it
gvim --servername SHELL_DRIVER --remote-send '<ESC>i something to the file<ESC>:wq<CR>'
echo "done."
This will be slow but will do what you want it to.
First we open a gvim in which we can open all of our files (for efficiency)
With the first gvim line we open the file in the previously opened gvim.
On the second gvim line we send a command to the previously opened instance of gvim (with the desired file still open).
The command is as follows:
<ESC> - get out of any mode that gvim might have been in
i something to the file - go into insert mode and type " something to the file"
<ESC> - exit insert mode
:wq - write the file and quit vim
Recently, I have answered a similar question, “Automated editing
of several files in Vim”. May be the solution that I describe there
will satisfy your needs.

Resources