company-mode / company-mode

Modular in-buffer completion framework for Emacs
http://company-mode.github.io/
GNU General Public License v3.0
2.21k stars 228 forks source link

Is it possible to turn off completion of file extensions? #910

Open doomchild opened 5 years ago

doomchild commented 5 years ago

When I'm editing (for example) Node code, I often want to complete a file path (for an import, for example), but I don't want the .js or .json extension to be completed. Is this configurable? Right now, I just delete the extension, but if it can be turned off, I'd like to do so.

dgutov commented 5 years ago

You can turn off company-mode in a major mode hook. The same hook function can also check the file extension.

This will require writing a few lines of Emacs Lisp.

doomchild commented 5 years ago

I don't want to disable company-mode, I just want to adjust the completed text in certain circumstances. I'm teaching myself about advising functions to try and deal with this. I was hoping there was already a configuration point, but it's entirely possible that there isn't.

dgutov commented 5 years ago

Ah. You can advise the company-files backend function somehow or write a derived backend.

dgutov commented 5 years ago

Or advise company-files--complete.

doomchild commented 5 years ago

Okay. I'll look into that function. I was still trying to figure out just exactly where to inject things.

doomchild commented 5 years ago

So I wrote something to filter the output of company-files--grab-existing-name, because it seemed like the least invasive change I could make, but I'm getting a weird error about the symbol's value as a variable being void.

This is how I'm doing it. Am I missing something? This is the first time I've tried advising a function.

(use-package company
  :demand t
  :bind (:map company-active-map
          ("C-n" . company-select-next)
          ("C-p" . company-select-previous)
          ("<tab>" . dc/company-complete))
  :config
  (setq company-dabbrev-downcase nil)
  (setq company-idle-delay 0.01)
  (add-to-list 'company-backends 'company-omnisharp)
  (add-hook 'csharp-mode-hook 'company-mode)
  (add-function :filter-return #'company-files--grab-existing-name #'dc/company-javascript-files-exclude-extensions))
dgutov commented 5 years ago

Try using advice-add instead.

doomchild commented 5 years ago

Okay, that solved that problem. Thanks. Now I just have to figure out why it seems like company-files--grab-existing-name isn't executing anymore. To the debugger, I suppose.

qhuyduong commented 4 years ago

@doomchild with #983 , we can do something like this:

(defun +company-files--post-completion (arg)
    (let* ((file-name-regex (rx (and "." (or "js" "jsx" "rb") line-end)))
           (matched-position (string-match file-name-regex arg)))
      (when matched-position (delete-char (- (- (length arg) matched-position))))))

(advice-add #'company-files--post-completion :after #'+company-files--post-completion)
yugaego commented 3 years ago

@dgutov , would it make sense to label this Issue as a wishlist with one of the following ideas (if feasible) in mind:

  1. Implement extensions chopping similar to company-files-chop-trailing-slash.
  2. Add user option such as ~company-files-complete-extension-explicitly and treat dots in filenames similar to directory separators (hit TAB one more time to complete an extension)? (With probably a need to list tracked extensions by one more user option in both cases.)

If not, can this issue be closed?

dgutov commented 3 years ago

I'm not sure. 2 feature requests (without extra likes, etc) in 2 years might indicate the lack of general interest, so we might as well close it.

If not, I like option 1 better. But how are are people going to use it? Set the variable on per-project basis? Or otherwise never see file extensions in completion, which seems odd. Perhaps it could be combined with #931, as a separate backend/wrapper of sorts, specifically for, like, completion of #include <...> and similar directives, together with a way to define a list of directories to search in. That one's not moving anywhere either, though, but perhaps @vspinu has some more ideas.

dgutov commented 3 years ago

In general, I think backspacing over a file extension is really not a problem most of the time (you don't really need to do that often). The other issue linked above seems more practical and interesting.

doomchild commented 3 years ago

I don't want to sound like a jerk, but if you're importing project-level stuff in Javascript, you have to backspace over the extension a lot.

dgutov commented 3 years ago

OK, guess I see what you mean.

With Node's require syntax any local imports use names relative to the current file (right?), so this backend should actually work fine most of the time (which is not the case with many other import systems and other languages), with file extensions being the main eyesore.

dgutov commented 3 years ago

Like described above, I think a new backend called something like company-imports should work best. The definition shouldn't be too big -- it can reuse most of the code in company-files.

doomchild commented 3 years ago

Yeah, my headache comes strictly from writing for node.