vim: in .vimrc how to set complex makeprg command? - vim

Usually we have :
set makeprg=make
to mean we use gnu make.
(1) So how to set it to a compound command like "cmake && make".
(2) And how to set it with argument? I tried this:
set makeprg=scons -U
It's invalid syntax. If I set:
set makeprg="scons -U"
Well it doesn't do any work, seems.
Need your help!

Use let &makeprg='str ing' or a backslash with set
PS: I'd rather call cmake only when I know i need it. Hence the dedicated :ReConfigure command in my build-tool-wrappers plugin.

Related

vimscript augment rtp with directory above result of system command

I'm trying to modify my vimrc to include a directory
let g:mydir = system('which someExecutable')
execute "set rtp+=" . g:mydir
The problem is that which someExecutable returns something like
/aDir/a/b.
I need g:mydir set to /aDir/, so two dirs above b.
Is there an easy way to do this in vimscript?
You're looking for fnamemodify(path, ":h")
If you version of vim is recent enough, you can even use exepath('someExecutable') instead of system('which someexecutable'). Which gives:
fnamemodify(exepath('someExecutable'), ":h")
PS: don't forget to escape what must be escaped if you use exe "set rtp+=....

vimrc how to invoke unix find?

i want to set the tags variable to the set of all gotags files i generated in specific folder(s) using exuberant Ctags. (gotags is nothing but the tags file renamed).
i put following lines in my .vimrc file.
set tags+=/usr/local/go/src/gotags
set tags+=`find /home/vimal/gowork/src -name gotags`
but it doesnt work and i get the following error
$ vi ~/.vimrc
Error detected while processing /home/vimal/.vimrc:
line 157:
E518: Unknown option: /home/vimal/gowork/src
Press ENTER or type command to continue
how can i fix the error and set the tags variable with the value: list of all the gotags files under one directory tree.
Inventing new syntax tends not to work that well in practice. Use system() to run external commands from Vim, not backticks. Also set in Vim is weird, it doesn't evaluate RHS the way you expect. Most of the time it's a lot simpler to use let &option = ... instead of set option=....
Anyway, to answer your question, you don't need to run find(1) for that, plain Vim functions are enough for what you want:
let &tags = join(extend([&tags, '/usr/local/go/src/gotags'],
\ findfile('gotags', '/home/vimal/gowork/src', -1)), ',')

Why my gdb prompt shows wrong after I change its color

