Change:
To make sure that we are on the same page: Kernel: System: Nix version: Nixpkgs version: I installed atom and ycmd, and the you-complete-me plugin for Atom, but none of the YCM functionality in Atom seems to work. It works. It doesn't. Install you-complete-me from Atom's package manager. Set the ycmd path in the plugin's settings appropriately ( in my case) Open a C/C++ source file, right click on something, try (e.g.) "GoToDeclaration" from the "YouCompleteMe" submenu (nothing happens) Boilerplate out of the way! The above commands all say 15.09, but I installed ycmd and atom from the 16.03 beta channel. , , you-complete-me plugin is 0.7.4. Running Atom in Dev Mode, if we try anything from the YouCompleteMe submenu, we see this in the debug console: ! Looking at that file, we see that it contains: It's actually a bash script! Which Nix created to setup before invoking the real_ from . And the syntax error is presumably because Atom/YCM are trying to execute it as a python script. We can verify this by looking at the : But I'm not sure where or how this should be fixed.
Set the path in the settings to ? Although then some dependencies might be missing..
Yeah. I want to use and that would just mean it won't find . Still no good, for me. It's not reasonable to do something like make the wrapper actually a Python script instead of Bash?
is used for a lot of packages, not just . Duplicating it in Python just for this issue doesn't make much sense I think. Ideally, you-complete-me would just be calling the executable directly, instead of going through python. Windows however doesn't understand shebags, I guess that's why they're doing it this way.
cc
Can anyone at least recommend me a better workaround (that will work together with ) than, like, installing an Ubuntu VM? On any other OS I could just hack it by editing one of the files in question to make it work, but Nix is not very conducive to that.
I am not familiar with NixOS and here are my thoughts after reading the discussion above. It is not appropriate to replace with a bash script. From python command line : And atom-youcompleteme can't execute directly without running command because there is an option for user to choose which python executable to use(useful when multiple versions of python installed).
So is this a WONTFIX from both sides? As in, wouldn't even accept a patch? (cc just in case you have any ideas, as someone I know in the intersection of the Rust and Nix communities...)
We absolutely should fix this, but I'm not sure how. There's nothing we can do about the wrapper because absolutely has to be set, and we can't patch you-complete-me either because it's not distributed through nix. cc also uses a bash wrapper, right? That's quite ironic, the shell wrapper exists for exactly that purpose, it allows us to use specific versions of dependencies.
Heh, we've got ourselves a nice case of polyglotitist here. I have no idea why the nix script is calling a bash script , that just seems plane wrong. In the spirit of hacks-on-hacks, I'd trick atom/yo into using a no-op "exec args" script as the "python interpreter"/
Evil genius! That seems to fix that problem -- the daemon gets started now. It still doesn't work (of course), but for some other reason...
I have the same issue with the vscode ycmd plugin (). Setting the following as the "python interpreter" as suggested above does not work (instead just moves the error to another one of these bash in python wrappers that is imported somewhere else). What can be done here? This bash in python stuff does not feel super robust to me, as clearly the assumption that these scripts will not be executed by the python interpreter does not always hold. My first thought would be to simply wrap the bash calls in a ? so the script can also be executed as python, or is that horribly naive? Anyway, super happy to do some work to get this fixed, but really have no idea where to start, so any tips / advice would be very much appreciated :) Relevant error logs / code snippets in this gist:
Wow, I have completely missed this discussion. I have written the Nix expression for ycmd, and I only use it with vim/emacs, which do call it as a normal process. That's why wrapping python scripts in bash ones worked fine. Making a wrapper script written in python seems the best solution for me. It should allow both running it as a python script and as a normal process, too.
Is there any reason can't just prepend to inside the python file when we modify them in , like we currently do to touch up the PYTHONPATH? (see and ). If there isn't a good rationale for it, we could avoid (that is, avoid the shell script indirection) and just lean on the stuff to touch up the environment within the python script itself.
I'm playing around with fixing this, and I'd think something like this should work:
I think should (mostly) fix this (no more bash wrapper). Ultimately, I think we should request that these editor plugins also support an option for invoking a command directly, that way we can just point them at (which will already have the appropriate interpreter in the shebang), rather than having to deal with either having the right on or providing a full path to e.g. the nix store path for python 2 (blech).

Discussion:
<ins> diff --git a/cpp/ycm/CMakeLists.txt b/cpp/ycm/CMakeLists.txt index 2074c58e..9ecd6e57 100644 --- a/cpp/ycm/CMakeLists.txt +++ b/cpp/ycm/CMakeLists.txt @@ -366,35 +366,6 @@ if( LIBCLANG_TARGET ) POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy "${LIBCLANG_TARGET}" "$<TARGET_FILE_DIR:${PROJECT_NAME}>" ) - -    if( APPLE ) -      # In OS X El Capitan, Apple introduced System Integrity Protection. -      # Amongst other things, this introduces features to the dynamic loader -      # (dyld) which cause it to "sanitise" (and complain about) embedded -      # LC_RPATH entries which contain @executable_path when then are loaded -      # into "restricted" binaries.  For our purposes, "restricted" here means -      # "supplied by Apple" and includes the system versions of python.  For -      # unknown reasons, the libclang.dylib that comes from llvm.org includes an -      # LC_RPATH entry '@executable_path/../lib' which causes the OS X dynamic -      # loader to print a cryptic warning to stderr of the form: -      # -      #    dyld: warning, LC_RPATH @executable_path/../lib in -      #    /path/to/ycmd/libclang.dylib being ignored in restricted program -      #    because of @executable_path -      # -      # In order to prevent this harmless and annoying message appearing, we -      # simply strip the rpath entry from the dylib.  There's no way any -      # @executable_path that python might have could be in any way useful to -      # libclang.dylib, so this seems perfectly safe. -      get_filename_component( LIBCLANG_TAIL ${LIBCLANG_TARGET} NAME ) -      add_custom_command( TARGET ${PROJECT_NAME} -                          POST_BUILD -                          COMMAND install_name_tool -                          "-delete_rpath" -                          "@executable_path/../lib" -                          "$<TARGET_FILE_DIR:${PROJECT_NAME}>/${LIBCLANG_TAIL}" -                        ) -    endif() endif() endif() </ins>

