From d51277e2fc22cbccc4ec659d07f2a0f78177a419 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Fri, 15 Aug 2025 19:00:51 +0300 Subject: [PATCH] vls: autocomplete for function signatures --- vlib/v/checker/autocomplete.v | 23 +++++++++++++++++++++++ vlib/v/checker/checker.v | 4 ++++ vlib/v/pref/line_info.v | 35 ++++++++++++++++++++++++++++------- vlib/v/pref/pref.v | 10 ---------- 4 files changed, 55 insertions(+), 17 deletions(-) diff --git a/vlib/v/checker/autocomplete.v b/vlib/v/checker/autocomplete.v index 60d8612be8..aa47a579ea 100644 --- a/vlib/v/checker/autocomplete.v +++ b/vlib/v/checker/autocomplete.v @@ -21,6 +21,17 @@ fn abs(a int) int { pub fn (mut c Checker) run_ac(ast_file &ast.File) { } +pub fn (mut c Checker) autocomplete_for_fn_call_expr() { + // println(c.pref.linfo.expr) + fn_name := c.pref.linfo.expr.replace('()', '').trim_space() + f := c.table.find_fn(fn_name) or { + println('failed to find fn "${fn_name}"') + return + } + res := c.build_fn_summary(f) + println(res) +} + fn (mut c Checker) ident_autocomplete(node ast.Ident) { // Mini LS hack (v -line-info "a.v:16") if c.pref.is_verbose { @@ -45,6 +56,7 @@ fn (mut c Checker) ident_autocomplete(node ast.Ident) { } // Module autocomplete // `os. ...` + // println(node) if node.name == '' && node.mod != 'builtin' { c.module_autocomplete(node) return @@ -165,3 +177,14 @@ fn build_method_summary(method ast.Fn) string { } return s + ')' } + +fn (c &Checker) build_fn_summary(method ast.Fn) string { + mut s := method.name + '(' + for i, param in method.params { + s += param.name + ' ' + c.table.type_to_str(param.typ) + if i < method.params.len - 1 { + s += ', ' + } + } + return s + ')' +} diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 98ab39bd80..08369f313f 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -433,6 +433,10 @@ pub fn (mut c Checker) check_files(ast_files []&ast.File) { // println('setting is_running=true, pref.path=${c.pref.linfo.path} curdir' + os.getwd()) c.pref.linfo.is_running = true // println('linfo path=${c.pref.linfo.path}') + if c.pref.linfo.expr.contains('()') { + c.autocomplete_for_fn_call_expr() + exit(0) + } for i, file in ast_files { // println(file.path) if file.path == c.pref.linfo.path { diff --git a/vlib/v/pref/line_info.v b/vlib/v/pref/line_info.v index 88d7b16b05..b7a00ae27a 100644 --- a/vlib/v/pref/line_info.v +++ b/vlib/v/pref/line_info.v @@ -2,6 +2,16 @@ // Use of this source code is governed by an MIT license that can be found in the LICENSE file. module pref +pub struct LineInfo { +pub mut: + line_nr int // a quick single file run when called with v -line-info (contains line nr to inspect) + path string // same, but stores the path being parsed + expr string // "os.foo()" V code (expression) which needs autocomplete, right only function calls + col int + is_running bool // so that line info is fetched only on the second checker run + vars_printed map[string]bool // to avoid dups +} + fn (mut p Preferences) parse_line_info(line string) { // println("parse_line_info '${line}'") format_err := 'wrong format, use `-line-info "file.v:24:7"' @@ -12,16 +22,27 @@ fn (mut p Preferences) parse_line_info(line string) { } file_name := vals[0] line_nr := vals[1].int() - 1 - col := vals[2].int() - 1 - // expr := vals[2] + if !file_name.ends_with('.v') || line_nr == -1 { eprintln(format_err) return } - p.linfo = LineInfo{ - line_nr: line_nr - path: file_name - // expr: expr - col: col + + // Third value can be a column or expression for autocomplete like `os.create()` + third := vals[2] + if third[0].is_digit() { + col := vals[2].int() - 1 + p.linfo = LineInfo{ + line_nr: line_nr + path: file_name + col: col + } + } else { + expr := vals[2] + p.linfo = LineInfo{ + line_nr: line_nr + path: file_name + expr: expr + } } } diff --git a/vlib/v/pref/pref.v b/vlib/v/pref/pref.v index 83320e4a4f..fcceb679ea 100644 --- a/vlib/v/pref/pref.v +++ b/vlib/v/pref/pref.v @@ -262,16 +262,6 @@ pub mut: json_errors bool // -json-errors, for VLS and other tools } -pub struct LineInfo { -pub mut: - line_nr int // a quick single file run when called with v -line-info (contains line nr to inspect) - path string // same, but stores the path being parsed - // expr string // "foo" or "foo.bar" V code (expression) which needs autocomplete - col int - is_running bool // so that line info is fetched only on the second checker run - vars_printed map[string]bool // to avoid dups -} - pub fn parse_args(known_external_commands []string, args []string) (&Preferences, string) { return parse_args_and_show_errors(known_external_commands, args, false) }