I change my gdb prompt's color by writing set prompt \033[1;33m(gdb) \033[0m into .gdbinitfile. And I change my gdb prompt's color sucessfully.
But I find that my long command with my parameters will overwrite my prompt after I input a long command without going to newline. Why?
Edit: if your gdb has python scripting enabled, look at #matt's answer to see how to do this using the set extended-prompt command - it's a better solution.
Gdb manages command input by using the readline package. The way to tell readline that a character sequence in a prompt string doesn't actually move the cursor when output to the screen is to surround it with the markers RL_PROMPT_START_IGNORE (currently '\001' in readline's C header file) and RL_PROMPT_END_IGNORE (currently '\002').
Bash has a portable way of expressing this: when it sees "\[" and "\]" in the prompt variable, it will convert them to RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE. Bash does this while it's processing various other escape sequences such as \w to include the current working directory.
Gdb's set prompt command doesn't support "\[" and "\]", but you can put the octal escapes \001 and \002 in your set prompt string (subject to change if readline's authors ever choose to use a different set of markers).
set prompt \001\033[1;33m\002(gdb) \001\033[0m\002
gdb has a command: set extended-prompt that accepts escape sequences described in the gdb.prompt python module. which includes the \[ and \] bashism's for wrapping characters that do not contribute to the prompts length. This of course requires a python enabled gdb to work though.

vim expanded makeprg variable

I use the :set makeprg functionality to set different make behaviour depending on files. One feature of this is that I can use % and %< in order to refer to the file in the active buffer, as well as $ for environment variables.
I'd like to echo the expanded makeprg variable, but I can't seem to achieve this.
For example, suppose I have :set makeprg=build\ %, and I'm working on file Foo.txt.
I would expect the output of echoing an expanded makeprg to be:
build Foo.txt
However, we have the following result when echoing the &makeprg variable:
:echo(&makeprg)
build\ %
The solution probably involves using expand(), except that this would involve parsing the &makeprg for escaped symbols and dealing with $ appropriately for environment variables. Is there a solution to this that I'm missing?
Why would you need this? For troubleshooting, I would probably just append echo to 'makeprg' (that's a trailing space after \):
:setl makeprg^=echo\
But the following should do what you had in mind. The trick is to split the 'makeprg' string on spaces, and process each word individually:
:echo join(map(split(&makeprg), 'expand(v:val)'))
A bit closer to the truth:
join(map(split(mystring, '\ze[<%#]'), 'expand(v:val)'), '').

Vim with Powershell

I'm using gvim on Windows.
In my _vimrc I've added:
set shell=powershell.exe
set shellcmdflag=-c
set shellpipe=>
set shellredir=>
function! Test()
echo system("dir -name")
endfunction
command! -nargs=0 Test :call Test()
If I execute this function (:Test) I see nonsense characters (non number/letter ASCII characters).
If I use cmd as the shell, it works (without the -name), so the problem seems to be with getting output from powershell into vim.
Interestingly, this works great:
:!dir -name
As does this:
:r !dir -name
UPDATE: confirming behavior mentioned by David
If you execute the set commands mentioned above in the _vimrc, :Test outputs nonsense. However, if you execute them directly in vim instead of in the _vimrc, :Test works as expected.
Also, I've tried using iconv in case it was an encoding problem:
:echo iconv( system("dir -name"), "unicode", &enc )
But this didn't make any difference. I could be using the wrong encoding types though.
Anyone know how to make this work?
It is a bit of a hack, but the following works in Vim 7.2. Notice, I am running Powershell within a CMD session.
if has("win32")
set shell=cmd.exe
set shellcmdflag=/c\ powershell.exe\ -NoLogo\ -NoProfile\ -NonInteractive\ -ExecutionPolicy\ RemoteSigned
set shellpipe=|
set shellredir=>
endif
function! Test()
echo system("dir -name")
endfunction
Tested with the following...
:!dir -name
:call Test()
I ran into a similar problem described by many here.
Specifically, calling
:set shell=powershell
manually from within vim would cause powershell to work fine, but as soon as I added:
set shell=powershell
to my vimrc file I would get the error "Unable to open temp file .... "
The problem is that by default when shell is modified, vim automatically sets shellxquote to " which means that shell commands will look like the following:
powershell -c "cmd > tmpfile"
Where as this command needs to look like this, in order for vim to read the temp file:
powershell -c "cmd" > tmpfile
Setting shellquote to " in my vimrc file and unsetting shellxquote (i.e. setting it to a blank space) seem to fix all my problems:
set shell=powershell
set shellcmdflag=-c
set shellquote=\"
set shellxquote=
I've also tried taking this further and scripting vim a bit using the system() call:
system() with powershell in vim
I suspect that the problem is that Powershell uses the native String encoding for .NET, which is UTF-16 plus a byte-order-mark.
When it's piping objects between commands it's not a problem. It's a total PITA for external programs though.
You can pipe the output through out-file, which does support changing the encoding, but still formats the output for the terminal that it's in by default (arrgh!), so things like "Get-Process" will truncate with ellipses, etc. You can specify the width of the virtual terminal that Out-File uses though.
Not sure how useful this information is, but it does illuminate the problem a bit more.
Try replacing
"dir \*vim\*"
with
" -command { dir \*vim\* }"
EDIT: Try using cmd.exe as the shell and put "powershell.exe" before "-command"
Interesting question - here is something else to add to the confusion. Without making any changes to my .vimrc file, if I then run the following commands in gvim:
:set shell=powershell.exe
:set shellcmdflag=-noprofile
:echo system("dir -name")
It behaves as expected!
If I make the same changes to my .vimrc file, though (the shell and shellcmdflag options), running :echo system("dir -name") returns the nonsense characters!
The initial example code works fine for me when I plop it in vimrc.
So now I'm trying to figure out what in my vimrc is making it function. Possibly:
set encoding=utf8
Edit: Yep, that appears to do it. You probably want to have VIM defaulting to unicode anyway, these days...
None of the answers on this page were working for me until I found this hint from https://github.com/dougireton/mirror_pond/blob/master/vimrc - set shellxquote= [space character] was the missing piece.
if has("win32") || has("gui_win32")
if executable("PowerShell")
" Set PowerShell as the shell for running external ! commands
" http://stackoverflow.com/questions/7605917/system-with-powershell-in-vim
set shell=PowerShell
set shellcmdflag=-ExecutionPolicy\ RemoteSigned\ -Command
set shellquote=\"
" shellxquote must be a literal space character.
set shellxquote=
endif
endif
Combining the answers in this and the related thread, add the following to your $profile assuming you installed diffutils from chocolatey:
Remove-Item Alias:diff -force
And add the following to your ~/.vimrc:
if (has('win32') || has('gui_win32')) && executable('pwsh')
set shell=pwsh
set shellcmdflag=\ -ExecutionPolicy\ RemoteSigned\ -NoProfile\ -Nologo\ -NonInteractive\ -Command
endif
make sure shellcmdflag is exactly as shown
All credit for these solutions to their respective contributors, this is merely an aggregation post.
I propose an hackish solution. It doesn't really solve the problem, but it get the job done somehow.
This Vim plugin automate the creation of a temporary script file, powershell call through cmd.exe and paste of the result. It's not as nice as a proper powershell handling by vim, but it works.
Try instead
set shellcmdflag=\ -c
Explanation:
Vim uses tempname() to generate a temp file path that system() reads.
If &shell contains 'sh' and &shellcmdflag starts with '-'
then tempname() generates a temp file path with forward slashes.
Thus, if
set shell=powershell
set shellcmdflag=-c
then Vim will try to read a temp file with forward slashes that
cannot be found.
A remedy is to set instead
set shellcmdflag=\ -c
that is, add a whitespace to &shellcmdflag so that the first character
is no longer '-' and tempname() produces a temp file path with backward
slashes that can be found by system().
I remarked on the vim_dev mailing list ( https://groups.google.com/forum/#!topic/vim_dev/vTR05EZyfE0 ) that this deserves better documentation.
actf answer works for me, but because of Powershell built in DIFF (which is different from the Linux one) you must add this line to your Powershell profile to have diff working again in VIM:
Remove-Item Alias:diff -force
I'm running GVim v8.2 (Windows).
Using the fullpath to the executable works for me:
set shell=C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe
I don't use VIM but Powershell's default output is Unicode. Notepad can read unicode, you could use it to see if you are getting the output you expect.

Resources