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

v0.3 issue (not tested) #37

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions MultilineGreyText/Options/General.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Community.VisualStudio.Toolkit;
using Microsoft.VisualStudio.Shell;
using System.Runtime.InteropServices;
using OutlineRegionTest.Properties;

namespace RefactAI{

Expand Down Expand Up @@ -63,9 +64,22 @@ public class General : BaseOptionModel<General>{
[DefaultValue(false)]
public bool TelemetryCodeSnippets{ get; set; } = false;

//enters a message into the log when the options are saved
[Category("Refact Assistant")]
[DisplayName("Insecure SSL")]
[Description("An informative description.")]
[DefaultValue(false)]
public bool InsecureSSL { get; set; } = false;

// Event handler to be invoked when settings are saved
private void OnSettingsSaved(General options)
{
OnSettingsChanged?.Invoke(this, EventArgs.Empty);
}

// Event to notify when settings are changed
public static event EventHandler OnSettingsChanged;
public General() : base(){
Saved += delegate { VS.StatusBar.ShowMessageAsync("Options Saved").FireAndForget(); };
Saved += OnSettingsSaved;
}
}
}
16 changes: 10 additions & 6 deletions MultilineGreyText/Options/GeneralOptionPage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,20 @@
using System.Runtime.InteropServices;
using System.Windows;

