TerminalFi / LSP-copilot

GitHub Copilot support for Sublime Text LSP plugin provided through Copilot.vim.
623 stars 25 forks source link

How to turn Github Copilot off in one file or turn it off temporarily? #126

Closed oshihirii closed 6 days ago

oshihirii commented 8 months ago

Hello,

Sometimes I don't want suggestions.

Is there a way to turn off GitHub Copilot for one file, or turn it off temporarily?

Thank You.

Edit:

Also, whilst I think of it, in terms of privacy/security...

Once I start using GitHub Copilot in Sublime Text, is everything I type into Sublime Text sent to GitHub Copilot servers and saved there?

Obviously, sometimes I am typing things that are business confidential and should not be shared with the world, so it would be good to get re-assurance that this is not happening. I wouldn't want something confidential I typed in my text editor, showing up as a suggestion in someone else's text editor who is using GitHub Copilot.

Thank you again.

jfcherng commented 8 months ago

You may ask Microsoft for that. https://github.com/orgs/community/discussions/11254

There is no general way to ignore thing in LSP protocol. It's per-server definition/implementation.

@rchl Is it possible to start/stop attaching a server seesion per view?

rchl commented 8 months ago

@rchl Is it possible to start/stop attaching a server seesion per view?

No, we don't support such use case.

@oshihirii I think you should be looking at the terms and conditions of https://github.com/features/copilot to understand what data it collects or receives since this package just starts the copilot without sending any data on top of that.

Also, it's probably up to your company to specify policies where it either allows or doesn't allow the use of copilot specifically.

timfjord commented 8 months ago

Actually, I was thinking about something similar too.

Technically, it should be possible, as we could check some flag in the view settings, and when it is True, do not autocomplete suggestions(similar to how we handle the auto_ask_completions flag). We also would need a view command to toggle the flag. The only downside is that(most likely) it will be tricky to maintain a proper status in the status bar, as it would be good to highlight whether Copilot is disabled in the view.

I think VSCode has a similar feature where you can disable Copilot for the current file.

TerminalFi commented 8 months ago

VS Code and Zed support this. Copilot is supposed to be supporting an ignore file now or soon.

jwortmann commented 7 months ago

I assume that this should be handled by the client, so that the server won't get any requests or file notifications for the ignored files. A related LSP issue: https://github.com/sublimelsp/LSP/issues/2282

jfcherng commented 7 months ago

Handling it in LSP makes more sense imho. So we don't need every LSP-* to invent its own format. The session doesn't even need to attach to those ignored files.

pineapplemachine commented 7 months ago

I'm interested in trying Copilot with Sublime Text, but for similar reasons I want to enable suggestions only on a per-file basis. I would like to use automatic suggestions, but only if I manually approve it first for a particular file. I need to be certain that credentials and other sensitive data that I may open in Sublime never leave my machine.

rchl commented 7 months ago

Many servers do file traversing on their own since they need to read and analyze the whole project to be able to provide all the functionality. While Copilot doesn't sound like a server of that kind, in theory you can never be sure what it does, even if you restrict it to specific files.

pineapplemachine commented 7 months ago

Yeah...Not being sure whether Copilot might be transmitting files without my explicit approval on a per-file basis is a non-starter. Have I overestimated Microsoft on this one?

TerminalFi commented 7 months ago

Seeing as GitHub doesn’t seem to want to support this. I’m working on support for this.

oshihirii commented 7 months ago

I'm just adding for reference, based on a resource that was suggested earlier, relevant snippets from FAQ > Privacy at:

https://github.com/features/copilot

Some of the statements are reassuring, but some of them seem a bit contradictory.

