need to write a script to change file format from dos to unix - vim

I have to make a script using vim which opens a file, set the fileformat=unix, and then save the file and exit. Could you please help? Thanks

First, check out whether you have a dos2unix or dos2ux command; it already does this for you.
With Vim, this should do the job:
$ vim -c "wq ++ff=unix" filename
This one in-lines the fileformat change with the :w command; of course, you can also do this separately via -c "set ff=unix".
Notes
You can also do this via a variety of tools, e.g. sed, perl, ...; Vim is a quite heavyweight alternative.
This still starts up a full, interactive Vim instance. Have a look at this answer which additional command-line arguments can turn Vim into batch mode.

Related

vim interpret argument with colon(s) as filename:line:column

Is it possible to configure VIM in a such way that if I type
vim filename:123:89
it opens file filename goes to line 123 and column 89?
If not through VIM maybe with a hack for the shell?
You can install the file-line plugin to open a file to the line and column specified after the filename. (github mirror)
From the Readme on github
When you open a file:line, for instance when coping and pasting from
an error from your compiler vim tries to open a file with a colon in
its name.
Examples:
vim index.html:20
vim app/models/user.rb:1337
With this little script in your plugins folder if the stuff after the colon is a number and a file exists with the name especified before the colon vim will open this file and take you to the line you wished in the first place.
I'm not sure how to skip to the column, but I've wanted the same feature for ages, so I just hacked up the "jump to line" functionality. In your .bashrc, set
VIM=$(which vim)
function vim {
local args
IFS=':' read -a args <<< "$1"
"$VIM" "${args[0]}" +0"${args[1]}"
}
This splits the argument to Vim by :, then constructs a command line of the form
vim <filename> +0<line>
The +0 is a hack to make sure the default line number is zero.
(If you're not using Bash, you can adapt this into a script and put it in your path, or translate it to your favorite shell language. To edit filename:with:colons, use $VIM.)
I've been using the file-line plugin, but it has a few open issues, and breaks some other vim plugins. So I went fishing for a better solution. Here it is:
function vim() {
local first="$1"
case $first in
*:*)
shift
command vim ${first%%:*} +0${first##*:} $#
;;
*)
command vim $#
;;
esac
}
Limitations:
bash only
Only parses first argument, whereas vim +X parses the first file argument. A more complex version could easily be made with proper command line parsing.
Advantages:
doesn't break other vim plugins
you could easily use $EDITOR and use this with emacs for instance.
compared to Fred's answer it doesn't use IFS/read to parse the argument but uses bash parameter expansion.
also sends in the remaining argument, which might occasionally be necessary.

Can I write a script to tell me which files are currently being edited in vim?

I'm using tmux with many windows, and I frequently lose track of which files I'm editing in vim. I'd like to have another shell open that runs a script that tells me the paths of files that vim is currently editing.
I'm running Mac OS.
The way I would tackle the problem is to query all remote Vim processes for their opened buffers. You can use Vim's clientserver functionality for that. The GVIM server names are usually sequentially named: GVIM, GVIM1, ...; for terminal Vim, you'd have to name them with the --servername argument (e.g. via a shell alias).
You can then query the list of open files via the --remote-expr argument. A simple expression to loop over all listed buffers (like what the :ls command shows) is:
map(filter(range(1, bufnr('$')), 'buflisted(v:val) && ! empty(bufname(v:val))'), 'bufname(v:val)')
As you can see, it's a bit involved and might affect your workflow of launching Vim. Think hard whether you really need this!
That I know of there is no way to get every open vim buffer from an external process. Instead of using separate tmux layouts and a separate instance of vim to edit multiple files, you could have one instance of vim and edit multiple separate files using :split and :tabnew. Then in that vim instance you can use :ls to see the paths of all open files relative to the current working directory. :pwd also works.
If this isn't your style and you'd still like to use vim in separate layouts, you can use ps to see the arguments to each vim process and check the cwd of these processes. Something like:
paste <(pgrep vim | xargs pwdx) <(pgrep vim | xargs ps -o %a | sed 1d)
Note that if you use multiple buffers in vim the above won't quite work because it will only list the arguments given to each vim command and not list the actual buffers.
You could tweak around with the piped commands ps -eF | grep vim for your script.
At the end of each line, of the result, you'll see you the different processes dealing with anything related to 'vim'. Therefore you'll find which files are currently being edited by vim('vim foo.txt' for instance), as well as 'grep vim' that was being active to get this result. To have a pretty output, you'd have to filter all of these with a script.
I hope this will help you.

