TerminalFi/LSP-copilot

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

oshihirii opened this issue · 24 comments

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.

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

@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.

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.

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

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: sublimelsp/LSP#2282

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.

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

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.

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?

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

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

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 sublimelsp/LSP#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

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)
  1. Put the following to Packages/User/Default.sublime-commands:
[
    {
        "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

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.

This has been shipped with .copilotignore support

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?

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.

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

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).

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

@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

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

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.