Giter VIP home page Giter VIP logo

irony-mode's Introduction

Irony-Mode

A C/C++ minor mode powered by libclang

irony-mode is an Emacs minor-mode that aims at improving the editing experience for the C, C++ and Objective-C languages. It works by using a combination of an Emacs package and a C++ program (irony-server) exposing libclang.

Features:

Dependencies

Elisp dependencies

These dependencies will be installed automatically when using the standard installation procedure described below.

Package Comment
cl-lib Built-in since Emacs 24.3
json Built-in since Emacs 23.1
YASnippet Optional. May be used to provide post-completion expansion of function arguments

Irony-Server prerequisites

irony-server provides the libclang interface to irony-mode. It uses a simple protocol based on S-expression. This server, written in C++ and requires the following packages to be installed on your system:

Installation

The recommended way to install irony-mode and its dependencies is to use a package manager.

  • Using MELPA

      M-x package-install RET irony RET
    
  • Using apt on Debian โ‰ฅ10 and derivatives

      sudo apt install elpa-irony
    

Exactly one package manager should manage irony-mode. If using apt, but the MELPA package is desired, uninstall the version managed by apt; Likewise, installing from both MELPA and straight.el may result in a state that requires a manual workaround.

To install the latest Debian-supported irony-mode and Clang

The backports mechanism is the recommended and officially supported method of accessing newer versions than Debian stable provides. For example on Debian 10 (buster):

    sudo apt install -t buster-backports elpa-irony

If one requires a newer version of Clang/LLVM than the one provided in backports, the following repository is available: LLVM Debian/Ubuntu nightly packages. This unofficial repository is maintained by Sylvestre Ledru, who is responsible for the official Debian package. His repository also supports Ubuntu and derivatives. When using this unofficial repository, it is recommended to use the MELPA package of irony-mode and to uninstall elpa-irony. Finally, when switching from apt to MELPA, the following action is required: M-x irony-install-server RET.

Configuration

(add-hook 'c++-mode-hook 'irony-mode)
(add-hook 'c-mode-hook 'irony-mode)
(add-hook 'objc-mode-hook 'irony-mode)

(add-hook 'irony-mode-hook 'irony-cdb-autosetup-compile-options)

Windows considerations

