michaelb / sniprun

A neovim plugin to run lines/blocs of code (independently of the rest of the file), supporting multiples languages
MIT License
1.43k stars 46 forks source link

add feature can auto add nested local package's function in go . #248

Open soluty opened 12 months ago

soluty commented 12 months ago

Is your feature request related to a problem? Please describe.

249

Describe the solution you'd like if i select a function to run , if the function called other packeages functions, it works fine, but if the function called current packages function, it cannot work because the genarate code only add my real select function, it will be big help to parse package and add it to generated code.

Additional context i dont know whether if other lang can do this, but because of golang only support package level function ,so do this may be not very hard.

michaelb commented 12 months ago

"Parsing" the package to get the needed (and only the needed symbols) is actually very hard

Let's suppose your are indeed writing package Foo. You've already finished foo, now you're trying to write bar

func bar () {
    test := 8                     // snippet to
    bar := foo()+2 *test // send to
    fmt.Println(bar)        // sniprun

    ...TODO 
}

//Another function not working yet
func test(){
Todo

Sniprun would have to understand that for evaluating the snippet, it needs to fetch foo() , but NOT test() ... or even bar()!!

The general problem is too hard for me to implement, so I would need to plug into an LSP and that's already hard

soluty commented 12 months ago

thank you , but for golang it is not very hard to do that because of gopls. suppose this is the content of main.go.

package main

import "fmt"

func bar() {
    test := 8             // snippet to
    bar := foo() + 2*test // send to
    fmt.Println(bar)      // sniprun
}

func foo() int {
    return 1
}

// Another function not working yet
func test() int {
    return 0
}

suppose i want to run function bar. run gopls symbols main.go i go

bar Function 5:6-5:9
foo Function 11:6-11:9
test Function 16:6-16:10

now i know bar function is in 5:6 then run gopls call_hierarchy main.go:5:6, i got

identifier: function bar in /root/vm/exports/lib/test/main.go:5:6-9
callee[0]: ranges 7:9-12 in /root/vm/exports/lib/test/main.go from/to function foo in /root/vm/exports/lib/test/main.go:11:6-9
callee[1]: ranges 8:6-13 in /root/vm/exports/lib/test/main.go from/to function Println in /root/.g/go/src/fmt/print.go:313:6-13

now i got the same package's function foo in /root/vm/exports/lib/test/main.go:11:6-9 and now i can fetch the content from main.go. and paste it to sniprun's generated main.go. i can run this rg --line-number ^} main.go | awk -F ":" '$1 > 11 {print $1; exit}' now i got 13 as the end of function foo. then run sed -n "11,13p" main.go i can get the content foo

func foo() int {
        return 1
}

add it to the last of generated main.go and thats ok.

it is not very hard but trivial and boreing. i am not a ruster, and its hard to implement these logic in rust for me. maybe i can do it in lua for my personal use. but i hope it can add to go_orignal.rs logic.

At last, thanks for your great work , it is more powerful than vscode's same plugin.

soluty commented 12 months ago

because of golang's package is flat, it can only support logic write in same dir, if two function is not in same file, simple loop dir so it can support all nest function call except init() function and global var. And if two function not in same file has other problem is how to add and organize import, and in this situation, i dont have a good idea. also for dot import like

import . "foo"