Skip to content

API: buffer notifications #7917

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 26 commits into from
Jun 8, 2018
Merged

API: buffer notifications #7917

merged 26 commits into from
Jun 8, 2018

Conversation

KillTheMule
Copy link
Contributor

@KillTheMule KillTheMule commented Jan 26, 2018

Since @phodge seems to have run out of time, I hope you don't mind me taking over your PR. Thanks for your work so far :)

I've added an argument to nvim_buf_live_udpates that notes if the full buffer should be sent upon starting the updates. I've also added a test, should work.

TODO:

  • Adjust documentation
  • Rename functions after some bikeshedding
  • Replace num_replaced with lastline, akin to set_lines
  • Enlargen channel buffer capacity
  • Fix tests on windows
    • Use new_pipename() for the multiple channel test
    • Don't fix the diffget test, but open an issue describing what happens, cc janlazo in it, see API: buffer notifications #7917 (comment) for a rough description
  • Add safeguards for the TODO conversion items. Send a message to the client and abort (only happens with really large diffs/files on 32bit systems anyways). Put in asserts for future proofness, can't happen today anyways.

Questions:

  1. What should the functions be named? I figure nvim_buf_live_updates is fine, as long as we want to call this functionality live updates. Any thoughts?
  2. What should the events be called? We have e.g. "LiveUpdateStart" and "LiveUpdate", which fits imho, but opinions are welcome.
  3. Is the documentation in the right place? Let me know where it should live. Is there another place this needs to be added to?
  4. As it stands now, registering and unregistering for the updates is done through the same function and takes a boolean argument to distinguish between registering and unregistering, e.g. nvim_buf_live_updates(true) vs. nvim_buf_live_updates(false). Since I've added a flag to maybe not send the whole buffer, those would be nvim_buf_live_updates(true, true) vs. nvim_buf_live_updates(false, true) where in the 2nd case the second argument is simply ignored. Feels ugly and weird. Should I make the 2 different functions? Or should there be a function to request the full buffer separately?
  5. As I mentioned in the original PR, I'm getting trouble from the channel capacity. My idea would be to allow this to be configured by the plugin (i.e. introduce methods nvim_get_channel_capacity and nvim_set_channel_capacity), and keep the current default. I'd also think this should be another PR (I'd do it), so unless someone pipes up, I'll not include this here.
  6. What else does this PR need in order to get merged?

All comments and ideas welcome, although please keep in mind I'm a beginner programmer.

cc @justinmk, @bfredl, @phodge, @jamessan, @lunixbochs, @bryphe,@Chillee

Note: Unless you like function names like function_to_make_nvim_send_lines_when_a_buffer_updated, DON'T leave me alone with the naming issues. You have been warned :P

@bfredl
Copy link
Member

bfredl commented Jan 26, 2018

We have e.g. "LiveUpdateStart" and "LiveUpdate", which fits imho, but opinions are welcome.

Events should have a prefix to distinguish builtin events from events sent by user code (rpcnotify(..., "theevent")). Unless there is a strong reason for CamelCase I think events should follow the general API convention, i e underscores and lower case. Also is "live" really good in the event name? All events about current state is "live"... It would better if the name signifies the actual change, that some lines of a buffer changed. Something in the roundabouts of nvim_buf_lines_changed I would expect.

@KillTheMule
Copy link
Contributor Author

Ok, how about

  • LiveUpdateStart -> nvim_buf_update_start
  • LiveUpdate -> nvim_buf_update
  • LiveUpdateTick -> nvim_buf_update_tick
  • LiveUpdateEnd -> nvim_buf_update_end

@bfredl
Copy link
Member

bfredl commented Jan 26, 2018

Or should there be a function to request the full buffer separately?

No, this would make it more easy to write racy code, subscription and full buffer send should be the same method call when applicable. I would rather have a separate method to stop subscription.

My idea would be to allow this to be configured by the plugin (i.e. introduce methods nvim_get_channel_capacity and nvim_set_channel_capacity), and keep the current default. I'd also think this should be another PR (I'd do it), so unless someone pipes up, I'll not include this here.

I think we should attempt at reducing copying and allocation before we consider to add user configuration for memory limits.

@KillTheMule
Copy link
Contributor Author

No, this would make it more easy to write racy code, subscription and full buffer send should be the same method call when applicable. I would rather have a separate method to stop subscription.

Ok, I will introduce a second function.

