Skip to content

Support neovim/neovim@a225374 api #36

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

Merged
merged 33 commits into from
Apr 24, 2019
Merged

Support neovim/neovim@a225374 api #36

merged 33 commits into from
Apr 24, 2019

Conversation

zchee
Copy link
Member

@zchee zchee commented Aug 5, 2018

Support neovim/neovim@a225374 API.

compare is here:

> nvim_buf_attach(buffer Buffer, send_buffer Boolean, opts Dictionary) Boolean { name(nvim_buf_attach) }
> nvim_buf_detach(buffer Buffer) Boolean { name(nvim_buf_detach) }
> nvim_buf_get_commands(buffer Buffer, opts Dictionary) Dictionary { name(nvim_buf_get_commands) }
> nvim_buf_is_loaded(buffer Buffer) Boolean { name(nvim_buf_is_loaded) }
> nvim_call_dict_function(dict Object, fn String, args Array) Object { name(nvim_call_dict_function) }
> nvim_get_chan_info(chan Integer) Dictionary { name(nvim_get_chan_info) }
> nvim_get_commands(opts Dictionary) Dictionary { name(nvim_get_commands) }
> nvim_get_proc(pid Integer) Object { name(nvim_get_proc) }
> nvim_get_proc_children(pid Integer) Array { name(nvim_get_proc_children) }
> nvim_list_chans() Array { name(nvim_list_chans) }
> nvim_list_uis() Array { name(nvim_list_uis) }
> nvim_parse_expression(expr String, flags String, highlight Boolean) Dictionary { name(nvim_parse_expression) }
> nvim_set_client_info(name String, version Dictionary, type String, methods Dictionary, attributes Dictionary) void { name(nvim_set_client_info) }
----
< nvim_get_color_map() map[string]int { name(nvim_get_color_map) }
> nvim_get_color_map() Dictionary { name(nvim_get_color_map) }

@zchee
Copy link
Member Author

zchee commented Aug 5, 2018

/cc: @garyburd

@zchee
Copy link
Member Author

zchee commented Aug 5, 2018