namespace RefactAI{
namespace RefactAI
{

[ComVisible(true)]
[Guid("D8B47497-8AC9-4E2E-9D62-D8E8E7A47AA4")]

public class GeneralOptionPage : UIElementDialogPage{
protected override UIElement Child{
get{
GeneralOptions page = new GeneralOptions{
public class GeneralOptionPage : UIElementDialogPage
{
protected override UIElement Child
{
get
{
GeneralOptions page = new GeneralOptions
{
generalOptionsPage = this
};
page.Initialize();
Expand All @@ -20,4 +25,3 @@ protected override UIElement Child{
}
}
}

5 changes: 5 additions & 0 deletions MultilineGreyText/Options/GeneralOptions.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@
<CheckBox x:Name="pTelemetryCodeSnippets" Content="Send corrected code snippets."
IsThreeState="False"
Checked="pTelemetryCodeSnippets_Checked" Unchecked="pTelemetryCodeSnippets_Unchecked"/>

<TextBlock Margin="0 15 0 10">Refactai: <Bold>Insecure SSL</Bold></TextBlock>
<CheckBox x:Name="pInsecureSSL" Content="Allow insecure server connections when using SSL, ignore certificaiton verification issues."
IsThreeState="False"
Checked="pInsecureSSL_Checked" Unchecked="pInsecureSSL_Unchecked"/>
</StackPanel>

</Grid>
Expand Down
57 changes: 42 additions & 15 deletions MultilineGreyText/Options/GeneralOptions.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
using System.Windows.Controls;

namespace RefactAI{
namespace RefactAI
{

/// <summary>
/// Interaction logic for GeneralOptions.xaml
/// </summary>
public partial class GeneralOptions : UserControl {
public partial class GeneralOptions : UserControl
{

internal GeneralOptionPage generalOptionsPage;

public GeneralOptions() {
public GeneralOptions()
{
InitializeComponent();
}

//Sets up all of the variables to display the current settings
public void Initialize(){
public void Initialize()
{
pPauseCompletion.IsChecked = General.Instance.PauseCompletion;
pTelemetryCodeSnippets.IsChecked = General.Instance.TelemetryCodeSnippets;

Expand All @@ -28,57 +32,80 @@ public void Initialize(){
}

//pause completion checkbox checked
private void pPauseCompletion_Checked(object sender, System.Windows.RoutedEventArgs e){
private void pPauseCompletion_Checked(object sender, System.Windows.RoutedEventArgs e)
{
General.Instance.PauseCompletion = (bool)pPauseCompletion.IsChecked;
General.Instance.Save();
}

//pause completion checkbox unchecked
private void pPauseCompletion_Unchecked(object sender, System.Windows.RoutedEventArgs e){
private void pPauseCompletion_Unchecked(object sender, System.Windows.RoutedEventArgs e)
{
General.Instance.PauseCompletion = (bool)pPauseCompletion.IsChecked;
General.Instance.Save();
}

//code snippets checked
private void pTelemetryCodeSnippets_Checked(object sender, System.Windows.RoutedEventArgs e){
private void pTelemetryCodeSnippets_Checked(object sender, System.Windows.RoutedEventArgs e)
{
General.Instance.TelemetryCodeSnippets = (bool)pTelemetryCodeSnippets.IsChecked;
General.Instance.Save();
}

//code snippets unchecked
private void pTelemetryCodeSnippets_Unchecked(object sender, System.Windows.RoutedEventArgs e){
private void pTelemetryCodeSnippets_Unchecked(object sender, System.Windows.RoutedEventArgs e)
{
General.Instance.TelemetryCodeSnippets = (bool)pTelemetryCodeSnippets.IsChecked;
General.Instance.Save();
}

//insecureSSL snippets checked
private void pInsecureSSL_Checked(object sender, System.Windows.RoutedEventArgs e)
{
General.Instance.InsecureSSL = (bool)pInsecureSSL.IsChecked;
General.Instance.Save();
}

//insecureSSL unchecked
private void pInsecureSSL_Unchecked(object sender, System.Windows.RoutedEventArgs e)
{
General.Instance.InsecureSSL = (bool)pInsecureSSL.IsChecked;
General.Instance.Save();
}

//address url text handler
private void AddressURL_textChanged(object sender, TextChangedEventArgs args){
private void AddressURL_textChanged(object sender, TextChangedEventArgs args)
{
General.Instance.AddressURL = AddressURL.Text;
General.Instance.Save();
}

//api key text handler
private void APIKey_textChanged(object sender, TextChangedEventArgs args){
private void APIKey_textChanged(object sender, TextChangedEventArgs args)
{
General.Instance.APIKey = APIKey.Text;
General.Instance.Save();
}

//code completion model text handler
private void CodeCompletionModel_textChanged(object sender, TextChangedEventArgs args){
private void CodeCompletionModel_textChanged(object sender, TextChangedEventArgs args)
{
General.Instance.CodeCompletionModel = CodeCompletionModel.Text;
General.Instance.Save();
}

//code completion other text handler
private void CodeCompletionModelOther_textChanged(object sender, TextChangedEventArgs args){
private void CodeCompletionModelOther_textChanged(object sender, TextChangedEventArgs args)
{
General.Instance.CodeCompletionModelOther = CodeCompletionModelOther.Text;
General.Instance.Save();
}

//code completion scratchpad text handler
private void CodeCompletionScratchpad_textChanged(object sender, TextChangedEventArgs args){
private void CodeCompletionScratchpad_textChanged(object sender, TextChangedEventArgs args)
{
General.Instance.CodeCompletionScratchpad = CodeCompletionScratchpad.Text;
General.Instance.Save();
}
}
}
}
}
78 changes: 56 additions & 22 deletions MultilineGreyText/RefactCompletionCommandHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using System.Threading.Tasks;
using Microsoft.VisualStudio.LanguageServer.Protocol;
using System.Text.RegularExpressions;
using System.Diagnostics;

namespace RefactAI{

Expand Down Expand Up @@ -48,23 +49,33 @@ public LanguageClientMetadata(string[] contentTypes, string clientName = null){
private Task<string> completionTask = null;

//The command Handler processes keyboard input.
internal RefactCompletionCommandHandler(IVsTextView textViewAdapter, ITextView textView, RefactCompletionHandlerProvider provider){
internal RefactCompletionCommandHandler(IVsTextView textViewAdapter, ITextView textView, RefactCompletionHandlerProvider provider)
{
this.m_textView = textView;
this.m_provider = provider;
this.textViewAdapter = textViewAdapter;

var topBuffer = textView.BufferGraph.TopBuffer;
var projectionBuffer = topBuffer as IProjectionBufferBase;
var typeName = topBuffer.GetType();
ITextBuffer textBuffer = projectionBuffer != null ? projectionBuffer.SourceBuffers[0] : topBuffer;
provider.documentFactory.TryGetTextDocument(textBuffer, out doc);
this.fileURI = new Uri(doc.FilePath);
this.filePath = this.fileURI.ToString();


if (doc != null && !string.IsNullOrEmpty(doc.FilePath))
{
this.fileURI = new Uri(doc.FilePath ?? throw new InvalidOperationException("Document file path is null."));
this.filePath = this.fileURI.ToString();
}
else
{
Debug.WriteLine("doc.FilePath is null or empty.");
this.filePath = string.Empty;
}

LoadLsp(this.filePath, doc);

//add the command to the command chain
textViewAdapter.AddCommandFilter(this, out m_nextCommandHandler);
// Add the command to the command chain
textViewAdapter.AddCommandFilter(this, out m_nextCommandHandler);
}

//Starts the refactlsp manually
Expand All @@ -81,6 +92,12 @@ void LoadLsp(String file, ITextDocument doc){

//Adds file to LSP
async Task ConnectFileToLSP(){
if (fileURI == null)
{
// Handle the case where fileURI is not initialized
return;
}

if (!client.ContainsFile(filePath)){
await client.AddFile(filePath, doc.TextBuffer.CurrentSnapshot.GetText());
}else{
Expand Down Expand Up @@ -120,8 +137,9 @@ public bool IsInline(int lineN){
}

//gets recommendations from LSP
public async void GetLSPCompletions(){
if (!General.Instance.PauseCompletion){
public async void GetLSPCompletions()
{
if (!General.Instance.PauseCompletion){
SnapshotPoint? caretPoint = m_textView.Caret.Position.Point.GetPoint(textBuffer => (!textBuffer.ContentType.IsOfType("projection")), PositionAffinity.Predecessor);

if (caretPoint.HasValue){
Expand All @@ -146,12 +164,12 @@ public async void GetLSPCompletions(){

hasCompletionUpdated = false;
bool multiline = !IsInline(lineN);
if(completionTask == null || completionTask.IsCompleted){
completionTask = client.RefactCompletion(m_textView.TextBuffer.Properties, filePath, lineN, multiline ? 0 : characterN, multiline);
var s = await completionTask;
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
if (completionTask == null || completionTask.IsCompleted){
ShowRefactSuggestion(s, lineN, characterN);
if(completionTask == null || completionTask.IsCompleted){
completionTask = client.RefactCompletion(m_textView.TextBuffer.Properties, filePath, lineN, multiline ? 0 : characterN, multiline);
var s = await completionTask;
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
if (completionTask == null || completionTask.IsCompleted){
ShowRefactSuggestion(s, lineN, characterN);
}
}
}
Expand All @@ -160,12 +178,14 @@ public async void GetLSPCompletions(){
}

//sends lsp reccomendations to grey text tagger to be dispalyed
public void ShowRefactSuggestion(String s, int lineN, int characterN){

if (!string.IsNullOrEmpty(s)){
public void ShowRefactSuggestion(String s, int lineN, int characterN)
{
if (!string.IsNullOrEmpty(s))
{
//the caret must be in a non-projection location
SnapshotPoint? caretPoint = m_textView.Caret.Position.Point.GetPoint(textBuffer => (!textBuffer.ContentType.IsOfType("projection")), PositionAffinity.Predecessor);
if (!caretPoint.HasValue){
if (!caretPoint.HasValue)
{
return;
}

Expand All @@ -174,17 +194,28 @@ public void ShowRefactSuggestion(String s, int lineN, int characterN){
int resCaretPos = textViewAdapter.GetCaretPos(out newLineN, out newCharacterN);

//double checks the cursor is still on the line the recommendation is for
if(resCaretPos != VSConstants.S_OK || (lineN != newLineN) || (characterN != newCharacterN)){
if (resCaretPos != VSConstants.S_OK || (lineN != newLineN) || (characterN != newCharacterN))
{
return;
}

var tagger = GetTagger();
if(tagger != null && s != null){
if (tagger != null && s != null)
{
tagger.SetSuggestion(s, IsInline(lineN), characterN);

// Ensure cursor is positioned correctly for multiline completions
if (s.Contains("\n"))
{
m_textView.Caret.MoveTo(new SnapshotPoint(m_textView.TextSnapshot, m_textView.TextSnapshot.Length));
m_textView.Caret.EnsureVisible();
}
}
}
}



//Used to detect when the user interacts with the intellisense popup
void CheckSuggestionUpdate(uint nCmdID){
switch (nCmdID){
Expand All @@ -206,7 +237,7 @@ void CheckSuggestionUpdate(uint nCmdID){

//Key input handler
public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut){
//let the other handlers handle automation functions
//let the other handlers handle automation
if (VsShellUtilities.IsInAutomationFunction(m_provider.ServiceProvider)){
return m_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
}
Expand All @@ -222,6 +253,9 @@ public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pv
return VSConstants.S_OK;
}else{
tagger.ClearSuggestion();

// start the suggestions process again to see if suggestion left in between due to token limit
_ = Task.Run(() => GetLSPCompletions());
}
}

Expand Down
Loading
Loading