I think we should attempt at reducing copying and allocation before we consider to add user configuration for memory limits.

I was afraid you were going to say something like this :D Are you positive a channel capacity of 10MB can be made sufficient to transfer a 1GB file in a sane number of notifications? Do you have something particular in mind?

@bfredl
Copy link
Member

bfredl commented Jan 26, 2018

I'm thinking of event names that maybe contains "lines" to mirror get_lines/set_lines. Also I would replace numreplaced with last_line, to follow the notion of set_lines (the numbers should be the same as a set_lines call that uses strict indexing, and nonnegative indicies)

@bfredl
Copy link
Member

bfredl commented Jan 26, 2018

How do you mean chunking solve the allocation problem? If the client hasn't read the first chunk when nvim wants to send the second, what happens?

@lunixbochs
Copy link

lunixbochs commented Jan 26, 2018

I think it makes far more sense to block the channel when the buffer fills, encourage clients to drain the buffer as fast as they can (thus moving the buffer size explosion to the client), and have a user setting for client timeout (so users who want neovim to block for multiple second sometimes need to enable it themselves), than it does for clients to ask neovim for more buffer size.

this mode is still helped greatly by copy on write, which may be able to remove the need for large channel buffer sizes

@KillTheMule
Copy link
Contributor Author

I'm thinking of event names that maybe contains "lines" to mirror get_lines/set_lines

We'd have to change that if we ever want to send partial lines though. That's why I'm kinda leaning towards not having line in the name. Otoh, if the return values change, a new name might not be the worst thing...

How do you mean chunking solve the allocation problem? If the client hasn't read the first chunk when nvim wants to send the second, what happens?

I really don't know, I was hoping something along the lines of "chunk it up and hope the client fetches the chunks fast enough".

Also I would replace numreplaced with last_line, to follow the notion of set_lines

Will do.

@bfredl
Copy link
Member

bfredl commented Jan 26, 2018

I really don't know, I was hoping something along the lines of "chunk it up and hope the client fetches the chunks fast enough".

I'm sorry to be "that one" but "chunking" doesn't say me anything unless you specify what decision rule nvim will apply at the chunk boundary (that it couldn't apply otherwise)

@KillTheMule
Copy link
Contributor Author

I'm sorry to be "that one" but "chunking" doesn't say me anything unless you specify what decision rule nvim will apply at the chunk boundary (that it couldn't apply otherwise)

No, worries, I'm really just "handwaving" in the worst possible way here. Note that the LiveUpdateStart notification already has a parameter more to notify that client that more lines are to be expected. That way, neovim can send several LiveUpdateStart notifications, each containing a set of lines so the message size is always <10MB.

@bfredl
Copy link
Member

bfredl commented Jan 26, 2018

Limiting chunk size surely has other benefits as it allows interleaving a smaller unrelated message without waiting for the full 1GB. But that is a separate problem (head-of-line problem).

I will investigate if memline can support COW-references without going insane (that would mean zero allocation of line contents whenever the line is still in undo history, even if it was changed), until then (in this PR) I think we should just increase the memory limit.

@KillTheMule
Copy link
Contributor Author

I will investigate if memline can support COW-references without going insane (that would mean zero allocation of line contents whenever the line is still in undo history, even if it was changed), until then (in this PR) I think we should just increase the memory limit.

Sounds good :) To what should I increase it? I went with 2GB locally, but I'm unsure if there are consequences of just using a large value.

@bfredl
Copy link
Member

bfredl commented Jan 26, 2018

Let's go for that unless someone protests. Alternatively, one possibility could be to make the memory quota shared among all channels, and at OOM close the one with largest memory consumption...

`"nvim_buf_live_updates"`API method to activate Live Update events for a
specific buffer. For example, in python >

import sys, neovim
Copy link
Member

Choose a reason for hiding this comment

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

I don't think this belongs here. At this point we can assume that the reader is aware of clients, attach-ment etc. Also we shouldn't start with a language-specific example, just describe the API functionality. (See :help ui-intro for comparison)

The co-process will start receiving the notification events which will be
equivilent to the following |rpcnotify()| calls:

1. rpcnotify({channel}, "LiveUpdateStart", *LiveUpdateStart*
Copy link
Member

Choose a reason for hiding this comment

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

rpcnotfy shouldn't be used here, the fundamental concept is msgpack notifications (and what's relevant for the reader is how they are represented at the receiving end, which we don't control). Just mention name + [argument, list]

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Like this?

Copy link
Member

Choose a reason for hiding this comment

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

Possibly, but I would like to make events visually distinct from methods in some way, maybe by using [ ] argument list.

@KillTheMule KillTheMule force-pushed the phodge branch 2 times, most recently from 8d75ac7 to d2f3bd9 Compare January 26, 2018 19:52
@KillTheMule KillTheMule changed the title Continue #5269 [WIP] Continue #5269 Jan 27, 2018
@phodge
Copy link
Contributor

phodge commented Jan 27, 2018

@KillTheMule Thanks for picking this up! I haven't had energy to keep this going after so long, so it'd be absolutely awesome if you can get it across the finish line.

WRT to renaming events from "LiveUpdate" to "[something else]", remember to make the name something that is easy to google. :-)

WRT chunking ... when the LiveUpdateStart message is being generated, you could count the number of characters in each line as it is added to the array, and start a new chunk when the number of characters goes over some predefined limit. I don't know what the limit should be, but you could set it low enough that you never hit the channel buffer limits. And if there's a single line of code that's too many characters even on its own, you could just disable LiveUpdates and return an error message saying Line X too many characters for live updates. I think most users would be OK with having LiveUpdate-dependent plugins turn themselves off on the rare occasion they're editing a big file.

Thanks again for taking this on - I look forward to a future version of neovim with "Merged #7917" in the release notes. 👍

@marvim marvim added the WIP label Jan 27, 2018
@KillTheMule
Copy link
Contributor Author

WRT chunking ...

Yeah, that's basically what I meant to say :) But since the buffer capacity is 10MB right now, sending a 1GB file would probably produce a lot of overhead. We'll just go with upping the capacity for now.

@bfredl So, for naming, we have the API functions, which are called nvim_buf_live_updates_start etc. right now, and the C functions with names like liveupdate_register. Should there be some similarity? I'll make an overview over the functions of this PR, so it's easier to think about :)

