Update.
This commit is contained in:
parent
8e84e9b2a3
commit
46a9040434
@ -1,254 +1,302 @@
|
||||
((("virtual" .
|
||||
[0 0 1 0 0 0 0])
|
||||
("slot" .
|
||||
[0 0 1 0])
|
||||
("hpp" .
|
||||
[1 0 0])
|
||||
("main" .
|
||||
[1 0 0 0])
|
||||
("oops" .
|
||||
[1 0 0 0])
|
||||
("struct" .
|
||||
[0 0 0 1 1 0])
|
||||
("sort" .
|
||||
[2 0 1 0])
|
||||
("yas-global-mode" .
|
||||
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 1])
|
||||
("algorithm" .
|
||||
[0 0 0 0 1 0 0 1 0])
|
||||
("alignas" .
|
||||
[0 0 1 0 0 0 0])
|
||||
("clock" .
|
||||
[1 0 0 0 0])
|
||||
("t1" .
|
||||
[1 0])
|
||||
("seq" .
|
||||
[1 0 0])
|
||||
("matrix" .
|
||||
[1 0 0 0 0 0])
|
||||
("range" .
|
||||
[1 0 0 0 0])
|
||||
("1:72" .
|
||||
[5 0 1 0])
|
||||
("scatterplot3d" .
|
||||
[0 0 0 0 0 0 0 0 0 0 0 0 1])
|
||||
("attach" .
|
||||
[1 0 0 0 0 0])
|
||||
("plot" .
|
||||
[1 0 0 0])
|
||||
("ncol" .
|
||||
[1 0 0 0])
|
||||
("nrow" .
|
||||
[2 0 0 0])
|
||||
("rgl::persp3d" .
|
||||
[0 0 0 0 0 0 0 0 0 1 0 0])
|
||||
("wireframe" .
|
||||
[0 0 0 0 1 0 0 0 0])
|
||||
("data" .
|
||||
[4 0 0 0])
|
||||
("ggplot" .
|
||||
[0 0 0 0 0 1])
|
||||
("library" .
|
||||
[7 0 0 0 0 0 0])
|
||||
("b" .
|
||||
[1])
|
||||
("auto" .
|
||||
[0 0 1 0])
|
||||
(":download_per_slot() const" .
|
||||
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1])
|
||||
("download_per_slot" .
|
||||
[0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0])
|
||||
("olsg" .
|
||||
[2 0 1 1])
|
||||
("(basic_ostream<_CharT, _Traits> &__os)" .
|
||||
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2])
|
||||
(":pdt() const" .
|
||||
[0 0 0 0 0 0 0 0 0 0 0 11])
|
||||
("pdt" .
|
||||
[3 1 11])
|
||||
("solve" .
|
||||
[6 0 0 0 1])
|
||||
("_instance" .
|
||||
[0 0 0 0 1 0 0 0 1])
|
||||
(":stations() const" .
|
||||
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5])
|
||||
("stations" .
|
||||
[12 0 3 2 4 2 0 7])
|
||||
("py_solution" .
|
||||
[2 0 1 0 1 0 0 0 0 0 0])
|
||||
("(int gen, ogsn::type_t type, int satellite" .
|
||||
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2])
|
||||
("cnes" .
|
||||
[1 0 0 1])
|
||||
("(int gen, ogsn::type_t type, int satellite{#, int year{#, int month#}#})" .
|
||||
[0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0])
|
||||
("make_instance" .
|
||||
[3 0 0 0 0 0 0 0 0 1 0 0 1])
|
||||
("instance" .
|
||||
[11 0 1 1 0 0 0 1])
|
||||
(":" .
|
||||
[3])
|
||||
("ogsn" .
|
||||
[9 0 3 2])
|
||||
("include" .
|
||||
[0 0 0 0 0 0 3])
|
||||
("begin" .
|
||||
[3 0 1 1 0])
|
||||
("()" .
|
||||
[0 9])
|
||||
("size" .
|
||||
[7 0 4 2])
|
||||
("at" .
|
||||
[0 1])
|
||||
("endl" .
|
||||
[8 0 1 6])
|
||||
("end" .
|
||||
[2 0 1])
|
||||
("cout" .
|
||||
[8 0 0 8])
|
||||
("vector" .
|
||||
[11 0 4 3 2 2])
|
||||
("std" .
|
||||
[66 0 7])
|
||||
("sol" .
|
||||
[2 0 1])
|
||||
("solution" .
|
||||
[7 0 0 5 2 2 2 6])
|
||||
("make_solution" .
|
||||
[2 0 0 0 0 0 1 1 1 0 0 0 0])
|
||||
("ilp_windows" .
|
||||
[1 0 0 0 0 1 1 2 0 0 0])
|
||||
("(const std::vector<bool> &)" .
|
||||
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2])
|
||||
("size_t" .
|
||||
[10 0 0 0 0 0])
|
||||
("_constraints" .
|
||||
[1 0 0 0 0 0 0 0 0 0 0 3])
|
||||
("x" .
|
||||
[1])
|
||||
("i" .
|
||||
[20])
|
||||
("_stations" .
|
||||
[3 0 0 0 0 1 0 0 0])
|
||||
(":solve()" .
|
||||
[0 0 0 0 0 0 0 2])
|
||||
("s" .
|
||||
[4])
|
||||
("percent_data_transfered" .
|
||||
[1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1])
|
||||
(":percent_data_transfered() const" .
|
||||
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1])
|
||||
("shared_ptr" .
|
||||
[5 0 0 0 0 1 1 0 0 0])
|
||||
("st_ilp" .
|
||||
[2 0 0 0 0 0])
|
||||
("mh" .
|
||||
[2 0])
|
||||
("solution_t" .
|
||||
[2 0 0 0 0 0 0 0 0 0])
|
||||
("keep" .
|
||||
[1 0 0 0])
|
||||
("stdin" .
|
||||
[0 0 0 1 0])
|
||||
("stationOn" .
|
||||
[2 0 0 0 0 0 0 0 0])
|
||||
("stationOff" .
|
||||
[2 0 0 0 0 0 0 0 0 0])
|
||||
("false" .
|
||||
[0 0 0 0 1])
|
||||
("_compute_pdt" .
|
||||
[0 0 0 0 0 1 0 0 2 0 0 0])
|
||||
("(std::vector<bool> stations)" .
|
||||
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3])
|
||||
("offPDT" .
|
||||
[3 0 0 0 0 0])
|
||||
("lastPDT" .
|
||||
[1 0 0 0 0 0 0])
|
||||
("onPDT" .
|
||||
[1 0 0 0 0])
|
||||
("gap_on2off" .
|
||||
[1 0 0 0 0 0 0 0 0 0])
|
||||
("gap_off2on" .
|
||||
[0 0 0 0 0 0 0 0 0 1])
|
||||
("ilp_prioritize" .
|
||||
[0 0 0 0 0 0 0 1 0 0 0 0 0 0])
|
||||
("ilpp" .
|
||||
[1 0 0 0])
|
||||
("_STDIO_H" .
|
||||
[0 0 0 0 0 0 0 1])
|
||||
("d" .
|
||||
[1])
|
||||
("int" .
|
||||
[0 0 1])
|
||||
("type_t" .
|
||||
[0 0 1 0 0 0])
|
||||
("y" .
|
||||
((("slot" .
|
||||
[0 0 0 1])
|
||||
(".debug-output" .
|
||||
[0 0 0 0 0 0 1 0 0 0 0 0 0])
|
||||
("ilp" .
|
||||
[4 0 0])
|
||||
("n" .
|
||||
[2])
|
||||
("m" .
|
||||
[6])
|
||||
("(const std::string &filename)" .
|
||||
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1])
|
||||
("type" .
|
||||
[3 0 0 0])
|
||||
("sat" .
|
||||
[2 0 0])
|
||||
("first_year" .
|
||||
[7 0 0 0 0 0 0 0 0 0])
|
||||
("last_year" .
|
||||
[3 0 0 0 0 0 0 0 0])
|
||||
("array" .
|
||||
[9 0 0 0 1])
|
||||
("n_solutions" .
|
||||
[4 0 1 2 1 1 0 0 0 0 0])
|
||||
("yb" .
|
||||
[4 0])
|
||||
("ym" .
|
||||
[2 0])
|
||||
("(std::shared_ptr<instance> instance)" .
|
||||
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2])
|
||||
("log" .
|
||||
("res" .
|
||||
[1 0 0])
|
||||
("pdts" .
|
||||
[3 0 0 0])
|
||||
("mb" .
|
||||
[1 0])
|
||||
("j" .
|
||||
[9])
|
||||
("instances" .
|
||||
[4 0 0 0 0 0 0 0 1])
|
||||
("solutions" .
|
||||
[4 0 0 0 0 0 0 0 0])
|
||||
("k" .
|
||||
[5])
|
||||
("l" .
|
||||
[3])
|
||||
("flush" .
|
||||
[0 0 0 0 1])
|
||||
("v" .
|
||||
[1])
|
||||
("p" .
|
||||
[1])
|
||||
("cerr" .
|
||||
[3 0 0 0])
|
||||
("c++-mode-common-hook" .
|
||||
[0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0])
|
||||
("defun" .
|
||||
[1 0 0 0 0])
|
||||
("auto-complete" .
|
||||
[0 0 0 0 0 0 0 0 0 0 0 0 1])
|
||||
("add-to-list" .
|
||||
[0 0 0 0 0 0 1 0 0 0 0])
|
||||
("ac-sources" .
|
||||
[0 0 0 0 0 0 0 1 0 0])
|
||||
("DATA_FOLDER" .
|
||||
[1 0 0 0 0 0 0 0 0 0 0])
|
||||
("environment" .
|
||||
[0 0 0 0 0 0 0 0 0 0 1])
|
||||
("usebox" .
|
||||
[0 0 0 2 0 1])
|
||||
("usepackage" .
|
||||
[0 0 0 0 1 4 2 0 0 0])
|
||||
("printf" .
|
||||
[12 0 0 0 0 0])
|
||||
("ac-source-c-headers" .
|
||||
[1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0])
|
||||
("require" .
|
||||
[2 0 0 0 0 0 0])
|
||||
("key-c-mode-setup" .
|
||||
[0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0])
|
||||
("c++-mode-hook" .
|
||||
[0 0 0 0 0 0 0 0 0 0 0 1 1])
|
||||
("local-set-key" .
|
||||
[1 0 0 0 0 0 0 0 0 0 0 0 0])
|
||||
("local" .
|
||||
[5 0 0 0 0])
|
||||
("add-hook" .
|
||||
[4 0 0 0 0 0 0 1])
|
||||
("fd-switch-dictionary" .
|
||||
[0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0])
|
||||
("LaTeX-mode-hook" .
|
||||
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 1])
|
||||
("LaTeX-mode" .
|
||||
[0 0 0 0 0 0 0 0 0 1])
|
||||
("français" .
|
||||
[0 0 0 0 0 0 1 0])
|
||||
("short" .
|
||||
[0 0 0 0 1])))
|
||||
("usepackage" .
|
||||
[0 0 0 0 1 4 2 0 0 0])
|
||||
("usebox" .
|
||||
[0 0 0 2 0 1])
|
||||
("environment" .
|
||||
[0 0 0 0 0 0 0 0 0 0 1])
|
||||
("DATA_FOLDER" .
|
||||
[1 0 0 0 0 0 0 0 0 0 0])
|
||||
("ac-sources" .
|
||||
[0 0 0 0 0 0 0 1 0 0])
|
||||
("add-to-list" .
|
||||
[0 0 0 0 0 0 1 0 0 0 1])
|
||||
("auto-complete" .
|
||||
[2 0 0 0 0 0 0 0 0 0 0 0 1])
|
||||
("defun" .
|
||||
[3 0 0 0 0])
|
||||
("c++-mode-common-hook" .
|
||||
[0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0])
|
||||
("cerr" .
|
||||
[3 0 0 0])
|
||||
("p" .
|
||||
[1])
|
||||
("v" .
|
||||
[1])
|
||||
("flush" .
|
||||
[0 0 0 0 1])
|
||||
("l" .
|
||||
[3])
|
||||
("k" .
|
||||
[5])
|
||||
("solutions" .
|
||||
[4 0 0 0 0 0 0 0 0])
|
||||
("instances" .
|
||||
[4 0 0 0 0 0 0 0 0])
|
||||
("j" .
|
||||
[9])
|
||||
("mb" .
|
||||
[1 0])
|
||||
("pdts" .
|
||||
[3 0 0 0])
|
||||
("log" .
|
||||
[1 0 0])
|
||||
("(std::shared_ptr<instance> instance)" .
|
||||
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2])
|
||||
("ym" .
|
||||
[2 0])
|
||||
("yb" .
|
||||
[4 0])
|
||||
("n_solutions" .
|
||||
[4 0 1 2 1 1 0 0 0 0 0])
|
||||
("array" .
|
||||
[9 0 0 0 0])
|
||||
("last_year" .
|
||||
[3 0 0 0 0 0 0 0 0])
|
||||
("first_year" .
|
||||
[7 0 0 0 0 0 0 0 0 0])
|
||||
("sat" .
|
||||
[2 0 0])
|
||||
("type" .
|
||||
[3 0 0 0])
|
||||
("(const std::string &filename)" .
|
||||
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1])
|
||||
("m" .
|
||||
[6])
|
||||
("y" .
|
||||
[2])
|
||||
("type_t" .
|
||||
[0 0 1 0 0 0])
|
||||
("int" .
|
||||
[0 0 1])
|
||||
("d" .
|
||||
[1])
|
||||
("_STDIO_H" .
|
||||
[0 0 0 0 0 0 0 1])
|
||||
("ilpp" .
|
||||
[1 0 0 1])
|
||||
("ilp_prioritize" .
|
||||
[0 0 0 0 0 0 0 1 0 0 0 0 0 0])
|
||||
("gap_off2on" .
|
||||
[0 0 0 0 0 0 0 0 0 1])
|
||||
("gap_on2off" .
|
||||
[1 0 0 0 0 0 0 0 0 0])
|
||||
("onPDT" .
|
||||
[1 0 0 0 0])
|
||||
("lastPDT" .
|
||||
[1 0 0 0 0 0 0])
|
||||
("offPDT" .
|
||||
[3 0 0 0 0 0])
|
||||
("(std::vector<bool> stations)" .
|
||||
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3])
|
||||
("_compute_pdt" .
|
||||
[0 0 0 0 0 1 0 0 2 0 0 0])
|
||||
("false" .
|
||||
[0 0 0 0 1])
|
||||
("stationOff" .
|
||||
[2 0 0 0 0 0 0 0 0 0])
|
||||
("stationOn" .
|
||||
[2 0 0 0 0 0 0 0 0])
|
||||
("stdin" .
|
||||
[0 0 0 1 0])
|
||||
("keep" .
|
||||
[1 0 0 0])
|
||||
("solution_t" .
|
||||
[2 0 0 0 0 0 0 0 0 0])
|
||||
("mh" .
|
||||
[2 0])
|
||||
("st_ilp" .
|
||||
[2 0 0 0 0 0])
|
||||
("shared_ptr" .
|
||||
[8 0 0 0 0 0 1 0 0 2])
|
||||
(":percent_data_transfered() const" .
|
||||
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1])
|
||||
("percent_data_transfered" .
|
||||
[1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1])
|
||||
("s" .
|
||||
[3])
|
||||
(":solve()" .
|
||||
[0 0 0 0 0 0 0 2])
|
||||
("_stations" .
|
||||
[3 0 0 0 0 1 0 0 0])
|
||||
("i" .
|
||||
[20])
|
||||
("x" .
|
||||
[1])
|
||||
("_constraints" .
|
||||
[1 0 0 0 0 0 0 0 0 0 0 3])
|
||||
("size_t" .
|
||||
[10 0 0 0 0 0])
|
||||
("(const std::vector<bool> &)" .
|
||||
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2])
|
||||
("ilp_windows" .
|
||||
[1 0 0 0 0 1 1 2 0 0 0])
|
||||
("make_solution" .
|
||||
[2 0 0 0 0 0 1 1 2 0 0 0 0])
|
||||
("solution" .
|
||||
[7 0 0 5 2 2 2 12])
|
||||
("sol" .
|
||||
[16 0 1])
|
||||
("std" .
|
||||
[62 0 7])
|
||||
("vector" .
|
||||
[10 0 2 3 1 1])
|
||||
("cout" .
|
||||
[8 0 0 8])
|
||||
("end" .
|
||||
[2 0 1])
|
||||
("endl" .
|
||||
[8 0 1 6])
|
||||
("at" .
|
||||
[0 1])
|
||||
("size" .
|
||||
[7 0 4 2])
|
||||
("()" .
|
||||
[0 11])
|
||||
("begin" .
|
||||
[3 0 1 1 0])
|
||||
("include" .
|
||||
[0 0 0 0 0 0 4])
|
||||
("ogsn" .
|
||||
[15 0 2 3])
|
||||
(":" .
|
||||
[3])
|
||||
("instance" .
|
||||
[8 0 1 2 1 0 0 4])
|
||||
("make_instance" .
|
||||
[3 0 0 0 1 0 0 0 0 0 0 0 1])
|
||||
("(int gen, ogsn::type_t type, int satellite{#, int year{#, int month#}#})" .
|
||||
[0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0])
|
||||
("cnes" .
|
||||
[1 0 0 1])
|
||||
("(int gen, ogsn::type_t type, int satellite" .
|
||||
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4])
|
||||
("py_solution" .
|
||||
[2 0 2 0 3 0 0 0 0 0 0])
|
||||
("stations" .
|
||||
[12 0 3 2 4 2 0 8])
|
||||
(":stations() const" .
|
||||
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5])
|
||||
("_instance" .
|
||||
[0 0 0 0 1 0 0 0 1])
|
||||
("solve" .
|
||||
[6 0 0 0 1])
|
||||
("pdt" .
|
||||
[3 1 14])
|
||||
(":pdt() const" .
|
||||
[0 0 0 0 0 0 0 0 0 0 0 11])
|
||||
("(basic_ostream<_CharT, _Traits> &__os)" .
|
||||
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2])
|
||||
("olsg" .
|
||||
[2 0 1 1])
|
||||
("download_per_slot" .
|
||||
[0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0])
|
||||
(":download_per_slot() const" .
|
||||
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1])
|
||||
("auto" .
|
||||
[0 0 1 0])
|
||||
("b" .
|
||||
[1])
|
||||
("library" .
|
||||
[7 0 0 0 0 0 0])
|
||||
("ggplot" .
|
||||
[0 0 0 0 0 1])
|
||||
("data" .
|
||||
[4 0 0 0])
|
||||
("wireframe" .
|
||||
[0 0 0 0 1 0 0 0 0])
|
||||
("rgl::persp3d" .
|
||||
[0 0 0 0 0 0 0 0 0 1 0 0])
|
||||
("nrow" .
|
||||
[2 0 0 0])
|
||||
("ncol" .
|
||||
[1 0 0 0])
|
||||
("plot" .
|
||||
[1 0 0 0])
|
||||
("attach" .
|
||||
[1 0 0 0 0 0])
|
||||
("scatterplot3d" .
|
||||
[0 0 0 0 0 0 0 0 0 0 0 0 1])
|
||||
("1:72" .
|
||||
[5 0 1 0])
|
||||
("range" .
|
||||
[1 0 0 0 0])
|
||||
("matrix" .
|
||||
[1 0 0 0 0 0])
|
||||
("seq" .
|
||||
[1 0 0])
|
||||
("t1" .
|
||||
[1 0])
|
||||
("clock" .
|
||||
[1 0 0 0 0])
|
||||
("alignas" .
|
||||
[0 0 1 0 0 0 0])
|
||||
("algorithm" .
|
||||
[0 0 0 0 1 0 0 1 0])
|
||||
("yas-global-mode" .
|
||||
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 1])
|
||||
("sort" .
|
||||
[2 0 1 0])
|
||||
("struct" .
|
||||
[0 0 0 1 1 0])
|
||||
("oops" .
|
||||
[1 0 0 0])
|
||||
("package-install" .
|
||||
[2 0 0 0 0 0 0 0 0 0 0 0 0 0 3])
|
||||
("ac-math" .
|
||||
[1 0 0 0 0 0 0])
|
||||
("auto-complete-c-headers" .
|
||||
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0])
|
||||
("auto-complete-clang-async" .
|
||||
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0])
|
||||
("global-auto-complete-mode" .
|
||||
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1])
|
||||
("c-mode-hook" .
|
||||
[0 0 0 0 0 0 0 0 0 0 1])
|
||||
("ac-cc-mode-setup" .
|
||||
[0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0])
|
||||
("c-mode-common-hook" .
|
||||
[0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0])
|
||||
("ins" .
|
||||
[6 0 0])
|
||||
("make_instance_path" .
|
||||
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0])
|
||||
("slots" .
|
||||
[0 0 1 1 2])
|
||||
("visibility_windows" .
|
||||
[0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0])
|
||||
("static" .
|
||||
[0 0 0 1 1 1])))
|
||||
|
@ -1,6 +0,0 @@
|
||||
/home/mcapelle/.emacs.el
|
||||
/home/mcapelle/#.emacs.el#
|
||||
/home/mcapelle/.bashrc
|
||||
/home/mcapelle/#.bashrc#
|
||||
/home/mcapelle/.softwares/emacs-24.5/share/emacs/24.5/lisp/loaddefs.el
|
||||
/home/mcapelle/.softwares/emacs-24.5/share/emacs/24.5/lisp/#loaddefs.el#
|
Binary file not shown.
1
.emacs.d/clang-complete
Symbolic link
1
.emacs.d/clang-complete
Symbolic link
@ -0,0 +1 @@
|
||||
/home/mcapelle/.emacs.d/sources/emacs-clang-complete-async/clang-complete
|
@ -3,8 +3,9 @@
|
||||
;;; Code:
|
||||
(add-to-list 'load-path (or (file-name-directory #$) (car load-path)))
|
||||
|
||||
;;;### (autoloads nil nil ("ac-c-headers.el") (22213 27915 34914
|
||||
;;;;;; 134000))
|
||||
;;;### (autoloads nil nil ("../../../../../.emacs.d/elpa/ac-c-headers-20151021.134/ac-c-headers-autoloads.el"
|
||||
;;;;;; "../../../../../.emacs.d/elpa/ac-c-headers-20151021.134/ac-c-headers.el")
|
||||
;;;;;; (22218 60999 748736 242000))
|
||||
|
||||
;;;***
|
||||
|
||||
|
@ -1,11 +0,0 @@
|
||||
;;; ac-c-headers-autoloads.el --- automatically extracted autoloads
|
||||
;;
|
||||
;;; Code:
|
||||
(add-to-list 'load-path (or (file-name-directory #$) (car load-path)))
|
||||
|
||||
;; Local Variables:
|
||||
;; version-control: never
|
||||
;; no-byte-compile: t
|
||||
;; no-update-autoloads: t
|
||||
;; End:
|
||||
;;; ac-c-headers-autoloads.el ends here
|
Binary file not shown.
Binary file not shown.
@ -1,16 +0,0 @@
|
||||
;;; ac-clang-autoloads.el --- automatically extracted autoloads
|
||||
;;
|
||||
;;; Code:
|
||||
(add-to-list 'load-path (or (file-name-directory #$) (car load-path)))
|
||||
|
||||
;;;### (autoloads nil nil ("ac-clang-pkg.el" "ac-clang.el") (22209
|
||||
;;;;;; 51595 894686 65000))
|
||||
|
||||
;;;***
|
||||
|
||||
;; Local Variables:
|
||||
;; version-control: never
|
||||
;; no-byte-compile: t
|
||||
;; no-update-autoloads: t
|
||||
;; End:
|
||||
;;; ac-clang-autoloads.el ends here
|
@ -1,11 +0,0 @@
|
||||
;;; ac-clang-autoloads.el --- automatically extracted autoloads
|
||||
;;
|
||||
;;; Code:
|
||||
(add-to-list 'load-path (or (file-name-directory #$) (car load-path)))
|
||||
|
||||
;; Local Variables:
|
||||
;; version-control: never
|
||||
;; no-byte-compile: t
|
||||
;; no-update-autoloads: t
|
||||
;; End:
|
||||
;;; ac-clang-autoloads.el ends here
|
@ -1,11 +0,0 @@
|
||||
(define-package "ac-clang" "20150906.1008" "Auto Completion source by libclang for GNU Emacs"
|
||||
'((emacs "24")
|
||||
(cl-lib "0.5")
|
||||
(auto-complete "1.4.0")
|
||||
(pos-tip "0.4.6")
|
||||
(yasnippet "0.8.0"))
|
||||
:url "https://github.com/yaruopooner/ac-clang" :keywords
|
||||
'("completion" "convenience" "intellisense"))
|
||||
;; Local Variables:
|
||||
;; no-byte-compile: t
|
||||
;; End:
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -1,26 +0,0 @@
|
||||
@rem @set PATH=c:/cygwin-x86_64/tmp/cmake-3.0.2-win32-x86/bin;%PATH%
|
||||
@set PATH=c:/cygwin-x86_64/tmp/cmake-3.3.1-win32-x86/bin;%PATH%
|
||||
|
||||
|
||||
@del /Q CMakeCache.txt
|
||||
@del /Q cmake_install.cmake
|
||||
@rmdir /Q /S CMakeFiles
|
||||
@rmdir /Q /S clang-server-x86_64.dir
|
||||
|
||||
|
||||
@rem cmake -G "Visual Studio 12 2013 Win64" ../clang-server
|
||||
@rem cmake -G "Visual Studio 12 2013 Win64" ../clang-server -DCMAKE_INSTALL_PREFIX="c:/cygwin-x86_64/usr/local/bin/"
|
||||
@rem cmake -G "Visual Studio 12 2013 Win64" ../clang-server -DLIBRARY_PATHS="c:/cygwin-x86_64/tmp/llvm-build-shells/ps1/clang-370/build/msvc-64/"
|
||||
rem cmake -G "Visual Studio 12 2013 Win64" ../clang-server -DLIBRARY_PATHS="c:/cygwin-x86_64/tmp/llvm-build-shells/ps1/clang-370/build/msvc-64/" -DCMAKE_INSTALL_PREFIX="c:/cygwin-x86_64/usr/local/bin/"
|
||||
rem cmake -G "Visual Studio 12 2013 Win64" ../clang-server -DLIBRARY_PATHS="c:/cygwin-x86_64/tmp/llvm-build-shells/ps1/clang-370/build/msvc-64/Release/" -DCMAKE_INSTALL_PREFIX="c:/cygwin-x86_64/usr/local/bin/"
|
||||
cmake -G "Visual Studio 14 2015 Win64" ../clang-server -DLIBRARY_PATHS="c:/cygwin-x86_64/tmp/llvm-build-shells/ps1/clang-370/build/msvc-64/Release/" -DCMAKE_INSTALL_PREFIX="c:/cygwin-x86_64/usr/local/bin/"
|
||||
rem cmake -G "Visual Studio 12 2013" ../clang-server -DLIBRARY_PATHS="c:/cygwin-x86_64/tmp/llvm-build-shells/ps1/clang-370/build/msvc-32/Release/" -DCMAKE_INSTALL_PREFIX="c:/cygwin-x86_64/usr/local/bin/"
|
||||
@pause
|
||||
|
||||
@rem cmake --build . [--config <config>] [--target <target>] [-- -i]
|
||||
@rem cmake --build . --config Release --target ALL_BUILD
|
||||
@rem cmake --build . --config Debug --target ALL_BUILD
|
||||
cmake --build . --config Release --target INSTALL
|
||||
@rem cmake --build . --config Debug --target INSTALL
|
||||
|
||||
@pause
|
@ -1,28 +0,0 @@
|
||||
# -*- mode: shell-script ; coding: utf-8-unix -*-
|
||||
#! /bin/sh
|
||||
# export PATH="/cygdrive/c/cygwin-x86_64/tmp/cmake-3.1.0-win32-x86/bin/:$PATH"
|
||||
|
||||
rm -rf CMakeCache.txt
|
||||
rm -rf cmake_install.cmake
|
||||
rm -rf CMakeFiles
|
||||
rm -rf Makefile
|
||||
|
||||
# switch compiler
|
||||
# export CC=clang
|
||||
# export CXX=clang++
|
||||
|
||||
# cmake --version
|
||||
# cmake -G "Unix Makefiles" ../clang-server -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
|
||||
# cmake -G "Unix Makefiles" ../clang-server -DLIBRARY_PATHS="c:/cygwin-x86_64/tmp/llvm-build-shells/sh/clang-361/build" -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
|
||||
cmake -G "Unix Makefiles" ../clang-server -DLIBRARY_PATHS="/home/yaruopooner/work/llvm-build-shells/sh/clang-361/build" -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
|
||||
# cmake -G "Unix Makefiles" ../clang-server -DLIBRARY_PATHS="/home/yaruopooner/work/llvm-build-shells/sh/clang-361/build" -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=RELWITHDEBINFO
|
||||
# cmake -G "Unix Makefiles" ../clang-server -DLIBRARY_PATHS="/home/yaruopooner/work/llvm-build-shells/sh/clang-361/build" -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=DEBUG
|
||||
# cmake -G "Unix Makefiles" ../clang-server -DLIBRARY_PATHS="/home/yaruopooner/work/llvm-build-shells/sh/clang-361/build" -DCMAKE_INSTALL_PREFIX="~/work/test" -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
|
||||
|
||||
# echo "please press Enter key"
|
||||
# read discard_tmp
|
||||
|
||||
cmake --build .
|
||||
# sudo make install
|
||||
|
||||
|
@ -1,383 +0,0 @@
|
||||
# -*- mode: cmake ; coding: utf-8-unix -*-
|
||||
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
cmake_policy(SET CMP0015 NEW)
|
||||
cmake_policy(SET CMP0022 NEW)
|
||||
|
||||
include(CheckCXXCompilerFlag)
|
||||
|
||||
|
||||
# ----------------------------------------
|
||||
# before common setting
|
||||
# ----------------------------------------
|
||||
|
||||
set(project_name clang-server)
|
||||
# set(platform_name x86_64)
|
||||
# set(platform_name x86_32)
|
||||
# set(project_elf_name ${project_name}-${platform_name})
|
||||
set(project_elf_name ${project_name})
|
||||
|
||||
|
||||
# CMAKE_INSTALL_PREFIX check designated value before function Project()
|
||||
if(CMAKE_INSTALL_PREFIX)
|
||||
# message("user_install_prefix TRUE")
|
||||
set(user_install_prefix TRUE)
|
||||
else()
|
||||
# message("user_install_prefix FALSE")
|
||||
endif()
|
||||
|
||||
|
||||
# The set before project declaration.
|
||||
set(CMAKE_CONFIGURATION_TYPES Release RelWithDebInfo Debug CACHE TYPE INTERNAL FORCE)
|
||||
# setup library per configuration
|
||||
string(TOUPPER "${CMAKE_CONFIGURATION_TYPES}" project_configurations)
|
||||
|
||||
|
||||
Project(${project_name})
|
||||
|
||||
|
||||
# The set after project declaration.
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
|
||||
# CMAKE_INSTALL_PREFIX
|
||||
# Windows (exe,dll)
|
||||
# Default: C:/Program Files/clang-server/
|
||||
# prefix : <user designate directory>
|
||||
#
|
||||
# Linux (elf)
|
||||
# Default: /usr/local/bin/
|
||||
# prefix : <user designate directory>
|
||||
# Linux (so)
|
||||
# Default: /usr/local/lib/clang-server/
|
||||
# prefix : <user designate directory>
|
||||
|
||||
set(CMAKE_SKIP_RPATH TRUE)
|
||||
# set(CMAKE_SKIP_BUILD_RPATH FALSE)
|
||||
# set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
|
||||
# set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||
# set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib)
|
||||
|
||||
|
||||
set(project_sources main.cpp ClangServer.cpp ClangServer.hpp ClangSession.cpp ClangSession.hpp Common.cpp Common.hpp CommandLine.hpp)
|
||||
|
||||
|
||||
add_library(libclang SHARED IMPORTED)
|
||||
|
||||
set(dependency_libraries libclang)
|
||||
|
||||
|
||||
list(APPEND CMAKE_FIND_LIBRARY_PREFIXES lib)
|
||||
list(REMOVE_DUPLICATES CMAKE_FIND_LIBRARY_PREFIXES)
|
||||
|
||||
# set(libclang_names clang-${platform_name} clang)
|
||||
set(libclang_names clang)
|
||||
|
||||
|
||||
function(display_vars vars prefix)
|
||||
message("${prefix}")
|
||||
foreach(IT ${vars})
|
||||
message("${prefix}${IT} = ${${IT}}")
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
|
||||
set(echo_vars)
|
||||
list(APPEND echo_vars CMAKE_CXX_COMPILER_ID CMAKE_CXX_STANDARD CYGWIN WIN32 UNIX MSVC MSVC_VERSION CMAKE_GNUtoMS CMAKE_SYSTEM_NAME CMAKE_COMPILER_IS_GNUC CMAKE_COMPILER_IS_GNUCXX CMAKE_COMPILER_IS_MINGW CMAKE_COMPILER_IS_CYGWIN)
|
||||
display_vars("${echo_vars}" "env: ")
|
||||
|
||||
|
||||
# ----------------------------------------
|
||||
# platform dependency setting
|
||||
# ----------------------------------------
|
||||
|
||||
if(MSVC)
|
||||
# ----------------------------------------
|
||||
# Microsoft Visual Studio
|
||||
# ----------------------------------------
|
||||
message("environment: MSVC")
|
||||
|
||||
set(echo_vars)
|
||||
list(APPEND echo_vars CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE)
|
||||
list(APPEND echo_vars CMAKE_EXE_LINKER_FLAGS CMAKE_EXE_LINKER_FLAGS_DEBUG CMAKE_EXE_LINKER_FLAGS_RELEASE)
|
||||
list(APPEND echo_vars IMPORTED_IMPLIB IMPORTED_IMPLIB_DEBUG IMPORTED_IMPLIB_RELEASE)
|
||||
display_vars("${echo_vars}" "msvc: ")
|
||||
|
||||
|
||||
# set_target_properties(TARGET)
|
||||
|
||||
# setup compile & link flags
|
||||
set(project_defs -D_CONSOLE -DUNICODE -D_UNICODE -D_CRT_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "/GR /EHsc /W3 /Zi")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "/Gm /Od")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "/GL /Gy /Oi")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG}")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG /DEBUG /OPT:ICF /OPT:REF")
|
||||
|
||||
set(dependency_libraries odbc32 odbccp32 ${dependency_libraries})
|
||||
|
||||
|
||||
# search & setup link library properties
|
||||
list(INSERT CMAKE_FIND_LIBRARY_SUFFIXES 0 .imp)
|
||||
list(REMOVE_DUPLICATES CMAKE_FIND_LIBRARY_SUFFIXES)
|
||||
|
||||
|
||||
# search priority EXTERNAL > CURRENT
|
||||
set(libclang_search_paths ${LIBRARY_PATHS} ${CMAKE_SOURCE_DIR})
|
||||
|
||||
foreach(IT_SEARCH_PATH ${libclang_search_paths})
|
||||
message("")
|
||||
message("IT_SEARCH_PATH : ${IT_SEARCH_PATH}")
|
||||
|
||||
# collect absolute file paths
|
||||
file(GLOB_RECURSE collected_library_apath ${IT_SEARCH_PATH} ${IT_SEARCH_PATH}/*.imp ${IT_SEARCH_PATH}/*.lib ${IT_SEARCH_PATH}/*.dll)
|
||||
|
||||
if(collected_library_apath)
|
||||
# generate absolute directory paths
|
||||
set(library_apaths ${IT_SEARCH_PATH})
|
||||
foreach(IT_PATH ${collected_library_apath})
|
||||
get_filename_component(library_dir_path ${IT_PATH} DIRECTORY)
|
||||
list(APPEND library_apaths ${library_dir_path})
|
||||
endforeach()
|
||||
list(REMOVE_DUPLICATES library_apaths)
|
||||
|
||||
# message("collected_library_apath : ${collected_library_apath}")
|
||||
message("library_apaths : ${library_apaths}")
|
||||
|
||||
# find library > generate relative path > set property per configuration.
|
||||
foreach(IT_CONFIG ${project_configurations})
|
||||
if(NOT matched_${IT_CONFIG})
|
||||
# collect a absolute path that includes the same configuration name.
|
||||
# IT_SEARCH_PATH is always accept.
|
||||
# set(filtered_library_apaths ${IT_SEARCH_PATH})
|
||||
# foreach(IT_PATH ${library_apaths})
|
||||
# string(TOUPPER ${IT_PATH} CHECK_PATH_STR)
|
||||
# if(${CHECK_PATH_STR} MATCHES /${IT_CONFIG})
|
||||
# list(APPEND filtered_library_apaths ${IT_PATH})
|
||||
# endif()
|
||||
# endforeach()
|
||||
# set(filtered_library_apaths ${library_apaths})
|
||||
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES .imp .lib)
|
||||
find_library(libclang_${IT_CONFIG}_found_lib_apath NAMES ${libclang_names} PATHS ${library_apaths} NO_DEFAULT_PATH)
|
||||
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES .dll)
|
||||
find_library(libclang_${IT_CONFIG}_found_dll_apath NAMES ${libclang_names} PATHS ${library_apaths} NO_DEFAULT_PATH)
|
||||
|
||||
display_vars("library_apaths;libclang_${IT_CONFIG}_found_lib_apath;libclang_${IT_CONFIG}_found_dll_apath" "${IT_CONFIG}: ")
|
||||
|
||||
if(libclang_${IT_CONFIG}_found_lib_apath AND libclang_${IT_CONFIG}_found_dll_apath)
|
||||
file(RELATIVE_PATH libclang_${IT_CONFIG}_rpath ${IT_SEARCH_PATH} ${libclang_${IT_CONFIG}_found_lib_apath})
|
||||
|
||||
set_property(TARGET libclang PROPERTY IMPORTED_IMPLIB_${IT_CONFIG} ${libclang_${IT_CONFIG}_rpath})
|
||||
set_property(TARGET libclang PROPERTY INTERFACE_LINK_LIBRARIES_${IT_CONFIG} ${libclang_${IT_CONFIG}_rpath})
|
||||
set_property(TARGET libclang PROPERTY IMPORTED_LOCATION_${IT_CONFIG} ${libclang_${IT_CONFIG}_found_lib_apath})
|
||||
link_directories(${IT_SEARCH_PATH})
|
||||
|
||||
set(libclang_${IT_CONFIG}_found_apath ${libclang_${IT_CONFIG}_found_dll_apath})
|
||||
message("${IT_CONFIG}: found library at ${IT_SEARCH_PATH}")
|
||||
set(matched_${IT_CONFIG} TRUE)
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
|
||||
# install info
|
||||
set(binary_destination_apath ${CMAKE_INSTALL_PREFIX})
|
||||
set(library_destination_apath ${CMAKE_INSTALL_PREFIX})
|
||||
|
||||
|
||||
if(NOT (matched_DEBUG OR matched_RELEASE OR matched_MINSIZEREL OR matched_RELWITHDEBINFO))
|
||||
message("not found library")
|
||||
endif()
|
||||
|
||||
elseif(UNIX)
|
||||
# ----------------------------------------
|
||||
# UNIX, Linux
|
||||
# ----------------------------------------
|
||||
message("environment: UNIX")
|
||||
|
||||
# setup compile & link flags
|
||||
check_cxx_compiler_flag(-std=c++11 COMPILER_SUPPORTS_CXX11)
|
||||
check_cxx_compiler_flag(-std=c++0x COMPILER_SUPPORTS_CXX0X)
|
||||
|
||||
# setup compile & link flags
|
||||
if(COMPILER_SUPPORTS_CXX11)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
elseif(COMPILER_SUPPORTS_CXX0X)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
|
||||
else()
|
||||
message(FATAL_ERROR "The compiler has no C++11 support.")
|
||||
endif()
|
||||
|
||||
# set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wunused-result")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-unused-result")
|
||||
|
||||
|
||||
# search priority EXTERNAL > CURRENT
|
||||
|
||||
if(CYGWIN)
|
||||
message("CYGWIN")
|
||||
# set(dependency_libraries clang.dll)
|
||||
# set(dependency_libraries libclang.a)
|
||||
|
||||
# find_library(CYG_LIBCLANG_PATH NAMES clang.dll PATHS ${library_apaths})
|
||||
# find_library(CYG_LIBCLANG_PATH NAMES libclang.dll clang.dll clang PATHS "/lib" "c:/cygwin-x86_64/lib" )
|
||||
# find_library(CYG_LIBCLANG_PATH NAMES libclang.dll PATHS "/lib" "c:/cygwin-x86_64/lib" )
|
||||
# find_library(CYG_LIBCLANG_PATH NAMES libclang libclang.dll PATHS "c:/cygwin-x86_64/lib" )
|
||||
message("CYG_LIBCLANG_PATH : ${CYG_LIBCLANG_PATH}")
|
||||
|
||||
else()
|
||||
message("non CYGWIN")
|
||||
endif()
|
||||
|
||||
|
||||
# search priority EXTERNAL > CURRENT
|
||||
set(libclang_search_paths ${LIBRARY_PATHS} ${CMAKE_SOURCE_DIR})
|
||||
|
||||
foreach(IT_SEARCH_PATH ${libclang_search_paths})
|
||||
message("IT_SEARCH_PATH : ${IT_SEARCH_PATH}")
|
||||
|
||||
# collect absolute file paths
|
||||
file(GLOB_RECURSE collected_library_apath ${IT_SEARCH_PATH} ${IT_SEARCH_PATH}/*.so ${IT_SEARCH_PATH}/*.a)
|
||||
|
||||
if(collected_library_apath)
|
||||
# generate absolute directory paths
|
||||
set(library_apaths ${IT_SEARCH_PATH})
|
||||
foreach(IT_PATH ${collected_library_apath})
|
||||
get_filename_component(library_dir_path ${IT_PATH} DIRECTORY)
|
||||
list(APPEND library_apaths ${library_dir_path})
|
||||
endforeach()
|
||||
list(REMOVE_DUPLICATES library_apaths)
|
||||
|
||||
# message("collected_library_apath : ${collected_library_apath}")
|
||||
message("library_apaths : ${library_apaths}")
|
||||
|
||||
# find library > generate relative path > set property per configuration.
|
||||
foreach(IT_CONFIG ${project_configurations})
|
||||
if(NOT matched_${IT_CONFIG})
|
||||
# find library > generate relative path
|
||||
find_library(libclang_${IT_CONFIG}_found_apath NAMES ${libclang_names} PATHS ${library_apaths} NO_DEFAULT_PATH)
|
||||
|
||||
display_vars("libclang_${IT_CONFIG}_found_apath" "${IT_CONFIG}: ")
|
||||
|
||||
if(libclang_${IT_CONFIG}_found_apath)
|
||||
# message("found library at ${libclang_${IT_CONFIG}_found_apath}")
|
||||
get_filename_component(libclang_link_apath ${libclang_${IT_CONFIG}_found_apath} DIRECTORY)
|
||||
link_directories(${libclang_link_apath})
|
||||
get_filename_component(libclang_found_name ${libclang_${IT_CONFIG}_found_apath} NAME_WE)
|
||||
string(REGEX REPLACE "^lib" "" libclang_found_name ${libclang_found_name})
|
||||
|
||||
# message("libclang_found_name at ${libclang_found_name}")
|
||||
set_property(TARGET libclang PROPERTY INTERFACE_LINK_LIBRARIES_${IT_CONFIG} ${libclang_found_name})
|
||||
set_property(TARGET libclang PROPERTY IMPORTED_LOCATION_${IT_CONFIG} ${libclang_${IT_CONFIG}_found_apath})
|
||||
message("${IT_CONFIG}: found library at ${libclang_link_apath}")
|
||||
set(matched_${IT_CONFIG} TRUE)
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
|
||||
# install info
|
||||
if(user_install_prefix)
|
||||
string(REGEX REPLACE "^~" "$ENV{HOME}" CMAKE_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX})
|
||||
get_filename_component(CMAKE_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX} ABSOLUTE)
|
||||
set(binary_destination_apath ${CMAKE_INSTALL_PREFIX})
|
||||
set(library_destination_apath ${CMAKE_INSTALL_PREFIX})
|
||||
else()
|
||||
set(binary_destination_apath ${CMAKE_INSTALL_PREFIX}/bin)
|
||||
set(library_destination_apath ${CMAKE_INSTALL_PREFIX}/lib/${project_name})
|
||||
endif()
|
||||
|
||||
|
||||
# The rpath is runtime library search path. The rpath specify path where you want to install a shared object.
|
||||
set(CMAKE_EXE_LINKER_FLAGS "-Wl,-rpath,${library_destination_apath}")
|
||||
|
||||
|
||||
if(NOT (matched_DEBUG OR matched_RELEASE OR matched_MINSIZEREL OR matched_RELWITHDEBINFO))
|
||||
message("not found library")
|
||||
endif()
|
||||
|
||||
|
||||
else()
|
||||
|
||||
message("sorry, not support environment")
|
||||
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
# ----------------------------------------
|
||||
# after common setting
|
||||
# ----------------------------------------
|
||||
|
||||
add_executable(${project_name} ${project_sources})
|
||||
|
||||
# set_property(TARGET ${project_name} PROPERTY CXX_STANDARD 11)
|
||||
|
||||
set_property(TARGET ${project_name} PROPERTY OUTPUT_NAME_DEBUG "${project_elf_name}-debug")
|
||||
set_property(TARGET ${project_name} PROPERTY OUTPUT_NAME_RELEASE "${project_elf_name}")
|
||||
# set_property(TARGET ${project_name} PROPERTY OUTPUT_NAME_MINSIZEREL "${project_elf_name}")
|
||||
set_property(TARGET ${project_name} PROPERTY OUTPUT_NAME_RELWITHDEBINFO "${project_elf_name}-reldbg")
|
||||
|
||||
|
||||
list(APPEND project_defs -DCMAKE_GENERATOR="${CMAKE_GENERATOR}" -DCMAKE_HOST_SYSTEM_PROCESSOR="${CMAKE_HOST_SYSTEM_PROCESSOR}")
|
||||
|
||||
# list(APPEND project_defs CMAKE_GENERATOR="${CMAKE_GENERATOR}")
|
||||
# set_property(TARGET ${project_name} PROPERTY COMPILE_DEFINITIONS ${project_defs})
|
||||
# set_property(TARGET ${project_name} PROPERTY COMPILE_DEFINITIONS_DEBUG ${project_defs})
|
||||
# set_property(TARGET ${project_name} PROPERTY COMPILE_DEFINITIONS_RELEASE ${project_defs})
|
||||
add_definitions(${project_defs})
|
||||
|
||||
include_directories(./)
|
||||
|
||||
|
||||
target_link_libraries(${project_name} ${dependency_libraries})
|
||||
|
||||
|
||||
# ----------------------------------------
|
||||
# install setting
|
||||
# ----------------------------------------
|
||||
|
||||
set(CMAKE_INSTALL_RPATH ${library_destination_apath})
|
||||
install(TARGETS ${project_name} RUNTIME DESTINATION ${binary_destination_apath})
|
||||
foreach(IT_CONFIG ${project_configurations})
|
||||
install(FILES ${libclang_${IT_CONFIG}_found_apath} DESTINATION ${library_destination_apath} CONFIGURATIONS ${IT_CONFIG})
|
||||
endforeach()
|
||||
|
||||
|
||||
|
||||
# ----------------------------------------
|
||||
# debug display for variables
|
||||
# ----------------------------------------
|
||||
|
||||
|
||||
# get_directory_property(DirDefs DIRECTORY ${CMAKE_SOURCE_DIR} COMPILE_DEFINITIONS)
|
||||
# foreach(IT_DEF ${DirDefs})
|
||||
# message(STATUS "Found Define: " ${IT_DEF})
|
||||
# endforeach()
|
||||
# message( "DirDefs: " ${DirDefs} )
|
||||
|
||||
set(echo_vars)
|
||||
list(APPEND echo_vars CMAKE_CONFIGURATION_TYPES project_configurations CMAKE_GENERATOR CMAKE_HOST_SYSTEM_PROCESSOR CMAKE_CURRENT_SOURCE_DIR collected_library_apath library_apaths)
|
||||
list(APPEND echo_vars CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE project_defs)
|
||||
list(APPEND echo_vars CMAKE_EXE_LINKER_FLAGS CMAKE_EXE_LINKER_FLAGS_DEBUG CMAKE_EXE_LINKER_FLAGS_RELEASE)
|
||||
list(APPEND echo_vars dependency_libraries binary_destination_apath library_destination_apath)
|
||||
list(APPEND echo_vars CMAKE_FIND_LIBRARY_PREFIXES CMAKE_FIND_LIBRARY_SUFFIXES)
|
||||
# list(APPEND echo_vars CMAKE_IMPORT_LIBRARY_SUFFIXES CMAKE_LINK_LIBRARY_SUFFIX CMAKE_SHARED_LIBRARY_SUFFIX CMAKE_SHARED_MODULE_SUFFIX CMAKE_STATIC_LIBRARY_SUFFIX)
|
||||
# list(APPEND echo_vars PROJECT_SOURCE_DIR PROJECT_BINARY_DIR CMAKE_SOURCE_DIR CMAKE_BINARY_DIR CMAKE_RUNTIME_OUTPUT_DIRECTORY CMAKE_LIBRARY_OUTPUT_DIRECTORY CMAKE_INSTALL_NAME_DIR CMAKE_INCLUDE_CURRENT_DIR CMAKE_HOME_DIRECTORY CMAKE_CURRENT_LIST_DIR CMAKE_CURRENT_BINARY_DIR CMAKE_BINARY_DIR CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${project_name}_SOURCE_DIR ${project_name}_BINARY_DIR)
|
||||
list(APPEND echo_vars CMAKE_INSTALL_PREFIX CMAKE_INSTALL_RPATH CMAKE_SKIP_BUILD_RPATH CMAKE_BUILD_WITH_INSTALL_RPATH CMAKE_SKIP_RPATH CMAKE_SKIP_INSTALL_RPATH)
|
||||
# list(APPEND echo_vars CMAKE_PREFIX_PATH CMAKE_LIBRARY_PATH CMAKE_FRAMEWORK_PATH CMAKE_SYSTEM_PREFIX_PATH CMAKE_SYSTEM_LIBRARY_PATH CMAKE_SYSTEM_FRAMEWORK_PATH)
|
||||
display_vars("${echo_vars}" "final: ")
|
||||
|
||||
|
@ -1,439 +0,0 @@
|
||||
/* -*- mode: c++ ; coding: utf-8-unix -*- */
|
||||
/* last updated : 2015/07/25.03:24:29 */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013-2015 yaruopooner [https://github.com/yaruopooner]
|
||||
*
|
||||
* This file is part of ac-clang.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
/*================================================================================================*/
|
||||
/* Comment */
|
||||
/*================================================================================================*/
|
||||
|
||||
|
||||
/*================================================================================================*/
|
||||
/* Include Files */
|
||||
/*================================================================================================*/
|
||||
|
||||
#include "ClangServer.hpp"
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
|
||||
/*================================================================================================*/
|
||||
/* Internal Function Definitions Section */
|
||||
/*================================================================================================*/
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
std::string GetClangVersion( void )
|
||||
{
|
||||
CXString version_text = clang_getClangVersion();
|
||||
const std::string clang_version = clang_getCString( version_text );
|
||||
|
||||
clang_disposeString( version_text );
|
||||
|
||||
return clang_version;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*================================================================================================*/
|
||||
/* Global Class Method Definitions Section */
|
||||
/*================================================================================================*/
|
||||
|
||||
|
||||
/*
|
||||
|
||||
---- SERVER MESSAGE ----
|
||||
|
||||
- GET_SPECIFIC_PROPERTIES: return clang-server specific properties
|
||||
Message format:
|
||||
command_type:Server
|
||||
command_name:GET_SPECIFIC_PROPERTIES
|
||||
|
||||
- GET_CLANG_VERSION: return libclang version (libclang.lib/a)
|
||||
Message format:
|
||||
command_type:Server
|
||||
command_name:GET_CLANG_VERSION
|
||||
|
||||
- SET_CLANG_PARAMETERS: setup libclang behavior parameters
|
||||
Message format:
|
||||
command_type:Server
|
||||
command_name:SET_CLANG_PARAMETERS
|
||||
translation_unit_flags:[#flag_name0|flag_name1|...#]
|
||||
complete_at_flags:[#flag_name0|flag_name1|...#]
|
||||
|
||||
- CREATE_SESSION: create session.
|
||||
Message format:
|
||||
command_type:Server
|
||||
command_name:CREATE_SESSION
|
||||
session_name::[#session_name#]
|
||||
|
||||
- DELETE_SESSION: delete session.
|
||||
Message format:
|
||||
command_type:Server
|
||||
command_name:DELETE_SESSION
|
||||
session_name::[#session_name#]
|
||||
|
||||
- RESET: reset the clang server(all session delete. context reallocate)
|
||||
Message format:
|
||||
command_type:Server
|
||||
command_name:RESET
|
||||
|
||||
- SHUTDOWN: shutdown the clang server (this program)
|
||||
Message format:
|
||||
command_type:Server
|
||||
command_name:SHUTDOWN
|
||||
|
||||
|
||||
---- SESSION MESSAGE ----
|
||||
|
||||
- SUSPEND: delete CXTranslationUnit
|
||||
Message format:
|
||||
command_type:Session
|
||||
command_name:SUSPEND
|
||||
session_name:[#session_name#]
|
||||
|
||||
- RESUME: realloc CXTranslationUnit
|
||||
Message format:
|
||||
command_type:Session
|
||||
command_name:RESUME
|
||||
session_name:[#session_name#]
|
||||
|
||||
- SET_CFLAGS: Specify CFLAGS argument passing to clang parser.
|
||||
Message format:
|
||||
command_type:Session
|
||||
command_name:SET_CFLAGS
|
||||
session_name:[#session_name#]
|
||||
num_cflags:[#num_cflags#]
|
||||
arg1 arg2 ...... (there should be num_cflags items here)
|
||||
CFLAGS's white space must be accept.
|
||||
a separator is '\n'.
|
||||
source_length:[#source_length#]
|
||||
<# SOURCE CODE #>
|
||||
|
||||
- SET_SOURCECODE: Update the source code in the source buffer
|
||||
Message format:
|
||||
command_type:Session
|
||||
command_name:SET_SOURCECODE
|
||||
session_name:[#session_name#]
|
||||
source_length:[#source_length#]
|
||||
<# SOURCE CODE #>
|
||||
|
||||
- REPARSE: Reparse the source code
|
||||
command_type:Session
|
||||
command_name:REPARSE
|
||||
session_name:[#session_name#]
|
||||
|
||||
- COMPLETION: Do code completion at a specified point.
|
||||
Message format:
|
||||
command_type:Session
|
||||
command_name:COMPLETION
|
||||
session_name:[#session_name#]
|
||||
line:[#line#]
|
||||
column:[#column#]
|
||||
source_length:[#source_length#]
|
||||
<# SOURCE CODE #>
|
||||
|
||||
- SYNTAXCHECK: Retrieve diagnostic messages
|
||||
Message format:
|
||||
command_type:Session
|
||||
command_name:SYNTAXCHECK
|
||||
session_name:[#session_name#]
|
||||
source_length:[#source_length#]
|
||||
<# SOURCE CODE #>
|
||||
|
||||
- INCLUSION: Get location of inclusion file at point
|
||||
Message format:
|
||||
command_type:Session
|
||||
command_name:INCLUSION
|
||||
session_name:[#session_name#]
|
||||
line:[#line#]
|
||||
column:[#column#]
|
||||
source_length:[#source_length#]
|
||||
<# SOURCE CODE #>
|
||||
|
||||
- DEFINITION: Get location of definition at point
|
||||
Message format:
|
||||
command_type:Session
|
||||
command_name:DEFINITION
|
||||
session_name:[#session_name#]
|
||||
line:[#line#]
|
||||
column:[#column#]
|
||||
source_length:[#source_length#]
|
||||
<# SOURCE CODE #>
|
||||
|
||||
- DECLARATION: Get location of declaration at point
|
||||
Message format:
|
||||
command_type:Session
|
||||
command_name:DECLARATION
|
||||
session_name:[#session_name#]
|
||||
line:[#line#]
|
||||
column:[#column#]
|
||||
source_length:[#source_length#]
|
||||
<# SOURCE CODE #>
|
||||
|
||||
- SMARTJUMP: Get location of inclusion, definition, declaration at point. If that fails, it will search following.
|
||||
inclusion -> finish, definition -> declaration -> finish.
|
||||
Message format:
|
||||
command_type:Session
|
||||
command_name:SMARTJUMP
|
||||
session_name:[#session_name#]
|
||||
line:[#line#]
|
||||
column:[#column#]
|
||||
source_length:[#source_length#]
|
||||
<# SOURCE CODE #>
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
ClangServer::ClangServer( const Specification& specification )
|
||||
:
|
||||
m_Status( kStatus_Running )
|
||||
, m_Specification( specification )
|
||||
{
|
||||
// setup stream buffer size
|
||||
m_Specification.m_StdinBufferSize = std::max( m_Specification.m_StdinBufferSize, static_cast< size_t >( Specification::kStreamBuffer_UnitSize ) );
|
||||
m_Specification.m_StdoutBufferSize = std::max( m_Specification.m_StdoutBufferSize, static_cast< size_t >( Specification::kStreamBuffer_UnitSize ) );
|
||||
|
||||
::setvbuf( stdin, nullptr, _IOFBF, m_Specification.m_StdinBufferSize );
|
||||
::setvbuf( stdout, nullptr, _IOFBF, m_Specification.m_StdoutBufferSize );
|
||||
|
||||
|
||||
// server command
|
||||
m_ServerCommands.insert( ServerHandleMap::value_type( "GET_SPECIFICATION", std::mem_fn( &ClangServer::commandGetSpecification ) ) );
|
||||
m_ServerCommands.insert( ServerHandleMap::value_type( "GET_CLANG_VERSION", std::mem_fn( &ClangServer::commandGetClangVersion ) ) );
|
||||
m_ServerCommands.insert( ServerHandleMap::value_type( "SET_CLANG_PARAMETERS", std::mem_fn( &ClangServer::commandSetClangParameters ) ) );
|
||||
m_ServerCommands.insert( ServerHandleMap::value_type( "CREATE_SESSION", std::mem_fn( &ClangServer::commandCreateSession ) ) );
|
||||
m_ServerCommands.insert( ServerHandleMap::value_type( "DELETE_SESSION", std::mem_fn( &ClangServer::commandDeleteSession ) ) );
|
||||
m_ServerCommands.insert( ServerHandleMap::value_type( "RESET", std::mem_fn( &ClangServer::commandReset ) ) );
|
||||
m_ServerCommands.insert( ServerHandleMap::value_type( "SHUTDOWN", std::mem_fn( &ClangServer::commandShutdown ) ) );
|
||||
|
||||
// session command
|
||||
m_SessionCommands.insert( SessionHandleMap::value_type( "SUSPEND", std::mem_fn( &ClangSession::commandSuspend ) ) );
|
||||
m_SessionCommands.insert( SessionHandleMap::value_type( "RESUME", std::mem_fn( &ClangSession::commandResume ) ) );
|
||||
m_SessionCommands.insert( SessionHandleMap::value_type( "SET_CFLAGS", std::mem_fn( &ClangSession::commandSetCFlags ) ) );
|
||||
m_SessionCommands.insert( SessionHandleMap::value_type( "SET_SOURCECODE", std::mem_fn( &ClangSession::commandSetSourceCode ) ) );
|
||||
m_SessionCommands.insert( SessionHandleMap::value_type( "REPARSE", std::mem_fn( &ClangSession::commandReparse ) ) );
|
||||
m_SessionCommands.insert( SessionHandleMap::value_type( "COMPLETION", std::mem_fn( &ClangSession::commandCompletion ) ) );
|
||||
m_SessionCommands.insert( SessionHandleMap::value_type( "SYNTAXCHECK", std::mem_fn( &ClangSession::commandDiagnostics ) ) );
|
||||
m_SessionCommands.insert( SessionHandleMap::value_type( "INCLUSION", std::mem_fn( &ClangSession::commandInclusion ) ) );
|
||||
m_SessionCommands.insert( SessionHandleMap::value_type( "DEFINITION", std::mem_fn( &ClangSession::commandDefinition ) ) );
|
||||
m_SessionCommands.insert( SessionHandleMap::value_type( "DECLARATION", std::mem_fn( &ClangSession::commandDeclaration ) ) );
|
||||
m_SessionCommands.insert( SessionHandleMap::value_type( "SMARTJUMP", std::mem_fn( &ClangSession::commandSmartJump ) ) );
|
||||
|
||||
// display initial specification
|
||||
commandGetSpecification();
|
||||
}
|
||||
|
||||
ClangServer::~ClangServer( void )
|
||||
{
|
||||
// m_Sessions must be destruction early than m_Context.
|
||||
// Because m_Sessions depend to m_Context.
|
||||
m_Sessions.clear();
|
||||
}
|
||||
|
||||
|
||||
void ClangServer::commandGetSpecification( void )
|
||||
{
|
||||
const std::string server_version = CLANG_SERVER_VERSION;
|
||||
const std::string clang_version = ::GetClangVersion();
|
||||
const std::string generate = CMAKE_GENERATOR "/" CMAKE_HOST_SYSTEM_PROCESSOR;
|
||||
|
||||
m_Writer.Write( "-------- Clang-Server Specification --------\n" );
|
||||
m_Writer.Write( "Server Version : %s\n", server_version.c_str() );
|
||||
m_Writer.Write( "Clang Version : %s\n", clang_version.c_str() );
|
||||
m_Writer.Write( "Generate : %s\n", generate.c_str() );
|
||||
// m_Writer.Write( "Log File : %s\n", m_Specification.m_LogFile.c_str() );
|
||||
m_Writer.Write( "STDIN Buffer Size : %d bytes\n", m_Specification.m_StdinBufferSize );
|
||||
m_Writer.Write( "STDOUT Buffer Size : %d bytes\n", m_Specification.m_StdoutBufferSize );
|
||||
m_Writer.Flush();
|
||||
}
|
||||
|
||||
|
||||
void ClangServer::commandGetClangVersion( void )
|
||||
{
|
||||
const std::string clang_version = ::GetClangVersion();
|
||||
|
||||
m_Writer.Write( "%s ", clang_version.c_str() );
|
||||
m_Writer.Flush();
|
||||
}
|
||||
|
||||
|
||||
void ClangServer::commandSetClangParameters( void )
|
||||
{
|
||||
const string translation_unit_flags = m_Reader.ReadToken( "translation_unit_flags:%s" );
|
||||
const string complete_at_flags = m_Reader.ReadToken( "complete_at_flags:%s" );
|
||||
const uint32_t translation_unit_flags_value = ClangFlagConverters::GetCXTranslationUnitFlags().GetValue( translation_unit_flags );
|
||||
const uint32_t complete_at_flags_value = ClangFlagConverters::GetCXCodeCompleteFlags().GetValue( complete_at_flags );
|
||||
uint32_t complete_results_limit;
|
||||
|
||||
m_Reader.ReadToken( "complete_results_limit:%d", complete_results_limit );
|
||||
|
||||
m_Context.SetTranslationUnitFlags( translation_unit_flags_value );
|
||||
m_Context.SetCompleteAtFlags( complete_at_flags_value );
|
||||
m_Context.SetCompleteResultsLimit( complete_results_limit );
|
||||
}
|
||||
|
||||
|
||||
void ClangServer::commandCreateSession( void )
|
||||
{
|
||||
const string session_name = m_Reader.ReadToken( "session_name:%s" );
|
||||
|
||||
// search session
|
||||
Dictionary::iterator session_it = m_Sessions.find( session_name );
|
||||
|
||||
if ( session_it == m_Sessions.end() )
|
||||
{
|
||||
// not found session
|
||||
// allocate & setup new session
|
||||
std::shared_ptr< ClangSession > new_session( std::make_shared< ClangSession >( session_name, m_Context, m_Reader, m_Writer ) );
|
||||
std::pair< Dictionary::iterator, bool > result = m_Sessions.insert( Dictionary::value_type( session_name, new_session ) );
|
||||
|
||||
if ( result.second )
|
||||
{
|
||||
// success
|
||||
new_session->Allocate();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// already exist
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ClangServer::commandDeleteSession( void )
|
||||
{
|
||||
const string session_name = m_Reader.ReadToken( "session_name:%s" );
|
||||
|
||||
// search session
|
||||
Dictionary::iterator session_it = m_Sessions.find( session_name );
|
||||
|
||||
if ( session_it != m_Sessions.end() )
|
||||
{
|
||||
// session_it->second->Deallocate();
|
||||
|
||||
m_Sessions.erase( session_it );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ClangServer::commandReset( void )
|
||||
{
|
||||
m_Sessions.clear();
|
||||
m_Context.Deallocate();
|
||||
m_Context.Allocate();
|
||||
}
|
||||
|
||||
|
||||
void ClangServer::commandShutdown( void )
|
||||
{
|
||||
m_Status = kStatus_Exit;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void ClangServer::ParseServerCommand( void )
|
||||
{
|
||||
const string command_name = m_Reader.ReadToken( "command_name:%s" );
|
||||
|
||||
ServerHandleMap::iterator command_it = m_ServerCommands.find( command_name );
|
||||
|
||||
// execute command handler
|
||||
if ( command_it != m_ServerCommands.end() )
|
||||
{
|
||||
command_it->second( *this );
|
||||
}
|
||||
else
|
||||
{
|
||||
// unknown command
|
||||
}
|
||||
}
|
||||
|
||||
void ClangServer::ParseSessionCommand( void )
|
||||
{
|
||||
const string command_name = m_Reader.ReadToken( "command_name:%s" );
|
||||
const string session_name = m_Reader.ReadToken( "session_name:%s" );
|
||||
|
||||
if ( session_name.empty() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// search session
|
||||
Dictionary::iterator session_it = m_Sessions.find( session_name );
|
||||
|
||||
// execute command handler
|
||||
if ( session_it != m_Sessions.end() )
|
||||
{
|
||||
SessionHandleMap::iterator command_it = m_SessionCommands.find( command_name );
|
||||
|
||||
if ( command_it != m_SessionCommands.end() )
|
||||
{
|
||||
command_it->second( *session_it->second );
|
||||
}
|
||||
else
|
||||
{
|
||||
// session not found
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// unknown command
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ClangServer::ParseCommand( void )
|
||||
{
|
||||
do
|
||||
{
|
||||
const string command_type = m_Reader.ReadToken( "command_type:%s" );
|
||||
|
||||
if ( command_type == "Server" )
|
||||
{
|
||||
ParseServerCommand();
|
||||
}
|
||||
else if ( command_type == "Session" )
|
||||
{
|
||||
ParseSessionCommand();
|
||||
}
|
||||
else
|
||||
{
|
||||
// unknown command type
|
||||
}
|
||||
} while ( m_Status != kStatus_Exit );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*================================================================================================*/
|
||||
/* EOF */
|
||||
/*================================================================================================*/
|
@ -1,132 +0,0 @@
|
||||
/* -*- mode: c++ ; coding: utf-8-unix -*- */
|
||||
/* last updated : 2015/09/05.04:13:59 */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013-2015 yaruopooner [https://github.com/yaruopooner]
|
||||
*
|
||||
* This file is part of ac-clang.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __CLANG_SERVER_HPP__
|
||||
#define __CLANG_SERVER_HPP__
|
||||
|
||||
|
||||
|
||||
#define CLANG_SERVER_VERSION "server version 1.4.0"
|
||||
|
||||
|
||||
/*================================================================================================*/
|
||||
/* Comment */
|
||||
/*================================================================================================*/
|
||||
|
||||
|
||||
/*================================================================================================*/
|
||||
/* Include Files */
|
||||
/*================================================================================================*/
|
||||
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "ClangSession.hpp"
|
||||
|
||||
|
||||
/*================================================================================================*/
|
||||
/* Class */
|
||||
/*================================================================================================*/
|
||||
|
||||
|
||||
class ClangServer
|
||||
{
|
||||
public:
|
||||
enum Status
|
||||
{
|
||||
kStatus_Running,
|
||||
kStatus_Exit,
|
||||
};
|
||||
|
||||
|
||||
struct Specification
|
||||
{
|
||||
enum
|
||||
{
|
||||
kStreamBuffer_UnitSize = 1 * 1024 * 1024,
|
||||
};
|
||||
|
||||
Specification( size_t StdinBufferSize = kStreamBuffer_UnitSize,
|
||||
size_t StdoutBufferSize = kStreamBuffer_UnitSize,
|
||||
const std::string& LogFile = std::string() ) :
|
||||
m_StdinBufferSize( StdinBufferSize )
|
||||
, m_StdoutBufferSize( StdoutBufferSize )
|
||||
, m_LogFile( LogFile )
|
||||
{
|
||||
}
|
||||
|
||||
size_t m_StdinBufferSize;
|
||||
size_t m_StdoutBufferSize;
|
||||
std::string m_LogFile;
|
||||
};
|
||||
|
||||
|
||||
ClangServer( const Specification& specification = Specification() );
|
||||
~ClangServer( void );
|
||||
|
||||
void ParseCommand( void );
|
||||
|
||||
// void SetLogFile( const std::string& LogFile );
|
||||
|
||||
|
||||
private:
|
||||
void ParseServerCommand( void );
|
||||
void ParseSessionCommand( void );
|
||||
|
||||
|
||||
// commands
|
||||
void commandGetSpecification( void );
|
||||
void commandGetClangVersion( void );
|
||||
void commandSetClangParameters( void );
|
||||
void commandCreateSession( void );
|
||||
void commandDeleteSession( void );
|
||||
void commandReset( void );
|
||||
void commandShutdown( void );
|
||||
|
||||
|
||||
private:
|
||||
typedef std::unordered_map< std::string, std::function< void (ClangServer&) > > ServerHandleMap;
|
||||
typedef std::unordered_map< std::string, std::function< void (ClangSession&) > > SessionHandleMap;
|
||||
typedef std::unordered_map< std::string, std::shared_ptr< ClangSession > > Dictionary;
|
||||
|
||||
|
||||
ClangContext m_Context;
|
||||
ServerHandleMap m_ServerCommands;
|
||||
SessionHandleMap m_SessionCommands;
|
||||
Dictionary m_Sessions;
|
||||
StreamReader m_Reader;
|
||||
StreamWriter m_Writer;
|
||||
uint32_t m_Status;
|
||||
Specification m_Specification;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // __CLANG_SERVER_HPP__
|
||||
/*================================================================================================*/
|
||||
/* EOF */
|
||||
/*================================================================================================*/
|
@ -1,739 +0,0 @@
|
||||
/* -*- mode: c++ ; coding: utf-8-unix -*- */
|
||||
/* last updated : 2015/07/25.03:32:02 */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013-2015 yaruopooner [https://github.com/yaruopooner]
|
||||
*
|
||||
* This file is part of ac-clang.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
/*================================================================================================*/
|
||||
/* Comment */
|
||||
/*================================================================================================*/
|
||||
|
||||
|
||||
/*================================================================================================*/
|
||||
/* Include Files */
|
||||
/*================================================================================================*/
|
||||
|
||||
#include <regex>
|
||||
|
||||
#include "ClangSession.hpp"
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
|
||||
/*================================================================================================*/
|
||||
/* Internal Printer Class Definitions Section */
|
||||
/*================================================================================================*/
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
string GetNormalizePath( CXFile file )
|
||||
{
|
||||
CXString filename = clang_getFileName( file );
|
||||
const string path = clang_getCString( filename );
|
||||
const regex expression( "[\\\\]+" );
|
||||
const string replace( "/" );
|
||||
const string normalize_path = regex_replace( path, expression, replace );
|
||||
|
||||
clang_disposeString( filename );
|
||||
|
||||
return normalize_path;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
class ClangSession::Completion
|
||||
{
|
||||
public:
|
||||
Completion( ClangSession& Session ) :
|
||||
m_Session( Session )
|
||||
{
|
||||
}
|
||||
|
||||
void PrintCompleteCandidates( void );
|
||||
|
||||
private:
|
||||
bool PrintCompletionHeadTerm( CXCompletionString CompletionString );
|
||||
void PrintAllCompletionTerms( CXCompletionString CompletionString );
|
||||
void PrintCompletionLine( CXCompletionString CompletionString );
|
||||
void PrintCompletionResults( CXCodeCompleteResults* CompleteResults );
|
||||
|
||||
private:
|
||||
ClangSession& m_Session;
|
||||
};
|
||||
|
||||
|
||||
class ClangSession::Diagnostics
|
||||
{
|
||||
public:
|
||||
Diagnostics( ClangSession& Session ) :
|
||||
m_Session( Session )
|
||||
{
|
||||
}
|
||||
|
||||
void PrintDiagnosticsResult( void );
|
||||
|
||||
private:
|
||||
ClangSession& m_Session;
|
||||
};
|
||||
|
||||
|
||||
class ClangSession::Jump
|
||||
{
|
||||
public:
|
||||
Jump( ClangSession& Session ) :
|
||||
m_Session( Session )
|
||||
{
|
||||
}
|
||||
|
||||
void PrintInclusionFileLocation( void );
|
||||
void PrintDefinitionLocation( void );
|
||||
void PrintDeclarationLocation( void );
|
||||
void PrintSmartJumpLocation( void );
|
||||
|
||||
private:
|
||||
struct Location
|
||||
{
|
||||
Location( void ) :
|
||||
m_Line( 0 )
|
||||
, m_Column( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
string m_NormalizePath;
|
||||
uint32_t m_Line;
|
||||
uint32_t m_Column;
|
||||
};
|
||||
|
||||
CXCursor GetCursor( const uint32_t Line, const uint32_t Column ) const;
|
||||
void PrepareTransaction( uint32_t& Line, uint32_t& Column );
|
||||
bool EvaluateCursorLocation( const CXCursor& Cursor );
|
||||
|
||||
bool EvaluateInclusionFileLocation( void );
|
||||
bool EvaluateDefinitionLocation( void );
|
||||
bool EvaluateDeclarationLocation( void );
|
||||
bool EvaluateSmartJumpLocation( void );
|
||||
void PrintLocation( void );
|
||||
|
||||
private:
|
||||
ClangSession& m_Session;
|
||||
Location m_Location;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
bool ClangSession::Completion::PrintCompletionHeadTerm( CXCompletionString CompletionString )
|
||||
{
|
||||
// check accessibility of candidate. (access specifier of member : public/protected/private)
|
||||
if ( clang_getCompletionAvailability( CompletionString ) == CXAvailability_NotAccessible )
|
||||
{
|
||||
return ( false );
|
||||
}
|
||||
|
||||
const uint32_t n_chunks = clang_getNumCompletionChunks( CompletionString );
|
||||
|
||||
// inspect all chunks only to find the TypedText chunk
|
||||
for ( uint32_t i_chunk = 0; i_chunk < n_chunks; ++i_chunk )
|
||||
{
|
||||
if ( clang_getCompletionChunkKind( CompletionString, i_chunk ) == CXCompletionChunk_TypedText )
|
||||
{
|
||||
// We got it, just dump it to fp
|
||||
CXString ac_string = clang_getCompletionChunkText( CompletionString, i_chunk );
|
||||
|
||||
m_Session.m_Writer.Write( "COMPLETION: %s", clang_getCString( ac_string ) );
|
||||
|
||||
clang_disposeString( ac_string );
|
||||
|
||||
// care package on the way
|
||||
return ( true );
|
||||
}
|
||||
}
|
||||
|
||||
// We haven't found TypedText chunk in CompletionString
|
||||
return ( false );
|
||||
}
|
||||
|
||||
void ClangSession::Completion::PrintAllCompletionTerms( CXCompletionString CompletionString )
|
||||
{
|
||||
const uint32_t n_chunks = clang_getNumCompletionChunks( CompletionString );
|
||||
|
||||
for ( uint32_t i_chunk = 0; i_chunk < n_chunks; ++i_chunk )
|
||||
{
|
||||
// get the type and completion text of this chunk
|
||||
CXCompletionChunkKind chk_kind = clang_getCompletionChunkKind( CompletionString, i_chunk );
|
||||
CXString chk_text = clang_getCompletionChunkText( CompletionString, i_chunk );
|
||||
|
||||
// differenct kinds of chunks has various output formats
|
||||
switch ( chk_kind )
|
||||
{
|
||||
case CXCompletionChunk_Placeholder:
|
||||
m_Session.m_Writer.Write( "<#%s#>", clang_getCString( chk_text ) );
|
||||
break;
|
||||
|
||||
case CXCompletionChunk_ResultType:
|
||||
m_Session.m_Writer.Write( "[#%s#]", clang_getCString( chk_text ) );
|
||||
break;
|
||||
|
||||
case CXCompletionChunk_Optional:
|
||||
// print optional term in a recursive way
|
||||
m_Session.m_Writer.Write( "{#" );
|
||||
PrintAllCompletionTerms( clang_getCompletionChunkCompletionString( CompletionString, i_chunk ) );
|
||||
m_Session.m_Writer.Write( "#}" );
|
||||
break;
|
||||
|
||||
default:
|
||||
m_Session.m_Writer.Write( "%s", clang_getCString( chk_text ) );
|
||||
}
|
||||
|
||||
clang_disposeString( chk_text );
|
||||
}
|
||||
}
|
||||
|
||||
void ClangSession::Completion::PrintCompletionLine( CXCompletionString CompletionString )
|
||||
{
|
||||
// print completion item head: COMPLETION: typed_string
|
||||
if ( PrintCompletionHeadTerm( CompletionString ) )
|
||||
{
|
||||
// If there's not only one TypedText chunk in this completion string,
|
||||
// * we still have a lot of info to dump:
|
||||
// *
|
||||
// * COMPLETION: typed_text : ##infos## \n
|
||||
m_Session.m_Writer.Write( " : " );
|
||||
|
||||
PrintAllCompletionTerms( CompletionString );
|
||||
|
||||
m_Session.m_Writer.Write( "\n" );
|
||||
}
|
||||
}
|
||||
|
||||
void ClangSession::Completion::PrintCompletionResults( CXCodeCompleteResults* CompleteResults )
|
||||
{
|
||||
const uint32_t results_limit = m_Session.m_Context.GetCompleteResultsLimit();
|
||||
const bool is_accept = results_limit ? ( CompleteResults->NumResults < results_limit ) : true;
|
||||
|
||||
if ( !is_accept )
|
||||
{
|
||||
m_Session.m_Writer.Write( "A number of completion results(%d) is threshold value(%d) over!!\n", CompleteResults->NumResults, results_limit );
|
||||
return;
|
||||
}
|
||||
|
||||
for ( uint32_t i = 0; i < CompleteResults->NumResults; ++i )
|
||||
{
|
||||
PrintCompletionLine( CompleteResults->Results[ i ].CompletionString );
|
||||
}
|
||||
}
|
||||
|
||||
void ClangSession::Completion::PrintCompleteCandidates( void )
|
||||
{
|
||||
uint32_t line;
|
||||
uint32_t column;
|
||||
|
||||
m_Session.m_Reader.ReadToken( "line:%d", line );
|
||||
m_Session.m_Reader.ReadToken( "column:%d", column );
|
||||
|
||||
m_Session.ReadSourceCode();
|
||||
|
||||
CXUnsavedFile unsaved_file = m_Session.GetCXUnsavedFile();
|
||||
// necessary call?
|
||||
// clang_reparseTranslationUnit( m_Session.m_CxTU, 1, &unsaved_file, m_Session.m_TranslationUnitFlags );
|
||||
CXCodeCompleteResults* results = clang_codeCompleteAt( m_Session.m_CxTU, m_Session.m_SessionName.c_str(), line, column, &unsaved_file, 1, m_Session.m_CompleteAtFlags );
|
||||
|
||||
if ( results )
|
||||
{
|
||||
clang_sortCodeCompletionResults( results->Results, results->NumResults );
|
||||
|
||||
PrintCompletionResults( results );
|
||||
|
||||
clang_disposeCodeCompleteResults( results );
|
||||
}
|
||||
|
||||
m_Session.m_Writer.Flush();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ClangSession::Diagnostics::PrintDiagnosticsResult( void )
|
||||
{
|
||||
m_Session.ReadSourceCode();
|
||||
|
||||
CXUnsavedFile unsaved_file = m_Session.GetCXUnsavedFile();
|
||||
|
||||
clang_reparseTranslationUnit( m_Session.m_CxTU, 1, &unsaved_file, m_Session.m_TranslationUnitFlags );
|
||||
|
||||
const uint32_t n_diagnostics = clang_getNumDiagnostics( m_Session.m_CxTU );
|
||||
|
||||
for ( uint32_t i = 0; i < n_diagnostics; ++i )
|
||||
{
|
||||
CXDiagnostic diagnostic = clang_getDiagnostic( m_Session.m_CxTU, i );
|
||||
CXString message = clang_formatDiagnostic( diagnostic, clang_defaultDiagnosticDisplayOptions() );
|
||||
|
||||
m_Session.m_Writer.Write( "%s\n", clang_getCString( message ) );
|
||||
|
||||
clang_disposeString( message );
|
||||
clang_disposeDiagnostic( diagnostic );
|
||||
}
|
||||
|
||||
m_Session.m_Writer.Flush();
|
||||
}
|
||||
|
||||
|
||||
|
||||
CXCursor ClangSession::Jump::GetCursor( const uint32_t Line, const uint32_t Column ) const
|
||||
{
|
||||
const CXFile file = clang_getFile( m_Session.m_CxTU, m_Session.m_SessionName.c_str() );
|
||||
const CXSourceLocation location = clang_getLocation( m_Session.m_CxTU, file, Line, Column );
|
||||
const CXCursor cursor = clang_getCursor( m_Session.m_CxTU, location );
|
||||
|
||||
return cursor;
|
||||
}
|
||||
|
||||
void ClangSession::Jump::PrepareTransaction( uint32_t& Line, uint32_t& Column )
|
||||
{
|
||||
m_Session.m_Reader.ReadToken( "line:%d", Line );
|
||||
m_Session.m_Reader.ReadToken( "column:%d", Column );
|
||||
|
||||
m_Session.ReadSourceCode();
|
||||
|
||||
CXUnsavedFile unsaved_file = m_Session.GetCXUnsavedFile();
|
||||
|
||||
clang_reparseTranslationUnit( m_Session.m_CxTU, 1, &unsaved_file, m_Session.m_TranslationUnitFlags );
|
||||
}
|
||||
|
||||
|
||||
bool ClangSession::Jump::EvaluateCursorLocation( const CXCursor& Cursor )
|
||||
{
|
||||
if ( clang_isInvalid( Cursor.kind ) )
|
||||
{
|
||||
return ( false );
|
||||
}
|
||||
|
||||
const CXSourceLocation dest_location = clang_getCursorLocation( Cursor );
|
||||
CXFile dest_file;
|
||||
uint32_t dest_line;
|
||||
uint32_t dest_column;
|
||||
uint32_t dest_offset;
|
||||
|
||||
clang_getExpansionLocation( dest_location, &dest_file, &dest_line, &dest_column, &dest_offset );
|
||||
|
||||
if ( !dest_file )
|
||||
{
|
||||
return ( false );
|
||||
}
|
||||
|
||||
const string normalize_path = ::GetNormalizePath( dest_file );
|
||||
|
||||
m_Location.m_NormalizePath = normalize_path;
|
||||
m_Location.m_Line = dest_line;
|
||||
m_Location.m_Column = dest_column;
|
||||
|
||||
return ( true );
|
||||
}
|
||||
|
||||
|
||||
bool ClangSession::Jump::EvaluateInclusionFileLocation( void )
|
||||
{
|
||||
uint32_t line;
|
||||
uint32_t column;
|
||||
|
||||
PrepareTransaction( line, column );
|
||||
|
||||
const CXCursor source_cursor = GetCursor( line, column );
|
||||
|
||||
if ( !clang_isInvalid( source_cursor.kind ) )
|
||||
{
|
||||
if ( source_cursor.kind == CXCursor_InclusionDirective )
|
||||
{
|
||||
const CXFile file = clang_getIncludedFile( source_cursor );
|
||||
|
||||
if ( file )
|
||||
{
|
||||
const uint32_t file_line = 1;
|
||||
const uint32_t file_column = 1;
|
||||
const string normalize_path = ::GetNormalizePath( file );
|
||||
|
||||
m_Location.m_NormalizePath = normalize_path;
|
||||
m_Location.m_Line = file_line;
|
||||
m_Location.m_Column = file_column;
|
||||
|
||||
return ( true );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ( false );
|
||||
}
|
||||
|
||||
bool ClangSession::Jump::EvaluateDefinitionLocation( void )
|
||||
{
|
||||
uint32_t line;
|
||||
uint32_t column;
|
||||
|
||||
PrepareTransaction( line, column );
|
||||
|
||||
const CXCursor source_cursor = GetCursor( line, column );
|
||||
|
||||
if ( !clang_isInvalid( source_cursor.kind ) )
|
||||
{
|
||||
return EvaluateCursorLocation( clang_getCursorDefinition( source_cursor ) );
|
||||
}
|
||||
|
||||
return ( false );
|
||||
}
|
||||
|
||||
bool ClangSession::Jump::EvaluateDeclarationLocation( void )
|
||||
{
|
||||
uint32_t line;
|
||||
uint32_t column;
|
||||
|
||||
PrepareTransaction( line, column );
|
||||
|
||||
const CXCursor source_cursor = GetCursor( line, column );
|
||||
|
||||
if ( !clang_isInvalid( source_cursor.kind ) )
|
||||
{
|
||||
return EvaluateCursorLocation( clang_getCursorReferenced( source_cursor ) );
|
||||
}
|
||||
|
||||
return ( false );
|
||||
}
|
||||
|
||||
bool ClangSession::Jump::EvaluateSmartJumpLocation( void )
|
||||
{
|
||||
uint32_t line;
|
||||
uint32_t column;
|
||||
|
||||
PrepareTransaction( line, column );
|
||||
|
||||
const CXCursor source_cursor = GetCursor( line, column );
|
||||
|
||||
if ( !clang_isInvalid( source_cursor.kind ) )
|
||||
{
|
||||
if ( source_cursor.kind == CXCursor_InclusionDirective )
|
||||
{
|
||||
const CXFile file = clang_getIncludedFile( source_cursor );
|
||||
|
||||
if ( file )
|
||||
{
|
||||
const uint32_t file_line = 1;
|
||||
const uint32_t file_column = 1;
|
||||
const string normalize_path = ::GetNormalizePath( file );
|
||||
|
||||
m_Location.m_NormalizePath = normalize_path;
|
||||
m_Location.m_Line = file_line;
|
||||
m_Location.m_Column = file_column;
|
||||
|
||||
return ( true );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return ( EvaluateCursorLocation( clang_getCursorDefinition( source_cursor ) )
|
||||
|| EvaluateCursorLocation( clang_getCursorReferenced( source_cursor ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
return ( false );
|
||||
}
|
||||
|
||||
|
||||
void ClangSession::Jump::PrintLocation( void )
|
||||
{
|
||||
m_Session.m_Writer.Write( "\"%s\" %d %d ", m_Location.m_NormalizePath.c_str(), m_Location.m_Line, m_Location.m_Column );
|
||||
}
|
||||
|
||||
|
||||
void ClangSession::Jump::PrintInclusionFileLocation( void )
|
||||
{
|
||||
if ( EvaluateInclusionFileLocation() )
|
||||
{
|
||||
PrintLocation();
|
||||
}
|
||||
|
||||
m_Session.m_Writer.Flush();
|
||||
}
|
||||
|
||||
void ClangSession::Jump::PrintDefinitionLocation( void )
|
||||
{
|
||||
if ( EvaluateDefinitionLocation() )
|
||||
{
|
||||
PrintLocation();
|
||||
}
|
||||
|
||||
m_Session.m_Writer.Flush();
|
||||
}
|
||||
|
||||
void ClangSession::Jump::PrintDeclarationLocation( void )
|
||||
{
|
||||
if ( EvaluateDeclarationLocation() )
|
||||
{
|
||||
PrintLocation();
|
||||
}
|
||||
|
||||
m_Session.m_Writer.Flush();
|
||||
}
|
||||
|
||||
void ClangSession::Jump::PrintSmartJumpLocation( void )
|
||||
{
|
||||
if ( EvaluateSmartJumpLocation() )
|
||||
{
|
||||
PrintLocation();
|
||||
}
|
||||
|
||||
m_Session.m_Writer.Flush();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*================================================================================================*/
|
||||
/* Global Class Method Definitions Section */
|
||||
/*================================================================================================*/
|
||||
|
||||
|
||||
ClangSession::ClangSession( const std::string& SessionName, const ClangContext& Context, StreamReader& Reader, StreamWriter& Writer )
|
||||
:
|
||||
m_SessionName( SessionName )
|
||||
, m_Context( Context )
|
||||
, m_Reader( Reader )
|
||||
, m_Writer( Writer )
|
||||
, m_CxTU( nullptr )
|
||||
, m_TranslationUnitFlags( Context.GetTranslationUnitFlags() )
|
||||
, m_CompleteAtFlags( Context.GetCompleteAtFlags() )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ClangSession::~ClangSession( void )
|
||||
{
|
||||
Deallocate();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ClangSession::ReadCFlags( void )
|
||||
{
|
||||
int32_t num_cflags;
|
||||
|
||||
m_Reader.ReadToken( "num_cflags:%d", num_cflags );
|
||||
|
||||
vector< string > cflags;
|
||||
|
||||
for ( int32_t i = 0; i < num_cflags; ++i )
|
||||
{
|
||||
// CFLAGS's white space must be accept.
|
||||
// a separator is '\n'.
|
||||
cflags.push_back( m_Reader.ReadToken( "%[^\n]" ) );
|
||||
}
|
||||
|
||||
m_CFlagsBuffer.Allocate( cflags );
|
||||
}
|
||||
|
||||
void ClangSession::ReadSourceCode( void )
|
||||
{
|
||||
int32_t src_length;
|
||||
|
||||
m_Reader.ReadToken( "source_length:%d", src_length );
|
||||
|
||||
m_CSourceCodeBuffer.Allocate( src_length );
|
||||
|
||||
m_Reader.Read( m_CSourceCodeBuffer.GetBuffer(), m_CSourceCodeBuffer.GetSize() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ClangSession::CreateTranslationUnit( void )
|
||||
{
|
||||
if ( m_CxTU )
|
||||
{
|
||||
// clang parser already exist
|
||||
return;
|
||||
}
|
||||
|
||||
CXUnsavedFile unsaved_file = GetCXUnsavedFile();
|
||||
|
||||
m_CxTU = clang_parseTranslationUnit( m_Context.GetCXIndex(), m_SessionName.c_str(),
|
||||
static_cast< const char * const *>( m_CFlagsBuffer.GetCFlags() ), m_CFlagsBuffer.GetNumberOfCFlags(),
|
||||
&unsaved_file, 1, m_TranslationUnitFlags );
|
||||
|
||||
clang_reparseTranslationUnit( m_CxTU, 1, &unsaved_file, m_TranslationUnitFlags );
|
||||
}
|
||||
|
||||
void ClangSession::DeleteTranslationUnit( void )
|
||||
{
|
||||
if ( !m_CxTU )
|
||||
{
|
||||
// clang parser not exist
|
||||
return;
|
||||
}
|
||||
|
||||
clang_disposeTranslationUnit( m_CxTU );
|
||||
m_CxTU = nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ClangSession::Allocate( void )
|
||||
{
|
||||
ReadCFlags();
|
||||
ReadSourceCode();
|
||||
CreateTranslationUnit();
|
||||
}
|
||||
|
||||
void ClangSession::Deallocate( void )
|
||||
{
|
||||
DeleteTranslationUnit();
|
||||
}
|
||||
|
||||
|
||||
void ClangSession::commandSuspend( void )
|
||||
{
|
||||
DeleteTranslationUnit();
|
||||
}
|
||||
|
||||
void ClangSession::commandResume( void )
|
||||
{
|
||||
CreateTranslationUnit();
|
||||
}
|
||||
|
||||
|
||||
void ClangSession::commandSetCFlags( void )
|
||||
{
|
||||
DeleteTranslationUnit();
|
||||
ReadCFlags();
|
||||
ReadSourceCode();
|
||||
CreateTranslationUnit();
|
||||
}
|
||||
|
||||
|
||||
void ClangSession::commandSetSourceCode( void )
|
||||
{
|
||||
ReadSourceCode();
|
||||
}
|
||||
|
||||
void ClangSession::commandReparse( void )
|
||||
{
|
||||
if ( !m_CxTU )
|
||||
{
|
||||
// clang parser not exist
|
||||
return;
|
||||
}
|
||||
|
||||
CXUnsavedFile unsaved_file = GetCXUnsavedFile();
|
||||
|
||||
clang_reparseTranslationUnit( m_CxTU, 1, &unsaved_file, m_TranslationUnitFlags );
|
||||
}
|
||||
|
||||
|
||||
void ClangSession::commandCompletion( void )
|
||||
{
|
||||
if ( !m_CxTU )
|
||||
{
|
||||
// clang parser not exist
|
||||
return;
|
||||
}
|
||||
|
||||
Completion printer( *this );
|
||||
|
||||
printer.PrintCompleteCandidates();
|
||||
}
|
||||
|
||||
|
||||
void ClangSession::commandDiagnostics( void )
|
||||
{
|
||||
if ( !m_CxTU )
|
||||
{
|
||||
// clang parser not exist
|
||||
return;
|
||||
}
|
||||
|
||||
Diagnostics printer( *this );
|
||||
|
||||
printer.PrintDiagnosticsResult();
|
||||
}
|
||||
|
||||
|
||||
void ClangSession::commandInclusion( void )
|
||||
{
|
||||
if ( !m_CxTU )
|
||||
{
|
||||
// clang parser not exist
|
||||
return;
|
||||
}
|
||||
|
||||
Jump printer( *this );
|
||||
|
||||
printer.PrintInclusionFileLocation();
|
||||
}
|
||||
|
||||
|
||||
void ClangSession::commandDeclaration( void )
|
||||
{
|
||||
if ( !m_CxTU )
|
||||
{
|
||||
// clang parser not exist
|
||||
return;
|
||||
}
|
||||
|
||||
Jump printer( *this );
|
||||
|
||||
printer.PrintDeclarationLocation();
|
||||
}
|
||||
|
||||
|
||||
void ClangSession::commandDefinition( void )
|
||||
{
|
||||
if ( !m_CxTU )
|
||||
{
|
||||
// clang parser not exist
|
||||
return;
|
||||
}
|
||||
|
||||
Jump printer( *this );
|
||||
|
||||
printer.PrintDefinitionLocation();
|
||||
}
|
||||
|
||||
|
||||
void ClangSession::commandSmartJump( void )
|
||||
{
|
||||
if ( !m_CxTU )
|
||||
{
|
||||
// clang parser not exist
|
||||
return;
|
||||
}
|
||||
|
||||
Jump printer( *this );
|
||||
|
||||
printer.PrintSmartJumpLocation();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*================================================================================================*/
|
||||
/* EOF */
|
||||
/*================================================================================================*/
|
@ -1,133 +0,0 @@
|
||||
/* -*- mode: c++ ; coding: utf-8-unix -*- */
|
||||
/* last updated : 2015/07/25.00:55:41 */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013-2015 yaruopooner [https://github.com/yaruopooner]
|
||||
*
|
||||
* This file is part of ac-clang.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __CLANG_SESSION_HPP__
|
||||
#define __CLANG_SESSION_HPP__
|
||||
|
||||
|
||||
|
||||
|
||||
/*================================================================================================*/
|
||||
/* Comment */
|
||||
/*================================================================================================*/
|
||||
|
||||
|
||||
/*================================================================================================*/
|
||||
/* Include Files */
|
||||
/*================================================================================================*/
|
||||
|
||||
#include "Common.hpp"
|
||||
|
||||
|
||||
/*================================================================================================*/
|
||||
/* Global Class Method Definitions Section */
|
||||
/*================================================================================================*/
|
||||
|
||||
|
||||
|
||||
class ClangSession
|
||||
{
|
||||
public:
|
||||
ClangSession( const std::string& SessionName, const ClangContext& Context, StreamReader& Reader, StreamWriter& Writer );
|
||||
virtual ~ClangSession( void );
|
||||
|
||||
|
||||
void Allocate( void );
|
||||
void Deallocate( void );
|
||||
|
||||
|
||||
// const CFlagsBuffer& GetCFlagsBuffer( void ) const
|
||||
// {
|
||||
// return ( m_CFlagsBuffer );
|
||||
// }
|
||||
// CFlagsBuffer& GetCFlagsBuffer( void )
|
||||
// {
|
||||
// return ( m_CFlagsBuffer );
|
||||
// }
|
||||
|
||||
|
||||
// commands
|
||||
void commandSuspend( void );
|
||||
void commandResume( void );
|
||||
void commandSetCFlags( void );
|
||||
void commandSetSourceCode( void );
|
||||
void commandReparse( void );
|
||||
void commandCompletion( void );
|
||||
void commandDiagnostics( void );
|
||||
void commandInclusion( void );
|
||||
void commandDeclaration( void );
|
||||
void commandDefinition( void );
|
||||
void commandSmartJump( void );
|
||||
|
||||
|
||||
private:
|
||||
CXUnsavedFile GetCXUnsavedFile( void ) const
|
||||
{
|
||||
CXUnsavedFile unsaved_file;
|
||||
|
||||
unsaved_file.Filename = m_SessionName.c_str();
|
||||
unsaved_file.Contents = m_CSourceCodeBuffer.GetBuffer();
|
||||
unsaved_file.Length = m_CSourceCodeBuffer.GetSize();
|
||||
|
||||
return ( unsaved_file );
|
||||
}
|
||||
|
||||
void ReadCFlags( void );
|
||||
void ReadSourceCode( void );
|
||||
|
||||
void CreateTranslationUnit( void );
|
||||
void DeleteTranslationUnit( void );
|
||||
|
||||
|
||||
// internal printer classes
|
||||
class Completion;
|
||||
class Diagnostics;
|
||||
class Jump;
|
||||
|
||||
|
||||
private:
|
||||
const std::string m_SessionName;
|
||||
const ClangContext& m_Context;
|
||||
StreamReader& m_Reader;
|
||||
StreamWriter& m_Writer;
|
||||
|
||||
// clang parser object
|
||||
CXTranslationUnit m_CxTU;
|
||||
|
||||
// clang parser options
|
||||
uint32_t m_TranslationUnitFlags;
|
||||
uint32_t m_CompleteAtFlags;
|
||||
|
||||
CFlagsBuffer m_CFlagsBuffer;
|
||||
CSourceCodeBuffer m_CSourceCodeBuffer;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // __CLANG_SESSION_HPP__
|
||||
/*================================================================================================*/
|
||||
/* EOF */
|
||||
/*================================================================================================*/
|
@ -1,607 +0,0 @@
|
||||
/* -*- mode: c++ ; coding: utf-8-unix -*- */
|
||||
/* last updated : 2015/05/23.23:17:32 */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013-2015 yaruopooner [https://github.com/yaruopooner]
|
||||
*
|
||||
* This file is part of ac-clang.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __COMMAND_LINE_HPP__
|
||||
#define __COMMAND_LINE_HPP__
|
||||
|
||||
|
||||
/*================================================================================================*/
|
||||
/* Include Files */
|
||||
/*================================================================================================*/
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
|
||||
/*================================================================================================*/
|
||||
/* Class */
|
||||
/*================================================================================================*/
|
||||
|
||||
|
||||
namespace CommandLine
|
||||
{
|
||||
|
||||
|
||||
template< typename Target, typename Source >
|
||||
struct lexical_cast_imp
|
||||
{
|
||||
static Target cast( const Source& value )
|
||||
{
|
||||
Target result;
|
||||
std::stringstream interpreter;
|
||||
|
||||
if ( !( interpreter << value ) || !( interpreter >> result ) || !( interpreter >> std::ws ).eof() )
|
||||
{
|
||||
throw std::invalid_argument( "value cast failure." );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template< typename Source >
|
||||
struct lexical_cast_imp< Source, Source >
|
||||
{
|
||||
static Source cast( const Source& value )
|
||||
{
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
template< typename Target, typename Source >
|
||||
static Target lexical_cast( const Source& value )
|
||||
{
|
||||
return lexical_cast_imp< Target, Source >::cast( value );
|
||||
}
|
||||
|
||||
|
||||
template< typename T >
|
||||
struct DefaultReader
|
||||
{
|
||||
virtual ~DefaultReader( void )
|
||||
{
|
||||
}
|
||||
virtual T operator ()( const std::string& argument ) const
|
||||
{
|
||||
return lexical_cast< T >( argument );
|
||||
}
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
class RangeReader : public DefaultReader< T >
|
||||
{
|
||||
public:
|
||||
RangeReader( T min, T max ) :
|
||||
m_Min( min )
|
||||
, m_Max( max )
|
||||
{
|
||||
}
|
||||
|
||||
virtual T operator ()( const std::string& argument ) const override
|
||||
{
|
||||
const T value = lexical_cast< T >( argument );
|
||||
|
||||
if ( ( value < m_Min ) || ( m_Max < value ) )
|
||||
{
|
||||
throw std::domain_error( "value is out of range : " + argument );
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
T m_Min;
|
||||
T m_Max;
|
||||
};
|
||||
|
||||
|
||||
class IOptionWithValue;
|
||||
template< typename T, typename Reader >
|
||||
class OptionWithValueWithReader;
|
||||
|
||||
|
||||
class IOptionDetail
|
||||
{
|
||||
protected:
|
||||
virtual ~IOptionDetail()
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
enum Flag
|
||||
{
|
||||
kFlag_Once = 1 << 0,
|
||||
kFlag_HasValue = 1 << 1,
|
||||
kFlag_RequireValue = 1 << 2,
|
||||
};
|
||||
|
||||
virtual int32_t GetId( void ) const = 0;
|
||||
virtual const std::string& GetName( void ) const = 0;
|
||||
virtual const std::string& GetShortName( void ) const = 0;
|
||||
virtual const std::string& GetDescription( void ) const = 0;
|
||||
virtual bool HasFlag( uint32_t flag ) const = 0;
|
||||
virtual const std::string& GetValueDescription( void ) const = 0;
|
||||
|
||||
virtual bool IsSameName( const std::string& name ) const = 0;
|
||||
|
||||
virtual std::shared_ptr< IOptionWithValue > CreateEvaluator( const std::string& argument ) const = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
template< typename T, typename Reader = DefaultReader< T > >
|
||||
class OptionDetail : public IOptionDetail
|
||||
{
|
||||
public:
|
||||
OptionDetail( int32_t id, const std::string& name, const std::string& shortName, const std::string& description, uint32_t flags = 0, const std::string& valueDescription = std::string(), const Reader& reader = Reader() ) :
|
||||
m_Id( id )
|
||||
, m_Name( "--" + name )
|
||||
, m_ShortName( "-" + shortName )
|
||||
, m_Description( description )
|
||||
, m_Flags( flags )
|
||||
, m_ValueDescription( valueDescription )
|
||||
, m_Reader( reader )
|
||||
{
|
||||
}
|
||||
virtual ~OptionDetail()
|
||||
{
|
||||
}
|
||||
|
||||
int32_t GetId( void ) const final
|
||||
{
|
||||
return m_Id;
|
||||
}
|
||||
const std::string& GetName( void ) const final
|
||||
{
|
||||
return m_Name;
|
||||
}
|
||||
const std::string& GetShortName( void ) const final
|
||||
{
|
||||
return m_ShortName;
|
||||
}
|
||||
const std::string& GetDescription( void ) const final
|
||||
{
|
||||
return m_Description;
|
||||
}
|
||||
bool HasFlag( uint32_t flag ) const final
|
||||
{
|
||||
return ( m_Flags & flag ) ? true : false;
|
||||
}
|
||||
const std::string& GetValueDescription( void ) const final
|
||||
{
|
||||
return m_ValueDescription;
|
||||
}
|
||||
|
||||
bool IsSameName( const std::string& name ) const final
|
||||
{
|
||||
return ( ( m_Name == name ) || ( m_ShortName == name ) );
|
||||
}
|
||||
|
||||
std::shared_ptr< IOptionWithValue > CreateEvaluator( const std::string& argument ) const override
|
||||
{
|
||||
return std::make_shared< OptionWithValueWithReader< T, Reader > >( this, argument );
|
||||
}
|
||||
|
||||
T GetValue( const std::string& argument ) const
|
||||
{
|
||||
return m_Reader( argument );
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
const int32_t m_Id;
|
||||
const std::string m_Name;
|
||||
const std::string m_ShortName;
|
||||
const std::string m_Description;
|
||||
const uint32_t m_Flags;
|
||||
const std::string m_ValueDescription;
|
||||
const Reader m_Reader;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class IOptionWithValue
|
||||
{
|
||||
protected:
|
||||
virtual ~IOptionWithValue( void )
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
virtual const IOptionDetail* GetDetail( void ) const = 0;
|
||||
virtual uint32_t GetId( void ) const = 0;
|
||||
virtual const std::string& GetOptionName( void ) const = 0;
|
||||
virtual bool IsValid( void ) const = 0;
|
||||
virtual bool Evaluate( std::string& message ) = 0;
|
||||
};
|
||||
|
||||
|
||||
template< typename T >
|
||||
class OptionWithValue : public IOptionWithValue
|
||||
{
|
||||
protected:
|
||||
OptionWithValue( const IOptionDetail* detail, const std::string& argument ) :
|
||||
m_Detail( detail )
|
||||
, m_Argument( argument )
|
||||
, m_ValidValue( false )
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
virtual ~OptionWithValue( void )
|
||||
{
|
||||
}
|
||||
|
||||
const IOptionDetail* GetDetail( void ) const final
|
||||
{
|
||||
return m_Detail;
|
||||
}
|
||||
|
||||
uint32_t GetId( void ) const final
|
||||
{
|
||||
return m_Detail->GetId();
|
||||
}
|
||||
|
||||
const std::string& GetOptionName( void ) const final
|
||||
{
|
||||
return m_Detail->GetName();
|
||||
}
|
||||
|
||||
bool IsValid( void ) const final
|
||||
{
|
||||
return m_ValidValue;
|
||||
}
|
||||
|
||||
virtual bool Evaluate( std::string& message ) override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
const T& GetValue( void ) const
|
||||
{
|
||||
return m_Value;
|
||||
}
|
||||
|
||||
protected:
|
||||
const IOptionDetail* m_Detail;
|
||||
const std::string m_Argument;
|
||||
bool m_ValidValue;
|
||||
T m_Value;
|
||||
};
|
||||
|
||||
|
||||
template< typename T, typename Reader >
|
||||
class OptionWithValueWithReader : public OptionWithValue< T >
|
||||
{
|
||||
public:
|
||||
OptionWithValueWithReader( const IOptionDetail* detail, const std::string& argument ) :
|
||||
OptionWithValue< T >( detail, argument )
|
||||
{
|
||||
}
|
||||
virtual ~OptionWithValueWithReader( void )
|
||||
{
|
||||
}
|
||||
|
||||
bool Evaluate( std::string& message ) override
|
||||
{
|
||||
try
|
||||
{
|
||||
if ( !this->m_Argument.empty() )
|
||||
{
|
||||
const auto* detail = dynamic_cast< const OptionDetail< T, Reader >* >( this->m_Detail );
|
||||
|
||||
this->m_Value = detail->GetValue( this->m_Argument );
|
||||
this->m_ValidValue = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch ( const std::exception& exception )
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
ss << this->m_Detail->GetName() << " : " << exception.what() << std::endl;
|
||||
ss << this->m_Detail->GetDescription();
|
||||
message = ss.str();
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
typedef std::vector< std::shared_ptr< IOptionDetail > > OptionDetailArray;
|
||||
typedef std::vector< std::shared_ptr< IOptionWithValue > > OptionWithValueArray;
|
||||
|
||||
class Parser
|
||||
{
|
||||
public:
|
||||
|
||||
void AddOption( int32_t id, const std::string& name, const std::string& shortName, const std::string& description, uint32_t flags = 0, const std::string& valueDescription = std::string() )
|
||||
{
|
||||
m_Details.push_back( std::make_shared< OptionDetail< std::string > >( id, name, shortName, description, flags, valueDescription ) );
|
||||
}
|
||||
|
||||
template< typename T, typename Reader = DefaultReader< T > >
|
||||
void AddOption( int32_t id, const std::string& name, const std::string& shortName, const std::string& description, uint32_t flags = 0, const std::string& valueDescription = std::string(), const Reader& reader = Reader() )
|
||||
{
|
||||
m_Details.push_back( std::make_shared< OptionDetail< T, Reader > >( id, name, shortName, description, flags, valueDescription, reader ) );
|
||||
}
|
||||
|
||||
size_t GetNumberOfOptionValues( void ) const
|
||||
{
|
||||
return m_OptionValues.size();
|
||||
}
|
||||
|
||||
size_t GetNumberOfArguments( void ) const
|
||||
{
|
||||
return m_Arguments.size();
|
||||
}
|
||||
|
||||
static const std::string& GetOptionName( const IOptionWithValue* value )
|
||||
{
|
||||
return value->GetDetail()->GetName();
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
static const T& GetValue( const std::shared_ptr< IOptionWithValue >& value )
|
||||
{
|
||||
const auto* casted_value = dynamic_cast< const OptionWithValue< T >* >( value.get() );
|
||||
|
||||
return casted_value->GetValue();
|
||||
}
|
||||
|
||||
const OptionDetailArray& GetOptionDetailArray( void ) const
|
||||
{
|
||||
return m_Details;
|
||||
}
|
||||
const OptionWithValueArray& GetOptionWithValueArray( void ) const
|
||||
{
|
||||
return m_OptionValues;
|
||||
}
|
||||
|
||||
bool Parse( int argc, char* argv[] )
|
||||
{
|
||||
// clear & store
|
||||
m_Arguments.clear();
|
||||
for ( int i = 1; i < argc; ++i )
|
||||
{
|
||||
m_Arguments.push_back( argv[ i ] );
|
||||
}
|
||||
|
||||
// parse
|
||||
const size_t n_args = m_Arguments.size();
|
||||
|
||||
for ( size_t i = 0; i < n_args; ++i )
|
||||
{
|
||||
const std::string& option_name = m_Arguments[ i ];
|
||||
|
||||
if ( !HasOptionPrefix( option_name ) )
|
||||
{
|
||||
// error, argument is not option format
|
||||
// ignore
|
||||
m_Errors.push_back( "option syntax error : argument is not option format : " + option_name );
|
||||
continue;
|
||||
}
|
||||
|
||||
bool is_match = false;
|
||||
bool is_valid_format = false;
|
||||
std::string value;
|
||||
|
||||
for ( const auto detail : m_Details )
|
||||
{
|
||||
if ( !detail->IsSameName( option_name ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
is_match = true;
|
||||
|
||||
// found
|
||||
if ( detail->HasFlag( IOptionDetail::kFlag_HasValue ) )
|
||||
{
|
||||
const size_t next_i = i + 1;
|
||||
|
||||
if ( detail->HasFlag( IOptionDetail::kFlag_RequireValue ) )
|
||||
{
|
||||
if ( n_args <= next_i )
|
||||
{
|
||||
// error, argument locator over
|
||||
m_Errors.push_back( "option syntax error : not enough argument : " + option_name );
|
||||
break;
|
||||
}
|
||||
|
||||
const std::string& next_value = m_Arguments[ next_i ];
|
||||
|
||||
if ( HasOptionPrefix( next_value ) )
|
||||
{
|
||||
// option have not value
|
||||
m_Errors.push_back( "option syntax error : value not found : " + option_name );
|
||||
break;
|
||||
}
|
||||
|
||||
value = m_Arguments[ next_i ];
|
||||
i = next_i;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( next_i < n_args )
|
||||
{
|
||||
const std::string& next_value = m_Arguments[ next_i ];
|
||||
|
||||
if ( !HasOptionPrefix( next_value ) )
|
||||
{
|
||||
// option have not value
|
||||
value = m_Arguments[ next_i ];
|
||||
i = next_i;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// not value, option only
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// store found detal & value
|
||||
m_OptionValues.push_back( detail->CreateEvaluator( value ) );
|
||||
|
||||
is_valid_format = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !is_match )
|
||||
{
|
||||
// unknown option
|
||||
m_Warnings.push_back( "unknown option : " + option_name );
|
||||
|
||||
// value check
|
||||
const size_t next_i = i + 1;
|
||||
|
||||
if ( next_i < n_args )
|
||||
{
|
||||
const std::string& next_value = m_Arguments[ next_i ];
|
||||
|
||||
if ( !HasOptionPrefix( next_value ) )
|
||||
{
|
||||
// discard unknown option value
|
||||
i = next_i;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( !is_valid_format )
|
||||
{
|
||||
// illegal option format
|
||||
m_Errors.push_back( "option syntax error : illegal option format : " + option_name );
|
||||
}
|
||||
}
|
||||
|
||||
std::set< const IOptionDetail* > used_options;
|
||||
|
||||
for ( auto& option_value : m_OptionValues )
|
||||
{
|
||||
const IOptionDetail* detal = option_value->GetDetail();
|
||||
const bool found = ( used_options.find( detal ) != used_options.end() );
|
||||
|
||||
if ( !found )
|
||||
{
|
||||
// first use
|
||||
used_options.insert( detal );
|
||||
}
|
||||
|
||||
if ( found && detal->HasFlag( IOptionDetail::kFlag_Once ) )
|
||||
{
|
||||
// duplicate use
|
||||
m_Errors.push_back( "option syntax error : duplicate use : " + detal->GetName() );
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string message;
|
||||
|
||||
if ( !option_value->Evaluate( message ) )
|
||||
{
|
||||
m_Errors.push_back( message );
|
||||
// bad value
|
||||
}
|
||||
}
|
||||
|
||||
return ( m_Errors.size() == 0 );
|
||||
}
|
||||
|
||||
void PrintUsage( const std::string& format ) const
|
||||
{
|
||||
std::cout << "Usage: " << format <<std::endl;
|
||||
std::cout << std::endl;
|
||||
std::cout << "OPTIONS:" << std::endl;
|
||||
for ( const auto& detail : m_Details )
|
||||
{
|
||||
std::cout << " " << detail->GetName();
|
||||
if ( !detail->GetShortName().empty() )
|
||||
{
|
||||
std::cout << ", " << detail->GetShortName();
|
||||
}
|
||||
if ( !detail->GetValueDescription().empty() )
|
||||
{
|
||||
std::cout << " <" << detail->GetValueDescription() << ">";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
std::cout << " " << detail->GetDescription() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void PrintErrors( void ) const
|
||||
{
|
||||
if ( !m_Errors.empty() )
|
||||
{
|
||||
std::cout << "Error:" << std::endl;
|
||||
for ( const auto& error : m_Errors )
|
||||
{
|
||||
std::cout << error << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PrintWarnings( void ) const
|
||||
{
|
||||
if ( !m_Warnings.empty() )
|
||||
{
|
||||
std::cout << "Warning:" << std::endl;
|
||||
for ( const auto& warning : m_Warnings )
|
||||
{
|
||||
std::cout << warning << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
static bool HasOptionPrefix( const std::string& name )
|
||||
{
|
||||
return ( ( name.compare( 0, 2, "--" ) == 0 ) || ( name.compare( 0, 1, "-" ) == 0 ) );
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
OptionDetailArray m_Details;
|
||||
std::vector< std::string > m_Arguments;
|
||||
std::vector< std::string > m_Errors;
|
||||
std::vector< std::string > m_Warnings;
|
||||
OptionWithValueArray m_OptionValues;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
/*================================================================================================*/
|
||||
/* EOF */
|
||||
/*================================================================================================*/
|
@ -1,284 +0,0 @@
|
||||
/* -*- mode: c++ ; coding: utf-8-unix -*- */
|
||||
/* last updated : 2015/03/25.01:38:16 */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013-2015 yaruopooner [https://github.com/yaruopooner]
|
||||
*
|
||||
* This file is part of ac-clang.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
/*================================================================================================*/
|
||||
/* Comment */
|
||||
/*================================================================================================*/
|
||||
|
||||
|
||||
/*================================================================================================*/
|
||||
/* Include Files */
|
||||
/*================================================================================================*/
|
||||
|
||||
#include <cstring>
|
||||
#include <cstdarg>
|
||||
|
||||
#include "Common.hpp"
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
FlagConverter ClangFlagConverters::sm_CXTranslationUnitFlags;
|
||||
FlagConverter ClangFlagConverters::sm_CXCodeCompleteFlags;
|
||||
|
||||
|
||||
|
||||
/*================================================================================================*/
|
||||
/* Global Class Method Definitions Section */
|
||||
/*================================================================================================*/
|
||||
|
||||
|
||||
|
||||
StreamReader::StreamReader( void )
|
||||
:
|
||||
m_File( stdin )
|
||||
{
|
||||
ClearLine();
|
||||
}
|
||||
|
||||
StreamReader::~StreamReader( void )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void StreamReader::ClearLine( void )
|
||||
{
|
||||
::memset( m_Line, 0, kLineMax );
|
||||
}
|
||||
|
||||
|
||||
void StreamReader::StepNextLine( void )
|
||||
{
|
||||
char crlf[ kLineMax ];
|
||||
::fgets( crlf, kLineMax, m_File );
|
||||
}
|
||||
|
||||
const char* StreamReader::ReadToken( const char* Format, bool bStepNextLine )
|
||||
{
|
||||
ClearLine();
|
||||
|
||||
const int32_t result = ::fscanf( m_File, Format, m_Line );
|
||||
(void) result;
|
||||
|
||||
if ( bStepNextLine )
|
||||
{
|
||||
StepNextLine();
|
||||
}
|
||||
|
||||
return ( m_Line );
|
||||
}
|
||||
|
||||
void StreamReader::Read( char* Buffer, size_t ReadSize )
|
||||
{
|
||||
const size_t stored_size = ::fread( Buffer, 1, ReadSize, m_File );
|
||||
|
||||
if ( (stored_size < ReadSize) || ::feof( m_File ) )
|
||||
{
|
||||
// error
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
StreamWriter::StreamWriter( void )
|
||||
:
|
||||
m_File( stdout )
|
||||
{
|
||||
}
|
||||
|
||||
StreamWriter::~StreamWriter( void )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void StreamWriter::Write( const char* Format, ... )
|
||||
{
|
||||
va_list args;
|
||||
va_start( args, Format );
|
||||
|
||||
::vfprintf( m_File, Format, args );
|
||||
|
||||
va_end( args );
|
||||
}
|
||||
|
||||
void StreamWriter::Flush( void )
|
||||
{
|
||||
::fprintf( m_File, "$" );
|
||||
::fflush( m_File );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
CFlagsBuffer::CFlagsBuffer( void )
|
||||
:
|
||||
m_NumberOfCFlags( 0 )
|
||||
, m_CFlags( nullptr )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
CFlagsBuffer::~CFlagsBuffer( void )
|
||||
{
|
||||
Deallocate();
|
||||
}
|
||||
|
||||
|
||||
void CFlagsBuffer::Allocate( const std::vector< std::string >& Args )
|
||||
{
|
||||
Deallocate();
|
||||
|
||||
m_NumberOfCFlags = static_cast< int32_t >( Args.size() );
|
||||
m_CFlags = reinterpret_cast< char** >( ::calloc( sizeof( char* ), m_NumberOfCFlags ) );
|
||||
|
||||
for ( int32_t i = 0; i < m_NumberOfCFlags; ++i )
|
||||
{
|
||||
m_CFlags[ i ] = reinterpret_cast< char* >( ::calloc( sizeof( char ), Args[ i ].length() + 1 ) );
|
||||
|
||||
::strcpy( m_CFlags[ i ], Args[ i ].c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
void CFlagsBuffer::Deallocate( void )
|
||||
{
|
||||
if ( !m_CFlags )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for ( int32_t i = 0; i < m_NumberOfCFlags; ++i )
|
||||
{
|
||||
::free( m_CFlags[ i ] );
|
||||
}
|
||||
::free( m_CFlags );
|
||||
|
||||
m_CFlags = nullptr;
|
||||
m_NumberOfCFlags = 0;
|
||||
}
|
||||
|
||||
|
||||
CSourceCodeBuffer::CSourceCodeBuffer( void )
|
||||
:
|
||||
m_Size( 0 )
|
||||
, m_BufferCapacity( 0 )
|
||||
, m_Buffer( nullptr )
|
||||
{
|
||||
}
|
||||
|
||||
CSourceCodeBuffer::~CSourceCodeBuffer( void )
|
||||
{
|
||||
Deallocate();
|
||||
}
|
||||
|
||||
|
||||
void CSourceCodeBuffer::Allocate( int32_t Size )
|
||||
{
|
||||
m_Size = Size;
|
||||
|
||||
if ( m_Size >= m_BufferCapacity )
|
||||
{
|
||||
const int32_t extend_size = std::max( m_Size * 2, static_cast< int32_t >( kInitialSrcBufferSize ) );
|
||||
char* extend_buffer = reinterpret_cast< char* >( ::realloc( m_Buffer, extend_size ) );
|
||||
|
||||
if ( extend_buffer )
|
||||
{
|
||||
m_BufferCapacity = extend_size;
|
||||
m_Buffer = extend_buffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
// error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSourceCodeBuffer::Deallocate( void )
|
||||
{
|
||||
if ( m_Buffer )
|
||||
{
|
||||
::free( m_Buffer );
|
||||
m_Buffer = nullptr;
|
||||
}
|
||||
|
||||
m_Size = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ClangContext::ClangContext( bool excludeDeclarationsFromPCH )
|
||||
:
|
||||
m_CxIndex( nullptr )
|
||||
, m_ExcludeDeclarationsFromPCH( excludeDeclarationsFromPCH )
|
||||
, m_TranslationUnitFlags( CXTranslationUnit_PrecompiledPreamble )
|
||||
, m_CompleteAtFlags( CXCodeComplete_IncludeMacros )
|
||||
, m_CompleteResultsLimit( 0 )
|
||||
{
|
||||
Allocate();
|
||||
}
|
||||
|
||||
ClangContext::~ClangContext( void )
|
||||
{
|
||||
Deallocate();
|
||||
}
|
||||
|
||||
|
||||
void ClangContext::Allocate( void )
|
||||
{
|
||||
m_CxIndex = clang_createIndex( m_ExcludeDeclarationsFromPCH, 0 );
|
||||
}
|
||||
|
||||
void ClangContext::Deallocate( void )
|
||||
{
|
||||
if ( m_CxIndex )
|
||||
{
|
||||
clang_disposeIndex( m_CxIndex );
|
||||
m_CxIndex = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
ClangFlagConverters::ClangFlagConverters( void )
|
||||
{
|
||||
sm_CXTranslationUnitFlags.Add( FLAG_DETAILS( CXTranslationUnit_DetailedPreprocessingRecord ) );
|
||||
sm_CXTranslationUnitFlags.Add( FLAG_DETAILS( CXTranslationUnit_Incomplete ) );
|
||||
sm_CXTranslationUnitFlags.Add( FLAG_DETAILS( CXTranslationUnit_PrecompiledPreamble ) );
|
||||
sm_CXTranslationUnitFlags.Add( FLAG_DETAILS( CXTranslationUnit_CacheCompletionResults ) );
|
||||
sm_CXTranslationUnitFlags.Add( FLAG_DETAILS( CXTranslationUnit_ForSerialization ) );
|
||||
sm_CXTranslationUnitFlags.Add( FLAG_DETAILS( CXTranslationUnit_CXXChainedPCH ) );
|
||||
sm_CXTranslationUnitFlags.Add( FLAG_DETAILS( CXTranslationUnit_SkipFunctionBodies ) );
|
||||
sm_CXTranslationUnitFlags.Add( FLAG_DETAILS( CXTranslationUnit_IncludeBriefCommentsInCodeCompletion ) );
|
||||
|
||||
sm_CXCodeCompleteFlags.Add( FLAG_DETAILS( CXCodeComplete_IncludeMacros ) );
|
||||
sm_CXCodeCompleteFlags.Add( FLAG_DETAILS( CXCodeComplete_IncludeCodePatterns ) );
|
||||
sm_CXCodeCompleteFlags.Add( FLAG_DETAILS( CXCodeComplete_IncludeBriefComments ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*================================================================================================*/
|
||||
/* EOF */
|
||||
/*================================================================================================*/
|
@ -1,371 +0,0 @@
|
||||
/* -*- mode: c++ ; coding: utf-8-unix -*- */
|
||||
/* last updated : 2015/03/25.01:38:00 */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013-2015 yaruopooner [https://github.com/yaruopooner]
|
||||
*
|
||||
* This file is part of ac-clang.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __COMMON_HPP__
|
||||
#define __COMMON_HPP__
|
||||
|
||||
|
||||
|
||||
|
||||
/*================================================================================================*/
|
||||
/* Comment */
|
||||
/*================================================================================================*/
|
||||
|
||||
|
||||
/*================================================================================================*/
|
||||
/* Include Files */
|
||||
/*================================================================================================*/
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
|
||||
#include <algorithm>
|
||||
#include <tuple>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "clang-c/Index.h"
|
||||
|
||||
|
||||
|
||||
/*================================================================================================*/
|
||||
/* Class */
|
||||
/*================================================================================================*/
|
||||
|
||||
|
||||
|
||||
|
||||
class StreamReader
|
||||
{
|
||||
public:
|
||||
StreamReader( void );
|
||||
virtual ~StreamReader( void );
|
||||
|
||||
template< typename T >
|
||||
void ReadToken( const char* Format, T& Value, bool bStepNextLine = true )
|
||||
{
|
||||
ClearLine();
|
||||
::fscanf( m_File, Format, &Value );
|
||||
if ( bStepNextLine )
|
||||
{
|
||||
StepNextLine();
|
||||
}
|
||||
}
|
||||
|
||||
const char* ReadToken( const char* Format, bool bStepNextLine = true );
|
||||
|
||||
void Read( char* Buffer, size_t ReadSize );
|
||||
|
||||
private:
|
||||
void ClearLine( void );
|
||||
void StepNextLine( void );
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
kLineMax = 2048,
|
||||
};
|
||||
|
||||
FILE* m_File;
|
||||
char m_Line[ kLineMax ];
|
||||
};
|
||||
|
||||
|
||||
class StreamWriter
|
||||
{
|
||||
public:
|
||||
StreamWriter( void );
|
||||
virtual ~StreamWriter( void );
|
||||
|
||||
void Write( const char* Format, ... );
|
||||
void Flush( void );
|
||||
|
||||
private:
|
||||
FILE* m_File;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class CFlagsBuffer
|
||||
{
|
||||
public:
|
||||
CFlagsBuffer( void );
|
||||
virtual ~CFlagsBuffer( void );
|
||||
|
||||
void Allocate( const std::vector< std::string >& CFlags );
|
||||
void Deallocate( void );
|
||||
|
||||
int32_t GetNumberOfCFlags( void ) const
|
||||
{
|
||||
return ( m_NumberOfCFlags );
|
||||
}
|
||||
char** GetCFlags( void ) const
|
||||
{
|
||||
return ( m_CFlags );
|
||||
}
|
||||
|
||||
private:
|
||||
int32_t m_NumberOfCFlags;
|
||||
char** m_CFlags;
|
||||
};
|
||||
|
||||
|
||||
class CSourceCodeBuffer
|
||||
{
|
||||
public:
|
||||
CSourceCodeBuffer( void );
|
||||
virtual ~CSourceCodeBuffer( void );
|
||||
|
||||
void Allocate( int32_t Size );
|
||||
void Deallocate( void );
|
||||
|
||||
int32_t GetSize( void ) const
|
||||
{
|
||||
return ( m_Size );
|
||||
}
|
||||
char* GetBuffer( void ) const
|
||||
{
|
||||
return ( m_Buffer );
|
||||
}
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
kInitialSrcBufferSize = 4096,
|
||||
};
|
||||
|
||||
int32_t m_Size;
|
||||
int32_t m_BufferCapacity;
|
||||
char* m_Buffer;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class ClangContext
|
||||
{
|
||||
public:
|
||||
ClangContext( bool excludeDeclarationsFromPCH = false );
|
||||
virtual ~ClangContext( void );
|
||||
|
||||
void Allocate( void );
|
||||
void Deallocate( void );
|
||||
|
||||
const CXIndex GetCXIndex( void ) const
|
||||
{
|
||||
return ( m_CxIndex );
|
||||
}
|
||||
CXIndex GetCXIndex( void )
|
||||
{
|
||||
return ( m_CxIndex );
|
||||
}
|
||||
|
||||
void SetTranslationUnitFlags( uint32_t Flags )
|
||||
{
|
||||
m_TranslationUnitFlags = Flags;
|
||||
}
|
||||
uint32_t GetTranslationUnitFlags( void ) const
|
||||
{
|
||||
return ( m_TranslationUnitFlags );
|
||||
}
|
||||
|
||||
void SetCompleteAtFlags( uint32_t Flags )
|
||||
{
|
||||
m_CompleteAtFlags = Flags;
|
||||
}
|
||||
uint32_t GetCompleteAtFlags( void ) const
|
||||
{
|
||||
return ( m_CompleteAtFlags );
|
||||
}
|
||||
|
||||
void SetCompleteResultsLimit( uint32_t NumberOfLimit )
|
||||
{
|
||||
m_CompleteResultsLimit = NumberOfLimit;
|
||||
}
|
||||
uint32_t GetCompleteResultsLimit( void ) const
|
||||
{
|
||||
return ( m_CompleteResultsLimit );
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
CXIndex m_CxIndex;
|
||||
|
||||
bool m_ExcludeDeclarationsFromPCH;
|
||||
uint32_t m_TranslationUnitFlags;
|
||||
uint32_t m_CompleteAtFlags;
|
||||
uint32_t m_CompleteResultsLimit;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
template< uint32_t Value >
|
||||
struct BitField
|
||||
{
|
||||
enum
|
||||
{
|
||||
kValue = Value,
|
||||
kIndex = BitField< (Value >> 1) >::kIndex + 1,
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct BitField< 0 >
|
||||
{
|
||||
enum
|
||||
{
|
||||
kValue = 0,
|
||||
kIndex = -1,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
class FlagConverter
|
||||
{
|
||||
public:
|
||||
typedef std::tuple< const char*, uint32_t > Details;
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
kMaxValues = 32,
|
||||
};
|
||||
|
||||
|
||||
FlagConverter( void ) :
|
||||
m_MaxValue( 0 )
|
||||
{
|
||||
}
|
||||
virtual ~FlagConverter( void )
|
||||
{
|
||||
}
|
||||
|
||||
void Clear( void )
|
||||
{
|
||||
m_MaxValue = 0;
|
||||
}
|
||||
|
||||
|
||||
void Add( const Details& Values )
|
||||
{
|
||||
Add( std::get< 0 >( Values ), std::get< 1 >( Values ) );
|
||||
}
|
||||
|
||||
void Add( const char* Name, uint32_t BitIndex )
|
||||
{
|
||||
assert( Name );
|
||||
assert( BitIndex < kMaxValues );
|
||||
|
||||
m_FlagNames[ BitIndex ] = Name;
|
||||
m_MaxValue = std::max( m_MaxValue, (BitIndex + 1) );
|
||||
}
|
||||
|
||||
uint32_t GetValue( const std::string& Names ) const
|
||||
{
|
||||
return ( GetValue( Names.c_str() ) );
|
||||
}
|
||||
|
||||
uint32_t GetValue( const char* Names ) const
|
||||
{
|
||||
if ( !Names )
|
||||
{
|
||||
return ( 0 );
|
||||
}
|
||||
|
||||
std::string names( Names );
|
||||
const char* delimit = "|";
|
||||
|
||||
if ( *(names.rbegin()) != *delimit )
|
||||
{
|
||||
names += delimit;
|
||||
}
|
||||
|
||||
uint32_t value = 0;
|
||||
size_t begin = 0;
|
||||
size_t end = names.find_first_of( delimit );
|
||||
|
||||
while ( end != std::string::npos )
|
||||
{
|
||||
const size_t length = end - begin;
|
||||
const std::string name = names.substr( begin, length );
|
||||
|
||||
for ( size_t i = 0; i < m_MaxValue; ++i )
|
||||
{
|
||||
if ( m_FlagNames[ i ] == name )
|
||||
{
|
||||
value |= (1 << i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
begin = end + 1;
|
||||
end = names.find_first_of( delimit, begin );
|
||||
}
|
||||
|
||||
return ( value );
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_FlagNames[ kMaxValues ];
|
||||
uint32_t m_MaxValue;
|
||||
};
|
||||
|
||||
|
||||
#define FLAG_DETAILS( _FLAG_NAME ) FlagConverter::Details( #_FLAG_NAME, BitField< _FLAG_NAME >::kIndex )
|
||||
|
||||
|
||||
|
||||
|
||||
class ClangFlagConverters
|
||||
{
|
||||
public:
|
||||
ClangFlagConverters( void );
|
||||
|
||||
|
||||
static const FlagConverter& GetCXTranslationUnitFlags( void )
|
||||
{
|
||||
return ( sm_CXTranslationUnitFlags );
|
||||
}
|
||||
static const FlagConverter& GetCXCodeCompleteFlags( void )
|
||||
{
|
||||
return ( sm_CXCodeCompleteFlags );
|
||||
}
|
||||
|
||||
private:
|
||||
static FlagConverter sm_CXTranslationUnitFlags;
|
||||
static FlagConverter sm_CXCodeCompleteFlags;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // __COMMON_HPP__
|
||||
/*================================================================================================*/
|
||||
/* EOF */
|
||||
/*================================================================================================*/
|
@ -1,32 +0,0 @@
|
||||
# -*- mode: org ; coding: utf-8-unix -*-
|
||||
# last updated : 2015/09/05.04:13:32
|
||||
|
||||
|
||||
#+TITLE: clang-server Changes Log
|
||||
#+AUTHOR: yaruopooner
|
||||
#+EMAIL: [https://github.com/yaruopooner]
|
||||
#+OPTIONS: author:nil timestamp:t |:t \n:t ^:nil
|
||||
|
||||
|
||||
* 1.4.0
|
||||
- Clang-3.7.0 support
|
||||
|
||||
* 1.3.0
|
||||
- Added new feature. Jump to inclusion file. return from jumped location.
|
||||
- Bugfix
|
||||
|
||||
* 1.2.1
|
||||
- Fix compile error in clang.
|
||||
|
||||
* 1.2.0
|
||||
- Access specifier of completion candidate support.
|
||||
|
||||
* 1.1.1
|
||||
- Clang-3.6.1 support
|
||||
- Bugfix
|
||||
|
||||
* 1.1.0
|
||||
- Clang-3.6.0 support
|
||||
|
||||
* 1.0.0
|
||||
- Clang-3.5.0 support
|
@ -1,156 +0,0 @@
|
||||
/*==-- clang-c/BuildSystem.h - Utilities for use by build systems -*- C -*-===*\
|
||||
|* *|
|
||||
|* The LLVM Compiler Infrastructure *|
|
||||
|* *|
|
||||
|* This file is distributed under the University of Illinois Open Source *|
|
||||
|* License. See LICENSE.TXT for details. *|
|
||||
|* *|
|
||||
|*===----------------------------------------------------------------------===*|
|
||||
|* *|
|
||||
|* This header provides various utilities for use by build systems. *|
|
||||
|* *|
|
||||
\*===----------------------------------------------------------------------===*/
|
||||
|
||||
#ifndef LLVM_CLANG_C_BUILDSYSTEM_H
|
||||
#define LLVM_CLANG_C_BUILDSYSTEM_H
|
||||
|
||||
#include "clang-c/Platform.h"
|
||||
#include "clang-c/CXErrorCode.h"
|
||||
#include "clang-c/CXString.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \defgroup BUILD_SYSTEM Build system utilities
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Return the timestamp for use with Clang's
|
||||
* \c -fbuild-session-timestamp= option.
|
||||
*/
|
||||
CINDEX_LINKAGE unsigned long long clang_getBuildSessionTimestamp(void);
|
||||
|
||||
/**
|
||||
* \brief Object encapsulating information about overlaying virtual
|
||||
* file/directories over the real file system.
|
||||
*/
|
||||
typedef struct CXVirtualFileOverlayImpl *CXVirtualFileOverlay;
|
||||
|
||||
/**
|
||||
* \brief Create a \c CXVirtualFileOverlay object.
|
||||
* Must be disposed with \c clang_VirtualFileOverlay_dispose().
|
||||
*
|
||||
* \param options is reserved, always pass 0.
|
||||
*/
|
||||
CINDEX_LINKAGE CXVirtualFileOverlay
|
||||
clang_VirtualFileOverlay_create(unsigned options);
|
||||
|
||||
/**
|
||||
* \brief Map an absolute virtual file path to an absolute real one.
|
||||
* The virtual path must be canonicalized (not contain "."/"..").
|
||||
* \returns 0 for success, non-zero to indicate an error.
|
||||
*/
|
||||
CINDEX_LINKAGE enum CXErrorCode
|
||||
clang_VirtualFileOverlay_addFileMapping(CXVirtualFileOverlay,
|
||||
const char *virtualPath,
|
||||
const char *realPath);
|
||||
|
||||
/**
|
||||
* \brief Set the case sensitivity for the \c CXVirtualFileOverlay object.
|
||||
* The \c CXVirtualFileOverlay object is case-sensitive by default, this
|
||||
* option can be used to override the default.
|
||||
* \returns 0 for success, non-zero to indicate an error.
|
||||
*/
|
||||
CINDEX_LINKAGE enum CXErrorCode
|
||||
clang_VirtualFileOverlay_setCaseSensitivity(CXVirtualFileOverlay,
|
||||
int caseSensitive);
|
||||
|
||||
/**
|
||||
* \brief Write out the \c CXVirtualFileOverlay object to a char buffer.
|
||||
*
|
||||
* \param options is reserved, always pass 0.
|
||||
* \param out_buffer_ptr pointer to receive the buffer pointer, which should be
|
||||
* disposed using \c clang_free().
|
||||
* \param out_buffer_size pointer to receive the buffer size.
|
||||
* \returns 0 for success, non-zero to indicate an error.
|
||||
*/
|
||||
CINDEX_LINKAGE enum CXErrorCode
|
||||
clang_VirtualFileOverlay_writeToBuffer(CXVirtualFileOverlay, unsigned options,
|
||||
char **out_buffer_ptr,
|
||||
unsigned *out_buffer_size);
|
||||
|
||||
/**
|
||||
* \brief free memory allocated by libclang, such as the buffer returned by
|
||||
* \c CXVirtualFileOverlay() or \c clang_ModuleMapDescriptor_writeToBuffer().
|
||||
*
|
||||
* \param buffer memory pointer to free.
|
||||
*/
|
||||
CINDEX_LINKAGE void clang_free(void *buffer);
|
||||
|
||||
/**
|
||||
* \brief Dispose a \c CXVirtualFileOverlay object.
|
||||
*/
|
||||
CINDEX_LINKAGE void clang_VirtualFileOverlay_dispose(CXVirtualFileOverlay);
|
||||
|
||||
/**
|
||||
* \brief Object encapsulating information about a module.map file.
|
||||
*/
|
||||
typedef struct CXModuleMapDescriptorImpl *CXModuleMapDescriptor;
|
||||
|
||||
/**
|
||||
* \brief Create a \c CXModuleMapDescriptor object.
|
||||
* Must be disposed with \c clang_ModuleMapDescriptor_dispose().
|
||||
*
|
||||
* \param options is reserved, always pass 0.
|
||||
*/
|
||||
CINDEX_LINKAGE CXModuleMapDescriptor
|
||||
clang_ModuleMapDescriptor_create(unsigned options);
|
||||
|
||||
/**
|
||||
* \brief Sets the framework module name that the module.map describes.
|
||||
* \returns 0 for success, non-zero to indicate an error.
|
||||
*/
|
||||
CINDEX_LINKAGE enum CXErrorCode
|
||||
clang_ModuleMapDescriptor_setFrameworkModuleName(CXModuleMapDescriptor,
|
||||
const char *name);
|
||||
|
||||
/**
|
||||
* \brief Sets the umbrealla header name that the module.map describes.
|
||||
* \returns 0 for success, non-zero to indicate an error.
|
||||
*/
|
||||
CINDEX_LINKAGE enum CXErrorCode
|
||||
clang_ModuleMapDescriptor_setUmbrellaHeader(CXModuleMapDescriptor,
|
||||
const char *name);
|
||||
|
||||
/**
|
||||
* \brief Write out the \c CXModuleMapDescriptor object to a char buffer.
|
||||
*
|
||||
* \param options is reserved, always pass 0.
|
||||
* \param out_buffer_ptr pointer to receive the buffer pointer, which should be
|
||||
* disposed using \c clang_free().
|
||||
* \param out_buffer_size pointer to receive the buffer size.
|
||||
* \returns 0 for success, non-zero to indicate an error.
|
||||
*/
|
||||
CINDEX_LINKAGE enum CXErrorCode
|
||||
clang_ModuleMapDescriptor_writeToBuffer(CXModuleMapDescriptor, unsigned options,
|
||||
char **out_buffer_ptr,
|
||||
unsigned *out_buffer_size);
|
||||
|
||||
/**
|
||||
* \brief Dispose a \c CXModuleMapDescriptor object.
|
||||
*/
|
||||
CINDEX_LINKAGE void clang_ModuleMapDescriptor_dispose(CXModuleMapDescriptor);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CLANG_C_BUILD_SYSTEM_H */
|
||||
|
@ -1,170 +0,0 @@
|
||||
/*===-- clang-c/CXCompilationDatabase.h - Compilation database ---*- C -*-===*\
|
||||
|* *|
|
||||
|* The LLVM Compiler Infrastructure *|
|
||||
|* *|
|
||||
|* This file is distributed under the University of Illinois Open Source *|
|
||||
|* License. See LICENSE.TXT for details. *|
|
||||
|* *|
|
||||
|*===----------------------------------------------------------------------===*|
|
||||
|* *|
|
||||
|* This header provides a public inferface to use CompilationDatabase without *|
|
||||
|* the full Clang C++ API. *|
|
||||
|* *|
|
||||
\*===----------------------------------------------------------------------===*/
|
||||
|
||||
#ifndef LLVM_CLANG_C_CXCOMPILATIONDATABASE_H
|
||||
#define LLVM_CLANG_C_CXCOMPILATIONDATABASE_H
|
||||
|
||||
#include "clang-c/Platform.h"
|
||||
#include "clang-c/CXString.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup COMPILATIONDB CompilationDatabase functions
|
||||
* \ingroup CINDEX
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* A compilation database holds all information used to compile files in a
|
||||
* project. For each file in the database, it can be queried for the working
|
||||
* directory or the command line used for the compiler invocation.
|
||||
*
|
||||
* Must be freed by \c clang_CompilationDatabase_dispose
|
||||
*/
|
||||
typedef void * CXCompilationDatabase;
|
||||
|
||||
/**
|
||||
* \brief Contains the results of a search in the compilation database
|
||||
*
|
||||
* When searching for the compile command for a file, the compilation db can
|
||||
* return several commands, as the file may have been compiled with
|
||||
* different options in different places of the project. This choice of compile
|
||||
* commands is wrapped in this opaque data structure. It must be freed by
|
||||
* \c clang_CompileCommands_dispose.
|
||||
*/
|
||||
typedef void * CXCompileCommands;
|
||||
|
||||
/**
|
||||
* \brief Represents the command line invocation to compile a specific file.
|
||||
*/
|
||||
typedef void * CXCompileCommand;
|
||||
|
||||
/**
|
||||
* \brief Error codes for Compilation Database
|
||||
*/
|
||||
typedef enum {
|
||||
/*
|
||||
* \brief No error occurred
|
||||
*/
|
||||
CXCompilationDatabase_NoError = 0,
|
||||
|
||||
/*
|
||||
* \brief Database can not be loaded
|
||||
*/
|
||||
CXCompilationDatabase_CanNotLoadDatabase = 1
|
||||
|
||||
} CXCompilationDatabase_Error;
|
||||
|
||||
/**
|
||||
* \brief Creates a compilation database from the database found in directory
|
||||
* buildDir. For example, CMake can output a compile_commands.json which can
|
||||
* be used to build the database.
|
||||
*
|
||||
* It must be freed by \c clang_CompilationDatabase_dispose.
|
||||
*/
|
||||
CINDEX_LINKAGE CXCompilationDatabase
|
||||
clang_CompilationDatabase_fromDirectory(const char *BuildDir,
|
||||
CXCompilationDatabase_Error *ErrorCode);
|
||||
|
||||
/**
|
||||
* \brief Free the given compilation database
|
||||
*/
|
||||
CINDEX_LINKAGE void
|
||||
clang_CompilationDatabase_dispose(CXCompilationDatabase);
|
||||
|
||||
/**
|
||||
* \brief Find the compile commands used for a file. The compile commands
|
||||
* must be freed by \c clang_CompileCommands_dispose.
|
||||
*/
|
||||
CINDEX_LINKAGE CXCompileCommands
|
||||
clang_CompilationDatabase_getCompileCommands(CXCompilationDatabase,
|
||||
const char *CompleteFileName);
|
||||
|
||||
/**
|
||||
* \brief Get all the compile commands in the given compilation database.
|
||||
*/
|
||||
CINDEX_LINKAGE CXCompileCommands
|
||||
clang_CompilationDatabase_getAllCompileCommands(CXCompilationDatabase);
|
||||
|
||||
/**
|
||||
* \brief Free the given CompileCommands
|
||||
*/
|
||||
CINDEX_LINKAGE void clang_CompileCommands_dispose(CXCompileCommands);
|
||||
|
||||
/**
|
||||
* \brief Get the number of CompileCommand we have for a file
|
||||
*/
|
||||
CINDEX_LINKAGE unsigned
|
||||
clang_CompileCommands_getSize(CXCompileCommands);
|
||||
|
||||
/**
|
||||
* \brief Get the I'th CompileCommand for a file
|
||||
*
|
||||
* Note : 0 <= i < clang_CompileCommands_getSize(CXCompileCommands)
|
||||
*/
|
||||
CINDEX_LINKAGE CXCompileCommand
|
||||
clang_CompileCommands_getCommand(CXCompileCommands, unsigned I);
|
||||
|
||||
/**
|
||||
* \brief Get the working directory where the CompileCommand was executed from
|
||||
*/
|
||||
CINDEX_LINKAGE CXString
|
||||
clang_CompileCommand_getDirectory(CXCompileCommand);
|
||||
|
||||
/**
|
||||
* \brief Get the number of arguments in the compiler invocation.
|
||||
*
|
||||
*/
|
||||
CINDEX_LINKAGE unsigned
|
||||
clang_CompileCommand_getNumArgs(CXCompileCommand);
|
||||
|
||||
/**
|
||||
* \brief Get the I'th argument value in the compiler invocations
|
||||
*
|
||||
* Invariant :
|
||||
* - argument 0 is the compiler executable
|
||||
*/
|
||||
CINDEX_LINKAGE CXString
|
||||
clang_CompileCommand_getArg(CXCompileCommand, unsigned I);
|
||||
|
||||
/**
|
||||
* \brief Get the number of source mappings for the compiler invocation.
|
||||
*/
|
||||
CINDEX_LINKAGE unsigned
|
||||
clang_CompileCommand_getNumMappedSources(CXCompileCommand);
|
||||
|
||||
/**
|
||||
* \brief Get the I'th mapped source path for the compiler invocation.
|
||||
*/
|
||||
CINDEX_LINKAGE CXString
|
||||
clang_CompileCommand_getMappedSourcePath(CXCompileCommand, unsigned I);
|
||||
|
||||
/**
|
||||
* \brief Get the I'th mapped source content for the compiler invocation.
|
||||
*/
|
||||
CINDEX_LINKAGE CXString
|
||||
clang_CompileCommand_getMappedSourceContent(CXCompileCommand, unsigned I);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
@ -1,64 +0,0 @@
|
||||
/*===-- clang-c/CXErrorCode.h - C Index Error Codes --------------*- C -*-===*\
|
||||
|* *|
|
||||
|* The LLVM Compiler Infrastructure *|
|
||||
|* *|
|
||||
|* This file is distributed under the University of Illinois Open Source *|
|
||||
|* License. See LICENSE.TXT for details. *|
|
||||
|* *|
|
||||
|*===----------------------------------------------------------------------===*|
|
||||
|* *|
|
||||
|* This header provides the CXErrorCode enumerators. *|
|
||||
|* *|
|
||||
\*===----------------------------------------------------------------------===*/
|
||||
|
||||
#ifndef LLVM_CLANG_C_CXERRORCODE_H
|
||||
#define LLVM_CLANG_C_CXERRORCODE_H
|
||||
|
||||
#include "clang-c/Platform.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Error codes returned by libclang routines.
|
||||
*
|
||||
* Zero (\c CXError_Success) is the only error code indicating success. Other
|
||||
* error codes, including not yet assigned non-zero values, indicate errors.
|
||||
*/
|
||||
enum CXErrorCode {
|
||||
/**
|
||||
* \brief No error.
|
||||
*/
|
||||
CXError_Success = 0,
|
||||
|
||||
/**
|
||||
* \brief A generic error code, no further details are available.
|
||||
*
|
||||
* Errors of this kind can get their own specific error codes in future
|
||||
* libclang versions.
|
||||
*/
|
||||
CXError_Failure = 1,
|
||||
|
||||
/**
|
||||
* \brief libclang crashed while performing the requested operation.
|
||||
*/
|
||||
CXError_Crashed = 2,
|
||||
|
||||
/**
|
||||
* \brief The function detected that the arguments violate the function
|
||||
* contract.
|
||||
*/
|
||||
CXError_InvalidArguments = 3,
|
||||
|
||||
/**
|
||||
* \brief An AST deserialization error has occurred.
|
||||
*/
|
||||
CXError_ASTReadError = 4
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
@ -1,61 +0,0 @@
|
||||
/*===-- clang-c/CXString.h - C Index strings --------------------*- C -*-===*\
|
||||
|* *|
|
||||
|* The LLVM Compiler Infrastructure *|
|
||||
|* *|
|
||||
|* This file is distributed under the University of Illinois Open Source *|
|
||||
|* License. See LICENSE.TXT for details. *|
|
||||
|* *|
|
||||
|*===----------------------------------------------------------------------===*|
|
||||
|* *|
|
||||
|* This header provides the interface to C Index strings. *|
|
||||
|* *|
|
||||
\*===----------------------------------------------------------------------===*/
|
||||
|
||||
#ifndef LLVM_CLANG_C_CXSTRING_H
|
||||
#define LLVM_CLANG_C_CXSTRING_H
|
||||
|
||||
#include "clang-c/Platform.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \defgroup CINDEX_STRING String manipulation routines
|
||||
* \ingroup CINDEX
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief A character string.
|
||||
*
|
||||
* The \c CXString type is used to return strings from the interface when
|
||||
* the ownership of that string might differ from one call to the next.
|
||||
* Use \c clang_getCString() to retrieve the string data and, once finished
|
||||
* with the string data, call \c clang_disposeString() to free the string.
|
||||
*/
|
||||
typedef struct {
|
||||
const void *data;
|
||||
unsigned private_flags;
|
||||
} CXString;
|
||||
|
||||
/**
|
||||
* \brief Retrieve the character data associated with the given string.
|
||||
*/
|
||||
CINDEX_LINKAGE const char *clang_getCString(CXString string);
|
||||
|
||||
/**
|
||||
* \brief Free the given string.
|
||||
*/
|
||||
CINDEX_LINKAGE void clang_disposeString(CXString string);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
@ -1,554 +0,0 @@
|
||||
/*==-- clang-c/Documentation.h - Utilities for comment processing -*- C -*-===*\
|
||||
|* *|
|
||||
|* The LLVM Compiler Infrastructure *|
|
||||
|* *|
|
||||
|* This file is distributed under the University of Illinois Open Source *|
|
||||
|* License. See LICENSE.TXT for details. *|
|
||||
|* *|
|
||||
|*===----------------------------------------------------------------------===*|
|
||||
|* *|
|
||||
|* This header provides a supplementary interface for inspecting *|
|
||||
|* documentation comments. *|
|
||||
|* *|
|
||||
\*===----------------------------------------------------------------------===*/
|
||||
|
||||
#ifndef LLVM_CLANG_C_DOCUMENTATION_H
|
||||
#define LLVM_CLANG_C_DOCUMENTATION_H
|
||||
|
||||
#include "clang-c/Index.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \defgroup CINDEX_COMMENT Comment introspection
|
||||
*
|
||||
* The routines in this group provide access to information in documentation
|
||||
* comments. These facilities are distinct from the core and may be subject to
|
||||
* their own schedule of stability and deprecation.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief A parsed comment.
|
||||
*/
|
||||
typedef struct {
|
||||
const void *ASTNode;
|
||||
CXTranslationUnit TranslationUnit;
|
||||
} CXComment;
|
||||
|
||||
/**
|
||||
* \brief Given a cursor that represents a documentable entity (e.g.,
|
||||
* declaration), return the associated parsed comment as a
|
||||
* \c CXComment_FullComment AST node.
|
||||
*/
|
||||
CINDEX_LINKAGE CXComment clang_Cursor_getParsedComment(CXCursor C);
|
||||
|
||||
/**
|
||||
* \brief Describes the type of the comment AST node (\c CXComment). A comment
|
||||
* node can be considered block content (e. g., paragraph), inline content
|
||||
* (plain text) or neither (the root AST node).
|
||||
*/
|
||||
enum CXCommentKind {
|
||||
/**
|
||||
* \brief Null comment. No AST node is constructed at the requested location
|
||||
* because there is no text or a syntax error.
|
||||
*/
|
||||
CXComment_Null = 0,
|
||||
|
||||
/**
|
||||
* \brief Plain text. Inline content.
|
||||
*/
|
||||
CXComment_Text = 1,
|
||||
|
||||
/**
|
||||
* \brief A command with word-like arguments that is considered inline content.
|
||||
*
|
||||
* For example: \\c command.
|
||||
*/
|
||||
CXComment_InlineCommand = 2,
|
||||
|
||||
/**
|
||||
* \brief HTML start tag with attributes (name-value pairs). Considered
|
||||
* inline content.
|
||||
*
|
||||
* For example:
|
||||
* \verbatim
|
||||
* <br> <br /> <a href="http://example.org/">
|
||||
* \endverbatim
|
||||
*/
|
||||
CXComment_HTMLStartTag = 3,
|
||||
|
||||
/**
|
||||
* \brief HTML end tag. Considered inline content.
|
||||
*
|
||||
* For example:
|
||||
* \verbatim
|
||||
* </a>
|
||||
* \endverbatim
|
||||
*/
|
||||
CXComment_HTMLEndTag = 4,
|
||||
|
||||
/**
|
||||
* \brief A paragraph, contains inline comment. The paragraph itself is
|
||||
* block content.
|
||||
*/
|
||||
CXComment_Paragraph = 5,
|
||||
|
||||
/**
|
||||
* \brief A command that has zero or more word-like arguments (number of
|
||||
* word-like arguments depends on command name) and a paragraph as an
|
||||
* argument. Block command is block content.
|
||||
*
|
||||
* Paragraph argument is also a child of the block command.
|
||||
*
|
||||
* For example: \\brief has 0 word-like arguments and a paragraph argument.
|
||||
*
|
||||
* AST nodes of special kinds that parser knows about (e. g., \\param
|
||||
* command) have their own node kinds.
|
||||
*/
|
||||
CXComment_BlockCommand = 6,
|
||||
|
||||
/**
|
||||
* \brief A \\param or \\arg command that describes the function parameter
|
||||
* (name, passing direction, description).
|
||||
*
|
||||
* For example: \\param [in] ParamName description.
|
||||
*/
|
||||
CXComment_ParamCommand = 7,
|
||||
|
||||
/**
|
||||
* \brief A \\tparam command that describes a template parameter (name and
|
||||
* description).
|
||||
*
|
||||
* For example: \\tparam T description.
|
||||
*/
|
||||
CXComment_TParamCommand = 8,
|
||||
|
||||
/**
|
||||
* \brief A verbatim block command (e. g., preformatted code). Verbatim
|
||||
* block has an opening and a closing command and contains multiple lines of
|
||||
* text (\c CXComment_VerbatimBlockLine child nodes).
|
||||
*
|
||||
* For example:
|
||||
* \\verbatim
|
||||
* aaa
|
||||
* \\endverbatim
|
||||
*/
|
||||
CXComment_VerbatimBlockCommand = 9,
|
||||
|
||||
/**
|
||||
* \brief A line of text that is contained within a
|
||||
* CXComment_VerbatimBlockCommand node.
|
||||
*/
|
||||
CXComment_VerbatimBlockLine = 10,
|
||||
|
||||
/**
|
||||
* \brief A verbatim line command. Verbatim line has an opening command,
|
||||
* a single line of text (up to the newline after the opening command) and
|
||||
* has no closing command.
|
||||
*/
|
||||
CXComment_VerbatimLine = 11,
|
||||
|
||||
/**
|
||||
* \brief A full comment attached to a declaration, contains block content.
|
||||
*/
|
||||
CXComment_FullComment = 12
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief The most appropriate rendering mode for an inline command, chosen on
|
||||
* command semantics in Doxygen.
|
||||
*/
|
||||
enum CXCommentInlineCommandRenderKind {
|
||||
/**
|
||||
* \brief Command argument should be rendered in a normal font.
|
||||
*/
|
||||
CXCommentInlineCommandRenderKind_Normal,
|
||||
|
||||
/**
|
||||
* \brief Command argument should be rendered in a bold font.
|
||||
*/
|
||||
CXCommentInlineCommandRenderKind_Bold,
|
||||
|
||||
/**
|
||||
* \brief Command argument should be rendered in a monospaced font.
|
||||
*/
|
||||
CXCommentInlineCommandRenderKind_Monospaced,
|
||||
|
||||
/**
|
||||
* \brief Command argument should be rendered emphasized (typically italic
|
||||
* font).
|
||||
*/
|
||||
CXCommentInlineCommandRenderKind_Emphasized
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Describes parameter passing direction for \\param or \\arg command.
|
||||
*/
|
||||
enum CXCommentParamPassDirection {
|
||||
/**
|
||||
* \brief The parameter is an input parameter.
|
||||
*/
|
||||
CXCommentParamPassDirection_In,
|
||||
|
||||
/**
|
||||
* \brief The parameter is an output parameter.
|
||||
*/
|
||||
CXCommentParamPassDirection_Out,
|
||||
|
||||
/**
|
||||
* \brief The parameter is an input and output parameter.
|
||||
*/
|
||||
CXCommentParamPassDirection_InOut
|
||||
};
|
||||
|
||||
/**
|
||||
* \param Comment AST node of any kind.
|
||||
*
|
||||
* \returns the type of the AST node.
|
||||
*/
|
||||
CINDEX_LINKAGE enum CXCommentKind clang_Comment_getKind(CXComment Comment);
|
||||
|
||||
/**
|
||||
* \param Comment AST node of any kind.
|
||||
*
|
||||
* \returns number of children of the AST node.
|
||||
*/
|
||||
CINDEX_LINKAGE unsigned clang_Comment_getNumChildren(CXComment Comment);
|
||||
|
||||
/**
|
||||
* \param Comment AST node of any kind.
|
||||
*
|
||||
* \param ChildIdx child index (zero-based).
|
||||
*
|
||||
* \returns the specified child of the AST node.
|
||||
*/
|
||||
CINDEX_LINKAGE
|
||||
CXComment clang_Comment_getChild(CXComment Comment, unsigned ChildIdx);
|
||||
|
||||
/**
|
||||
* \brief A \c CXComment_Paragraph node is considered whitespace if it contains
|
||||
* only \c CXComment_Text nodes that are empty or whitespace.
|
||||
*
|
||||
* Other AST nodes (except \c CXComment_Paragraph and \c CXComment_Text) are
|
||||
* never considered whitespace.
|
||||
*
|
||||
* \returns non-zero if \c Comment is whitespace.
|
||||
*/
|
||||
CINDEX_LINKAGE unsigned clang_Comment_isWhitespace(CXComment Comment);
|
||||
|
||||
/**
|
||||
* \returns non-zero if \c Comment is inline content and has a newline
|
||||
* immediately following it in the comment text. Newlines between paragraphs
|
||||
* do not count.
|
||||
*/
|
||||
CINDEX_LINKAGE
|
||||
unsigned clang_InlineContentComment_hasTrailingNewline(CXComment Comment);
|
||||
|
||||
/**
|
||||
* \param Comment a \c CXComment_Text AST node.
|
||||
*
|
||||
* \returns text contained in the AST node.
|
||||
*/
|
||||
CINDEX_LINKAGE CXString clang_TextComment_getText(CXComment Comment);
|
||||
|
||||
/**
|
||||
* \param Comment a \c CXComment_InlineCommand AST node.
|
||||
*
|
||||
* \returns name of the inline command.
|
||||
*/
|
||||
CINDEX_LINKAGE
|
||||
CXString clang_InlineCommandComment_getCommandName(CXComment Comment);
|
||||
|
||||
/**
|
||||
* \param Comment a \c CXComment_InlineCommand AST node.
|
||||
*
|
||||
* \returns the most appropriate rendering mode, chosen on command
|
||||
* semantics in Doxygen.
|
||||
*/
|
||||
CINDEX_LINKAGE enum CXCommentInlineCommandRenderKind
|
||||
clang_InlineCommandComment_getRenderKind(CXComment Comment);
|
||||
|
||||
/**
|
||||
* \param Comment a \c CXComment_InlineCommand AST node.
|
||||
*
|
||||
* \returns number of command arguments.
|
||||
*/
|
||||
CINDEX_LINKAGE
|
||||
unsigned clang_InlineCommandComment_getNumArgs(CXComment Comment);
|
||||
|
||||
/**
|
||||
* \param Comment a \c CXComment_InlineCommand AST node.
|
||||
*
|
||||
* \param ArgIdx argument index (zero-based).
|
||||
*
|
||||
* \returns text of the specified argument.
|
||||
*/
|
||||
CINDEX_LINKAGE
|
||||
CXString clang_InlineCommandComment_getArgText(CXComment Comment,
|
||||
unsigned ArgIdx);
|
||||
|
||||
/**
|
||||
* \param Comment a \c CXComment_HTMLStartTag or \c CXComment_HTMLEndTag AST
|
||||
* node.
|
||||
*
|
||||
* \returns HTML tag name.
|
||||
*/
|
||||
CINDEX_LINKAGE CXString clang_HTMLTagComment_getTagName(CXComment Comment);
|
||||
|
||||
/**
|
||||
* \param Comment a \c CXComment_HTMLStartTag AST node.
|
||||
*
|
||||
* \returns non-zero if tag is self-closing (for example, <br />).
|
||||
*/
|
||||
CINDEX_LINKAGE
|
||||
unsigned clang_HTMLStartTagComment_isSelfClosing(CXComment Comment);
|
||||
|
||||
/**
|
||||
* \param Comment a \c CXComment_HTMLStartTag AST node.
|
||||
*
|
||||
* \returns number of attributes (name-value pairs) attached to the start tag.
|
||||
*/
|
||||
CINDEX_LINKAGE unsigned clang_HTMLStartTag_getNumAttrs(CXComment Comment);
|
||||
|
||||
/**
|
||||
* \param Comment a \c CXComment_HTMLStartTag AST node.
|
||||
*
|
||||
* \param AttrIdx attribute index (zero-based).
|
||||
*
|
||||
* \returns name of the specified attribute.
|
||||
*/
|
||||
CINDEX_LINKAGE
|
||||
CXString clang_HTMLStartTag_getAttrName(CXComment Comment, unsigned AttrIdx);
|
||||
|
||||
/**
|
||||
* \param Comment a \c CXComment_HTMLStartTag AST node.
|
||||
*
|
||||
* \param AttrIdx attribute index (zero-based).
|
||||
*
|
||||
* \returns value of the specified attribute.
|
||||
*/
|
||||
CINDEX_LINKAGE
|
||||
CXString clang_HTMLStartTag_getAttrValue(CXComment Comment, unsigned AttrIdx);
|
||||
|
||||
/**
|
||||
* \param Comment a \c CXComment_BlockCommand AST node.
|
||||
*
|
||||
* \returns name of the block command.
|
||||
*/
|
||||
CINDEX_LINKAGE
|
||||
CXString clang_BlockCommandComment_getCommandName(CXComment Comment);
|
||||
|
||||
/**
|
||||
* \param Comment a \c CXComment_BlockCommand AST node.
|
||||
*
|
||||
* \returns number of word-like arguments.
|
||||
*/
|
||||
CINDEX_LINKAGE
|
||||
unsigned clang_BlockCommandComment_getNumArgs(CXComment Comment);
|
||||
|
||||
/**
|
||||
* \param Comment a \c CXComment_BlockCommand AST node.
|
||||
*
|
||||
* \param ArgIdx argument index (zero-based).
|
||||
*
|
||||
* \returns text of the specified word-like argument.
|
||||
*/
|
||||
CINDEX_LINKAGE
|
||||
CXString clang_BlockCommandComment_getArgText(CXComment Comment,
|
||||
unsigned ArgIdx);
|
||||
|
||||
/**
|
||||
* \param Comment a \c CXComment_BlockCommand or
|
||||
* \c CXComment_VerbatimBlockCommand AST node.
|
||||
*
|
||||
* \returns paragraph argument of the block command.
|
||||
*/
|
||||
CINDEX_LINKAGE
|
||||
CXComment clang_BlockCommandComment_getParagraph(CXComment Comment);
|
||||
|
||||
/**
|
||||
* \param Comment a \c CXComment_ParamCommand AST node.
|
||||
*
|
||||
* \returns parameter name.
|
||||
*/
|
||||
CINDEX_LINKAGE
|
||||
CXString clang_ParamCommandComment_getParamName(CXComment Comment);
|
||||
|
||||
/**
|
||||
* \param Comment a \c CXComment_ParamCommand AST node.
|
||||
*
|
||||
* \returns non-zero if the parameter that this AST node represents was found
|
||||
* in the function prototype and \c clang_ParamCommandComment_getParamIndex
|
||||
* function will return a meaningful value.
|
||||
*/
|
||||
CINDEX_LINKAGE
|
||||
unsigned clang_ParamCommandComment_isParamIndexValid(CXComment Comment);
|
||||
|
||||
/**
|
||||
* \param Comment a \c CXComment_ParamCommand AST node.
|
||||
*
|
||||
* \returns zero-based parameter index in function prototype.
|
||||
*/
|
||||
CINDEX_LINKAGE
|
||||
unsigned clang_ParamCommandComment_getParamIndex(CXComment Comment);
|
||||
|
||||
/**
|
||||
* \param Comment a \c CXComment_ParamCommand AST node.
|
||||
*
|
||||
* \returns non-zero if parameter passing direction was specified explicitly in
|
||||
* the comment.
|
||||
*/
|
||||
CINDEX_LINKAGE
|
||||
unsigned clang_ParamCommandComment_isDirectionExplicit(CXComment Comment);
|
||||
|
||||
/**
|
||||
* \param Comment a \c CXComment_ParamCommand AST node.
|
||||
*
|
||||
* \returns parameter passing direction.
|
||||
*/
|
||||
CINDEX_LINKAGE
|
||||
enum CXCommentParamPassDirection clang_ParamCommandComment_getDirection(
|
||||
CXComment Comment);
|
||||
|
||||
/**
|
||||
* \param Comment a \c CXComment_TParamCommand AST node.
|
||||
*
|
||||
* \returns template parameter name.
|
||||
*/
|
||||
CINDEX_LINKAGE
|
||||
CXString clang_TParamCommandComment_getParamName(CXComment Comment);
|
||||
|
||||
/**
|
||||
* \param Comment a \c CXComment_TParamCommand AST node.
|
||||
*
|
||||
* \returns non-zero if the parameter that this AST node represents was found
|
||||
* in the template parameter list and
|
||||
* \c clang_TParamCommandComment_getDepth and
|
||||
* \c clang_TParamCommandComment_getIndex functions will return a meaningful
|
||||
* value.
|
||||
*/
|
||||
CINDEX_LINKAGE
|
||||
unsigned clang_TParamCommandComment_isParamPositionValid(CXComment Comment);
|
||||
|
||||
/**
|
||||
* \param Comment a \c CXComment_TParamCommand AST node.
|
||||
*
|
||||
* \returns zero-based nesting depth of this parameter in the template parameter list.
|
||||
*
|
||||
* For example,
|
||||
* \verbatim
|
||||
* template<typename C, template<typename T> class TT>
|
||||
* void test(TT<int> aaa);
|
||||
* \endverbatim
|
||||
* for C and TT nesting depth is 0,
|
||||
* for T nesting depth is 1.
|
||||
*/
|
||||
CINDEX_LINKAGE
|
||||
unsigned clang_TParamCommandComment_getDepth(CXComment Comment);
|
||||
|
||||
/**
|
||||
* \param Comment a \c CXComment_TParamCommand AST node.
|
||||
*
|
||||
* \returns zero-based parameter index in the template parameter list at a
|
||||
* given nesting depth.
|
||||
*
|
||||
* For example,
|
||||
* \verbatim
|
||||
* template<typename C, template<typename T> class TT>
|
||||
* void test(TT<int> aaa);
|
||||
* \endverbatim
|
||||
* for C and TT nesting depth is 0, so we can ask for index at depth 0:
|
||||
* at depth 0 C's index is 0, TT's index is 1.
|
||||
*
|
||||
* For T nesting depth is 1, so we can ask for index at depth 0 and 1:
|
||||
* at depth 0 T's index is 1 (same as TT's),
|
||||
* at depth 1 T's index is 0.
|
||||
*/
|
||||
CINDEX_LINKAGE
|
||||
unsigned clang_TParamCommandComment_getIndex(CXComment Comment, unsigned Depth);
|
||||
|
||||
/**
|
||||
* \param Comment a \c CXComment_VerbatimBlockLine AST node.
|
||||
*
|
||||
* \returns text contained in the AST node.
|
||||
*/
|
||||
CINDEX_LINKAGE
|
||||
CXString clang_VerbatimBlockLineComment_getText(CXComment Comment);
|
||||
|
||||
/**
|
||||
* \param Comment a \c CXComment_VerbatimLine AST node.
|
||||
*
|
||||
* \returns text contained in the AST node.
|
||||
*/
|
||||
CINDEX_LINKAGE CXString clang_VerbatimLineComment_getText(CXComment Comment);
|
||||
|
||||
/**
|
||||
* \brief Convert an HTML tag AST node to string.
|
||||
*
|
||||
* \param Comment a \c CXComment_HTMLStartTag or \c CXComment_HTMLEndTag AST
|
||||
* node.
|
||||
*
|
||||
* \returns string containing an HTML tag.
|
||||
*/
|
||||
CINDEX_LINKAGE CXString clang_HTMLTagComment_getAsString(CXComment Comment);
|
||||
|
||||
/**
|
||||
* \brief Convert a given full parsed comment to an HTML fragment.
|
||||
*
|
||||
* Specific details of HTML layout are subject to change. Don't try to parse
|
||||
* this HTML back into an AST, use other APIs instead.
|
||||
*
|
||||
* Currently the following CSS classes are used:
|
||||
* \li "para-brief" for \\brief paragraph and equivalent commands;
|
||||
* \li "para-returns" for \\returns paragraph and equivalent commands;
|
||||
* \li "word-returns" for the "Returns" word in \\returns paragraph.
|
||||
*
|
||||
* Function argument documentation is rendered as a \<dl\> list with arguments
|
||||
* sorted in function prototype order. CSS classes used:
|
||||
* \li "param-name-index-NUMBER" for parameter name (\<dt\>);
|
||||
* \li "param-descr-index-NUMBER" for parameter description (\<dd\>);
|
||||
* \li "param-name-index-invalid" and "param-descr-index-invalid" are used if
|
||||
* parameter index is invalid.
|
||||
*
|
||||
* Template parameter documentation is rendered as a \<dl\> list with
|
||||
* parameters sorted in template parameter list order. CSS classes used:
|
||||
* \li "tparam-name-index-NUMBER" for parameter name (\<dt\>);
|
||||
* \li "tparam-descr-index-NUMBER" for parameter description (\<dd\>);
|
||||
* \li "tparam-name-index-other" and "tparam-descr-index-other" are used for
|
||||
* names inside template template parameters;
|
||||
* \li "tparam-name-index-invalid" and "tparam-descr-index-invalid" are used if
|
||||
* parameter position is invalid.
|
||||
*
|
||||
* \param Comment a \c CXComment_FullComment AST node.
|
||||
*
|
||||
* \returns string containing an HTML fragment.
|
||||
*/
|
||||
CINDEX_LINKAGE CXString clang_FullComment_getAsHTML(CXComment Comment);
|
||||
|
||||
/**
|
||||
* \brief Convert a given full parsed comment to an XML document.
|
||||
*
|
||||
* A Relax NG schema for the XML can be found in comment-xml-schema.rng file
|
||||
* inside clang source tree.
|
||||
*
|
||||
* \param Comment a \c CXComment_FullComment AST node.
|
||||
*
|
||||
* \returns string containing an XML document.
|
||||
*/
|
||||
CINDEX_LINKAGE CXString clang_FullComment_getAsXML(CXComment Comment);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CLANG_C_DOCUMENTATION_H */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,38 +0,0 @@
|
||||
CLANG_LEVEL := ../..
|
||||
DIRS :=
|
||||
|
||||
include $(CLANG_LEVEL)/Makefile
|
||||
|
||||
IntIncludeDir = $(DESTDIR)$(PROJ_internal_prefix)/include
|
||||
|
||||
install-local::
|
||||
$(Echo) Installing Clang C API include files
|
||||
$(Verb) $(MKDIR) $(IntIncludeDir)
|
||||
$(Verb) if test -d "$(PROJ_SRC_DIR)" ; then \
|
||||
cd $(PROJ_SRC_DIR)/.. && \
|
||||
for hdr in `find clang-c -type f '!' '(' -name '*~' \
|
||||
-o -name '.#*' -o -name '*.in' -o -name '*.txt' \
|
||||
-o -name 'Makefile' -o -name '*.td' ')' -print \
|
||||
| grep -v CVS | grep -v .svn | grep -v .dir` ; do \
|
||||
instdir=`dirname "$(IntIncludeDir)/$$hdr"` ; \
|
||||
if test \! -d "$$instdir" ; then \
|
||||
$(EchoCmd) Making install directory $$instdir ; \
|
||||
$(MKDIR) $$instdir ;\
|
||||
fi ; \
|
||||
$(DataInstall) $$hdr $(IntIncludeDir)/$$hdr ; \
|
||||
done ; \
|
||||
fi
|
||||
ifneq ($(PROJ_SRC_ROOT),$(PROJ_OBJ_ROOT))
|
||||
$(Verb) if test -d "$(PROJ_OBJ_ROOT)/tools/clang/include/clang-c" ; then \
|
||||
cd $(PROJ_OBJ_ROOT)/tools/clang/include && \
|
||||
for hdr in `find clang-c -type f '!' '(' -name 'Makefile' ')' -print \
|
||||
| grep -v CVS | grep -v .tmp | grep -v .dir` ; do \
|
||||
instdir=`dirname "$(IntIncludeDir)/$$hdr"` ; \
|
||||
if test \! -d "$$instdir" ; then \
|
||||
$(EchoCmd) Making install directory $$instdir ; \
|
||||
$(MKDIR) $$instdir ;\
|
||||
fi ; \
|
||||
$(DataInstall) $$hdr $(IntIncludeDir)/$$hdr ; \
|
||||
done ; \
|
||||
fi
|
||||
endif
|
@ -1,45 +0,0 @@
|
||||
/*===-- clang-c/Platform.h - C Index platform decls -------------*- C -*-===*\
|
||||
|* *|
|
||||
|* The LLVM Compiler Infrastructure *|
|
||||
|* *|
|
||||
|* This file is distributed under the University of Illinois Open Source *|
|
||||
|* License. See LICENSE.TXT for details. *|
|
||||
|* *|
|
||||
|*===----------------------------------------------------------------------===*|
|
||||
|* *|
|
||||
|* This header provides platform specific macros (dllimport, deprecated, ...) *|
|
||||
|* *|
|
||||
\*===----------------------------------------------------------------------===*/
|
||||
|
||||
#ifndef LLVM_CLANG_C_PLATFORM_H
|
||||
#define LLVM_CLANG_C_PLATFORM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* MSVC DLL import/export. */
|
||||
#ifdef _MSC_VER
|
||||
#ifdef _CINDEX_LIB_
|
||||
#define CINDEX_LINKAGE __declspec(dllexport)
|
||||
#else
|
||||
#define CINDEX_LINKAGE __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define CINDEX_LINKAGE
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define CINDEX_DEPRECATED __attribute__((deprecated))
|
||||
#else
|
||||
#ifdef _MSC_VER
|
||||
#define CINDEX_DEPRECATED __declspec(deprecated)
|
||||
#else
|
||||
#define CINDEX_DEPRECATED
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
@ -1,4 +0,0 @@
|
||||
module Clang_C {
|
||||
umbrella "."
|
||||
module * { export * }
|
||||
}
|
@ -1,176 +0,0 @@
|
||||
/* -*- mode: c++ ; coding: utf-8-unix -*- */
|
||||
/* last updated : 2015/05/25.01:59:31 */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013-2015 yaruopooner [https://github.com/yaruopooner]
|
||||
*
|
||||
* This file is part of ac-clang.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*================================================================================================*/
|
||||
/* Include Files */
|
||||
/*================================================================================================*/
|
||||
|
||||
|
||||
#include "CommandLine.hpp"
|
||||
#include "ClangServer.hpp"
|
||||
|
||||
|
||||
|
||||
/*================================================================================================*/
|
||||
/* Global Function Definitions Section */
|
||||
/*================================================================================================*/
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
kStreamBuffer_UnitSize = 1 * 1024 * 1024,
|
||||
kStreamBuffer_MinMB = 1,
|
||||
kStreamBuffer_MaxMB = 5,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
kOption_Help,
|
||||
kOption_Version,
|
||||
kOption_LogFile,
|
||||
kOption_STDIN_BufferSize,
|
||||
kOption_STDOUT_BufferSize,
|
||||
};
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
std::string GetClangVersion( void )
|
||||
{
|
||||
CXString version_text = clang_getClangVersion();
|
||||
const std::string clang_version = clang_getCString( version_text );
|
||||
|
||||
clang_disposeString( version_text );
|
||||
|
||||
return clang_version;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
std::ios_base::sync_with_stdio( false );
|
||||
|
||||
// parse options
|
||||
const std::string server_version = CLANG_SERVER_VERSION;
|
||||
const std::string clang_version = ::GetClangVersion();
|
||||
const std::string generate = CMAKE_GENERATOR "/" CMAKE_HOST_SYSTEM_PROCESSOR;
|
||||
std::string logfile;
|
||||
size_t stdin_buffer_size = kStreamBuffer_MinMB;
|
||||
size_t stdout_buffer_size = kStreamBuffer_MinMB;
|
||||
|
||||
{
|
||||
CommandLine::Parser declare_options;
|
||||
|
||||
declare_options.AddOption( kOption_Help, "help", "h", "Display available options.",
|
||||
CommandLine::IOptionDetail::kFlag_Once );
|
||||
declare_options.AddOption( kOption_Version, "version", "v", "Display current version.",
|
||||
CommandLine::IOptionDetail::kFlag_Once );
|
||||
// declare_options.AddOption< std::string >( kOption_LogFile, "logfile", "l", "Enable IPC records output.(for debug)",
|
||||
// ( CommandLine::IOptionDetail::kFlag_Once | CommandLine::IOptionDetail::kFlag_HasValue ), "file path" );
|
||||
declare_options.AddOption< uint32_t >( kOption_STDIN_BufferSize, "stdin-buffer-size", "sibs", "STDIN buffer size. <size> is 1 - 5 MB",
|
||||
( CommandLine::IOptionDetail::kFlag_Once | CommandLine::IOptionDetail::kFlag_HasValue ), "size",
|
||||
CommandLine::RangeReader< uint32_t >( kStreamBuffer_MinMB, kStreamBuffer_MaxMB ) );
|
||||
declare_options.AddOption< uint32_t >( kOption_STDOUT_BufferSize, "stdout-buffer-size", "sobs", "STDOUT buffer size. <size> is 1 - 5 MB",
|
||||
( CommandLine::IOptionDetail::kFlag_Once | CommandLine::IOptionDetail::kFlag_HasValue ), "size",
|
||||
CommandLine::RangeReader< uint32_t >( kStreamBuffer_MinMB, kStreamBuffer_MaxMB ) );
|
||||
|
||||
if ( declare_options.Parse( argc, argv ) )
|
||||
{
|
||||
for ( const auto& option_value : declare_options.GetOptionWithValueArray() )
|
||||
{
|
||||
switch ( option_value->GetId() )
|
||||
{
|
||||
case kOption_Help:
|
||||
declare_options.PrintUsage( "clang-server [options] <values>" );
|
||||
return 0;
|
||||
case kOption_Version:
|
||||
std::cout << server_version << " (" << generate << ")" << std::endl;
|
||||
std::cout << clang_version << std::endl;
|
||||
return 0;
|
||||
case kOption_LogFile:
|
||||
if ( option_value->IsValid() )
|
||||
{
|
||||
const std::string result = declare_options.GetValue< std::string >( option_value );
|
||||
|
||||
logfile = result;
|
||||
}
|
||||
break;
|
||||
case kOption_STDIN_BufferSize:
|
||||
if ( option_value->IsValid() )
|
||||
{
|
||||
const uint32_t result = declare_options.GetValue< uint32_t >( option_value );
|
||||
|
||||
stdin_buffer_size = result;
|
||||
}
|
||||
break;
|
||||
case kOption_STDOUT_BufferSize:
|
||||
if ( option_value->IsValid() )
|
||||
{
|
||||
const uint32_t result = declare_options.GetValue< uint32_t >( option_value );
|
||||
|
||||
stdout_buffer_size = result;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
declare_options.PrintWarnings();
|
||||
}
|
||||
else
|
||||
{
|
||||
declare_options.PrintErrors();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// stream buffer expand
|
||||
// std::shared_ptr< char > stdin_buffer( new char[ kStreamBuffer_UnitSize ], std::default_delete< char[] >() );
|
||||
// std::shared_ptr< char > stdout_buffer( new char[ kStreamBuffer_UnitSize ], std::default_delete< char[] >() );
|
||||
|
||||
stdin_buffer_size *= kStreamBuffer_UnitSize;
|
||||
stdout_buffer_size *= kStreamBuffer_UnitSize;
|
||||
|
||||
|
||||
// server instance
|
||||
ClangFlagConverters flag_converter;
|
||||
ClangServer::Specification initial_spec( stdin_buffer_size, stdout_buffer_size, logfile );
|
||||
ClangServer server( initial_spec );
|
||||
|
||||
|
||||
server.ParseCommand();
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*================================================================================================*/
|
||||
/* EOF */
|
||||
/*================================================================================================*/
|
@ -1,22 +0,0 @@
|
||||
Index: lib/Support/MemoryBuffer.cpp
|
||||
===================================================================
|
||||
--- lib/Support/MemoryBuffer.cpp (revision 226551)
|
||||
+++ lib/Support/MemoryBuffer.cpp (working copy)
|
||||
@@ -267,6 +267,9 @@
|
||||
bool RequiresNullTerminator,
|
||||
int PageSize,
|
||||
bool IsVolatileSize) {
|
||||
+#if 1
|
||||
+ return false;
|
||||
+#else
|
||||
// mmap may leave the buffer without null terminator if the file size changed
|
||||
// by the time the last page is mapped in, so avoid it if the file size is
|
||||
// likely to change.
|
||||
@@ -306,6 +309,7 @@
|
||||
return false;
|
||||
|
||||
return true;
|
||||
+#endif
|
||||
}
|
||||
|
||||
static ErrorOr<std::unique_ptr<MemoryBuffer>>
|
@ -1,29 +0,0 @@
|
||||
Index: tools/libclang/CMakeLists.txt
|
||||
===================================================================
|
||||
--- tools/libclang/CMakeLists.txt (revision 226551)
|
||||
+++ tools/libclang/CMakeLists.txt (working copy)
|
||||
@@ -72,9 +72,9 @@
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
- set(output_name "libclang")
|
||||
+ set(output_name "libclang-x86_64")
|
||||
else()
|
||||
- set(output_name "clang")
|
||||
+ set(output_name "clang-x86_64")
|
||||
endif()
|
||||
|
||||
add_clang_library(libclang ${ENABLE_SHARED} ${ENABLE_STATIC}
|
||||
Index: tools/libclang/Makefile
|
||||
===================================================================
|
||||
--- tools/libclang/Makefile (revision 226551)
|
||||
+++ tools/libclang/Makefile (working copy)
|
||||
@@ -8,7 +8,7 @@
|
||||
##===----------------------------------------------------------------------===##
|
||||
|
||||
CLANG_LEVEL := ../..
|
||||
-LIBRARYNAME = clang
|
||||
+LIBRARYNAME = clang-x86_64
|
||||
|
||||
EXPORTED_SYMBOL_FILE = $(PROJ_SRC_DIR)/libclang.exports
|
||||
|
@ -1,381 +0,0 @@
|
||||
<div id="table-of-contents">
|
||||
<h2>Table of Contents</h2>
|
||||
<div id="text-table-of-contents">
|
||||
<ul>
|
||||
<li><a href="#sec-1">1. このドキュメントについて</a></li>
|
||||
<li><a href="#sec-2">2. セルフビルド手順</a>
|
||||
<ul>
|
||||
<li><a href="#sec-2-1">2.1. LLVMセルフビルド</a></li>
|
||||
<li><a href="#sec-2-2">2.2. clang-serverセルフビルド</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#sec-3">3. セルフビルドに必要なソフトウェア</a>
|
||||
<ul>
|
||||
<li><a href="#sec-3-1">3.1. Windows</a>
|
||||
<ul>
|
||||
<li><a href="#sec-3-1-1">3.1.1. LLVM</a></li>
|
||||
<li><a href="#sec-3-1-2">3.1.2. Visual Studio 2015/2013/2012/2010</a></li>
|
||||
<li><a href="#sec-3-1-3">3.1.3. CMake</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#sec-3-2">3.2. Linux</a>
|
||||
<ul>
|
||||
<li><a href="#sec-3-2-1">3.2.1. LLVM</a></li>
|
||||
<li><a href="#sec-3-2-2">3.2.2. CMake</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#sec-4">4. セルフビルド</a>
|
||||
<ul>
|
||||
<li><a href="#sec-4-1">4.1. Windows</a>
|
||||
<ul>
|
||||
<li><a href="#sec-4-1-1">4.1.1. LLVM</a></li>
|
||||
<li><a href="#sec-4-1-2">4.1.2. clang-server</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#sec-4-2">4.2. Linux</a>
|
||||
<ul>
|
||||
<li><a href="#sec-4-2-1">4.2.1. LLVM</a></li>
|
||||
<li><a href="#sec-4-2-2">4.2.2. clang-server</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#sec-5">5. パッチ適用済みバイナリ(Windows Only)</a></li>
|
||||
<li><a href="#sec-6">6. パッチを適用せずLLVMオフィシャルのlibclangを使用する場合の制限事項</a>
|
||||
<ul>
|
||||
<li><a href="#sec-6-1">6.1. 特定ファイルがロックされセーブできなくなる</a>
|
||||
<ul>
|
||||
<li><a href="#sec-6-1-1">6.1.1. emacs側での対処方法</a></li>
|
||||
<li><a href="#sec-6-1-2">6.1.2. 原因(実装上の問題説明、解決案求む)</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#sec-6-2">6.2. その他</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#sec-7">7. パッチ解説</a>
|
||||
<ul>
|
||||
<li><a href="#sec-7-1">7.1. パッチ</a></li>
|
||||
<li><a href="#sec-7-2">7.2. パッチ(invalidate-mmap.patch)で行っている事</a></li>
|
||||
<li><a href="#sec-7-3">7.3. LLVM3.5の追加仕様</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
[English Manual](./readme.md)
|
||||
|
||||
# このドキュメントについて<a id="sec-1" name="sec-1"></a>
|
||||
|
||||
clang-serverのセルフビルドについて説明します。
|
||||
※Windows環境で付属の実行ファイルを利用する場合は読まなくても問題ありません。
|
||||
|
||||
# セルフビルド手順<a id="sec-2" name="sec-2"></a>
|
||||
|
||||
clang-serverのビルドにはLLVMのlibclangが必要になります。
|
||||
ですのでLLVM libclangをセルフビルドしてからclang-serverをセルフビルドします。
|
||||
|
||||
## LLVMセルフビルド<a id="sec-2-1" name="sec-2-1"></a>
|
||||
|
||||
以下の4つを行います。
|
||||
この作業を簡略化するスクリプトもあります。
|
||||
- LLVMのチェックアウト
|
||||
- パッチの適用
|
||||
- CMake or configureによるプロジェクトファイル生成
|
||||
- ビルド
|
||||
|
||||
## clang-serverセルフビルド<a id="sec-2-2" name="sec-2-2"></a>
|
||||
|
||||
LLVMセルフビルドで生成したパッチ適用済みのライブラリ libclang を使用します。
|
||||
- CMakeによるプロジェクトファイル生成
|
||||
- ビルド
|
||||
- インストール
|
||||
|
||||
# セルフビルドに必要なソフトウェア<a id="sec-3" name="sec-3"></a>
|
||||
|
||||
## Windows<a id="sec-3-1" name="sec-3-1"></a>
|
||||
|
||||
以下が必要になります。
|
||||
|
||||
### LLVM<a id="sec-3-1-1" name="sec-3-1-1"></a>
|
||||
|
||||
ビルド済みライブラリ
|
||||
libclang.lib or libclang.imp
|
||||
libclang.dll
|
||||
が必要です。
|
||||
|
||||
### Visual Studio 2015/2013/2012/2010<a id="sec-3-1-2" name="sec-3-1-2"></a>
|
||||
|
||||
どれでもOK
|
||||
|
||||
### CMake<a id="sec-3-1-3" name="sec-3-1-3"></a>
|
||||
|
||||
<http://www.cmake.org/>
|
||||
|
||||
Windows ZIPをダウンロードして何処かへ展開。
|
||||
Visual Studio ソリューション&プロジェクトファイル生成と、ビルド&インストールのmsbuild呼び出しで使用されます。
|
||||
|
||||
## Linux<a id="sec-3-2" name="sec-3-2"></a>
|
||||
|
||||
以下が必要になります。
|
||||
|
||||
### LLVM<a id="sec-3-2-1" name="sec-3-2-1"></a>
|
||||
|
||||
ビルド済みライブラリ
|
||||
libclang.so
|
||||
が必要です。
|
||||
|
||||
### CMake<a id="sec-3-2-2" name="sec-3-2-2"></a>
|
||||
|
||||
$ sudo apt-get install cmake
|
||||
|
||||
最新版の場合は↓からダウンロード
|
||||
|
||||
<http://www.cmake.org/>
|
||||
|
||||
cmake-3.1.3.tar.gzをダウンロードし解凍、ビルド、インストールを行う。
|
||||
|
||||
$ tar -xf cmake-3.1.3.tar.gz .
|
||||
$ cd cmake-3.1.3
|
||||
$ ./configure && make
|
||||
$ make install
|
||||
|
||||
# セルフビルド<a id="sec-4" name="sec-4"></a>
|
||||
|
||||
## Windows<a id="sec-4-1" name="sec-4-1"></a>
|
||||
|
||||
### LLVM<a id="sec-4-1-1" name="sec-4-1-1"></a>
|
||||
|
||||
LLVMのセルフビルドが必要になります。
|
||||
またセルフビルド時にパッチを適用する必要があります。
|
||||
セルフビルド後のパッケージはインストールする必要はありません。
|
||||
ビルド後に生成されたバイナリを指すパスを
|
||||
CMakeによるプロジェクト生成時に設定すればビルド可能です。
|
||||
LLVMがインストール済みであればインストールされているディレクトリを指定します。
|
||||
|
||||
LLVMセルフビルドを行う場合は
|
||||
自前でチェックアウトし、CMakeでLLVMソリューションファイルを生成するか、以下のshell scriptを使用してください。
|
||||
<https://github.com/yaruopooner/llvm-build-shells>
|
||||
|
||||
1. スクリプトでLLVMパッチを適用する方法
|
||||
|
||||
builderShell の引数に -tasks を指定し、-tasks パラメーターに PATCH を追加、
|
||||
パッチを適用するパスとパッチファイルを記述したテーブルを -patchInfos パラメーターとして与えます。
|
||||
詳しくはllvm-build-shellsのsample.ps1を参考にしてください。
|
||||
|
||||
2. LLVMパッチの内容
|
||||
|
||||
mmapの使用が常時無効化されます。
|
||||
|
||||
### clang-server<a id="sec-4-1-2" name="sec-4-1-2"></a>
|
||||
|
||||
ac-clang/build/builder\_sample.bat
|
||||
を使用します。
|
||||
必要に応じてbuilder\_sample.batを編集してください。
|
||||
コマンドラインかエクスプローラーから実行します。
|
||||
|
||||
- example
|
||||
|
||||
cmake -G "Visual Studio 12 2013 Win64" ../clang-server -DLIBRARY_PATHS="c:/cygwin-x86_64/tmp/llvm-build-shells/ps1/clang-360/build/msvc-64/" -DCMAKE_INSTALL_PREFIX="c:/cygwin-x86_64/usr/local/bin/"
|
||||
|
||||
- オプション解説
|
||||
- `-DLIBRARY_PATHS`
|
||||
セルフビルドしたLLVMが配置されているディレクトリを指定します。
|
||||
LLVMのトップディレクトリである必要があります。
|
||||
省略した場合は ac-clang/clang-server が使われます。
|
||||
- `-DCMAKE_INSTALL_PREFIX`
|
||||
clang-serverのインストールパスを指定します。
|
||||
省略した場合は
|
||||
`C:/Program Files/clang-server`
|
||||
になります。
|
||||
|
||||
## Linux<a id="sec-4-2" name="sec-4-2"></a>
|
||||
|
||||
### LLVM<a id="sec-4-2-1" name="sec-4-2-1"></a>
|
||||
|
||||
LLVMのセルフビルドが必要になります。
|
||||
またセルフビルド時にパッチを適用する必要があります。
|
||||
セルフビルド後のパッケージはインストールする必要はありません。
|
||||
ビルド後に生成されたバイナリを指すパスを
|
||||
CMakeによるプロジェクト生成時に設定すればビルド可能です。
|
||||
LLVMがインストール済みであればインストールされているディレクトリを指定します。
|
||||
|
||||
LLVMセルフビルドを行う場合は
|
||||
自前でチェックアウトし、CMakeでLLVMソリューションファイルを生成するか、以下のshell scriptを使用してください。
|
||||
<https://github.com/yaruopooner/llvm-build-shells>
|
||||
|
||||
1. スクリプトでLLVMパッチを適用する方法
|
||||
|
||||
executeBuilder の引数に -patch を追加し、
|
||||
パッチを適用するパスを-patchApplyLocation、
|
||||
パッチファイルを-patchPathに記述して引数として与えます。
|
||||
-patchApplyLocation,-patchPathはペアになっており、複数回指定可能です。
|
||||
詳しくはllvm-build-shellsのsample.shを参考にしてください。
|
||||
|
||||
2. LLVMパッチの内容
|
||||
|
||||
mmapの使用が常時無効化されます。
|
||||
|
||||
### clang-server<a id="sec-4-2-2" name="sec-4-2-2"></a>
|
||||
|
||||
ac-clang/build/builder\_sample.sh
|
||||
を使用します。
|
||||
必要に応じてbuilder\_sample.shを編集してください。
|
||||
builder\_sample.shを実行します。
|
||||
|
||||
- example
|
||||
|
||||
cmake -G "Unix Makefiles" ../clang-server -DLIBRARY_PATHS="/home/yaruopooner/work/llvm-build-shells/sh/clang-350/build" -DCMAKE_INSTALL_PREFIX="~/work/clang-server"
|
||||
|
||||
- オプション解説
|
||||
- `-DLIBRARY_PATHS`
|
||||
セルフビルドしたLLVMが配置されているディレクトリを指定します。
|
||||
LLVMのトップディレクトリである必要があります。
|
||||
省略した場合は ac-clang/clang-server が使われます。
|
||||
- `-DCMAKE_INSTALL_PREFIX`
|
||||
clang-serverのインストールパスを指定します。
|
||||
省略した場合は
|
||||
`/usr/local/bin`
|
||||
になります。
|
||||
|
||||
# パッチ適用済みバイナリ(Windows Only)<a id="sec-5" name="sec-5"></a>
|
||||
|
||||
<https://github.com/yaruopooner/ac-clang/releases>
|
||||
|
||||
上記に置いてあるclang-server-X.X.X.zipは
|
||||
パッチ適用済みのバイナリとライブラリファイル
|
||||
- clang-server.exe
|
||||
- libclang.dll
|
||||
- libclang.lib or libclang.imp
|
||||
|
||||
の3ファイルが格納されています。
|
||||
|
||||
LLVMはセルフビルドせずにclang-serverのみをセルフビルドする場合は
|
||||
clang-server-X.X.X.zipをac-clangに解凍します。
|
||||
すると以下のように配置されます。
|
||||
ac-clang/clang-server/binary/clang-server.exe
|
||||
ac-clang/clang-server/library/x86\_64/release/libclang.dll
|
||||
ac-clang/clang-server/library/x86\_64/release/libclang.lib
|
||||
|
||||
# パッチを適用せずLLVMオフィシャルのlibclangを使用する場合の制限事項<a id="sec-6" name="sec-6"></a>
|
||||
|
||||
## 特定ファイルがロックされセーブできなくなる<a id="sec-6-1" name="sec-6-1"></a>
|
||||
|
||||
編集したヘッダファイルをセーブしようとすると "basic-save-buffer-2: Opening output file: invalid argument \`HEADER-FILE-NAME\`" となりセーブできない。
|
||||
必ず発生するわけではなく特定の条件を満たしたファイルサイズが16kBを越えるヘッダファイルで発生する。
|
||||
16kB以下のヘッダファイルではまったく発生しない。
|
||||
libclang の TranslationUnit(以下TU) の問題。
|
||||
libclang の TU がinclude対象のファイルをロックしている。
|
||||
ac-clang側で暫定対処パッチを施してあるので多少は緩和されているが完全に回避はできない。
|
||||
発生した場合はマニュアル対処する以外ない。
|
||||
|
||||
### emacs側での対処方法<a id="sec-6-1-1" name="sec-6-1-1"></a>
|
||||
|
||||
include対象なので大抵は foo.cpp/foo.hpp という構成だとおもわれます。
|
||||
foo.hpp(modified)がセーブできない場合、大抵foo.cppが(modified)になっているのでfoo.cppをセーブしましょう。
|
||||
これによりfoo.hppはセーブ可能になるはずです。
|
||||
これでもセーブできない場合は、foo.cpp以外のソースでfoo.hppをインクルードしており(modified)になっているバッファがあるはずなので
|
||||
それもセーブしましょう。
|
||||
また、定義へのジャンプ機能で該当ソースがアクティブ化されている場合は、未編集バッファであってもアクティブ化されています。
|
||||
該当バッファを削除してみるか、そのバッファへスイッチして (ac-clang-deactivate) を実行してください。
|
||||
これ以外でも16kBを越えるヘッダを編集しようとした際に、そのファイルのcppはオープンしてもいないのにセーブできない場合、
|
||||
該当ヘッダファイルを何処か遠いモジュールでインクルードしている場合なども同様の症状になります。
|
||||
ライブラリモジュールやフレームワークなどを開発している場合は発生しやすいかもしれません。
|
||||
※ライブラリ・フレームワークはアプリ側からよくincludeされるため。
|
||||
|
||||
### 原因(実装上の問題説明、解決案求む)<a id="sec-6-1-2" name="sec-6-1-2"></a>
|
||||
|
||||
foo.cpp(modified)のとき foo.cppのセッションで
|
||||
TUが foo.cpp パース後もincludeされているファイルのロックを保持しつづけている。
|
||||
この状態で foo.hpp を編集してセーブしようとするとロックでエラーになる。
|
||||
ロックを解除するには、 foo.cpp のTUをリリースする。
|
||||
なので foo.cpp セーブ時にセッションは保持した状態で TU だけをリリースして、
|
||||
foo.cpp が再び modified になったときに TU を生成するように修正。
|
||||
これにより foo.cpp セーブ後であればincludeロックでが全解除されるので foo.hpp がセーブ可能になる。
|
||||
当然 foo.cpp 以外に foo.hpp をinclude しているソースでかつ、編集中のバッファがある場合は、
|
||||
それら全てを保存しないとロックでは解除されない。
|
||||
|
||||
Windows環境において、
|
||||
このロックはI/Oのopen関数によるロックはではなくWindowsAPIのCreateFileMappingによるロックである。
|
||||
libclang FileManagerは16kB以上のファイルをメモリマップドファイルとしてアロケーションする。
|
||||
TUがリリースされるとUnmapViewOfFileによりメモリマップドファイルがリリースされるようになりファイルに対して書き込み可能になる。
|
||||
|
||||
Linux環境においても発現する不具合はWindows環境と若干異なるものの mmap/munmapによる問題は発生する。
|
||||
foo.cppのTUを保持している状態でfoo.hppにおいてclass fooのメソッドを追加・削除し保存する。
|
||||
foo.hpp更新後にfoo.cppにおいてclass fooのメソッドを補間しようとするとTUがクラッシュする。
|
||||
libclangがSTDOUTに "libclang: crash detected in code completion" を出力する。
|
||||
clang-serverのプロセスは生きており、セッションを破棄して再生成すれば補間続行は可能。
|
||||
|
||||
## その他<a id="sec-6-2" name="sec-6-2"></a>
|
||||
|
||||
上記の問題はlibclangにパッチを適用して改善している。
|
||||
|
||||
パッチを適用したリリースバイナリのlibclang-x86\_XX.(dll or so)を使用している場合は発生しない。
|
||||
パッチを適用していないLLVMセルフビルドおよび、LLVMオフィシャルバイナリを使用する場合にのみ問題が発生します。
|
||||
clang側の仕様バグなので現在LLVM bugzilla に報告済み。対応待ち中。
|
||||
<http://llvm.org/bugs/show_bug.cgi?id=20880>
|
||||
|
||||
# パッチ解説<a id="sec-7" name="sec-7"></a>
|
||||
|
||||
## パッチ<a id="sec-7-1" name="sec-7-1"></a>
|
||||
|
||||
ac-clang/clang-server/patch/invalidate-mmap.patch
|
||||
を使用。
|
||||
|
||||
cd llvm/
|
||||
svn patch ac-clang/clang-server/patch/invalidate-mmap.patch
|
||||
|
||||
## パッチ(invalidate-mmap.patch)で行っている事<a id="sec-7-2" name="sec-7-2"></a>
|
||||
|
||||
mmapを使わないようにパッチを適用している
|
||||
適用するのは以下のソース
|
||||
clang-trunk/llvm/lib/Support/MemoryBuffer.cpp
|
||||
|
||||
static error_code getOpenFileImpl(int FD, const char *Filename,
|
||||
OwningPtr<MemoryBuffer> &result,
|
||||
uint64_t FileSize, uint64_t MapSize,
|
||||
int64_t Offset, bool RequiresNullTerminator) {
|
||||
|
||||
↑の関数内で呼ばれる shouldUseMmap によりファイルに対するmmapの使用可否が判断される
|
||||
|
||||
static bool shouldUseMmap(int FD,
|
||||
size_t FileSize,
|
||||
size_t MapSize,
|
||||
off_t Offset,
|
||||
bool RequiresNullTerminator,
|
||||
int PageSize) {
|
||||
|
||||
この関数のresultが常時falseであればmmapは恒久的に使用されない。
|
||||
よってこの関数の先頭で
|
||||
|
||||
return false;
|
||||
|
||||
とすればよい。
|
||||
以降のコードは#if 0 end するなりすればよい。
|
||||
|
||||
## LLVM3.5の追加仕様<a id="sec-7-3" name="sec-7-3"></a>
|
||||
|
||||
shouldUseMmap,getOpenFileImplに引数IsVolatileSizeが追加された。
|
||||
これはshouldUseMmapまで加工なしでパスされ、
|
||||
shouldUseMmap先頭において、
|
||||
|
||||
if (IsVolatileSize)
|
||||
return false;
|
||||
|
||||
される。
|
||||
コメントがついていた
|
||||
|
||||
// mmap may leave the buffer without null terminator if the file size changed
|
||||
// by the time the last page is mapped in, so avoid it if the file size is
|
||||
// likely to change.
|
||||
|
||||
mmapはファイルサイズが最後のページがマップされたされた時点で変更された場合はnull終端せずにバッファを残すので、ファイルサイズが変更される可能性がある場合は、それを回避することができる。
|
||||
|
||||
とは言っているものの、想定されていない事態がいろいろあるようで仕様抜けの模様。
|
||||
またバッファ確保系関数の上流で IsVolatileSize が指定されていなかったりコンストラクタのデフォルト値のまま運用されている箇所が何箇所か見受けられた。
|
||||
そういった箇所を自前で修正してみたところ従来よりマシになったものの、他にも問題があるようで想定通りにmmapを制御は出来なかった。
|
||||
LLVMのファイルシステム・メモリ周りの仕様を完全に把握していないと、ここら辺の修正は厳しいのかもしれない。
|
||||
よって現時点においては上記パッチ適用が一番無難なやり方となる。
|
@ -1,297 +0,0 @@
|
||||
# -*- mode: org ; coding: utf-8-unix -*-
|
||||
# last updated : 2015/07/21.00:46:00
|
||||
|
||||
|
||||
#+TITLE: Clang Server Manual
|
||||
#+AUTHOR: yaruopooner
|
||||
#+EMAIL: [https://github.com/yaruopooner]
|
||||
#+OPTIONS: author:nil timestamp:t |:t \n:t ^:nil
|
||||
|
||||
|
||||
[[./readme.org][English Manual]]
|
||||
|
||||
* このドキュメントについて
|
||||
clang-serverのセルフビルドについて説明します。
|
||||
※Windows環境で付属の実行ファイルを利用する場合は読まなくても問題ありません。
|
||||
|
||||
* セルフビルド手順
|
||||
clang-serverのビルドにはLLVMのlibclangが必要になります。
|
||||
ですのでLLVM libclangをセルフビルドしてからclang-serverをセルフビルドします。
|
||||
|
||||
** LLVMセルフビルド
|
||||
以下の4つを行います。
|
||||
この作業を簡略化するスクリプトもあります。
|
||||
- LLVMのチェックアウト
|
||||
- パッチの適用
|
||||
- CMake or configureによるプロジェクトファイル生成
|
||||
- ビルド
|
||||
|
||||
** clang-serverセルフビルド
|
||||
LLVMセルフビルドで生成したパッチ適用済みのライブラリ libclang を使用します。
|
||||
- CMakeによるプロジェクトファイル生成
|
||||
- ビルド
|
||||
- インストール
|
||||
|
||||
* セルフビルドに必要なソフトウェア
|
||||
** Windows
|
||||
以下が必要になります。
|
||||
*** LLVM
|
||||
ビルド済みライブラリ
|
||||
libclang.lib or libclang.imp
|
||||
libclang.dll
|
||||
が必要です。
|
||||
|
||||
*** Visual Studio 2015/2013/2012/2010
|
||||
どれでもOK
|
||||
|
||||
*** CMake
|
||||
http://www.cmake.org/
|
||||
|
||||
Windows ZIPをダウンロードして何処かへ展開。
|
||||
Visual Studio ソリューション&プロジェクトファイル生成と、ビルド&インストールのmsbuild呼び出しで使用されます。
|
||||
|
||||
** Linux
|
||||
以下が必要になります。
|
||||
*** LLVM
|
||||
ビルド済みライブラリ
|
||||
libclang.so
|
||||
が必要です。
|
||||
|
||||
*** CMake
|
||||
#+begin_src shell
|
||||
$ sudo apt-get install cmake
|
||||
#+end_src
|
||||
|
||||
最新版の場合は↓からダウンロード
|
||||
|
||||
http://www.cmake.org/
|
||||
|
||||
cmake-3.1.3.tar.gzをダウンロードし解凍、ビルド、インストールを行う。
|
||||
#+begin_src shell
|
||||
$ tar -xf cmake-3.1.3.tar.gz .
|
||||
$ cd cmake-3.1.3
|
||||
$ ./configure && make
|
||||
$ make install
|
||||
#+end_src
|
||||
|
||||
* セルフビルド
|
||||
** Windows
|
||||
*** LLVM
|
||||
LLVMのセルフビルドが必要になります。
|
||||
またセルフビルド時にパッチを適用する必要があります。
|
||||
セルフビルド後のパッケージはインストールする必要はありません。
|
||||
ビルド後に生成されたバイナリを指すパスを
|
||||
CMakeによるプロジェクト生成時に設定すればビルド可能です。
|
||||
LLVMがインストール済みであればインストールされているディレクトリを指定します。
|
||||
|
||||
LLVMセルフビルドを行う場合は
|
||||
自前でチェックアウトし、CMakeでLLVMソリューションファイルを生成するか、以下のshell scriptを使用してください。
|
||||
https://github.com/yaruopooner/llvm-build-shells
|
||||
|
||||
**** スクリプトでLLVMパッチを適用する方法
|
||||
builderShell の引数に -tasks を指定し、-tasks パラメーターに PATCH を追加、
|
||||
パッチを適用するパスとパッチファイルを記述したテーブルを -patchInfos パラメーターとして与えます。
|
||||
詳しくはllvm-build-shellsのsample.ps1を参考にしてください。
|
||||
|
||||
**** LLVMパッチの内容
|
||||
mmapの使用が常時無効化されます。
|
||||
|
||||
*** clang-server
|
||||
ac-clang/build/builder_sample.bat
|
||||
を使用します。
|
||||
必要に応じてbuilder_sample.batを編集してください。
|
||||
コマンドラインかエクスプローラーから実行します。
|
||||
|
||||
- example
|
||||
#+begin_src bat
|
||||
cmake -G "Visual Studio 12 2013 Win64" ../clang-server -DLIBRARY_PATHS="c:/cygwin-x86_64/tmp/llvm-build-shells/ps1/clang-360/build/msvc-64/" -DCMAKE_INSTALL_PREFIX="c:/cygwin-x86_64/usr/local/bin/"
|
||||
#+end_src
|
||||
|
||||
- オプション解説
|
||||
- =-DLIBRARY_PATHS=
|
||||
セルフビルドしたLLVMが配置されているディレクトリを指定します。
|
||||
LLVMのトップディレクトリである必要があります。
|
||||
省略した場合は ac-clang/clang-server が使われます。
|
||||
- =-DCMAKE_INSTALL_PREFIX=
|
||||
clang-serverのインストールパスを指定します。
|
||||
省略した場合は
|
||||
=C:/Program Files/clang-server=
|
||||
になります。
|
||||
|
||||
** Linux
|
||||
*** LLVM
|
||||
LLVMのセルフビルドが必要になります。
|
||||
またセルフビルド時にパッチを適用する必要があります。
|
||||
セルフビルド後のパッケージはインストールする必要はありません。
|
||||
ビルド後に生成されたバイナリを指すパスを
|
||||
CMakeによるプロジェクト生成時に設定すればビルド可能です。
|
||||
LLVMがインストール済みであればインストールされているディレクトリを指定します。
|
||||
|
||||
LLVMセルフビルドを行う場合は
|
||||
自前でチェックアウトし、CMakeでLLVMソリューションファイルを生成するか、以下のshell scriptを使用してください。
|
||||
https://github.com/yaruopooner/llvm-build-shells
|
||||
|
||||
**** スクリプトでLLVMパッチを適用する方法
|
||||
executeBuilder の引数に -patch を追加し、
|
||||
パッチを適用するパスを-patchApplyLocation、
|
||||
パッチファイルを-patchPathに記述して引数として与えます。
|
||||
-patchApplyLocation,-patchPathはペアになっており、複数回指定可能です。
|
||||
詳しくはllvm-build-shellsのsample.shを参考にしてください。
|
||||
|
||||
**** LLVMパッチの内容
|
||||
mmapの使用が常時無効化されます。
|
||||
|
||||
*** clang-server
|
||||
ac-clang/build/builder_sample.sh
|
||||
を使用します。
|
||||
必要に応じてbuilder_sample.shを編集してください。
|
||||
builder_sample.shを実行します。
|
||||
|
||||
- example
|
||||
#+begin_src shell-script
|
||||
cmake -G "Unix Makefiles" ../clang-server -DLIBRARY_PATHS="/home/yaruopooner/work/llvm-build-shells/sh/clang-350/build" -DCMAKE_INSTALL_PREFIX="~/work/clang-server"
|
||||
#+end_src
|
||||
|
||||
- オプション解説
|
||||
- =-DLIBRARY_PATHS=
|
||||
セルフビルドしたLLVMが配置されているディレクトリを指定します。
|
||||
LLVMのトップディレクトリである必要があります。
|
||||
省略した場合は ac-clang/clang-server が使われます。
|
||||
- =-DCMAKE_INSTALL_PREFIX=
|
||||
clang-serverのインストールパスを指定します。
|
||||
省略した場合は
|
||||
=/usr/local/bin=
|
||||
になります。
|
||||
|
||||
* パッチ適用済みバイナリ(Windows Only)
|
||||
https://github.com/yaruopooner/ac-clang/releases
|
||||
|
||||
上記に置いてあるclang-server-X.X.X.zipは
|
||||
パッチ適用済みのバイナリとライブラリファイル
|
||||
- clang-server.exe
|
||||
- libclang.dll
|
||||
- libclang.lib or libclang.imp
|
||||
の3ファイルが格納されています。
|
||||
|
||||
LLVMはセルフビルドせずにclang-serverのみをセルフビルドする場合は
|
||||
clang-server-X.X.X.zipをac-clangに解凍します。
|
||||
すると以下のように配置されます。
|
||||
ac-clang/clang-server/binary/clang-server.exe
|
||||
ac-clang/clang-server/library/x86_64/release/libclang.dll
|
||||
ac-clang/clang-server/library/x86_64/release/libclang.lib
|
||||
|
||||
* パッチを適用せずLLVMオフィシャルのlibclangを使用する場合の制限事項
|
||||
** 特定ファイルがロックされセーブできなくなる
|
||||
編集したヘッダファイルをセーブしようとすると "basic-save-buffer-2: Opening output file: invalid argument `HEADER-FILE-NAME`" となりセーブできない。
|
||||
必ず発生するわけではなく特定の条件を満たしたファイルサイズが16kBを越えるヘッダファイルで発生する。
|
||||
16kB以下のヘッダファイルではまったく発生しない。
|
||||
libclang の TranslationUnit(以下TU) の問題。
|
||||
libclang の TU がinclude対象のファイルをロックしている。
|
||||
ac-clang側で暫定対処パッチを施してあるので多少は緩和されているが完全に回避はできない。
|
||||
発生した場合はマニュアル対処する以外ない。
|
||||
|
||||
*** emacs側での対処方法
|
||||
include対象なので大抵は foo.cpp/foo.hpp という構成だとおもわれます。
|
||||
foo.hpp(modified)がセーブできない場合、大抵foo.cppが(modified)になっているのでfoo.cppをセーブしましょう。
|
||||
これによりfoo.hppはセーブ可能になるはずです。
|
||||
これでもセーブできない場合は、foo.cpp以外のソースでfoo.hppをインクルードしており(modified)になっているバッファがあるはずなので
|
||||
それもセーブしましょう。
|
||||
また、定義へのジャンプ機能で該当ソースがアクティブ化されている場合は、未編集バッファであってもアクティブ化されています。
|
||||
該当バッファを削除してみるか、そのバッファへスイッチして (ac-clang-deactivate) を実行してください。
|
||||
これ以外でも16kBを越えるヘッダを編集しようとした際に、そのファイルのcppはオープンしてもいないのにセーブできない場合、
|
||||
該当ヘッダファイルを何処か遠いモジュールでインクルードしている場合なども同様の症状になります。
|
||||
ライブラリモジュールやフレームワークなどを開発している場合は発生しやすいかもしれません。
|
||||
※ライブラリ・フレームワークはアプリ側からよくincludeされるため。
|
||||
|
||||
*** 原因(実装上の問題説明、解決案求む)
|
||||
foo.cpp(modified)のとき foo.cppのセッションで
|
||||
TUが foo.cpp パース後もincludeされているファイルのロックを保持しつづけている。
|
||||
この状態で foo.hpp を編集してセーブしようとするとロックでエラーになる。
|
||||
ロックを解除するには、 foo.cpp のTUをリリースする。
|
||||
なので foo.cpp セーブ時にセッションは保持した状態で TU だけをリリースして、
|
||||
foo.cpp が再び modified になったときに TU を生成するように修正。
|
||||
これにより foo.cpp セーブ後であればincludeロックでが全解除されるので foo.hpp がセーブ可能になる。
|
||||
当然 foo.cpp 以外に foo.hpp をinclude しているソースでかつ、編集中のバッファがある場合は、
|
||||
それら全てを保存しないとロックでは解除されない。
|
||||
|
||||
Windows環境において、
|
||||
このロックはI/Oのopen関数によるロックはではなくWindowsAPIのCreateFileMappingによるロックである。
|
||||
libclang FileManagerは16kB以上のファイルをメモリマップドファイルとしてアロケーションする。
|
||||
TUがリリースされるとUnmapViewOfFileによりメモリマップドファイルがリリースされるようになりファイルに対して書き込み可能になる。
|
||||
|
||||
Linux環境においても発現する不具合はWindows環境と若干異なるものの mmap/munmapによる問題は発生する。
|
||||
foo.cppのTUを保持している状態でfoo.hppにおいてclass fooのメソッドを追加・削除し保存する。
|
||||
foo.hpp更新後にfoo.cppにおいてclass fooのメソッドを補間しようとするとTUがクラッシュする。
|
||||
libclangがSTDOUTに "libclang: crash detected in code completion" を出力する。
|
||||
clang-serverのプロセスは生きており、セッションを破棄して再生成すれば補間続行は可能。
|
||||
|
||||
** その他
|
||||
上記の問題はlibclangにパッチを適用して改善している。
|
||||
|
||||
パッチを適用したリリースバイナリのlibclang-x86_XX.(dll or so)を使用している場合は発生しない。
|
||||
パッチを適用していないLLVMセルフビルドおよび、LLVMオフィシャルバイナリを使用する場合にのみ問題が発生します。
|
||||
clang側の仕様バグなので現在LLVM bugzilla に報告済み。対応待ち中。
|
||||
http://llvm.org/bugs/show_bug.cgi?id=20880
|
||||
|
||||
* パッチ解説
|
||||
** パッチ
|
||||
ac-clang/clang-server/patch/invalidate-mmap.patch
|
||||
を使用。
|
||||
#+begin_src shell-script
|
||||
cd llvm/
|
||||
svn patch ac-clang/clang-server/patch/invalidate-mmap.patch
|
||||
#+end_src
|
||||
|
||||
** パッチ(invalidate-mmap.patch)で行っている事
|
||||
mmapを使わないようにパッチを適用している
|
||||
適用するのは以下のソース
|
||||
clang-trunk/llvm/lib/Support/MemoryBuffer.cpp
|
||||
|
||||
#+begin_src C++
|
||||
static error_code getOpenFileImpl(int FD, const char *Filename,
|
||||
OwningPtr<MemoryBuffer> &result,
|
||||
uint64_t FileSize, uint64_t MapSize,
|
||||
int64_t Offset, bool RequiresNullTerminator) {
|
||||
#+end_src
|
||||
|
||||
↑の関数内で呼ばれる shouldUseMmap によりファイルに対するmmapの使用可否が判断される
|
||||
#+begin_src C++
|
||||
static bool shouldUseMmap(int FD,
|
||||
size_t FileSize,
|
||||
size_t MapSize,
|
||||
off_t Offset,
|
||||
bool RequiresNullTerminator,
|
||||
int PageSize) {
|
||||
#+end_src
|
||||
この関数のresultが常時falseであればmmapは恒久的に使用されない。
|
||||
よってこの関数の先頭で
|
||||
#+begin_src C++
|
||||
return false;
|
||||
#+end_src
|
||||
とすればよい。
|
||||
以降のコードは#if 0 end するなりすればよい。
|
||||
|
||||
** LLVM3.5の追加仕様
|
||||
shouldUseMmap,getOpenFileImplに引数IsVolatileSizeが追加された。
|
||||
これはshouldUseMmapまで加工なしでパスされ、
|
||||
shouldUseMmap先頭において、
|
||||
#+begin_src C++
|
||||
if (IsVolatileSize)
|
||||
return false;
|
||||
#+end_src
|
||||
される。
|
||||
コメントがついていた
|
||||
#+begin_src C++
|
||||
// mmap may leave the buffer without null terminator if the file size changed
|
||||
// by the time the last page is mapped in, so avoid it if the file size is
|
||||
// likely to change.
|
||||
#+end_src
|
||||
|
||||
mmapはファイルサイズが最後のページがマップされたされた時点で変更された場合はnull終端せずにバッファを残すので、ファイルサイズが変更される可能性がある場合は、それを回避することができる。
|
||||
|
||||
とは言っているものの、想定されていない事態がいろいろあるようで仕様抜けの模様。
|
||||
またバッファ確保系関数の上流で IsVolatileSize が指定されていなかったりコンストラクタのデフォルト値のまま運用されている箇所が何箇所か見受けられた。
|
||||
そういった箇所を自前で修正してみたところ従来よりマシになったものの、他にも問題があるようで想定通りにmmapを制御は出来なかった。
|
||||
LLVMのファイルシステム・メモリ周りの仕様を完全に把握していないと、ここら辺の修正は厳しいのかもしれない。
|
||||
よって現時点においては上記パッチ適用が一番無難なやり方となる。
|
||||
|
@ -1,392 +0,0 @@
|
||||
<div id="table-of-contents">
|
||||
<h2>Table of Contents</h2>
|
||||
<div id="text-table-of-contents">
|
||||
<ul>
|
||||
<li><a href="#sec-1">1. About this document</a></li>
|
||||
<li><a href="#sec-2">2. Step of self-build</a>
|
||||
<ul>
|
||||
<li><a href="#sec-2-1">2.1. LLVM self-build</a></li>
|
||||
<li><a href="#sec-2-2">2.2. clang-server self-build</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#sec-3">3. Software required for self-build</a>
|
||||
<ul>
|
||||
<li><a href="#sec-3-1">3.1. Windows</a>
|
||||
<ul>
|
||||
<li><a href="#sec-3-1-1">3.1.1. LLVM</a></li>
|
||||
<li><a href="#sec-3-1-2">3.1.2. Visual Studio 2015/2013/2012/2010</a></li>
|
||||
<li><a href="#sec-3-1-3">3.1.3. CMake</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#sec-3-2">3.2. Linux</a>
|
||||
<ul>
|
||||
<li><a href="#sec-3-2-1">3.2.1. LLVM</a></li>
|
||||
<li><a href="#sec-3-2-2">3.2.2. CMake</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#sec-4">4. Self-Build</a>
|
||||
<ul>
|
||||
<li><a href="#sec-4-1">4.1. Windows</a>
|
||||
<ul>
|
||||
<li><a href="#sec-4-1-1">4.1.1. LLVM</a></li>
|
||||
<li><a href="#sec-4-1-2">4.1.2. clang-server</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#sec-4-2">4.2. Linux</a>
|
||||
<ul>
|
||||
<li><a href="#sec-4-2-1">4.2.1. LLVM</a></li>
|
||||
<li><a href="#sec-4-2-2">4.2.2. clang-server</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#sec-5">5. Patch was applied binary(Windows Only)</a></li>
|
||||
<li><a href="#sec-6">6. Restrictions when you use LLVM official libclang without applying a patch</a>
|
||||
<ul>
|
||||
<li><a href="#sec-6-1">6.1. A specific file is locked and cannot save it</a>
|
||||
<ul>
|
||||
<li><a href="#sec-6-1-1">6.1.1. Solution in Emacs side</a></li>
|
||||
<li><a href="#sec-6-1-2">6.1.2. Issue(Implementation issues explanation, it wanted suggested solutions)</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#sec-6-2">6.2. Miscellaneous</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#sec-7">7. Patch commentary</a>
|
||||
<ul>
|
||||
<li><a href="#sec-7-1">7.1. Patch</a></li>
|
||||
<li><a href="#sec-7-2">7.2. The contents of the LLVM patch(invalidate-mmap.patch)</a></li>
|
||||
<li><a href="#sec-7-3">7.3. <span class="todo TODO">TODO</span> Additional Specification of LLVM3.5</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
[Japanese Manual](./readme.ja.md)
|
||||
|
||||
# About this document<a id="sec-1" name="sec-1"></a>
|
||||
|
||||
This is explained about self-build of clang-server.
|
||||
When you use clang-server binary for distribution on Windows environment, it is not necessary to read this document.
|
||||
|
||||
# Step of self-build<a id="sec-2" name="sec-2"></a>
|
||||
|
||||
A build of clang-server requires libclang of LLVM.
|
||||
Therefore, first self-build is LLVM libclang, next self-build is clang-server.
|
||||
|
||||
## LLVM self-build<a id="sec-2-1" name="sec-2-1"></a>
|
||||
|
||||
You have to do four step of following.
|
||||
There is also a script which simplify this work.
|
||||
- Checkout LLVM
|
||||
- Apply patch to LLVM for libclang
|
||||
- Project file generation by CMAKE or configure
|
||||
- Build
|
||||
|
||||
## clang-server self-build<a id="sec-2-2" name="sec-2-2"></a>
|
||||
|
||||
Patch applied libclang library use by LLVM self-build
|
||||
Use the patch applied libclang library
|
||||
- Project file generation by CMAKE
|
||||
- Build
|
||||
- Installation
|
||||
|
||||
# Software required for self-build<a id="sec-3" name="sec-3"></a>
|
||||
|
||||
## Windows<a id="sec-3-1" name="sec-3-1"></a>
|
||||
|
||||
The following is required.
|
||||
|
||||
### LLVM<a id="sec-3-1-1" name="sec-3-1-1"></a>
|
||||
|
||||
The following built library is required.
|
||||
libclang.lib or libclang.imp
|
||||
libclang.dll
|
||||
|
||||
### Visual Studio 2015/2013/2012/2010<a id="sec-3-1-2" name="sec-3-1-2"></a>
|
||||
|
||||
any OK
|
||||
|
||||
### CMake<a id="sec-3-1-3" name="sec-3-1-3"></a>
|
||||
|
||||
<http://www.cmake.org/>
|
||||
|
||||
Download cmake archive, and decompress to any location.
|
||||
CMake is used for Visual Studio Solution File generation and build and installation.
|
||||
|
||||
## Linux<a id="sec-3-2" name="sec-3-2"></a>
|
||||
|
||||
The following is required.
|
||||
|
||||
### LLVM<a id="sec-3-2-1" name="sec-3-2-1"></a>
|
||||
|
||||
The following built library is required.
|
||||
libclang.so
|
||||
|
||||
### CMake<a id="sec-3-2-2" name="sec-3-2-2"></a>
|
||||
|
||||
$ sudo apt-get install cmake
|
||||
|
||||
If you want to use latest version, download from following
|
||||
|
||||
<http://www.cmake.org/>
|
||||
|
||||
e.g.
|
||||
Download cmake-3.1.3.tar.gz, and decompress to work directory.
|
||||
You perform a build and installation.
|
||||
|
||||
$ tar -xf cmake-3.1.3.tar.gz .
|
||||
$ cd cmake-3.1.3
|
||||
$ ./configure && make
|
||||
$ make install
|
||||
|
||||
# Self-Build<a id="sec-4" name="sec-4"></a>
|
||||
|
||||
## Windows<a id="sec-4-1" name="sec-4-1"></a>
|
||||
|
||||
### LLVM<a id="sec-4-1-1" name="sec-4-1-1"></a>
|
||||
|
||||
Required process for LLVM self-build.
|
||||
And you must apply patch to LLVM before build.
|
||||
It isn't necessary install a package after self-build.
|
||||
You must designate generated binary PATH after LLVM self-build at CMake project generation argument.
|
||||
Therefore clang-server is able to build.
|
||||
When LLVM is already installed, you must designate installed directory of LLVM.
|
||||
|
||||
When you want to self-build,
|
||||
Checkout from SVN by yourself, and perform the LLVM Solution File generation and build by cmake.
|
||||
Or, use following script.
|
||||
<https://github.com/yaruopooner/llvm-build-shells>
|
||||
|
||||
1. How to designate the LLVM patch in the script
|
||||
|
||||
You will designate -tasks to the argument of builderShell,
|
||||
and designate PATCH to the parameter of -tasks,
|
||||
It will gives a table that describes the path to apply the patch and patch file to parameter of -patchInfos.
|
||||
Please refer to the sample.ps1 of llvm-build-shells for details.
|
||||
|
||||
2. The contents of the LLVM patch
|
||||
|
||||
Use of mmap always invalidation.
|
||||
|
||||
### clang-server<a id="sec-4-1-2" name="sec-4-1-2"></a>
|
||||
|
||||
Use the ac-clang/build/builder\_sample.bat
|
||||
Please edit the builder\_sample.bat as necessary.
|
||||
It's necessary to execute in the command line or Windows Explorer.
|
||||
|
||||
- example
|
||||
|
||||
cmake -G "Visual Studio 12 2013 Win64" ../clang-server -DLIBRARY_PATHS="c:/cygwin-x86_64/tmp/llvm-build-shells/ps1/clang-360/build/msvc-64/" -DCMAKE_INSTALL_PREFIX="c:/cygwin-x86_64/usr/local/bin/"
|
||||
|
||||
- Option commentary
|
||||
- `-DLIBRARY_PATHS`
|
||||
You have to designate location of LLVM self-build completed directory.
|
||||
It is necessary to designate the directory that a binary was generated.(e.g. {LLVM output path}/Release/)
|
||||
If you omit this option, value will be use `ac-clang/clang-server` .
|
||||
- `-DCMAKE_INSTALL_PREFIX`
|
||||
You have to designate installation location of clang-server.
|
||||
If you omit this option, value will be use `C:/Program Files/clang-server` .
|
||||
|
||||
## Linux<a id="sec-4-2" name="sec-4-2"></a>
|
||||
|
||||
### LLVM<a id="sec-4-2-1" name="sec-4-2-1"></a>
|
||||
|
||||
Required process for LLVM self-build.
|
||||
And you must apply patch to LLVM before build.
|
||||
It isn't necessary install a package after self-build.
|
||||
You must designate generated binary PATH after LLVM self-build at CMake project generation argument.
|
||||
Therefore clang-server is able to build.
|
||||
When LLVM is already installed, you must designate installed directory of LLVM.
|
||||
|
||||
When you want to self-build,
|
||||
Checkout from SVN by yourself, and perform the LLVM Solution File generation and build by cmake.
|
||||
Or, use following script.
|
||||
<https://github.com/yaruopooner/llvm-build-shells>
|
||||
|
||||
1. How to designate the LLVM patch in the script
|
||||
|
||||
You will designate -patch to the argument of executeBuilder.
|
||||
Add to -patchApplyLocation the path where you want to apply the patch.
|
||||
You write the patch file to -patchPath gives as an parameter.
|
||||
-patchApplyLocation,-patchPath becomes the pair, it is possible to multiple times designate.
|
||||
Please refer to the sample.sh of llvm-build-shells for details.
|
||||
|
||||
2. The contents of the LLVM patch
|
||||
|
||||
Use of mmap always invalidation.
|
||||
|
||||
### clang-server<a id="sec-4-2-2" name="sec-4-2-2"></a>
|
||||
|
||||
Use the ac-clang/build/builder\_sample.sh
|
||||
Please edit the builder\_sample.sh as necessary.
|
||||
Execute the builder\_sample.sh
|
||||
|
||||
- example
|
||||
|
||||
cmake -G "Unix Makefiles" ../clang-server -DLIBRARY_PATHS="/home/yaruopooner/work/llvm-build-shells/sh/clang-350/build" -DCMAKE_INSTALL_PREFIX="~/work/clang-server"
|
||||
|
||||
- Option commentary
|
||||
- `-DLIBRARY_PATHS`
|
||||
You have to designate location of LLVM self-build completed directory.
|
||||
It is necessary to designate the directory that a binary was generated.(e.g. {LLVM output path}/Release/)
|
||||
If you omit this option, value will be use `ac-clang/clang-server` .
|
||||
- `-DCMAKE_INSTALL_PREFIX`
|
||||
You have to designate installation location of clang-server.
|
||||
If you omit this option, value will be use `/usr/local/bin` .
|
||||
|
||||
# Patch was applied binary(Windows Only)<a id="sec-5" name="sec-5"></a>
|
||||
|
||||
<https://github.com/yaruopooner/ac-clang/releases>
|
||||
|
||||
clang-server-X.X.X.zip is you can download from the above
|
||||
The archive is 3 files contain, these file applied patch.
|
||||
- clang-server.exe
|
||||
- libclang.dll
|
||||
- libclang.lib or libclang.imp
|
||||
|
||||
When you want to self-build only clang-server without LLVM,
|
||||
clang-server-X.X.X.zip decompress to ac-clang directory.
|
||||
Then, it will be placed in the following.
|
||||
ac-clang/clang-server/binary/clang-server.exe
|
||||
ac-clang/clang-server/library/x86\_64/release/libclang.dll
|
||||
ac-clang/clang-server/library/x86\_64/release/libclang.lib
|
||||
|
||||
# Restrictions when you use LLVM official libclang without applying a patch<a id="sec-6" name="sec-6"></a>
|
||||
|
||||
## A specific file is locked and cannot save it<a id="sec-6-1" name="sec-6-1"></a>
|
||||
|
||||
When you try to save the edited header file,
|
||||
it will be "basic-save-buffer-2: Opening output file: invalid argument \`HEADER-FILE-NAME\`",
|
||||
and you can't save.
|
||||
This occur if it meets certain conditions.
|
||||
This condition is met when the header file size is larger than 16kB.
|
||||
It is not at all occur when header file size is smaller than 16kB.
|
||||
This issue belong to TranslationUnit(TU) of libclang.
|
||||
The inclusion target file is locked by TU of libclang.
|
||||
By performing a provisional transaction in ac-clang side, the more or less is erased, but it can't be avoided perfectly.
|
||||
When this issue is occurring, only manual handle can be avoided.
|
||||
|
||||
### Solution in Emacs side<a id="sec-6-1-1" name="sec-6-1-1"></a>
|
||||
|
||||
I suppose that combination of source file is foo.cpp/foo.hpp.
|
||||
When foo.hpp(modified) can't save, foo.cpp is (modified) often, so foo.cpp have to saved.
|
||||
Therefore, foo.hpp should be possible to save.
|
||||
When this can't save,
|
||||
foo.hpp is included by source files besides foo.cpp, and it has (modified) status.
|
||||
You have to save those.
|
||||
And, when corresponding source is activated by definition jump feature, even if buffer don't modified that buffer is activated.
|
||||
You try remove corresponding buffer, or (ac-clang-deactivate) must be execute in buffer.
|
||||
In other cases, when you try save header file that file size larger than 16kB
|
||||
When you save a header file of larger than 16kB, if it fails.
|
||||
And that header file does not opened.
|
||||
In this case, header file is included by a far module from current source file.
|
||||
When you having developed a library module framework, it may be easy to occur.
|
||||
because library and framework is included from application side.
|
||||
|
||||
### Issue(Implementation issues explanation, it wanted suggested solutions)<a id="sec-6-1-2" name="sec-6-1-2"></a>
|
||||
|
||||
When session of "foo.cpp" is edited in the buffer,
|
||||
TU continue locking to included header file after parsed "foo.cpp".
|
||||
|
||||
When you edit and save to "foo.hpp" in this state, it occur error, because file is locked by mmap.
|
||||
|
||||
Therefore I modified a server as follows.
|
||||
So while maintaining the session when "foo.cpp" saving,
|
||||
TU is generated when "foo.cpp" is edited after TU released.
|
||||
|
||||
Therefore "foo.hpp" is possible to save that the included header file is unlocked after "foo.cpp" saved.
|
||||
|
||||
When a "foo.hpp" is included buffer where exist in buffer editing group without buffer of "foo.cpp",
|
||||
the lock is not released when you does not save all them.
|
||||
|
||||
In the Windows environment,
|
||||
This lock is not open function of I/O, is a lock by CreateFileMapping of WindowsAPI.
|
||||
libclang FileManager does allocation to memory mapped file for the files larger than 16kB.
|
||||
When TU is released, memory mapped file is released by UnmapViewOfFile, these becomes writable to file.
|
||||
|
||||
In the Linux environment,
|
||||
problems with mmap/munmap bug differ slightly from the Windows environment, but also occurred in Linux environment.
|
||||
The method add to "class Foo" in "foo.hpp" in the state that holds TU of "foo.cpp", and save to file.
|
||||
After "foo.hpp" update, when you try complete method of "class Foo" in the "foo.cpp", TU will crash.
|
||||
in this case, libclang output to STDOUT that "libclang: crash detected in code completion"
|
||||
libclang output "libclang: crash detected in code completion" to STDOUT.
|
||||
The process of clang-server is living in this situation.
|
||||
Completion is possible after deletion of session and creation of session.
|
||||
|
||||
## Miscellaneous<a id="sec-6-2" name="sec-6-2"></a>
|
||||
|
||||
The above problems are solved by patching for libclang.
|
||||
|
||||
When you use the patch applied release binary(libclang.dll or so) it is not occur.
|
||||
When you use the patch does not applied to LLVM self-build and LLVM official binary, this problem is occur.
|
||||
I think specification bug of clang side. This problem has been reported to LLVM bugzilla. in the corresponding waitting.
|
||||
<http://llvm.org/bugs/show_bug.cgi?id=20880>
|
||||
|
||||
# Patch commentary<a id="sec-7" name="sec-7"></a>
|
||||
|
||||
## Patch<a id="sec-7-1" name="sec-7-1"></a>
|
||||
|
||||
Use the ac-clang/clang-server/patch/invalidate-mmap.patch
|
||||
|
||||
cd llvm/
|
||||
svn patch ac-clang/clang-server/patch/invalidate-mmap.patch
|
||||
|
||||
## The contents of the LLVM patch(invalidate-mmap.patch)<a id="sec-7-2" name="sec-7-2"></a>
|
||||
|
||||
Patch is applied so as not to use mmap.
|
||||
Apply to the following source code to
|
||||
`clang-trunk/llvm/lib/Support/MemoryBuffer.cpp`
|
||||
|
||||
static error_code getOpenFileImpl(int FD, const char *Filename,
|
||||
OwningPtr<MemoryBuffer> &result,
|
||||
uint64_t FileSize, uint64_t MapSize,
|
||||
int64_t Offset, bool RequiresNullTerminator) {
|
||||
|
||||
It is determined availability of mmap for file by shouldUseMmap call from the above function.
|
||||
|
||||
static bool shouldUseMmap(int FD,
|
||||
size_t FileSize,
|
||||
size_t MapSize,
|
||||
off_t Offset,
|
||||
bool RequiresNullTerminator,
|
||||
int PageSize) {
|
||||
|
||||
When the result of function is always false, mmap is not never used.
|
||||
Therefore, the following modify has been applied to the top of this function.
|
||||
|
||||
#if 1
|
||||
return false;
|
||||
#else
|
||||
/* original codes */
|
||||
#endif
|
||||
|
||||
## TODO Additional Specification of LLVM3.5<a id="sec-7-3" name="sec-7-3"></a>
|
||||
|
||||
IsVolatileSize has been added to arguments of shouldUseMmap and getOpenFileImpl.
|
||||
This will be passed unchanged to shouldUseMmap.
|
||||
|
||||
It is executed as follows in the shouldUseMmap top.
|
||||
|
||||
if (IsVolatileSize)
|
||||
return false;
|
||||
|
||||
Following comments had been attached
|
||||
|
||||
// mmap may leave the buffer without null terminator if the file size changed
|
||||
// by the time the last page is mapped in, so avoid it if the file size is
|
||||
// likely to change.
|
||||
|
||||
Although that said, there is a situation which isn't assumed Variously, I'm supposing that mistake of specification.
|
||||
Moreover, upstream function of buffer association function
|
||||
I was found some place where is not designated value of IsVolatileSize and is used default value of constructor argument.
|
||||
I tried modified it.
|
||||
Result was become more better than conventional.
|
||||
But it seem to have a problem, because I was not able to control mmap like a assumption.
|
||||
I'm not enough understand the specification of around the file system and memory of LLVM.
|
||||
For that reason that the rightly correction is difficult.
|
||||
Therefore, the above patching becomes the most safe way at present.
|
@ -1,314 +0,0 @@
|
||||
# -*- mode: org ; coding: utf-8-unix -*-
|
||||
# last updated : 2015/07/21.00:46:31
|
||||
|
||||
|
||||
#+TITLE: Clang Server Manual
|
||||
#+AUTHOR: yaruopooner
|
||||
#+EMAIL: [https://github.com/yaruopooner]
|
||||
#+OPTIONS: author:nil timestamp:t |:t \n:t ^:nil
|
||||
|
||||
|
||||
[[./readme.ja.org][Japanese Manual]]
|
||||
|
||||
* About this document
|
||||
This is explained about self-build of clang-server.
|
||||
When you use clang-server binary for distribution on Windows environment, it is not necessary to read this document.
|
||||
|
||||
* Step of self-build
|
||||
A build of clang-server requires libclang of LLVM.
|
||||
Therefore, first self-build is LLVM libclang, next self-build is clang-server.
|
||||
|
||||
** LLVM self-build
|
||||
You have to do four step of following.
|
||||
There is also a script which simplify this work.
|
||||
- Checkout LLVM
|
||||
- Apply patch to LLVM for libclang
|
||||
- Project file generation by CMAKE or configure
|
||||
- Build
|
||||
|
||||
** clang-server self-build
|
||||
Patch applied libclang library use by LLVM self-build
|
||||
Use the patch applied libclang library
|
||||
- Project file generation by CMAKE
|
||||
- Build
|
||||
- Installation
|
||||
|
||||
* Software required for self-build
|
||||
** Windows
|
||||
The following is required.
|
||||
*** LLVM
|
||||
The following built library is required.
|
||||
libclang.lib or libclang.imp
|
||||
libclang.dll
|
||||
|
||||
*** Visual Studio 2015/2013/2012/2010
|
||||
any OK
|
||||
|
||||
*** CMake
|
||||
http://www.cmake.org/
|
||||
|
||||
Download cmake archive, and decompress to any location.
|
||||
CMake is used for Visual Studio Solution File generation and build and installation.
|
||||
|
||||
** Linux
|
||||
The following is required.
|
||||
*** LLVM
|
||||
The following built library is required.
|
||||
libclang.so
|
||||
|
||||
*** CMake
|
||||
#+begin_src shell
|
||||
$ sudo apt-get install cmake
|
||||
#+end_src
|
||||
|
||||
If you want to use latest version, download from following
|
||||
|
||||
http://www.cmake.org/
|
||||
|
||||
e.g.
|
||||
Download cmake-3.1.3.tar.gz, and decompress to work directory.
|
||||
You perform a build and installation.
|
||||
#+begin_src shell
|
||||
$ tar -xf cmake-3.1.3.tar.gz .
|
||||
$ cd cmake-3.1.3
|
||||
$ ./configure && make
|
||||
$ make install
|
||||
#+end_src
|
||||
|
||||
* Self-Build
|
||||
** Windows
|
||||
*** LLVM
|
||||
Required process for LLVM self-build.
|
||||
And you must apply patch to LLVM before build.
|
||||
It isn't necessary install a package after self-build.
|
||||
You must designate generated binary PATH after LLVM self-build at CMake project generation argument.
|
||||
Therefore clang-server is able to build.
|
||||
When LLVM is already installed, you must designate installed directory of LLVM.
|
||||
|
||||
When you want to self-build,
|
||||
Checkout from SVN by yourself, and perform the LLVM Solution File generation and build by cmake.
|
||||
Or, use following script.
|
||||
https://github.com/yaruopooner/llvm-build-shells
|
||||
|
||||
**** How to designate the LLVM patch in the script
|
||||
You will designate -tasks to the argument of builderShell,
|
||||
and designate PATCH to the parameter of -tasks,
|
||||
It will gives a table that describes the path to apply the patch and patch file to parameter of -patchInfos.
|
||||
Please refer to the sample.ps1 of llvm-build-shells for details.
|
||||
|
||||
**** The contents of the LLVM patch
|
||||
Use of mmap always invalidation.
|
||||
|
||||
*** clang-server
|
||||
Use the ac-clang/build/builder_sample.bat
|
||||
Please edit the builder_sample.bat as necessary.
|
||||
It's necessary to execute in the command line or Windows Explorer.
|
||||
|
||||
- example
|
||||
#+begin_src bat
|
||||
cmake -G "Visual Studio 12 2013 Win64" ../clang-server -DLIBRARY_PATHS="c:/cygwin-x86_64/tmp/llvm-build-shells/ps1/clang-360/build/msvc-64/" -DCMAKE_INSTALL_PREFIX="c:/cygwin-x86_64/usr/local/bin/"
|
||||
#+end_src
|
||||
|
||||
- Option commentary
|
||||
- =-DLIBRARY_PATHS=
|
||||
You have to designate location of LLVM self-build completed directory.
|
||||
It is necessary to designate the directory that a binary was generated.(e.g. {LLVM output path}/Release/)
|
||||
If you omit this option, value will be use =ac-clang/clang-server= .
|
||||
- =-DCMAKE_INSTALL_PREFIX=
|
||||
You have to designate installation location of clang-server.
|
||||
If you omit this option, value will be use =C:/Program Files/clang-server= .
|
||||
|
||||
** Linux
|
||||
*** LLVM
|
||||
Required process for LLVM self-build.
|
||||
And you must apply patch to LLVM before build.
|
||||
It isn't necessary install a package after self-build.
|
||||
You must designate generated binary PATH after LLVM self-build at CMake project generation argument.
|
||||
Therefore clang-server is able to build.
|
||||
When LLVM is already installed, you must designate installed directory of LLVM.
|
||||
|
||||
When you want to self-build,
|
||||
Checkout from SVN by yourself, and perform the LLVM Solution File generation and build by cmake.
|
||||
Or, use following script.
|
||||
https://github.com/yaruopooner/llvm-build-shells
|
||||
|
||||
**** How to designate the LLVM patch in the script
|
||||
You will designate -patch to the argument of executeBuilder.
|
||||
Add to -patchApplyLocation the path where you want to apply the patch.
|
||||
You write the patch file to -patchPath gives as an parameter.
|
||||
-patchApplyLocation,-patchPath becomes the pair, it is possible to multiple times designate.
|
||||
Please refer to the sample.sh of llvm-build-shells for details.
|
||||
|
||||
**** The contents of the LLVM patch
|
||||
Use of mmap always invalidation.
|
||||
|
||||
*** clang-server
|
||||
Use the ac-clang/build/builder_sample.sh
|
||||
Please edit the builder_sample.sh as necessary.
|
||||
Execute the builder_sample.sh
|
||||
|
||||
- example
|
||||
#+begin_src shell-script
|
||||
cmake -G "Unix Makefiles" ../clang-server -DLIBRARY_PATHS="/home/yaruopooner/work/llvm-build-shells/sh/clang-350/build" -DCMAKE_INSTALL_PREFIX="~/work/clang-server"
|
||||
#+end_src
|
||||
|
||||
- Option commentary
|
||||
- =-DLIBRARY_PATHS=
|
||||
You have to designate location of LLVM self-build completed directory.
|
||||
It is necessary to designate the directory that a binary was generated.(e.g. {LLVM output path}/Release/)
|
||||
If you omit this option, value will be use =ac-clang/clang-server= .
|
||||
- =-DCMAKE_INSTALL_PREFIX=
|
||||
You have to designate installation location of clang-server.
|
||||
If you omit this option, value will be use =/usr/local/bin= .
|
||||
|
||||
* Patch was applied binary(Windows Only)
|
||||
https://github.com/yaruopooner/ac-clang/releases
|
||||
|
||||
clang-server-X.X.X.zip is you can download from the above
|
||||
The archive is 3 files contain, these file applied patch.
|
||||
- clang-server.exe
|
||||
- libclang.dll
|
||||
- libclang.lib or libclang.imp
|
||||
|
||||
When you want to self-build only clang-server without LLVM,
|
||||
clang-server-X.X.X.zip decompress to ac-clang directory.
|
||||
Then, it will be placed in the following.
|
||||
ac-clang/clang-server/binary/clang-server.exe
|
||||
ac-clang/clang-server/library/x86_64/release/libclang.dll
|
||||
ac-clang/clang-server/library/x86_64/release/libclang.lib
|
||||
|
||||
* Restrictions when you use LLVM official libclang without applying a patch
|
||||
** A specific file is locked and cannot save it
|
||||
When you try to save the edited header file,
|
||||
it will be "basic-save-buffer-2: Opening output file: invalid argument `HEADER-FILE-NAME`",
|
||||
and you can't save.
|
||||
This occur if it meets certain conditions.
|
||||
This condition is met when the header file size is larger than 16kB.
|
||||
It is not at all occur when header file size is smaller than 16kB.
|
||||
This issue belong to TranslationUnit(TU) of libclang.
|
||||
The inclusion target file is locked by TU of libclang.
|
||||
By performing a provisional transaction in ac-clang side, the more or less is erased, but it can't be avoided perfectly.
|
||||
When this issue is occurring, only manual handle can be avoided.
|
||||
|
||||
*** Solution in Emacs side
|
||||
I suppose that combination of source file is foo.cpp/foo.hpp.
|
||||
When foo.hpp(modified) can't save, foo.cpp is (modified) often, so foo.cpp have to saved.
|
||||
Therefore, foo.hpp should be possible to save.
|
||||
When this can't save,
|
||||
foo.hpp is included by source files besides foo.cpp, and it has (modified) status.
|
||||
You have to save those.
|
||||
And, when corresponding source is activated by definition jump feature, even if buffer don't modified that buffer is activated.
|
||||
You try remove corresponding buffer, or (ac-clang-deactivate) must be execute in buffer.
|
||||
In other cases, when you try save header file that file size larger than 16kB
|
||||
When you save a header file of larger than 16kB, if it fails.
|
||||
And that header file does not opened.
|
||||
In this case, header file is included by a far module from current source file.
|
||||
When you having developed a library module framework, it may be easy to occur.
|
||||
because library and framework is included from application side.
|
||||
|
||||
*** Issue(Implementation issues explanation, it wanted suggested solutions)
|
||||
When session of "foo.cpp" is edited in the buffer,
|
||||
TU continue locking to included header file after parsed "foo.cpp".
|
||||
|
||||
When you edit and save to "foo.hpp" in this state, it occur error, because file is locked by mmap.
|
||||
|
||||
Therefore I modified a server as follows.
|
||||
So while maintaining the session when "foo.cpp" saving,
|
||||
TU is generated when "foo.cpp" is edited after TU released.
|
||||
|
||||
Therefore "foo.hpp" is possible to save that the included header file is unlocked after "foo.cpp" saved.
|
||||
|
||||
When a "foo.hpp" is included buffer where exist in buffer editing group without buffer of "foo.cpp",
|
||||
the lock is not released when you does not save all them.
|
||||
|
||||
|
||||
In the Windows environment,
|
||||
This lock is not open function of I/O, is a lock by CreateFileMapping of WindowsAPI.
|
||||
libclang FileManager does allocation to memory mapped file for the files larger than 16kB.
|
||||
When TU is released, memory mapped file is released by UnmapViewOfFile, these becomes writable to file.
|
||||
|
||||
In the Linux environment,
|
||||
problems with mmap/munmap bug differ slightly from the Windows environment, but also occurred in Linux environment.
|
||||
The method add to "class Foo" in "foo.hpp" in the state that holds TU of "foo.cpp", and save to file.
|
||||
After "foo.hpp" update, when you try complete method of "class Foo" in the "foo.cpp", TU will crash.
|
||||
in this case, libclang output to STDOUT that "libclang: crash detected in code completion"
|
||||
libclang output "libclang: crash detected in code completion" to STDOUT.
|
||||
The process of clang-server is living in this situation.
|
||||
Completion is possible after deletion of session and creation of session.
|
||||
|
||||
** Miscellaneous
|
||||
The above problems are solved by patching for libclang.
|
||||
|
||||
When you use the patch applied release binary(libclang.dll or so) it is not occur.
|
||||
When you use the patch does not applied to LLVM self-build and LLVM official binary, this problem is occur.
|
||||
I think specification bug of clang side. This problem has been reported to LLVM bugzilla. in the corresponding waitting.
|
||||
http://llvm.org/bugs/show_bug.cgi?id=20880
|
||||
|
||||
* Patch commentary
|
||||
** Patch
|
||||
Use the ac-clang/clang-server/patch/invalidate-mmap.patch
|
||||
#+begin_src shell-script
|
||||
cd llvm/
|
||||
svn patch ac-clang/clang-server/patch/invalidate-mmap.patch
|
||||
#+end_src
|
||||
|
||||
** The contents of the LLVM patch(invalidate-mmap.patch)
|
||||
Patch is applied so as not to use mmap.
|
||||
Apply to the following source code to
|
||||
=clang-trunk/llvm/lib/Support/MemoryBuffer.cpp=
|
||||
|
||||
#+begin_src C++
|
||||
static error_code getOpenFileImpl(int FD, const char *Filename,
|
||||
OwningPtr<MemoryBuffer> &result,
|
||||
uint64_t FileSize, uint64_t MapSize,
|
||||
int64_t Offset, bool RequiresNullTerminator) {
|
||||
#+end_src
|
||||
|
||||
It is determined availability of mmap for file by shouldUseMmap call from the above function.
|
||||
|
||||
#+begin_src C++
|
||||
static bool shouldUseMmap(int FD,
|
||||
size_t FileSize,
|
||||
size_t MapSize,
|
||||
off_t Offset,
|
||||
bool RequiresNullTerminator,
|
||||
int PageSize) {
|
||||
#+end_src
|
||||
When the result of function is always false, mmap is not never used.
|
||||
Therefore, the following modify has been applied to the top of this function.
|
||||
#+begin_src C++
|
||||
#if 1
|
||||
return false;
|
||||
#else
|
||||
/* original codes */
|
||||
#endif
|
||||
#+end_src
|
||||
|
||||
** TODO Additional Specification of LLVM3.5
|
||||
IsVolatileSize has been added to arguments of shouldUseMmap and getOpenFileImpl.
|
||||
This will be passed unchanged to shouldUseMmap.
|
||||
|
||||
It is executed as follows in the shouldUseMmap top.
|
||||
#+begin_src C++
|
||||
if (IsVolatileSize)
|
||||
return false;
|
||||
#+end_src
|
||||
|
||||
Following comments had been attached
|
||||
#+begin_src C++
|
||||
// mmap may leave the buffer without null terminator if the file size changed
|
||||
// by the time the last page is mapped in, so avoid it if the file size is
|
||||
// likely to change.
|
||||
#+end_src
|
||||
|
||||
Although that said, there is a situation which isn't assumed Variously, I'm supposing that mistake of specification.
|
||||
Moreover, upstream function of buffer association function
|
||||
I was found some place where is not designated value of IsVolatileSize and is used default value of constructor argument.
|
||||
I tried modified it.
|
||||
Result was become more better than conventional.
|
||||
But it seem to have a problem, because I was not able to control mmap like a assumption.
|
||||
I'm not enough understand the specification of around the file system and memory of LLVM.
|
||||
For that reason that the rightly correction is difficult.
|
||||
Therefore, the above patching becomes the most safe way at present.
|
||||
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 59 KiB |
@ -750,10 +750,12 @@
|
||||
((:keywords "convenience")
|
||||
(:url . "https://github.com/abo-abo/tiny"))])
|
||||
(tramp-theme .
|
||||
[(0 1)
|
||||
nil "Custom theme for remote buffers" single
|
||||
[(0 1 1)
|
||||
((emacs
|
||||
(24 1)))
|
||||
"Custom theme for remote buffers" single
|
||||
((:url . "http://elpa.gnu.org/packages/tramp-theme.html")
|
||||
(:keywords))])
|
||||
(:keywords "convenience" "faces"))])
|
||||
(transcribe .
|
||||
[(1 0 2)
|
||||
nil "Package for audio transcriptions" single
|
||||
@ -777,6 +779,15 @@
|
||||
[(0 1)
|
||||
nil "Unicode confusables table" tar
|
||||
((:url . "http://elpa.gnu.org/packages/uni-confusables.html"))])
|
||||
(url-http-ntlm .
|
||||
[(2 0 1)
|
||||
((cl-lib
|
||||
(0 5))
|
||||
(ntlm
|
||||
(2 0 0)))
|
||||
"NTLM authentication for the url library" tar
|
||||
((:keywords "comm" "data" "processes" "hypermedia")
|
||||
(:url . "http://elpa.gnu.org/packages/url-http-ntlm.html"))])
|
||||
(vlf .
|
||||
[(1 7)
|
||||
nil "View Large Files" tar
|
||||
|
@ -1 +1 @@
|
||||
Good signature from 474F05837FBDEF9B GNU ELPA Signing Agent <elpasign@elpa.gnu.org> (trust undefined) created at 2016-02-17T11:10:03+0100 using DSA
|
||||
Good signature from 474F05837FBDEF9B GNU ELPA Signing Agent <elpasign@elpa.gnu.org> (trust undefined) created at 2016-02-21T11:20:02+0100 using DSA
|
File diff suppressed because one or more lines are too long
@ -1,16 +0,0 @@
|
||||
;;; auto-complete-clang-async-autoloads.el --- automatically extracted autoloads
|
||||
;;
|
||||
;;; Code:
|
||||
(add-to-list 'load-path (or (file-name-directory #$) (car load-path)))
|
||||
|
||||
;;;### (autoloads nil nil ("auto-complete-clang-async.el") (22209
|
||||
;;;;;; 43687 573985 981000))
|
||||
|
||||
;;;***
|
||||
|
||||
;; Local Variables:
|
||||
;; version-control: never
|
||||
;; no-byte-compile: t
|
||||
;; no-update-autoloads: t
|
||||
;; End:
|
||||
;;; auto-complete-clang-async-autoloads.el ends here
|
@ -1,11 +0,0 @@
|
||||
;;; auto-complete-clang-async-autoloads.el --- automatically extracted autoloads
|
||||
;;
|
||||
;;; Code:
|
||||
(add-to-list 'load-path (or (file-name-directory #$) (car load-path)))
|
||||
|
||||
;; Local Variables:
|
||||
;; version-control: never
|
||||
;; no-byte-compile: t
|
||||
;; no-update-autoloads: t
|
||||
;; End:
|
||||
;;; auto-complete-clang-async-autoloads.el ends here
|
@ -1 +0,0 @@
|
||||
(define-package "auto-complete-clang-async" "20130526.814" "Auto Completion source for clang for GNU Emacs" 'nil :keywords '("completion" "convenience"))
|
Binary file not shown.
@ -1,639 +0,0 @@
|
||||
;;; auto-complete-clang-async.el --- Auto Completion source for clang for GNU Emacs
|
||||
|
||||
;; Copyright (C) 2010 Brian Jiang
|
||||
;; Copyright (C) 2012 Taylan Ulrich Bayirli/Kammer
|
||||
|
||||
;; Authors: Brian Jiang <brianjcj@gmail.com>
|
||||
;; Golevka(?) [https://github.com/Golevka]
|
||||
;; Taylan Ulrich Bayirli/Kammer <taylanbayirli@gmail.com>
|
||||
;; Many others
|
||||
;; Keywords: completion, convenience
|
||||
;; Package-Version: 20130526.814
|
||||
;; Version: 0
|
||||
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; Auto Completion source for clang.
|
||||
;; Uses a "completion server" process to utilize libclang.
|
||||
;; Also provides flymake syntax checking.
|
||||
|
||||
;;; Code:
|
||||
|
||||
|
||||
(provide 'auto-complete-clang-async)
|
||||
(eval-when-compile (require' cl))
|
||||
(require 'auto-complete)
|
||||
(require 'flymake)
|
||||
|
||||
|
||||
(defcustom ac-clang-complete-executable
|
||||
(executable-find "clang-complete")
|
||||
"Location of clang-complete executable."
|
||||
:group 'auto-complete
|
||||
:type 'file)
|
||||
|
||||
(defcustom ac-clang-lang-option-function nil
|
||||
"Function to return the lang type for option -x."
|
||||
:group 'auto-complete
|
||||
:type 'function)
|
||||
|
||||
(defcustom ac-clang-cflags nil
|
||||
"Extra flags to pass to the Clang executable.
|
||||
This variable will typically contain include paths, e.g., (\"-I~/MyProject\" \"-I.\")."
|
||||
:group 'auto-complete
|
||||
:type '(repeat (string :tag "Argument" "")))
|
||||
(make-variable-buffer-local 'ac-clang-cflags)
|
||||
|
||||
(defun ac-clang-set-cflags ()
|
||||
"Set `ac-clang-cflags' interactively."
|
||||
(interactive)
|
||||
(setq ac-clang-cflags (split-string (read-string "New cflags: ")))
|
||||
(ac-clang-update-cmdlineargs))
|
||||
|
||||
(defun ac-clang-set-cflags-from-shell-command ()
|
||||
"Set `ac-clang-cflags' to a shell command's output.
|
||||
|
||||
set new cflags for ac-clang from shell command output"
|
||||
(interactive)
|
||||
(setq ac-clang-cflags
|
||||
(split-string
|
||||
(shell-command-to-string
|
||||
(read-shell-command "Shell command: " nil nil
|
||||
(and buffer-file-name
|
||||
(file-relative-name buffer-file-name))))))
|
||||
(ac-clang-update-cmdlineargs))
|
||||
|
||||
(defvar ac-clang-prefix-header nil
|
||||
"The prefix header to pass to the Clang executable.")
|
||||
(make-variable-buffer-local 'ac-clang-prefix-header)
|
||||
|
||||
(defvar ac-clang-async-do-autocompletion-automatically t
|
||||
"If autocompletion is automatically triggered when you type ., -> or ::")
|
||||
|
||||
(defun ac-clang-set-prefix-header (prefix-header)
|
||||
"Set `ac-clang-prefix-header' interactively."
|
||||
(interactive
|
||||
(let ((default (car (directory-files "." t "\\([^.]h\\|[^h]\\).pch\\'" t))))
|
||||
(list
|
||||
(read-file-name (concat "Clang prefix header (currently " (or ac-clang-prefix-header "nil") "): ")
|
||||
(when default (file-name-directory default))
|
||||
default nil (when default (file-name-nondirectory default))))))
|
||||
(cond
|
||||
((string-match "^[\s\t]*$" prefix-header)
|
||||
(setq ac-clang-prefix-header nil))
|
||||
(t
|
||||
(setq ac-clang-prefix-header prefix-header))))
|
||||
|
||||
|
||||
(defconst ac-clang-completion-pattern
|
||||
"^COMPLETION: \\(%s[^\s\n:]*\\)\\(?: : \\)*\\(.*$\\)")
|
||||
|
||||
(defun ac-clang-parse-output (prefix)
|
||||
(goto-char (point-min))
|
||||
(let ((pattern (format ac-clang-completion-pattern
|
||||
(regexp-quote prefix)))
|
||||
lines match detailed-info
|
||||
(prev-match ""))
|
||||
(while (re-search-forward pattern nil t)
|
||||
(setq match (match-string-no-properties 1))
|
||||
(unless (string= "Pattern" match)
|
||||
(setq detailed-info (match-string-no-properties 2))
|
||||
|
||||
(if (string= match prev-match)
|
||||
(progn
|
||||
(when detailed-info
|
||||
(setq match (propertize match
|
||||
'ac-clang-help
|
||||
(concat
|
||||
(get-text-property 0 'ac-clang-help (car lines))
|
||||
"\n"
|
||||
detailed-info)))
|
||||
(setf (car lines) match)
|
||||
))
|
||||
(setq prev-match match)
|
||||
(when detailed-info
|
||||
(setq match (propertize match 'ac-clang-help detailed-info)))
|
||||
(push match lines))))
|
||||
lines))
|
||||
|
||||
|
||||
(defconst ac-clang-error-buffer-name "*clang error*")
|
||||
|
||||
(defun ac-clang-handle-error (res args)
|
||||
(goto-char (point-min))
|
||||
(let* ((buf (get-buffer-create ac-clang-error-buffer-name))
|
||||
(cmd (concat ac-clang-complete-executable " " (mapconcat 'identity args " ")))
|
||||
(pattern (format ac-clang-completion-pattern ""))
|
||||
(err (if (re-search-forward pattern nil t)
|
||||
(buffer-substring-no-properties (point-min)
|
||||
(1- (match-beginning 0)))
|
||||
;; Warn the user more agressively if no match was found.
|
||||
(message "clang failed with error %d:\n%s" res cmd)
|
||||
(buffer-string))))
|
||||
|
||||
(with-current-buffer buf
|
||||
(let ((inhibit-read-only t))
|
||||
(erase-buffer)
|
||||
(insert (current-time-string)
|
||||
(format "\nclang failed with error %d:\n" res)
|
||||
cmd "\n\n")
|
||||
(insert err)
|
||||
(setq buffer-read-only t)
|
||||
(goto-char (point-min))))))
|
||||
|
||||
(defun ac-clang-call-process (prefix &rest args)
|
||||
(let ((buf (get-buffer-create "*clang-output*"))
|
||||
res)
|
||||
(with-current-buffer buf (erase-buffer))
|
||||
(setq res (apply 'call-process-region (point-min) (point-max)
|
||||
ac-clang-complete-executable nil buf nil args))
|
||||
(with-current-buffer buf
|
||||
(unless (eq 0 res)
|
||||
(ac-clang-handle-error res args))
|
||||
;; Still try to get any useful input.
|
||||
(ac-clang-parse-output prefix))))
|
||||
|
||||
|
||||
(defsubst ac-clang-create-position-string (pos)
|
||||
(save-excursion
|
||||
(goto-char pos)
|
||||
(format "row:%d\ncolumn:%d\n"
|
||||
(line-number-at-pos)
|
||||
(1+ (- (point) (line-beginning-position))))))
|
||||
|
||||
(defsubst ac-clang-lang-option ()
|
||||
(or (and ac-clang-lang-option-function
|
||||
(funcall ac-clang-lang-option-function))
|
||||
(cond ((eq major-mode 'c++-mode)
|
||||
"c++")
|
||||
((eq major-mode 'c-mode)
|
||||
"c")
|
||||
((eq major-mode 'objc-mode)
|
||||
(cond ((string= "m" (file-name-extension (buffer-file-name)))
|
||||
"objective-c")
|
||||
(t
|
||||
"objective-c++")))
|
||||
(t
|
||||
"c++"))))
|
||||
|
||||
(defsubst ac-clang-build-complete-args ()
|
||||
(append '("-cc1" "-fsyntax-only")
|
||||
(list "-x" (ac-clang-lang-option))
|
||||
ac-clang-cflags
|
||||
(when (stringp ac-clang-prefix-header)
|
||||
(list "-include-pch" (expand-file-name ac-clang-prefix-header)))))
|
||||
|
||||
|
||||
(defsubst ac-clang-clean-document (s)
|
||||
(when s
|
||||
(setq s (replace-regexp-in-string "<#\\|#>\\|\\[#" "" s))
|
||||
(setq s (replace-regexp-in-string "#\\]" " " s)))
|
||||
s)
|
||||
|
||||
(defun ac-clang-document (item)
|
||||
(if (stringp item)
|
||||
(let (s)
|
||||
(setq s (get-text-property 0 'ac-clang-help item))
|
||||
(ac-clang-clean-document s)))
|
||||
;; (popup-item-property item 'ac-clang-help)
|
||||
)
|
||||
|
||||
|
||||
(defface ac-clang-candidate-face
|
||||
'((t (:background "lightgray" :foreground "navy")))
|
||||
"Face for clang candidate"
|
||||
:group 'auto-complete)
|
||||
|
||||
(defface ac-clang-selection-face
|
||||
'((t (:background "navy" :foreground "white")))
|
||||
"Face for the clang selected candidate."
|
||||
:group 'auto-complete)
|
||||
|
||||
(defsubst ac-clang-in-string/comment ()
|
||||
"Return non-nil if point is in a literal (a comment or string)."
|
||||
(nth 8 (syntax-ppss)))
|
||||
|
||||
|
||||
(defvar ac-clang-template-start-point nil)
|
||||
(defvar ac-clang-template-candidates (list "ok" "no" "yes:)"))
|
||||
|
||||
(defun ac-clang-action ()
|
||||
(interactive)
|
||||
;; (ac-last-quick-help)
|
||||
(let ((help (ac-clang-clean-document (get-text-property 0 'ac-clang-help (cdr ac-last-completion))))
|
||||
(raw-help (get-text-property 0 'ac-clang-help (cdr ac-last-completion)))
|
||||
(candidates (list)) ss fn args (ret-t "") ret-f)
|
||||
(setq ss (split-string raw-help "\n"))
|
||||
(dolist (s ss)
|
||||
(when (string-match "\\[#\\(.*\\)#\\]" s)
|
||||
(setq ret-t (match-string 1 s)))
|
||||
(setq s (replace-regexp-in-string "\\[#.*?#\\]" "" s))
|
||||
(cond ((string-match "^\\([^(<]*\\)\\(:.*\\)" s)
|
||||
(setq fn (match-string 1 s)
|
||||
args (match-string 2 s))
|
||||
(push (propertize (ac-clang-clean-document args) 'ac-clang-help ret-t
|
||||
'raw-args args) candidates))
|
||||
((string-match "^\\([^(]*\\)\\((.*)\\)" s)
|
||||
(setq fn (match-string 1 s)
|
||||
args (match-string 2 s))
|
||||
(push (propertize (ac-clang-clean-document args) 'ac-clang-help ret-t
|
||||
'raw-args args) candidates)
|
||||
(when (string-match "\{#" args)
|
||||
(setq args (replace-regexp-in-string "\{#.*#\}" "" args))
|
||||
(push (propertize (ac-clang-clean-document args) 'ac-clang-help ret-t
|
||||
'raw-args args) candidates))
|
||||
(when (string-match ", \\.\\.\\." args)
|
||||
(setq args (replace-regexp-in-string ", \\.\\.\\." "" args))
|
||||
(push (propertize (ac-clang-clean-document args) 'ac-clang-help ret-t
|
||||
'raw-args args) candidates)))
|
||||
((string-match "^\\([^(]*\\)(\\*)\\((.*)\\)" ret-t) ;; check whether it is a function ptr
|
||||
(setq ret-f (match-string 1 ret-t)
|
||||
args (match-string 2 ret-t))
|
||||
(push (propertize args 'ac-clang-help ret-f 'raw-args "") candidates)
|
||||
(when (string-match ", \\.\\.\\." args)
|
||||
(setq args (replace-regexp-in-string ", \\.\\.\\." "" args))
|
||||
(push (propertize args 'ac-clang-help ret-f 'raw-args "") candidates)))))
|
||||
(cond (candidates
|
||||
(setq candidates (delete-dups candidates))
|
||||
(setq candidates (nreverse candidates))
|
||||
(setq ac-clang-template-candidates candidates)
|
||||
(setq ac-clang-template-start-point (point))
|
||||
(ac-complete-clang-template)
|
||||
|
||||
(unless (cdr candidates) ;; unless length > 1
|
||||
(message (replace-regexp-in-string "\n" " ; " help))))
|
||||
(t
|
||||
(message (replace-regexp-in-string "\n" " ; " help))))))
|
||||
|
||||
(defun ac-clang-prefix ()
|
||||
(or (ac-prefix-symbol)
|
||||
(let ((c (char-before)))
|
||||
(when (or (eq ?\. c)
|
||||
;; ->
|
||||
(and (eq ?> c)
|
||||
(eq ?- (char-before (1- (point)))))
|
||||
;; ::
|
||||
(and (eq ?: c)
|
||||
(eq ?: (char-before (1- (point))))))
|
||||
(point)))))
|
||||
|
||||
(defun ac-clang-same-count-in-string (c1 c2 s)
|
||||
(let ((count 0) (cur 0) (end (length s)) c)
|
||||
(while (< cur end)
|
||||
(setq c (aref s cur))
|
||||
(cond ((eq c1 c)
|
||||
(setq count (1+ count)))
|
||||
((eq c2 c)
|
||||
(setq count (1- count))))
|
||||
(setq cur (1+ cur)))
|
||||
(= count 0)))
|
||||
|
||||
(defun ac-clang-split-args (s)
|
||||
(let ((sl (split-string s ", *")))
|
||||
(cond ((string-match "<\\|(" s)
|
||||
(let ((res (list)) (pre "") subs)
|
||||
(while sl
|
||||
(setq subs (pop sl))
|
||||
(unless (string= pre "")
|
||||
(setq subs (concat pre ", " subs))
|
||||
(setq pre ""))
|
||||
(cond ((and (ac-clang-same-count-in-string ?\< ?\> subs)
|
||||
(ac-clang-same-count-in-string ?\( ?\) subs))
|
||||
;; (cond ((ac-clang-same-count-in-string ?\< ?\> subs)
|
||||
(push subs res))
|
||||
(t
|
||||
(setq pre subs))))
|
||||
(nreverse res)))
|
||||
(t
|
||||
sl))))
|
||||
|
||||
|
||||
(defun ac-clang-template-candidate ()
|
||||
ac-clang-template-candidates)
|
||||
|
||||
(defun ac-clang-template-action ()
|
||||
(interactive)
|
||||
(unless (null ac-clang-template-start-point)
|
||||
(let ((pos (point)) sl (snp "")
|
||||
(s (get-text-property 0 'raw-args (cdr ac-last-completion))))
|
||||
(cond ((string= s "")
|
||||
;; function ptr call
|
||||
(setq s (cdr ac-last-completion))
|
||||
(setq s (replace-regexp-in-string "^(\\|)$" "" s))
|
||||
(setq sl (ac-clang-split-args s))
|
||||
(cond ((featurep 'yasnippet)
|
||||
(dolist (arg sl)
|
||||
(setq snp (concat snp ", ${" arg "}")))
|
||||
(condition-case nil
|
||||
(yas/expand-snippet (concat "(" (substring snp 2) ")")
|
||||
ac-clang-template-start-point pos) ;; 0.6.1c
|
||||
(error
|
||||
;; try this one:
|
||||
(ignore-errors (yas/expand-snippet
|
||||
ac-clang-template-start-point pos
|
||||
(concat "(" (substring snp 2) ")"))) ;; work in 0.5.7
|
||||
)))
|
||||
((featurep 'snippet)
|
||||
(delete-region ac-clang-template-start-point pos)
|
||||
(dolist (arg sl)
|
||||
(setq snp (concat snp ", $${" arg "}")))
|
||||
(snippet-insert (concat "(" (substring snp 2) ")")))
|
||||
(t
|
||||
(message "Dude! You are too out! Please install a yasnippet or a snippet script:)"))))
|
||||
(t
|
||||
(unless (string= s "()")
|
||||
(setq s (replace-regexp-in-string "{#" "" s))
|
||||
(setq s (replace-regexp-in-string "#}" "" s))
|
||||
(cond ((featurep 'yasnippet)
|
||||
(setq s (replace-regexp-in-string "<#" "${" s))
|
||||
(setq s (replace-regexp-in-string "#>" "}" s))
|
||||
(setq s (replace-regexp-in-string ", \\.\\.\\." "}, ${..." s))
|
||||
(condition-case nil
|
||||
(yas/expand-snippet s ac-clang-template-start-point pos) ;; 0.6.1c
|
||||
(error
|
||||
;; try this one:
|
||||
(ignore-errors (yas/expand-snippet ac-clang-template-start-point pos s)) ;; work in 0.5.7
|
||||
)))
|
||||
((featurep 'snippet)
|
||||
(delete-region ac-clang-template-start-point pos)
|
||||
(setq s (replace-regexp-in-string "<#" "$${" s))
|
||||
(setq s (replace-regexp-in-string "#>" "}" s))
|
||||
(setq s (replace-regexp-in-string ", \\.\\.\\." "}, $${..." s))
|
||||
(snippet-insert s))
|
||||
(t
|
||||
(message "Dude! You are too out! Please install a yasnippet or a snippet script:)")))))))))
|
||||
|
||||
|
||||
(defun ac-clang-template-prefix ()
|
||||
ac-clang-template-start-point)
|
||||
|
||||
|
||||
;; This source shall only be used internally.
|
||||
(ac-define-source clang-template
|
||||
'((candidates . ac-clang-template-candidate)
|
||||
(prefix . ac-clang-template-prefix)
|
||||
(requires . 0)
|
||||
(action . ac-clang-template-action)
|
||||
(document . ac-clang-document)
|
||||
(cache)
|
||||
(symbol . "t")))
|
||||
|
||||
|
||||
;;;
|
||||
;;; Rest of the file is related to async.
|
||||
;;;
|
||||
|
||||
(defvar ac-clang-status 'idle)
|
||||
(defvar ac-clang-current-candidate nil)
|
||||
(defvar ac-clang-completion-process nil)
|
||||
(defvar ac-clang-saved-prefix "")
|
||||
|
||||
(make-variable-buffer-local 'ac-clang-status)
|
||||
(make-variable-buffer-local 'ac-clang-current-candidate)
|
||||
(make-variable-buffer-local 'ac-clang-completion-process)
|
||||
|
||||
;;;
|
||||
;;; Functions to speak with the clang-complete process
|
||||
;;;
|
||||
|
||||
(defun ac-clang-send-source-code (proc)
|
||||
(save-restriction
|
||||
(widen)
|
||||
(process-send-string
|
||||
proc (format "source_length:%d\n"
|
||||
(length (string-as-unibyte ; fix non-ascii character problem
|
||||
(buffer-substring-no-properties (point-min) (point-max)))
|
||||
)))
|
||||
(process-send-string proc (buffer-substring-no-properties (point-min) (point-max)))
|
||||
(process-send-string proc "\n\n")))
|
||||
|
||||
(defun ac-clang-send-reparse-request (proc)
|
||||
(if (eq (process-status proc) 'run)
|
||||
(save-restriction
|
||||
(widen)
|
||||
(process-send-string proc "SOURCEFILE\n")
|
||||
(ac-clang-send-source-code proc)
|
||||
(process-send-string proc "REPARSE\n\n"))))
|
||||
|
||||
(defun ac-clang-send-completion-request (proc)
|
||||
(save-restriction
|
||||
(widen)
|
||||
(process-send-string proc "COMPLETION\n")
|
||||
(process-send-string proc (ac-clang-create-position-string (- (point) (length ac-prefix))))
|
||||
(ac-clang-send-source-code proc)))
|
||||
|
||||
(defun ac-clang-send-syntaxcheck-request (proc)
|
||||
(save-restriction
|
||||
(widen)
|
||||
(process-send-string proc "SYNTAXCHECK\n")
|
||||
(ac-clang-send-source-code proc)))
|
||||
|
||||
(defun ac-clang-send-cmdline-args (proc)
|
||||
;; send message head and num_args
|
||||
(process-send-string proc "CMDLINEARGS\n")
|
||||
(process-send-string
|
||||
proc (format "num_args:%d\n" (length (ac-clang-build-complete-args))))
|
||||
|
||||
;; send arguments
|
||||
(mapc
|
||||
(lambda (arg)
|
||||
(process-send-string proc (format "%s " arg)))
|
||||
(ac-clang-build-complete-args))
|
||||
(process-send-string proc "\n"))
|
||||
|
||||
(defun ac-clang-update-cmdlineargs ()
|
||||
(interactive)
|
||||
(if (listp ac-clang-cflags)
|
||||
(ac-clang-send-cmdline-args ac-clang-completion-process)
|
||||
(message "`ac-clang-cflags' should be a list of strings")))
|
||||
|
||||
(defun ac-clang-send-shutdown-command (proc)
|
||||
(if (eq (process-status proc) 'run)
|
||||
(process-send-string proc "SHUTDOWN\n"))
|
||||
)
|
||||
|
||||
|
||||
(defun ac-clang-append-process-output-to-process-buffer (process output)
|
||||
"Append process output to the process buffer."
|
||||
(with-current-buffer (process-buffer process)
|
||||
(save-excursion
|
||||
;; Insert the text, advancing the process marker.
|
||||
(goto-char (process-mark process))
|
||||
(insert output)
|
||||
(set-marker (process-mark process) (point)))
|
||||
(goto-char (process-mark process))))
|
||||
|
||||
|
||||
;;
|
||||
;; Receive server responses (completion candidates) and fire auto-complete
|
||||
;;
|
||||
(defun ac-clang-parse-completion-results (proc)
|
||||
(with-current-buffer (process-buffer proc)
|
||||
(ac-clang-parse-output ac-clang-saved-prefix)))
|
||||
|
||||
(defun ac-clang-filter-output (proc string)
|
||||
(ac-clang-append-process-output-to-process-buffer proc string)
|
||||
(if (string= (substring string -1 nil) "$")
|
||||
(case ac-clang-status
|
||||
(preempted
|
||||
(setq ac-clang-status 'idle)
|
||||
(ac-start)
|
||||
(ac-update))
|
||||
|
||||
(otherwise
|
||||
(setq ac-clang-current-candidate (ac-clang-parse-completion-results proc))
|
||||
;; (message "ac-clang results arrived")
|
||||
(setq ac-clang-status 'acknowledged)
|
||||
(ac-start :force-init t)
|
||||
(ac-update)
|
||||
(setq ac-clang-status 'idle)))))
|
||||
|
||||
|
||||
(defun ac-clang-candidate ()
|
||||
(case ac-clang-status
|
||||
(idle
|
||||
;; (message "ac-clang-candidate triggered - fetching candidates...")
|
||||
(setq ac-clang-saved-prefix ac-prefix)
|
||||
|
||||
;; NOTE: although auto-complete would filter the result for us, but when there's
|
||||
;; a HUGE number of candidates avaliable it would cause auto-complete to
|
||||
;; block. So we filter it uncompletely here, then let auto-complete filter
|
||||
;; the rest later, this would ease the feeling of being "stalled" at some degree.
|
||||
|
||||
;; (message "saved prefix: %s" ac-clang-saved-prefix)
|
||||
(with-current-buffer (process-buffer ac-clang-completion-process)
|
||||
(erase-buffer))
|
||||
(setq ac-clang-status 'wait)
|
||||
(setq ac-clang-current-candidate nil)
|
||||
|
||||
;; send completion request
|
||||
(ac-clang-send-completion-request ac-clang-completion-process)
|
||||
ac-clang-current-candidate)
|
||||
|
||||
(wait
|
||||
;; (message "ac-clang-candidate triggered - wait")
|
||||
ac-clang-current-candidate)
|
||||
|
||||
(acknowledged
|
||||
;; (message "ac-clang-candidate triggered - ack")
|
||||
(setq ac-clang-status 'idle)
|
||||
ac-clang-current-candidate)
|
||||
|
||||
(preempted
|
||||
;; (message "clang-async is preempted by a critical request")
|
||||
nil)))
|
||||
|
||||
|
||||
;; Syntax checking with flymake
|
||||
|
||||
(defun ac-clang-flymake-process-sentinel ()
|
||||
(interactive)
|
||||
(setq flymake-err-info flymake-new-err-info)
|
||||
(setq flymake-new-err-info nil)
|
||||
(setq flymake-err-info
|
||||
(flymake-fix-line-numbers
|
||||
flymake-err-info 1 (flymake-count-lines)))
|
||||
(flymake-delete-own-overlays)
|
||||
(flymake-highlight-err-lines flymake-err-info))
|
||||
|
||||
(defun ac-clang-flymake-process-filter (process output)
|
||||
(ac-clang-append-process-output-to-process-buffer process output)
|
||||
(flymake-log 3 "received %d byte(s) of output from process %d"
|
||||
(length output) (process-id process))
|
||||
(flymake-parse-output-and-residual output)
|
||||
(when (string= (substring output -1 nil) "$")
|
||||
(flymake-parse-residual)
|
||||
(ac-clang-flymake-process-sentinel)
|
||||
(setq ac-clang-status 'idle)
|
||||
(set-process-filter ac-clang-completion-process 'ac-clang-filter-output)))
|
||||
|
||||
(defun ac-clang-syntax-check ()
|
||||
(interactive)
|
||||
(when (eq ac-clang-status 'idle)
|
||||
(with-current-buffer (process-buffer ac-clang-completion-process)
|
||||
(erase-buffer))
|
||||
(setq ac-clang-status 'wait)
|
||||
(set-process-filter ac-clang-completion-process 'ac-clang-flymake-process-filter)
|
||||
(ac-clang-send-syntaxcheck-request ac-clang-completion-process)))
|
||||
|
||||
|
||||
|
||||
(defun ac-clang-shutdown-process ()
|
||||
(if ac-clang-completion-process
|
||||
(ac-clang-send-shutdown-command ac-clang-completion-process)))
|
||||
|
||||
(defun ac-clang-reparse-buffer ()
|
||||
(if ac-clang-completion-process
|
||||
(ac-clang-send-reparse-request ac-clang-completion-process)))
|
||||
|
||||
|
||||
|
||||
(defun ac-clang-async-autocomplete-autotrigger ()
|
||||
(interactive)
|
||||
(if ac-clang-async-do-autocompletion-automatically
|
||||
(ac-clang-async-preemptive)
|
||||
(self-insert-command 1)))
|
||||
|
||||
|
||||
|
||||
(defun ac-clang-async-preemptive ()
|
||||
(interactive)
|
||||
(self-insert-command 1)
|
||||
(if (eq ac-clang-status 'idle)
|
||||
(ac-start)
|
||||
(setq ac-clang-status 'preempted)))
|
||||
|
||||
(defun ac-clang-launch-completion-process ()
|
||||
(let ((filename (buffer-file-name)))
|
||||
(if filename
|
||||
(ac-clang-launch-completion-process-with-file filename))))
|
||||
|
||||
(defun ac-clang-launch-completion-process-with-file (filename)
|
||||
(setq ac-clang-completion-process
|
||||
(let ((process-connection-type nil))
|
||||
(apply 'start-process
|
||||
"clang-complete" "*clang-complete*"
|
||||
ac-clang-complete-executable
|
||||
(append (ac-clang-build-complete-args)
|
||||
(list filename)))))
|
||||
|
||||
(set-process-filter ac-clang-completion-process 'ac-clang-filter-output)
|
||||
(set-process-query-on-exit-flag ac-clang-completion-process nil)
|
||||
;; Pre-parse source code.
|
||||
(ac-clang-send-reparse-request ac-clang-completion-process)
|
||||
|
||||
(add-hook 'kill-buffer-hook 'ac-clang-shutdown-process nil t)
|
||||
(add-hook 'before-revert-hook 'ac-clang-shutdown-process nil t)
|
||||
(add-hook 'before-save-hook 'ac-clang-reparse-buffer)
|
||||
|
||||
(local-set-key (kbd ".") 'ac-clang-async-autocomplete-autotrigger)
|
||||
(local-set-key (kbd ":") 'ac-clang-async-autocomplete-autotrigger)
|
||||
(local-set-key (kbd ">") 'ac-clang-async-autocomplete-autotrigger))
|
||||
|
||||
|
||||
(ac-define-source clang-async
|
||||
'((candidates . ac-clang-candidate)
|
||||
(candidate-face . ac-clang-candidate-face)
|
||||
(selection-face . ac-clang-selection-face)
|
||||
(prefix . ac-clang-prefix)
|
||||
(requires . 0)
|
||||
(document . ac-clang-document)
|
||||
(action . ac-clang-action)
|
||||
(cache)
|
||||
(symbol . "c")))
|
||||
|
||||
;;; auto-complete-clang-async.el ends here
|
Binary file not shown.
@ -1,43 +0,0 @@
|
||||
;;; autopair-autoloads.el --- automatically extracted autoloads
|
||||
;;
|
||||
;;; Code:
|
||||
(add-to-list 'load-path (or (file-name-directory #$) (car load-path)))
|
||||
|
||||
;;;### (autoloads nil "autopair" "autopair.el" (22209 42920 167632
|
||||
;;;;;; 0))
|
||||
;;; Generated autoloads from autopair.el
|
||||
|
||||
(autoload 'autopair-mode "autopair" "\
|
||||
Automagically pair braces and quotes like in TextMate.
|
||||
|
||||
\(fn &optional ARG)" t nil)
|
||||
|
||||
(defvar autopair-global-mode nil "\
|
||||
Non-nil if Autopair-Global mode is enabled.
|
||||
See the command `autopair-global-mode' for a description of this minor mode.
|
||||
Setting this variable directly does not take effect;
|
||||
either customize it (see the info node `Easy Customization')
|
||||
or call the function `autopair-global-mode'.")
|
||||
|
||||
(custom-autoload 'autopair-global-mode "autopair" nil)
|
||||
|
||||
(autoload 'autopair-global-mode "autopair" "\
|
||||
Toggle Autopair mode in all buffers.
|
||||
With prefix ARG, enable Autopair-Global mode if ARG is positive;
|
||||
otherwise, disable it. If called from Lisp, enable the mode if
|
||||
ARG is omitted or nil.
|
||||
|
||||
Autopair mode is enabled in all buffers where
|
||||
`autopair-on' would do it.
|
||||
See `autopair-mode' for more information on Autopair mode.
|
||||
|
||||
\(fn &optional ARG)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;; Local Variables:
|
||||
;; version-control: never
|
||||
;; no-byte-compile: t
|
||||
;; no-update-autoloads: t
|
||||
;; End:
|
||||
;;; autopair-autoloads.el ends here
|
@ -1,11 +0,0 @@
|
||||
;;; autopair-autoloads.el --- automatically extracted autoloads
|
||||
;;
|
||||
;;; Code:
|
||||
(add-to-list 'load-path (or (file-name-directory #$) (car load-path)))
|
||||
|
||||
;; Local Variables:
|
||||
;; version-control: never
|
||||
;; no-byte-compile: t
|
||||
;; no-update-autoloads: t
|
||||
;; End:
|
||||
;;; autopair-autoloads.el ends here
|
@ -1 +0,0 @@
|
||||
(define-package "autopair" "20140825.427" "Automagically pair braces and quotes like TextMate" '((cl-lib "0.3")) :url "http://autopair.googlecode.com" :keywords '("convenience" "emulations"))
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -1,4 +0,0 @@
|
||||
((nil . ((indent-tabs-mode . nil)
|
||||
(fill-column . 80)
|
||||
(sentence-end-double-space . t)
|
||||
(emacs-lisp-docstring-fill-column . 75))))
|
@ -1,5 +0,0 @@
|
||||
.travis.yml
|
||||
.gitignore
|
||||
Makefile
|
||||
test/
|
||||
company-tests.el
|
@ -1,310 +0,0 @@
|
||||
2015-03-04 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
Merge commit 'e085a333867959a1b36015a3ad8e12e5bd6550d9' from company
|
||||
|
||||
2015-02-04 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
Merge commit '3e70e12bd942bbd0acac4963b5caca63756ad784' from company
|
||||
|
||||
2015-02-02 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
Merge commit 'a015fb350abe50d250e3e7a9c3c762397326977f' from company
|
||||
|
||||
2015-01-23 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
Merge commit 'a4ac0dead8e9cb440c1f8aec9141d6c64bad4933' from company
|
||||
|
||||
2015-01-15 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
* packages/company/test/clang-tests.el: Add copyright notice
|
||||
|
||||
2015-01-13 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
Merge commit 'd12ddaa05f582ecc00e74bc42fd46652153ec7a6' from company
|
||||
|
||||
2015-01-13 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
Merge commit 'eb0d8d9e687e1364098f9abc6f9281fcbc0d3abd' from company
|
||||
|
||||
2014-10-28 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
Merge commit 'd3fcbefcf56d2caad172e22f24de95397c635bf2' from company
|
||||
|
||||
2014-10-15 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
* packages/company/company-xcode.el (company-xcode-fetch): Avoid
|
||||
add-to-list on local var.
|
||||
* packages/company/company.el (company--window-height)
|
||||
(company--window-width): Move before first use.
|
||||
|
||||
2014-10-15 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
Merge commit '60d4c09c982a1c562a70cd6aa705f47ab3badcfb' from company
|
||||
|
||||
2014-09-14 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
Merge commit 'fa4ba155a3e22ddc4b8bc33fcbf8cc69ef8f0043' from company
|
||||
|
||||
2014-09-13 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
Merge commit '2ef6263c65a109b4d36503e6484fdbf4cb307d0f' from company
|
||||
|
||||
2014-08-27 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
Merge commit 'f4ffe2b47cf6854ff3bc3ca1717efe1258c01547' from company
|
||||
|
||||
2014-07-26 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
Merge commit 'b1d019a4c815ac8bdc240d69eaa74eb4e34640e8' from
|
||||
company-master
|
||||
|
||||
2014-07-01 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
Merge commit '7c14dedc79bf0c6eaad5bf50b80ea80dd721afdc' from company
|
||||
|
||||
Conflicts:
|
||||
packages/company/company-pysmell.el
|
||||
|
||||
2014-06-14 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
* company/company-capf.el: Don't ignore things like semantic-capf.
|
||||
|
||||
2014-04-19 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
Merge commit '51c140ca9ee32d27cacc7b2b07d4539bf98ae575' from
|
||||
company-master
|
||||
|
||||
Conflicts:
|
||||
packages/company/company-pysmell.el
|
||||
|
||||
2014-03-25 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
Merge commit '4a7995ff69b25990dc520ed9e466dfbcdb7eafc8' from company
|
||||
|
||||
2014-03-19 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
Merge commit 'fec7c0b4a8651160c5d759cc6703b2c45852d5bb'
|
||||
|
||||
2014-03-18 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
Merge commit '7be4321260f0c73ef4c3cadc646f6bb496650253' from company
|
||||
|
||||
2014-02-18 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
Merge commit '119822078ee3024c2d27017d45ef4578fa36040f' from company
|
||||
|
||||
2014-02-03 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
Merge commit '67ab56a5469f16652e73667ec3b4f76ff6befee6' from company
|
||||
|
||||
2014-01-25 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
Merge commit '8dc8f9525714db66f659a2a51322345068764bd3' from company
|
||||
|
||||
Conflicts:
|
||||
packages/company/company-capf.el
|
||||
|
||||
2014-01-24 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
* company-capf.el (company--capf-data): Don't get confused by lambda
|
||||
exps.
|
||||
|
||||
2014-01-20 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
Merge commit '2badcc6227a88e1aba288f442af5f4e1ce55d366' from company
|
||||
|
||||
2014-01-15 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
Merge commit '8b4d7da0d6aa1e24379fe5ace5bd2705352ea07e' from company
|
||||
|
||||
2014-01-14 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
Merge commit '67a96dbbfe645b64291ed62eab6f1eb391a834e0' from company
|
||||
|
||||
Conflicts:
|
||||
packages/company/company-elisp.el
|
||||
packages/company/company-oddmuse.el
|
||||
|
||||
2014-01-13 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
* packages/company/company-etags.el: Require `cl' for `case'.
|
||||
* packages/company/company-oddmuse.el: Avoid `eval-when' before
|
||||
requiring `cl'.
|
||||
* packages/company/company-elisp.el (company-elisp): Simplify.
|
||||
|
||||
2013-10-06 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
Sync from company/master
|
||||
|
||||
2013-08-29 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
* packages/company/company-capf.el (company-capf): Add preliminary
|
||||
support for doc-buffer, meta, location, and require-match.
|
||||
|
||||
2013-08-21 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
* packages/company/company-cmake.el: Fix up copyright. Require CL.
|
||||
* packages/company/company-template.el
|
||||
(company-template--buffer-templates): Declare before first use.
|
||||
* packages/company/company-eclim.el (json-array-type): Declare
|
||||
json-array-type.
|
||||
(company-eclim--candidates): Remove unused var `project-name'.
|
||||
|
||||
2013-08-21 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
Sync from company/master
|
||||
|
||||
2013-08-14 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
Mark merge point of company.
|
||||
|
||||
2013-06-27 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
* GNUmakefile: Rename from Makefile. Add targets for in-place use.
|
||||
(all, all-in-place): New targets.
|
||||
* admin/archive-contents.el (archive--simple-package-p): Ignore
|
||||
autosave files.
|
||||
(archive--refresh-pkg-file): New function.
|
||||
(archive--write-pkg-file): Print with ' and ` shorthands.
|
||||
* packages/company/company-pysmell.el: Don't require pysmell during
|
||||
compile.
|
||||
* packages/muse/htmlize-hack.el: Don't require htmlize during compile.
|
||||
* packages/shen-mode/shen-mode.el (shen-functions): Define during
|
||||
compile.
|
||||
* smart-operator/smart-operator.el (smart-operator-insert-1): Use
|
||||
pcase.
|
||||
|
||||
2013-05-26 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
company: Release 0.6.10
|
||||
|
||||
* Plays nicer with `org-indent-mode`.
|
||||
* Works in horizontally scrolled windows.
|
||||
|
||||
Git commit 764d2aa4ba50081adf69408e62d4863905b68b7f
|
||||
|
||||
2013-05-10 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
company: Release 0.6.9
|
||||
|
||||
* `company-capf` respects `:exit-function` completion property.
|
||||
* `company-backends`: `prefix` command can return `t` in the cdr.
|
||||
* `company-clang-begin-after-member-access`: New option.
|
||||
* Mouse click outside the tooltip aborts completion.
|
||||
* `company-clang` uses standard input to pass the contents of current
|
||||
buffer to
|
||||
Clang 2.9+, otherwise saves the buffer and passes the path to the
|
||||
file.
|
||||
* `company-clang-auto-save` option has been removed.
|
||||
* Better interaction with `outline-minor-mode`.
|
||||
* `company-dabbrev-code` supports all `prog-mode` derivatives.
|
||||
|
||||
Git commit 4c735454d91f9674da0ecea950504888b1e10ff7
|
||||
|
||||
2013-04-27 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
* company.el (company-capf): Add support for `sorted' and
|
||||
`post-completion'.
|
||||
(company--capf-data): New function.
|
||||
(company-backend): Declare before first use.
|
||||
(company-require-match-p): Only call company-require-match is needed.
|
||||
(company--continue-failed): Don't use backward-delete-char
|
||||
non-interactively.
|
||||
(company-search-assert-enabled): Demote it, since it comes too late to
|
||||
be inlined.
|
||||
(company-begin-with): Use a lexical closure, so the code is
|
||||
byte-compiled.
|
||||
(company--replacement-string, company--create-lines)
|
||||
(company-pseudo-tooltip-edit, company-doc-buffer): Silence the
|
||||
byte-compiler.
|
||||
|
||||
2013-04-16 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
Release 0.6.8
|
||||
|
||||
* `company-auto-complete` is disabled by default.
|
||||
* `company-auto-complete-chars` default value includes fewer syntax
|
||||
classes.
|
||||
* In expanded function calls, arguments skipped by the user default to
|
||||
"argN".
|
||||
* `company-eclim` and `company-clang` do not strip argument types from
|
||||
fields.
|
||||
* `company-clang` expands function calls for all three modes now.
|
||||
* `company-clang` supports `c++-mode` by default.
|
||||
|
||||
Git commit 92ac3d0ef663bca26abbda33cc20a02a58b1c328
|
||||
|
||||
2013-04-05 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
company: Release 0.6.7
|
||||
|
||||
* Two `company-elisp` tweaks.
|
||||
|
||||
Git commit 8dceda389115b397de48becc4b68a64f4dc4bbab
|
||||
|
||||
2013-04-01 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
company: Release 0.6.6
|
||||
|
||||
## 2013-04-01 (0.6.6)
|
||||
|
||||
* `company-elisp` doesn't offer completions when typing the name and
|
||||
the arguments of a new function or macro definition, allowing to
|
||||
fall back to other back-ends like `company-dabbrev-code`.
|
||||
|
||||
## 2013-03-30 (0.6.5)
|
||||
|
||||
* Fixed keybindings when running in a terminal.
|
||||
* `company-elisp-show-locals-first`: new customizable variable.
|
||||
* `company-elisp` shows more accurate and comprehensive candidates
|
||||
list.
|
||||
|
||||
## 2013-03-26 (0.6.4)
|
||||
|
||||
* `company-eclim` shows valid completions after an opening paren.
|
||||
* Expanded template does not get removed until the point leaves it.
|
||||
After your input the last argument in a method call expanded by
|
||||
`company-eclim`, you can press `<tab>` once more, to jump after the
|
||||
closing paren. No other bundled back-ends are affected.
|
||||
|
||||
## 2013-03-25 (0.6.3)
|
||||
|
||||
* New tooltip face colors used on themes with light background.
|
||||
* Pseudo-tooltip stays up-to-date when text is inserted after the
|
||||
point.
|
||||
* Fixed `company-require-match` mechanics.
|
||||
|
||||
2013-03-24 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
company: Release 0.6.2
|
||||
|
||||
2013-03-23 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
company: Release 0.6.1
|
||||
|
||||
2013-03-21 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
company: Remove angle brackets from README
|
||||
|
||||
2013-03-19 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
company: Update pkg.el and summary string
|
||||
|
||||
2013-03-19 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
company-tests.el: add copyright boilerplate
|
||||
|
||||
2013-03-19 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
company-mode: Release 0.6
|
||||
|
||||
2011-08-01 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
* company/*.el: Fix case misunderstanding. Use checkdoc.
|
||||
* company/company.el (company-capf): First cut at making Company use
|
||||
completion-at-point-functions.
|
||||
|
||||
2011-06-30 Chong Yidong <cyd@stupidchicken.com>
|
||||
|
||||
Remove version numbers in packages/ directory
|
||||
|
@ -1,329 +0,0 @@
|
||||
# History of user-visible changes
|
||||
|
||||
## 2015-02-02 (0.8.10)
|
||||
|
||||
* New variable `company-lighter-base`.
|
||||
* Better tracking of the current selection.
|
||||
* Pressing `M-0`...`M-9` works in the search mode.
|
||||
* Pressing `<up>` or `<down>` doesn't quit the search mode.
|
||||
|
||||
## 2015-01-23 (0.8.9)
|
||||
|
||||
* New commands `company-next-page` and `company-previous-page`, remapping
|
||||
`scroll-up-command` and `scroll-down-command` during completion.
|
||||
|
||||
## 2015-01-13 (0.8.8)
|
||||
|
||||
* Pressing `M-n` or `M-p` doesn't quit the search mode.
|
||||
* New command `company-complete-common-or-cycle`. No default binding.
|
||||
* `company-search-toggle-filtering` replaced `company-search-kill-others`.
|
||||
* Quitting the search mode resets the filtering.
|
||||
* Pressing `backspace` in the search mode deletes the character at the end of
|
||||
the search string.
|
||||
* `company-semantic` displays function arguments as annotations.
|
||||
* New user option, `company-bbdb-modes`.
|
||||
* `company-show-numbers` and `company-complete-number` now use visual numbering
|
||||
of the candidates, taking into account only the ones currently displayed.
|
||||
* `company-complete-number` can be bound to keypad numbers directly, with or
|
||||
without modifiers.
|
||||
* `company-cmake` expands `<LANG>` and `<CONFIG>` placeholders inside variable
|
||||
names.
|
||||
|
||||
## 2014-10-15 (0.8.6)
|
||||
|
||||
* `company-clang` and `company-template-c-like-templatify` support templated
|
||||
functions and arguments.
|
||||
* `company-dabbrev` ignores "uninteresting" buffers by default. Depends on the
|
||||
new user option, `company-dabbrev-ignore-buffers`.
|
||||
* `company-files` checks directory's last modification time.
|
||||
* `company-files` supports relative paths and Windows drive letters.
|
||||
|
||||
## 2014-08-13 (0.8.4)
|
||||
|
||||
* `company-ropemacs` is only used when `ropemacs-mode` is on.
|
||||
* `company-gtags` is enabled in all `prog-mode` derivatives by default.
|
||||
* `company-end-of-buffer-workaround` is not used anymore.
|
||||
* `company-begin-commands` includes some of `cc-mode` commands.
|
||||
|
||||
## 2014-08-27 (0.8.3)
|
||||
|
||||
* On Emacs 24.4 or newer, tooltip positioning takes line-spacing into account.
|
||||
* New face `company-tooltip-search`, used for the search string in the tooltip.
|
||||
* The default value of `company-dabbrev-minimum-length` is set to 4, independent
|
||||
of the `company-minimum-prefix-length` value.
|
||||
|
||||
## 2014-07-26 (0.8.2)
|
||||
|
||||
* New user option `company-occurrence-weight-function`, allowing to tweak the
|
||||
behavior of the transformer `company-sort-by-occurrence`.
|
||||
* Setting `company-idle-delay` to `t` is deprecated. Use the value 0 instead.
|
||||
|
||||
## 2014-07-01 (0.8.1)
|
||||
|
||||
* `company-require-match` is not in effect when the new input doesn't continue
|
||||
the previous prefix, and that prefix was a match.
|
||||
* The meaning of `company-begin-commands` value t has slightly changed.
|
||||
* New transformer, `company-sort-by-backend-importance`.
|
||||
* When grouped back-ends are used, the back-end of the current candidate is
|
||||
indicated in the mode-line, enclosed in angle brackets.
|
||||
* New user option `company-gtags-insert-arguments`, t by default.
|
||||
* `company-css` knows about CSS3.
|
||||
* `company-gtags` supports `meta` and `annotation`.
|
||||
* User option `company-dabbrev-code-other-buffers` can have a new value: `code`.
|
||||
* New user option `company-tooltip-flip-when-above`.
|
||||
* `company-clang` uses the standard header search paths by default.
|
||||
* `C-h` is bound to `company-show-doc-buffer` (like `f1`).
|
||||
|
||||
## 2014-04-19 (0.8.0)
|
||||
|
||||
* `company-capf` is included in `company-backends` in any supported Emacs
|
||||
version (>= 24.1). `company-elisp` goes before it if Emacs version is < 24.4.
|
||||
* New user option `company-clang-insert-arguments`, by default t.
|
||||
* Default value of `company-idle-delay` lowered to `0.5`.
|
||||
* New user option `company-tooltip-minimum-width`, by default 0.
|
||||
* New function `company-grab-symbol-cons`.
|
||||
* `company-clang` fetches completion candidates asynchronously.
|
||||
* Added support for asynchronous back-ends (experimental).
|
||||
* Support for back-end command `crop` dropped (it was never documented).
|
||||
* Support for Emacs 23 dropped.
|
||||
* New user option `company-abort-manual-when-too-short`.
|
||||
|
||||
## 2014-03-25 (0.7.3)
|
||||
|
||||
* New user option `company-etags-ignore-case`.
|
||||
|
||||
## 2014-03-19 (0.7.2)
|
||||
|
||||
* Support for Emacs 22 officially dropped.
|
||||
* `company-clang` supports `indent-tabs-mode` and multibyte chars before point.
|
||||
|
||||
## 2014-03-18 (0.7.1)
|
||||
|
||||
* Group of back-ends can now contain keyword `:with`, which makes all back-ends
|
||||
after it to be skipped for prefix calculation.
|
||||
* New function `company-version`.
|
||||
* New bundled back-end `company-yasnippet`.
|
||||
* Completion candidates returned from grouped back-ends are tagged to remember
|
||||
which back-end each came from.
|
||||
* New user option `company-tooltip-align-annotations`, off by default.
|
||||
* New bundled back-end `company-bbdb`.
|
||||
|
||||
## 2014-02-18 (0.7)
|
||||
|
||||
* New back-end command, `match`, for non-prefix completion.
|
||||
* New user option `company-continue-commands`. The default value aborts
|
||||
completion on buffer saving commands.
|
||||
* New back-end command, `annotation`, for text displayed inline in the popup
|
||||
that's not a part of completion candidate.
|
||||
* `company-capf`, `company-clang` and `company-eclim` use `annotation`.
|
||||
* `company-preview*` faces inherit from `company-tooltip-selection` and
|
||||
`company-tooltip-common-selection` on light themes.
|
||||
* New user option `company-transformers`.
|
||||
* First transformer, `company-sort-by-occurrence`.
|
||||
* New user options controlling `company-dabbrev` and `company-dabbrev-code`.
|
||||
|
||||
## 2014-01-25 (0.6.14)
|
||||
|
||||
* The tooltip front-end is rendered with scrollbar, controlled by the user
|
||||
option `company-tooltip-offset-display`.
|
||||
* The tooltip front-end is rendered with margins, controlled by the user option
|
||||
`company-tooltip-margin`.
|
||||
|
||||
## 2014-01-14 (0.6.13)
|
||||
|
||||
* Experimental support for non-prefix completion.
|
||||
* Starting with Emacs version 24.4, `company-capf` is included in
|
||||
`company-backends` and replaces `company-elisp`.
|
||||
* `company-capf` supports completion tables that return non-default boundaries.
|
||||
* `company-elisp` is enabled in `inferior-emacs-lisp-mode`.
|
||||
|
||||
## 2013-09-28 (0.6.12)
|
||||
|
||||
* Default value of `company-begin-commands` changed to `(self-insert-command)`.
|
||||
* Futher improvement in `org-indent-mode` compatibility.
|
||||
|
||||
## 2013-08-18 (0.6.11)
|
||||
|
||||
* `company-template-c-like-templatify` removes all text after closing paren, for
|
||||
use in backends that display additional info there.
|
||||
* `company-cmake` is now bundled.
|
||||
* Better `linum` compatibility in Emacs <= 24.2.
|
||||
* `company-global-modes`: New option.
|
||||
|
||||
## 2013-05-26 (0.6.10)
|
||||
|
||||
* Plays nicer with `org-indent-mode`.
|
||||
* Works in horizontally scrolled windows.
|
||||
|
||||
## 2013-05-10 (0.6.9)
|
||||
|
||||
* `company-capf` respects `:exit-function` completion property.
|
||||
* `company-backends`: `prefix` command can return `t` in the cdr.
|
||||
* `company-clang-begin-after-member-access`: New option.
|
||||
* Mouse click outside the tooltip aborts completion.
|
||||
* `company-clang` uses standard input to pass the contents of current buffer to
|
||||
Clang 2.9+, otherwise saves the buffer and passes the path to the file.
|
||||
* `company-clang-auto-save` option has been removed.
|
||||
* Better interaction with `outline-minor-mode`.
|
||||
* `company-dabbrev-code` supports all `prog-mode` derivatives.
|
||||
|
||||
## 2013-04-16 (0.6.8)
|
||||
|
||||
* `company-auto-complete` is disabled by default.
|
||||
* `company-auto-complete-chars` default value includes fewer syntax classes.
|
||||
* In expanded function calls, arguments skipped by the user default to "argN".
|
||||
* `company-eclim` and `company-clang` do not strip argument types from fields.
|
||||
* `company-clang` expands function calls for all three modes now.
|
||||
* `company-clang` supports `c++-mode` by default.
|
||||
|
||||
## 2013-04-05 (0.6.7)
|
||||
|
||||
* Two `company-elisp` tweaks.
|
||||
|
||||
## 2013-04-01 (0.6.6)
|
||||
|
||||
* `company-elisp` doesn't offer completions when typing the name and the
|
||||
arguments of a new function or macro definition, allowing to fall back to
|
||||
other back-ends like `company-dabbrev-code`.
|
||||
|
||||
## 2013-03-30 (0.6.5)
|
||||
|
||||
* Fixed keybindings when running in a terminal.
|
||||
* `company-elisp-show-locals-first`: new customizable variable.
|
||||
* `company-elisp` shows more accurate and comprehensive candidates list.
|
||||
|
||||
## 2013-03-26 (0.6.4)
|
||||
|
||||
* `company-eclim` shows valid completions after an opening paren.
|
||||
* Expanded template does not get removed until the point leaves it. After your
|
||||
input the last argument in a method call expanded by `company-eclim`, you can
|
||||
press `<tab>` once more, to jump after the closing paren. No other bundled
|
||||
back-ends are affected.
|
||||
|
||||
## 2013-03-25 (0.6.3)
|
||||
|
||||
* New tooltip face colors used on themes with light background.
|
||||
* Pseudo-tooltip stays up-to-date when text is inserted after the point.
|
||||
* Fixed `company-require-match` mechanics.
|
||||
|
||||
## 2013-03-24 (0.6.2)
|
||||
|
||||
* `global-company-mode` is now autoloaded.
|
||||
|
||||
## 2013-03-23 (0.6.1)
|
||||
|
||||
* Documented `init` and `post-completion` back-end commands.
|
||||
* `company-eclim` and `company-clang` only expand the template on explicit user
|
||||
action (such as `company-complete-{selection,number,mouse}`).
|
||||
* `company-template` has some breaking changes. When point is at one of the
|
||||
fields, it's displayed at the beginning, not right after it; `<tab>` jumps to
|
||||
the next field, `forward-word` and `subword-forward` remappings are removed;
|
||||
when you jump to the next field, if the current one hasn't been edited, the
|
||||
overlay gets removed but the text remains.
|
||||
* `company-eclim` shows method overloads and expands templates for calls.
|
||||
* `company-clang-objc-templatify` does not insert spaces after colons anymore.
|
||||
* `company-clang` is now only initialized in supported buffers.
|
||||
So, no error messages if you don't have Clang until you open a C file.
|
||||
* `company-clang` recognizes Clang included in recent Xcode.
|
||||
* New commands `company-select-previous-or-abort` and
|
||||
`company-select-next-or-abort`, bound to `<up>` and `<down>`.
|
||||
|
||||
## 2013-03-19 (0.6)
|
||||
|
||||
* Across-the-board bugfixing.
|
||||
* `company-pysmell` is not used by default anymore.
|
||||
* Loading of `nxml`, `semantic`, `pymacs` and `ropemacs` is now deferred.
|
||||
* Candidates from grouped back-ends are merged more conservatively: only
|
||||
back-ends that return the same prefix at point are used.
|
||||
* `company-clang` now shows meta information, too.
|
||||
* Some performance improvements.
|
||||
* Fixed two old tooltip annoyances.
|
||||
* Instead of `overrriding-terminal-local-map`, we're now using
|
||||
`emulation-mode-map-alists` (experimental). This largely means that when the
|
||||
completion keymap is active, other minor modes' keymaps are still used, so,
|
||||
for example, it's not as easy to accidentally circumvent `paredit-mode`
|
||||
when it's enabled.
|
||||
* `company-elisp` has seen some improvements.
|
||||
* Added `company-capf`: completion adapter using
|
||||
`completion-at-point-functions`. (Stefan Monnier)
|
||||
* Clang completions now include macros and are case-sensitive.
|
||||
* Switching between tag files now works correctly with `company-etags`.
|
||||
|
||||
## 2010-02-24 (0.5)
|
||||
|
||||
* `company-ropemacs` now provides location and docs. (Fernando H. Silva)
|
||||
* Added `company-with-candidate-inserted` macro.
|
||||
* Added `company-clang` back-end.
|
||||
* Added new mechanism for non-consecutive insertion.
|
||||
(So far only used by clang for ObjC.)
|
||||
* The semantic back-end now shows meta information for local symbols.
|
||||
* Added compatibility for CEDET in Emacs 23.2 and from CVS. (Oleg Andreev)
|
||||
|
||||
## 2009-05-07 (0.4.3)
|
||||
|
||||
* Added `company-other-backend`.
|
||||
* Idle completion no longer interrupts multi-key command input.
|
||||
* Added `company-ropemacs` and `company-pysmell` back-ends.
|
||||
|
||||
## 2009-04-25 (0.4.2)
|
||||
|
||||
* In C modes . and -> now count towards `company-minimum-prefix-length`.
|
||||
* Reverted default front-end back to `company-preview-if-just-one-frontend`.
|
||||
* The pseudo tooltip will no longer be clipped at the right window edge.
|
||||
* Added `company-tooltip-minimum`.
|
||||
* Windows compatibility fixes.
|
||||
|
||||
## 2009-04-19 (0.4.1)
|
||||
|
||||
* Added `global-company-mode`.
|
||||
* Performance enhancements.
|
||||
* Added `company-eclim` back-end.
|
||||
* Added safer workaround for Emacs `posn-col-row` bug.
|
||||
|
||||
## 2009-04-18 (0.4)
|
||||
|
||||
* Automatic completion is now aborted if the prefix gets too short.
|
||||
* Added option `company-dabbrev-time-limit`.
|
||||
* `company-backends` now supports merging back-ends.
|
||||
* Added back-end `company-dabbrev-code` for generic code.
|
||||
* Fixed `company-begin-with`.
|
||||
|
||||
## 2009-04-15 (0.3.1)
|
||||
|
||||
* Added 'stop prefix to prevent dabbrev from completing inside of symbols.
|
||||
* Fixed issues with tabbar-mode and line-spacing.
|
||||
* Performance enhancements.
|
||||
|
||||
## 2009-04-12 (0.3)
|
||||
|
||||
* Added `company-begin-commands` option.
|
||||
* Added abbrev, tempo and Xcode back-ends.
|
||||
* Back-ends are now interactive. You can start them with M-x backend-name.
|
||||
* Added `company-begin-with` for starting company from elisp-code.
|
||||
* Added hooks.
|
||||
* Added `company-require-match` and `company-auto-complete` options.
|
||||
|
||||
## 2009-04-05 (0.2.1)
|
||||
|
||||
* Improved Emacs Lisp back-end behavior for local variables.
|
||||
* Added `company-elisp-detect-function-context` option.
|
||||
* The mouse can now be used for selection.
|
||||
|
||||
## 2009-03-22 (0.2)
|
||||
|
||||
* Added `company-show-location`.
|
||||
* Added etags back-end.
|
||||
* Added work-around for end-of-buffer bug.
|
||||
* Added `company-filter-candidates`.
|
||||
* More local Lisp variables are now included in the candidates.
|
||||
|
||||
## 2009-03-21 (0.1.5)
|
||||
|
||||
* Fixed elisp documentation buffer always showing the same doc.
|
||||
* Added `company-echo-strip-common-frontend`.
|
||||
* Added `company-show-numbers` option and M-0 ... M-9 default bindings.
|
||||
* Don't hide the echo message if it isn't shown.
|
||||
|
||||
## 2009-03-20 (0.1)
|
||||
|
||||
* Initial release.
|
@ -1,4 +0,0 @@
|
||||
See the [homepage](http://company-mode.github.com/).
|
||||
[![githalytics.com alpha](https://cruel-carlota.pagodabox.com/336ef4be2595a7859d52e2c17b7da2b2 "githalytics.com")](http://githalytics.com/company-mode/company-mode)
|
||||
|
||||
[![Build Status](https://travis-ci.org/company-mode/company-mode.png?branch=master)](https://travis-ci.org/company-mode/company-mode)
|
@ -1,51 +0,0 @@
|
||||
;;; company-abbrev.el --- company-mode completion back-end for abbrev
|
||||
|
||||
;; Copyright (C) 2009-2011 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Nikolaj Schumacher
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
;;
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'company)
|
||||
(require 'cl-lib)
|
||||
(require 'abbrev)
|
||||
|
||||
(defun company-abbrev-insert (match)
|
||||
"Replace MATCH with the expanded abbrev."
|
||||
(expand-abbrev))
|
||||
|
||||
;;;###autoload
|
||||
(defun company-abbrev (command &optional arg &rest ignored)
|
||||
"`company-mode' completion back-end for abbrev."
|
||||
(interactive (list 'interactive))
|
||||
(cl-case command
|
||||
(interactive (company-begin-backend 'company-abbrev
|
||||
'company-abbrev-insert))
|
||||
(prefix (company-grab-symbol))
|
||||
(candidates (nconc
|
||||
(delete "" (all-completions arg global-abbrev-table))
|
||||
(delete "" (all-completions arg local-abbrev-table))))
|
||||
(meta (abbrev-expansion arg))
|
||||
(require-match t)))
|
||||
|
||||
(provide 'company-abbrev)
|
||||
;;; company-abbrev.el ends here
|
Binary file not shown.
@ -1,296 +0,0 @@
|
||||
;;; company-autoloads.el --- automatically extracted autoloads
|
||||
;;
|
||||
;;; Code:
|
||||
|
||||
|
||||
;;;### (autoloads (global-company-mode company-mode) "company" "company.el"
|
||||
;;;;;; (22209 40170 243646 0))
|
||||
;;; Generated autoloads from company.el
|
||||
|
||||
(autoload 'company-mode "company" "\
|
||||
\"complete anything\"; is an in-buffer completion framework.
|
||||
Completion starts automatically, depending on the values
|
||||
`company-idle-delay' and `company-minimum-prefix-length'.
|
||||
|
||||
Completion can be controlled with the commands:
|
||||
`company-complete-common', `company-complete-selection', `company-complete',
|
||||
`company-select-next', `company-select-previous'. If these commands are
|
||||
called before `company-idle-delay', completion will also start.
|
||||
|
||||
Completions can be searched with `company-search-candidates' or
|
||||
`company-filter-candidates'. These can be used while completion is
|
||||
inactive, as well.
|
||||
|
||||
The completion data is retrieved using `company-backends' and displayed
|
||||
using `company-frontends'. If you want to start a specific back-end, call
|
||||
it interactively or use `company-begin-backend'.
|
||||
|
||||
regular keymap (`company-mode-map'):
|
||||
|
||||
\\{company-mode-map}
|
||||
keymap during active completions (`company-active-map'):
|
||||
|
||||
\\{company-active-map}
|
||||
|
||||
\(fn &optional ARG)" t nil)
|
||||
|
||||
(defvar global-company-mode nil "\
|
||||
Non-nil if Global-Company mode is enabled.
|
||||
See the command `global-company-mode' for a description of this minor mode.
|
||||
Setting this variable directly does not take effect;
|
||||
either customize it (see the info node `Easy Customization')
|
||||
or call the function `global-company-mode'.")
|
||||
|
||||
(custom-autoload 'global-company-mode "company" nil)
|
||||
|
||||
(autoload 'global-company-mode "company" "\
|
||||
Toggle Company mode in all buffers.
|
||||
With prefix ARG, enable Global-Company mode if ARG is positive;
|
||||
otherwise, disable it. If called from Lisp, enable the mode if
|
||||
ARG is omitted or nil.
|
||||
|
||||
Company mode is enabled in all buffers where
|
||||
`company-mode-on' would do it.
|
||||
See `company-mode' for more information on Company mode.
|
||||
|
||||
\(fn &optional ARG)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads (company-abbrev) "company-abbrev" "company-abbrev.el"
|
||||
;;;;;; (22209 40169 978650 0))
|
||||
;;; Generated autoloads from company-abbrev.el
|
||||
|
||||
(autoload 'company-abbrev "company-abbrev" "\
|
||||
`company-mode' completion back-end for abbrev.
|
||||
|
||||
\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads (company-bbdb) "company-bbdb" "company-bbdb.el"
|
||||
;;;;;; (22209 40170 252645 0))
|
||||
;;; Generated autoloads from company-bbdb.el
|
||||
|
||||
(autoload 'company-bbdb "company-bbdb" "\
|
||||
`company-mode' completion back-end for BBDB.
|
||||
|
||||
\(fn COMMAND &optional ARG &rest IGNORE)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads (company-css) "company-css" "company-css.el" (22209
|
||||
;;;;;; 40169 988651 0))
|
||||
;;; Generated autoloads from company-css.el
|
||||
|
||||
(autoload 'company-css "company-css" "\
|
||||
`company-mode' completion back-end for `css-mode'.
|
||||
|
||||
\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads (company-dabbrev) "company-dabbrev" "company-dabbrev.el"
|
||||
;;;;;; (22209 40169 996650 0))
|
||||
;;; Generated autoloads from company-dabbrev.el
|
||||
|
||||
(autoload 'company-dabbrev "company-dabbrev" "\
|
||||
dabbrev-like `company-mode' completion back-end.
|
||||
|
||||
\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads (company-dabbrev-code) "company-dabbrev-code" "company-dabbrev-code.el"
|
||||
;;;;;; (22209 40170 316642 0))
|
||||
;;; Generated autoloads from company-dabbrev-code.el
|
||||
|
||||
(autoload 'company-dabbrev-code "company-dabbrev-code" "\
|
||||
dabbrev-like `company-mode' back-end for code.
|
||||
The back-end looks for all symbols in the current buffer that aren't in
|
||||
comments or strings.
|
||||
|
||||
\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads (company-elisp) "company-elisp" "company-elisp.el"
|
||||
;;;;;; (22209 40170 14649 0))
|
||||
;;; Generated autoloads from company-elisp.el
|
||||
|
||||
(autoload 'company-elisp "company-elisp" "\
|
||||
`company-mode' completion back-end for Emacs Lisp.
|
||||
|
||||
\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads (company-etags) "company-etags" "company-etags.el"
|
||||
;;;;;; (22209 40169 933651 0))
|
||||
;;; Generated autoloads from company-etags.el
|
||||
|
||||
(autoload 'company-etags "company-etags" "\
|
||||
`company-mode' completion back-end for etags.
|
||||
|
||||
\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads (company-files) "company-files" "company-files.el"
|
||||
;;;;;; (22209 40170 22649 0))
|
||||
;;; Generated autoloads from company-files.el
|
||||
|
||||
(autoload 'company-files "company-files" "\
|
||||
`company-mode' completion back-end existing file names.
|
||||
Completions works for proper absolute and relative files paths.
|
||||
File paths with spaces are only supported inside strings.
|
||||
|
||||
\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads (company-gtags) "company-gtags" "company-gtags.el"
|
||||
;;;;;; (22209 40170 324643 0))
|
||||
;;; Generated autoloads from company-gtags.el
|
||||
|
||||
(autoload 'company-gtags "company-gtags" "\
|
||||
`company-mode' completion back-end for GNU Global.
|
||||
|
||||
\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads (company-ispell) "company-ispell" "company-ispell.el"
|
||||
;;;;;; (22209 40169 915651 0))
|
||||
;;; Generated autoloads from company-ispell.el
|
||||
|
||||
(autoload 'company-ispell "company-ispell" "\
|
||||
`company-mode' completion back-end using Ispell.
|
||||
|
||||
\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads (company-keywords) "company-keywords" "company-keywords.el"
|
||||
;;;;;; (22209 40169 943651 0))
|
||||
;;; Generated autoloads from company-keywords.el
|
||||
|
||||
(autoload 'company-keywords "company-keywords" "\
|
||||
`company-mode' back-end for programming language keywords.
|
||||
|
||||
\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads (company-nxml) "company-nxml" "company-nxml.el"
|
||||
;;;;;; (22209 40169 952651 0))
|
||||
;;; Generated autoloads from company-nxml.el
|
||||
|
||||
(autoload 'company-nxml "company-nxml" "\
|
||||
`company-mode' completion back-end for `nxml-mode'.
|
||||
|
||||
\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads (company-oddmuse) "company-oddmuse" "company-oddmuse.el"
|
||||
;;;;;; (22209 40170 31653 0))
|
||||
;;; Generated autoloads from company-oddmuse.el
|
||||
|
||||
(autoload 'company-oddmuse "company-oddmuse" "\
|
||||
`company-mode' completion back-end for `oddmuse-mode'.
|
||||
|
||||
\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads (company-pysmell) "company-pysmell" "company-pysmell.el"
|
||||
;;;;;; (22209 40170 215648 0))
|
||||
;;; Generated autoloads from company-pysmell.el
|
||||
|
||||
(autoload 'company-pysmell "company-pysmell" "\
|
||||
`company-mode' completion back-end for pysmell.
|
||||
This requires pysmell.el and pymacs.el.
|
||||
|
||||
\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads (company-semantic) "company-semantic" "company-semantic.el"
|
||||
;;;;;; (22209 40170 356644 0))
|
||||
;;; Generated autoloads from company-semantic.el
|
||||
|
||||
(autoload 'company-semantic "company-semantic" "\
|
||||
`company-mode' completion back-end using CEDET Semantic.
|
||||
|
||||
\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads (company-tempo) "company-tempo" "company-tempo.el"
|
||||
;;;;;; (22209 40170 280643 0))
|
||||
;;; Generated autoloads from company-tempo.el
|
||||
|
||||
(autoload 'company-tempo "company-tempo" "\
|
||||
`company-mode' completion back-end for tempo.
|
||||
|
||||
\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads (company-xcode) "company-xcode" "company-xcode.el"
|
||||
;;;;;; (22209 40170 299643 0))
|
||||
;;; Generated autoloads from company-xcode.el
|
||||
|
||||
(autoload 'company-xcode "company-xcode" "\
|
||||
`company-mode' completion back-end for Xcode projects.
|
||||
|
||||
\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads (company-yasnippet) "company-yasnippet" "company-yasnippet.el"
|
||||
;;;;;; (22209 40170 332643 0))
|
||||
;;; Generated autoloads from company-yasnippet.el
|
||||
|
||||
(autoload 'company-yasnippet "company-yasnippet" "\
|
||||
`company-mode' back-end for `yasnippet'.
|
||||
|
||||
This back-end should be used with care, because as long as there are
|
||||
snippets defined for the current major mode, this back-end will always
|
||||
shadow back-ends that come after it. Recommended usages:
|
||||
|
||||
* In a buffer-local value of `company-backends', grouped with a back-end or
|
||||
several that provide actual text completions.
|
||||
|
||||
(add-hook 'js-mode-hook
|
||||
(lambda ()
|
||||
(set (make-local-variable 'company-backends)
|
||||
'((company-dabbrev-code company-yasnippet)))))
|
||||
|
||||
* After keyword `:with', grouped with other back-ends.
|
||||
|
||||
(push '(company-semantic :with company-yasnippet) company-backends)
|
||||
|
||||
* Not in `company-backends', just bound to a key.
|
||||
|
||||
(global-set-key (kbd \"C-c y\") 'company-yasnippet)
|
||||
|
||||
\(fn COMMAND &optional ARG &rest IGNORE)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil nil ("company-capf.el" "company-clang.el" "company-cmake.el"
|
||||
;;;;;; "company-eclim.el" "company-pkg.el" "company-ropemacs.el"
|
||||
;;;;;; "company-template.el") (22209 40170 385855 827000))
|
||||
|
||||
;;;***
|
||||
|
||||
(provide 'company-autoloads)
|
||||
;; Local Variables:
|
||||
;; version-control: never
|
||||
;; no-byte-compile: t
|
||||
;; no-update-autoloads: t
|
||||
;; coding: utf-8
|
||||
;; End:
|
||||
;;; company-autoloads.el ends here
|
@ -1,13 +0,0 @@
|
||||
;;; company-autoloads.el --- automatically extracted autoloads
|
||||
;;
|
||||
;;; Code:
|
||||
|
||||
|
||||
(provide 'company-autoloads)
|
||||
;; Local Variables:
|
||||
;; version-control: never
|
||||
;; no-byte-compile: t
|
||||
;; no-update-autoloads: t
|
||||
;; coding: utf-8
|
||||
;; End:
|
||||
;;; company-autoloads.el ends here
|
@ -1,61 +0,0 @@
|
||||
;;; company-bbdb.el --- company-mode completion back-end for BBDB in message-mode
|
||||
|
||||
;; Copyright (C) 2013-2014 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Jan Tatarik <jan.tatarik@gmail.com>
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
(require 'company)
|
||||
(require 'cl-lib)
|
||||
|
||||
(declare-function bbdb-record-get-field "bbdb")
|
||||
(declare-function bbdb-records "bbdb")
|
||||
(declare-function bbdb-dwim-mail "bbdb-com")
|
||||
(declare-function bbdb-search "bbdb-com")
|
||||
|
||||
(defgroup company-bbdb nil
|
||||
"Completion back-end for BBDB."
|
||||
:group 'company)
|
||||
|
||||
(defcustom company-bbdb-modes '(message-mode)
|
||||
"Major modes in which `company-bbdb' may complete."
|
||||
:type '(repeat (symbol :tag "Major mode"))
|
||||
:package-version '(company . "0.8.8"))
|
||||
|
||||
(defun company-bbdb--candidates (arg)
|
||||
(cl-mapcan (lambda (record)
|
||||
(mapcar (lambda (mail) (bbdb-dwim-mail record mail))
|
||||
(bbdb-record-get-field record 'mail)))
|
||||
(eval '(bbdb-search (bbdb-records) arg nil arg))))
|
||||
|
||||
;;;###autoload
|
||||
(defun company-bbdb (command &optional arg &rest ignore)
|
||||
"`company-mode' completion back-end for BBDB."
|
||||
(interactive (list 'interactive))
|
||||
(cl-case command
|
||||
(interactive (company-begin-backend 'company-bbdb))
|
||||
(prefix (and (memq major-mode company-bbdb-modes)
|
||||
(featurep 'bbdb-com)
|
||||
(looking-back "^\\(To\\|Cc\\|Bcc\\): *\\(.*\\)"
|
||||
(line-beginning-position))
|
||||
(match-string-no-properties 2)))
|
||||
(candidates (company-bbdb--candidates arg))
|
||||
(sorted t)
|
||||
(no-cache t)))
|
||||
|
||||
(provide 'company-bbdb)
|
||||
;;; company-bbdb.el ends here
|
Binary file not shown.
@ -1,153 +0,0 @@
|
||||
;;; company-capf.el --- company-mode completion-at-point-functions back-end -*- lexical-binding: t -*-
|
||||
|
||||
;; Copyright (C) 2013-2014 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
;;
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'company)
|
||||
(require 'cl-lib)
|
||||
|
||||
(defvar company--capf-cache nil)
|
||||
|
||||
(defun company--capf-data ()
|
||||
(let ((cache company--capf-cache))
|
||||
(if (and (equal (current-buffer) (car cache))
|
||||
(equal (point) (car (setq cache (cdr cache))))
|
||||
(equal (buffer-chars-modified-tick) (car (setq cache (cdr cache)))))
|
||||
(cadr cache)
|
||||
(let ((data (company--capf-data-real)))
|
||||
(setq company--capf-cache
|
||||
(list (current-buffer) (point) (buffer-chars-modified-tick) data))
|
||||
data))))
|
||||
|
||||
(defun company--capf-data-real ()
|
||||
(cl-letf* (((default-value 'completion-at-point-functions)
|
||||
;; Ignore tags-completion-at-point-function because it subverts
|
||||
;; company-etags in the default value of company-backends, where
|
||||
;; the latter comes later.
|
||||
(remove 'tags-completion-at-point-function
|
||||
(default-value 'completion-at-point-functions)))
|
||||
(data (run-hook-wrapped 'completion-at-point-functions
|
||||
;; Ignore misbehaving functions.
|
||||
#'completion--capf-wrapper 'optimist)))
|
||||
(when (and (consp (cdr data)) (numberp (nth 1 data))) data)))
|
||||
|
||||
(defun company-capf (command &optional arg &rest _args)
|
||||
"`company-mode' back-end using `completion-at-point-functions'."
|
||||
(interactive (list 'interactive))
|
||||
(pcase command
|
||||
(`interactive (company-begin-backend 'company-capf))
|
||||
(`prefix
|
||||
(let ((res (company--capf-data)))
|
||||
(when res
|
||||
(if (> (nth 2 res) (point))
|
||||
'stop
|
||||
(buffer-substring-no-properties (nth 1 res) (point))))))
|
||||
(`candidates
|
||||
(let ((res (company--capf-data)))
|
||||
(when res
|
||||
(let* ((table (nth 3 res))
|
||||
(pred (plist-get (nthcdr 4 res) :predicate))
|
||||
(meta (completion-metadata
|
||||
(buffer-substring (nth 1 res) (nth 2 res))
|
||||
table pred))
|
||||
(sortfun (cdr (assq 'display-sort-function meta)))
|
||||
(candidates (completion-all-completions arg table pred (length arg)))
|
||||
(last (last candidates))
|
||||
(base-size (and (numberp (cdr last)) (cdr last))))
|
||||
(when base-size
|
||||
(setcdr last nil))
|
||||
(when sortfun
|
||||
(setq candidates (funcall sortfun candidates)))
|
||||
(if (not (zerop (or base-size 0)))
|
||||
(let ((before (substring arg 0 base-size)))
|
||||
(mapcar (lambda (candidate)
|
||||
(concat before candidate))
|
||||
candidates))
|
||||
candidates)))))
|
||||
(`sorted
|
||||
(let ((res (company--capf-data)))
|
||||
(when res
|
||||
(let ((meta (completion-metadata
|
||||
(buffer-substring (nth 1 res) (nth 2 res))
|
||||
(nth 3 res) (plist-get (nthcdr 4 res) :predicate))))
|
||||
(cdr (assq 'display-sort-function meta))))))
|
||||
(`match
|
||||
;; Can't just use 0 when base-size (see above) is non-zero.
|
||||
(let ((start (if (get-text-property 0 'font-lock-face arg)
|
||||
0
|
||||
(next-single-property-change 0 'font-lock-face arg))))
|
||||
(when start
|
||||
;; completions-common-part comes first, but we can't just look for this
|
||||
;; value because it can be in a list.
|
||||
(or
|
||||
(let ((value (get-text-property start 'font-lock-face arg)))
|
||||
(text-property-not-all start (length arg)
|
||||
'font-lock-face value arg))
|
||||
(length arg)))))
|
||||
(`duplicates t)
|
||||
(`no-cache t) ;Not much can be done here, as long as we handle
|
||||
;non-prefix matches.
|
||||
(`meta
|
||||
(let ((f (plist-get (nthcdr 4 (company--capf-data)) :company-docsig)))
|
||||
(when f (funcall f arg))))
|
||||
(`doc-buffer
|
||||
(let ((f (plist-get (nthcdr 4 (company--capf-data)) :company-doc-buffer)))
|
||||
(when f (funcall f arg))))
|
||||
(`location
|
||||
(let ((f (plist-get (nthcdr 4 (company--capf-data)) :company-location)))
|
||||
(when f (funcall f arg))))
|
||||
(`annotation
|
||||
(save-excursion
|
||||
;; FIXME: `company-begin' sets `company-point' after calling
|
||||
;; `company--begin-new'. We shouldn't rely on `company-point' here,
|
||||
;; better to cache the capf-data value instead. However: we can't just
|
||||
;; save the last capf-data value in `prefix', because that command can
|
||||
;; get called more often than `candidates', and at any point in the
|
||||
;; buffer (https://github.com/company-mode/company-mode/issues/153).
|
||||
;; We could try propertizing the returned prefix string, but it's not
|
||||
;; passed to `annotation', and `company-prefix' is set only after
|
||||
;; `company--strip-duplicates' is called.
|
||||
(when company-point
|
||||
(goto-char company-point))
|
||||
(let ((f (plist-get (nthcdr 4 (company--capf-data)) :annotation-function)))
|
||||
(when f (funcall f arg)))))
|
||||
(`require-match
|
||||
(plist-get (nthcdr 4 (company--capf-data)) :company-require-match))
|
||||
(`init nil) ;Don't bother: plenty of other ways to initialize the code.
|
||||
(`post-completion
|
||||
(let* ((res (company--capf-data))
|
||||
(exit-function (plist-get (nthcdr 4 res) :exit-function))
|
||||
(table (nth 3 res))
|
||||
(pred (plist-get (nthcdr 4 res) :predicate)))
|
||||
(if exit-function
|
||||
;; Follow the example of `completion--done'.
|
||||
(funcall exit-function arg
|
||||
(if (eq (try-completion arg table pred) t)
|
||||
'finished 'sole)))))
|
||||
))
|
||||
|
||||
(provide 'company-capf)
|
||||
|
||||
;;; company-capf.el ends here
|
Binary file not shown.
@ -1,335 +0,0 @@
|
||||
;;; company-clang.el --- company-mode completion back-end for Clang -*- lexical-binding: t -*-
|
||||
|
||||
;; Copyright (C) 2009, 2011, 2013-2014 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Nikolaj Schumacher
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
;;
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'company)
|
||||
(require 'company-template)
|
||||
(require 'cl-lib)
|
||||
|
||||
(defgroup company-clang nil
|
||||
"Completion back-end for Clang."
|
||||
:group 'company)
|
||||
|
||||
(defcustom company-clang-executable
|
||||
(executable-find "clang")
|
||||
"Location of clang executable."
|
||||
:type 'file)
|
||||
|
||||
(defcustom company-clang-begin-after-member-access t
|
||||
"When non-nil, automatic completion will start whenever the current
|
||||
symbol is preceded by \".\", \"->\" or \"::\", ignoring
|
||||
`company-minimum-prefix-length'.
|
||||
|
||||
If `company-begin-commands' is a list, it should include `c-electric-lt-gt'
|
||||
and `c-electric-colon', for automatic completion right after \">\" and
|
||||
\":\".")
|
||||
|
||||
(defcustom company-clang-arguments nil
|
||||
"Additional arguments to pass to clang when completing.
|
||||
Prefix files (-include ...) can be selected with `company-clang-set-prefix'
|
||||
or automatically through a custom `company-clang-prefix-guesser'."
|
||||
:type '(repeat (string :tag "Argument")))
|
||||
|
||||
(defcustom company-clang-prefix-guesser 'company-clang-guess-prefix
|
||||
"A function to determine the prefix file for the current buffer."
|
||||
:type '(function :tag "Guesser function" nil))
|
||||
|
||||
(defvar company-clang-modes '(c-mode c++-mode objc-mode)
|
||||
"Major modes which clang may complete.")
|
||||
|
||||
(defcustom company-clang-insert-arguments t
|
||||
"When non-nil, insert function arguments as a template after completion."
|
||||
:type 'boolean
|
||||
:package-version '(company . "0.8.0"))
|
||||
|
||||
;; prefix ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defvar company-clang--prefix nil)
|
||||
|
||||
(defsubst company-clang--guess-pch-file (file)
|
||||
(let ((dir (directory-file-name (file-name-directory file))))
|
||||
(when (equal (file-name-nondirectory dir) "Classes")
|
||||
(setq dir (file-name-directory dir)))
|
||||
(car (directory-files dir t "\\([^.]h\\|[^h]\\).pch\\'" t))))
|
||||
|
||||
(defsubst company-clang--file-substring (file beg end)
|
||||
(with-temp-buffer
|
||||
(insert-file-contents-literally file nil beg end)
|
||||
(buffer-string)))
|
||||
|
||||
(defun company-clang-guess-prefix ()
|
||||
"Try to guess the prefix file for the current buffer."
|
||||
;; Prefixes seem to be called .pch. Pre-compiled headers do, too.
|
||||
;; So we look at the magic number to rule them out.
|
||||
(let* ((file (company-clang--guess-pch-file buffer-file-name))
|
||||
(magic-number (and file (company-clang--file-substring file 0 4))))
|
||||
(unless (member magic-number '("CPCH" "gpch"))
|
||||
file)))
|
||||
|
||||
(defun company-clang-set-prefix (&optional prefix)
|
||||
"Use PREFIX as a prefix (-include ...) file for clang completion."
|
||||
(interactive (let ((def (funcall company-clang-prefix-guesser)))
|
||||
(unless (stringp def)
|
||||
(setq def default-directory))
|
||||
(list (read-file-name "Prefix file: "
|
||||
(when def (file-name-directory def))
|
||||
def t (when def (file-name-nondirectory def))))))
|
||||
;; TODO: pre-compile?
|
||||
(setq company-clang--prefix (and (stringp prefix)
|
||||
(file-regular-p prefix)
|
||||
prefix)))
|
||||
|
||||
;; Clean-up on exit.
|
||||
(add-hook 'kill-emacs-hook 'company-clang-set-prefix)
|
||||
|
||||
;; parsing ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; TODO: Handle Pattern (syntactic hints would be neat).
|
||||
;; Do we ever see OVERLOAD (or OVERRIDE)?
|
||||
(defconst company-clang--completion-pattern
|
||||
"^COMPLETION: \\_<\\(%s[a-zA-Z0-9_:]*\\)\\(?: : \\(.*\\)$\\)?$")
|
||||
|
||||
(defconst company-clang--error-buffer-name "*clang-error*")
|
||||
|
||||
(defun company-clang--lang-option ()
|
||||
(if (eq major-mode 'objc-mode)
|
||||
(if (string= "m" (file-name-extension buffer-file-name))
|
||||
"objective-c" "objective-c++")
|
||||
(substring (symbol-name major-mode) 0 -5)))
|
||||
|
||||
(defun company-clang--parse-output (prefix _objc)
|
||||
(goto-char (point-min))
|
||||
(let ((pattern (format company-clang--completion-pattern
|
||||
(regexp-quote prefix)))
|
||||
(case-fold-search nil)
|
||||
lines match)
|
||||
(while (re-search-forward pattern nil t)
|
||||
(setq match (match-string-no-properties 1))
|
||||
(unless (equal match "Pattern")
|
||||
(save-match-data
|
||||
(when (string-match ":" match)
|
||||
(setq match (substring match 0 (match-beginning 0)))))
|
||||
(let ((meta (match-string-no-properties 2)))
|
||||
(when (and meta (not (string= match meta)))
|
||||
(put-text-property 0 1 'meta
|
||||
(company-clang--strip-formatting meta)
|
||||
match)))
|
||||
(push match lines)))
|
||||
lines))
|
||||
|
||||
(defun company-clang--meta (candidate)
|
||||
(get-text-property 0 'meta candidate))
|
||||
|
||||
(defun company-clang--annotation (candidate)
|
||||
(let ((meta (company-clang--meta candidate)))
|
||||
(cond
|
||||
((null meta) nil)
|
||||
((string-match "[^:]:[^:]" meta)
|
||||
(substring meta (1+ (match-beginning 0))))
|
||||
((string-match "\\((.*)[ a-z]*\\'\\)" meta)
|
||||
(let ((paren (match-beginning 1)))
|
||||
(if (not (eq (aref meta (1- paren)) ?>))
|
||||
(match-string 1 meta)
|
||||
(with-temp-buffer
|
||||
(insert meta)
|
||||
(goto-char paren)
|
||||
(substring meta (1- (search-backward "<"))))))))))
|
||||
|
||||
(defun company-clang--strip-formatting (text)
|
||||
(replace-regexp-in-string
|
||||
"#]" " "
|
||||
(replace-regexp-in-string "[<{[]#\\|#[>}]" "" text t)
|
||||
t))
|
||||
|
||||
(defun company-clang--handle-error (res args)
|
||||
(goto-char (point-min))
|
||||
(let* ((buf (get-buffer-create company-clang--error-buffer-name))
|
||||
(cmd (concat company-clang-executable " " (mapconcat 'identity args " ")))
|
||||
(pattern (format company-clang--completion-pattern ""))
|
||||
(err (if (re-search-forward pattern nil t)
|
||||
(buffer-substring-no-properties (point-min)
|
||||
(1- (match-beginning 0)))
|
||||
;; Warn the user more aggressively if no match was found.
|
||||
(message "clang failed with error %d:\n%s" res cmd)
|
||||
(buffer-string))))
|
||||
|
||||
(with-current-buffer buf
|
||||
(let ((inhibit-read-only t))
|
||||
(erase-buffer)
|
||||
(insert (current-time-string)
|
||||
(format "\nclang failed with error %d:\n" res)
|
||||
cmd "\n\n")
|
||||
(insert err)
|
||||
(setq buffer-read-only t)
|
||||
(goto-char (point-min))))))
|
||||
|
||||
(defun company-clang--start-process (prefix callback &rest args)
|
||||
(let ((objc (derived-mode-p 'objc-mode))
|
||||
(buf (get-buffer-create "*clang-output*"))
|
||||
;; Looks unnecessary in Emacs 25.1 and later.
|
||||
(process-adaptive-read-buffering nil))
|
||||
(with-current-buffer buf (erase-buffer))
|
||||
(if (get-buffer-process buf)
|
||||
(funcall callback nil)
|
||||
(let ((process (apply #'start-process "company-clang" buf
|
||||
company-clang-executable args)))
|
||||
(set-process-sentinel
|
||||
process
|
||||
(lambda (proc status)
|
||||
(unless (string-match-p "hangup" status)
|
||||
(funcall
|
||||
callback
|
||||
(let ((res (process-exit-status proc)))
|
||||
(with-current-buffer buf
|
||||
(unless (eq 0 res)
|
||||
(company-clang--handle-error res args))
|
||||
;; Still try to get any useful input.
|
||||
(company-clang--parse-output prefix objc)))))))
|
||||
(unless (company-clang--auto-save-p)
|
||||
(send-region process (point-min) (point-max))
|
||||
(send-string process "\n")
|
||||
(process-send-eof process))))))
|
||||
|
||||
(defsubst company-clang--build-location (pos)
|
||||
(save-excursion
|
||||
(goto-char pos)
|
||||
(format "%s:%d:%d"
|
||||
(if (company-clang--auto-save-p) buffer-file-name "-")
|
||||
(line-number-at-pos)
|
||||
(1+ (length
|
||||
(encode-coding-region
|
||||
(line-beginning-position)
|
||||
(point)
|
||||
'utf-8
|
||||
t))))))
|
||||
|
||||
(defsubst company-clang--build-complete-args (pos)
|
||||
(append '("-fsyntax-only" "-Xclang" "-code-completion-macros")
|
||||
(unless (company-clang--auto-save-p)
|
||||
(list "-x" (company-clang--lang-option)))
|
||||
company-clang-arguments
|
||||
(when (stringp company-clang--prefix)
|
||||
(list "-include" (expand-file-name company-clang--prefix)))
|
||||
(list "-Xclang" (format "-code-completion-at=%s"
|
||||
(company-clang--build-location pos)))
|
||||
(list (if (company-clang--auto-save-p) buffer-file-name "-"))))
|
||||
|
||||
(defun company-clang--candidates (prefix callback)
|
||||
(and (company-clang--auto-save-p)
|
||||
(buffer-modified-p)
|
||||
(basic-save-buffer))
|
||||
(when (null company-clang--prefix)
|
||||
(company-clang-set-prefix (or (funcall company-clang-prefix-guesser)
|
||||
'none)))
|
||||
(apply 'company-clang--start-process
|
||||
prefix
|
||||
callback
|
||||
(company-clang--build-complete-args (- (point) (length prefix)))))
|
||||
|
||||
(defun company-clang--prefix ()
|
||||
(if company-clang-begin-after-member-access
|
||||
(company-grab-symbol-cons "\\.\\|->\\|::" 2)
|
||||
(company-grab-symbol)))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defconst company-clang-required-version 1.1)
|
||||
|
||||
(defvar company-clang--version nil)
|
||||
|
||||
(defun company-clang--auto-save-p ()
|
||||
(< company-clang--version 2.9))
|
||||
|
||||
(defsubst company-clang-version ()
|
||||
"Return the version of `company-clang-executable'."
|
||||
(with-temp-buffer
|
||||
(call-process company-clang-executable nil t nil "--version")
|
||||
(goto-char (point-min))
|
||||
(if (re-search-forward "clang\\(?: version \\|-\\)\\([0-9.]+\\)" nil t)
|
||||
(let ((ver (string-to-number (match-string-no-properties 1))))
|
||||
(if (> ver 100)
|
||||
(/ ver 100)
|
||||
ver))
|
||||
0)))
|
||||
|
||||
(defun company-clang-objc-templatify (selector)
|
||||
(let* ((end (point-marker))
|
||||
(beg (- (point) (length selector) 1))
|
||||
(templ (company-template-declare-template beg end))
|
||||
(cnt 0))
|
||||
(save-excursion
|
||||
(goto-char beg)
|
||||
(catch 'stop
|
||||
(while (search-forward ":" end t)
|
||||
(when (looking-at "([^)]*) ?")
|
||||
(delete-region (match-beginning 0) (match-end 0)))
|
||||
(company-template-add-field templ (point) (format "arg%d" cnt))
|
||||
(if (< (point) end)
|
||||
(insert " ")
|
||||
(throw 'stop t))
|
||||
(cl-incf cnt))))
|
||||
(company-template-move-to-first templ)))
|
||||
|
||||
(defun company-clang (command &optional arg &rest ignored)
|
||||
"`company-mode' completion back-end for Clang.
|
||||
Clang is a parser for C and ObjC. Clang version 1.1 or newer is required.
|
||||
|
||||
Additional command line arguments can be specified in
|
||||
`company-clang-arguments'. Prefix files (-include ...) can be selected
|
||||
with `company-clang-set-prefix' or automatically through a custom
|
||||
`company-clang-prefix-guesser'.
|
||||
|
||||
With Clang versions before 2.9, we have to save the buffer before
|
||||
performing completion. With Clang 2.9 and later, buffer contents are
|
||||
passed via standard input."
|
||||
(interactive (list 'interactive))
|
||||
(cl-case command
|
||||
(interactive (company-begin-backend 'company-clang))
|
||||
(init (when (memq major-mode company-clang-modes)
|
||||
(unless company-clang-executable
|
||||
(error "Company found no clang executable"))
|
||||
(setq company-clang--version (company-clang-version))
|
||||
(when (< company-clang--version company-clang-required-version)
|
||||
(error "Company requires clang version 1.1"))))
|
||||
(prefix (and (memq major-mode company-clang-modes)
|
||||
buffer-file-name
|
||||
company-clang-executable
|
||||
(not (company-in-string-or-comment))
|
||||
(or (company-clang--prefix) 'stop)))
|
||||
(candidates (cons :async
|
||||
(lambda (cb) (company-clang--candidates arg cb))))
|
||||
(meta (company-clang--meta arg))
|
||||
(annotation (company-clang--annotation arg))
|
||||
(post-completion (let ((anno (company-clang--annotation arg)))
|
||||
(when (and company-clang-insert-arguments anno)
|
||||
(insert anno)
|
||||
(if (string-match "\\`:[^:]" anno)
|
||||
(company-clang-objc-templatify anno)
|
||||
(company-template-c-like-templatify
|
||||
(concat arg anno))))))))
|
||||
|
||||
(provide 'company-clang)
|
||||
;;; company-clang.el ends here
|
Binary file not shown.
@ -1,198 +0,0 @@
|
||||
;;; company-cmake.el --- company-mode completion back-end for CMake
|
||||
|
||||
;; Copyright (C) 2013-2014 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Chen Bin <chenbin DOT sh AT gmail>
|
||||
;; Version: 0.2
|
||||
|
||||
;; This program is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
;;
|
||||
;; company-cmake offers completions for module names, variable names and
|
||||
;; commands used by CMake. And their descriptions.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'company)
|
||||
(require 'cl-lib)
|
||||
|
||||
(defgroup company-cmake nil
|
||||
"Completion back-end for CMake."
|
||||
:group 'company)
|
||||
|
||||
(defcustom company-cmake-executable
|
||||
(executable-find "cmake")
|
||||
"Location of cmake executable."
|
||||
:type 'file)
|
||||
|
||||
(defvar company-cmake-executable-arguments
|
||||
'("--help-command-list"
|
||||
"--help-module-list"
|
||||
"--help-variable-list")
|
||||
"The arguments we pass to cmake, separately.
|
||||
They affect which types of symbols we get completion candidates for.")
|
||||
|
||||
(defvar company-cmake--completion-pattern
|
||||
"^\\(%s[a-zA-Z0-9_<>]%s\\)$"
|
||||
"Regexp to match the candidates.")
|
||||
|
||||
(defvar company-cmake-modes '(cmake-mode)
|
||||
"Major modes in which cmake may complete.")
|
||||
|
||||
(defvar company-cmake--candidates-cache nil
|
||||
"Cache for the raw candidates.")
|
||||
|
||||
(defvar company-cmake--meta-command-cache nil
|
||||
"Cache for command arguments to retrieve descriptions for the candidates.")
|
||||
|
||||
(defun company-cmake--replace-tags (rlt)
|
||||
(setq rlt (replace-regexp-in-string
|
||||
"\\(.*?\\(IS_GNU\\)?\\)<LANG>\\(.*\\)"
|
||||
(lambda (_match)
|
||||
(mapconcat 'identity
|
||||
(if (match-beginning 2)
|
||||
'("\\1CXX\\3" "\\1C\\3" "\\1G77\\3")
|
||||
'("\\1CXX\\3" "\\1C\\3" "\\1Fortran\\3"))
|
||||
"\n"))
|
||||
rlt t))
|
||||
(setq rlt (replace-regexp-in-string
|
||||
"\\(.*\\)<CONFIG>\\(.*\\)"
|
||||
(mapconcat 'identity '("\\1DEBUG\\2" "\\1RELEASE\\2"
|
||||
"\\1RELWITHDEBINFO\\2" "\\1MINSIZEREL\\2")
|
||||
"\n")
|
||||
rlt))
|
||||
rlt)
|
||||
|
||||
(defun company-cmake--fill-candidates-cache (arg)
|
||||
"Fill candidates cache if needed."
|
||||
(let (rlt)
|
||||
(unless company-cmake--candidates-cache
|
||||
(setq company-cmake--candidates-cache (make-hash-table :test 'equal)))
|
||||
|
||||
;; If hash is empty, fill it.
|
||||
(unless (gethash arg company-cmake--candidates-cache)
|
||||
(with-temp-buffer
|
||||
(let ((res (call-process company-cmake-executable nil t nil arg)))
|
||||
(unless (zerop res)
|
||||
(message "cmake executable exited with error=%d" res)))
|
||||
(setq rlt (buffer-string)))
|
||||
(setq rlt (company-cmake--replace-tags rlt))
|
||||
(puthash arg rlt company-cmake--candidates-cache))
|
||||
))
|
||||
|
||||
(defun company-cmake--parse (prefix content cmd)
|
||||
(let ((start 0)
|
||||
(pattern (format company-cmake--completion-pattern
|
||||
(regexp-quote prefix)
|
||||
(if (zerop (length prefix)) "+" "*")))
|
||||
(lines (split-string content "\n"))
|
||||
match
|
||||
rlt)
|
||||
(dolist (line lines)
|
||||
(when (string-match pattern line)
|
||||
(let ((match (match-string 1 line)))
|
||||
(when match
|
||||
(puthash match cmd company-cmake--meta-command-cache)
|
||||
(push match rlt)))))
|
||||
rlt))
|
||||
|
||||
(defun company-cmake--candidates (prefix)
|
||||
(let (results
|
||||
cmd-opts
|
||||
str)
|
||||
|
||||
(unless company-cmake--meta-command-cache
|
||||
(setq company-cmake--meta-command-cache (make-hash-table :test 'equal)))
|
||||
|
||||
(dolist (arg company-cmake-executable-arguments)
|
||||
(company-cmake--fill-candidates-cache arg)
|
||||
(setq cmd-opts (replace-regexp-in-string "-list$" "" arg) )
|
||||
|
||||
(setq str (gethash arg company-cmake--candidates-cache))
|
||||
(when str
|
||||
(setq results (nconc results
|
||||
(company-cmake--parse prefix str cmd-opts)))))
|
||||
results))
|
||||
|
||||
(defun company-cmake--unexpand-candidate (candidate)
|
||||
(cond
|
||||
((string-match "^CMAKE_\\(C\\|CXX\\|Fortran\\)\\(_.*\\)$" candidate)
|
||||
(setq candidate (concat "CMAKE_<LANG>" (match-string 2 candidate))))
|
||||
|
||||
;; C flags
|
||||
((string-match "^\\(.*_\\)IS_GNU\\(C\\|CXX\\|G77\\)$" candidate)
|
||||
(setq candidate (concat (match-string 1 candidate) "IS_GNU<LANG>")))
|
||||
|
||||
;; C flags
|
||||
((string-match "^\\(.*_\\)OVERRIDE_\\(C\\|CXX\\|Fortran\\)$" candidate)
|
||||
(setq candidate (concat (match-string 1 candidate) "OVERRIDE_<LANG>")))
|
||||
|
||||
((string-match "^\\(.*\\)\\(_DEBUG\\|_RELEASE\\|_RELWITHDEBINFO\\|_MINSIZEREL\\)\\(.*\\)$" candidate)
|
||||
(setq candidate (concat (match-string 1 candidate)
|
||||
"_<CONFIG>"
|
||||
(match-string 3 candidate)))))
|
||||
candidate)
|
||||
|
||||
(defun company-cmake--meta (candidate)
|
||||
(let ((cmd-opts (gethash candidate company-cmake--meta-command-cache))
|
||||
result)
|
||||
(setq candidate (company-cmake--unexpand-candidate candidate))
|
||||
|
||||
;; Don't cache the documentation of every candidate (command)
|
||||
;; Cache in this case will cost too much memory.
|
||||
(with-temp-buffer
|
||||
(call-process company-cmake-executable nil t nil cmd-opts candidate)
|
||||
;; Go to the third line, trim it and return the result.
|
||||
;; Tested with cmake 2.8.9.
|
||||
(goto-char (point-min))
|
||||
(forward-line 2)
|
||||
(setq result (buffer-substring-no-properties (line-beginning-position)
|
||||
(line-end-position)))
|
||||
(setq result (replace-regexp-in-string "^[ \t\n\r]+" "" result))
|
||||
result)))
|
||||
|
||||
(defun company-cmake--doc-buffer (candidate)
|
||||
(let ((cmd-opts (gethash candidate company-cmake--meta-command-cache)))
|
||||
|
||||
(setq candidate (company-cmake--unexpand-candidate candidate))
|
||||
(with-temp-buffer
|
||||
(call-process company-cmake-executable nil t nil cmd-opts candidate)
|
||||
;; Go to the third line, trim it and return the doc buffer.
|
||||
;; Tested with cmake 2.8.9.
|
||||
(goto-char (point-min))
|
||||
(forward-line 2)
|
||||
(company-doc-buffer
|
||||
(buffer-substring-no-properties (line-beginning-position)
|
||||
(point-max))))))
|
||||
|
||||
(defun company-cmake (command &optional arg &rest ignored)
|
||||
"`company-mode' completion back-end for CMake.
|
||||
CMake is a cross-platform, open-source make system."
|
||||
(interactive (list 'interactive))
|
||||
(cl-case command
|
||||
(interactive (company-begin-backend 'company-cmake))
|
||||
(init (when (memq major-mode company-cmake-modes)
|
||||
(unless company-cmake-executable
|
||||
(error "Company found no cmake executable"))))
|
||||
(prefix (and (memq major-mode company-cmake-modes)
|
||||
(not (company-in-string-or-comment))
|
||||
(company-grab-symbol)))
|
||||
(candidates (company-cmake--candidates arg))
|
||||
(meta (company-cmake--meta arg))
|
||||
(doc-buffer (company-cmake--doc-buffer arg))
|
||||
))
|
||||
|
||||
(provide 'company-cmake)
|
||||
;;; company-cmake.el ends here
|
Binary file not shown.
@ -1,438 +0,0 @@
|
||||
;;; company-css.el --- company-mode completion back-end for css-mode -*- lexical-binding: t -*-
|
||||
|
||||
;; Copyright (C) 2009, 2011, 2014 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Nikolaj Schumacher
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'company)
|
||||
(require 'cl-lib)
|
||||
|
||||
(defconst company-css-property-alist
|
||||
;; see http://www.w3.org/TR/CSS21/propidx.html
|
||||
'(("azimuth" angle "left-side" "far-left" "left" "center-left" "center"
|
||||
"center-right" "right" "far-right" "right-side" "behind" "leftwards"
|
||||
"rightwards")
|
||||
("background" background-color background-image background-repeat
|
||||
background-attachment background-position
|
||||
background-clip background-origin background-size)
|
||||
("background-attachment" "scroll" "fixed")
|
||||
("background-color" color "transparent")
|
||||
("background-image" uri "none")
|
||||
("background-position" percentage length "left" "center" "right" percentage
|
||||
length "top" "center" "bottom" "left" "center" "right" "top" "center"
|
||||
"bottom")
|
||||
("background-repeat" "repeat" "repeat-x" "repeat-y" "no-repeat")
|
||||
("border" border-width border-style border-color)
|
||||
("border-bottom" border)
|
||||
("border-bottom-color" border-color)
|
||||
("border-bottom-style" border-style)
|
||||
("border-bottom-width" border-width)
|
||||
("border-collapse" "collapse" "separate")
|
||||
("border-color" color "transparent")
|
||||
("border-left" border)
|
||||
("border-left-color" border-color)
|
||||
("border-left-style" border-style)
|
||||
("border-left-width" border-width)
|
||||
("border-right" border)
|
||||
("border-right-color" border-color)
|
||||
("border-right-style" border-style)
|
||||
("border-right-width" border-width)
|
||||
("border-spacing" length length)
|
||||
("border-style" border-style)
|
||||
("border-top" border)
|
||||
("border-top-color" border-color)
|
||||
("border-top-style" border-style)
|
||||
("border-top-width" border-width)
|
||||
("border-width" border-width)
|
||||
("bottom" length percentage "auto")
|
||||
("caption-side" "top" "bottom")
|
||||
("clear" "none" "left" "right" "both")
|
||||
("clip" shape "auto")
|
||||
("color" color)
|
||||
("content" "normal" "none" string uri counter "attr()" "open-quote"
|
||||
"close-quote" "no-open-quote" "no-close-quote")
|
||||
("counter-increment" identifier integer "none")
|
||||
("counter-reset" identifier integer "none")
|
||||
("cue" cue-before cue-after)
|
||||
("cue-after" uri "none")
|
||||
("cue-before" uri "none")
|
||||
("cursor" uri "*" "auto" "crosshair" "default" "pointer" "move" "e-resize"
|
||||
"ne-resize" "nw-resize" "n-resize" "se-resize" "sw-resize" "s-resize"
|
||||
"w-resize" "text" "wait" "help" "progress")
|
||||
("direction" "ltr" "rtl")
|
||||
("display" "inline" "block" "list-item" "run-in" "inline-block" "table"
|
||||
"inline-table" "table-row-group" "table-header-group" "table-footer-group"
|
||||
"table-row" "table-column-group" "table-column" "table-cell"
|
||||
"table-caption" "none")
|
||||
("elevation" angle "below" "level" "above" "higher" "lower")
|
||||
("empty-cells" "show" "hide")
|
||||
("float" "left" "right" "none")
|
||||
("font" font-style font-weight font-size "/" line-height
|
||||
font-family "caption" "icon" "menu" "message-box" "small-caption"
|
||||
"status-bar" "normal" "small-caps"
|
||||
;; CSS3
|
||||
font-stretch)
|
||||
("font-family" family-name generic-family)
|
||||
("font-size" absolute-size relative-size length percentage)
|
||||
("font-style" "normal" "italic" "oblique")
|
||||
("font-weight" "normal" "bold" "bolder" "lighter" "100" "200" "300" "400"
|
||||
"500" "600" "700" "800" "900")
|
||||
("height" length percentage "auto")
|
||||
("left" length percentage "auto")
|
||||
("letter-spacing" "normal" length)
|
||||
("line-height" "normal" number length percentage)
|
||||
("list-style" list-style-type list-style-position list-style-image)
|
||||
("list-style-image" uri "none")
|
||||
("list-style-position" "inside" "outside")
|
||||
("list-style-type" "disc" "circle" "square" "decimal" "decimal-leading-zero"
|
||||
"lower-roman" "upper-roman" "lower-greek" "lower-latin" "upper-latin"
|
||||
"armenian" "georgian" "lower-alpha" "upper-alpha" "none")
|
||||
("margin" margin-width)
|
||||
("margin-bottom" margin-width)
|
||||
("margin-left" margin-width)
|
||||
("margin-right" margin-width)
|
||||
("margin-top" margin-width)
|
||||
("max-height" length percentage "none")
|
||||
("max-width" length percentage "none")
|
||||
("min-height" length percentage)
|
||||
("min-width" length percentage)
|
||||
("orphans" integer)
|
||||
("outline" outline-color outline-style outline-width)
|
||||
("outline-color" color "invert")
|
||||
("outline-style" border-style)
|
||||
("outline-width" border-width)
|
||||
("overflow" "visible" "hidden" "scroll" "auto"
|
||||
;; CSS3:
|
||||
"no-display" "no-content")
|
||||
("padding" padding-width)
|
||||
("padding-bottom" padding-width)
|
||||
("padding-left" padding-width)
|
||||
("padding-right" padding-width)
|
||||
("padding-top" padding-width)
|
||||
("page-break-after" "auto" "always" "avoid" "left" "right")
|
||||
("page-break-before" "auto" "always" "avoid" "left" "right")
|
||||
("page-break-inside" "avoid" "auto")
|
||||
("pause" time percentage)
|
||||
("pause-after" time percentage)
|
||||
("pause-before" time percentage)
|
||||
("pitch" frequency "x-low" "low" "medium" "high" "x-high")
|
||||
("pitch-range" number)
|
||||
("play-during" uri "mix" "repeat" "auto" "none")
|
||||
("position" "static" "relative" "absolute" "fixed")
|
||||
("quotes" string string "none")
|
||||
("richness" number)
|
||||
("right" length percentage "auto")
|
||||
("speak" "normal" "none" "spell-out")
|
||||
("speak-header" "once" "always")
|
||||
("speak-numeral" "digits" "continuous")
|
||||
("speak-punctuation" "code" "none")
|
||||
("speech-rate" number "x-slow" "slow" "medium" "fast" "x-fast" "faster"
|
||||
"slower")
|
||||
("stress" number)
|
||||
("table-layout" "auto" "fixed")
|
||||
("text-align" "left" "right" "center" "justify")
|
||||
("text-indent" length percentage)
|
||||
("text-transform" "capitalize" "uppercase" "lowercase" "none")
|
||||
("top" length percentage "auto")
|
||||
("unicode-bidi" "normal" "embed" "bidi-override")
|
||||
("vertical-align" "baseline" "sub" "super" "top" "text-top" "middle"
|
||||
"bottom" "text-bottom" percentage length)
|
||||
("visibility" "visible" "hidden" "collapse")
|
||||
("voice-family" specific-voice generic-voice "*" specific-voice
|
||||
generic-voice)
|
||||
("volume" number percentage "silent" "x-soft" "soft" "medium" "loud"
|
||||
"x-loud")
|
||||
("white-space" "normal" "pre" "nowrap" "pre-wrap" "pre-line")
|
||||
("widows" integer)
|
||||
("width" length percentage "auto")
|
||||
("word-spacing" "normal" length)
|
||||
("z-index" "auto" integer)
|
||||
;; CSS3
|
||||
("align-content" align-stretch "space-between" "space-around")
|
||||
("align-items" align-stretch "baseline")
|
||||
("align-self" align-items "auto")
|
||||
("animation" animation-name animation-duration animation-timing-function
|
||||
animation-delay animation-iteration-count animation-direction
|
||||
animation-fill-mode)
|
||||
("animation-delay" time)
|
||||
("animation-direction" "normal" "reverse" "alternate" "alternate-reverse")
|
||||
("animation-duration" time)
|
||||
("animation-fill-mode" "none" "forwards" "backwards" "both")
|
||||
("animation-iteration-count" integer "infinite")
|
||||
("animation-name" "none")
|
||||
("animation-play-state" "paused" "running")
|
||||
("animation-timing-function" transition-timing-function
|
||||
"step-start" "step-end" "steps(,)")
|
||||
("backface-visibility" "visible" "hidden")
|
||||
("background-clip" background-origin)
|
||||
("background-origin" "border-box" "padding-box" "content-box")
|
||||
("background-size" length percentage "auto" "cover" "contain")
|
||||
("border-image" border-image-outset border-image-repeat border-image-source
|
||||
border-image-slice border-image-width)
|
||||
("border-image-outset" length)
|
||||
("border-image-repeat" "stretch" "repeat" "round" "space")
|
||||
("border-image-source" uri "none")
|
||||
("border-image-slice" length)
|
||||
("border-image-width" length percentage)
|
||||
("border-radius" length)
|
||||
("border-top-left-radius" length)
|
||||
("border-top-right-radius" length)
|
||||
("border-bottom-left-radius" length)
|
||||
("border-bottom-right-radius" length)
|
||||
("box-decoration-break" "slice" "clone")
|
||||
("box-shadow" length color)
|
||||
("box-sizing" "content-box" "border-box")
|
||||
("break-after" "auto" "always" "avoid" "left" "right" "page" "column"
|
||||
"avoid-page" "avoid-column")
|
||||
("break-before" break-after)
|
||||
("break-inside" "avoid" "auto")
|
||||
("columns" column-width column-count)
|
||||
("column-count" integer)
|
||||
("column-fill" "auto" "balance")
|
||||
("column-gap" length "normal")
|
||||
("column-rule" column-rule-width column-rule-style column-rule-color)
|
||||
("column-rule-color" color)
|
||||
("column-rule-style" border-style)
|
||||
("column-rule-width" border-width)
|
||||
("column-span" "all" "none")
|
||||
("column-width" length "auto")
|
||||
("filter" url "blur()" "brightness()" "contrast()" "drop-shadow()"
|
||||
"grayscale()" "hue-rotate()" "invert()" "opacity()" "saturate()" "sepia()")
|
||||
("flex" flex-grow flex-shrink flex-basis)
|
||||
("flex-basis" percentage length "auto")
|
||||
("flex-direction" "row" "row-reverse" "column" "column-reverse")
|
||||
("flex-flow" flex-direction flex-wrap)
|
||||
("flex-grow" number)
|
||||
("flex-shrink" number)
|
||||
("flex-wrap" "nowrap" "wrap" "wrap-reverse")
|
||||
("font-feature-setting" normal string number)
|
||||
("font-kerning" "auto" "normal" "none")
|
||||
("font-language-override" "normal" string)
|
||||
("font-size-adjust" "none" number)
|
||||
("font-stretch" "normal" "ultra-condensed" "extra-condensed" "condensed"
|
||||
"semi-condensed" "semi-expanded" "expanded" "extra-expanded" "ultra-expanded")
|
||||
("font-synthesis" "none" "weight" "style")
|
||||
("font-variant" font-variant-alternates font-variant-caps
|
||||
font-variant-east-asian font-variant-ligatures font-variant-numeric
|
||||
font-variant-position)
|
||||
("font-variant-alternates" "normal" "historical-forms" "stylistic()"
|
||||
"styleset()" "character-variant()" "swash()" "ornaments()" "annotation()")
|
||||
("font-variant-caps" "normal" "small-caps" "all-small-caps" "petite-caps"
|
||||
"all-petite-caps" "unicase" "titling-caps")
|
||||
("font-variant-east-asian" "jis78" "jis83" "jis90" "jis04" "simplified"
|
||||
"traditional" "full-width" "proportional-width" "ruby")
|
||||
("font-variant-ligatures" "normal" "none" "common-ligatures"
|
||||
"no-common-ligatures" "discretionary-ligatures" "no-discretionary-ligatures"
|
||||
"historical-ligatures" "no-historical-ligatures" "contextual" "no-contextual")
|
||||
("font-variant-numeric" "normal" "ordinal" "slashed-zero"
|
||||
"lining-nums" "oldstyle-nums" "proportional-nums" "tabular-nums"
|
||||
"diagonal-fractions" "stacked-fractions")
|
||||
("font-variant-position" "normal" "sub" "super")
|
||||
("hyphens" "none" "manual" "auto")
|
||||
("justify-content" align-common "space-between" "space-around")
|
||||
("line-break" "auto" "loose" "normal" "strict")
|
||||
("marquee-direction" "forward" "reverse")
|
||||
("marquee-play-count" integer "infinite")
|
||||
("marquee-speed" "slow" "normal" "fast")
|
||||
("marquee-style" "scroll" "slide" "alternate")
|
||||
("opacity" number)
|
||||
("order" number)
|
||||
("outline-offset" length)
|
||||
("overflow-x" overflow)
|
||||
("overflow-y" overflow)
|
||||
("overflow-style" "auto" "marquee-line" "marquee-block")
|
||||
("overflow-wrap" "normal" "break-word")
|
||||
("perspective" "none" length)
|
||||
("perspective-origin" percentage length "left" "center" "right" "top" "bottom")
|
||||
("resize" "none" "both" "horizontal" "vertical")
|
||||
("tab-size" integer length)
|
||||
("text-align-last" "auto" "start" "end" "left" "right" "center" "justify")
|
||||
("text-decoration" text-decoration-color text-decoration-line text-decoration-style)
|
||||
("text-decoration-color" color)
|
||||
("text-decoration-line" "none" "underline" "overline" "line-through" "blink")
|
||||
("text-decoration-style" "solid" "double" "dotted" "dashed" "wavy")
|
||||
("text-overflow" "clip" "ellipsis")
|
||||
("text-shadow" color length)
|
||||
("text-underline-position" "auto" "under" "left" "right")
|
||||
("transform" "matrix(,,,,,)" "translate(,)" "translateX()" "translateY()"
|
||||
"scale()" "scaleX()" "scaleY()" "rotate()" "skewX()" "skewY()" "none")
|
||||
("transform-origin" perspective-origin)
|
||||
("transform-style" "flat" "preserve-3d")
|
||||
("transition" transition-property transition-duration
|
||||
transition-timing-function transition-delay)
|
||||
("transition-delay" time)
|
||||
("transition-duration" time)
|
||||
("transition-timing-function"
|
||||
"ease" "linear" "ease-in" "ease-out" "ease-in-out" "cubic-bezier(,,,)")
|
||||
("transition-property" "none" "all" identifier)
|
||||
("word-wrap" overflow-wrap)
|
||||
("word-break" "normal" "break-all" "keep-all"))
|
||||
"A list of CSS properties and their possible values.")
|
||||
|
||||
(defconst company-css-value-classes
|
||||
'((absolute-size "xx-small" "x-small" "small" "medium" "large" "x-large"
|
||||
"xx-large")
|
||||
(align-common "flex-start" "flex-end" "center")
|
||||
(align-stretch align-common "stretch")
|
||||
(border-style "none" "hidden" "dotted" "dashed" "solid" "double" "groove"
|
||||
"ridge" "inset" "outset")
|
||||
(border-width "thick" "medium" "thin")
|
||||
(color "aqua" "black" "blue" "fuchsia" "gray" "green" "lime" "maroon" "navy"
|
||||
"olive" "orange" "purple" "red" "silver" "teal" "white" "yellow")
|
||||
(counter "counter(,)")
|
||||
(family-name "Courier" "Helvetica" "Times")
|
||||
(generic-family "serif" "sans-serif" "cursive" "fantasy" "monospace")
|
||||
(generic-voice "male" "female" "child")
|
||||
(margin-width "auto") ;; length percentage
|
||||
(relative-size "larger" "smaller")
|
||||
(shape "rect(,,,)")
|
||||
(uri "url()"))
|
||||
"A list of CSS property value classes and their contents.")
|
||||
;; missing, because not completable
|
||||
;; <angle><frequency><identifier><integer><length><number><padding-width>
|
||||
;; <percentage><specific-voice><string><time><uri>
|
||||
|
||||
(defconst company-css-html-tags
|
||||
'("a" "abbr" "acronym" "address" "applet" "area" "b" "base" "basefont" "bdo"
|
||||
"big" "blockquote" "body" "br" "button" "caption" "center" "cite" "code"
|
||||
"col" "colgroup" "dd" "del" "dfn" "dir" "div" "dl" "dt" "em" "fieldset"
|
||||
"font" "form" "frame" "frameset" "h1" "h2" "h3" "h4" "h5" "h6" "head" "hr"
|
||||
"html" "i" "iframe" "img" "input" "ins" "isindex" "kbd" "label" "legend"
|
||||
"li" "link" "map" "menu" "meta" "noframes" "noscript" "object" "ol"
|
||||
"optgroup" "option" "p" "param" "pre" "q" "s" "samp" "script" "select"
|
||||
"small" "span" "strike" "strong" "style" "sub" "sup" "table" "tbody" "td"
|
||||
"textarea" "tfoot" "th" "thead" "title" "tr" "tt" "u" "ul" "var"
|
||||
;; HTML5
|
||||
"section" "article" "aside" "header" "footer" "nav" "figure" "figcaption"
|
||||
"time" "mark" "main")
|
||||
"A list of HTML tags for use in CSS completion.")
|
||||
|
||||
(defconst company-css-pseudo-classes
|
||||
'("active" "after" "before" "first" "first-child" "first-letter" "first-line"
|
||||
"focus" "hover" "lang" "left" "link" "right" "visited")
|
||||
"Identifiers for CSS pseudo-elements and pseudo-classes.")
|
||||
|
||||
(defconst company-css-property-cache (make-hash-table :size 115 :test 'equal))
|
||||
|
||||
(defun company-css-property-values (attribute)
|
||||
"Access the `company-css-property-alist' cached and flattened."
|
||||
(or (gethash attribute company-css-property-cache)
|
||||
(let (results)
|
||||
(dolist (value (cdr (assoc attribute company-css-property-alist)))
|
||||
(if (symbolp value)
|
||||
(dolist (child (or (cdr (assoc value company-css-value-classes))
|
||||
(company-css-property-values
|
||||
(symbol-name value))))
|
||||
(push child results))
|
||||
(push value results)))
|
||||
(setq results (sort results 'string<))
|
||||
(puthash attribute
|
||||
(if (fboundp 'delete-consecutive-dups)
|
||||
(delete-consecutive-dups results)
|
||||
(delete-dups results))
|
||||
company-css-property-cache)
|
||||
results)))
|
||||
|
||||
;;; bracket detection
|
||||
|
||||
(defconst company-css-braces-syntax-table
|
||||
(let ((table (make-syntax-table)))
|
||||
(setf (aref table ?{) '(4 . 125))
|
||||
(setf (aref table ?}) '(5 . 123))
|
||||
table)
|
||||
"A syntax table giving { and } paren syntax.")
|
||||
|
||||
(defun company-css-inside-braces-p ()
|
||||
"Return non-nil, if point is within matched { and }."
|
||||
(ignore-errors
|
||||
(with-syntax-table company-css-braces-syntax-table
|
||||
(let ((parse-sexp-ignore-comments t))
|
||||
(scan-lists (point) -1 1)))))
|
||||
|
||||
;;; tags
|
||||
(defconst company-css-tag-regexp
|
||||
(concat "\\(?:\\`\\|}\\)[[:space:]]*"
|
||||
;; multiple
|
||||
"\\(?:"
|
||||
;; previous tags:
|
||||
"\\(?:#\\|\\_<[[:alpha:]]\\)[[:alnum:]-#]*\\(?:\\[[^]]*\\]\\)?"
|
||||
;; space or selectors
|
||||
"\\(?:[[:space:]]+\\|[[:space:]]*[+,>][[:space:]]*\\)"
|
||||
"\\)*"
|
||||
"\\(\\(?:#\\|\\_<[[:alpha:]]\\)\\(?:[[:alnum:]-#]*\\_>\\)?\\_>\\|\\)"
|
||||
"\\=")
|
||||
"A regular expression matching CSS tags.")
|
||||
|
||||
;;; pseudo id
|
||||
(defconst company-css-pseudo-regexp
|
||||
(concat "\\(?:\\`\\|}\\)[[:space:]]*"
|
||||
;; multiple
|
||||
"\\(?:"
|
||||
;; previous tags:
|
||||
"\\(?:#\\|\\_<[[:alpha:]]\\)[[:alnum:]-#]*\\(?:\\[[^]]*\\]\\)?"
|
||||
;; space or delimiters
|
||||
"\\(?:[[:space:]]+\\|[[:space:]]*[+,>][[:space:]]*\\)"
|
||||
"\\)*"
|
||||
"\\(?:\\(?:\\#\\|\\_<[[:alpha:]]\\)[[:alnum:]-#]*\\):"
|
||||
"\\([[:alpha:]-]+\\_>\\|\\)\\_>\\=")
|
||||
"A regular expression matching CSS pseudo classes.")
|
||||
|
||||
;;; properties
|
||||
|
||||
(defun company-css-grab-property ()
|
||||
"Return the CSS property before point, if any.
|
||||
Returns \"\" if no property found, but feasible at this position."
|
||||
(when (company-css-inside-braces-p)
|
||||
(company-grab-symbol)))
|
||||
|
||||
;;; values
|
||||
(defconst company-css-property-value-regexp
|
||||
"\\_<\\([[:alpha:]-]+\\):\\(?:[^{};]*[[:space:]]+\\)?\\([^{};]*\\_>\\|\\)\\="
|
||||
"A regular expression matching CSS tags.")
|
||||
|
||||
;;;###autoload
|
||||
(defun company-css (command &optional arg &rest ignored)
|
||||
"`company-mode' completion back-end for `css-mode'."
|
||||
(interactive (list 'interactive))
|
||||
(cl-case command
|
||||
(interactive (company-begin-backend 'company-css))
|
||||
(prefix (and (derived-mode-p 'css-mode)
|
||||
(or (company-grab company-css-tag-regexp 1)
|
||||
(company-grab company-css-pseudo-regexp 1)
|
||||
(company-grab company-css-property-value-regexp 2)
|
||||
(company-css-grab-property))))
|
||||
(candidates
|
||||
(cond
|
||||
((company-grab company-css-tag-regexp 1)
|
||||
(all-completions arg company-css-html-tags))
|
||||
((company-grab company-css-pseudo-regexp 1)
|
||||
(all-completions arg company-css-pseudo-classes))
|
||||
((company-grab company-css-property-value-regexp 2)
|
||||
(all-completions arg
|
||||
(company-css-property-values
|
||||
(company-grab company-css-property-value-regexp 1))))
|
||||
((company-css-grab-property)
|
||||
(all-completions arg company-css-property-alist))))
|
||||
(sorted t)))
|
||||
|
||||
(provide 'company-css)
|
||||
;;; company-css.el ends here
|
Binary file not shown.
@ -1,104 +0,0 @@
|
||||
;;; company-dabbrev-code.el --- dabbrev-like company-mode back-end for code -*- lexical-binding: t -*-
|
||||
|
||||
;; Copyright (C) 2009, 2011, 2014 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Nikolaj Schumacher
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
;;
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'company)
|
||||
(require 'company-dabbrev)
|
||||
(require 'cl-lib)
|
||||
|
||||
(defgroup company-dabbrev-code nil
|
||||
"dabbrev-like completion back-end for code."
|
||||
:group 'company)
|
||||
|
||||
(defcustom company-dabbrev-code-modes
|
||||
'(prog-mode
|
||||
batch-file-mode csharp-mode css-mode erlang-mode haskell-mode jde-mode
|
||||
lua-mode python-mode)
|
||||
"Modes that use `company-dabbrev-code'.
|
||||
In all these modes (and their derivatives) `company-dabbrev-code' will
|
||||
complete only symbols, not text in comments or strings. In other modes
|
||||
`company-dabbrev-code' will pass control to other back-ends
|
||||
\(e.g. `company-dabbrev'\). Value t means complete in all modes."
|
||||
:type '(choice (repeat (symbol :tag "Major mode"))
|
||||
(const tag "All modes" t)))
|
||||
|
||||
(defcustom company-dabbrev-code-other-buffers t
|
||||
"Determines whether `company-dabbrev-code' should search other buffers.
|
||||
If `all', search all other buffers, except the ignored ones. If t, search
|
||||
buffers with the same major mode. If `code', search all buffers with major
|
||||
modes in `company-dabbrev-code-modes', or derived from one of them. See
|
||||
also `company-dabbrev-code-time-limit'."
|
||||
:type '(choice (const :tag "Off" nil)
|
||||
(const :tag "Same major mode" t)
|
||||
(const :tag "Code major modes" code)
|
||||
(const :tag "All" all)))
|
||||
|
||||
(defcustom company-dabbrev-code-time-limit .1
|
||||
"Determines how long `company-dabbrev-code' should look for matches."
|
||||
:type '(choice (const :tag "Off" nil)
|
||||
(number :tag "Seconds")))
|
||||
|
||||
(defcustom company-dabbrev-code-everywhere nil
|
||||
"Non-nil to offer completions in comments and strings."
|
||||
:type 'boolean)
|
||||
|
||||
(defcustom company-dabbrev-code-ignore-case nil
|
||||
"Non-nil to ignore case when collecting completion candidates."
|
||||
:type 'boolean)
|
||||
|
||||
(defsubst company-dabbrev-code--make-regexp (prefix)
|
||||
(concat "\\_<" (if (equal prefix "")
|
||||
"\\([a-zA-Z]\\|\\s_\\)"
|
||||
(regexp-quote prefix))
|
||||
"\\(\\sw\\|\\s_\\)*\\_>"))
|
||||
|
||||
;;;###autoload
|
||||
(defun company-dabbrev-code (command &optional arg &rest ignored)
|
||||
"dabbrev-like `company-mode' back-end for code.
|
||||
The back-end looks for all symbols in the current buffer that aren't in
|
||||
comments or strings."
|
||||
(interactive (list 'interactive))
|
||||
(cl-case command
|
||||
(interactive (company-begin-backend 'company-dabbrev-code))
|
||||
(prefix (and (or (eq t company-dabbrev-code-modes)
|
||||
(apply #'derived-mode-p company-dabbrev-code-modes))
|
||||
(or company-dabbrev-code-everywhere
|
||||
(not (company-in-string-or-comment)))
|
||||
(or (company-grab-symbol) 'stop)))
|
||||
(candidates (let ((case-fold-search company-dabbrev-code-ignore-case))
|
||||
(company-dabbrev--search
|
||||
(company-dabbrev-code--make-regexp arg)
|
||||
company-dabbrev-code-time-limit
|
||||
(pcase company-dabbrev-code-other-buffers
|
||||
(`t (list major-mode))
|
||||
(`code company-dabbrev-code-modes)
|
||||
(`all `all))
|
||||
t)))
|
||||
(ignore-case company-dabbrev-code-ignore-case)
|
||||
(duplicates t)))
|
||||
|
||||
(provide 'company-dabbrev-code)
|
||||
;;; company-dabbrev-code.el ends here
|
Binary file not shown.
@ -1,163 +0,0 @@
|
||||
;;; company-dabbrev.el --- dabbrev-like company-mode completion back-end -*- lexical-binding: t -*-
|
||||
|
||||
;; Copyright (C) 2009, 2011, 2014 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Nikolaj Schumacher
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
;;
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'company)
|
||||
(require 'cl-lib)
|
||||
|
||||
(defgroup company-dabbrev nil
|
||||
"dabbrev-like completion back-end."
|
||||
:group 'company)
|
||||
|
||||
(defcustom company-dabbrev-other-buffers 'all
|
||||
"Determines whether `company-dabbrev' should search other buffers.
|
||||
If `all', search all other buffers, except the ignored ones. If t, search
|
||||
buffers with the same major mode. See also `company-dabbrev-time-limit'."
|
||||
:type '(choice (const :tag "Off" nil)
|
||||
(const :tag "Same major mode" t)
|
||||
(const :tag "All" all)))
|
||||
|
||||
(defcustom company-dabbrev-ignore-buffers "\\`[ *]"
|
||||
"Regexp matching the names of buffers to ignore."
|
||||
:type 'regexp)
|
||||
|
||||
(defcustom company-dabbrev-time-limit .1
|
||||
"Determines how many seconds `company-dabbrev' should look for matches."
|
||||
:type '(choice (const :tag "Off" nil)
|
||||
(number :tag "Seconds")))
|
||||
|
||||
(defcustom company-dabbrev-char-regexp "\\sw"
|
||||
"A regular expression matching the characters `company-dabbrev' looks for."
|
||||
:type 'regexp)
|
||||
|
||||
(defcustom company-dabbrev-ignore-case 'keep-prefix
|
||||
"Non-nil to ignore case when collecting completion candidates.
|
||||
When it's `keep-prefix', the text before point will remain unchanged after
|
||||
candidate is inserted, even some of its characters have different case.")
|
||||
|
||||
(defcustom company-dabbrev-downcase 'case-replace
|
||||
"Whether to downcase the returned candidates.
|
||||
|
||||
The value of nil means keep them as-is.
|
||||
`case-replace' means use the value of `case-replace'.
|
||||
Any other value means downcase.
|
||||
|
||||
If you set this value to nil, you may also want to set
|
||||
`company-dabbrev-ignore-case' to any value other than `keep-prefix'.")
|
||||
|
||||
(defcustom company-dabbrev-minimum-length 4
|
||||
"The minimum length for the completion candidate to be included.
|
||||
This variable affects both `company-dabbrev' and `company-dabbrev-code'."
|
||||
:type 'integer
|
||||
:package-version '(company . "0.8.3"))
|
||||
|
||||
(defmacro company-dabrev--time-limit-while (test start limit &rest body)
|
||||
(declare (indent 3) (debug t))
|
||||
`(let ((company-time-limit-while-counter 0))
|
||||
(catch 'done
|
||||
(while ,test
|
||||
,@body
|
||||
(and ,limit
|
||||
(eq (cl-incf company-time-limit-while-counter) 25)
|
||||
(setq company-time-limit-while-counter 0)
|
||||
(> (float-time (time-since ,start)) ,limit)
|
||||
(throw 'done 'company-time-out))))))
|
||||
|
||||
(defsubst company-dabbrev--make-regexp (prefix)
|
||||
(concat "\\<" (if (equal prefix "")
|
||||
company-dabbrev-char-regexp
|
||||
(regexp-quote prefix))
|
||||
"\\(" company-dabbrev-char-regexp "\\)*\\>"))
|
||||
|
||||
(defun company-dabbrev--search-buffer (regexp pos symbols start limit
|
||||
ignore-comments)
|
||||
(save-excursion
|
||||
(let (match)
|
||||
(goto-char (if pos (1- pos) (point-min)))
|
||||
;; search before pos
|
||||
(company-dabrev--time-limit-while (re-search-backward regexp nil t)
|
||||
start limit
|
||||
(setq match (match-string-no-properties 0))
|
||||
(if (and ignore-comments (company-in-string-or-comment))
|
||||
(goto-char (nth 8 (syntax-ppss)))
|
||||
(when (>= (length match) company-dabbrev-minimum-length)
|
||||
(push match symbols))))
|
||||
(goto-char (or pos (point-min)))
|
||||
;; search after pos
|
||||
(company-dabrev--time-limit-while (re-search-forward regexp nil t)
|
||||
start limit
|
||||
(setq match (match-string-no-properties 0))
|
||||
(if (and ignore-comments (company-in-string-or-comment))
|
||||
(re-search-forward "\\s>\\|\\s!\\|\\s\"" nil t)
|
||||
(when (>= (length match) company-dabbrev-minimum-length)
|
||||
(push match symbols))))
|
||||
symbols)))
|
||||
|
||||
(defun company-dabbrev--search (regexp &optional limit other-buffer-modes
|
||||
ignore-comments)
|
||||
(let* ((start (current-time))
|
||||
(symbols (company-dabbrev--search-buffer regexp (point) nil start limit
|
||||
ignore-comments)))
|
||||
(when other-buffer-modes
|
||||
(cl-dolist (buffer (delq (current-buffer) (buffer-list)))
|
||||
(with-current-buffer buffer
|
||||
(when (if (eq other-buffer-modes 'all)
|
||||
(not (string-match-p company-dabbrev-ignore-buffers
|
||||
(buffer-name)))
|
||||
(apply #'derived-mode-p other-buffer-modes))
|
||||
(setq symbols
|
||||
(company-dabbrev--search-buffer regexp nil symbols start
|
||||
limit ignore-comments))))
|
||||
(and limit
|
||||
(> (float-time (time-since start)) limit)
|
||||
(cl-return))))
|
||||
symbols))
|
||||
|
||||
;;;###autoload
|
||||
(defun company-dabbrev (command &optional arg &rest ignored)
|
||||
"dabbrev-like `company-mode' completion back-end."
|
||||
(interactive (list 'interactive))
|
||||
(cl-case command
|
||||
(interactive (company-begin-backend 'company-dabbrev))
|
||||
(prefix (company-grab-word))
|
||||
(candidates
|
||||
(let* ((case-fold-search company-dabbrev-ignore-case)
|
||||
(words (company-dabbrev--search (company-dabbrev--make-regexp arg)
|
||||
company-dabbrev-time-limit
|
||||
(pcase company-dabbrev-other-buffers
|
||||
(`t (list major-mode))
|
||||
(`all `all))))
|
||||
(downcase-p (if (eq company-dabbrev-downcase 'case-replace)
|
||||
case-replace
|
||||
company-dabbrev-downcase)))
|
||||
(if downcase-p
|
||||
(mapcar 'downcase words)
|
||||
words)))
|
||||
(ignore-case company-dabbrev-ignore-case)
|
||||
(duplicates t)))
|
||||
|
||||
(provide 'company-dabbrev)
|
||||
;;; company-dabbrev.el ends here
|
Binary file not shown.
@ -1,183 +0,0 @@
|
||||
;;; company-eclim.el --- company-mode completion back-end for Eclim
|
||||
|
||||
;; Copyright (C) 2009, 2011, 2013 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Nikolaj Schumacher
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
;;
|
||||
;; Using `emacs-eclim' together with (or instead of) this back-end is
|
||||
;; recommended, as it allows you to use other Eclim features.
|
||||
;;
|
||||
;; The alternative back-end provided by `emacs-eclim' uses `yasnippet'
|
||||
;; instead of `company-template' to expand function calls, and it supports
|
||||
;; some languages other than Java.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'company)
|
||||
(require 'company-template)
|
||||
(require 'cl-lib)
|
||||
|
||||
(defgroup company-eclim nil
|
||||
"Completion back-end for Eclim."
|
||||
:group 'company)
|
||||
|
||||
(defun company-eclim-executable-find ()
|
||||
(let (file)
|
||||
(cl-dolist (eclipse-root '("/Applications/eclipse" "/usr/lib/eclipse"
|
||||
"/usr/local/lib/eclipse"))
|
||||
(and (file-exists-p (setq file (expand-file-name "plugins" eclipse-root)))
|
||||
(setq file (car (last (directory-files file t "^org.eclim_"))))
|
||||
(file-exists-p (setq file (expand-file-name "bin/eclim" file)))
|
||||
(cl-return file)))))
|
||||
|
||||
(defcustom company-eclim-executable
|
||||
(or (executable-find "eclim") (company-eclim-executable-find))
|
||||
"Location of eclim executable."
|
||||
:type 'file)
|
||||
|
||||
(defcustom company-eclim-auto-save t
|
||||
"Determines whether to save the buffer when retrieving completions.
|
||||
eclim can only complete correctly when the buffer has been saved."
|
||||
:type '(choice (const :tag "Off" nil)
|
||||
(const :tag "On" t)))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defvar-local company-eclim--project-dir 'unknown)
|
||||
|
||||
(defvar-local company-eclim--project-name nil)
|
||||
|
||||
(declare-function json-read "json")
|
||||
(defvar json-array-type)
|
||||
|
||||
(defun company-eclim--call-process (&rest args)
|
||||
(let ((coding-system-for-read 'utf-8)
|
||||
res)
|
||||
(require 'json)
|
||||
(with-temp-buffer
|
||||
(if (= 0 (setq res (apply 'call-process company-eclim-executable nil t nil
|
||||
"-command" args)))
|
||||
(let ((json-array-type 'list))
|
||||
(goto-char (point-min))
|
||||
(unless (eobp)
|
||||
(json-read)))
|
||||
(message "Company-eclim command failed with error %d:\n%s" res
|
||||
(buffer-substring (point-min) (point-max)))
|
||||
nil))))
|
||||
|
||||
(defun company-eclim--project-list ()
|
||||
(company-eclim--call-process "project_list"))
|
||||
|
||||
(defun company-eclim--project-dir ()
|
||||
(if (eq company-eclim--project-dir 'unknown)
|
||||
(setq company-eclim--project-dir
|
||||
(directory-file-name
|
||||
(expand-file-name
|
||||
(locate-dominating-file buffer-file-name ".project"))))
|
||||
company-eclim--project-dir))
|
||||
|
||||
(defun company-eclim--project-name ()
|
||||
(or company-eclim--project-name
|
||||
(let ((dir (company-eclim--project-dir)))
|
||||
(when dir
|
||||
(setq company-eclim--project-name
|
||||
(cl-loop for project in (company-eclim--project-list)
|
||||
when (equal (cdr (assoc 'path project)) dir)
|
||||
return (cdr (assoc 'name project))))))))
|
||||
|
||||
(defun company-eclim--candidates (prefix)
|
||||
(interactive "d")
|
||||
(let ((project-file (file-relative-name buffer-file-name
|
||||
(company-eclim--project-dir)))
|
||||
completions)
|
||||
(when company-eclim-auto-save
|
||||
(when (buffer-modified-p)
|
||||
(basic-save-buffer))
|
||||
;; FIXME: Sometimes this isn't finished when we complete.
|
||||
(company-eclim--call-process "java_src_update"
|
||||
"-p" (company-eclim--project-name)
|
||||
"-f" project-file))
|
||||
(dolist (item (cdr (assoc 'completions
|
||||
(company-eclim--call-process
|
||||
"java_complete" "-p" (company-eclim--project-name)
|
||||
"-f" project-file
|
||||
"-o" (number-to-string
|
||||
(company-eclim--search-point prefix))
|
||||
"-e" "utf-8"
|
||||
"-l" "standard"))))
|
||||
(let* ((meta (cdr (assoc 'info item)))
|
||||
(completion meta))
|
||||
(when (string-match " ?[(:-]" completion)
|
||||
(setq completion (substring completion 0 (match-beginning 0))))
|
||||
(put-text-property 0 1 'meta meta completion)
|
||||
(push completion completions)))
|
||||
(let ((completion-ignore-case nil))
|
||||
(all-completions prefix completions))))
|
||||
|
||||
(defun company-eclim--search-point (prefix)
|
||||
(if (or (cl-plusp (length prefix)) (eq (char-before) ?.))
|
||||
(1- (point))
|
||||
(point)))
|
||||
|
||||
(defun company-eclim--meta (candidate)
|
||||
(get-text-property 0 'meta candidate))
|
||||
|
||||
(defun company-eclim--annotation (candidate)
|
||||
(let ((meta (company-eclim--meta candidate)))
|
||||
(when (string-match "\\(([^-]*\\) -" meta)
|
||||
(substring meta (match-beginning 1) (match-end 1)))))
|
||||
|
||||
(defun company-eclim--prefix ()
|
||||
(let ((prefix (company-grab-symbol)))
|
||||
(when prefix
|
||||
;; Completion candidates for annotations don't include '@'.
|
||||
(when (eq ?@ (string-to-char prefix))
|
||||
(setq prefix (substring prefix 1)))
|
||||
prefix)))
|
||||
|
||||
(defun company-eclim (command &optional arg &rest ignored)
|
||||
"`company-mode' completion back-end for Eclim.
|
||||
Eclim provides access to Eclipse Java IDE features for other editors.
|
||||
|
||||
Eclim version 1.7.13 or newer (?) is required.
|
||||
|
||||
Completions only work correctly when the buffer has been saved.
|
||||
`company-eclim-auto-save' determines whether to do this automatically."
|
||||
(interactive (list 'interactive))
|
||||
(cl-case command
|
||||
(interactive (company-begin-backend 'company-eclim))
|
||||
(prefix (and (derived-mode-p 'java-mode 'jde-mode)
|
||||
buffer-file-name
|
||||
company-eclim-executable
|
||||
(company-eclim--project-name)
|
||||
(not (company-in-string-or-comment))
|
||||
(or (company-eclim--prefix) 'stop)))
|
||||
(candidates (company-eclim--candidates arg))
|
||||
(meta (company-eclim--meta arg))
|
||||
;; because "" doesn't return everything
|
||||
(no-cache (equal arg ""))
|
||||
(annotation (company-eclim--annotation arg))
|
||||
(post-completion (let ((anno (company-eclim--annotation arg)))
|
||||
(when anno
|
||||
(insert anno)
|
||||
(company-template-c-like-templatify anno))))))
|
||||
|
||||
(provide 'company-eclim)
|
||||
;;; company-eclim.el ends here
|
Binary file not shown.
@ -1,225 +0,0 @@
|
||||
;;; company-elisp.el --- company-mode completion back-end for Emacs Lisp -*- lexical-binding: t -*-
|
||||
|
||||
;; Copyright (C) 2009, 2011-2013 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Nikolaj Schumacher
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
;;
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'company)
|
||||
(require 'cl-lib)
|
||||
(require 'help-mode)
|
||||
(require 'find-func)
|
||||
|
||||
(defgroup company-elisp nil
|
||||
"Completion back-end for Emacs Lisp."
|
||||
:group 'company)
|
||||
|
||||
(defcustom company-elisp-detect-function-context t
|
||||
"If enabled, offer Lisp functions only in appropriate contexts.
|
||||
Functions are offered for completion only after ' and \(."
|
||||
:type '(choice (const :tag "Off" nil)
|
||||
(const :tag "On" t)))
|
||||
|
||||
(defcustom company-elisp-show-locals-first t
|
||||
"If enabled, locally bound variables and functions are displayed
|
||||
first in the candidates list."
|
||||
:type '(choice (const :tag "Off" nil)
|
||||
(const :tag "On" t)))
|
||||
|
||||
(defun company-elisp--prefix ()
|
||||
(let ((prefix (company-grab-symbol)))
|
||||
(if prefix
|
||||
(when (if (company-in-string-or-comment)
|
||||
(= (char-before (- (point) (length prefix))) ?`)
|
||||
(company-elisp--should-complete))
|
||||
prefix)
|
||||
'stop)))
|
||||
|
||||
(defun company-elisp--predicate (symbol)
|
||||
(or (boundp symbol)
|
||||
(fboundp symbol)
|
||||
(facep symbol)
|
||||
(featurep symbol)))
|
||||
|
||||
(defun company-elisp--fns-regexp (&rest names)
|
||||
(concat "\\_<\\(?:cl-\\)?" (regexp-opt names) "\\*?\\_>"))
|
||||
|
||||
(defvar company-elisp-parse-limit 30)
|
||||
(defvar company-elisp-parse-depth 100)
|
||||
|
||||
(defvar company-elisp-defun-names '("defun" "defmacro" "defsubst"))
|
||||
|
||||
(defvar company-elisp-var-binding-regexp
|
||||
(apply #'company-elisp--fns-regexp "let" "lambda" "lexical-let"
|
||||
company-elisp-defun-names)
|
||||
"Regular expression matching head of a multiple variable bindings form.")
|
||||
|
||||
(defvar company-elisp-var-binding-regexp-1
|
||||
(company-elisp--fns-regexp "dolist" "dotimes")
|
||||
"Regular expression matching head of a form with one variable binding.")
|
||||
|
||||
(defvar company-elisp-fun-binding-regexp
|
||||
(company-elisp--fns-regexp "flet" "labels")
|
||||
"Regular expression matching head of a function bindings form.")
|
||||
|
||||
(defvar company-elisp-defuns-regexp
|
||||
(concat "([ \t\n]*"
|
||||
(apply #'company-elisp--fns-regexp company-elisp-defun-names)))
|
||||
|
||||
(defun company-elisp--should-complete ()
|
||||
(let ((start (point))
|
||||
(depth (car (syntax-ppss))))
|
||||
(not
|
||||
(when (> depth 0)
|
||||
(save-excursion
|
||||
(up-list (- depth))
|
||||
(when (looking-at company-elisp-defuns-regexp)
|
||||
(forward-char)
|
||||
(forward-sexp 1)
|
||||
(unless (= (point) start)
|
||||
(condition-case nil
|
||||
(let ((args-end (scan-sexps (point) 2)))
|
||||
(or (null args-end)
|
||||
(> args-end start)))
|
||||
(scan-error
|
||||
t)))))))))
|
||||
|
||||
(defun company-elisp--locals (prefix functions-p)
|
||||
(let ((regexp (concat "[ \t\n]*\\(\\_<" (regexp-quote prefix)
|
||||
"\\(?:\\sw\\|\\s_\\)*\\_>\\)"))
|
||||
(pos (point))
|
||||
res)
|
||||
(condition-case nil
|
||||
(save-excursion
|
||||
(dotimes (_ company-elisp-parse-depth)
|
||||
(up-list -1)
|
||||
(save-excursion
|
||||
(when (eq (char-after) ?\()
|
||||
(forward-char 1)
|
||||
(when (ignore-errors
|
||||
(save-excursion (forward-list)
|
||||
(<= (point) pos)))
|
||||
(skip-chars-forward " \t\n")
|
||||
(cond
|
||||
((looking-at (if functions-p
|
||||
company-elisp-fun-binding-regexp
|
||||
company-elisp-var-binding-regexp))
|
||||
(down-list 1)
|
||||
(condition-case nil
|
||||
(dotimes (_ company-elisp-parse-limit)
|
||||
(save-excursion
|
||||
(when (looking-at "[ \t\n]*(")
|
||||
(down-list 1))
|
||||
(when (looking-at regexp)
|
||||
(cl-pushnew (match-string-no-properties 1) res)))
|
||||
(forward-sexp))
|
||||
(scan-error nil)))
|
||||
((unless functions-p
|
||||
(looking-at company-elisp-var-binding-regexp-1))
|
||||
(down-list 1)
|
||||
(when (looking-at regexp)
|
||||
(cl-pushnew (match-string-no-properties 1) res)))))))))
|
||||
(scan-error nil))
|
||||
res))
|
||||
|
||||
(defun company-elisp-candidates (prefix)
|
||||
(let* ((predicate (company-elisp--candidates-predicate prefix))
|
||||
(locals (company-elisp--locals prefix (eq predicate 'fboundp)))
|
||||
(globals (company-elisp--globals prefix predicate))
|
||||
(locals (cl-loop for local in locals
|
||||
when (not (member local globals))
|
||||
collect local)))
|
||||
(if company-elisp-show-locals-first
|
||||
(append (sort locals 'string<)
|
||||
(sort globals 'string<))
|
||||
(append locals globals))))
|
||||
|
||||
(defun company-elisp--globals (prefix predicate)
|
||||
(all-completions prefix obarray predicate))
|
||||
|
||||
(defun company-elisp--candidates-predicate (prefix)
|
||||
(let* ((completion-ignore-case nil)
|
||||
(beg (- (point) (length prefix)))
|
||||
(before (char-before beg)))
|
||||
(if (and company-elisp-detect-function-context
|
||||
(not (memq before '(?' ?`))))
|
||||
(if (and (eq before ?\()
|
||||
(not
|
||||
(save-excursion
|
||||
(ignore-errors
|
||||
(goto-char (1- beg))
|
||||
(or (company-elisp--before-binding-varlist-p)
|
||||
(progn
|
||||
(up-list -1)
|
||||
(company-elisp--before-binding-varlist-p)))))))
|
||||
'fboundp
|
||||
'boundp)
|
||||
'company-elisp--predicate)))
|
||||
|
||||
(defun company-elisp--before-binding-varlist-p ()
|
||||
(save-excursion
|
||||
(and (prog1 (search-backward "(")
|
||||
(forward-char 1))
|
||||
(looking-at company-elisp-var-binding-regexp))))
|
||||
|
||||
(defun company-elisp--doc (symbol)
|
||||
(let* ((symbol (intern symbol))
|
||||
(doc (if (fboundp symbol)
|
||||
(documentation symbol t)
|
||||
(documentation-property symbol 'variable-documentation t))))
|
||||
(and (stringp doc)
|
||||
(string-match ".*$" doc)
|
||||
(match-string 0 doc))))
|
||||
|
||||
;;;###autoload
|
||||
(defun company-elisp (command &optional arg &rest ignored)
|
||||
"`company-mode' completion back-end for Emacs Lisp."
|
||||
(interactive (list 'interactive))
|
||||
(cl-case command
|
||||
(interactive (company-begin-backend 'company-elisp))
|
||||
(prefix (and (derived-mode-p 'emacs-lisp-mode 'inferior-emacs-lisp-mode)
|
||||
(company-elisp--prefix)))
|
||||
(candidates (company-elisp-candidates arg))
|
||||
(sorted company-elisp-show-locals-first)
|
||||
(meta (company-elisp--doc arg))
|
||||
(doc-buffer (let ((symbol (intern arg)))
|
||||
(save-window-excursion
|
||||
(ignore-errors
|
||||
(cond
|
||||
((fboundp symbol) (describe-function symbol))
|
||||
((boundp symbol) (describe-variable symbol))
|
||||
((featurep symbol) (describe-package symbol))
|
||||
((facep symbol) (describe-face symbol))
|
||||
(t (signal 'user-error nil)))
|
||||
(help-buffer)))))
|
||||
(location (let ((sym (intern arg)))
|
||||
(cond
|
||||
((fboundp sym) (find-definition-noselect sym nil))
|
||||
((boundp sym) (find-definition-noselect sym 'defvar))
|
||||
((featurep sym) (cons (find-file-noselect (find-library-name
|
||||
(symbol-name sym)))
|
||||
0))
|
||||
((facep sym) (find-definition-noselect sym 'defface)))))))
|
||||
|
||||
(provide 'company-elisp)
|
||||
;;; company-elisp.el ends here
|
Binary file not shown.
@ -1,94 +0,0 @@
|
||||
;;; company-etags.el --- company-mode completion back-end for etags
|
||||
|
||||
;; Copyright (C) 2009-2011, 2014 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Nikolaj Schumacher
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
;;
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'company)
|
||||
(require 'cl-lib)
|
||||
(require 'etags)
|
||||
|
||||
(defgroup company-etags nil
|
||||
"Completion back-end for etags."
|
||||
:group 'company)
|
||||
|
||||
(defcustom company-etags-use-main-table-list t
|
||||
"Always search `tags-table-list' if set.
|
||||
If this is disabled, `company-etags' will try to find the one table for each
|
||||
buffer automatically."
|
||||
:type '(choice (const :tag "off" nil)
|
||||
(const :tag "on" t)))
|
||||
|
||||
(defcustom company-etags-ignore-case nil
|
||||
"Non-nil to ignore case in completion candidates."
|
||||
:type 'boolean
|
||||
:package-version '(company . "0.7.3"))
|
||||
|
||||
(defvar company-etags-modes '(prog-mode c-mode objc-mode c++-mode java-mode
|
||||
jde-mode pascal-mode perl-mode python-mode))
|
||||
|
||||
(defvar-local company-etags-buffer-table 'unknown)
|
||||
|
||||
(defun company-etags-find-table ()
|
||||
(let ((file (locate-dominating-file (or buffer-file-name
|
||||
default-directory)
|
||||
"TAGS")))
|
||||
(when (and file (file-regular-p file))
|
||||
(list (expand-file-name file)))))
|
||||
|
||||
(defun company-etags-buffer-table ()
|
||||
(or (and company-etags-use-main-table-list tags-table-list)
|
||||
(if (eq company-etags-buffer-table 'unknown)
|
||||
(setq company-etags-buffer-table (company-etags-find-table))
|
||||
company-etags-buffer-table)))
|
||||
|
||||
(defun company-etags--candidates (prefix)
|
||||
(let ((tags-table-list (company-etags-buffer-table))
|
||||
(completion-ignore-case company-etags-ignore-case))
|
||||
(and (or tags-file-name tags-table-list)
|
||||
(fboundp 'tags-completion-table)
|
||||
(save-excursion
|
||||
(visit-tags-table-buffer)
|
||||
(all-completions prefix (tags-completion-table))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun company-etags (command &optional arg &rest ignored)
|
||||
"`company-mode' completion back-end for etags."
|
||||
(interactive (list 'interactive))
|
||||
(cl-case command
|
||||
(interactive (company-begin-backend 'company-etags))
|
||||
(prefix (and (apply 'derived-mode-p company-etags-modes)
|
||||
(not (company-in-string-or-comment))
|
||||
(company-etags-buffer-table)
|
||||
(or (company-grab-symbol) 'stop)))
|
||||
(candidates (company-etags--candidates arg))
|
||||
(location (let ((tags-table-list (company-etags-buffer-table)))
|
||||
(when (fboundp 'find-tag-noselect)
|
||||
(save-excursion
|
||||
(let ((buffer (find-tag-noselect arg)))
|
||||
(cons buffer (with-current-buffer buffer (point))))))))
|
||||
(ignore-case company-etags-ignore-case)))
|
||||
|
||||
(provide 'company-etags)
|
||||
;;; company-etags.el ends here
|
Binary file not shown.
@ -1,105 +0,0 @@
|
||||
;;; company-files.el --- company-mode completion back-end for file paths
|
||||
|
||||
;; Copyright (C) 2009-2011, 2014 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Nikolaj Schumacher
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
;;
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'company)
|
||||
(require 'cl-lib)
|
||||
|
||||
(defun company-files--directory-files (dir prefix)
|
||||
(ignore-errors
|
||||
(if (equal prefix "")
|
||||
(directory-files dir nil "\\`[^.]\\|\\`.[^.]")
|
||||
(file-name-all-completions prefix dir))))
|
||||
|
||||
(defvar company-files--regexps
|
||||
(let* ((root (if (eq system-type 'windows-nt)
|
||||
"[a-zA-Z]:/"
|
||||
"/"))
|
||||
(begin (concat "\\(?:\\.\\{1,2\\}/\\|~/\\|" root "\\)")))
|
||||
(list (concat "\"\\(" begin "[^\"\n]*\\)")
|
||||
(concat "\'\\(" begin "[^\'\n]*\\)")
|
||||
(concat "\\(?:[ \t]\\|^\\)\\(" begin "[^ \t\n]*\\)"))))
|
||||
|
||||
(defun company-files--grab-existing-name ()
|
||||
;; Grab the file name.
|
||||
;; When surrounded with quotes, it can include spaces.
|
||||
(let (file dir)
|
||||
(and (cl-dolist (regexp company-files--regexps)
|
||||
(when (setq file (company-grab-line regexp 1))
|
||||
(cl-return file)))
|
||||
(setq dir (file-name-directory file))
|
||||
(not (string-match "//" dir))
|
||||
(file-exists-p dir)
|
||||
(file-name-all-completions (file-name-nondirectory file) dir)
|
||||
file)))
|
||||
|
||||
(defvar company-files--completion-cache nil)
|
||||
|
||||
(defun company-files--complete (prefix)
|
||||
(let* ((dir (file-name-directory prefix))
|
||||
(key (list (file-name-nondirectory prefix)
|
||||
(expand-file-name dir)
|
||||
(nth 5 (file-attributes dir))))
|
||||
(file (file-name-nondirectory prefix))
|
||||
(completion-ignore-case read-file-name-completion-ignore-case)
|
||||
candidates directories)
|
||||
(unless (company-file--keys-match-p key (car company-files--completion-cache))
|
||||
(dolist (file (company-files--directory-files dir file))
|
||||
(setq file (concat dir file))
|
||||
(push file candidates)
|
||||
(when (file-directory-p file)
|
||||
(push file directories)))
|
||||
(dolist (directory (reverse directories))
|
||||
;; Add one level of children.
|
||||
(dolist (child (company-files--directory-files directory ""))
|
||||
(push (concat directory
|
||||
(unless (eq (aref directory (1- (length directory))) ?/) "/")
|
||||
child) candidates)))
|
||||
(setq company-files--completion-cache (cons key (nreverse candidates))))
|
||||
(all-completions prefix
|
||||
(cdr company-files--completion-cache))))
|
||||
|
||||
(defun company-file--keys-match-p (new old)
|
||||
(and (equal (cdr old) (cdr new))
|
||||
(string-prefix-p (car old) (car new))))
|
||||
|
||||
;;;###autoload
|
||||
(defun company-files (command &optional arg &rest ignored)
|
||||
"`company-mode' completion back-end existing file names.
|
||||
Completions works for proper absolute and relative files paths.
|
||||
File paths with spaces are only supported inside strings."
|
||||
(interactive (list 'interactive))
|
||||
(cl-case command
|
||||
(interactive (company-begin-backend 'company-files))
|
||||
(prefix (company-files--grab-existing-name))
|
||||
(candidates (company-files--complete arg))
|
||||
(location (cons (dired-noselect
|
||||
(file-name-directory (directory-file-name arg))) 1))
|
||||
(sorted t)
|
||||
(no-cache t)))
|
||||
|
||||
(provide 'company-files)
|
||||
;;; company-files.el ends here
|
Binary file not shown.
@ -1,115 +0,0 @@
|
||||
;;; company-gtags.el --- company-mode completion back-end for GNU Global
|
||||
|
||||
;; Copyright (C) 2009-2011, 2014 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Nikolaj Schumacher
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
;;
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'company)
|
||||
(require 'cl-lib)
|
||||
|
||||
(defgroup company-gtags nil
|
||||
"Completion back-end for GNU Global."
|
||||
:group 'company)
|
||||
|
||||
(defcustom company-gtags-executable
|
||||
(executable-find "global")
|
||||
"Location of GNU global executable."
|
||||
:type 'string)
|
||||
|
||||
(define-obsolete-variable-alias
|
||||
'company-gtags-gnu-global-program-name
|
||||
'company-gtags-executable "earlier")
|
||||
|
||||
(defcustom company-gtags-insert-arguments t
|
||||
"When non-nil, insert function arguments as a template after completion."
|
||||
:type 'boolean
|
||||
:package-version '(company . "0.8.1"))
|
||||
|
||||
(defvar-local company-gtags--tags-available-p 'unknown)
|
||||
|
||||
(defcustom company-gtags-modes '(prog-mode jde-mode)
|
||||
"Modes that use `company-gtags'.
|
||||
In all these modes (and their derivatives) `company-gtags' will perform
|
||||
completion."
|
||||
:type '(repeat (symbol :tag "Major mode"))
|
||||
:package-version '(company . "0.8.4"))
|
||||
|
||||
(defun company-gtags--tags-available-p ()
|
||||
(if (eq company-gtags--tags-available-p 'unknown)
|
||||
(setq company-gtags--tags-available-p
|
||||
(locate-dominating-file buffer-file-name "GTAGS"))
|
||||
company-gtags--tags-available-p))
|
||||
|
||||
(defun company-gtags--fetch-tags (prefix)
|
||||
(with-temp-buffer
|
||||
(let (tags)
|
||||
(when (= 0 (call-process company-gtags-executable nil
|
||||
(list (current-buffer) nil) nil "-xGq" (concat "^" prefix)))
|
||||
(goto-char (point-min))
|
||||
(cl-loop while
|
||||
(re-search-forward (concat
|
||||
"^"
|
||||
"\\([^ ]*\\)" ;; completion
|
||||
"[ \t]+\\([[:digit:]]+\\)" ;; linum
|
||||
"[ \t]+\\([^ \t]+\\)" ;; file
|
||||
"[ \t]+\\(.*\\)" ;; definition
|
||||
"$"
|
||||
) nil t)
|
||||
collect
|
||||
(propertize (match-string 1)
|
||||
'meta (match-string 4)
|
||||
'location (cons (expand-file-name (match-string 3))
|
||||
(string-to-number (match-string 2)))
|
||||
))))))
|
||||
|
||||
(defun company-gtags--annotation (arg)
|
||||
(let ((meta (get-text-property 0 'meta arg)))
|
||||
(when (string-match (concat arg "\\((.*)\\).*") meta)
|
||||
(match-string 1 meta))))
|
||||
|
||||
;;;###autoload
|
||||
(defun company-gtags (command &optional arg &rest ignored)
|
||||
"`company-mode' completion back-end for GNU Global."
|
||||
(interactive (list 'interactive))
|
||||
(cl-case command
|
||||
(interactive (company-begin-backend 'company-gtags))
|
||||
(prefix (and company-gtags-executable
|
||||
buffer-file-name
|
||||
(apply #'derived-mode-p company-gtags-modes)
|
||||
(not (company-in-string-or-comment))
|
||||
(company-gtags--tags-available-p)
|
||||
(or (company-grab-symbol) 'stop)))
|
||||
(candidates (company-gtags--fetch-tags arg))
|
||||
(sorted t)
|
||||
(duplicates t)
|
||||
(annotation (company-gtags--annotation arg))
|
||||
(meta (get-text-property 0 'meta arg))
|
||||
(location (get-text-property 0 'location arg))
|
||||
(post-completion (let ((anno (company-gtags--annotation arg)))
|
||||
(when (and company-gtags-insert-arguments anno)
|
||||
(insert anno)
|
||||
(company-template-c-like-templatify anno))))))
|
||||
|
||||
(provide 'company-gtags)
|
||||
;;; company-gtags.el ends here
|
Binary file not shown.
@ -1,76 +0,0 @@
|
||||
;;; company-ispell.el --- company-mode completion back-end using Ispell
|
||||
|
||||
;; Copyright (C) 2009-2011, 2013-2015 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Nikolaj Schumacher
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
;;
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'company)
|
||||
(require 'cl-lib)
|
||||
(require 'ispell)
|
||||
|
||||
(defgroup company-ispell nil
|
||||
"Completion back-end using Ispell."
|
||||
:group 'company)
|
||||
|
||||
(defcustom company-ispell-dictionary nil
|
||||
"Dictionary to use for `company-ispell'.
|
||||
If nil, use `ispell-complete-word-dict'."
|
||||
:type '(choice (const :tag "default (nil)" nil)
|
||||
(file :tag "dictionary" t)))
|
||||
|
||||
(defvar company-ispell-available 'unknown)
|
||||
|
||||
(defun company-ispell-available ()
|
||||
(when (eq company-ispell-available 'unknown)
|
||||
(condition-case err
|
||||
(progn
|
||||
(lookup-words "WHATEVER")
|
||||
(setq company-ispell-available t))
|
||||
(error
|
||||
(message "Company: ispell-look-command not found")
|
||||
(setq company-ispell-available nil))))
|
||||
company-ispell-available)
|
||||
|
||||
;;;###autoload
|
||||
(defun company-ispell (command &optional arg &rest ignored)
|
||||
"`company-mode' completion back-end using Ispell."
|
||||
(interactive (list 'interactive))
|
||||
(cl-case command
|
||||
(interactive (company-begin-backend 'company-ispell))
|
||||
(prefix (when (company-ispell-available)
|
||||
(company-grab-word)))
|
||||
(candidates
|
||||
(let ((words (lookup-words arg (or company-ispell-dictionary
|
||||
ispell-complete-word-dict)))
|
||||
(completion-ignore-case t))
|
||||
(if (string= arg "")
|
||||
;; Small optimization.
|
||||
words
|
||||
;; Work around issue #284.
|
||||
(all-completions arg words))))
|
||||
(sorted t)
|
||||
(ignore-case 'keep-prefix)))
|
||||
|
||||
(provide 'company-ispell)
|
||||
;;; company-ispell.el ends here
|
Binary file not shown.
@ -1,236 +0,0 @@
|
||||
;;; company-keywords.el --- A company back-end for programming language keywords
|
||||
|
||||
;; Copyright (C) 2009-2011 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Nikolaj Schumacher
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
;;
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'company)
|
||||
(require 'cl-lib)
|
||||
|
||||
(defun company-keywords-upper-lower (&rest lst)
|
||||
;; Upcase order is different for _.
|
||||
(nconc (sort (mapcar 'upcase lst) 'string<) lst))
|
||||
|
||||
(defvar company-keywords-alist
|
||||
;; Please contribute corrections or additions.
|
||||
`((c++-mode
|
||||
"asm" "auto" "bool" "break" "case" "catch" "char" "class" "const"
|
||||
"const_cast" "continue" "default" "delete" "do" "double" "dynamic_cast"
|
||||
"else" "enum" "explicit" "export" "extern" "false" "float" "for" "friend"
|
||||
"goto" "if" "inline" "int" "long" "mutable" "namespace" "new"
|
||||
"operator" "private" "protected" "public" "register" "reinterpret_cast"
|
||||
"return" "short" "signed" "sizeof" "static" "static_cast" "struct" "switch"
|
||||
"template" "this" "throw" "true" "try" "typedef" "typeid" "typename"
|
||||
"union" "unsigned" "using" "virtual" "void" "volatile" "wchar_t" "while")
|
||||
(c-mode
|
||||
"auto" "break" "case" "char" "const" "continue" "default" "do"
|
||||
"double" "else" "enum" "extern" "float" "for" "goto" "if" "int" "long"
|
||||
"register" "return" "short" "signed" "sizeof" "static" "struct"
|
||||
"switch" "typedef" "union" "unsigned" "void" "volatile" "while")
|
||||
(csharp-mode
|
||||
"abstract" "add" "alias" "as" "base" "bool" "break" "byte" "case"
|
||||
"catch" "char" "checked" "class" "const" "continue" "decimal" "default"
|
||||
"delegate" "do" "double" "else" "enum" "event" "explicit" "extern"
|
||||
"false" "finally" "fixed" "float" "for" "foreach" "get" "global" "goto"
|
||||
"if" "implicit" "in" "int" "interface" "internal" "is" "lock" "long"
|
||||
"namespace" "new" "null" "object" "operator" "out" "override" "params"
|
||||
"partial" "private" "protected" "public" "readonly" "ref" "remove"
|
||||
"return" "sbyte" "sealed" "set" "short" "sizeof" "stackalloc" "static"
|
||||
"string" "struct" "switch" "this" "throw" "true" "try" "typeof" "uint"
|
||||
"ulong" "unchecked" "unsafe" "ushort" "using" "value" "var" "virtual"
|
||||
"void" "volatile" "where" "while" "yield")
|
||||
(d-mode
|
||||
;; from http://www.digitalmars.com/d/2.0/lex.html
|
||||
"abstract" "alias" "align" "asm"
|
||||
"assert" "auto" "body" "bool" "break" "byte" "case" "cast" "catch"
|
||||
"cdouble" "cent" "cfloat" "char" "class" "const" "continue" "creal"
|
||||
"dchar" "debug" "default" "delegate" "delete" "deprecated" "do"
|
||||
"double" "else" "enum" "export" "extern" "false" "final" "finally"
|
||||
"float" "for" "foreach" "foreach_reverse" "function" "goto" "idouble"
|
||||
"if" "ifloat" "import" "in" "inout" "int" "interface" "invariant"
|
||||
"ireal" "is" "lazy" "long" "macro" "mixin" "module" "new" "nothrow"
|
||||
"null" "out" "override" "package" "pragma" "private" "protected"
|
||||
"public" "pure" "real" "ref" "return" "scope" "short" "static" "struct"
|
||||
"super" "switch" "synchronized" "template" "this" "throw" "true" "try"
|
||||
"typedef" "typeid" "typeof" "ubyte" "ucent" "uint" "ulong" "union"
|
||||
"unittest" "ushort" "version" "void" "volatile" "wchar" "while" "with")
|
||||
(f90-mode .
|
||||
;; from f90.el
|
||||
;; ".AND." ".GE." ".GT." ".LT." ".LE." ".NE." ".OR." ".TRUE." ".FALSE."
|
||||
,(company-keywords-upper-lower
|
||||
"abs" "abstract" "achar" "acos" "adjustl" "adjustr" "aimag" "aint"
|
||||
"align" "all" "all_prefix" "all_scatter" "all_suffix" "allocatable"
|
||||
"allocate" "allocated" "and" "anint" "any" "any_prefix" "any_scatter"
|
||||
"any_suffix" "asin" "assign" "assignment" "associate" "associated"
|
||||
"asynchronous" "atan" "atan2" "backspace" "bind" "bit_size" "block"
|
||||
"btest" "c_alert" "c_associated" "c_backspace" "c_bool"
|
||||
"c_carriage_return" "c_char" "c_double" "c_double_complex" "c_f_pointer"
|
||||
"c_f_procpointer" "c_float" "c_float_complex" "c_form_feed" "c_funloc"
|
||||
"c_funptr" "c_horizontal_tab" "c_int" "c_int16_t" "c_int32_t" "c_int64_t"
|
||||
"c_int8_t" "c_int_fast16_t" "c_int_fast32_t" "c_int_fast64_t"
|
||||
"c_int_fast8_t" "c_int_least16_t" "c_int_least32_t" "c_int_least64_t"
|
||||
"c_int_least8_t" "c_intmax_t" "c_intptr_t" "c_loc" "c_long"
|
||||
"c_long_double" "c_long_double_complex" "c_long_long" "c_new_line"
|
||||
"c_null_char" "c_null_funptr" "c_null_ptr" "c_ptr" "c_short"
|
||||
"c_signed_char" "c_size_t" "c_vertical_tab" "call" "case" "ceiling"
|
||||
"char" "character" "character_storage_size" "class" "close" "cmplx"
|
||||
"command_argument_count" "common" "complex" "conjg" "contains" "continue"
|
||||
"copy_prefix" "copy_scatter" "copy_suffix" "cos" "cosh" "count"
|
||||
"count_prefix" "count_scatter" "count_suffix" "cpu_time" "cshift"
|
||||
"cycle" "cyclic" "data" "date_and_time" "dble" "deallocate" "deferred"
|
||||
"digits" "dim" "dimension" "distribute" "do" "dot_product" "double"
|
||||
"dprod" "dynamic" "elemental" "else" "elseif" "elsewhere" "end" "enddo"
|
||||
"endfile" "endif" "entry" "enum" "enumerator" "eoshift" "epsilon" "eq"
|
||||
"equivalence" "eqv" "error_unit" "exit" "exp" "exponent" "extends"
|
||||
"extends_type_of" "external" "extrinsic" "false" "file_storage_size"
|
||||
"final" "floor" "flush" "forall" "format" "fraction" "function" "ge"
|
||||
"generic" "get_command" "get_command_argument" "get_environment_variable"
|
||||
"goto" "grade_down" "grade_up" "gt" "hpf_alignment" "hpf_distribution"
|
||||
"hpf_template" "huge" "iachar" "iall" "iall_prefix" "iall_scatter"
|
||||
"iall_suffix" "iand" "iany" "iany_prefix" "iany_scatter" "iany_suffix"
|
||||
"ibclr" "ibits" "ibset" "ichar" "ieee_arithmetic" "ieee_exceptions"
|
||||
"ieee_features" "ieee_get_underflow_mode" "ieee_set_underflow_mode"
|
||||
"ieee_support_underflow_control" "ieor" "if" "ilen" "implicit"
|
||||
"import" "include" "independent" "index" "inherit" "input_unit"
|
||||
"inquire" "int" "integer" "intent" "interface" "intrinsic" "ior"
|
||||
"iostat_end" "iostat_eor" "iparity" "iparity_prefix" "iparity_scatter"
|
||||
"iparity_suffix" "ishft" "ishftc" "iso_c_binding" "iso_fortran_env"
|
||||
"kind" "lbound" "le" "leadz" "len" "len_trim" "lge" "lgt" "lle" "llt"
|
||||
"log" "log10" "logical" "lt" "matmul" "max" "maxexponent" "maxloc"
|
||||
"maxval" "maxval_prefix" "maxval_scatter" "maxval_suffix" "merge"
|
||||
"min" "minexponent" "minloc" "minval" "minval_prefix" "minval_scatter"
|
||||
"minval_suffix" "mod" "module" "modulo" "move_alloc" "mvbits" "namelist"
|
||||
"ne" "nearest" "neqv" "new" "new_line" "nint" "non_intrinsic"
|
||||
"non_overridable" "none" "nopass" "not" "null" "nullify"
|
||||
"number_of_processors" "numeric_storage_size" "only" "onto" "open"
|
||||
"operator" "optional" "or" "output_unit" "pack" "parameter" "parity"
|
||||
"parity_prefix" "parity_scatter" "parity_suffix" "pass" "pause"
|
||||
"pointer" "popcnt" "poppar" "precision" "present" "print" "private"
|
||||
"procedure" "processors" "processors_shape" "product" "product_prefix"
|
||||
"product_scatter" "product_suffix" "program" "protected" "public"
|
||||
"pure" "radix" "random_number" "random_seed" "range" "read" "real"
|
||||
"realign" "recursive" "redistribute" "repeat" "reshape" "result"
|
||||
"return" "rewind" "rrspacing" "same_type_as" "save" "scale" "scan"
|
||||
"select" "selected_char_kind" "selected_int_kind" "selected_real_kind"
|
||||
"sequence" "set_exponent" "shape" "sign" "sin" "sinh" "size" "spacing"
|
||||
"spread" "sqrt" "stop" "subroutine" "sum" "sum_prefix" "sum_scatter"
|
||||
"sum_suffix" "system_clock" "tan" "tanh" "target" "template" "then"
|
||||
"tiny" "transfer" "transpose" "trim" "true" "type" "ubound" "unpack"
|
||||
"use" "value" "verify" "volatile" "wait" "where" "while" "with" "write"))
|
||||
(java-mode
|
||||
"abstract" "assert" "boolean" "break" "byte" "case" "catch" "char" "class"
|
||||
"continue" "default" "do" "double" "else" "enum" "extends" "final"
|
||||
"finally" "float" "for" "if" "implements" "import" "instanceof" "int"
|
||||
"interface" "long" "native" "new" "package" "private" "protected" "public"
|
||||
"return" "short" "static" "strictfp" "super" "switch" "synchronized"
|
||||
"this" "throw" "throws" "transient" "try" "void" "volatile" "while")
|
||||
(javascript-mode
|
||||
"break" "catch" "const" "continue" "delete" "do" "else" "export" "for"
|
||||
"function" "if" "import" "in" "instanceOf" "label" "let" "new" "return"
|
||||
"switch" "this" "throw" "try" "typeof" "var" "void" "while" "with" "yield")
|
||||
(objc-mode
|
||||
"@catch" "@class" "@encode" "@end" "@finally" "@implementation"
|
||||
"@interface" "@private" "@protected" "@protocol" "@public"
|
||||
"@selector" "@synchronized" "@throw" "@try" "alloc" "autorelease"
|
||||
"bycopy" "byref" "in" "inout" "oneway" "out" "release" "retain")
|
||||
(perl-mode
|
||||
;; from cperl.el
|
||||
"AUTOLOAD" "BEGIN" "CHECK" "CORE" "DESTROY" "END" "INIT" "__END__"
|
||||
"__FILE__" "__LINE__" "abs" "accept" "alarm" "and" "atan2" "bind"
|
||||
"binmode" "bless" "caller" "chdir" "chmod" "chomp" "chop" "chown" "chr"
|
||||
"chroot" "close" "closedir" "cmp" "connect" "continue" "cos"
|
||||
"crypt" "dbmclose" "dbmopen" "defined" "delete" "die" "do" "dump" "each"
|
||||
"else" "elsif" "endgrent" "endhostent" "endnetent" "endprotoent"
|
||||
"endpwent" "endservent" "eof" "eq" "eval" "exec" "exists" "exit" "exp"
|
||||
"fcntl" "fileno" "flock" "for" "foreach" "fork" "format" "formline"
|
||||
"ge" "getc" "getgrent" "getgrgid" "getgrnam" "gethostbyaddr"
|
||||
"gethostbyname" "gethostent" "getlogin" "getnetbyaddr" "getnetbyname"
|
||||
"getnetent" "getpeername" "getpgrp" "getppid" "getpriority"
|
||||
"getprotobyname" "getprotobynumber" "getprotoent" "getpwent" "getpwnam"
|
||||
"getpwuid" "getservbyname" "getservbyport" "getservent" "getsockname"
|
||||
"getsockopt" "glob" "gmtime" "goto" "grep" "gt" "hex" "if" "index" "int"
|
||||
"ioctl" "join" "keys" "kill" "last" "lc" "lcfirst" "le" "length"
|
||||
"link" "listen" "local" "localtime" "lock" "log" "lstat" "lt" "map"
|
||||
"mkdir" "msgctl" "msgget" "msgrcv" "msgsnd" "my" "ne" "next" "no"
|
||||
"not" "oct" "open" "opendir" "or" "ord" "our" "pack" "package" "pipe"
|
||||
"pop" "pos" "print" "printf" "push" "q" "qq" "quotemeta" "qw" "qx"
|
||||
"rand" "read" "readdir" "readline" "readlink" "readpipe" "recv" "redo"
|
||||
"ref" "rename" "require" "reset" "return" "reverse" "rewinddir" "rindex"
|
||||
"rmdir" "scalar" "seek" "seekdir" "select" "semctl" "semget" "semop"
|
||||
"send" "setgrent" "sethostent" "setnetent" "setpgrp" "setpriority"
|
||||
"setprotoent" "setpwent" "setservent" "setsockopt" "shift" "shmctl"
|
||||
"shmget" "shmread" "shmwrite" "shutdown" "sin" "sleep" "socket"
|
||||
"socketpair" "sort" "splice" "split" "sprintf" "sqrt" "srand" "stat"
|
||||
"study" "sub" "substr" "symlink" "syscall" "sysopen" "sysread" "system"
|
||||
"syswrite" "tell" "telldir" "tie" "time" "times" "tr" "truncate" "uc"
|
||||
"ucfirst" "umask" "undef" "unless" "unlink" "unpack" "unshift" "untie"
|
||||
"until" "use" "utime" "values" "vec" "wait" "waitpid"
|
||||
"wantarray" "warn" "while" "write" "x" "xor" "y")
|
||||
(php-mode
|
||||
"__CLASS__" "__DIR__" "__FILE__" "__FUNCTION__" "__LINE__" "__METHOD__"
|
||||
"__NAMESPACE__" "_once" "abstract" "and" "array" "as" "break" "case"
|
||||
"catch" "cfunction" "class" "clone" "const" "continue" "declare"
|
||||
"default" "die" "do" "echo" "else" "elseif" "empty" "enddeclare"
|
||||
"endfor" "endforeach" "endif" "endswitch" "endwhile" "eval" "exception"
|
||||
"exit" "extends" "final" "for" "foreach" "function" "global"
|
||||
"goto" "if" "implements" "include" "instanceof" "interface"
|
||||
"isset" "list" "namespace" "new" "old_function" "or" "php_user_filter"
|
||||
"print" "private" "protected" "public" "require" "require_once" "return"
|
||||
"static" "switch" "this" "throw" "try" "unset" "use" "var" "while" "xor")
|
||||
(python-mode
|
||||
"and" "assert" "break" "class" "continue" "def" "del" "elif" "else"
|
||||
"except" "exec" "finally" "for" "from" "global" "if" "import" "in" "is"
|
||||
"lambda" "not" "or" "pass" "print" "raise" "return" "try" "while" "yield")
|
||||
(ruby-mode
|
||||
"BEGIN" "END" "alias" "and" "begin" "break" "case" "class" "def" "defined?"
|
||||
"do" "else" "elsif" "end" "ensure" "false" "for" "if" "in" "module"
|
||||
"next" "nil" "not" "or" "redo" "rescue" "retry" "return" "self" "super"
|
||||
"then" "true" "undef" "unless" "until" "when" "while" "yield")
|
||||
;; aliases
|
||||
(js2-mode . javascript-mode)
|
||||
(espresso-mode . javascript-mode)
|
||||
(js-mode . javascript-mode)
|
||||
(cperl-mode . perl-mode)
|
||||
(jde-mode . java-mode))
|
||||
"Alist mapping major-modes to sorted keywords for `company-keywords'.")
|
||||
|
||||
;;;###autoload
|
||||
(defun company-keywords (command &optional arg &rest ignored)
|
||||
"`company-mode' back-end for programming language keywords."
|
||||
(interactive (list 'interactive))
|
||||
(cl-case command
|
||||
(interactive (company-begin-backend 'company-keywords))
|
||||
(prefix (and (assq major-mode company-keywords-alist)
|
||||
(not (company-in-string-or-comment))
|
||||
(or (company-grab-symbol) 'stop)))
|
||||
(candidates
|
||||
(let ((completion-ignore-case nil)
|
||||
(symbols (cdr (assq major-mode company-keywords-alist))))
|
||||
(all-completions arg (if (consp symbols)
|
||||
symbols
|
||||
(cdr (assq symbols company-keywords-alist))))))
|
||||
(sorted t)))
|
||||
|
||||
(provide 'company-keywords)
|
||||
;;; company-keywords.el ends here
|
Binary file not shown.
@ -1,142 +0,0 @@
|
||||
;;; company-nxml.el --- company-mode completion back-end for nxml-mode
|
||||
|
||||
;; Copyright (C) 2009-2011, 2013 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Nikolaj Schumacher
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
;;
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'company)
|
||||
(require 'cl-lib)
|
||||
|
||||
(defvar rng-open-elements)
|
||||
(defvar rng-validate-mode)
|
||||
(defvar rng-in-attribute-regex)
|
||||
(defvar rng-in-attribute-value-regex)
|
||||
(declare-function rng-set-state-after "rng-nxml")
|
||||
(declare-function rng-match-possible-start-tag-names "rng-match")
|
||||
(declare-function rng-adjust-state-for-attribute "rng-nxml")
|
||||
(declare-function rng-match-possible-attribute-names "rng-match")
|
||||
(declare-function rng-adjust-state-for-attribute-value "rng-nxml")
|
||||
(declare-function rng-match-possible-value-strings "rng-match")
|
||||
|
||||
(defconst company-nxml-token-regexp
|
||||
"\\(?:[_[:alpha:]][-._[:alnum:]]*\\_>\\)")
|
||||
|
||||
(defvar company-nxml-in-attribute-value-regexp
|
||||
(replace-regexp-in-string "w" company-nxml-token-regexp
|
||||
"<w\\(?::w\\)?\
|
||||
\\(?:[ \t\r\n]+w\\(?::w\\)?[ \t\r\n]*=\
|
||||
\[ \t\r\n]*\\(?:\"[^\"]*\"\\|'[^']*'\\)\\)*\
|
||||
\[ \t\r\n]+\\(w\\(:w\\)?\\)[ \t\r\n]*=[ \t\r\n]*\
|
||||
\\(\"\\([^\"]*\\>\\)\\|'\\([^']*\\>\\)\\)\\="
|
||||
t t))
|
||||
|
||||
(defvar company-nxml-in-tag-name-regexp
|
||||
(replace-regexp-in-string "w" company-nxml-token-regexp
|
||||
"<\\(/?w\\(?::w?\\)?\\)?\\=" t t))
|
||||
|
||||
(defun company-nxml-all-completions (prefix alist)
|
||||
(let ((candidates (mapcar 'cdr alist))
|
||||
(case-fold-search nil)
|
||||
filtered)
|
||||
(when (cdar rng-open-elements)
|
||||
(push (concat "/" (cdar rng-open-elements)) candidates))
|
||||
(setq candidates (sort (all-completions prefix candidates) 'string<))
|
||||
(while candidates
|
||||
(unless (equal (car candidates) (car filtered))
|
||||
(push (car candidates) filtered))
|
||||
(pop candidates))
|
||||
(nreverse filtered)))
|
||||
|
||||
(defmacro company-nxml-prepared (&rest body)
|
||||
(declare (indent 0) (debug t))
|
||||
`(let ((lt-pos (save-excursion (search-backward "<" nil t)))
|
||||
xmltok-dtd)
|
||||
(when (and lt-pos (= (rng-set-state-after lt-pos) lt-pos))
|
||||
,@body)))
|
||||
|
||||
(defun company-nxml-tag (command &optional arg &rest ignored)
|
||||
(cl-case command
|
||||
(prefix (and (derived-mode-p 'nxml-mode)
|
||||
rng-validate-mode
|
||||
(company-grab company-nxml-in-tag-name-regexp 1)))
|
||||
(candidates (company-nxml-prepared
|
||||
(company-nxml-all-completions
|
||||
arg (rng-match-possible-start-tag-names))))
|
||||
(sorted t)))
|
||||
|
||||
(defun company-nxml-attribute (command &optional arg &rest ignored)
|
||||
(cl-case command
|
||||
(prefix (and (derived-mode-p 'nxml-mode)
|
||||
rng-validate-mode
|
||||
(memq (char-after) '(?\ ?\t ?\n)) ;; outside word
|
||||
(company-grab rng-in-attribute-regex 1)))
|
||||
(candidates (company-nxml-prepared
|
||||
(and (rng-adjust-state-for-attribute
|
||||
lt-pos (- (point) (length arg)))
|
||||
(company-nxml-all-completions
|
||||
arg (rng-match-possible-attribute-names)))))
|
||||
(sorted t)))
|
||||
|
||||
(defun company-nxml-attribute-value (command &optional arg &rest ignored)
|
||||
(cl-case command
|
||||
(prefix (and (derived-mode-p 'nxml-mode)
|
||||
rng-validate-mode
|
||||
(and (memq (char-after) '(?' ?\" ?\ ?\t ?\n)) ;; outside word
|
||||
(looking-back company-nxml-in-attribute-value-regexp)
|
||||
(or (match-string-no-properties 4)
|
||||
(match-string-no-properties 5)
|
||||
""))))
|
||||
(candidates (company-nxml-prepared
|
||||
(let (attr-start attr-end colon)
|
||||
(and (looking-back rng-in-attribute-value-regex lt-pos)
|
||||
(setq colon (match-beginning 2)
|
||||
attr-start (match-beginning 1)
|
||||
attr-end (match-end 1))
|
||||
(rng-adjust-state-for-attribute lt-pos attr-start)
|
||||
(rng-adjust-state-for-attribute-value
|
||||
attr-start colon attr-end)
|
||||
(all-completions
|
||||
arg (rng-match-possible-value-strings))))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun company-nxml (command &optional arg &rest ignored)
|
||||
"`company-mode' completion back-end for `nxml-mode'."
|
||||
(interactive (list 'interactive))
|
||||
(cl-case command
|
||||
(interactive (company-begin-backend 'company-nxml))
|
||||
(prefix (or (company-nxml-tag 'prefix)
|
||||
(company-nxml-attribute 'prefix)
|
||||
(company-nxml-attribute-value 'prefix)))
|
||||
(candidates (cond
|
||||
((company-nxml-tag 'prefix)
|
||||
(company-nxml-tag 'candidates arg))
|
||||
((company-nxml-attribute 'prefix)
|
||||
(company-nxml-attribute 'candidates arg))
|
||||
((company-nxml-attribute-value 'prefix)
|
||||
(sort (company-nxml-attribute-value 'candidates arg)
|
||||
'string<))))
|
||||
(sorted t)))
|
||||
|
||||
(provide 'company-nxml)
|
||||
;;; company-nxml.el ends here
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user