| #!/usr/bin/env perl |
| |
| use strict; |
| use warnings; |
| |
| # This script updates the .ycm_extra_conf.py in $LLVM_SRC to work with |
| # $LLVM_BLD's compile_commands.json and include/library paths. |
| # |
| # Syntax: llvm-ycm |
| # |
| # It will: |
| # * automatically detect $LLVM_SRC/BLD and change the paths. |
| # * also bail if those variables or .ycm_extra_conf.py don't exist. |
| # * exit successfully and silently if the file has already changed. |
| |
| my ($SRC, $BLD) = ($ENV{'LLVM_SRC'}, $ENV{'LLVM_BLD'}); |
| if (!$SRC || !$BLD || $ARGV[0] || ! -d $SRC || ! -d $BLD) { |
| die "Syntax: llvm-ycm\n\nUse llvm-env to set \$LLVM_SRC/BLD\n"; |
| } |
| my ($ycm_conf, $compile_db) = (".ycm_extra_conf.py", "compile_commands.json"); |
| |
| # If the file doesn't exist, don't try to guess the location of YCM-Generator |
| # Vim can do that on its own, if properly setup. Educate the user. |
| if (! -f "$SRC/$ycm_conf") { |
| die "$SRC/$ycm_conf doesn't exist!\n". |
| "You need to generate it using YCM-Generator.\n". |
| "\nTo install, run:\n". |
| " mkdir -p ~/.vim/ext\n". |
| " cd ~/.vim/ext\n". |
| " git clone https://github.com/rdnetto/YCM-Generator.git\n". |
| "\nTo enable in vim, add this line to your .vimrc:\n". |
| " set rtp+=~/.vim/ext/YCM-Generator\n". |
| "\nTo generate the file, open Vim inside your project and type:\n". |
| " :YcmGenerateConfig\n". |
| "\nIf all goes well, you should have an $ycm_conf in $SRC\n"; |
| } |
| |
| # If the compile database doesn't exist, there's no point in even trying. |
| # Educate the user. |
| if (! -f "$BLD/$compile_db") { |
| die "$BLD/$compile_db doesn't exist!\n". |
| "You need to generate it using LLVM's CMake file.\n". |
| "\nTo create the compile database every build, add this option to CMake:\n". |
| " -DCMAKE_EXPORT_COMPILE_COMMANDS=ON\n". |
| "\nRebuild, and check if the file is there, then run this script again.\n"; |
| } |
| |
| my @lines = (); |
| my $bld_re = $BLD; |
| $bld_re =~ s/\//\\\//g; |
| |
| # We need to open the file, buffer and close, so we can write back to the same |
| # file again. |
| open(FH, "$SRC/$ycm_conf") || die "Can't open file '$SRC/$ycm_conf': $!\n"; |
| foreach my $line (<FH>) { |
| # If the file has already been changed, let go. |
| if (&is_changed($line)) { |
| close FH; |
| exit(0); |
| } |
| |
| # Change lines if needed |
| &change(\$line); |
| |
| # Buffer |
| push @lines, $line; |
| } |
| close FH; |
| |
| # Now we write back and all should be good. |
| open(FH, ">$SRC/$ycm_conf") || die "Can't open file '$SRC/$ycm_conf': $!\n"; |
| foreach my $line (@lines) { |
| print FH $line; |
| } |
| close FH; |
| |
| # All is good. |
| exit(0); |
| |
| ################################ Methods |
| |
| # is_changed($line): checks whether the line has been changed by this script. |
| sub is_changed($) { |
| my ($line) = @_; |
| return ($line =~ /-I$bld_re/); |
| } |
| |
| # change($$line): change the line in-place to make it work with YCM. |
| sub change($) { |
| my ($line) = @_; |
| # from: -I/tmp/tmpUF9s_w/include |
| # to: -I$LLVM_BLD/include |
| my $changed = ($$line =~ s/\/tmp\/\w+/$BLD/); |
| return if ($changed); |
| |
| # Changing this line will make header and include files not work for |
| # completion, since they're not in the compilation database. Just using the |
| # whole lot of flags above works fine. |
| # from: compilation_database_folder = '' |
| # to: compilation_database_folder = '$LLVM_BLD' |
| #$$line =~ s/(compilation_database_folder) = ''/$1 = '$BLD'/; |
| } |