what is the load order of scripts when you start up vim? - vim

If you start up vim with something like this:
vim -S myscript.vim file.txt
What is the load order of scripts? Does myscript.vim get loaded after or before ~/.vimrc.
If you pass in vimscript commands to vim directly on the command line, when do they get executed relative to sourced and default vimscripts?

I believe vimrc is always first. You can run :scriptnames to get a list of sourced scripts in order in which they were first sourced in your Vim instance.

The help entry is way too long to post here, but it lists the order of everything that vim does at initialization. See :help initialization.

The answer is myscript.vim gets loaded dead last.
The vim -V option is a lifesaver here. (Capital -V, because -v starts in vi mode.) Just ran across it, after searching further since although the other answers answered your question, they don't show what wasn't sourced because it wasn't found. If I could send it back in time, I'd save myself a lot of time banging my head against strace output.
This will not only show you all of the scriptnames that it did source in order, but also all of the scriptnames that it would have sourced if they existed in order. So, you can discover what files you can create to load at the appropriate time.
$ vim -V
Adding it to your vim arguments easily answers the question.
$ vim -V -S myscript.vim file.txt
It shows myscript.vim as dead last.
It prints a ton, and winds up at a "Press ENTER or type command to continue" prompt, which lets you step through Autocommands.

Related

In vim, how do I start vim at the end of the file and what commands are available with -c

By reading this question I learned that you can give -c to vim such that it will call a command. The question is then answered by calling vim -c startinsert. Good, but what if I want to give other commands? I only know the shortcuts like i for :startinsert.
For example I'd like to write vim -c gotoend but it doesn't exists.
After some reading, all : commands, which are ex commands are written here and in man vim, but where do I find a lis or method to know what can be done?
The commands for options -c are called ex-command named after ex(tendended line editor). The list of commands are in vimdoc and vimhelp.
The command to jump to the end of file is just :$ so you can do this in command line:
vim -c $ <file>
Please note you probably better escape or quote $ as it's a shell metacharacter:
vim -c \$ <file>
or
vim -c '$' <file>
:help :normal. Also note that instead of -c command you can use +command.
With that, I'd typically say vim +"norm G" foo.txt to start at the bottom. You could even alias it: alias vimbottom='vim +"norm G"'; then you can use vimbottom foo.txt to start at the bottom, if you prefer.
where do I find a lis or method to know what can be done
There is no better resource for Vim than its :help. And I don't know any place that has all the ex-commands in one place, since it would be a huge list. (EDIT: :help :index actually has that. Thanks, Christian Brabandt!)

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.

Is there a way to configure Vim grepprg option to avoid waiting until the external tool has finished searching?

