-
Notifications
You must be signed in to change notification settings - Fork 97
Make irony-mode work with Tramp #58
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Thinking about this a little more, this might be very simple. The exact same irony-server executable may work fine; the elisp code would just have to notice that it was looking at a file via Tramp and run irony-server on the remote server, redirecting stdin and stdout over the ssh connection. |
I would be interested in such functionality too. Right now the "snapshot" of a file is saved in the '/tmp/' directory for irony-server to find. Issue #57 propose to just send the unsaved file content to the irony-server process as a part of the request. This should be cheaper than creating a file on disk, saving it's content, ....and in this case I think it can make this issue easier to solve since it will limit dependencies on the file system. I don't know how to capture the stdin/stdout of a SSH process but hopefully it's not too difficult. |
Closing this. |
Hi. I find Irony module very useful in everyday programming. Its auto completion is fast and precise. Additionally, appending return value as last segment of complete choice is very nice. The thing I'm missing with it is tramp support, which I find outstanding comparing to all other IDEs. As the problem has been raised twice in the past (in this thread and in #217), I'd like to share my experience with adapting tramp to be used by some emacs module. Maybe someone will find this information useful enough in case of adapting tramp to be used with irony as well. Tramp allows for handling files/processes that reside on some 'remote site'. 'remote site' means some user@host we have ssh access to, but it also means su/sudo user being on the same machine, some smb share etc. IMHO: from irony perspective, ssh and su/sudo (to root or any other user) are most interesting ones. Communication with server using tcp socket does not seem to be good choice:
Tramp is part of emacs ?core?. This implies that crucial functions used to communicate with external processes have their tramp aware counterparts, which communicate with processes residing on 'remote site'. Example: emacs communicates with sudo::irony_server. What is more, most of these functions are unified, so You do not need to have two versions of code, first version for non-tramp communication and second for tramp one. Here is the list of functions and its tramp counterparts. Roughly, it is enough to replace one with another.
Tramp is aimed to be an abstraction layer to work with files and communicate processes regardless they are local or remote. There are some small pitfalls but I believe they are not that hard to overcome (see below). For the sake of completeness let's give example path to local file and to remote one: /home/user/file.txt - local. That would be good if irony server does not have the notion if request comes from 'local' emacs or 'remote' one. That would be even better if no changes were required to irony server at all. To achieve that, elisp code must take care to convert remote paths to local ones when passing them as arguments to remote irony server. example: visiting the /scp:user@host:/home/user/project/module/file.cpp will issue Before It's as easy as:
where:
so, after that:
Now it's server part to process the request and produce results. If result contains some paths, these will be returned to remote emacs as local paths (we want server does not have the notion whether emacs is local or remote). Thus when elisp code receives the result, it has to convert such paths back into remote ones. Here's the function:
The magic behind this function is When for example You are visiting /scp:user@host:/home/user/project/module/file.cpp, then Sometimes one really needs to know if current file is local or remote one. Here's how to get it:
The dirty thing is about killing the remote process. The following is the rough example how it could be done, but it does not mean that there is some much better solution. Anyway I believe that the following code might be usable.
@Sarcasm mentions:
If irony server will be started with I hope the information above will be a bit helpful in case someone will try to adapt tramp into irony. Thank You very much for irony. regards, |
Just curious, did you get irony working with tramp by doing the modification you propose? This is a functionality I would be very interested in having if there is no limitation. You summarized well what needs to be done. One "feature" I'm wondering about, is whether You made the hard work, it would be super nice if you (and I, I can help) can push it further so it makes it into irony-mode. I would use the feature at work from time to time I think. :) |
I didn't do any modifications to the code.
irony also uses flycheck. As far as I know flycheck does not work with tramp.
For the path returned from irony server it is enough to call
IMHO yes. The only extra step would be to copy (using tramp) irony server sources to some remote directory before compilation. Maybe it is worth dividing the task into sub-steps. I included questions.
What do You think about it? Luckily all the steps must work with local irony server as well so maybe they could be committed one by one without having to wait by the end of step 6. Step 1 seems to me to be most difficult. It should be discussed before the subsequent steps will be started. I'm going to be busy till the end of January 2017, so it will be a bit difficult to me to touch the code by this time, but I'm willing to help as much as I can. regards, |
2 functions:
Hopefully, starting irony-server is as simple as replacing Also irony-server can be compiled by hand for starter. I think, stopping the process can be automatic when we kill the tramp buffer/session, I think it will be transparent.
Changing communication should be reasonably easy, 2 functions do the actual work. They can probably call one common function that would do the right thing for tramp. The There is
Sounds great.
Agreed, or it's okay to work on this in a branch and commit when all is working. Either way is fine for me but I may prefer to push only when at least something is working.
To me step 1 is relatively easy. Since irony-server communicates with stdout/stdin, we just have to find a way to communicate with a remote process instead of local but I'm am under the impression that tramp handles this kind of things nicely. |
the contents of modified buffer to be completed as well? I'm asking because, I found the following above:
I just looked at irony-cdb. To see what filesystem aware functions are used there (I hope I didn't overlook anything):
Good news is that all of them work with remote files. |
Irony used to store things in Oh great, if locate-dominating-file works with tramp. |
good news. This was the reason why I classified step 1 as most difficult.
works with tramp. |
I am very interested in this as well. I am still looking for a solution to have Emacs C++ code completion on my remote C++ projects. I couldn't get either auto-complete-clang nor company-clang to work remotely, and of course flycheck was never meant to really work on remote files, which is sad. |
Any progress on this? |
Bump |
Is there a way to only disable irony when accessing remote files? It gives too many messages viewing errors. So I want to disable it until irony and tramp can play nice together. |
I think you can enable irony-mode only under the following condition: (unless (and buffer-file-name (file-remote-p buffer-file-name))
(irony-mode 1)) |
Thanks for the response. I have this setup, so I guess your suggestion wont work for me?
|
I did not give full code because I wanted to give you the opportunity to learn some elisp. But here you go, you can use this config: (use-package irony
:ensure t
:diminish irony-mode
:preface
(defun my/irony-mode ()
(unless (and buffer-file-name (file-remote-p buffer-file-name))
(irony-mode 1)
(irony-cdb-autosetup-compile-options)))
:hook ((c-mode . my/irony-mode)
(c++-mode . my/irony-mode)
(objc-mode . my/irony-mode)
(c++-mode . my/irony-mode))) |
I love irony-mode. It works much better than any of the alternatives for me. One problem I've found, though, is that it doesn't seem to work correctly with Tramp. I get some sort of fall-back completion instead of irony-mode when editing remote C++ files.
Can this be fixed? I'm guessing this has something to do with either irony-server or libclang itself being unable to open the remote files. Would it be feasible to run irony-server remotely and communicate with it via TCP? Looks to me like irony-server just communicates via stdin/stdout right now, and it may not be hard to extend it to support IO over a socket as well, but I'm not sure what other implications there are.
The text was updated successfully, but these errors were encountered: