Git Product home page Git Product logo

badavi's Introduction

badavi

Build Status

badavi is a vi-like terminal mode text editor, implemented in C and using the termbox library to draw to the terminal.

It's meant to be a learning exercise and fun project to hack on rather than a serious day-to-day editor, although who knows where it'll end up.

Features supported so far

  • Normal, insert, and visual modes.

  • Motions -- h, j, k, l, 0, $, ^, {, }, b, B, w, W, e, E, G, g_, ge, gE, gg, %, and more. Motions can be prefixed with an optional count.

  • : commands -- :w [path], :wq, :q, :e path and more.

  • Split windows with :split (horizontal) and :vsplit (vertical). You can navigate between them with <C-w> hjkl, resize the current window with <C-w> + and <C-w> -, and equalize the layout with <C-w> =.

  • Delete (d), change (c) and yank (y) operators, which can be applied to any of the motions, or the visual mode selection. (Text objects aren't implemented yet). The affected region is saved into the unnamed register, used by p to paste text. Named registers from a to z are also implemented, and can be specified by prefixing the operator (or p) with "a through "z.

  • Undo (u) and redo (<c-r>) (only single-level for now, unlike vim).

  • ctags support -- on startup badavi looks for a tags file called tags in the current directory ('tags' option not supported yet). The :tag command jumps to the specified tag, and <c-]> jumps to the tag of the word under the cursor. <c-t> and :tag can be used to walk up and down the tag stack. The -t command line option can also be passed in to start editing at the given tag, as in e.g. badavi -t main.

  • A small subset of the options are implemented. You can manipulate them with :set, :setlocal and :setglobal. These commands accept a similar syntax as vim, e.g. :set number, :set number!, :set nonumber, :set number?, etc. Options can be read from a file with :source path. At startup a file called ~/.badavimrc is sourced.

  • Search forwards with /, backwards with ?. Standard POSIX regexes are used, so the syntax is not exactly the same as vim's. For instance, word boundaries are specified with [[:<:]] and [[:>:]] instead of \< and \>. n and N can be used to cycle through matches. * and # can be used to search forwards or backwards for the next occurrence of the word under the cursor. Searching is a motion, so it works with the operators. The 'incsearch' and 'hlsearch' options are also implemented.

Building

Just run make.

License

MIT -- see LICENSE file for details.

badavi's People

Contributors

isbadawi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

viegasfh

badavi's Issues

Special registers

From :help registers

  • 1. The unnamed register ""
  • 2. 10 numbered registers "0 to "9
  • 3. The small delete register "-
  • 4. 26 named registers "a to "z or "A to "Z (although we don't support the uppercase form)
  • 5. Three read-only registers ":, "., "%
  • 6. Alternate buffer register "#
  • 7. The expression register "=
  • 8. The selection and drop registers "*, "+ and "~
  • 9. The black hole register "_
  • 10. Last search pattern register "/

Horizontal splits

Not any harder to implement than vertical splits.
Main open question is the best way to go up, down, left, right. It's easy now with a singly linked list going left to right.

Replace mode

5. Replace mode                         *Replace* *Replace-mode* *mode-replace*

Enter Replace mode with the "R" command in normal mode.

In Replace mode, one character in the line is deleted for every character you
type.  If there is no character to delete (at the end of the line), the
typed character is appended (as in Insert mode).  Thus the number of
characters in a line stays the same until you get to the end of the line.
If a <NL> is typed, a line break is inserted and no character is deleted.

Be careful with <Tab> characters.  If you type a normal printing character in
its place, the number of characters is still the same, but the number of
columns will become smaller.

If you delete characters in Replace mode (with <BS>, CTRL-W, or CTRL-U), what
happens is that you delete the changes.  The characters that were replaced
are restored.  If you had typed past the existing text, the characters you
added are deleted.  This is effectively a character-at-a-time undo.

If the 'expandtab' option is on, a <Tab> will replace one character with
several spaces.  The result of this is that the number of characters in the
line increases.  Backspacing will delete one space at a time.  The original
character will be put back for only one space that you backspace over (the
last one).  {Vi does not have the 'expandtab' option}

Indenting

autoindent, smartindent, expandtab, shiftwidth, tabstop, softtabstop...

variants of :set command

Right now we support these

  • :set opt: set boolean option to true, or show value of int or string option
  • :set noopt: set boolean option to false
  • :set opt=val: set string or int option to value
  • :set opt!: toggle boolean option
  • :set opt?: show value of option

According to :help set-option, vim also supports these

  • :set: show all options that differ from default -- done in 9ed92f1
  • :set all: show all options (except terminal options) -- done in 9ed92f1
  • :set termcap: show terminal options
  • :set invopt: same as :set opt!
  • :set opt&: reset option value to default -- done in b97a8f8
  • :set opt&vi, :set opt&vim: reset to vi default or vim default
  • :set all&: reset all option values to default (with a few exceptions)
  • :set opt:val: same as :set opt=val
  • :set opt+=val: increment int option, append string option. If string option is a comma separated list, adds a comma, also makes sure there's no duplicate -- done in e7e27cf
  • :set opt^-=val: multiply int option, prepend string option.
  • :set opt-=val: decrement int option, remove value from string option
  • :set multiple options at the same time
  • :set is also affected by the 'verbose' option and can print information about where an option was last set

Most of these make sense to add, except maybe :set opt&vi, :set opt&vim, :set termcap

Visual mode

Need a way for modes to affect the drawing.
(Could also use this to draw the cursor in / and : modes.)

Line wrapping

Especially now with splits, horizontal scrolling is kind of lame.

Isolate termbox dependency

There are references to termbox sprinkled throughout the code. Could imagine a struct terminal with function pointers wrapping the termbox api.
One advantage would be that we could set up a mock terminal for testing. This would let us test the code in draw.c, and also clean this up:

badavi/draw.c

Lines 351 to 357 in 63feceb

// FIXME(ibadawi): Hack to make the tests run.
// If termbox wasn't initialized (like in the tests), let's not try to draw,
// because we can hit a segfault when we try to access the tb_cell buffer.
// (search_motion() calls editor_draw(), which is why the tests draw).
if (tb_width() == -1) {
return;
}

ctags support

ctags format is not hard to parse. Can at least implement badavi -t, :tag, and the tag stack.

Don't leak memory in tests

It would be nice to get useful output out of LSan in the tests, but there's a lot of noise because the tests themselves allocate things without freeing. Some leaks could maybe be suppressed (e.g. LSAN_OPTIONS=suppressions=<(echo "leak:test_*__initialize")) but it would be better to fix.

Some structs like editor, buffer, gapbuf don't have free functions because they stay around for the life of the program (for now), so those would have to be added.

Text objects

Easy to implement -- just don't want to have too much duplication with motion code.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.