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

[WIP] add popup support #748

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
Open

Conversation

prabirshrestha
Copy link

@prabirshrestha prabirshrestha commented Jun 28, 2020

PR for #747. This PR is at a very early stage so will need lot of revisions but starting a thread so folks can start contributing and looking at it and provide feedback.

Goal is to have a consistent api that works on both vim and neovim. It is also meant to be very dumb api where other powerful popup manager can be built on top. It is also meant to easily work with lua apis hence it uses id

  • documentation
  • tests
  • new({}) to create popup
  • close(id)
  • pos: 'topleft|topright|bottomleft|bottomright|topcenter|bottomcenter'
  • hide(id)
  • show(id)
  • contents(['line1', 'line2']) to update popup text
  • border support
  • custom border chars support
  • add options() to move, resize popup.
  • scrollbars??
  • title
  • fixed width/height
  • max/min width/height
  • auto width/height
  • custom buffer settings such as linenumbers/syntax onoff/wrap onoff
  • terminals are special
    ... and many more... feel free to suggest

Events

  • create event
  • close event
  • hide event
  • show event
  • options event
  • add before and after events. either beforeshow aftershow or preshow postshow.
let s:V = vital#vital#new()
let s:Popup = s:V.import('Experimental.UI.Popup')

let s:id = s:Popup.create({
    \ 'contents': ['This', 'is', 'a', 'line'],
    \ 'w': 5,
    \ 'h': 5,
    \ 'x': 1,
    \ 'y': 1,
    \ 'pos': 'topleft',
    \ })

call timer_start(2000, {->s:Popup.close(s:id)})

@prabirshrestha
Copy link
Author

Since neovim and vim using different position. I'm now using x, y instead. Also added support for pos: 'topleft|topright|bottomleft|bottomright|topcenter|bottomcenter'.

Simple way to check the position is using this file.

A0123456789
B0123456789
C0123456789
D0123456789
E0123456789
F0123456789
G0123456789
H0123456789
I0123456789
J0123456789

Then run this code

let s:V = vital#vital#new()
let s:Popup = s:V.import('Experimental.UI.Popup')

call s:Popup.create({
    \ 'contents': ['XXXX', 'XXXX', 'XXXX', 'XXXX'],
    \ 'w': 4,
    \ 'h': 4,
    \ 'x': 5,
    \ 'y': 5,
    \ 'pos': 'topcenter',
    \ })

call cursor(5, 5)

Here is how topcenter looks like. Cursor is at E3 and X is the popup contents.

image

@prabirshrestha
Copy link
Author

prabirshrestha commented Sep 19, 2020

Added support for events. One can use either generic on_event where all events are fired if it exists or register to specific events by explicitly prefixing with on_* where * is the event name.

function! s:on_event(id, data, event) abort
    echom a:event
endfunction

let s:pid = s:Popup.create({
    \ 'contents': ['XXXX', 'XXXX', 'XXXX', 'XXXX'],
    \ 'w': 4,
    \ 'h': 4,
    \ 'x': 5,
    \ 'y': 5,
    \ 'pos': 'topcenter',
    \ 'on_create': {id, data, event->timer_start(2000, {->s:Popup.close(id)})},
    \ 'on_event': function('s:on_event'),
    \ })

Feel free to review the code.

@prabirshrestha
Copy link
Author

added contents() api to change the contents of the popup and options() api to move and resize the popup. https://asciinema.org/a/360796
popup resize and move

let s:V = vital#vital#new()
let s:Popup = s:V.import('Experimental.UI.Popup')

function! s:update(id) abort
    call s:Popup.contents(a:id, ['hello', 'world'])
    call s:Popup.options(a:id, { 'w': 10, 'h': 10, 'x': 2, 'y': 2 })
    call timer_start(2000, {->s:Popup.hide(a:id)})
endfunction

function! s:on_event(id, data, event) abort
    if a:event ==# 'show'
        call timer_start(1000, {->s:update(a:id)})
    endif
endfunction

let s:pid = s:Popup.create({
    \ 'contents': ['XXXX', 'XXXX', 'XXXX', 'XXXX'],
    \ 'w': 4,
    \ 'h': 4,
    \ 'x': 5,
    \ 'y': 5,
    \ 'pos': 'topcenter',
    \ 'on_event': function('s:on_event'),
    \ })

@subnut
Copy link

subnut commented Oct 23, 2020

I'm now using x, y instead

x and y with respect to? Starts from 0 or 1 or something else?

E.g. in neovim, the indexing for window placement starts from (0, 0) (which is how I represent ('width', 'height') )
and that represents the top-left corner of the screen.

In the same way, which corner of the screen do you start your co-ordinates from, and what value it starts from? Also, just being sure, by x you mean the width, right? And y for height?

Just for clarity

@prabirshrestha
Copy link
Author

Currently I use _user_to_editor_xy to normalize with different editors. I personally do not have strong opinion on if we want to use vim or neovim position. We should stick with one. I have been trying to make the api either complelty like vim or neovim so I can tell someone to just go and read one of those docs and should be simple. for example xy starts with 1 in vim so I chose pos as topleft. I will document this in code so it is easy to follow.

x is width and y is height. If you have better suggestions let me know. vim uses line and col. this was one exception I did with the above rule I mentioned since line and col sounds as if we can't have a popup above status line and only applies to inside a buffer..

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.

2 participants