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

Use $acmeaddr to address the target text #43

Open
wants to merge 1 commit into
base: master
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
48 changes: 42 additions & 6 deletions cmd/L/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ import (
"os"
"path/filepath"
"strconv"
"strings"

p9client "github.com/fhs/9fans-go/plan9/client"
"github.com/fhs/acme-lsp/internal/acme"
"github.com/fhs/acme-lsp/internal/golang_org_x_tools/jsonrpc2"
"github.com/fhs/acme-lsp/internal/lsp"
"github.com/fhs/acme-lsp/internal/lsp/acmelsp"
Expand Down Expand Up @@ -185,12 +187,12 @@ func run(cfg *config.Config, args []string) error {
return fmt.Errorf("unknown assist command %q", args[0])
}

winid, err := getWinID()
winid, offset, err := getWinID()
if err != nil {
return err
}

rc := acmelsp.NewRemoteCmd(server, winid)
rc := acmelsp.NewRemoteCmd(server, winid, offset)

// In case the window has unsaved changes (it's dirty), sync changes with LSP server.
err = rc.DidChange(ctx)
Expand Down Expand Up @@ -230,16 +232,50 @@ func run(cfg *config.Config, args []string) error {
return fmt.Errorf("unknown command %q", args[0])
}

func getWinID() (int, error) {
func parseAddress(addr string) (file string, offset int, err error) {
split := strings.Split(addr, ":")
file = split[0]
if len(split) > 1 {
split = strings.Split(split[1], ",")
offsetstring := split[len(split)-1]
offsettrim := strings.TrimPrefix(offsetstring, "#")
offset, err = strconv.Atoi(offsettrim)
}
return file, offset, err
}

func getWinID() (id int, offset int, err error) {
winid, err := getFocusedWinID(filepath.Join(p9client.Namespace(), "acmefocused"))
if err != nil {
return 0, fmt.Errorf("could not get focused window ID: %v", err)
return 0, -1, fmt.Errorf("could not get focused window ID: %v", err)
}
n, err := strconv.Atoi(winid)
if err != nil {
return 0, fmt.Errorf("failed to parse $winid: %v", err)
return 0, -1, fmt.Errorf("failed to parse $winid: %v", err)
}
// Now check for a chord command
acmeaddr := os.Getenv("acmeaddr")
if acmeaddr != "" {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this condition is true only when you have a wrapper script around L that sets winid to empty. I don't see how $acmeaddr would be non-empty and $winid empty otherwise.

We should be checking $acmeaddr before $windid. If $acmeaddr is non-empty, it's a 2-1 cord. Plan 9 acme gets this correct. Plan9port acme has a bug where it sets $acmeaddr but never unsets it (forgetting we don't have rfork(RFENVG) in unix).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created plan9port issue: 9fans/plan9port#533

Copy link
Author

@paul-lalonde paul-lalonde Nov 1, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Edwood has the same bug, and I now have a patch to fix edwood.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Edwood is now patched.

if err != nil {
return 0, -1, fmt.Errorf("failed to to parse chord %v: %v", n, err)
}
file, offset, err := parseAddress(string(acmeaddr))
if err != nil {
return n, -1, nil
}
// Find the file in the index
windows, err := acme.Windows()
if err != nil {
return n, -1, nil
}
for _, w := range windows {
if w.Name == file {
return w.ID, offset, nil
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why we need the offset. Once we have the window id, this program will take care of getting the current selection position in that window.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Xerox. You don't know the window id, just the file name.

}
}
fmt.Println(file, offset)
}
return n, nil
return n, -1, nil
}

func dirsOrCurrentDir(dirs []string) ([]protocol.WorkspaceFolder, error) {
Expand Down
2 changes: 1 addition & 1 deletion internal/lsp/acmelsp/acmelsp.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func WindowRemoteCmd(ss *ServerSet, fm *FileManager, winid int) (*RemoteCmd, err
return nil, fmt.Errorf("DidChange failed: %v", err)
}

return NewRemoteCmd(srv.Client, winid), nil
return NewRemoteCmd(srv.Client, winid, -1), nil
}

func getLine(p string, l int) string {
Expand Down
2 changes: 1 addition & 1 deletion internal/lsp/acmelsp/assist.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ func (w *outputWin) Update(fw *focusWin, server proxy.Server, cmd string) {
}
}

rc := NewRemoteCmd(server, fw.id)
rc := NewRemoteCmd(server, fw.id, -1)
rc.Stdout = w.body
rc.Stderr = w.body
ctx := context.Background()
Expand Down
8 changes: 6 additions & 2 deletions internal/lsp/acmelsp/remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,16 @@ import (
type RemoteCmd struct {
server proxy.Server
winid int
offset int
Stdout io.Writer
Stderr io.Writer
}

func NewRemoteCmd(server proxy.Server, winid int) *RemoteCmd {
func NewRemoteCmd(server proxy.Server, winid int, offset int) *RemoteCmd {
return &RemoteCmd{
server: server,
winid: winid,
offset: offset,
Stdout: os.Stdout,
Stderr: os.Stderr,
}
Expand All @@ -37,7 +39,9 @@ func (rc *RemoteCmd) getPosition() (pos *protocol.TextDocumentPositionParams, fi
return nil, "", fmt.Errorf("failed to to open window %v: %v", rc.winid, err)
}
defer w.CloseFiles()

if rc.offset != -1 {
return text.PositionQ0(w, rc.offset)
}
return text.Position(w)
}

Expand Down
20 changes: 12 additions & 8 deletions internal/lsp/text/edit.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func Edit(f File, edits []protocol.TextEdit) error {
if err != nil {
return err
}
off, err := getNewlineOffsets(reader)
off, err := GetNewlineOffsets(reader)
if err != nil {
return fmt.Errorf("failed to obtain newline offsets: %v", err)
}
Expand Down Expand Up @@ -72,21 +72,16 @@ func DocumentURI(f AddressableFile) (uri protocol.DocumentURI, filename string,
return ToURI(name), name, nil
}

// Position returns the current position within a file being edited.
func Position(f AddressableFile) (pos *protocol.TextDocumentPositionParams, filename string, err error) {
func PositionQ0(f AddressableFile, q0 int) (pos *protocol.TextDocumentPositionParams, filename string, err error) {
name, err := f.Filename()
if err != nil {
return nil, "", fmt.Errorf("could not get window filename: %v", err)
}
q0, _, err := f.CurrentAddr()
if err != nil {
return nil, "", fmt.Errorf("could not get current address: %v", err)
}
reader, err := f.Reader()
if err != nil {
return nil, "", fmt.Errorf("could not get window body reader: %v", err)
}
off, err := getNewlineOffsets(reader)
off, err := GetNewlineOffsets(reader)
if err != nil {
return nil, "", fmt.Errorf("failed to get newline offset: %v", err)
}
Expand All @@ -102,6 +97,15 @@ func Position(f AddressableFile) (pos *protocol.TextDocumentPositionParams, file
}, name, nil
}

// Position returns the current position within a file being edited.
func Position(f AddressableFile) (pos *protocol.TextDocumentPositionParams, filename string, err error) {
q0, _, err := f.CurrentAddr()
if err != nil {
return nil, "", fmt.Errorf("could not get current address: %v", err)
}
return PositionQ0(f, q0)
}

// ToURI converts filename to URI.
func ToURI(filename string) protocol.DocumentURI {
return protocol.DocumentURI(span.NewURI(filename))
Expand Down
2 changes: 1 addition & 1 deletion internal/lsp/text/line.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ type nlOffsets struct {
leftover int // runes leftover after last '\n'
}

func getNewlineOffsets(r io.Reader) (*nlOffsets, error) {
func GetNewlineOffsets(r io.Reader) (*nlOffsets, error) {
br := bufio.NewReader(r)
o := 0
nl := []int{0}
Expand Down