@KillTheMule
Copy link
Contributor Author

I made the changes @bfredl requested to the LiveUpdate event.

Here are the C functions we have (from liveupdate.h), and if applicable the corresponding API function, and the events sent:

  • Functions:
    • liveupdate_register -> API nvim_buf_live_updates_start
    • liveupdate_unregister -> API nvim_buf_live_updates_stop
    • liveupdate_unregister_all
    • liveupdate_send_changes
    • liveupdate_send_tick
  • Events:
    • LiveUpdateStart
    • LiveUpdate
    • LiveUpdateTick
    • LiveUpdateEnd

So how about we replace that with

  • Functions:
    • buffer_updates_register -> API nvim_buf_updates_start
    • buffer_updates_unregister -> API nvim_buf_updates_stop
    • buffer_updates_unregister_all
    • buffer_updates_send_changes
    • buffer_updates_send_tick
  • Events:
    • nvim_buf_updates_start
    • nvim_buf_update
    • nvim_buf_update_tick
    • nvim_buf_updates_end

Just throwing out ideas, get me something better (or what you like better, I don't mind), and I'll put it in :)

@KillTheMule
Copy link
Contributor Author

KillTheMule commented Jan 27, 2018

Also, this fails on windows with Vim(diffthis):E97: Cannot create diffs, does anyone know what's up with this?

Third, this fails on windows with test\functional\helpers.lua:93: Failed to evaluate expression, does anyone know those things.

@janlazo You seem to know a lot about windows things, could you have a look? Unfortunately, I can't test on windows locally...

(e) justin says on gitter:

the "cannot create diffs" issue could be related to the $TMPDIR change i pushed today (which hopefully fixes it)
regarding the "third" problem, what is the value of where
try this instead: eval("serverstart('"..where.."')")

when possible, use ' in VimL, it avoids escaping issues (forces all chars to be literal)

yeah, on windows with \ slashes, \ in a " string will break. so use '

@KillTheMule KillTheMule force-pushed the phodge branch 2 times, most recently from b84c411 to 7bccf03 Compare January 30, 2018 18:51
where = alter_slashes(where)
print("serverstart('"..where.."')")
--eval("serverstart('"..where.."')")
helpers.command("call serverstart('"..where.."')")
Copy link
Member

Choose a reason for hiding this comment

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

Do we really need multiple servers for this? Can't we just connect multiple times to v:servername ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep, adjusted that.

@KillTheMule
Copy link
Contributor Author

QB/Travis failures unrelated. AV failure seems geniune, but I have not idea how to go about it, I could not reproduce it manually. I'll do some desperate debugging attempts, but hopefully someone can lend me a hand.

Other than that, I think what's needed is a decision about naming. That's it :)

@bfredl
Copy link
Member

bfredl commented May 29, 2018

@chemzqm In general attachment is on a channel basis (same as UI). Rather the host should allow multiple plugins to share a buffer attachment. I might prototype this in the python host, to show the general pattern. This will have other benefits: in any sync context buf[line:range] (python syntax, but the idea should work the same) can use the cached value in the host instead of needing to send an additional request.

@chemzqm
Copy link
Contributor

chemzqm commented May 29, 2018

@bfredl I've tested that this could happen for different node plugins

let buffer = null

async function getLines () {
  let {nvim} = this
  buffer = await nvim.buffer
  await buffer.request('nvim_buf_attach', [buffer, false, {}])
}

async function unbind() {
  await buffer.request('nvim_buf_detach', [buffer])
}

module.exports = (plugin) => {
  plugin.registerCommand('LiveListen', getLines.bind(plugin), {sync: false})
  plugin.registerCommand('LiveunListen', unbind.bind(plugin), {sync: false})
  plugin.nvim.on('notification', (name, args) => {
    if (name === 'nvim_buf_lines_event') {
      let [buf, tick, firstline, lastline, linedata, more] = args
      console.error(`changes: ${firstline} ${lastline}`)
    }
  })
}
let buffer = null

async function getLines () {
  let {nvim} = this
  buffer = await nvim.buffer
  await buffer.request('nvim_buf_attach', [buffer, false, {}])
}

module.exports = (plugin) => {
  plugin.registerCommand('LiveNotify', getLines.bind(plugin), {sync: false})
  plugin.nvim.on('notification', (name, args) => {
    if (name === 'nvim_buf_lines_event') {
      let [buf, tick, firstline, lastline, linedata, more] = args
      console.error(`notify: ${firstline} ${lastline}`)
    }
  })
}

Detach called in one plugin would cause notification not working in other plugins.

There is a detach event nvim_buf_detach_event, but how could I attach event listener to the buffer again if it was triggered by other plugin calling detach?

@bfredl
Copy link
Member

bfredl commented May 29, 2018

There is a detach event nvim_buf_detach_event, but how could I attach event listener to the buffer again if it was triggered by other plugin calling detach?

Well the point is that the plugin won't call the nvim methods directly, rather helper functions in the host. The host can keep refcounting on the buffer, and only call detach when the number of plugins using it goes to zero. I think I have an old unfinished branch for this in python, seems like a good time for me to revive it....

@chemzqm
Copy link
Contributor

chemzqm commented May 29, 2018

@bfredl But there would some other problem for a host to manage the count of attach and detach.
For example, a plugin may call attach on different user event(the attach could be called more than one time), and it would expect one detach call to detach the events.
So it requires something like plugin id to make the detach work properly when one plugin call attach multiply times.

@bfredl
Copy link
Member

bfredl commented May 29, 2018

@chemzqm That sounds to me more like an "accidental" problem (change the helper functions to expose the most convenient interface to plugins) rather than a "fundamental" problem (that helper function solution won't work at all)

My thought for python host would be to just reify the subscription rather than introduce plugin identity, so something like

id = thebuf.attach(self.callback, options...)

and the plugin could later do thebuf.detach(id) or alternative attach would return an object with a .detach(). So detach is called the same number times as attach (or not at all, if subscription is persistent) Won't something like this make sense for nodejs as well?


The alternative for me, if we want nvim core to be more involved, would be to introduce some kind of sub-channel routing mechanism, where each nvim_..._event will have an adress handle (or list of such) as first parameter. (but even then I think host will be involved, because we will want to multicast the some updates to different addresses on a channel, to not duplicate all buffer updates). To me this seems overblown for this PR as it stands, but maybe this will be useful with further expansions, like individual plugin only caring about extmarks in its own namespace.

@KillTheMule
Copy link
Contributor Author

KillTheMule commented May 29, 2018

Wait, am I missing something? Registering for updats happens via channel_id. Am I wrong in thinking that every remote plugin gets its own channel? So what I think you're describing shouldn't happen, @chemzqm . I can't read your code, but maybe I can cook up a test for that.

Or am I off with something here?

(e) Btw, calling attach multiple times is equivalent to calling it once.

(ee) Actually this test tests the scenario, doesn't it? We're detaching here, but still receive notifications here.

@bfredl
Copy link
Member

bfredl commented May 29, 2018

@KillTheMule remote plugins that use the registration mechanism will all run in a host shared among all such plugins in the same language. My thought was to add a thin layer in the host to make sure multiple plugins can subscribe and only get callbacks when their buffers has an event.

@KillTheMule
Copy link
Contributor Author

Oh, ok, so there even are docs for this feature :) Imho, that would be the job of the host indeed.