Why doesn't "history | vim" work?

I want to use the Vim to see the result of history (not in the shell). I think history | vim will work (use the result of history as the input of vim), but it returns with:
$history | vim
Vim: Warning: Input is not from a terminal
Vim: Error reading input, exiting...
Vim: Finished.
Can anybody explain this?
By piping into vim, you are changing the standard input stream. Because vim is an interactive program, it requires the standard input to be the console.
If you want to view in vim, you should tell it you are reading the file from stdin (by supplying the argument -):
history | vim -
Alternatively, you could just use more or less:
history | more
history | less
These latter two are preferable. If you pipe into vim, it will see your "file" as having modifications, and so you can't quit with a straight :q command. Instead you have to force quit by :q!, which is a bit clunky.
On the other hand, you can exit more or less just by typing q. Have a look at the man-page for these two programs. You'll use them a lot.
As recommended by Russell Silva in the comments, you can open vim in read-only mode when you read from stdin. Just supply the -R argument. Then you can quit normally without needing the override:
history | vim -R -
Apart of vim -, you may try bash command substitution like:
vim <(history)
See also:
How to write whole buffer to standard output from the command line? at Vim SE
How to edit files non-interactively (e.g. in pipeline)? at Vim SE
This happend to me trying to send it to background console (&)
One script used:
...
vi "$file" &
...
# change to just:
vi "$file"
removing &, problem went away.

Use vim as command line tool?

is there a way to use vim as a command line tool? What I mean is, use it from the console (without opening a ncurses window) to run vim commands on file and save them. I need this because I usually run through all my files and do 'gg=G' to auto indent them.
Thanks
Here are listed two different ways to do that:
by using vim -s file-containing-commands file-to-edit
by using vim file "+:firstcommand" "+:secondcommand" ...
The first solution needs a file to be written beforehands; the second solution will launch vim and execute the commands, without leaving vim; you'll have to do that yourself, for instance adding a last command '+:x'

How to check if it's still in Vim shell mode

In vim, type :sh will switch to shell, and exit can exit the shell and get back to vim. Is there any command to check if it's in vim shell mode? So that I won't accidentally vim to open the same file again. I want to avoid below scenario:
vim myfile > :sh > exit > vim myfile // get warning of another vim instance is editing the same file
These are the normal scenario:
vim myfile > :sh > exit // keep editing
vim myfile > :wq > vim myfile // keep editing
In addition to #a3nm answer, what you can do is
use pstree -h: it will output process tree with current branch highligted and all you need to check is whether there is vim in the highlight.
Another possibility is ps t: it will show all processes using the current terminal and should show vim in a list when you are inside :sh. ps -oargs t may be more useful in case you want to know arguments you ran vim with.
These methods are more reliable because VIMRUNTIME, VIM and MYVIMRC environment variables may be overrided by you in order to do some customizations (BTW, they are defined by vim for use in vimscripts, not by :sh). They also work for other processes that allow you to run a subshell, but do not define any environment variables.
I would also suggest to consider using <C-z> in normal mode or :suspend/:stop in Ex because these use shell vim was launched from instead of creating new. This behavior gives you access to history of commands you typed before running vim and also makes you able to write more complex and time-consuming shell configuration without needing to wait every time.
In case you use <C-z> both methods still work, but first method won’t highlight vim because it will be at the same level (has the same parent) as pstree itself, likely just below or above pstree in graph. This also enables third method: jobs shell builtin.
In order to restore from <C-z> you should use fg (a single % in zsh and bash also works) which is less to type then exit (but more then <C-d>).
The :sh command in vim seems to define the VIMRUNTIME, VIM and MYVIMRC environment variables, so you can just check if they are defined. To do so, you can run echo $VIM, for instance, which should return an empty line in a normal shell and something like /usr/share/vim in a shell run from vim.

Resources