0

I'm using python venv to manage my local pip packages. I'd want to let g:python3_host_prog read the result of shell command line command -v python3 dynamically when venv enabled/disabled in Neovim.

However, when I tried to use :

let g:python3_host_prog = expand( system('command -v python3') )

it shows:

:echo has('python3')
0

BTW, it works when using hardcode python3 path.

4
  • If you found an answer to your question the best would be that you publish it as an answer and accept it (two days later) such that the question doesn't stay open :-) Commented May 9 at 10:19
  • The system() function should not return a result with that string. (See also systemlist().) Smells like a bug to me.
    – D. Ben Knoble
    Commented May 9 at 15:11
  • 1
    (It could also be that you actually just need trim())
    – D. Ben Knoble
    Commented May 9 at 15:12
  • 1
    @VivianDeSmedt, thanks for your inform, will convert it as answer
    – Marslo
    Commented May 13 at 23:49

1 Answer 1

0

Okay, the reason is the extra new line \n returned by system(..), check :help press-enter for more details : enter image description here

So the solutions is to "suppress" the extra content ( new lines ), here are multiple way can handle:

1. via trim() : trim string

mentioned by @D.BenKnoble :

" .vimrc
let g:python3_host_prog = expand( trim(system('command -v python3')) )
  • :help trim()

    trim({text} [, {mask} [, {dir}]])

    If {mask} is not given, or is an empty string, {mask} is all characters up to 0x20, which includes Tab, space, NL and CR, plus the non-breaking space character 0xa0

  • debug:

    :echo "aabbcc\n"
    
    " trim
    :echo trim( "aabbcc\n" )
    :echo trim( "aabbcc\n", "\n" )
    
    " or even more new lines
    :echo trim( "aabbcc\n\n\n" )
    

2. via systemlist(): return list of system()

thanks @D.BenKnoble

let g:python3_host_prog = expand( systemlist('command -v python3')[0] )

" or
let g:python3_host_prog = expand( get(systemlist('command -v python3'), 0) )

" or with default value if not found from cmd
let g:python3_host_prog = expand( get(systemlist('command -v python3'), 0, '/usr/local/bin/python3') )
  • more info

    systemlist('...') == split(system('...'), '\n')
    
  • :help systemlist()

    systemlist({cmd} [, {input} [, {keepempty}]])

    Same as |system()|, but returns a |List| with lines (parts of output separated by NL) with NULs transformed into NLs.

  • :help get()

    get({list}, {idx} [, {default}])

    Get item {idx} from |List| {list}. When this item is not available return {default}.

3. via substitute(): find and replace

Got clue from https://stackoverflow.com/a/52983182/2940319 and tomtom/tlib_vim :

let g:python3_host_prog = expand( substitute(system('command -v python3'), '\n\+$', '', '') )
"                                            ----------------------------   ------  --
"                                                          |                   |    + replace to ''
"                                                          |                   + search patten: find one or more new line(s)
"                                                          + string

" or you can use two lines:
let python3_dynamic_path = substitute(system('command -v python3'), '\n\+$', '', '')
let g:python3_host_prog = expand(python3_dynamic_path)
  • Search and replace

    The :substitute command searches for a text pattern, and replaces it with a text string.

  • :help substitute()

    substitute({string}, {pat}, {sub}, {flags})


the :checkhealth provider.python result:

==============================================================================
provider.python: require("provider.python.health").check()

Python 3 provider (optional) ~
- Using: g:python3_host_prog = "/Users/marslo/.venv/tools/bin/python3"
- Executable: /Users/marslo/.venv/tools/bin/python3
- Python version: 3.12.3
- pynvim version: 0.5.0
- OK Latest pynvim is installed.

Python virtualenv ~
- $VIRTUAL_ENV is set to: /Users/marslo/.venv/tools
- Python version: 3.12.3
- OK $VIRTUAL_ENV provides :!python.
2
  • 2
    You missed systemlist(), which I think would make this easy.
    – D. Ben Knoble
    Commented May 17 at 0:11
  • @D.BenKnoble thanks. systemlist() solution has been added.
    – Marslo
    Commented May 17 at 18:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.