Skip to content

Commit 57f7e5c

Browse files
authored
Merge pull request #33 from n-WN/copilot/fix-32
Add missing SageMath functions to autocompletion including LLL lattice algorithm
2 parents a9ebc44 + 6ebee50 commit 57f7e5c

File tree

7 files changed

+359
-3
lines changed

7 files changed

+359
-3
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"publisher": "Lov3",
44
"displayName": "SageMath Enhanced",
55
"description": "An enhanced VS Code extension for SageMath, providing advanced features and integrations.",
6-
"version": "2.0.2",
6+
"version": "2.0.3",
77
"engines": {
88
"vscode": "^1.76.0"
99
},

server/src/server.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ const SAGEMATH_BUILTINS = [
3434
// Rings and Fields
3535
'ZZ', 'QQ', 'RR', 'CC', 'GF', 'Zmod', 'PolynomialRing', 'NumberField',
3636
'LaurentPolynomialRing', 'PowerSeriesRing', 'FractionField', 'QuotientRing',
37+
'FiniteField', 'CyclotomicField', 'QuaternionAlgebra', 'MatrixAlgebra',
3738
// Basic functions
3839
'var', 'vars', 'SR', 'solve', 'factor', 'expand', 'simplify', 'diff', 'integrate',
3940
// Polynomial operations
@@ -47,6 +48,10 @@ const SAGEMATH_BUILTINS = [
4748
// Number theory
4849
'gcd', 'lcm', 'is_prime', 'next_prime', 'prime_range', 'factorial',
4950
'euler_phi', 'divisors', 'prime_divisors', 'factor_trial_division',
51+
'legendre_symbol', 'jacobi_symbol', 'kronecker_symbol', 'quadratic_residues',
52+
'continued_fraction', 'convergents', 'nth_prime', 'prime_pi', 'discrete_log',
53+
// Lattice algorithms
54+
'LLL', 'BKZ', 'hermite_form', 'smith_form',
5055
// Combinatorics
5156
'Permutations', 'Combinations', 'Partitions', 'binomial',
5257
'catalan_number', 'fibonacci', 'lucas_number', 'stirling_number1', 'stirling_number2',
@@ -56,7 +61,8 @@ const SAGEMATH_BUILTINS = [
5661
'Point', 'Line', 'Circle', 'Polygon', 'Polyhedron',
5762
// Calculus
5863
'limit', 'taylor', 'series', 'laplace', 'inverse_laplace',
59-
'derivative', 'integral', 'sum', 'product',
64+
'derivative', 'integral', 'sum', 'product', 'fourier_transform',
65+
'laplace_transform', 'symbolic_sum', 'symbolic_product',
6066
// Cryptography
6167
'RSA', 'ElGamal', 'DiffieHellman', 'AES', 'DES',
6268
// Elliptic curves
@@ -266,7 +272,9 @@ function getWordAtPosition(document: TextDocument, position: { line: number; cha
266272

267273
// Helper function to check if a string matches a partial input (fuzzy matching)
268274
function isPartialMatch(input: string, target: string): boolean {
269-
if (!input) return true; // Empty input matches everything
275+
if (!input) {
276+
return true; // Empty input matches everything
277+
}
270278

271279
const inputLower = input.toLowerCase();
272280
const targetLower = target.toLowerCase();

tests/demo_lll_fix.js

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#!/usr/bin/env node
2+
3+
const { LSPClient } = require('./test_lsp_completion.js');
4+
5+
/**
6+
* Simple demonstration that LLL completion works
7+
*/
8+
async function demonstrateLLLFix() {
9+
const client = new LSPClient();
10+
11+
try {
12+
console.log('🧪 Demonstrating LLL Completion Fix');
13+
console.log('==================================\n');
14+
15+
// Start server and initialize
16+
console.log('🚀 Starting language server...');
17+
await client.startServer();
18+
await client.initialize();
19+
console.log('✅ LSP connection initialized\n');
20+
21+
// Test document with LLL
22+
const testContent = `# Test LLL completion
23+
LLL
24+
`;
25+
26+
const testUri = 'file:///demo.sage';
27+
await client.openDocument(testUri, testContent);
28+
29+
// Wait for processing
30+
await new Promise(resolve => setTimeout(resolve, 500));
31+
32+
console.log('📝 Testing "LLL" completion...');
33+
34+
const completions = await client.getCompletion(testUri, 1, 3);
35+
36+
const lllItem = completions.find(item => item.label === 'LLL');
37+
38+
if (lllItem) {
39+
console.log('✅ SUCCESS: LLL function found in completion results!');
40+
console.log(` Label: ${lllItem.label}`);
41+
console.log(` Detail: ${lllItem.detail}`);
42+
console.log(` Sort text: ${lllItem.sortText}`);
43+
console.log('\n🎉 The LLL completion issue has been fixed!');
44+
} else {
45+
console.log('❌ FAILED: LLL function not found in completion results');
46+
console.log('Available completions:');
47+
completions.forEach((item, index) => {
48+
console.log(` ${index + 1}. ${item.label}`);
49+
});
50+
}
51+
52+
} catch (error) {
53+
console.error('💥 Error:', error);
54+
} finally {
55+
await client.shutdown();
56+
}
57+
}
58+
59+
// Run the demonstration
60+
if (require.main === module) {
61+
demonstrateLLLFix();
62+
}

tests/manual_completion_test.sage

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Manual test file to verify LLL completion
2+
# Open this file in VS Code with the SageMath Enhanced extension
3+
# Type these incomplete function names and press Ctrl+Space for completion
4+
5+
# Test 1: Type "LLL" and it should autocomplete the LLL function
6+
# LLL
7+
8+
# Test 2: Type "BKZ" and it should autocomplete the BKZ function
9+
# BKZ
10+
11+
# Test 3: Type "legendre_" and it should show legendre_symbol
12+
# legendre_
13+
14+
# Test 4: Type "hermite_" and it should show hermite_form
15+
# hermite_
16+
17+
# Test 5: Type "FiniteF" and it should show FiniteField
18+
# FiniteF
19+
20+
# Test 6: Type "QuaternionA" and it should show QuaternionAlgebra
21+
# QuaternionA
22+
23+
# All of these should now work with the completion system!

tests/test_lll_completion.js

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
#!/usr/bin/env node
2+
3+
const { LSPClient } = require('./test_lsp_completion.js');
4+
5+
/**
6+
* Test LLL completion functionality
7+
*/
8+
async function testLLLCompletion() {
9+
const client = new LSPClient();
10+
11+
try {
12+
// Start server and initialize
13+
await client.startServer();
14+
await client.initialize();
15+
16+
// Test document content with LLL completion scenarios
17+
const testContent = `# SageMath LLL completion test
18+
# Test case 1: Simple completion
19+
LLL
20+
# Test case 2: Assignment
21+
alg = LLL
22+
# Test case 3: Lowercase partial
23+
lll
24+
# Test case 4: In function call
25+
my_function(LLL
26+
# Test case 5: Just 'L'
27+
L
28+
`;
29+
30+
const testUri = 'file:///tests/test_lll_completion.sage';
31+
await client.openDocument(testUri, testContent);
32+
33+
// Wait a bit for document processing
34+
await new Promise(resolve => setTimeout(resolve, 500));
35+
36+
console.log('\n🧪 Testing LLL completion scenarios...\n');
37+
38+
// Test cases with expected positions
39+
const testCases = [
40+
{ name: 'LLL', line: 2, character: 3, input: 'LLL' },
41+
{ name: 'LLL', line: 4, character: 9, input: 'LLL' },
42+
{ name: 'lll', line: 6, character: 3, input: 'lll' },
43+
{ name: 'LLL', line: 8, character: 16, input: 'LLL' },
44+
{ name: 'L', line: 10, character: 1, input: 'L' }
45+
];
46+
47+
let allTestsPassed = true;
48+
49+
for (const testCase of testCases) {
50+
console.log(`📝 Testing "${testCase.input}" completion...`);
51+
52+
try {
53+
const completions = await client.getCompletion(testUri, testCase.line, testCase.character);
54+
55+
console.log(` Found ${completions.length} completion items`);
56+
57+
// Check if LLL is in the results
58+
const lllItem = completions.find(item =>
59+
item.label === 'LLL' ||
60+
item.insertText === 'LLL'
61+
);
62+
63+
if (lllItem) {
64+
console.log(` ✅ LLL found at position ${completions.indexOf(lllItem) + 1}`);
65+
console.log(` Sort text: "${lllItem.sortText}"`);
66+
console.log(` Detail: "${lllItem.detail}"`);
67+
68+
// Check if it's in top 10 (indicating good prioritization)
69+
const position = completions.indexOf(lllItem) + 1;
70+
if (position <= 10) {
71+
console.log(` 🌟 Great! LLL is in top 10 (position ${position})`);
72+
} else {
73+
console.log(` ⚠️ LLL found but not in top 10 (position ${position})`);
74+
}
75+
} else {
76+
console.log(` ❌ LLL not found in completion results`);
77+
allTestsPassed = false;
78+
}
79+
80+
// Show top 5 for debugging
81+
console.log(` Top 5 completions:`);
82+
completions.slice(0, 5).forEach((item, index) => {
83+
console.log(` ${index + 1}. ${item.label} (${item.sortText})`);
84+
});
85+
86+
} catch (error) {
87+
console.error(` 💥 Error testing "${testCase.input}":`, error.message);
88+
allTestsPassed = false;
89+
}
90+
91+
console.log('');
92+
}
93+
94+
console.log('📊 Test Summary:');
95+
if (allTestsPassed) {
96+
console.log('🎉 All tests passed! LLL completion is working correctly.');
97+
} else {
98+
console.log('❌ Some tests failed! LLL completion needs to be fixed.');
99+
process.exit(1);
100+
}
101+
102+
} catch (error) {
103+
console.error('💥 Fatal error:', error);
104+
process.exit(1);
105+
} finally {
106+
await client.shutdown();
107+
}
108+
}
109+
110+
/**
111+
* Main execution
112+
*/
113+
async function main() {
114+
console.log('🧪 SageMath Enhanced - LLL Completion Test');
115+
console.log('==========================================\n');
116+
117+
console.log('This script tests the Language Server Protocol completion functionality for LLL.');
118+
console.log('It verifies that typing "LLL", "lll", "L", etc. returns "LLL" in completion results.\n');
119+
120+
try {
121+
await testLLLCompletion();
122+
} catch (error) {
123+
console.error('💥 Fatal error:', error);
124+
process.exit(1);
125+
}
126+
}
127+
128+
// Run the test
129+
if (require.main === module) {
130+
main();
131+
}
132+
133+
module.exports = { testLLLCompletion };

tests/test_lll_completion.sage

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Test LLL function completion
2+
# The issue reported is that LLL() function does not autocomplete
3+
4+
# Test case 1: Simple LLL completion
5+
LLL
6+
7+
# Test case 2: Assignment context
8+
alg = LLL
9+
10+
# Test case 3: Lowercase partial
11+
lll
12+
13+
# Test case 4: In function call
14+
my_function(LLL
15+
16+
# Test case 5: Just 'L'
17+
L

0 commit comments

Comments
 (0)