CI is failed :( I'll check it and fix later.

@justinmk
BTW, Who is current neovim/go-client owner? still at garyburd?

@justinmk
Copy link
Member

justinmk commented Aug 5, 2018

@zchee yes

@zchee
Copy link
Member Author

zchee commented Aug 5, 2018

@justinmk OK, So I want to the repository owner to rerun the CI because of TravisCI failed caused by wrong(mysterious?) error on go1.10.x.

No output has been received in the last 10m0s, this potentially indicates a stalled build or something wrong with the build itself.
Check the details on how to adjust your build configuration on: https://docs.travis-ci.com/user/common-build-problems/#Build-times-out-because-no-output-was-received
The build has been terminated

Or, Should I just empty git amend and force push?

@zchee
Copy link
Member Author

zchee commented Aug 13, 2018

/ping @garyburd

@ghost
Copy link

ghost commented Aug 14, 2018

Thank you for the ping. I was traveling with limited internet access, and forgot to look at this when I did get access. I'll look at it tomorrow.

@zchee
Copy link
Member Author

zchee commented Aug 14, 2018

@garyburd Woa! where did you travel? :D
And thanks, looks forward your review.

FYI, I said before,

Can I write additional type use iota?

It means I can write completely response struct, but might be needs many type Foo int and const Bar Foo = 1<iota and corespondents structs.

I want to ask to you whether the needs above implements or not. (in other works, you like or not)

@ghost
Copy link

ghost commented Aug 15, 2018

  • The type interface{} should be avoided in the API. It's usually the case that interface{} can be eliminated by defining a struct type.
  • Return "large" values by pointer. Channel is large.
  • Regarding enumerated types: The precedent is to use strings. Defining types as you suggest adds some amount of type safety, but it does not make the API easier to use in a significant way.

I've been backpacking, camping and hiking in Washington & Wyoming.

@zchee
Copy link
Member Author

zchee commented Aug 28, 2018

@garyburd Sorry for the late reply :(
I got it! will fix.

@zchee
Copy link
Member Author

zchee commented Aug 28, 2018

@garyburd Added Client struct and fixed some point. PTAL.

@zchee
Copy link
Member Author

zchee commented Aug 31, 2018

/ping @garyburd @justinmk

@zchee
Copy link
Member Author

zchee commented Sep 7, 2018

sorry, re-ping: @garyburd @justinmk

@justinmk
Copy link
Member

justinmk commented Sep 7, 2018

@zchee I'm not qualified to review this, so we just have to wait. If we get more activity here perhaps @garyburd will add another maintainer.

@ghost
Copy link

ghost commented Sep 13, 2018

My feedback on the use of interface{} still stands. Values with type interface{} are much more difficult to pick apart than specific map or struct types. One example is that BufferCommands should return map of structs.

I have more time to work on this now. Do you want me to continue working on it?

@zchee
Copy link
Member Author

zchee commented Sep 26, 2018

@garyburd

My feedback on the use of interface{} still stands. Values with type interface{} are much more difficult to pick apart than specific map or struct types. One example is that BufferCommands should return map of structs.

I misunderstood your feedback. It means adding some new API return value to should not use interface as much as possible?
If so, I’ll continue to fix this PR.

I have more time to work on this now. Do you want me to continue working on it?

If you have time, I glad to send PR to my PR.

BTW, neovim has been nvim_buf_set_virtual_text new api. I also want to use it, so will send another PR which supports this API.
neovim/neovim@45f53b3

@ghost
Copy link

ghost commented Sep 26, 2018

I apologize for any confusion. Method return types should not include the type interface{} unless a value can be of multiple concrete types.

The BufferVar and Eval methods are examples of where interface{} in the return type is acceptable. The concrete type returned by these methods can be integer, string, map and other types.

The code generator has a special case for a return value of interface{}: the result is returned through a pointer argument instead of as a return value. This allows the application to specify a specific concrete type to MsgPack decoder.

The result of all this is that the application can work with concrete types instead of picking part results with type assertions.

@zchee
Copy link
Member Author

zchee commented Sep 27, 2018

@garyburd Thanks polite reply. I'll read your comment and will fix this pull request :)

@zchee
Copy link
Member Author

zchee commented Dec 1, 2018

@garyburd I was many changed and push new commit. If my interpretation is wrong, sorry take your time...
But removed almost interface value.

PTAL.

@zchee zchee self-assigned this Dec 1, 2018
@zchee zchee added the area/nvim label Dec 1, 2018
@zchee
Copy link
Member Author

zchee commented Jan 8, 2019

@garyburd /cc @justinmk
Sorry for late. I'll fix failed CI points later.
And, If @garyburd is busy or no reply (I'll wait to ~1 week), I'll merge this pull request into master because now pending
#40
If you don't like current interface variable, could you advise to me? (Anytime is fine. I will fix it ASAP.)


Also, I think time is come the go-client should release the versions. It is for make compatibility to more explicit with neovim core API.
What do you think about it?

@justinmk
Copy link
Member

justinmk commented Jan 8, 2019

Also, I think time is come the go-client should release the versions. It is for make compatibility to more explicit with neovim core API.

Not sure I follow. Nvim API is backwards-compatible, so go-client has no need to make breaking changes.

@zchee
Copy link
Member Author

zchee commented Jan 8, 2019

@justinmk

Nvim API is backwards-compatible, so go-client has no need to make breaking changes.

Ah, sorry for lack description.
I mean, for example,

Release neovim/[email protected]
This version supported nvim_buf_set_virtual_text API (neovim/neovim@0ce8800)

like the neovim/pynvim, go-client also publish release note or etc, and describe what supported neovim upstream API. It's more easy to understand to developer who uses go-client.

Also, The Go language has been supported semantic version vendoring in the core runtime (still ALPHA yet, will stable on Go1.12). Now Go package authors preparing it gradually.

More details: https://github.com/golang/go/wiki/Modules#gomod


But yes, As your said, neovim core api have backward compatibility. I'm just suggested based on the current state of Go language.
Versioning policy is up to you.

@ghost
Copy link

ghost commented Jan 11, 2019

The method BufferCommands is defined as:

 func BufferCommands(buffer Buffer, opts map[string]interface{}) map[string]interface{}

Each application that uses this method must use type assertions to access command properties. This work can be eliminated for all applications by declaring a command type:

type Command struct {
    Name string `msgpack:"name"`
    Definition string `msgpack:"definition"`
    ScriptID int `msgpack:"script_id"`
    ... and so on
}

 func BufferCommands(buffer Buffer, opts map[string]interface{}) map[string]*Command

If the PR is merged as is, then it's ugly moving forward to using a declared type for commands. The addition of the type requires either a breaking change or the addition of the second method for nvim_buf_get_commands.

 func BufferCommands(buffer Buffer, opts map[string]interface{}) map[string]interface{}
 func BufferCommands2(buffer Buffer, opts map[string]interface{}) map[string]*Command

I think the following are preferable to the current PR:

  1. Declare and use a type for commands. This is the best option.
  2. Omit the method from the PR. This is the least amount of work.
  3. Declare an empty struct type for command with TODO comment stating that fields should be added. This is almost the same as omitting the method in terms of work and functionality, but it does leave a pointer forward for people who come looking for the method.

@ghost
Copy link

ghost commented Jan 11, 2019

It is more conventional and more convenient to declare types like Version as a struct:

type Version struct {
     Major int `msgpack:"major"`
     Minor int `msgpack:"minor"`
     ... and so on
}

Use "omitempty" as needed to omit optional values. If the zero value (typically the empty value) has meaning, then use pointer to value or "empty" field tag to omit the value.

@zchee
Copy link
Member Author

zchee commented Jan 14, 2019

@garyburd thanks polite reply.
I'll read it.

@zchee
Copy link
Member Author

zchee commented Mar 4, 2019

@garyburd At first, Sorry for late reply :(

But I'd added Command type and fixed {Buffer}Commands return map type. Also changed the Version type to struct instead of map.
PTAL.


BTW, are you busy these days...? Do you have time to review this PR?

@zchee

This comment has been minimized.

@zchee
Copy link
Member Author

zchee commented Apr 23, 2019

@justinmk Rebased current master branch. Ready to merge!


// Blocking is true if Nvim is waiting for input.
Blocking bool `msgpack:"blocking"`
}
Copy link
Member

@justinmk justinmk Apr 24, 2019

Choose a reason for hiding this comment

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

why make a new type for this? This seems over-specific. Can't it just be a map? I guess go does not allow heterogeneous maps so it would be map[string]interface{}.

If having types for every little thing is idiomatic in go, then I guess this is ok. But it means that the client will not be forward-compatible if Nvim API adds a new field to the map. :help api-contract and :help dev-api-client explain that clients should be prepared for new, optional fields to appear in any map or list.

Copy link
Member

Choose a reason for hiding this comment

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

#36 (comment) leads me to believe this will be forward-compatible. If so, OK.

Copy link
Member Author

Choose a reason for hiding this comment

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

@justinmk I didn't add a new type.
Just move some types to types.go such as

go-client/nvim/nvim.go

Lines 645 to 691 in fba3ac8

type Mode struct {
// Mode is the current mode.
Mode string `msgpack:"mode"`
// Blocking is true if Nvim is waiting for input.
Blocking bool `msgpack:"blocking"`
}
type HLAttrs struct {
Bold bool `msgpack:"bold,omitempty"`
Underline bool `msgpack:"underline,omitempty"`
Undercurl bool `msgpack:"undercurl,omitempty"`
Italic bool `msgpack:"italic,omitempty"`
Reverse bool `msgpack:"reverse,omitempty"`
Foreground int `msgpack:"foreground,omitempty" empty:"-1"`
Background int `msgpack:"background,omitempty" empty:"-1"`
Special int `msgpack:"special,omitempty" empty:"-1"`
}
type Mapping struct {
// LHS is the {lhs} of the mapping.
LHS string `msgpack:"lhs"`
// RHS is the {hrs} of the mapping as typed.
RHS string `msgpack:"rhs"`
// Silent is 1 for a |:map-silent| mapping, else 0.
Silent int `msgpack:"silent"`
// Noremap is 1 if the {rhs} of the mapping is not remappable.
NoRemap int `msgpack:"noremap"`
// Expr is 1 for an expression mapping.
Expr int `msgpack:"expr"`
// Buffer for a local mapping.
Buffer int `msgpack:"buffer"`
// SID is the script local ID, used for <sid> mappings.
SID int `msgpack:"sid"`
// Nowait is 1 if map does not wait for other, longer mappings.
NoWait int `msgpack:"nowait"`
// Mode specifies modes for which the mapping is defined.
Mode string `msgpack:"string"`
}

Special int `msgpack:"special,omitempty" empty:"-1"`
}

// Mapping represents a nvim mapping options.
Copy link
Member

Choose a reason for hiding this comment

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

That comment doesn't really add any information. But at least "a nvim" should be just "Nvim" (no "a").

Copy link
Member Author

Choose a reason for hiding this comment

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

@justinmk I see will fix.

// LHS is the {lhs} of the mapping.
LHS string `msgpack:"lhs"`

// RHS is the {hrs} of the mapping as typed.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// RHS is the {hrs} of the mapping as typed.
// RHS is the {rhs} of the mapping as typed.

or just:

Suggested change
// RHS is the {hrs} of the mapping as typed.
// RHS of the mapping.

BTW, why does every comment start with "Foo is ..." ? It's redundant.

Copy link
Contributor

Choose a reason for hiding this comment

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

It is coding standard in Go. Golang linters demand that every doc string on function, struct or other declaration starts with its name. As I know it is Rob Pike idea.

It could be seemed redundant but in fact it simplifies understanding since doc strings has predefined structure.

Copy link
Contributor

@daskol daskol Apr 24, 2019

Choose a reason for hiding this comment

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

That comment doesn't really add any information. But at least "a nvim" should be just "Nvim" (no "a").

Nevertheless, sometimes such 'comment style' results in useless and meaningless descriptions like above.

Copy link
Member Author

Choose a reason for hiding this comment

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

@daskol Thanks for description :)

// For a host, this does not include plugin methods which will be discovered later.
// The key should be the method name, the values are dicts with the following (optional) keys. See below.
//
// Further keys might be added in later versions of nvim and unknown keys are thus ignored.
Copy link
Member

Choose a reason for hiding this comment

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

Ah, ok. Good.

@@ -123,6 +123,50 @@ func (b *Batch) BufferLines(buffer Buffer, start int, end int, strict bool, resu
b.call("nvim_buf_get_lines", result, buffer, start, end, strict)
}

// AttachBuffer activate updates from this buffer to the current channel.
Copy link
Member

@justinmk justinmk Apr 24, 2019

Choose a reason for hiding this comment

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

I recently updated the Nvim docs for the attach methods. https://neovim.io/doc/user/api.html#nvim_buf_attach()
Could help with clarity/wording of these attach/detach docstrings.

Suggested change
// AttachBuffer activate updates from this buffer to the current channel.
// Activates buffer-update events on the channel.

Copy link
Member Author

Choose a reason for hiding this comment

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

Also will fix.

@justinmk justinmk merged commit ada0455 into neovim:master Apr 24, 2019
@zchee zchee deleted the api/a225374 branch May 2, 2019 06:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants