Skip to content

Commit 77426a9

Browse files
committed
vscode extension
1 parent 7c2f8d4 commit 77426a9

File tree

2 files changed

+72
-27
lines changed

2 files changed

+72
-27
lines changed

python_autocomplete/serve.py

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
import json
2-
import string
32
import threading
43

4+
import torch
55
from flask import Flask, request, jsonify
66

77
from labml import monit
8+
from python_autocomplete.evaluate import NextWordPredictionComplete
89
from python_autocomplete.evaluate.factory import get_predictor
910

10-
TOKEN_CHARS = set(string.ascii_letters + string.digits + ' ' + '\n' + '\r' + '_')
11-
1211
app = Flask('python_autocomplete')
1312
predictor = get_predictor()
1413
lock = threading.Lock()
@@ -21,17 +20,25 @@ def home():
2120

2221
@app.route('/autocomplete', methods=['POST'])
2322
def autocomplete():
24-
prompt = request.json['prompt']
25-
if not prompt:
23+
prefix = request.json['prompt']
24+
if not prefix:
2625
return jsonify({'success': False})
2726

2827
with monit.section('Predict') as s:
2928
acquired = lock.acquire(blocking=False)
3029
if acquired:
31-
res, state = predictor.get_next_word(prompt, TOKEN_CHARS, None)
30+
stripped, prompt = predictor.rstrip(prefix)
31+
rest = prefix[len(stripped):]
32+
prediction_complete = NextWordPredictionComplete(rest, 5)
33+
prompt = torch.tensor(prompt, dtype=torch.long).unsqueeze(-1)
34+
35+
predictions = predictor.get_next_word(prompt, None, rest, [1.], prediction_complete, 5)
36+
predictions.sort(key=lambda x: -x[0])
37+
38+
results = [pred.text[len(rest):] for pred in predictions]
3239
lock.release()
33-
s.message = f'{json.dumps(prompt[-5:])} -> {json.dumps(res)}'
34-
return jsonify({'success': True, 'prediction': res})
40+
s.message = f'{json.dumps(prefix[-5:])} -> {json.dumps(results)}'
41+
return jsonify({'success': True, 'prediction': results})
3542
else:
3643
monit.fail()
3744
return jsonify({'success': False})

vscode_extension/src/extension.ts

Lines changed: 57 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,56 @@ function getPrompt(document: vscode.TextDocument, position: vscode.Position) {
4242
return text
4343
}
4444

45+
function cleanupPredictions(predictions: string[]): string[] {
46+
let res = []
47+
for(let p of predictions) {
48+
let nl = p.indexOf('\n')
49+
if (nl !== -1) {
50+
p = p.substr(0, nl)
51+
}
52+
if(p !== '') {
53+
res.push(p)
54+
}
55+
}
56+
57+
return res
58+
}
59+
60+
function addPrefix(prefix: string, predictions: string[]): string[] {
61+
let res = []
62+
for(let p of predictions) {
63+
res.push(prefix + p)
64+
}
65+
66+
return res
67+
}
68+
69+
function hasNewLine(predictions: string[]): boolean[] {
70+
let res = []
71+
for(let p of predictions) {
72+
res.push(p.indexOf('\n') !== -1)
73+
}
74+
75+
return res
76+
}
77+
78+
function getCompletions(predictions: string[], nl: boolean[]): vscode.CompletionItem[] {
79+
let res = []
80+
for(let i = 0; i < predictions.length; ++i) {
81+
// Create a completion
82+
const simpleCompletion = new vscode.CompletionItem(predictions[i])
83+
simpleCompletion.kind = vscode.CompletionItemKind.Text
84+
// Dont trigger autocompletion if we hit a new line
85+
if (!nl[i]) {
86+
simpleCompletion.command = { command: 'editor.action.triggerSuggest', title: 'Re-trigger completions...' }
87+
}
88+
89+
res.push(simpleCompletion)
90+
}
91+
92+
return res
93+
}
94+
4595
export function activate(context: vscode.ExtensionContext) {
4696
const provider = vscode.languages.registerCompletionItemProvider('python', {
4797
async provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, context: vscode.CompletionContext) {
@@ -59,17 +109,13 @@ export function activate(context: vscode.ExtensionContext) {
59109
return []
60110
}
61111

62-
let prediction: string = response.prediction
112+
let predictions: string[] = response.prediction
113+
const nl = hasNewLine(predictions)
114+
predictions = cleanupPredictions(predictions)
63115

64-
// Remove new lines because it's a bit annoying?
65-
let nl = prediction.indexOf('\n')
66-
if (nl !== -1) {
67-
prediction = prediction.substr(0, nl)
68-
}
69-
70-
if (prediction === '') {
116+
if (predictions.length === 0) {
71117
// If at end of a line just predict new line, to avoid annoying default vscode predictions
72-
if (nl !== -1) {
118+
if (nl.length > 0 && nl[0]) {
73119
const simpleCompletion = new vscode.CompletionItem('\n')
74120
simpleCompletion.kind = vscode.CompletionItemKind.Text
75121
simpleCompletion.command = { command: 'editor.action.triggerSuggest', title: 'Re-trigger completions...' }
@@ -83,18 +129,10 @@ export function activate(context: vscode.ExtensionContext) {
83129
if (range != null) {
84130
const line = document.lineAt(position).text
85131
let prefix = line.substring(range.start.character, position.character)
86-
prediction = prefix + prediction
87-
}
88-
89-
// Create a completion
90-
const simpleCompletion = new vscode.CompletionItem(prediction)
91-
simpleCompletion.kind = vscode.CompletionItemKind.Text
92-
// Dont trigger autocompletion if we hit a new line
93-
if (nl === -1) {
94-
simpleCompletion.command = { command: 'editor.action.triggerSuggest', title: 'Re-trigger completions...' }
132+
predictions = addPrefix(prefix, predictions)
95133
}
96134

97-
return [simpleCompletion]
135+
return getCompletions(predictions, nl)
98136
}
99137
})
100138

0 commit comments

Comments
 (0)