@justinmk
Copy link
Member

justinmk commented Jun 8, 2018

Nicely done. Thank you @phodge @KillTheMule @bfredl @chemzqm and @ZyX-I .

I made some superficial changes in the merge-commit.

justinmk added a commit that referenced this pull request Jun 8, 2018
@@ -1234,7 +1234,8 @@ static void refresh_screen(Terminal *term, buf_T *buf)

int change_start = row_to_linenr(term, term->invalid_start);
int change_end = change_start + changed;
changed_lines(change_start, 0, change_end, added);
// Note: don't send nvim_buf_lines_event event for a :terminal buffer
changed_lines(change_start, 0, change_end, added, false);
Copy link
Member

Choose a reason for hiding this comment

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

@KillTheMule is there at test to check that :terminal buffers do not trigger nvim_buf_lines_event?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No there isn't. But now that you mention it: Why shouldn't they? I mean, they're buffers after all, if someone wants to subscribe to their updates, I don't see I reason why we should deny them. Or is there a specific reason I'm not seeing?

Copy link
Member

Choose a reason for hiding this comment

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

Sure, why not. I was just going by the comment here.

Would still want a test either way

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll send a PR, might take some time though.

Copy link
Contributor

Choose a reason for hiding this comment

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

I want to monitor the content of a terminal buffer that loaded from session file, it seems no other options except using the buffer updates API.

@bfredl
Copy link
Member

bfredl commented Jun 8, 2018

I began to look into python host integration: neovim/pynvim#340

@janlazo janlazo mentioned this pull request Jun 8, 2018
justinmk added a commit to justinmk/neovim that referenced this pull request Jun 10, 2018
justinmk added a commit to justinmk/neovim that referenced this pull request Jun 10, 2018
doc: termios defaults. ref neovim#6992
doc: :help shell-powershell
doc: provider: Python minimum version is 2.7, 3.4
doc: remove :!start special-case. neovim#5844

