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

Keybinding prints key when switching to editable view. #65

Closed
thekeymaker opened this issue Oct 26, 2016 · 7 comments
Closed

Keybinding prints key when switching to editable view. #65

thekeymaker opened this issue Oct 26, 2016 · 7 comments
Assignees
Milestone

Comments

@thekeymaker
Copy link

thekeymaker commented Oct 26, 2016

I am trying to write some code that edits a view with vim like key-bindings. The problem I am running into is the key I press is also getting inserted. I have put together some test code to hopefully explain better.

package main

import (
    "log"
    "github.com/jroimartin/gocui"
)

func edit(g *gocui.Gui, v *gocui.View) error {
    v.Editable = true
    return nil
}

func quit(g *gocui.Gui, v *gocui.View) error {
    return gocui.ErrQuit
}

func keybindings(g *gocui.Gui) error {
    if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil {return err}
    if err := g.SetKeybinding("main", 'i', gocui.ModNone, edit); err != nil {return err}

    return nil
}


func layout(g *gocui.Gui) error {
    maxX, maxY := g.Size()
    if v, err := g.SetView("main", 30, -1, maxX, maxY); err != nil {
        if err != gocui.ErrUnknownView {
            return err
        }

        v.Editable = false
        v.Wrap = true
        if _, err := g.SetCurrentView("main"); err != nil {return err}
    }
    return nil
}

func main() {
    g, _ := gocui.NewGui()
    defer g.Close()

    g.SetManagerFunc(layout)
    keybindings(g); 
    g.Cursor = true

    if err := g.MainLoop(); err != nil && err != gocui.ErrQuit {log.Panicln(err)}
}

What happens is when I press the 'i' key to change the main view from not-Editable to Editable it also inserts an i character. Is there a way to prevent this?

Thank you for any help!

@jroimartin
Copy link
Owner

jroimartin commented Oct 26, 2016

Other people requested this behaviour before (#54 (comment)) and after some tests I think it's good change. So, PR #66 should fix it, can you check?

Thanks! :)

@jroimartin
Copy link
Owner

jroimartin commented Oct 26, 2016

BTW take into account that after this change if any keybinding matches the event, its handler is executed and the edition step is skipped. It means that, in your example, if you want to type i after making the view Editable, you will need to delete the keybinding.

if err := g.DeleteKeybinding("main", 'i', gocui.ModNone); err != nil {
        return err
}

Maybe this behaviour could be configurable if there is a rationale for that.

@thekeymaker
Copy link
Author

I can defiantly try this out and get back to you later today. Thanks for the changes.

@thekeymaker
Copy link
Author

thekeymaker commented Oct 26, 2016

That looks good for me. Your right, with this new commit I would have to assign the key again if I ever wanted that functionality back. Here is my previous code modified to do just that and works with your new commit:

package main

import (
    "log"
    "github.com/jroimartin/gocui"
)

func edit(g *gocui.Gui, v *gocui.View) error {
    v.Editable = true

    if err := g.DeleteKeybinding("main", 'i', gocui.ModNone); err != nil { return err }

    return nil
}

func escape_edit(g *gocui.Gui, v *gocui.View) error {
    v.Editable = false

    if err := g.SetKeybinding("main", 'i', gocui.ModNone, edit); err != nil {return err}

    return nil
}

func quit(g *gocui.Gui, v *gocui.View) error {
    return gocui.ErrQuit
}

func keybindings(g *gocui.Gui) error {
    if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil {return err}
    if err := g.SetKeybinding("main", 'i', gocui.ModNone, edit); err != nil {return err}
    if err := g.SetKeybinding("main", gocui.KeyEsc, gocui.ModNone, escape_edit); err != nil {return err}

    return nil
}


func layout(g *gocui.Gui) error {
    maxX, maxY := g.Size()
    if v, err := g.SetView("main", 30, -1, maxX, maxY); err != nil {
    if err != gocui.ErrUnknownView {
        return err
    }

    v.Editable = false
    v.Wrap = true
    if _, err := g.SetCurrentView("main"); err != nil {return err}
    }
    return nil
}

func main() {
    g, _ := gocui.NewGui()
    defer g.Close()

    g.SetManagerFunc(layout)
    keybindings(g); 
    g.Cursor = true
    g.InputEsc = true

    if err := g.MainLoop(); err != nil && err != gocui.ErrQuit {log.Panicln(err)}
}

I think this is an improvement because it always mean the key handler will capture that key unless the handler doesn't exist. Although, I do agree with your last comment that it may be nice to have the ability to change this functionality based on the situation.

Maybe another argument to the SetKeybinding() function to either capture or pass through the key press???

Don't know but like I said, I think this is an improvement. Thanks!

@jroimartin
Copy link
Owner

Let's keep it simple for now. At some point, if needed, we can add a Passthrough field to View.

BTW for your specific case, you can use the Editor interface to implement a custom edition mode. For instance, the following snippet shows how to create a simple vim editor:

https://gist.github.com/jroimartin/1ac98d3da7278fa18866c9cae0af6007

@jroimartin
Copy link
Owner

PR #67 is also related.

@thekeymaker
Copy link
Author

Cool! I will have to take a look at that. Thanks for the help. It looks like you merge this change into master so you can close this issue if it isn't still in progress.

Cheers!

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

No branches or pull requests

2 participants