I am a long time Vimmer. However, I keep switching to shell to make searches. This avoids me to use the quickfix functionality.
The main reason for switching to shell is that when I use grep from inside Vim (with :grep), I cannot follow progress.
Because the code base I search is usually wide, I really appreciate immediate feedback.
It gives me a chance to find out that my search expression is wrong before the full results have been displayed.
This allow me to cancel the search, refine the expression then relaunch the search.
Any hint how to reproduce this pattern inside Vim would be appreciated.
I don't see the same vim behaviour as you. When I run :grep, I still see the results in vim (not in the quickfix) before the search completes (but I cannot do anything until the search is done).
I even tried using no vim settings or plugins:
gvim -u NONE -U NONE
If that's not your behaviour, check your grepprg. Mine is the default:
:verbose set grepprg
grepprg=grep -n $* /dev/null
When I use run grep -e "score" -R /etc I see this output in vim:
:!grep -n -e "score" -R /etc /dev/null 2>&1| tee /tmp/voLcaNS/232
It's possible that your system is missing tee or your vim doesn't use it (I'm using Vim 7.2 on Ubuntu 10.10). tee takes the text passed to it and writes it to a file and to stdout.
If you're looking for a way to have the quickfix get updated with your search results and have vim not block while you're searching, then you could write a script that:
searches with grep as a background process and redirects to a file
every second until grep completes, have vim load the file in quickfix (cgetfile) (you can tell vim to do something from another process with --remote-expr)
You can try my AsyncCommand plugin to get your code started. It does the above, except that it only loads the file when the search is complete.
Are you familiar with ack.vim at all? It doesn't use the quickfix window, but uses a separate buffer in a split. However, it's rather faster results come right back to the vim frame.
This may be due to buffering between grep and tee, not vim itself. To test this theory, run grep from the command-line and pipe the output through tee (i.e. grep <pattern> <files> | tee temp.out). If it behaves the same as you observe within vim, then buffering is occurring.
To work around, install expect (sudo apt-get install expect-dev on Ubuntu 10.10) and grepprg to unbuffer grep -n $* /dev/null. (See Turn off buffering in pipe).
Take a look at :vimgrep in the online documentation. It displays the file name being searched and updates as it goes.
There are three ways to do a search in entire projects.
System command grep(fast, but not working well with Ouickfix list)
=>$ grep -n Example *
Vim internal grep(slow, but have a strong pattern support)
:vim[grep] /{pattern}/[g][j] {file} ...
System plugin ack(perfect)
1 install ack
brew install ack
2 add below configs to your .vimrc
:set grepprg=ack\ --nongroup\ --column\ $*
:set grepformat=%f:%l:%c:%m
3 then you can use grep to call ack in vim like
:grep "object\." app/**/*.rb

Alternative to Up Arrow + Enter to run previous command?

Sometimes I have to run a command many times in succession, for example to see if a service has started, and it becomes tedious to move my hands away from my normal typing position to press the Up Arrow and Enter keys repeatedly. Is there a way to run the previous command without the Up Arrow and Enter keys, perhaps with an elaborate shell script?
I've tried the following, but it is unsatisfactory because it cannot execute aliases, and it is a little slow.
history | tail -2 | head -1 | cut -d' ' -f4- | cat > prev_command.txt
sleep .01
chmod 777 prev_command.txt
eval prev_command.txt
rm prev_command.txt
Ideally I'd have an alias to this script so I can type in something like "prev" in the command line and hit Enter to run the previous command again.
In bash, you can press ctrlp to go to the previous command -- that's a lot better than having to move to the arrow keys.
See also: https://github.com/fliptheweb/bash-shortcuts-cheat-sheet/
Use
!!
to run your previous command.
sudo !!
also works , for the record.
Instead of running the same command many times in succession, why not watch it instead? watch will run a specified command repeatedly and display the output in stdout so you can see it change over time.
watchcommand
I often use the "history expansion" feature in bash (usually activated with cntlR) -- it interactively searches through your history for the previous closest match.
See the bash manual section Searching for Commands in the History, and also Using History Interactively.
Are you an emacs or vi user? You can use
set -o vi
set -o emacs
to set emacs or vi keybindings. You can then use the emacs or vi key bindings in bash. I don't know if this should work for other shells. I believe the vi mode starts in insert mode, so you need to hit esc to enter command mode. In emacs mode (the default), you can use ctrl+p and then ctrl+j to move to the previous line and do a carriage return.
Otherwise, you can use !! as someone else suggested.
In bash:
$ help fc
fc: fc [-e ename] [-lnr] [first] [last] or fc -s [pat=rep] [command]
Display or execute commands from the history list.
fc is used to list or edit and re-execute commands from the history list.
FIRST and LAST can be numbers specifying the range, or FIRST can be a
string, which means the most recent command beginning with that
string.
Options:
-e ENAME select which editor to use. Default is FCEDIT, then EDITOR,
then vi
-l list lines instead of editing
-n omit line numbers when listing
-r reverse the order of the lines (newest listed first)
With the `fc -s [pat=rep ...] [command]' format, COMMAND is
re-executed after the substitution OLD=NEW is performed.
A useful alias to use with this is r='fc -s', so that typing `r cc'
runs the last command beginning with `cc' and typing `r' re-executes
the last command.
Exit Status:
Returns success or status of executed command; non-zero if an error occurs.
Note the suggestion for alias r; I use this frequently.
Depending on what terminal you're using, I know a lot used to have F3 as an option for repeating, but that's still outside the normal range for typing as well unless you have a special keyboard with more accessible function keys.
My keyboard makes the function keys easily accessible, but I don't do much command line work in unix any more, so I wouldn't be able to tell you for sure whether or not this is still possible.

Bash Shell - What is equivalent of DOS shell F8?

When working an interactive bash session, one aspect from the Windows shell I miss is the F8 key where you start typing a command, hit F8 and the shell finds the most recent command entered in history that matches what you have typed so far. e.g.
me#Ubntu07:~>cd /home/jb<F8 Key Here>
brings up my prior command:
me#Ubntu07:~>cd /home/jboss/server/default/log
Is there any way to do this in bash ?
Hit Ctrl-R before you start typing.
(There may well be another version which finds commands based on what's already been typed - I wouldn't know, as Ctrl-R has always been good enough for me :)
Pressing Ctrl-R again shows the next match etc.
My Gentoo is configured in a way that I can press PgUp and PgDn to scroll through those commands in the command history that start with what’s currently in my command line.
# cd<PgUp>
results in:
# cd hydrogen
That’s pretty much the same function. It is defined in my /etc/inputrc with the following lines:
# mappings for "page up" and "page down" to step to the beginning/end
# of the history
"\e[5~": history-search-backward
"\e[6~": history-search-forward
I have these lines in my .inputrc file:
"\e[A": history-search-backward
"\e[B": history-search-forward
This binds history search to the up and down arrow keys. So you can start typing a command, kextload say, and then each tap of the up arrow will complete the line with the previous command that started with kextload.
All of my config files are public on github.
http://github.com/jonshea/config-files/tree/master
In your case !jb would print and then run that command.
e.g.,
$ nano logconfig.properties
$ !n
nano logconfig.properties
$
Of course if you want to be on the safe side, use ctrl-r first to bring up the interactive command history.
Ctrl + R does a history search. It's a bit different in that first you hit Ctrl + R and then type what you're looking for.
If you're just talking about a command, you can use the !<cmd> to do the last one. For example, say you entered python runscript.py a while ago; you can type:
!py
or something along those lines to run that command again.
To repeat an argument to a command, you could do something like this:
echo !py:1
which would echo runscript.py back to the terminal, in this example. The number after the colon refers to the argument you'd like to use from the given command.
There's a lot of other great information about the bash history here.
If you use vi input mode (set -o vi in bash or via set editing-mode vi in .inputrc), you can use normal vi commands to search the history (/). This gives you full regular expressions, too, which can be helpful for finding a complex command.

Resources