irony-mode should work fine on Windows but there are some things to take care of first.

  • libclang.dll is expected to be available in the PATH or in Emacs' exec-path.

  • Emacs >= 24.4 is required. A bug in previous versions makes irony unuseable (Emacs bug #18420).

  • w32-pipe-read-delay default value of 50 should be changed. This should not cause any issue on today's version of Windows. The default value of 50 may be lowered in mainline Emacs in future versions, until then, I suggest to set it to 0.

  • w32-pipe-buffer-size, introduced by Emacs 25, can be set to a larger value than the default to improve irony-server communication performances (c.f. #321). The variable to customize is irony-server-w32-pipe-buffer-size.

Windows configuration tweaks to add to your Emacs configuration:

;; Windows performance tweaks
;;
(when (boundp 'w32-pipe-read-delay)
  (setq w32-pipe-read-delay 0))
;; Set the buffer size to 64K on Windows (from the original 4K)
(when (boundp 'w32-pipe-buffer-size)
  (setq irony-server-w32-pipe-buffer-size (* 64 1024)))

Usage

On the first run, irony-mode will ask you to build and install irony-server. To do so, type M-x irony-install-server RET.

To tune irony-mode, use customize:

M-x customize-group RET irony RET

In order to provide context sensitive and accurate information, irony-mode needs to know about the compiler flags used to parse the current buffer. The best way to achieve this is to use a Compilation Database.

Compilation Database

In order to work correctly, irony-mode needs to know the compile flags. irony-cdb aims to provide as automatic as possible compile flags discovery, with minimal user input.

Please refer to irony-cdb-autosetup-compile-options and irony-cdb-compilation-databases.

Right now irony-cdb supports the following compilation databases:

  • JSON Compilation Database - A JSON formatted file generated by various build tools. The file is named compile_commands.json, it lists the compile options associated to each file in the project.

    • CMake >= 2.8.5 will generate a compilation database in the build directory when issuing the following command cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON <...>.

    • ninja >= 1.2 will generate a JSON Compilation Database when using the compdb tool.

    • Bear generates a JSON Compilation Database file by "monitoring" the build of a project. The typical usage for a make-based project will be bear -- make -B.

  • .clang_complete - A file at the root of your project containing the compilation flags, one per line. This is compatible with the with plugin Rip-Rip/clang_complete. If you want to generate the .clang_complete automatically, take a look at the cc_args.py documentation.

More detailed information on compilation database is available here:

FAQ

It's slow, why?

A bug in old version of Clang (at least '3.1-8') caused the completion to fail on the standard library types. To eliminate this bug an optimisation has been disabled in the parsing of a translation unit. This result in a slower parsing.

This only affect old versions of Clang (< 3.2), it is suggested to update your libclang installation if you want to take advantage of the optimizations.

libclang.so: cannot open shared object file...

Compiling irony-server succeed but you have the following message when you try to run the irony-server executable:

'irony-server: error while loading shared libraries: libclang.so: cannot open shared object file: No such file or directory

When libclang is installed in a non-standard location (one that is missing from the path list of the dynamic loader, see ld.so.conf) you can tell CMake to use the rpath when installing the target irony-server. To enable rpath in CMake use the following command:

cmake -DCMAKE_INSTALL_RPATH_USE_LINK_PATH=ON <args...>

If you're running OS X, you can also use install_name_tool to explicitly tell irony-server where an appropriate version of libclang.dylib lives. For example, Homebrew (with brew install llvm --with-clang) will install a libclang.dylib library at /usr/local/opt/llvm/lib/libclang.dylib; you can instruct irony-server to use this with something like:

install_name_tool -change @rpath/libclang.dylib /usr/local/opt/llvm/lib/libclang.dylib irony-server

irony-mode's People

Contributors

3246251196 avatar abergard avatar arximboldi avatar drvink avatar gavv avatar hotpxl avatar hylen avatar itollefsen avatar jerryxgh avatar joshluisaac avatar josteink avatar kangjianbin avatar kevinushey avatar kosh04 avatar kprav33n avatar kumar8600 avatar lehy avatar netromdk avatar nick-wallingford avatar oblique avatar pythonnut avatar rmcclellan-izo avatar rochg avatar rushankhan1 avatar sarcasm avatar simonbates avatar smithsg84 avatar sten0 avatar tsukimizake avatar vaivaswatha avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

irony-mode's Issues

Test completion support for C

Apparently completion doesn't work well with C files.

I tried with libgit and the CMake generation.

When trying to completion something like this (from commit.c#L21:

static void clear_parents(git_commit *commit)
{
    unsigned int i;

    for (i = 0; i < commit->parent_ids.length; ++i) {
        git_oid *parent = git_vector_get(&commit->parent_ids, i);
        git__free(parent);
    }
    commit->[COMP]
    git_vector_clear(&commit->parent_ids);
}

The irony log shows:

1 errors found during completion.
<cut>!commit.c:30:2: error: no member named 'git_v' in 'struct git_commit'

Rewrite include completion

Some issues and enhancement are related to header completion:

Fix conflicting keybinding with irony-ac-. Both plugins, ac-header-comp and ac[-simple] use C-RET as a shortcut. Modify header-comp to use something else (or maybe merge it with ac[-simple]?). Even better, integrate completely header-comp at the standard completion command (bypass a call to clang___complete*()?

Completion: Misc tasks

  • add information about a candidate such as, if it is a function, a type, a variable, ...So it will be possible to inform the user in a completion popup if the type is a function at least.
  • test current CXCompletionChunk_CurrentParameter
  • retrigger on header completion doesn't work.
  • Bypass Clang for #include completion to use ac-start on expansion action. So #inc[COMP] -> expand to #include "[COMP-STARTS-AUTOMATICALLY-HERE-WITHOUT-ANY-CHARACTER-INPUT]. This might not be necessary if completion is asynchronous and after-command-hook of the snippet extension find a new completion point and trigger a new completion.
  • Check when the completion is triggered on a switch/case, it matches even after the colon.
  • Map C-c : as a trigger command
  • For auto-complete disabled in preprocessor lines take a look at (c-in-literal &optional LIM DETECT-CPP).
  • Take a look at c-beginning-of-macro and similar for clever preprocessor completions
  • Take a look at c-syntactic-re-search-forward
  • Rewrite init-list detection for completion point. The non-trivial function c-guess-basic-syntax is called 3 times in a row while 1 call would suffice. Also try this function inside a namespace.
  • Limit size of data sent through the 'socket', pre-render completion result string?

Add goto completion

Check if Clang completes goto statements (probably), if so add it to the function looking for the completion point in the same manner as switch/case.

This might be done at the same time as #27

Compilation DB: Find the flags for a header

compile_commands.json contains the flags to compile a source file, but since header files are not compiled it will not work for them.

Find a way to make this work as best as possible (if we already have the flags for a file using this header).

Make ac plugin 'asynchronous'

For the moment the AC plugin for a wait loop for the completion results, a better idea will be to call auto-complete with the candidates when we have the completion results available.

Note: the synchronous version is still welcomed when the use ask for completion explicitly.

  • user triggered completion (relaunch/force with a shortcut)
  • fix the case where there is only one completion result that auto-complete process at the same time the user is typing. If typing fast characters typed will be duplicated with the autocompletion.
  • handle simple results (typed text only)
  • integrate header-comp seamlessly
  • Move yasnippet to another/detached location, so it can be reused.
  • add information about a candidate such as, if it is a function, a type, a variable, ...So it will be possible to inform the user in a completion popup if the type is a function at least.
  • support standard auto-complete (not only my fork)
  • find a way to re-trigger auto-completion after header completion. Maybe the action shouldn't be dictated by auto-complete but by another plugin. So we can set this kind of smart action if necessary.
  • Create an event/callback/hook taking the following parameters: candidates & position

Emacs hangs

Emacs sometimes hangs when it tries to complete word in background (i.e. while typing, not after pressing "TAB").

I also noticed that it probably hangs more often if other completion sources was used recently, e.g. ac-source-words-in-same-mode-buffers, but it also hangs if ac-source-irony is the only source. It doesn't hang if irony-mode is disabled.

Backtraces look like there is a deadlock. Irony server log is empty.

irony-server backtrace

#0  0xffffe424 in __kernel_vsyscall ()
#1  0xb67700eb in read () at ../sysdeps/unix/syscall-template.S:82
#2  0x0805b36e in Server::run (this=0xbfecc0cc) at /home/viktor/dev/config/emacs/emacs.d/modules/irony-mode/server/Server.cpp:76
#3  0x0805f057 in main () at /home/viktor/dev/config/emacs/emacs.d/modules/irony-mode/server/main.cpp:39

emacs xbacktrace

"accept-process-output" (0xbfae6814)
"while" (0xbfae6928)
"let" (0xbfae6a58)
"condition-case" (0xbfae6c28)
"with-local-quit" (0xbfae6cc8)
"irony-wait-request-answer" (0xbfae6d80)
"cdr" (0xbfae6ef8)
"let*" (0xbfae6fd8)
"catch" (0xbfae71a8)
"cl-block-wrapper" (0xbfae7248)
"block" (0xbfae72e8)
"loop" (0xbfae7388)
"irony-complete" (0xbfae7440)
"let*" (0xbfae75f8)
"catch" (0xbfae77c8)
"cl-block-wrapper" (0xbfae7868)
"block" (0xbfae7908)
"loop" (0xbfae79a8)
"irony-ac-candidates" (0xbfae7a60)
"eval" (0xbfae7c44)
"ac-candidates-1" (0xbfae7dbc)
"ac-candidates" (0xbfae7f34)
"ac-update" (0xbfae80a4)
"ac-update-greedy" (0xbfae82e8)
"apply" (0xbfae82e4)
"byte-code" (0xbfae83d4)
"timer-event-handler" (0xbfae86cc)

emacs backtrace

#0  0xffffe424 in __kernel_vsyscall ()
#1  0xb6c9932d in ___newselect_nocancel () at ../sysdeps/unix/syscall-template.S:82
#2  0x08122300 in xg_select (max_fds=8, rfds=0xbfae6634, wfds=0xbfae65b4, efds=0x0, timeout=0xbfae6750) at xgselect.c:100
#3  0x081db447 in wait_reading_process_output (time_limit=0, microsecs=50000, read_kbd=0, do_display=0, wait_for_cell=138563754, wait_proc=0x9805950, just_wait_proc=0) at process.c:4613
#4  0x081dd6f3 in Faccept_process_output (process=159406421, seconds=155449743, millisec=-1079090428, just_this_one=138563754) at process.c:3999
#5  0x0819f79e in eval_sub (form=156270542) at eval.c:2359
#6  0x0819fa9d in Fprogn (args=156270470) at eval.c:364
#7  0x081a0120 in Fwhile (args=156270550) at eval.c:1141
#8  0x0819f947 in eval_sub (form=156282414) at eval.c:2297
#9  0x0819fa9d in Fprogn (args=159846478) at eval.c:364
#10 0x081a03f8 in Flet (args=159846470) at eval.c:1119
#11 0x0819f947 in eval_sub (form=159846462) at eval.c:2297
#12 0x081a0dc2 in internal_lisp_condition_case (var=138563754, bodyform=159846462, handlers=136608198) at eval.c:1468
#13 0x081a0e7b in Fcondition_case (args=159846446) at eval.c:1409
#14 0x0819f947 in eval_sub (form=159846438) at eval.c:2297
#15 0x0819f6d6 in eval_sub (form=156282422) at eval.c:2410
#16 0x0819fa9d in Fprogn (args=156282430) at eval.c:364
#17 0x0819fdd0 in funcall_lambda (fun=<value optimized out>, nargs=<value optimized out>, arg_vector=0xbfae6384) at eval.c:3225
#18 0x0819f28f in apply_lambda (fun=<value optimized out>, args=138563754) at eval.c:3109
#19 0x0819f528 in eval_sub (form=154819806) at eval.c:2413
#20 0x0819f688 in eval_sub (form=154819814) at eval.c:2334
#21 0x081a055a in FletX (args=159846582) at eval.c:1024
#22 0x0819f947 in eval_sub (form=159846574) at eval.c:2297
#23 0x0819fa9d in Fprogn (args=159846542) at eval.c:364
#24 0x081a0bf1 in internal_catch (tag=148011026, func=0x819fa70 <Fprogn>, arg=159846542) at eval.c:1271
#25 0x081a0c3d in Fcatch (args=159846510) at eval.c:1242
#26 0x0819f947 in eval_sub (form=159846502) at eval.c:2297
#27 0x0819f688 in eval_sub (form=159846486) at eval.c:2334
#28 0x0819f6d6 in eval_sub (form=159846550) at eval.c:2410
#29 0x0819f6d6 in eval_sub (form=154819846) at eval.c:2410
#30 0x0819fa9d in Fprogn (args=154821430) at eval.c:364
#31 0x0819fdd0 in funcall_lambda (fun=<value optimized out>, nargs=<value optimized out>, arg_vector=0xbfae6384) at eval.c:3225
#32 0x0819f28f in apply_lambda (fun=<value optimized out>, args=138563754) at eval.c:3109
#33 0x0819f528 in eval_sub (form=156878070) at eval.c:2413
#34 0x081a055a in FletX (args=159853422) at eval.c:1024
#35 0x0819f947 in eval_sub (form=159853414) at eval.c:2297
#36 0x0819fa9d in Fprogn (args=159853382) at eval.c:364
#37 0x081a0bf1 in internal_catch (tag=148011026, func=0x819fa70 <Fprogn>, arg=159853382) at eval.c:1271
#38 0x081a0c3d in Fcatch (args=159853350) at eval.c:1242
#39 0x0819f947 in eval_sub (form=159853342) at eval.c:2297
#40 0x0819f688 in eval_sub (form=159853326) at eval.c:2334
#41 0x0819f6d6 in eval_sub (form=159853390) at eval.c:2410
#42 0x0819f6d6 in eval_sub (form=156877934) at eval.c:2410
#43 0x0819fa9d in Fprogn (args=156877926) at eval.c:364
#44 0x0819fdd0 in funcall_lambda (fun=<value optimized out>, nargs=<value optimized out>, arg_vector=0xbfae6384) at eval.c:3225
#45 0x0819f28f in apply_lambda (fun=<value optimized out>, args=138563754) at eval.c:3109
#46 0x0819f528 in eval_sub (form=156847166) at eval.c:2413
#47 0x0819ff5a in Feval (form=156847166, lexical=<value optimized out>) at eval.c:2203
#48 0x0819d75e in Ffuncall (nargs=2, args=0xbfae7c40) at eval.c:3004
#49 0x081d5f54 in exec_byte_code (bytestr=155348977, vector=154011333, maxdepth=16, args_template=138563754, nargs=0, args=0x0) at bytecode.c:785
#50 0x0819fc87 in funcall_lambda (fun=<value optimized out>, nargs=<value optimized out>, arg_vector=0xbfae6384) at eval.c:3232
#51 0x0819d58b in Ffuncall (nargs=2, args=0xbfae7db8) at eval.c:3062
#52 0x081d5f54 in exec_byte_code (bytestr=155350153, vector=154011605, maxdepth=24, args_template=138563754, nargs=0, args=0x0) at bytecode.c:785
#53 0x0819fc87 in funcall_lambda (fun=<value optimized out>, nargs=<value optimized out>, arg_vector=0xbfae6384) at eval.c:3232
#54 0x0819d58b in Ffuncall (nargs=1, args=0xbfae7f30) at eval.c:3062
#55 0x081d5f54 in exec_byte_code (bytestr=155365945, vector=154013709, maxdepth=16, args_template=138563754, nargs=0, args=0x0) at bytecode.c:785
#56 0x0819fc87 in funcall_lambda (fun=<value optimized out>, nargs=<value optimized out>, arg_vector=0xbfae6384) at eval.c:3232
#57 0x0819d58b in Ffuncall (nargs=2, args=0xbfae80a0) at eval.c:3062
#58 0x081d5f54 in exec_byte_code (bytestr=155368721, vector=154023237, maxdepth=12, args_template=138563754, nargs=0, args=0x0) at bytecode.c:785
#59 0x0819fc87 in funcall_lambda (fun=<value optimized out>, nargs=<value optimized out>, arg_vector=0xbfae6384) at eval.c:3232
#60 0x0819d58b in Ffuncall (nargs=1, args=0xbfae82e4) at eval.c:3062
#61 0x0819e5d7 in Fapply (nargs=2, args=0xbfae82e4) at eval.c:2449
#62 0x0819d7ea in Ffuncall (nargs=3, args=0xbfae82e0) at eval.c:2983
#63 0x081d5f54 in exec_byte_code (bytestr=137222313, vector=137222341, maxdepth=16, args_template=138563754, nargs=0, args=0x0) at bytecode.c:785
#64 0x081d6c18 in Fbyte_code (bytestr=137222313, vector=137222341, maxdepth=16) at bytecode.c:423
#65 0x0819f7bc in eval_sub (form=137222302) at eval.c:2355
#66 0x081a0dc2 in internal_lisp_condition_case (var=138563754, bodyform=137222302, handlers=136599014) at eval.c:1468
#67 0x081d56cb in exec_byte_code (bytestr=137222169, vector=137222189, maxdepth=20, args_template=138563754, nargs=0, args=0x0) at bytecode.c:981
#68 0x0819fc87 in funcall_lambda (fun=<value optimized out>, nargs=<value optimized out>, arg_vector=0xbfae6384) at eval.c:3232
#69 0x0819d58b in Ffuncall (nargs=2, args=0xbfae86c8) at eval.c:3062
#70 0x0819da55 in call1 (fn=138588474, arg1=159582437) at eval.c:2770
#71 0x08135512 in timer_check_2 () at keyboard.c:4465
#72 timer_check () at keyboard.c:4511
#73 0x081357a6 in readable_events (flags=<value optimized out>) at keyboard.c:3392
#74 0x081396ff in get_input_pending (flags=1, addr=<value optimized out>) at keyboard.c:6741
#75 0x081397d5 in swallow_events (do_display=1) at keyboard.c:4230
#76 0x08057ebd in sit_for (timeout=120, reading=1, do_display=1) at dispnew.c:6032
#77 0x0813b708 in read_char (commandflag=1, nmaps=11, maps=0xbfae8b00, prev_event=138563754, used_mouse_menu=0xbfae8c38, end_time=0x0) at keyboard.c:2692
#78 0x0813c595 in read_key_sequence (keybuf=<value optimized out>, bufsize=<value optimized out>, prompt=<value optimized out>, dont_downcase_last=0, can_return_switch_frame=1, fix_current_buffer=1) at keyboard.c:9328
#79 0x0813e3a3 in command_loop_1 () at keyboard.c:1449
#80 0x081a0b14 in internal_condition_case (bfun=0x813e1d0 <command_loop_1>, handlers=138594810, hfun=0x8138ee0 <cmd_error>) at eval.c:1514
#81 0x08138b55 in command_loop_2 (ignore=138563754) at keyboard.c:1160
#82 0x081a0bf1 in internal_catch (tag=138592762, func=0x8138b30 <command_loop_2>, arg=138563754) at eval.c:1271
#83 0x08139176 in command_loop () at keyboard.c:1139
#84 recursive_edit_1 () at keyboard.c:759
#85 0x08139272 in Frecursive_edit () at keyboard.c:823
#86 0x0812c87b in main (argc=0, argv=<value optimized out>) at emacs.c:1715

Create a .dir-locals.el for the C++ style

I use some modification to the standard C++ style, it can be good to have the same settings for people contributing to the project.

Take a look at the existing .eproject which already contains these kind of settings.

If possible, marks the header files .h as C++ (not sure if this can fit in the .dir-locals.el or if it has to be done in each header.

Enable/disable plugin on the server

For the moment, someone who doesn't use the completion plugin on the Emacs side will suffer from the performance penalty of having the plugin enabled on the irony-server side.

It should be trivial to add a command that enable/disable a plugin on the server side (the plugins already do the setup/cleanup correctly with their constructor/destructor).

Compilation DB improvements and ideas

Here is some ideas of improvements but the priority is low and I think by using the plugin some other needs will get the priority. It's just a list of nice thing to have.

- [ ] Better bear integration. Detect it and maybe auto-install it at CMake generation if Unix system system is detected?

  • Add an option that offers the possibility to load flags based on a file in the same directory. For example on a CMake project, we work on a new file, not yet added to CMake, there is a high probability that the compile flags will be identical to another file in the same directory. Offer to insert the new entry in the compilation database as well (b/c the generation of a compilation database, with Bear for example might be slow as it requires to re-build the project).
  • Add a menu entry: "Show current flag in use"

- [ ] To limit slowness of the parsing and limit space used by the compilation db it should be possible to manage this on the C++ side. Since the command parsing algorithm looks more imperative than functional to me it should be quite straightforward to write it in C++. Also irony-server can use a command switch a la git to start a compilation db server. irony-server cbd, irony-server code-complete, ...

Instructions incomplete

I couldn't get any interesting completions to work in Boost.Python until I put this .eproject file at the root of my Boost working copy:

:includes '("." "/opt/local/Library/Frameworks/Python.framework/Headers/")

However, figuring that out took an hour with edebug. There may be other (maybe even much better) ways to get this to work but they're unknown to me. A doc section on setting up (e)projects to work with irony-mode would be very helpful.

Use std::ostream for plugins output

A comment from gaydov here suggests to use std::ostream: #5 (comment)

Which seems reasonable, it will remove the need to call std::to_string(type) for example.

For reading, actually it's done like this read(0, ...), this can use the C++ way as well with std::cin.

Introduce version

Tasks

  • add version irony-mode-version variable (see below)
  • create corresponding tag in git and create a tag for the develop branch
  • add version in irony.el comment (see below) and other files
  • document everything, "normal" workflow to start quickly
  • update MELPA/el-get recipe

irony-mode-version variable

When the first "stable" version will appear, do not forget to start offering a version variable.

(defvar irony-mode-version "0.1"
"<irony-mode version variable blabla>")

Use a format like:

MAJOR.MINOR[.SUBMINOR-IF-IT-MAKES-SENSE?].

Look at the function version-to-list and document it, this idea come from a discussion in the following pull request: auto-complete/auto-complete#161 (comment)

Version comment

In addition to the variable, add the following information to the main file, after Author:

;; URL: https://github.com/Sarcasm/irony-mode
;; Version: 0.1

Doesn't seem to work with your fork of auto-complete

With the original auto-complete and the six lines in the "Emacs configuration" section of your README, auto-completion works for a single cpp file. With the fork and the same six lines, I get the following error:

Error in timer: (error "Keyword argument :view not one of (:value :face :mouse-face :selection-face :sublist :document :symbol :summary)")

This is on Emacs 24.3.50.1 on Ubuntu 12.04 32-bit.

AC: Take more advantage of snippet expansion

Even of the completion is with the standard auto-complete and not my fork (that support display of overloaded functions) snippet can still be interesting to expand.
At least differentiation function from variable.

Also the the simple candidates should be able to contain a bit more than the identifier/typed-text

AC: Attach brief comments to completion results

Auto-complete can display documentation popup on a selected candidate, display the Doxygen brief comment with the help of clang_getCompletionBriefComment().

Make this optional/configurable since not all project have a version a libclang with this feature and not all project use Doxygen comments.

Type inference variable declaration?

The title is quite bad, here is the idea:

void foo(const std::vector<Blah *> & v)
{
  // Before:
  // write a local variable declaration (or class variable) missing the type
  b = v[0];

  // After some magic:
  // The type has been inserted automatically
  Blah *b = v[0];
}

The first thing to look at is if the Fix-hint in the API can solve this issue.

This is something I really enjoy in Eclipse while writing in Java, KDevelop as something similar and probably some other tools that I don't know about.

Semantic integration

Hello.

In addition to auto-completion features, libclang supports source code indexing and AST traversing. Emacs has its own C++ parser (in semantic) that works quite slow and is not perfect (e.g., 'jump to definition' is very slow not always accurate for me).

And since both semantic and irony-mode are extensible, it's possible to write irony-mode plugin that will provide (hopefully) fast and reliable C++ back-end for semantic.

So is there already some work in progress? If not, I'm going to start working on it. Would you like such plugin to be in main irony-mode repository?

For now I have proof-of-concept standalone program that parses C++ code using libclang and prints elisp expression that is similar to (semantic-parse-region) output (but it is yet incomplete).

proof-of-concept program
example input
example output

Merge completion plugin into one

Since the last version of my auto-complete fork introduced a version that can be checked, the plugins irony-ac and irony-ac-simple can be merged into one (and limit unnecessary duplicated code). Hopefully, if one day auto-complete makes my fork obsolete we will be able to add support to the new version quite easily.

Tasks

  • merge irony-ac and irony-ac-simple (see 8415a15)
  • merge irony-ac-header-comp so header completion will be seamlessly integrated as part of the completion plugin (see related issue #16)
  • fix related issue header completion issue #9
  • update documentation/README (see 516d204)

Linking with libclang at non-standard path

If libclang is installed into /usr/local/ instead of /usr, irony-server fails to start with error:

irony-server: error while loading shared libraries: libclang.so: cannot open shared object file: No such file or directory

Enabling RPATH in CMake fixes the problem:

diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt
index ae0efc5..4278813 100644
--- a/server/CMakeLists.txt
+++ b/server/CMakeLists.txt
@@ -8,6 +8,8 @@ include_directories (${LibClang_INCLUDE_DIRS})
 include_directories (${IRONY_UTILS_INCLUDES})
 include_directories (${CMAKE_CURRENT_SOURCE_DIR})

+set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
+
 #
 # irony-server executable
 #

Unclear error message

When using auto-completion in a fresh install of irony-mode, it freezes for a few seconds and log file contains this:

1 errors found.
unknown type name 'type_info'

Is it possible to determine file and line that produced that error? I think it is in some system header, because I don't use type_info in my project.

It will be helpful to add file & line to log at least.

Auto-completion for std:: types doesn't work with CXTranslationUnit_PrecompiledPreamble

When CXTranslationUnit_PrecompiledPreamble option is used, auto-completion doesn't work for std:: types.

How to reproduce:

  • project-dir/.eproject
:includes '("src")
:extra-flags '("-std=c++11")
  • project-dir/src/main.cpp
#include <memory>

int foobar();

int main()
{
    ::foo       // <--- completion works
    std::auto_  // <--- no completion here
}

This fixes the situation for me:

diff --git a/server/TUManager.cpp b/server/TUManager.cpp
index 8ccf472..6e0f482 100644
--- a/server/TUManager.cpp
+++ b/server/TUManager.cpp
@@ -51,8 +51,7 @@ CXTranslationUnit TUManager::parse(const std::string &              filename,
                                       filename.c_str(),
                                       argv, static_cast<int>(nbArgs),
                                       0, 0,
-                                      clang_defaultEditingTranslationUnitOptions()
-                                      | CXTranslationUnit_PrecompiledPreamble
+                                      (clang_defaultEditingTranslationUnitOptions() & ~CXTranslationUnit_PrecompiledPreamble)
                                       | CXTranslationUnit_CacheCompletionResults);
       delete [] argv;
       translationUnits_[filename] = tu;
  • clang --version
Debian clang version 3.1-8 (branches/release_31) (based on LLVM 3.1)
Target: x86_64-pc-linux-gnu
Thread model: posix

It seems that there was no such bug before I've updated clang from 3.0-6 to 3.1-8. However, if I'm not missing something, last version from Git no longer compiles with 3.0-6 and produces linker error:

undefined reference to `clang_getExpansionLocation'

Please tell me if I can provide some additional information.

Server process segfault

Irony server segfaults sometimes, for example when irony-flycheck is enabled and "1 = 2 + 3" was typed.

Backtrace:

#0  __strlen_sse42 () at ../sysdeps/x86_64/multiarch/strlen-sse4.S:32
#1  0x00007fa09f627b4c in std::string::append(char const*) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#2  0x000000000041c79a in SyntaxChecker::formatSourceLocation (this=0xc40350, location=..., buf=...) at /home/victor/.emacs.d/modules/irony-mode/server/plugins/SyntaxChecker.cpp:160
#3  0x000000000041c8e5 in SyntaxChecker::formatSourceRange (this=0xc40350, range=..., buf=...) at /home/victor/.emacs.d/modules/irony-mode/server/plugins/SyntaxChecker.cpp:172
#4  0x000000000041c57c in SyntaxChecker::formatDiagnostic (this=0xc40350, diagnostic=@0x7fff1fad4370: 0x1f11490, buf=...) at /home/victor/.emacs.d/modules/irony-mode/server/plugins/SyntaxChecker.cpp:132
#5  0x000000000041c0e1 in SyntaxChecker::handleRequest (this=0xc40350, tuManager=..., data=..., buf=...) at /home/victor/.emacs.d/modules/irony-mode/server/plugins/SyntaxChecker.cpp:62
#6  0x000000000041720e in Server::handleRequest (this=0x7fff1fad8710, request=..., json=..., data=...) at /home/victor/.emacs.d/modules/irony-mode/server/Server.cpp:136
#7  0x0000000000416ef2 in Server::parseJSONAndProceed (this=0x7fff1fad8710, buf=...) at /home/victor/.emacs.d/modules/irony-mode/server/Server.cpp:105
#8  0x0000000000416c97 in Server::run (this=0x7fff1fad8710) at /home/victor/.emacs.d/modules/irony-mode/server/Server.cpp:84
#9  0x000000000041a661 in main () at /home/victor/.emacs.d/modules/irony-mode/server/main.cpp:39

Actually it calls std::string::append(NULL), becuase filename was NULL and so clang_getCString() also returned NULL. This patch fixes that:

diff --git a/server/plugins/SyntaxChecker.cpp b/server/plugins/SyntaxChecker.cpp
index 0bc8f6e..c6334f2 100644
--- a/server/plugins/SyntaxChecker.cpp
+++ b/server/plugins/SyntaxChecker.cpp
@@ -155,9 +155,12 @@ void SyntaxChecker::formatSourceLocation(const CXSourceLocation & location,
   clang_getInstantiationLocation(location, &file, &line, &column, &offset);
   CXString filename = clang_getFileName(file);

+  const char *filename_str = clang_getCString(filename);
+  if (! filename_str)
+      filename_str = "";

   // ("filename" offset (line . column))
-  buf.append("(\"").append(clang_getCString(filename)) // filename
+  buf.append("(\"").append(filename_str)               // filename
     .append("\" ").append(str::to_string(offset))      // offset
     .append(" (").append(str::to_string(line))         // line
     .append(" . ").append(str::to_string(column)).append("))"); // column

Remove SimpleJSON submodule

Using the submodule retrieve the whole project, submodule are not that well integrated into git IMHO and it makes the clone command just a bit more complicated.

Replace this by using a CMake external project if possible. Maybe this will not be possible because SimpleJSON is not a library.

Compilation DB: Make the menu option more obvious

In the CDB menu there are often two choices, a lowercase letter then an uppercase letter.

The difference is that the uppercase version will select the default value [with root=...] while the lowercase one will ask the user for input.

This should be documented somehow so the user knows directly about it.
Check if org-mode export C-x C-e has solved this problem already eventually since the menu use the same principles.

Note that currently the help-echo (mouse-over) is able to show some extra info but it's not obvious and won't work on TTY setups.

Syntax checking

  • A flymake implementation
  • A flycheck implementation http://flycheck.github.io/
  • Maybe a custom implementation to offers things such as fix-hints (can be [coupled with/additional to] flycheck/flymake I think)
  • document when done

Completion doesn't work, [1 error] in *Messages* but irony.<pid>.log is empty

Here's the content of my .dir-locals.el

((c++-mode
  (irony-compile-flags-work-dir . "/home/amey/Developer/GamePlay")
  (irony-compile-flags . ("-Igameplay/src"
                          "-Iexternal-deps/bullet/include"
                          "-Iexternal-deps/openal/include"
                          "-Iexternal-deps/oggvorbis/include"
                          "-Iexternal-deps/libpng/include"
                          "-Iexternal-deps/zlib/include"
                          "-Iexternal-deps/lua/include"
                          "-Iexternal-deps/glew/include"))))

And I get the following error in Messages:

Directory-local variables error: (wrong-type-argument stringp irony-compile-flags)
[1 error] Type `C-c C-b' to configure project

One suggestion: instead of just saying "1 error", print the error in the messages buffer or some other buffer.

Look travis-ci support

It could be interesting to have the continuous integration running for the project, the travis server have a bit more "outdated" version of Clang than I have and can be a way to monitor compatibility with older version of Clang.

Create an easily installable package

Tasks

  • Make it work with el-get, this is a tool that I know almost for sure can do a "1 click install". The standard package system of Emacs on the other doesn't integrate the idea of compilation steps for example I think.
  • Check Emacs byte-compilation, it improves performance significantly while parsing an entry of a compilation-db. http://www.gnu.org/software/emacs/manual/html_node/elisp/Byte-Compilation.html using (byte-compile 'irony-split-command-line) and (byte-compile 'irony-split-command-line) divide the time by ~2.
  • Play with CMake to retrieve Clang if not on the system. Some binaries of Clang can be found here: http://llvm.org/releases/download.html

Integrate with ff-find-other-file

Would be nice to jump from header file to source file. Emacs already integrates such functionality, with the knowledge of irony-mode about the includes directories and everything it should be easy to integrates.

Also, at least for source files, libclang has some a function getInclusions() which allow to iterate over the inclusion. It might be unnecessary, I'm not sure.

Some problems and suggestions

Hi Guillaume, thanks so much for providing this wonderful tool for C++ programming in Emacs.

However I think there still can be some improvements:

  1. irony-compile-flags is usually not set right when explicit flag is a necessity. It seems that there is always a need to run C-c C-b manually each time I load a project, which is a bit annoying. I think there need to be a choice(or simply loads it) when irony detects some flags related files(cmake, json compilation database, .clang_complete or .dir-locals).
  2. irony-cdb settings for cmake is a bit inflexible since the build directory has to be put inside the root directory of the project(for instance, irony-build directory has to be put inside irony-mode).
  3. It seems that .clang_compilation have a limitation that each flag should occupy one line. Although it is a good habit to be written like this, but I think the docs should include this detail.
  4. I think the completion of headers should also contain those specified in irony-compile-flags, and it seems that irony has not included yet. Also I find that there are some problems when irony-compile-flags also include those system headers, however without them irony complains there are errors as well.
  5. Personally I have a need to set ffap-c-path for convenience(especially when due to some reasons irony detects errors and I have to lookup the header files to make sure it's not my fault), a hook after the cdb settings should be a direct solution.
  6. The error messages returned by irony-compile-check give so little information that I usually have to read the log file inside /tmp/. And I think there is a need to include the diagnostics, too. And when irony-compile-check finds error, there is a choice that I can see what's going wrong(I simply add a line inside CompileCheck.cpp to print the diagnostics information, it's really a dirty tweak; I think the right approach should be redirecting them to a special file). Also when there are only warnings, there is no need to suggest C-c C-b:-)
  7. Some kind of completion is not covered, for instance, when I write puts(__fu|) and the cursor now behind u of __fu(and it is in the snippet state), C-<RET> would cause Emacs hanging there(I guess it is because there is no answer from the server side).
  8. I don't know why, but irony-flycheck is really slow. And there are some errors for this plugin: to use (irony-enable 'flycheck), I have to change the name irony-flycheck.el to flycheck.el and change (provide 'irony-flycheck) to (provide 'irony/flycheck). And since there is a general purposed Emacs extension flycheck with the same name flycheck.el, I think some modifications is needed.
  9. Could you please tell me the necessity to add a copy inside /tmp/? (Sorry that I am not so familiar with clang pch and emacs handling for process.)
  10. I write a simple plugin SymbolInfo,cpp and elisp, based on cc-lookup(I wrote several days before) for irony-mode(and I copy quite a lot of code from your well written completion plugin), but since I think it is still too simple(for instance, doxygen document features can be added). I hope you can give me some adivice whether it could be added into the main stream now(there are still some bugs which I think have relations with the temporary files inside /tmp/ since I really don't know the mechanism behind this).

.dir-locals.el need a manual reload

According to the following comment: #41 (comment)

The .dir-locals.el method might need for the user to call reload manually.

Also, with the flags in .dir-locals.el (again, in the project root) I'm being forced to run irony-reload-flags every time I visit a c++ file for the first time after launching emacs. Is that supposed to happen?

It should not be necessary when the file is freshly opened.

Support RuntimeCompiledCPlusPlus

Surprisingly it worked out-of-the box when I tested (it now have some CMakeFiles). It can be interested to see if something can be done in Emacs to integrate it.

Just an idea, maybe a bad one.

Yasnippet version

What is minimal required version of yasnippet? It seems that yasnippet < 0.6.1 is not supported. If yes, it'll be greate to add a note to README.

Add support for .clang_complete

Using eproject my be a bit tedious and not necessary if it's used only to set some project properties (such as the compilation flags). An elisp-only plugin can be made to manage the flags the same way as the Vim plugins (https://github.com/Rip-Rip/clang_complete/)

The current format in use is described here: https://github.com/Rip-Rip/clang_complete/blob/2831a5040ee328103b941fcdbc3c8d6ef5593b59/doc/clang_complete.txt#L45

Taking a look at the cc_args.py script my be interesting too: https://github.com/Rip-Rip/clang_complete/blob/2831a5040ee328103b941fcdbc3c8d6ef5593b59/doc/clang_complete.txt#L271

Compilation DB

  • Move irony-cmake.el to a more general compilation-db.el
  • Add support for .clang_complete (#6)
  • compile_commands.json contains the flags to compile a source file but not for header. Find a way to retrieve the flags for headers. It should work if possible without any user input (if we already have the flags for a file using this header it should be enough). (see: dfb2a30)
  • Trigger a "file compile check" (asynchrone) when the file is loaded. When the result is received, if the file doesn't compile print a message indicating about the build configuration shortcut (e.g: "Hit C-c C-b to configure the build").
  • Do not make it a plugin but simply part of irony loading as no external dependencies is needed and it is quite useful.
  • Find a meaningful prompt for read-char-choice
  • Not the right issue for that, but try to see if headers in the same directory are completed during header-comp.
  • Find out why the irony-mode init seems to be called twice when opening a new file.
  • Remove ASM entries from the compilation db entries, it's a waste of time to process their flags.

See: http://clang.llvm.org/docs/JSONCompilationDatabase.html

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.