Skip to content

Conversation

phodge
Copy link
Contributor

@phodge phodge commented Jun 29, 2018

Proposed solution for #7688 and #5534. Changes in this PR:

  • nvim_buf_get_lines() will now always return an empty list for an unloaded buffer, instead of a list containing a single empty string.
  • nvim_buf_line_count() will now always return 0 for an unloaded buffer, instead of 1.
  • nvim_buf_is_loaded() has been added to check if a buffer is loaded
  • help text updates for the above
  • extra unit tests for the above

@@ -847,7 +847,8 @@ nvim_buf_line_count({buffer}) *nvim_buf_line_count()*
{buffer} Buffer handle

Return:~
Line count
Line count, or `0` if the buffer has been unloaded (see
Copy link
Member

Choose a reason for hiding this comment

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

This section is autogenerated, please change the docstrings in api/buf.c only

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What command can I run to regenerate the api docs locally?

Copy link
Member

Choose a reason for hiding this comment

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

python3 scripts/gen_api_vimdoc.py

///
/// @param buffer Buffer handle
/// @return true if the buffer is valid, false otherwise
/// @return true if the buffer is valid, false otherwise.
Boolean nvim_buf_is_valid(Buffer buffer)
Copy link
Member

Choose a reason for hiding this comment

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

Just noticed that this returns true for 0.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah all of the nvim_buf_*() functions accept a buffer id of 0, which is interpreted as "the current buffer". This feature is used in the lua tests.

Copy link
Member

Choose a reason for hiding this comment

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

Yes but does it make sense for this function?

Copy link
Member

Choose a reason for hiding this comment

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

@justinmk what would 0 mean instead in this case? And why is that better than curbuf?

Copy link
Member

@justinmk justinmk Jul 4, 2018

Choose a reason for hiding this comment

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

@bfredl I don't understand your question about curbuf.

I'm thinking nvim_buf_is_valid(0) should return false, because nvim_buf_is_valid is for checking validity of buffer handles, and 0 is not a buffer handle. 0 makes sense for other buffer-related functions, but not this one.

Copy link
Member

Choose a reason for hiding this comment

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

But 0 is a valid buffer handle, and it means curbuf. Why should it mean something different for this function?

Copy link
Member

Choose a reason for hiding this comment

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

It's a special value that only is relevant in the context of a buffer-related function. If someone uses nvim_buf_is_valid to validate a loop or something like that, then nvim_buf_is_valid (0) => true might be unhelpful.

Copy link
Member

@bfredl bfredl Jul 4, 2018

Choose a reason for hiding this comment

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

And exactly how is this function not even related to buffers? I'm not saying true is obviously objectively better a priori, just that if we are introducing a special case, and a change of behaviour of existing input at that, I want a stronger argument than "maybe false is more useful in a some more situations". After all, clients can already special case 0 as they want, the only functional effect of changing this now is potentially breaking code that already uses this function and didn't anticipate this change.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If neovim was ever refactored such that the curbuf global variable could be NULL, perhaps during early startup when neovim hasn't had a chance to open a file yet, then nvim_buf_is_valid(0) would be the logical way to ask neovim "Is there a current buffer yet?".

Copy link
Member

@bfredl bfredl Jul 4, 2018

Choose a reason for hiding this comment

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

@phodge In that hypothetical situation: yes. Then most other nvim_buf_ functions would also unconditionally throw an error in that situation. (if we want such a situation to be exposed to local and remote user code is of course a different question, the programming model is simpler as long as we can avoid it)

@phodge
Copy link
Contributor Author

phodge commented Jul 4, 2018

The QuickBuild error (from inccommand tests) appears to be unrelated?

@KillTheMule
Copy link
Contributor

That's the "inccomand during term activity" test, that's known to be flakey.

Boolean nvim_buf_is_loaded(Buffer buffer)
FUNC_API_SINCE(5)
{
Error stub = ERROR_INIT;
Copy link
Member

Choose a reason for hiding this comment

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

Maybe we should use Error *err here, then it would be possible to identify the three states: loaded, unloaded (thus loadable) and invalid in one RPC call.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My hesitation with returning an error for invalid buffers is that you'd now need to introduce error handling code (try/except in python or pcall() in lua) to use buf.is_loaded(). Which in turn means you can't write a one-liner like if buf.is_loaded() && buf.line_count() > 10:

Copy link
Member

Choose a reason for hiding this comment

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

That makes sense. We could add some more detailed state function later it need be.

Copy link
Member

Choose a reason for hiding this comment

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

(for posterity: just realized nvim_buf_line_count is already this function.)

@phodge
Copy link
Contributor Author

phodge commented Jul 5, 2018

@justinmk, @bfredl: I'd like to finalize this PR if possible, is there anything else that needs addressing?

@phodge
Copy link
Contributor Author

phodge commented Jul 5, 2018

I've updated the description to mention that #5534 will also be resolved by this PR.

@@ -35,7 +35,8 @@
///
/// @param buffer Buffer handle
/// @param[out] err Error details, if any
/// @return Line count
/// @return Line count, or \`0` if the buffer has been unloaded (see
/// |nvim_buf_is_loaded()|).
Copy link
Member

Choose a reason for hiding this comment

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

perhaps this could be formulated to make it clear if nvim_buf_line_count is already used, then nvim_buf_is_loaded need not also be used. The later is only referenced because shared info of all buffer functions is placed there, ideally this information could be at |api-buffer| before any specific function (but the generation script maybe needs to be changed to not overwrite such a section).

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've updated the nvim_buf_is_loaded() docs to mention that you can also use nvim_buf_line_count(). I have also moved the comments on unloaded buffers to a new intro paragraph at the top of the api-buffer section.

eq(4, request('buffer_line_count', bufnr))
eq(4, request('nvim_buf_line_count', bufnr))
-- force unload the buffer (this will discard changes)
request('nvim_command','new')
Copy link
Member

Choose a reason for hiding this comment

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

use command('new')

request('nvim_command','new')
request('nvim_command', 'bunload! '..bufnr)
-- line count for an unloaded buffer should always be 0
eq(0, request('buffer_line_count', bufnr))
Copy link
Member

Choose a reason for hiding this comment

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

obsolete functions (or even just an obsolete name in this case) need not be tested in new tests, unless there is some edge case that affects the obsolete function or something (which is not here, this this just an alias)

command('bunload! '..bufnr)
-- attempting to get lines now always gives empty list
eq({}, buffer('get_lines', bufnr, 1, 3, 1))
eq({}, request('buffer_get_lines', bufnr, 1, 3, 1))
Copy link
Member

Choose a reason for hiding this comment

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

same here, buffer_get_lines is just an alias, while the even older buffer_get_line_range could be potentially interesting to test in some situation (but it is probably not worth the trouble either here).


it('line_count has defined behaviour for unloaded buffers', function()
-- we'll need to know our bufnr for when it gets unloaded
local bufnr = request('nvim_buf_get_number', 0)
Copy link
Member

Choose a reason for hiding this comment

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

nvim_buf_get_number is deprecated, nvim_get_current_buf is preferred for this, or just use curbuf() without args.

@bfredl
Copy link
Member

bfredl commented Jul 6, 2018

Good code changes, just some minor quibbles about docs and tests. 👍

@phodge
Copy link
Contributor Author

phodge commented Jul 9, 2018

OK that should be everything

buffer('set_lines', bufnr, 0, -1, 1, {"line1", "line2", "line3", "line4"})
-- confirm that getting lines works
eq({"line2", "line3"}, buffer('get_lines', bufnr, 1, 3, 1))
eq({"line2", "line3"}, request('buffer_get_lines', bufnr, 1, 3, 1))
Copy link
Member

Choose a reason for hiding this comment

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

this line can be removed


it('line_count has defined behaviour for unloaded buffers', function()
-- we'll need to know our bufnr for when it gets unloaded
local bufnr = buffer('get_number', 0)
Copy link
Member

Choose a reason for hiding this comment

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

use nvim('get_current_buf') or curbuf() (one more case below)

sep = '=' * text_width

base = os.path.join(out_dir, 'xml')
dom = minidom.parse(os.path.join(base, 'index.xml'))

# generate docs for section intros
for compound in dom.getElementsByTagName('compound'):
Copy link
Member

Choose a reason for hiding this comment

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

nice improvement!

@@ -38,7 +38,7 @@ describe('api/buf', function()

it('line_count has defined behaviour for unloaded buffers', function()
-- we'll need to know our bufnr for when it gets unloaded
local bufnr = buffer('get_number', 0)
local bufnr = curbuf('get_number')
Copy link
Member

Choose a reason for hiding this comment

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

I meant just curbuf() with no args.

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 need the buffer number to use in command('bunload! '..bufnr), but I can't figure out how to get the buffer number from the handle returned by curbuf() with no args.

Copy link
Member

Choose a reason for hiding this comment

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

The handle returned by curbuf() is the buffer number.

@bfredl
Copy link
Member

bfredl commented Jul 14, 2018

LGTM. Squash and rebase?

@phodge phodge force-pushed the 7688-nvim-buf-lines-should-return-empty-list-for-unloaded-buffer branch from f16e10e to ea2e8f4 Compare July 25, 2018 05:28
@phodge
Copy link
Contributor Author

phodge commented Aug 1, 2018

@bfredl: I've rebased into a smaller set of commits. I'm not 100% certain what's going on with the build there - but I'm pretty sure the errors are unrelated. I think it's OK to merge now, but I don't have access to do that myself.

@bfredl
Copy link
Member

bfredl commented Aug 2, 2018

Failures look unrelated, I restarted the failed builds.

@bfredl bfredl merged commit 2b9fc9a into neovim:master Aug 2, 2018
@bfredl
Copy link
Member

bfredl commented Aug 2, 2018

merged, thanks!

justinmk added a commit to justinmk/neovim that referenced this pull request Dec 30, 2018
Besides the "visible" improvements, this release features numerous
internal improvements to the UI/screen code and test infrastructure.

Numerous patches were merged from Vim, which are not mentioned below.

FEATURES:

07ad5d7 clipboard: Support custom VimL functions neovim#9304
725da1f neovim#9401 win/TUI: Improve terminal/console support
7a8dadb neovim#9077 startup: Use $XDG_CONFIG_DIRS/nvim/sysinit.vim if it exists
feec926 neovim#9299 support <cmd> mapping in more places
0653ed6 neovim#9028 diff/highlight: Show underline for low-priority CursorLine
bddcbbb signs: Add "numhl" argument neovim#9113
05f9c7c clipboard: support Wayland (neovim#9230)
14ae394 neovim#9052 TUI: add support for undercurl and underline color
4fa3492 neovim#9023 man.vim: soft (dynamic) wrap neovim#9023

API:

8b39e4e neovim#6920 API: implement object namespaces
b1aaa0a API: Implement nvim_win_set_buf() neovim#9100
8de87c7 neovim#8180 API: virtual text annotations (nvim_buf_set_virtual_text)
2b9fc9a neovim#8660 API: add nvim_buf_is_loaded()
    API: buf_get_lines, buf_line_count handle unloaded buffers
88f77c2 API: nvim_buf_get_offset_for_line
94841e5 API/UI: neovim#8221 ext_newgrid, ext_hlstate
    (use line-based rather than char-based updates)

UI

b5cfac0 neovim#8806 TUI: use BCE again more often, (smoother resizes/scrolling)
77b5e9a neovim#9315 screen: add missing status redraw when redraw_later(CLEAR) was used
5f15788 TUI: clip invalid regions on resize (neovim#8779), fixes neovim#8774
c936ae0 neovim#9193 TUI: improvements for scrolling and clearing
f204274 neovim#9143 UI: disable clearing almost everywhere
f4b2b66 neovim#9079 TUI: always use safe cursor movement after resize
d36afaf neovim#9211 ui_options: also send when starting or from OptionSet
67f80d4 TUI: Avoid reset_cursor_color in old VTE neovim#9191
e55ebae neovim#9021 don't erase screen on `:hi Normal` during startup
c5790d9 neovim#8915 TUI: Hint wrapped lines to terminals.

FIXES:

231de72 RPC: turn errors from async calls into notifications
907ad92 TUI: Restore terminal title via "title stacking" (neovim#9407)
cb76a8a genappimage: Unset $ARGV0 at invocation neovim#9376
b48efd9 neovim#9347 TUI: FreeBSD: Improve support for BSD vt console
c16529a TUI: Konsole 18.07.70 supports DECSCUSR (neovim#9364)
aec096f os/lang: use the correct LC_NUMERIC also for OS X
5fee0be provider: improve error message (neovim#9344)
3c42d7a TUI: alacritty supports set_cursor_color neovim#9353
7bff9a5 TUI: Alacritty supports DECSCUSR (neovim#9048)
57acfce macOS: infer primary language if $LANG is empty neovim#9345
bc132ae runtime/syntax: Fix highlighting of augroup contents (neovim#9328)
715fdfe neovim#9297 VimL/confirm(): Show dialog even if :silent
799d9c3 clipboard: Prefer xclip (neovim#9302)
6dae777 provider/nodejs: fix npm,yarn detection
16bc1e9 neovim#9218 channel: avoid buffering output when only terminal and no callbacks are active
72fecad neovim#8804 Fix crash in lang_init() on macOS if lang_region = NULL
d581398 ruby: detect rbenv shims for other versions (neovim#8733)
e568ac7 neovim#9123 third-party/unibilium: Fix parsing of extended capability entries
c4c74c3 jobstart(): Fix hang on non-executable cwd neovim#9204
1cf50cb provider/nodejs: Simultaneously query npm and yarn neovim#9054
6c496db undo: Fix infinite loop if undo_read_byte returns EOF neovim#2880
f8f8357 neovim#9034 'swapfile: always show dialog'

CHANGES:

c236e80 neovim#9024 --embed: wait for UI unless --headless
180b50d neovim#9248 python: 'neovim' module was renamed to 'pynvim'
2000b6a neovim#8589 VimL: Remove legacy aliases "v:errmsg", "v:shell_error", "v:this_session"
deb18a0 defaults: background=dark neovim#2894 (neovim#9205)
c1187d4 defaults: win: 'shellpipe' for cmd.exe (neovim#8827)
justinmk added a commit to justinmk/neovim that referenced this pull request Dec 31, 2018
Besides the "visible" improvements, this release features numerous
internal improvements to the UI/screen code and test infrastructure.

Numerous patches were merged from Vim, which are not mentioned below.

FEATURES:

07ad5d7 clipboard: Support custom VimL functions neovim#9304
725da1f neovim#9401 win/TUI: Improve terminal/console support
7a8dadb neovim#9077 startup: Use $XDG_CONFIG_DIRS/nvim/sysinit.vim if it exists
feec926 neovim#9299 support <cmd> mapping in more places
0653ed6 neovim#9028 diff/highlight: Show underline for low-priority CursorLine
bddcbbb signs: Add "numhl" argument neovim#9113
05f9c7c clipboard: support Wayland (neovim#9230)
14ae394 neovim#9052 TUI: add support for undercurl and underline color
4fa3492 neovim#9023 man.vim: soft (dynamic) wrap neovim#9023

API:

8b39e4e neovim#6920 API: implement object namespaces
b1aaa0a API: Implement nvim_win_set_buf() neovim#9100
8de87c7 neovim#8180 API: virtual text annotations (nvim_buf_set_virtual_text)
2b9fc9a neovim#8660 API: add nvim_buf_is_loaded()
    API: buf_get_lines, buf_line_count handle unloaded buffers
88f77c2 API: nvim_buf_get_offset_for_line
94841e5 API/UI: neovim#8221 ext_newgrid, ext_hlstate
    (use line-based rather than char-based updates)

UI

b5cfac0 neovim#8806 TUI: use BCE again more often, (smoother resizes/scrolling)
77b5e9a neovim#9315 screen: add missing status redraw when redraw_later(CLEAR) was used
5f15788 TUI: clip invalid regions on resize (neovim#8779), fixes neovim#8774
c936ae0 neovim#9193 TUI: improvements for scrolling and clearing
f204274 neovim#9143 UI: disable clearing almost everywhere
f4b2b66 neovim#9079 TUI: always use safe cursor movement after resize
d36afaf neovim#9211 ui_options: also send when starting or from OptionSet
67f80d4 TUI: Avoid reset_cursor_color in old VTE neovim#9191
e55ebae neovim#9021 don't erase screen on `:hi Normal` during startup
c5790d9 neovim#8915 TUI: Hint wrapped lines to terminals.

FIXES:

231de72 RPC: turn errors from async calls into notifications
907ad92 TUI: Restore terminal title via "title stacking" (neovim#9407)
cb76a8a genappimage: Unset $ARGV0 at invocation neovim#9376
b48efd9 neovim#9347 TUI: FreeBSD: Improve support for BSD vt console
c16529a TUI: Konsole 18.07.70 supports DECSCUSR (neovim#9364)
aec096f os/lang: use the correct LC_NUMERIC also for OS X
5fee0be provider: improve error message (neovim#9344)
3c42d7a TUI: alacritty supports set_cursor_color neovim#9353
7bff9a5 TUI: Alacritty supports DECSCUSR (neovim#9048)
57acfce macOS: infer primary language if $LANG is empty neovim#9345
bc132ae runtime/syntax: Fix highlighting of augroup contents (neovim#9328)
715fdfe neovim#9297 VimL/confirm(): Show dialog even if :silent
799d9c3 clipboard: Prefer xclip (neovim#9302)
6dae777 provider/nodejs: fix npm,yarn detection
16bc1e9 neovim#9218 channel: avoid buffering output when only terminal and no callbacks are active
72fecad neovim#8804 Fix crash in lang_init() on macOS if lang_region = NULL
d581398 ruby: detect rbenv shims for other versions (neovim#8733)
e568ac7 neovim#9123 third-party/unibilium: Fix parsing of extended capability entries
c4c74c3 jobstart(): Fix hang on non-executable cwd neovim#9204
1cf50cb provider/nodejs: Simultaneously query npm and yarn neovim#9054
6c496db undo: Fix infinite loop if undo_read_byte returns EOF neovim#2880
f8f8357 neovim#9034 'swapfile: always show dialog'

CHANGES:

c236e80 neovim#9024 --embed: wait for UI unless --headless
180b50d neovim#9248 python: 'neovim' module was renamed to 'pynvim'
2000b6a neovim#8589 VimL: Remove legacy aliases "v:errmsg", "v:shell_error", "v:this_session"
deb18a0 defaults: background=dark neovim#2894 (neovim#9205)
c1187d4 defaults: win: 'shellpipe' for cmd.exe (neovim#8827)
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.

5 participants