mention neovim#7917 change which accepts empty Array for Dictionary parameter
justinmk added a commit to justinmk/neovim that referenced this pull request Jun 10, 2018
doc: termios defaults. ref neovim#6992
doc: :help shell-powershell
doc: provider: Python minimum version is 2.7, 3.4
doc: remove :!start special-case. neovim#5844
doc: mention neovim#7917 change which accepts empty Array for Dictionary parameter
doc: <Cmd> pseudokey
doc: lmap change neovim#5658
doc: -s, -es
justinmk added a commit to justinmk/neovim that referenced this pull request Jun 10, 2018
doc: termios defaults. ref neovim#6992
doc: :help shell-powershell
doc: provider: Python minimum version is 2.7, 3.4
doc: remove :!start special-case. neovim#5844
doc: mention neovim#7917 change which accepts empty Array for Dictionary parameter
doc: <Cmd> pseudokey
doc: lmap change neovim#5658
doc: -s, -es
justinmk added a commit that referenced this pull request Jun 11, 2018
FEATURES:
3cc7ebf #7234 built-in VimL expression parser
6a7c904 #4419 implement <Cmd> key to invoke command in any mode
b836328 #7679 'startup: treat stdin as text instead of commands'
58b210e :digraphs : highlight with hl-SpecialKey #2690
7a13611 #8276 'startup: Let `-s -` read from stdin'
1e71978 events: VimSuspend, VimResume #8280
1e7d5e8 #6272 'stdpath()'
f96d99a #8247 server: introduce --listen
e8c39f7 #8226 insert-mode: interpret unmapped META as ESC
98e7112 msg: do not scroll entire screen (#8088)
f72630b #8055 let negative 'writedelay' show all redraws
5d2dd2e win: has("wsl") on Windows Subsystem for Linux #7330
a4f6cec cmdline: CmdlineEnter and CmdlineLeave autocommands (#7422)
207b7ca #6844 channels: support buffered output and bytes sockets/stdio

API:
f85cbea #7917 API: buffer updates
418abfc #6743 API: list information about all channels/jobs.
36b2e3f #8375 API: nvim_get_commands
273d2cd #8329 API: Make nvim_set_option() update `:verbose set …`
8d40b36 #8371 API: more reliable/descriptive VimL errors
ebb1acb #8353 API: nvim_call_dict_function
9f994bb #8004 API: nvim_list_uis
3405704 #7520 API/UI: forward option updates to UIs
911b1e4 #7821 API: improve nvim_command_output

WINDOWS OS:
9cefd83 #8084, #8516 build/win: support MSVC
ee4e1fd win: Fix reading content from stdin (#8267)

TUI:
ffb8904 #8309 TUI: add support for mouse release events in urxvt
8d5a46e #8081 TUI: implement "standout" attribute
6071637 TUI: support TERM=konsole-256color
67848c0 #7653 TUI: report TUI info with -V3 ('verbose' >= 3)
3d0ee17 TUI/rxvt: enable focus-reporting
d109f56 #7640 TUI: 'term' option: reflect effective terminal behavior

FIXES:
ed6a113 #8273 'job-control: avoid kill-timer race'
4e02f1a #8107 'jobs: separate process-group'
451c48a terminal: flush vterm output buffer on pty output #8486
5d6732f :checkhealth fixes #8335
53f11dc #8218 'Fix errors reported by PVS'
d05712f inccommand: pause :terminal redraws (#8307)
51af911 inccommand: do not execute trailing commands #8256
84359a4 terminal: resize to the max dimensions (#8249)
d49c1dd #8228 Make vim_fgets() return the same values as in Vim
60e96a4 screen: winhl=Normal:Background should not override syntax (#8093)
0c59ac1 #5908 'shada: Also save numbered marks'
ba87a2c cscope: ignore EINTR while reading the prompt (#8079)
b1412dc #7971 ':terminal Enter/Leave should not increment jumplist'
3a5721e TUI: libtermkey: force CSI driver for mouse input #7948
6ff13d7 #7720 TUI: faster startup
1c6e956 #7862 TUI: fix resize-related segfaults
a58c909 #7676 TUI: always hide cursor when flushing, never flush buffers during unibilium output
303e1df #7624 TUI: disable BCE almost always
249bdb0 #7761 mark: Make sure that jumplist item will not have zero lnum
6f41ce0 #7704 macOS: Set $LANG based on the system locale
a043899 #7633 'Retry fgets on EINTR'

CHANGES:
ad60927 #8304 default to 'nofsync'
f3f1970 #8035 defaults: 'fillchars'
a6052c7 #7984 defaults: sidescroll=1
b69fa86 #7888 defaults: enable cscopeverbose
7c4bb23 defaults: do :filetype stuff unless explicitly "off"
2aa308c #5658 'Apply :lmap in macros'
8ce6393 terminal: Leave 'relativenumber' alone (#8360)
e46534b #4486 refactor: Remove maxmem, maxmemtot options
131aad9 win: defaults: 'shellcmdflag', 'shellxquote' #7343
c57d315 #8031 jobwait(): return -2 on interrupt also with timeout
6452831 clipboard: macOS: fallback to tmux if pbcopy is broken #7940
300d365 #7919 Make 'langnoremap' apply directly after a map
ada1956 #7880 'lua/executor: Remove lightuserdata'

INTERNAL:
de0a954 #7806 internal statistics for list impl
dee78a4 #7708 rewrite internal list impl
@KillTheMule KillTheMule deleted the phodge branch June 21, 2018 17:44
@@ -223,6 +223,11 @@ for i = 1, #functions do
output:write('\n } else if (args.items['..(j - 1)..'].type == kObjectTypeInteger && args.items['..(j - 1)..'].data.integer >= 0) {')
output:write('\n '..converted..' = (handle_T)args.items['..(j - 1)..'].data.integer;')
end
-- accept empty lua tables as empty dictionarys
Copy link
Member

Choose a reason for hiding this comment

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

"lua" in the above comment is a bit misleading. This applies to all msgpack requests--though it's probably only useful for a Lua client.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right, I was somewhat in "lua-land" when I did this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.