1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
#!/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'/;
}
|