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

option: "local to tab page" options has getBuffer() method #268

Open
Milly opened this issue Aug 28, 2024 · 5 comments
Open

option: "local to tab page" options has getBuffer() method #268

Milly opened this issue Aug 28, 2024 · 5 comments
Labels
bug Something isn't working

Comments

@Milly
Copy link
Contributor

Milly commented Aug 28, 2024

Describe the bug

Related #267.

"local to tab page" options has getBuffer() method.
There is also getWindow() etc. methods.

import { cmdheight } from "jsr:@denops/std/option";

declare const denops: Denops;

await cmdheight.getBuffer(denops, 1);

Currently (Vim/Nvim target for v7) there are only these options:

  • 'cmdheight'
						*'cmdheight'* *'ch'*
'cmdheight' 'ch'	number	(default 1)
			global or local to tab page
	Number of screen lines to use for the command-line.  A larger value
	helps avoiding |hit-enter| prompts.
	The value of this option is stored with the tab page, so that each tab
	page can have a different value.

Expected behavior

  • No getBuffer() etc. methods are available.
  • No setWindow() etc. methods are available.
  • Add getTabPage() etc. methods.
@Milly Milly added the bug Something isn't working label Aug 28, 2024
@Milly
Copy link
Contributor Author

Milly commented Aug 28, 2024

I'm working on this.

@Milly
Copy link
Contributor Author

Milly commented Aug 29, 2024

getTabPage() etc. methods cannot be implemented.

getBuffer() method uses getbufvar(), which allows to get buffer options:

getbufvar({buf}, {varname} [, {def}])				*getbufvar()*
		The result is the value of option or local buffer variable
		{varname} in buffer {buf}.  Note that the name without "b:"
		must be used.
		The {varname} argument is a string.
		When {varname} is empty returns a |Dictionary| with all the
		buffer-local variables.
		When {varname} is equal to "&" returns a |Dictionary| with all
		the buffer-local options.
		Otherwise, when {varname} starts with "&" returns the value of
		a buffer-local option.
		This also works for a global or buffer-local option, but it
		doesn't work for a global variable, window-local variable or
		window-local option.

But gettabvar() does not provide to get tab page options:

gettabvar({tabnr}, {varname} [, {def}])				*gettabvar()*
		Get the value of a tab-local variable {varname} in tab page
		{tabnr}. |t:var|
		Tabs are numbered starting with one.
		The {varname} argument is a string.  When {varname} is empty a
		dictionary with all tab-local variables is returned.
		Note that the name without "t:" must be used.
		When the tab or variable doesn't exist {def} or an empty
		string is returned, there is no error message.

Also same issues with settabvar().

Milly added a commit that referenced this issue Aug 29, 2024
Milly added a commit that referenced this issue Sep 6, 2024
@lambdalisue
Copy link
Member

lambdalisue commented Sep 6, 2024

Not tested but I think we can use win_getid, win_execute like

function! s:gettabopt(tabnr, varname, def) abort
  let l:winid = win_getid(1, a:tabnr)
  let l:result = win_execute(l:winid, printf('echo &l:%s', a:varname))
  return empty(l:result) ? a:def : l:result
endfunction

function! s:settabopt(tabnr, varname, val) abort
  let l:winid = win_getid(1, a:tabnr)
  call win_execute(l:winid, printf('let &l:%s = %s', a:varname, string(a:val)))
endfunction

@Milly
Copy link
Contributor Author

Milly commented Sep 16, 2024

Not tested but I think we can use win_getid, win_execute like

These not work. It always returns the value of the current tab page.
Currently Vim does not seem to have a way to get/set local tab options other than actually switching tab pages.

The following works:

function! s:gettabopt(tabnr, varname) abort
  let l:winid_save = win_getid()
  let l:lazyredraw_save = &lazyredraw
  try
    set lazyredraw
    execute a:tabnr 'tabnext'
    let l:result = a:varname->printf('&l:%s')->eval()
    return l:result
  finally
    call win_gotoid(l:winid_save)
    let &lazyredraw = l:lazyredraw_save
  endtry
endfunction

But has side effects (We can add more redundant state saving code):

setglobal cmdheight=1
tabnew
setlocal cmdheight=5
tabnew
1tabnext
echo tabpagenr('#')
" -> 3
echo s:gettabopt(2, 'cmdheight')
" -> 5
echo tabpagenr('#')
" -> 2

And causes an update of the GUI screen.
(CUI screen updates seem to be blocked by 'lazyredraw'.)

@Milly
Copy link
Contributor Author

Milly commented Sep 21, 2024

vim/vim#15713 fixes this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants