Skip to content
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

Integrate YCMD JSON settings #485

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

ChoppinBlockParty
Copy link

Add ycmd-settings-json-filepath - path to YCMD settings JSON file.
YCMD accepts a json file where the server settings are set, including
a one-time HMAC. The file is deleted after the server starts.
As for now, emacs-ycmd was just creating a temporary file from
some hard-coded/customizable values.
Since those settings have to direct relation to emacs-ycmd, rather
only to YCMD, it is good idea to keep it this way and just feed the
file adding an HMAC value.

That change will read the JSON file, insert HMAC and pass it to YCMD.
Please, test it, feedback is appreciated, I will mainly test it on
C/C++ and Go.

That is supposed to solve #472, #479.

I copied ycmd/default_settings.json to my .emacs. and use it

ycmd-settings-json-filepath (concat user-emacs-directory "ycmd_default_setting.json")

Add `ycmd-settings-json-filepath` - path to YCMD settings JSON file.
YCMD accepts a json file where the server settings are set, including
a one-time HMAC. The file is deleted after the server starts.
As for now, emacs-ycmd was just creating a temporary file from
some hard-coded/customizable values.
Since those settings have to direct relation to emacs-ycmd, rather
only to YCMD, it is good idea to keep it this way and just feed the
file adding an HMAC value.

That change will read the JSON file, insert HMAC and pass it to YCMD.
Please, test it, feedback is appreciated, I will mainly test it on
C/C++ and Go.

That is supposed to solve abingham#472, abingham#479.
(let ((hmac-secret (base64-encode-string hmac-secret))
(global-config (or ycmd-global-config ""))
(extra-conf-whitelist (or ycmd-extra-conf-whitelist []))
(confirm-extra-conf (if (eq ycmd-extra-conf-handler 'load) 0 1))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ycmd-extra-conf-handler is used also in ycmd--handle-extra-conf-exception so it needs to be saved from the json.

Copy link
Collaborator

@ptrv ptrv Oct 18, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes also a couple of defcustoms redundant and need to be removed

Copy link
Author

@ChoppinBlockParty ChoppinBlockParty Oct 18, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ycmd-extra-conf-handler is used also in ycmd--handle-extra-conf-exception so it needs to be saved from the json.

I am not sure about that, because that is just how emacs-ycmd displays exceptions from ycmd. ycmd's option to confirm config is a little bit different, it is about does the server send this exceptions or not.

Copy link
Collaborator

@ptrv ptrv Oct 18, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually you are right. ycmd-extra-conf-handler also has to be removed, also from the check in ycmd--handle-extra-conf-exception

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not have a strong opinion, but I find it ok to keep ycmd-extra-conf-handler even, though it does overlap in behavior with the ycmd's option, it still has some neat behavior control over how emacs handles the exceptions, that someone might like. Ofc, it is not useful if the exceptions are totally disabled from the JSON settings, but I think it is fine.

ycmd.el Outdated
@@ -130,6 +130,10 @@
"Path to global extra conf file."
:type '(string))

(defcustom ycmd-settings-json-filepath (concat (file-name-directory load-file-name) "ycmd_default_settings.json")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this it's better to use the f.el library and this (f-join (f-dirname (f-this-file)) "ycmd_default_settings.json") because it handles also the cases when the file is loaded with eval-buffer, rather than loaded from the init file.
f.el is already used in company-ycmd and needs only to be added to the required packages to the header.

@ptrv
Copy link
Collaborator

ptrv commented Oct 18, 2018

Maybe we should keep the way we load settings and add loading from a json file as additional option, because this adds an extra step to setting up emacs-ycmd (which is already a pain point). Or we add a default json file to the repo. The setting should work out of the box.

@ChoppinBlockParty
Copy link
Author

ChoppinBlockParty commented Oct 18, 2018

Actually, I intended to add the default settings file, but forgot to commit it. Thank you for the review. I will clean up the stuff you mentioned earlier.

@abingham
Copy link
Owner

First of all, thanks for putting this together. I think this is a big step forward for emacs-ycmd.

I do have some concerns about the design, though. My primary concern is that we've moved a lot of stuff that was under programmatic control and put it into a JSON file. For example, users used to be able to set ycmd-gocode-binary-path, and it would be used by ycmd; they could do this entirely within emacs lisp without having to really know much about ycmd itself. I considered this a win. Now, in order to do any sort of ycmd customization, they have to create an entire ycmd conf file.

As I mentioned in my comments in #479, I was hoping for a system that augmented the existing implementation rather than replacing it. I imagined that we would keep the original emacs-lisp-based system intact (i.e. ycmd--options-contents or something equivalent), but we would also let users specify a json config file. The contents of that file would be merged in to the configuration generated by ycmd--options-contents.

As I see it, this approach has several benefits:

  1. It doesn't require an extra file (i.e. the default settings json file)
  2. It keeps a lot of things under emacs-lisp control. In principle, in fact, we could put the entire configuration under emacs-lisp control if we chose to.
  3. It lets users use an external ycmd config file to modify only the parts they need to modify. With this PR, they have to either replace all or none of the default config.

It's possible that the merging I mention is hard or impossible, in which case I'm happy to be corrected. But am I missing some benefits of the approach taken in this PR?

@ChoppinBlockParty
Copy link
Author

ChoppinBlockParty commented Oct 19, 2018

The advantage of this is to not duplicate the functionality that is already done in ycmd. At the beginning there was no ycmd, there was ycm - vim plugin, all options of the server were in vim's config. Now, there is ycmd and they moved the options from vim to ycmd json file, likewise emacs-ycmd should not keep server options inside itself for many reasons.
Of course, I see your concerns that the users who set up the options in emacs might get disappointed, however, that cleans up code removing duplicated functionality making the project less dependent on ycmd options. Though in reality I think 99% or more do not know anything about this options and do not touch them at all (we have provided a default ycmd json to the project, so this PR would not break anything for them).

@abingham
Copy link
Owner

emacs-ycmd should not keep server options inside itself for many reasons.

What reasons? I'm asking in all seriousness, because it's entirely possible that I'm missing an important point.

As far as I can see, though, with your approach we still have to maintain and ship a JSON file with all of the ycmd configuration options in there, so we haven't gained any freedom from needing to know that information. Given that we have to know what goes in that file, I don't see how putting it in a JSON file is better than keeping it in emacs-lisp. On other hand, I think there are practical benefits to keeping it in emacs-lisp (though perhaps minor ones, as you say).

making the project less dependent on ycmd options.

As long as we have to maintain a JSON file containing all of the options with their default values, we are still dependent on them. Now, if we could get the ycmd server to generate a default configuration for us on demand (i.e. so that we didn't have to know anything about it), that would be a different story. As it is, though, we've just moved the location of a dependency from one place to another, while degrading actual and potential functionality.

I guess I'm struggling to see how the new JSON file you're proposing is any better than keeping identical information in emacs-lisp. Either we need to know that information or we don't.

@ChoppinBlockParty
Copy link
Author

ChoppinBlockParty commented Oct 19, 2018

As long as we have to maintain a JSON file containing all of the options with their default values, we are still dependent on them.

ycmd ships this default file. In this revision we added it only to avoid breaking changes, or reduce them to minimum, with the current version of emacs-ycmd. In the future we might post a fat comment in the readme, to draw people attention to switch to ycmd config. Also it is possible to provide an option to set a path to ycmd. This path will be used for two things: json config and ycmd command, with this you do not need to ship the options (and the side improvement would be to set a default command prefix to python3 -u, that will make it easier to start with emacs-ycmd).

I guess I'm struggling to see how the new JSON file you're proposing is any better than keeping identical information in emacs-lisp. Either we need to know that information or we don't.

If you take into account what I said above, this means that you do not need to know this information. As I said in the comments above it has no relevance to emacs-ycmd itself, it is only relevant to ycmd.

@abingham
Copy link
Owner

abingham commented Oct 19, 2018

In the future we might post a fat comment in the readme, to draw people attention to switch to ycmd config.

I guess this is where we differ. I'm strongly opposed to requiring people to have a ycmd config, esp. as we've already demonstrated that we can provide one for them. I think it's part of our job to make using ycmd as painless as possible, while at the same time giving them the flexibility to configure it as much as they want to. A lot of users - myself included - will never have a need to know about these configuration files, and I think that we're doing them a service by not forcing them to.

As I said in the comments above it has no relevance to emacs-ycmd itself, it is only relevant to ycmd.

I'm sorry, but this is nonsense. emacs-ycmd only exists to make ycmd accessible to emacs users. To say that the details of ycmd aren't "relevant" to emacs-ycmd is some sort of software engineering fundamentalism.

@ChoppinBlockParty
Copy link
Author

ChoppinBlockParty commented Oct 19, 2018

this is nonsense

software engineering fundamentalism.

Relax, it is just 50 line pull request, no reasons to get that emotional.

@abingham
Copy link
Owner

abingham commented Oct 23, 2018 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants