Vi in Go

ViGo - Vi in Go

Build Status

ViGo is an attempt to implement a vim-like text editor in Go, while maintaining a lean feature set. The project is still in its early days and definitely not suitable for daily use yet.

It's based on nsf's religious godit

Contributing

ViGo is still in its early days, though contributions are welcome. In order to get started, you will first need to fork the respository.

Due to the way that golang imports work, the way you work on the project will differ slightly to other Github projects. Instead of cloning your fork locally, you will instead need to clone the original repository in $GOPATH/src/github.com/kisielk/vigo/. It is important that it be at this path, and all the imports in the application will look for packages here. You can clone the project using git, or simply run go get github.com/kisielk/vigo/.

Once you have the repository at the above location, you will need to add your fork as a git remote. You can do this with the following command: git remote add fork <url of your fork>. Now, when you work on a feature, you can push to your fork, create a pull request, and then update from origin when your change is merged.

The complete workflow could be:

$ cd $GOPATH
$ go get github.com/kisielk/vigo/
$ cd src/github.com/kisielk/vigo/
$ git remote add fork <url of your fork>
#* hack hack hack*
$ git push fork
# create github pull request
$ git pull origin master

Building

In the project directory, you can build ViGo by running go build. This will produce a vigo binary which you can run with ./vigo.

Owner
Comments
  • Search implementation

    Search implementation

    This is a question more than an issue. I'm thinking that having search functionality would be a good next step for the editor, and have an implementation question.

    I know that there is the concept of a mode, and also an overlay, so I'm wondering if it would be correct to implement search as both a mode and an overlay. It will need the capture the cursor (as an overlay) in order to allow the search term to be entered, then the navigating of search results will be contained in the mode (pressing n to go to next occurrence etc).

    Does that sound somewhat sensible? Wanted to get some thoughts before proceeding.

  • Added visual mode

    Added visual mode

    This adds visual mode selection and movement and ability to delete selection.

    It uses the viewTag data structure to manipulate the selection, and stores it in View.VisualRange.

    Let me know what you think!

  • Add CtrlG command - show file status

    Add CtrlG command - show file status

    Show information on the current file in the status buffer.

    Information shown is:

    • file path
    • number of lines
    • position in the file as a percentage (from the top line)
  • Enhancement: Add some more advertising :)

    Enhancement: Add some more advertising :)

    I couldn't find this repo although I tried really hard and even needed to bother guys from godit with a question about adding vi-like key-bindings and behavior :)

    I would suggest to write to the README file at least (!) the keywords text, editor, vim (not only vi) and certainly ask guys from cat-v to add link to this repo to the page http://go-lang.cat-v.org/go-code to gain more attention. I guarantee, that there ale plenty other vi-fans which would surely want to try out (and improve) this editor!

  • Configuration options

    Configuration options

    Is it too early to start looking at how to specify external configuration? The vigo equivalent of a .vimrc?

    Not sure if you guys have thought about this already. Personally, I think it would be cool to have some kind of python API that would allow certain parts of the editor to be customized. For instance, to bind a key:

    from vigo.keys import bind_key
    from vigo.commands.movement import center_line
    
    bind_key("CtrlL", center_line)
    

    Or something simpler like a JSON file, which would be more like how Sublime Text does it.

    {"keys": ["CtrlL"], "command": "center_line"}
    

    The idea being then that either the file is evaluated when the editor is started, or if JSON then just loaded into memory, and when it comes to handle an event, we add an extra step which would first check the loaded config options, otherwise it will do whatever the default is.

    These are just ideas, wanted to get some thoughts and opinions. If you've already thought about this, what way had you planned?

  • Add dedicated Selection class; make view track active selection.

    Add dedicated Selection class; make view track active selection.

    First of all, big thanks to @gchp for the initial work. I wish I thought about this stuff during the original review, rather than after the fact. I have not yet removed any code to simplify the review.

    Selection gives us an abstraction over a couple of implementation details

    • Selection can be more complex than a non-interrupted buffer range (eg. block selection; we'll likely need a list of ranges to implement this). Separating overall selection and resulting buffer range(s) concepts creates a nice point where we can take care of all the grizzly conversion details (see EffectiveRange()) For instance, selection works on inclusive ranges, while normally ranges are end-exclusive.
    • Having view update the selection as cursor is moved around makes sure the two don't get out of sync and removes the need for separate adjustment commands.

    The change also attempts to make more use of Cursor object as opposed to line/offset arguments. Working with cursors is useful because some routines rely on Line field (eg. ExtractBytes), which is otherwise absent.

  • Converted snake_case identifiers to idiomatic go camelCase. A few other minor changes.

    Converted snake_case identifiers to idiomatic go camelCase. A few other minor changes.

    I also unexported all the identifiers because eventually we might end up pulling some of the code out to expose in an API pkg. This will help avoid confusion later. Besides there is no reason to export identifiers in a non importable pkg anyways.

    Also I added a sleep(10 * time.Millisecond) in the termbox loop right after we flush the buffer to smooth out the cursor keystroke.

  • Added initial search functionality

    Added initial search functionality

    When you press / in normal mode, you enter the new SearchMode, which simply allows you to enter your search term, and then stores that term in Editor.LastSearchCommand.

    Then, when you press n or N in normal mode, it will use the Search command from commands/search.go.

    Let me know if you have any feedback / thoughts on this. I think it works pretty well, and that it is open enough for other commands to make use of it, like you mentioned in #20

    Thanks!

  • Add basic contribution guide

    Add basic contribution guide

    Just some simple instructions on how to go about working on the project. We can probably flesh this out more in the future, but I think it's good to have something there for now.

  • Add change and delete to end of line commands

    Add change and delete to end of line commands

    Added "Change to end of line" and "Delete to end of line" to normal mode.

    Both commands use the same function, the difference being that "change" also changes the editor mode to Insert.

  • Small bugfixes

    Small bugfixes

    Just some small fixes for issues I came across earlier today.

    • Fix crash in command mode when you press enter without giving a command. It was dying because it expected a command and an argument.
    • Fix status message when you try move past the start / end of a line
    • Corrected a comment
  • Edit multiple files, move between buffers

    Edit multiple files, move between buffers

    Looks like you've not had much time to work on this project, but this is a very interesting and it would be a shame to see it stall here. Maybe I can help out.

    I find most of the basic functionality I use in vim is there, with the seeming exception of being able to edit multiple files and switch between buffers. It looks as if vigo opens multiple files if specified on the command line... but then no way to switch between the buffers ? Maybe I'm missing something, but I did read through the code and did not find that functionality anywhere.

  • What is Enter?

    What is Enter?

    So, we have a method Enter on all our Modes - but it is only implemented once and it doesn't seem idomatic - (but rather quite literal: what happens when you press Enter). I figure it should be more general -> What happens when you enter the mode.

    Where should we go from here?

  • Add documentation for modes

    Add documentation for modes

    Each of the modes should have som documentation. What they are are pretty obvious to a VI/VIM user for some of them (NormalMode, InsertMode, VisualMode) others are not so clear: WindowMode, TextObjectMode.

    also gives a change to validate if they should all be modes (no clue - don't quite grok Window and TextObjectMode yet)

  • Change how status strings are formated and printed

    Change how status strings are formated and printed

    • update the status, Name and Path on a buffer you Save as (currently, it will change you to the new file if you save to a new file. this will be shown in the status)
    • Kinda borked the dirty flag display - so that needs to be fixed.
    • need to refactor the reused code on Editor, view and context.
    • Dynamically load template strings?

    this is for issue #42

    Not ready yet - Comments wanted

  • in OSX, pasting freezes vigo

    in OSX, pasting freezes vigo

    Not sure what is causing it - Done this with URLS and free text

    Also - it pastes backwards and freezes before the input is done on long inputs

    however, i've managed to crash it with the input done

    panic: runtime error: slice bounds out of range
    goroutine 22 [running]: runtime.panic(0x10d860, 0x1e432f)
    /usr/local/Cellar/go/1.3/libexec/src/pkg/runtime/panic.c:279 +0xf5
    github.com/kisielk/vigo/buffer.(*Cursor).VoffsetCoffset(0x22083f3f20, 0x0, 0x0)
    /Users/someuser/go/src/github.com/kisielk/vigo/buffer/cursor.go:135 +0x117
    github.com/kisielk/vigo/view.(*View).MoveCursorTo(0x208298000, 0x208250570, 0x1, 0x6)
    /Users/someuser/go/src/github.com/kisielk/vigo/view/view.go:718 +0x16c
    github.com/kisielk/vigo/view.(*View).bufferEventLoop(0x208298000)
    /Users/someuser/go/src/github.com/kisielk/vigo/view/view.go:321 +0x15a
    created by github.com/kisielk/vigo/view.(*View).Attach
    /Users/someuser/go/src/github.com/kisielk/vigo/view/view.go:309 +0x1b0
    goroutine 16 [select]: github.com/kisielk/vigo/editor.(*Editor).Loop(0x208286140, 0x0, 0x0)
    /Users/someuser/go/src/github.com/kisielk/vigo/editor/editor.go:384 +0x257
    main.main()
    /Users/someuser/go/src/github.com/kisielk/vigo/main.go:29 +0x1ec
    goroutine 19 [finalizer wait]: runtime.park(0x14200, 0x1e7610, 0x1e69c9)
    /usr/local/Cellar/go/1.3/libexec/src/pkg/runtime/proc.c:1369 +0x89
    runtime.parkunlock(0x1e7610, 0x1e69c9)
    /usr/local/Cellar/go/1.3/libexec/src/pkg/runtime/proc.c:1385 +0x3b
    runfinq()
    /usr/local/Cellar/go/1.3/libexec/src/pkg/runtime/mgc0.c:2644 +0xcf
    runtime.goexit()
    /usr/local/Cellar/go/1.3/libexec/src/pkg/runtime/proc.c:1445
    goroutine 20 [syscall]:
    os/signal.loop()
    /usr/local/Cellar/go/1.3/libexec/src/pkg/os/signal/signal_unix.go:21 +0x1e
    created by os/signal.init·1
    /usr/local/Cellar/go/1.3/libexec/src/pkg/os/signal/signal_unix.go:27 +0x32
    goroutine 21 [select]:
    github.com/nsf/termbox-go.func·001()
    /Users/someuser/go/src/github.com/nsf/termbox-go/api.go:86 +0x41a
    created by github.com/nsf/termbox-go.Init
    /Users/someuser/go/src/github.com/nsf/termbox-go/api.go:105 +0x81b
    goroutine 23 [select]:
    github.com/nsf/termbox-go.PollEvent(0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
    /Users/someuser/go/src/github.com/nsf/termbox-go/api.go:244 +0x396
    main.func·001()
    /Users/someuser/go/src/github.com/kisielk/vigo/main.go:26 +0x27
    created by main.main
    /Users/someuser/go/src/github.com/kisielk/vigo/main.go:28 +0x1d9
    
Related tags