(I've attached a screenshot of the whole FAQ > Privacy section for reference).

Will my code be shared with other users?

No. We follow responsible practices in accordance with our Privacy Statement to ensure that your code snippets will not be used as suggested code for other users of GitHub Copilot.

What personal data does GitHub Copilot collect?

GitHub Copilot personal data from three categories of data: user engagement data, prompts and suggestions.

User engagement data User engagement data is usage information about events generated when interacting with a code editor. These events include user edit actions (for example completions accepted and dismissed), error messages, and general usage data to identify user metrics such as latency and feature engagement. This information may include personal data, such as pseudonymous identifiers.

Prompts A prompt is the collection of code and supporting contextual information that the GitHub Copilot extension sends to GitHub to generate suggestions. The extension sends a prompt when a user working on a file, pauses typing, or uses a designated keyboard shortcut to request a suggestion.

Suggestions A suggestion is one or more lines of proposed code and other output returned to the Copilot extension after a prompt is received and processed by the AI models that power Copilot.

Does GitHub Copilot use Prompts or Suggestions to train AI models?

No, GitHub Copilot does not use Prompts or Suggestions to train AI models. These inputs are not retained or utilized in the training process of AI models for GitHub Copilot.

github_copilot_faq_privacy_141123_0958

jwortmann commented 5 months ago

It seems like .copilotignore files are now supported by 3rd-party extension in VSCode (https://github.com/mattickx/copilotignore-vscode) and Vim.

I'd like to leave the following example code snippet here, which should make it possible to ignore file patterns from a .copilotignore file placed in the root of a folder that is opened in the sidebar, once https://github.com/sublimelsp/LSP/pull/2410 is merged and a new LSP release gets published (i.e. wait until it's final before adding the implementation here). I don't use Copilot myself, and I don't know how far the .copilotignore file is standardized, so you may want to adjust the logic regarding how the patterns from the file are handled, or for example read files from other locations like ~/.copilotignore too. Not sure if it's relevant or not, but possibly it's also of interest how LSP handles the file pattern format from ST, in order to use it with fnmatch: https://github.com/sublimelsp/LSP/blob/8023408dfd7917d23f89c9bb3f7356a4d2d1d895/plugin/core/types.py#L85

The should_ignore method will be called each time a file (or other view), which is handled by the language server, gets opened. So perhaps it would even be useful to add some kind of caching (for the file patterns), to reduce disk IO (?)

I think passing only the view argument to the method should be sufficient, but if you see any potential design improvements, feedback is welcome.

from fnmatch import fnmatch
import os

    # in your plugin class:

    @classmethod
    def should_ignore(cls, view: sublime.View) -> bool:
        filepath = view.file_name()
        if not filepath:
            return False
        window = view.window()
        if not window:
            return False
        for folder in window.folders():
            copilotignorefile = os.path.join(folder, '.copilotignore')
            if os.path.isfile(copilotignorefile):
                try:
                    with open(copilotignorefile, 'r') as file:
                        for pattern in file.readlines():
                            pattern = pattern.strip()
                            if pattern == '' or pattern.startswith(('#', ';')):
                                continue
                            if '/' not in pattern:
                                pattern = '**/{}'.format(pattern)
                            if fnmatch(filepath, pattern):
                                return True
                except OSError:
                    pass
                break
        return False

Ideally please also include a syntax definition for .copilotignore files, so that themes can add a special file icon for them. Example (reusing some parts from the .gitignore syntax):

%YAML 1.2
---
name: Copilot Ignore
scope: text.copilotignore
version: 2
hidden: true
hidden_file_extensions:
  - .copilotignore

contexts:
  main:
    - include: Git Common.sublime-syntax#comments
    - match: '(?=\S)'
      push: [pattern-content, Git Common.sublime-syntax#fnmatch-start]

  pattern-content:
    - meta_scope: string.unquoted.copilotignore entity.name.pattern.copilotignore
    - match: $
      pop: 1
    - include: Git Common.sublime-syntax#fnmatch-unquoted-body
davidhcefx commented 3 months ago

Is there a way to turn off GitHub Copilot for one file, or turn it off temporarily?

I have just worked out a simple way to turn it off temporarily. Here's the instructions:

  1. Put the following to Packages/User/copilot_auto_ask_completions.py:
    
    import sublime
    import sublime_plugin

class CopilotAutoAskCompletions(sublime_plugin.ApplicationCommand): SETTING_FILE = 'LSP-copilot.sublime-settings'

def run(self, **kwargs):
    # load settings
    setting = sublime.load_settings(CopilotAutoAskCompletions.SETTING_FILE)
    enable = kwargs.get('enable', True)
    setting['settings'] = {
        'auto_ask_completions': enable
    }
    # write back
    sublime.save_settings(CopilotAutoAskCompletions.SETTING_FILE)
2. Put the following to `Packages/User/Default.sublime-commands`:
```json
[
    {
        "caption": "Copilot: Disable auto_ask_completions",
        "command": "copilot_auto_ask_completions",
        "args": { "enable": false }
    },
    {
        "caption": "Copilot: Enable auto_ask_completions",
        "command": "copilot_auto_ask_completions",
        "args": { "enable": true }
    }
]
  1. Now, just trigger it in the command palette to enable or disable it
mklcp commented 1 month ago

In Command Palette, setting "LSP: Disable Language Server Globally" (or in Project) was enough for me. LSP-copilot can be disabled if you want, but not others.

TerminalFi commented 6 days ago

This has been shipped with .copilotignore support

jwortmann commented 6 days ago

I haven't tested and have only skimmed over the PR, but it looks like you don't use the new API method that I added based on the discussion here. So I assume that the file contents including secrets and all edits of the affected files are still sent to the server, right? I guess you needed some more code to handle the non-standard requests that Copilot uses, but is there any reason why you didn't use the new LSP API to suppress the file synchronisation?

TerminalFi commented 6 days ago

I haven't tested and have only skimmed over the PR, but it looks like you don't use the new API method that I added based on the discussion here. So I assume that the file contents including secrets and all edits of the affected files are still sent to the server, right? I guess you needed some more code to handle the non-standard requests that Copilot uses, but is there any reason why you didn't use the new LSP API to suppress the file synchronisation?

Which API ? Line 50 of listeners.py prevents ignored files from being sent.

TerminalFi commented 6 days ago

Ahh honestly, I didn't see it. So I can update it so we use should ignore on top of the file watcher we added. But currently, no files aren't sent to the server still

jwortmann commented 6 days ago

Well I don't really know how Copilot works, but if this package is using LSP, then document syncronisation is still automatically handled by LSP (unless suppressed via should_ignore). So I guess this means that the full contents of any newly opened file are still sent to the server (via didOpen notification) and also whenever new changes are made to the file (didChange).

TerminalFi commented 6 days ago

Makes sense. I've got the local changes for should_ignore. So I'll push and make a new release since we never cut a release for cooilotingore yet

TerminalFi commented 6 days ago

@jwortmann This is what I noticed. Which seems like I might need to use this approach, and my approach combined. This continues to ignore a file if

  1. copilotignore contains env.py
  2. Open env.py
  3. copilotignore removes env.py
  4. Switch back to env.py
  5. lsp-copilot is still ignoring it

So changes to this file wont reflect to already opened views

TerminalFi commented 6 days ago

Is there a way to re-notify LSP to add file to session? I can either close and opens file (poor ux) or restart lsp-copilot

jwortmann commented 6 days ago

Is there a way to re-notify LSP to add file to session? I can either close and opens file (poor ux) or restart lsp-copilot

Hm, I think there is no "official" way. Maybe we could add another method to unigore ignored views.

What you could try to do is to modify either the "syntax" or "lsp_uri" view setting (and then set it back to the old value after a very short delay). This should retrigger the registration of the view, when the corresponding tab gets focused the next time: https://github.com/sublimelsp/LSP/blob/293f4a4340cca5ab1ad065643e4f20d9b270b2b1/plugin/documents.py#L1020-L1030 This is more of a hack though, and I haven't tested it.

TerminalFi commented 6 days ago

This seems working

https://github.com/TerminalFi/LSP-copilot/pull/173/files