How to use variable when setting makeprg in vim? - vim

I am creating a method called SetLaunchingComponent which is used to set the makeprg with the variable passed in.This is how the script look like now.
function! SetLaunchingComponent(path)
set makeprg=$path
endfunction
Obviously the function isn't working as i wished. As vim resolve the path environment as the system variable but not a:path. So what should i do?

To set a option you should use the following syntax:
let &makeprg=a:path

command! -n=1 SL call SetLanuchingComponent(<arg>)
it will make you easy to use the function.

Related

Buffer-local value of global variable?

Many Vim's plugin's settings are specified by let g:something = value. I have a need for setting buffer-local values of some variables (actually with vim-localvimrc)
I know there's a way to outwit by using a condition (Setting buffer specific variables in Vim). But not all these autocmds are under my control, since some are set by other plugins. Is there anything like setlocal for global variable?
There are many ways to do to what you actually want (strip trailing whitespace for some projects) but I don't think there is anyway to shadow a global variable with a buffer local one (which is what you asked).
One way to do this is to add
autocmd BufWritePre /path/to/project/* call StripTrailingWhitespace()
the following to your vimrc. Which will call the function StripTrailingWhitespace for any file under /path/to/project (including subdirectories). StripTailingWhitespace is defined in spf13.
You can probably generate the path to the project dynamically by looking at the path to the local vimrc file.
Another way would be to change the condition spf13 uses to call StripTrailingWhitespace
The StripTrailingWhitespace autocmd in spf13 is defined as the following. (I added newlines so I'm not sure if this will work.)
autocmd FileType c,cpp,java,go,php,javascript,python,twig,xml,yml,perl
\ autocmd BufWritePre <buffer>
\ if !exists('g:spf13_keep_trailing_whitespace') |
\ call StripTrailingWhitespace() |
\ endif
So you would change it to !exists('g:spf13_keep_trailing_whitespace') to some other condition like checking if in whitelisted projects or check a buffer local variable.
General recommendation would be to get rid of any vim distribution. It is very hard to understand what is in them when you are first starting out. It then becomes very hard to modify them. It is generally better to start from scratch and add plugins and mappings when you find something lacking. It will take longer but you will understand everything in your vim configuration.
In your case, the plugin you are using shall accept overriding global variables with buffer local variables. Indeed it can be done by changing the condition -- in lh-vim-lib there is a lh#option#get() function that'll be easy to adapt to spf13. If you think it makes sense, contact spf13 maintainers or open an issue in the project bug tracker.
Another solution would rely on defining a local_vimrc script for each project you are working on. In some projects you'll have a :let g:spf13_keep_trailing_whitespace = 1, in other you'll have a :silent! unlet g:spf13_keep_trailing_whitespace -- usually it is accomplished with a :let g:var=0, but the current condition ignores the variable value.

VimScript: pass value of local variable to edit command

I have written a simple function to invoke edit command with a path followed by the given filename.
However it looks like edit l:path invokes edit for file named "l:path" instead of l:path variable value. I guess this is a trivial issue, but it's hard to get search results for calling edit command in function, not from the vim editor.
Following code show the proper value of l:path when I change edit to echon.
command! -nargs=1 E call EditAtCurrentPath(<f-args>)
function! EditAtCurrentPath(filename)
let l:path=expand('%:p:h').'/'.a:filename
edit l:path
endfunction
You have to use :execute to pass variables to commands:
execute 'edit' l:path
There are some good examples in :help :execute.

vim redirect output to quickfix

Is it possible to redirect an output of a command to the quick fix window?
The command I am running is
:!java %:r
and was hoping the output would go into the quickfix window
I would suggest one of two options: configure makeprg to run java like you want, or create a mapping or command to populate the quickfix list without changing anything else.
Option 1: Using makeprg and compiler plugins
I would generally set the makeprg option for this, as others have said. It's not a hack, that's exactly what the makeprg option is for.
The only problem is if you have another build script you want to run as well. A more general solution is to create a simple compiler plugin. For instance, somewhere on your runtimepath, you can create a file under compiler/java.vim and set it to something like this:
if exists("current_compiler")
finish
endif
let current_compiler = "java"
CompilerSet makeprg=java
Now when you're working with java, you can do :compiler java and then your makeprg will be set as desired in the current window. If you want to use it for all windows, use :compiler! java, with a bang. Not all compiler plugins set the makeprg option, but you can always reset it with :set makeprg&. Try :help write-compiler-plugin for more information.
Option 2: Create a command to do it
Alternatively, you can also use cexpr to populate the quickfix list. For instance:
:cexpr system('java ' . shellescape(expand('%:r')))
The expand is necessary to expand the '%:r' in an expression, and shellescape escapes it so it can be used as an argument to a shell command. Then the string 'java ' is prepended to the escaped path and the result is invoked as a shell command by system. The output from this command is used to load the quickfix list.
The nice thing about this is that it doesn't change makeprg or any other settings, but still lets you easily populate the quickfix list. Of course, you'll probably want to map this or define a custom command for it.
Please note that the quickfix window is for specific output (e.g. of compiler or syntax checker tools) which includes references (i.e. line and column numbers) to the current buffer. There's a lot of infrastructure around this: 'makeprg', 'errorformat', etc., usually bundled into a compiler plugin.
Though you can redirect arbitrary output into the quickfix window, it provides little benefit (and has the downside of clobbering 'makeprg') over reading the output of an external program into a new scratch buffer, e.g. like this:
:new|0read !java #:r
Try this:
set makeprg=java
make %:r
It's a bit of hack, and of course assumes you aren't already using makeprg for your actual build script.
I mapped leader + j + r to run my java code and display it in the quickfix window by doing
map <leader>jr :set makeprg=java <CR>:make %:r<CR>:copen<CR>

How to set an option, using let, for the current buffer (vim)?

In vimlanguage, you can set options for the current buffer only using setlocal.
However, I need to set a more complex expression than just a literal, which isn't possible with setlocal.
I currently have let &formatprg=s:prgpath." ".a:args, but this sets the formatprg for all buffers, which is not what I want.
How would I set the formatprg like above, only for the current buffer?
Use let &l:option instead of let &option to only change the local value, like setlocal option. Similarly, let &g:option would only set the global value, like setglobal option. See :help :let-option for more information.
Note that formatprg in particular is global (no "local to buffer" in its help).
Making a global option buffer-local requires changes to Vim's source code. Alternatively, I've just published the GlobalOptions plugin that uses autocmds to work around this, and turns any global option into a buffer- or window-local one.

How to set numeric variables in vim functions

I'm trying to write a function that calls setlocal to set some variables to the param(s) that I pass in. But I'm getting the error Number required after =: tabstop=...
function! MyFunction(param)
setlocal tabstop=param
setlocal tabstop=a:param
endfunction
Both lines will fail. Is there some sort of variable interpolation I'm missing?
You need to define the option as an &option variable. For example:
fun! MyFun(param)
let &l:tabstop = a:param
endfun
See :help let-&. The &l: is listed a little below that tag showing that it is for the equivalent of setlocal. Basically, when you want to set an option to an expression instead of a defined value then you need to use let &option= instead of set option=. Use let &l:option= instead of setlocal option=. There is also &g:option to set the option globally.

Resources