For the YouCompleteMe plugin, I would like to set the parameter g:ycm_path_to_python_interpreter in my vimrc to the path of the system python3 installation.
I am using let g:ycm_path_to_python_interpreter = system('which python3') however that is invalid, as the system(..) returns the string of the python3 path in a separate buffer it seems like. What I mean is that I see
/home/ubuntu/anaconda3/bin/python3
Press ENTER or type command to continue
when I :echo g:ycm_path_to_python_interpreter. I would expect just the path as string (i.e. /home/ubuntu/anaconda3/bin/python3). How can I do that?
The issue you're having is that system() will include the newline at the end of the command.
You can see that with the command:
:let g:ycm_path_to_python_interpreter
Which will show you:
g:ycm_path_to_python_interpreter /home/ubuntu/anaconda3/bin/python3^#
(The ^# at the end represents the newline character.)
To fix that, just use a call to trim() around the system() call.
let g:ycm_path_to_python_interpreter = trim(system('which python3'))
Related
This is inside a script:
:let s:submission_path = expand("%:p:h") . '\submissions\test_submission.csv'
:echo s:submission_path
:write s:submission_path
The script raises an error "can't open file for writing", because I'm on windows and ':' is not a valid filename character. If I name the variable 'submission_path' a file with that name is written (edit: and the contents of the file are as I expect, the contents of the buffer the script is editing).
I don't understand this. The echo command before the write does what I expect it to, output the full path to the file I want to write. But write seems to ignore the variable value and use its name instead? Do I need to dereference it somehow?
Try this:
:let s:submission_path = expand("%:p:h") . '\submissions\test_submission.csv'
:echo s:submission_path
:execute "write " . s:submission_path
Execute will allow you to compose an ex command with string operations and then execute it.
vim has very screwy evaluation rules (and you just need to learn them). write does not take an expression it takes a string so s:submission_path is treated literally for write. However echo does evaluate its arguments so s:submission_path is evaluated.
To do what you want you need to use the execute command.
exec 'write' s:submission_path
Environment variables don't have this problem, but you have to dereference them like in unix with a dollar sign:
:let $submission_path = expand("%:p:h") . '\submissions\test_submission.csv'
:echo $submission_path
:write $submission_path
AND it modifies your environment within the vim process, so just be aware of that.
I have a path stored in a variable (say l:s) and want to execute lcd l:s in a vim script, but it tells me the path "l:s" doesn't exist. What is the problem here, because vim resolves variable names in other ex commands just fine (echo, etc.). I don't understand the difference.
You can use exe and construct the command:
let s:some_dir_name = "foo"
exe "lcd " . s:some_dir_name
That'll evaluate the variable s:some_dir_name and execute the command lcd foo.
(I didn't use l:s from your question because that's not a legal variable name, but I think you get the idea.)
Vim lets you set environment variables within a script, and these work with :cd and :lcd. For example:
function foo()
let $SOME_PATH = '/some/path'
lcd $SOME_PATH
endfunction
For example:
If my current directory is /temp/src/com. And the file edited in vim is from /java/test.And now i want to add the path of the file to path environment. So if there is a cmd like set path+=$(filepath) in vim?
case 2:
Run make in terminal will start to compile a project, and it will out put logs about this compile. And now i want to read the outputed logs into vim using some command like r !make.
1) Pull the path into the current Vim buffer:
:r !echo \%PATH\%
Append to the path:
:let $PATH="C:\Test" . $PATH
2) This question is ambiguous, because it depends on your makefile behavior.
If your Makefile simply print to the console, then, :r make should do the trick.
If your make file actually writes to files explicitly, then there is no automatic way.
You'll have to write a custom vimscript function to pull in the logs.
1) Part 2
I do not know of what a way to do it in one line, but here's one way to achieve the functionality you want.
:redir #a "redirect output to register a
:pwd
:redir END "stop redirecting
:let #a = substitute(#a, '\n', '', 'g') "remove the newlines
:let $PATH=#a .":". $PATH
You should be able to wrap this in a function if you need to use it often.
You may reference environment variables using $MYVAR syntax. To set system environment variables use
let $MYVAR=foo
e.g.
let $PATH = "/foo" . $PATH
See http://vim.wikia.com/wiki/Environment_variables or :help :let-environment
Then you may use filename-modifiers to get directory name of a file in a current buffer:
let $PATH = expand("%:p:h") . $PATH
To read and parse compilation output in vim you might be interested to check quickfix mode
Use :make instead of :!make
I'm trying to define a new command in Vim that calls an external script with the name of the current file, but slightly modified. Here's how I defined the command:
:command MyNewCommand !/tmp/myscript.sh substitute(expand("%:p"), "-debug", "", 'g')
In other words, myscript.sh takes one parameter, which is the full pathname of the file being edited, with the string -debug in the pathname removed. My command definition doesn't work because rather than passing the pathname, Vim seems to pass to myscript.sh the entire string itself, beginning with the word substitute. How do I define the command to do what I want? Thanks :).
You can use the system() function to execute the script.
Change the command definition as follows:
:command! MyNewCommand call system('/tmp/myscript.sh ' .
\ shellescape(substitute(expand('%:p'), '-debug', '', 'g')))
To see the output of the command, replace call with echo.
You can use solution similar to #ib's one, but with ! which will show you the output of the shell command (and will also handle case when expand('%:p') contains newlines (it can if FS is fully POSIX-compliant)):
command MyNewCommand execute '!/tmp/myscript.sh' shellescape(substitute(expand('%:p'), '-debug', '', 'g'))
The generic approach is to build a string and then execute it. The problem in your command is that substitute(expand(... is not being evaluated and it's passed as is.
So in a generic example
command MyNewCommand OldCommand expand("%:p")
should be converted to
command MyNewCommand execute 'OldCommand '.expand("%:p")
That way MyNewCommand will just invoke execute with the expression 'OldCommand '.expand("%:p"). execute will evaluate the expression and therefore expand() will get evaluated to the filename and concatenated to 'OldCommand ' resulting in a string of the form 'OldCommand myfilename'. That string then gets executed as an Ex command by the same execute.
I would like to save the output of g/pattern1/,/pattern2/ to a file (for each match, a different file).
e.g.
def
.......
end
def
.......
end
you would end up with a file for each "def...end".
Tried using tempname() like so:
g/pattern1/,/pattern2/exe 'w ' . tempname() but this fails with no range allowed for exe
also tried
g/pattern1/,/pattern2/w `tempname()`
to get tempname() evaluated but this failed with a "too many filenames" error.
What am I missing? Can this be done by using global and other commands, or would you need vimscript to do it?
g/pattern1/,/pattern2/execute "w ".fnameescape(tempname())<CR>
Use execute whenever you want to insert variable into command-line if it is a mapping. If it is not, try using
g/pattern1/,/pattern2/w <C-r>=fn<Tab>e<Tab>te<Tab>)<CR><CR>
Here fn<Tab> with wildmode=longest,list:full will expand to fname, fnamee<Tab> will expand to fnameescape(, te<Tab> will expand to tempname(), so this is a short way to input <C-r>=fnameescape(tempname())<CR>. You can omit fnameescape if you are sure that tempname will not return filename with special characters.
And note that backticks will not execute vimscript function, they execute shell command, so `tempname()` tries to call tempname() in a shell and substitute filename with the result of this call. According to the help, you should have written `=tempname()`.
Try :g/pattern1/normal! :.,/pattern2/w `tempname()`^M with ^M entered as CTRL-V then ENTER