<del> { stdenv, fetchgit, cmake, llvmPackages, boost, python2Packages </del> <ins> { stdenv, lib, fetchgit, cmake, llvmPackages, boost, python , gocode ? null , godef ? null , rustracerd ? null , Cocoa ? null </ins> }: <del> let inherit (python2Packages) python mkPythonDerivation waitress frozendict bottle; in mkPythonDerivation rec { name = "ycmd-2016-01-12"; namePrefix = ""; </del> <ins> stdenv.mkDerivation rec { name = "ycmd-${version}"; version = "2017-02-03"; </ins> src = fetchgit { url = "git://github.com/Valloric/ycmd.git"; <del> rev = "f982f6251c5ff85e3abe6e862aad8bcd19e85ece"; sha256 = "1g0hivv3wla7z5dgnkcn3ny38p089pjfj36nx6k29zmprgmjinyr"; </del> <ins> rev = "ec7a154f8fe50c071ecd0ac6841de8a50ce92f5d"; sha256 = "0rzxgqqqmmrv9r4k2ji074iprhw6sb0jkvh84wvi45yfyphsh0xi"; </ins> }; <del> buildInputs = [ cmake boost ]; propagatedBuildInputs = [ waitress frozendict bottle ]; </del> <ins> buildInputs = [ cmake boost ]  ++ stdenv.lib.optional stdenv.isDarwin Cocoa; </ins> buildPhase = '' export EXTRA_CMAKE_ARGS=-DPATH_TO_LLVM_ROOT=${llvmPackages.clang-unwrapped} ${python.interpreter} build.py --clang-completer --system-boost ''; <ins> patches = [ ./2-ycm-cmake.patch ]; </ins> configurePhase = ":"; <ins> # remove the tests # # make __main__.py executable and add shebang # # copy over third-party libs # note: if we switch to using our packaged libs, we'll need to symlink them # into the same spots, as YouCompleteMe (the vim plugin) expects those paths # to be available # # symlink completion backends where ycmd expects them </ins> installPhase = '' <del> mkdir -p $out/lib/ycmd/third_party $out/bin cp -r ycmd/ CORE_VERSION libclang.so.* ycm_client_support.so ycm_core.so $out/lib/ycmd/ </del> <ins> rm -rf ycmd/tests chmod +x ycmd/__main__.py sed -i "1i #!${python.interpreter} " ycmd/__main__.py mkdir -p $out/lib/ycmd cp -r ycmd/ CORE_VERSION libclang.so.* ycm_core.so $out/lib/ycmd/ mkdir -p $out/bin </ins> ln -s $out/lib/ycmd/ycmd/__main__.py $out/bin/ycmd <ins> mkdir -p $out/lib/ycmd/third_party/{gocode,godef,racerd/target/release} cp -r third_party/JediHTTP $out/lib/ycmd/third_party for p in waitress frozendict bottle python-future argparse requests; do cp -r third_party/$p $out/lib/ycmd/third_party done '' + lib.optionalString (gocode != null) '' ln -s ${gocode}/bin/gocode $out/lib/ycmd/third_party/gocode '' + lib.optionalString (godef != null) '' ln -s ${godef}/bin/godef $out/lib/ycmd/third_party/godef '' + lib.optionalString (rustracerd != null) '' ln -s ${rustracerd}/bin/racerd $out/lib/ycmd/third_party/racerd/target/release ''; # fixup the argv[0] and replace __file__ with the corresponding path so # python won't be thrown off by argv[0] postFixup = '' substituteInPlace $out/lib/ycmd/ycmd/__main__.py  --replace $out/lib/ycmd/ycmd/__main__.py  $out/bin/ycmd  --replace __file__  "'$out/lib/ycmd/ycmd/__main__.py'" </ins> ''; meta = with stdenv.lib; { description = "A code-completion and comprehension server"; homepage = https://github.com/Valloric/ycmd; license = licenses.gpl3; <del> maintainers = with maintainers; [ rasendubi ]; </del> <ins> maintainers = with maintainers; [ rasendubi cstrahan ]; </ins> platforms = platforms.all; }; }

yacc = bison; <del> ycmd = callPackage ../development/tools/misc/ycmd { }; </del> <ins> ycmd = callPackage ../development/tools/misc/ycmd { inherit (darwin.apple_sdk.frameworks) Cocoa; python = python2; }; </ins> yodl = callPackage ../development/tools/misc/yodl { };