Chapter 1: Introduction

Background and Motivation

With the world shrinking to become one global village, with the leading MNCs of the world exalting the need for Virtual Teams and with heavy emphasis on dividing a problem into sub-problems, each to be handled in parallel, Real-time Collaboration has become simply inevitable. As such, there is a surge in demand for solutions which can help in real-time collaboration rather than the traditional method of granting access to only one user at a time for doing his work and then passing the floor to the next user. It does not come as a surprise that Google is already creating the Waves in the field of Real-time Collaboration.

In the past, the emphasis was on Non-real time collaborative systems like Microsoft Sharepoint, SunForum etc. Although these applications allowed multi users to work on a single document concurrently but being non-real time, only one user could hold the lock to edit the document at a time and the other users were held waiting. This defies the actual concept of "collaboration" which has to be mutual i.e. interaction between all parties involved. Many researchers from across the globe have been working to address this issue. For instance, CoWord and CoPowerPoint are the recent innovations which serve as a solution to the problem raised above. The collaboration technique used here does not modify the original application, but rather exploits the Microsoft APIs to build collaboration on top of Microsoft Word and PowerPoint. A similar approach would be used by the author to extend functionalities to CoVIM - a multi-user collaborative version of single user text editor called VIM.

Project Objectives

The main purpose of this project is to fully convert a single-user text editor called VIM into a multi-user collaborative application called CoVIM. Being an on-going project carried forward from previous FYP student, the focus of the author's project is to incorporate various new features in CoVIM application. The scope of the project is as follows:

  1. Understanding of various user modes in VIM
  2. Familiarisation with VIM Script to use its API (Application Programming Interface) for implementation of new functionalities in CoVIM
  3. Studying, adapting and extending the technical approaches used to design Insert and Normal Mode to design Replace Mode for CoVIM
  4. Stress-testing the system from the user's point of view


CoVim is an on-going project aimed to overcome its limitations with continuous research and future developments. At present, the complexity of Vi script and limitation of time has given rise to following limitations:

  1. Lack of incorporation of all the fundamental 7 Modes of Vim into CoVIM
  2. Lack of concept of privileged users
  3. Inability to exactly replicate all user actions (e.g. Ctrl+Backspace)
  4. Inability to track mouse events


In terms of the Resources utilization, the Project is not very expensive. Both the hardware and the software required for the completion of Project are easily available. The software is charity-ware and easily downloadable.


  1. 2 or more personal Computers for Testing
  2. LAN infrastructure


  1. gVIM 7.2 for understanding the working of VIM software, editing of Vim Script and user testing.

Report Organization

The Report has been divided into several chapters:

  • Chapter 1 is the prelude to the report expressing the author's motivation, project's overview, scope, resources and limitations.
  • Chapter 2 accredits the previous research work already done in the field of the project
  • Chapter 3 gives the reader a basic background of functions and features of VIM.
  • Chapter 4 introduces the collaborative technique used to develop CoVIM and the system architecture for the same
  • Chapter 5 elaborates the mechanisms to incorporate Replace Mode in CoVIM
  • Chapter 6 illustrates various Test Cases and the system's response to the same
  • Chapter 7 concludes the report by listing future recommendations for further improvement of CoVIM.

Chapter 2: Literature Review

For long, the world has realized the need for real-time collaborating techniques to turn single user applications into multi user applications. This chapter would accredit the prior work that has been done in this area and the highlight the concepts that would be applied in the implementation of CoVim.

Prior Work

Sun et al (2006) recognises the previous work that has been done in this field and has classified them on the basis of their approach to create multi-user applications out of single-user applications. According to this classification, following approaches exist:

Generic Application Sharing with Centralized Architecture

The generic-application sharing approach has been modelled after a chalkboard used during meetings. Following are the three fundamentals of this approach:

  1. Strict WYSIWIS (what you see is what I see): All the users of the shared application see the same thing at a time
  2. Sequential interaction paradigm: Only one user is the current holder of the floor i.e. only one user can interact with the application at a time.
  3. Centralized architecture: Only one instance of shared application is running in the system

However, these basic fundamentals are a hindrance to the collaborative work that requires free and concurrent interactions. Moreover, a centralized architecture also leads to poor responsiveness and inefficient network usage.

Generic Application Sharing with Replicated Architecture

This approach attempts to replace the centralized architecture with a Replicated architecture wherein there are multiple instances of the shared application in the system. However, Technical challenges associated with replication like consistency maintenance of the state and view of the shared application, management of external resources (e.g., files, clocks, and network connections) and support for spontaneous interactions (e.g., accommodating late-comers) remain an open challenge to solve under the constraints of generic application sharing environments.

Component Replacement Approach

Flexible JAMM (Java Applets Made Multiuser) spearheaded this approach. The implementation is based on an object-oriented replicated architecture where certain single-user interface objects are dynamically replaced by multi-user extensions to allow for simultaneous editing. This approach brought about a paradigm shift in seeking generic solutions at the operating system level to exploring solutions at the application interface library level. Although this approach allows for concurrent work, relaxed WYSIWIS, flexible control, however it requires the application platform to have capabilities like process migration, runtime object replacement, and dynamic binding, which are not provided in many systems. Moreover, the coordination policies are embedded in the substituted collaboration-aware runtime environment of the single-user application, which according to Furuta and Stotts and Li etc is a major source of inflexibility.

Transparent Adaptation Approach

This is an innovative approach to Leveraging single-user applications for supporting multi-user collaboration. Sun et al. (2006) explains that this approach has the potential to significantly increase the availability and improve the usability of collaborative applications. The underlying fundamental of TA approach is to convert existing and new single-user applications into collaborative ones, without changing the source code of the original application. The cornerstone of the TA approach is the operational transformation (OT) technique and the method of adapting the single-user application programming interface to the data and operation models of OT. The aim is to not only retain the functionalities and "look-and-feel" of the single-user counterparts of the shared application, but also provide advanced multi-user collaboration capabilities for supporting multiple interaction paradigms, ranging from concurrent and free interaction to sequential and synchronized interaction, and for supporting detailed workspace awareness, including multi-user telepointers and radar views. The TA approach and generic collaboration engine software component developed from this work are potentially applicable and reusable in adapting a wide range of single-user applications. Using this technique, CoWord, CoMaya, CoPowerpoint have already been developed and this project report would extend the TA approach to develop CoVim. The fundamentals underlying this approach are as follows:

  1. Transparent: TA uses the single-user application API and its execution environment to intercept and replay users' interaction so that it does not need to access or change the application source code, thus being transparent to the application.
  2. Adaptation: Application API must be adaptable to data and operational models of OT technique
  3. Replicated architecture: Similar to component-replacement approach, the same instance of document is replicated at different collaborating sites so as to provide each user their own view of the document. This also allows local operation to take effect instantaneously at local site before propagating to other collaborating sites. The consistency maintenance problem that comes with the use of replicated architecture would be handled by the OT technique as described in the following section

As a result of the above mentioned design considerations, Sun et al (2006) describes that collaborative applications based on the TA approach are able to achieve fast local response, concurrent work, relaxed WYSIWIS viewsharing and detailed workspace awareness - the up-to-the-moment understanding of other users' interactions with a shared workspace in order to coordinate users' activities.

Operational Transformation (OT)

Operational transformation(OT) is a technology for supporting a range of collaboration functionalities in advancedgroupwaresystems. OT was originally invented for consistency maintenance andconcurrency controlin collaborative editing of plain text documents. Two decades of research has extended its capabilities and expanded its applications to include group undo, locking, conflict resolution, operation notification and compression, group-awareness, HTML/XML and tree-structured document editing, collaborative office productivity tools, application-sharing, and collaborative computer-aided media design tools. Recently, OT has been adopted as a core technique behind the collaboration features inGoogle Wave, which is taking OT to a new range of web-based applications.

Collaborative systems using OT typically adopt a replicated architecture for the storage of shared documents to ensure good responsiveness in high latency environments, such as the Internet. The shared documents are replicated at the local storage of each collaborating site, so editing operations can be performed at local sites immediately and then propagated to remote sites. Remote editing operations arriving at a local site are typically transformed and then executed. The transformation ensures that application-dependent consistency criteria are achieved across all sites. The lock-free, non-blocking property of OT makes the local response time not sensitive to networking latencies. As a result, OT is particularly suitable for implementing collaboration features such as group editing in the Web/Internet context.

The basic idea of OT is to transform (or adjust) the parameters of an editing operation according to the effects of previously executed concurrent operations so that the transformed operation can achieve the correct effect and maintain document consistency. It can be illustrated by the following example:

  1. Given a replicated text document containing string "abc" at two collaborating sites.
  2. Site 1 generates an independent operation O1 = Insert[0, "x"], which is to insert character "x" at position 0.
  3. Site 2 concurrently generates another independent operation O2 = Delete[2, "c"], which is to delete character "c" at position 2. (Assume index to start from 0)
  4. Suppose at Site 1, operations are executed in the order of O1 and O2, thus after execution of O1, the document would contain the string "xabc".
  5. Suppose Site 1 executes O2 directly without any manipulation to the operation, it would incorrectly delete the text at position 2, which is character "b" instead of "c", thus resulting in the string "xac" instead of "xab".
  6. However, with OT, Site 1 would transform O2 against O1, which result in O2 being transformed into Delete[3, "c"], where the position parameter is incremented by 1 to take into consideration the impact of previous operation of inserting 1 character into the document. Thus, through proper transformation of an operation, document at Site 1 would correctly contain "xab" which is the intended end result.

There exist two underlying models in each OT system:

  1. Data model that defines the way data objects in a document are addressed by operations. For e.g., the most fundamental data model is single linear address space.
  2. Operation model that defines the set of operations that can be directly transformed by OT functions. The most fundamental operation model consists of two primitive operations (PO): character-wise insert and delete.

Chapter 3: Introduction to VIM

VIM: What is VIM?

VIM is a text-editor which does not only have all commands from the Unix program called Vi, but many new powerful commands as well (Appendix). So much so that it's name was changed from being "Vi IMitation" initially to "Vi IMproved". (Duperval, 1998)

Since VIM is an editor and not a word-processor, the focus was always on entering the text effectively and not typesetting it. As such today, VIM is one of the most powerful text-editors around and one of the favourites of many programmers and users of Unix-like OS's.

A brief history:

  1. Creator: Bram Moolenaar
  2. Initial release: 1991
  3. Created for: Editing program source code
  4. Written in: C and Vim Script
  5. Stable Release: 7.2 (2008) - The one used in this Project

VIM: Where to use VIM?

VIM is a portable cross-platform editor. It runs on most UNIX flavors as well as Widows, MacOS, DOS, VMS etc. Many several fronts to VIM exist like console, Motif, KDE, Windows GUI, Gtk+ etc.

VIM: When to use VIM?

All commands can be given to VIM with the keyboard. This has the advantage that one can keep his fingers on the keyboard and his eyes on the screen. For those who want it, there is mouse support and a GUI version with scrollbars and menus. Although Vim supports UTF-8 and has partial support for BIDI, it is not recommended for Hebrew editing.

VIM: Why use VIM?

There are a lot of fans of the 20-year-old vim editor. And no, they are not dinosaurs who don't want to catch up with the times - the community of vim users just keeps growing. There are definite reasons why the vi/vim editing model is just superior to any other out there. And one doesn't need to be a UNIX whiz to use it, either: vim is available for free for almost any platform out there; and there are plug-ins to get the functionality inside all major IDEs. Let's see what makes it so popular:

  • Extensibility: Vim supports its own scripting language, numerous plug-ins and several common scripting languages (Perl, Python, Tcl, Ruby).
  • Highlighting: Text highlighting was designed to help programmers through visual aids which enable users to recognize the structure of the file and to spot errors easily. It is also used in text searching, where search results are highlighted.
  • Repeat Commands: The "." command repeats the last change made in normal mode. For example, if the user presses dw to delete a word, he can then press . to delete another word. The "@:" command repeats the last command-line change (a command invoked with ":", for example :s/old/new/). Vim also supports macros. A macro is used to record a sequence of actions inside Vim. Once recorded, it can be executed multiple times using the repeat factor in vim.
  • Folding: A method that is able to represent a range of lines with a single line of text. Through folding, users can get a good overview of the file content.
  • Indentation: Indentation of text, especially program source codes, can be a tedious and time consuming task. The autoindent feature of VIM indents a line by the same amount of indentation as the previous line. The task of indenting C program code has been made easier with the cindent feature. It automatically indents C code and similar languages like Java and C++ in the way that most programmers want. The way of indentation can also be tuned to follow many different styles. The last type of indentation, which Vim is currently still working on, is a flexible scheme for indentation. It works by calling a user defined function that returns the preferred indentation. This would encourage users to write and contribute indent functions for different languages and thus aid other users in their indentation of the same type of file.
  • Customizable: Using Vim Map feature, the user can map a key to a particular job that he performs repeatedly. The map feature has been exploited a lot while designing the CoVIM. The keys are mapped to not only perform an operation one local side but remote side as well. For details, please refer to Chapter 4. Vim allows users to modify the behavior of Vim via its own declarative scripting language. This scripting language is offers the complete collection of keyboard shortcuts and ex-commands and can also be used to author existing tools which enhances Vim's syntax highlighting facilities or change the editor's approach depending on the current file type. Scripting can be enabled in several ways. Script functions can be inserted in short segments into .vimrc file. Alternatively, a separate containing the functions file such as myscript.vim, can be created and placed into the Vim plug-in directory. When it is launched, Vim will automatically load any scripts residing in the script path as if they had been added to .vimrc
  • Documentation: It is very well documented

VIM: How to use VIM?

VIM can be used in various modes. It has got 6 fundamental modes and 6 derived modes (italicised in table below), thereby enabling the flexibility of moving across in 12 modes.

Mode How to use this Mode?

Insert Insert mode can be reached in several ways, but some of the most common ones are<a>(append after cursor),<i>(insert before cursor),<A>(append at end of line),<I>(insert at beginning of line),<C>(change to end of line), and<s>(substitute characters). This mode is, in simple terms, used for inserting new text in the buffer.

Normal Also known as the Command mode, whatever the user types in this mode are some kinds of commands. This is the default mode in Vim. It is mainly used for navigation and manipulation of text by the use of simple commands. For e.g., typing "dd" in this mode will delete a line in this mode, typing ":" will take the user to Commandline mode, etc. If the user is in any mode, he can always return to Normal mode by pressing <Esc>.

Visual Visual mode is the visual representation of the Normal mode wherein the text on which any command is to be executed will be highlighted simultaneously so that the user could see for himself what text he is going to alter. In a nutshell, the mode is frequently used for navigation and manipulation of text selections. Details in Section 6.5.

Select Similar to visual mode, but Select mode has a more MS-Windows like behavior. This means that if the user types a single character it replaces the selection. Of course he loses all the one key operation on selection like<U>to make a selection uppercase. The user normally starts selecting a text to enter select mode or uses "gH" command to enter this mode. Details in Section 6.5

Command-line Behaves similarly to a command prompt where user is given one line to input his command after which it would be interpreted as a command, search or filter. At the end of the command, user goes back to the Normal Mode. For e.g., /word will find the text 'word' in the document and highlight all instances. Then :s/old/new is used to substitute new text for all occurrences of old text.

Ex-mode Similar to the command-line mode but optimized for batch processing i.e. user can enter multiple commands continuously until they leave the mode. The user can enter the mode by pressing Q in Normal Mode and exit by typing :visual. The user uses this mode to update (save) his changes to file or quit from the application.

Operator-pending Similar to Normal mode, it is used for accepting motion to determine the text which will be operated on. For e.g., w means that a word will be operated upon. $ means that the text from current position to end of line will be operated upon. Operators are d for deletion, > for indenting. So d$ will delete the text from cursor till end of line. Thus, the user uses this mode when he has a range of text to be operated upon and that range can be determined by a motion command. Details in Section 6.3

Replace Similar to the Insert mode but typing a new character overwrites the existing ones. The user enters this mode by pressing Insert key or typing R command in Normal mode. Replace Mode should be used when a majority of text is to be overwritten with a new text. For minor text replacements, user can always use r command in Normal mode. Details in Section 5.1

Virtual Replace Similar to Replace mode, but instead of file characters you are replacing screen real estate.

Insert Normal Entered when CTRL-O given in Insert mode; this is like Normal mode, but after executing one command Vim returns to Insert mode. The mode is used when the user mainly wants to work in the Insert Mode but wants to use a few Normal mode commands off and on. For eg, type <Ctrl-O>x to delete the current character and go back to typing in Insert Mode.

Insert Visual Entered when starting a Visual selection from Insert mode, it ends in Insert Mode once the visual selection is completed. The mode is used when the user wants to use visual mode for a short while and quickly return back to the Insert mode for creating text.

Insert Select Entered when starting Select mode from Insert mode, it ends in Insert mode. The user uses this mode when he wants to create text, select it to manipulate it and then go back to creating new text in the buffer. To enter this mode, just select the text using mouse while in Insert Mode.

Chapter 4: Collaborative Technique and Birth of CoVIM

System Architecture

The figure on the left describes the architecture of the technique used to model CoVim:

  1. Single-User Application: The application with single UI and functionalities, oblivious of the collaborative components. For e.g., standard VIM application.
  2. Collaborative Adaptor: An additional software component built on top of SA to make it adaptable to underlying GCE. CA acts as a bridge between SA and GCE by customizing collaboration capabilities offered by GCE for SA. Thus, CA is aware of both SA and collaborative techniques offered by GCE. For e.g., CoVim.
  3. General Collaboration Engine: A framework which offers application-independent collaborative techniques, thus being oblivious to SA. It uses OT as an underlying principle for consistency maintenance.

Collaboration Adaptor

The CA is the most vital component for real-time collaboration.

It serves 2 specific purposes:

  1. To convert single-user application for collaboration without making any changes to the existing application
  2. To reuse same GCE for different collaboration projects

Following are the various modules of CA:

CoVim Data Address Adaptation

Data Addressing is regarded as the way how the textual information is referenced, and how it is being viewed by the user in an editing session. In Vim, every new file or existing file loaded into memory for editing is termed as a buffer. The buffer maintains information such as cursor positions, marks and text information. Although characters in a plain text document may be represented in a sequential manner, information in these buffers, including position of cursors and characters, however, is referenced by two parameters: line and column. Every buffer starts with line one and every line starts with column one. But CoVim still uses linear addressing space to access the buffer information. This has been possible because of line2byte method in Vi-script (i.e. Vim API) which converts information in a line into its bytes equivalent. And it is known that every character 1 byte, so byte equivalent of a line is actually number of characters present in the line. Similarly, byte2line method returns the line number of the character given the byte is known. And using little maths, the column of that character can also be found. This is needed because to correctly replay the effect, the linear position would have to be translated back to two parameters, line and column, so that the character can be correctly inserted at the correct position.

With the linear addressing scheme created, CoVim could implement the basic OT data model for address adaptation. In this approach, the user's point of view of the document would remain the same, where they would still visualize and refer characters' position with line and column. However, in the API's point of view, the modified addressing scheme had allowed characters to be accessed by their position references in the new linear addressing space. The relationship between the characters in the user interface and their position references in the linear addressing space is illustrated below:

Inter-process Communication

To further aid the explanation and comprehension of CoVim's implementation, this section describes how messages are being exchanged between the SA and CA.

Vim OLE: To pass messages to Vim

Vim has provided an Object Linking and Embedding (OLE) interface which enables Vim to act as an OLE automation server, accessible from any OLE client. By making use of the interface, OLE clients would be able to execute OLE methods, which include sending keys (SendKeys) to and evaluating (Eval) script functions defined in Vim.

CoVim external library: To pass messages from Vim

Vim script has a built-in method called libcall which is used to call functions in external libraries. Vimcom.dll serves as the external library and also acts as an intermediary between the SA i.e. Vim and CA. Messages were passed from Vim into the function as arguments which were then forwarded to the CA via Inter-Process Communication methods. The method used in this case was SendMessage, which help guarantees the message is received before returning the libcall function. This is to ensure that no messages were lost which could cause inconsistency problem and disrupt the collaboration process.

Interception of User-generated events

The task of intercepting and processing the events at the local side is done by LOH. In CoVim, Vim script is used for interception of events such as key inputs. In CoVim, an array of all possible keys is created. This array is mapped and unmapped whenever the user enters/exits the Insert Mode. Similarly, all these keys behave as commands in Normal/Visual/Operator pending modes. So, they are mapped to methods which simulate the designated command on the remote sides. For e.g., r is mapped to the Replace method in Normal Mode which simulates r on the remote sides of the shared application Vim using libcall method as mentioned in Section 4.4.2

API-AO Implementation

Adapted Operations (AO) play a very important role in the implementation of CA for the following reasons:

  1. AO represents the interactions between the user and SA:
    1. AO transforms the events produced by user interaction with SA into standard representations to be processed by OT for consistency maintenance.
    2. AO is also the representative of remote operation processed by ROH.
  2. AO acts as a bridge between API (SA- level) and OT (GCE-level): All the remote operations (indicated by AOs) are first transformed into suitable POs and then processed by OT. The OT-processed operation is interpreted by means of API to be suitable replayed at the remote side. Thus, AO serves as a common medium between these two processes thereby keeping OT independent of SA.

As seen from the figure xxx, the POs available in GCE are Insert, Delete and Update. But being a text editor, all the operations in Vim can be manipulated in terms of Insert and Delete solely. This is because the text is never italicised or underlined or changed in font or colour, so Update is redundant. Thus, AOs only for Insert and Delete are needed in Vim.

Mutual exclusion

It is necessary that the LOH and ROH modules in CA are able to run concurrently as two processes but they should be mutually exclusive as well i.e. at one time only one of them should be active. This is done to enforce the atomicity of local and remote operations. For instance, during an atomic local operation, from the point where the local interaction is intercepted, till the time where the interaction is replayed locally, any remote operations received should not be allowed to process. But because of different communication paths taken for sending and receiving of messages, it is quite possible that the remote operation gets processed by CA before the local operation is played. For example, local operation O(L) = Insert[1,"x"] and O(R) = Insert[1,"y"]. Now since O(L) is generated before O(R) is received, the local side should contain "xy". But if O(R) is replayed before O(L), then the local side text would be read as "yx". However, on the remote side, the text should look like "xy". This would lead to inconsistency of the documents at two sides. So to avoid this trouble, it is possible to force the local operation to be played first. This has been done by implementing a lock in the Vim script. Now the local operation would first try to acquire this lock. Upon successful acquisition only, the function (operation) would perform its task; else it would return ignoring the input. Now when the remote operation comes to the local side, it would not be able to acquire the lock if it has been taken by the local operation. Once the local operation is replayed, it would give out the lock to remote operation to replay its effect.

Inter-collaborative site communication

To facilitate the various sites to collaborate, it is necessary to appropriately propagate and receive AOs.:

It is important to see the format of serialized AO:

siteid, adaptedoperation, numofprimitiveoperations {,type, pos, length, data}, type, pos, length, data


siteid: id of site where AO is generated

adaptedoperation = string called "AO"

numofprimitiveoperations = number of POs in which this AO is to be translated into

type = type of PO i.e. Insert or Delete

pos = position where the PO takes place

length = length of data modified

data = text to be inserted/deleted

, (comma) acts as the delimiter.

For example, following are valid serialized AOs:



Chapter 5: Replace Mode Implementation

Requirements Analysis: How Replace works?

The user can enter Replace mode with the "R" command in normal mode. The "Insert" key on keyboard toggles the mode between Insert and Replace.

In Replace mode, every new character typed overwrites the original character written in the buffer. 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 the end of the line is reached. If a <NL> is typed, a line break is inserted and no character is deleted. Even <Del> behaves the same way as in Insert Mode i.e. deletes the character next to the cursor. The only exception being the use of <BS> i.e. Backspace. Backspacing in Replace Mode actually deletes the changes. The characters that were replaced are restored. If the user had typed past the existing text, the characters added would be deleted. This is effectively a character-at-a-time undo.

Effectively, writing in Replace Mode is combination of 2 primitive operations: Deletion and Insertion.

The user can exit Replace Mode by pressing <Esc> to enter Normal Mode.

Alternately, VIM provides 'r' command in Normal Mode for quick replace of a character. It saves the user the trouble of shifting mode to replace the characters.

The syntax of replace command is given as below:



<Esc> is to enter the Normal Mode

<Count> is the number of characters to be replaced

<x> is the new character to overwrite the existing ones

Let's see how it works:

Assume the following text is written in a file and the cursor is on R of replace:

"I am going to test Replace command here"

Case 1: x is any key but Enter

Now if the user presses <Esc>3rt

Buffer: "I am going to test tttlace command"

Case 2: x is Enter key

Assume now he presses 2r<Enter>

Buffer: "I am going to test tt ace command here"

Where \n means NewLine and \r means carriage return

So, it is observed that even though both 't' and 'l' character have been replaced since count=2 but only one has been inputted.


If x=Enter, Only 1 newline replaces the <count> number of characters

Else, <count> number of x replaces <count> number of characters

Note: x cannot b Del or BS. It has to be a printable character.

After execution of this command, the user stays in Normal Mode. Thus, for minor replaces, it is convenient to use 'r' command than changing the mode to Replace. Anyhow the author has covered both the implementations in his project.

Design: Pseudo code

Build: Coding

Refer to Appendix B for Codes.

Integration: Testing

Once the code has been written, it is essential to test it for all possible imaginable inputs a user can enter. Even while the code was being written, the author had been running various Unit tests to ensure that the changes he is making to the code are yielding the expected results. In totality, the author has come up with following test cases to stress-test the replace functionality. What comprises of an exhaustive Test case package?

  1. Test (count = 0): As soon as the user presses 0, the cursor moves to the start of line. And then replaces the first character with the <x>
  2. Test (count < 0): If count is negative, the Vim automatically ignores the negative sign and replaces modulus(<count>) number of characters with <x>
  3. Test (count > 0): <count> characters are replaced by <x>
  4. Test (x = Enter): <count> characters are deleted but only one newline is inserted.
  5. Test (x = All other printable keys): <count> characters are replaced by <x>
  6. Test (x= Non-printable keys): Nothing happens.

Remember that the syntax for 'r' is r. Let's now focus on test cases for 'r' replace command. Assume all commands to be independent of any previous command. Assume the text written in the test file is:

"I am going to test Replace command."

Now, let's see what comprises of an exhaustive test case package for Replace Mode:

  1. Inserting a printable character at a position where buffer is empty: Inserts like in Insert Mode; Since no character is deleted so <orig> = NULL.
  2. Inserting at a position where a character already exists in the buffer: Deletes the original character and puts the character and its position called pos in buffer in <orig> and inserts the newly typed character and its pos in <new>
  3. Deleting using Del key: Deletes the character at cursor
  4. Backspacing
    1. Pos in <orig> and <new> exists: Deletes character at pos in <new> and inserts character at pos from <orig>
    2. Pos in <orig> does not exist but exists in <new>: Deletes character at pos in <new> and does not insert anything; like Normal BS.
    3. If any character from <replaceobstructlist> is typed, <orig> and <new> becomes NULL.
    4. <orig> and <new> don't contain pos: If BS is pressed, then it behaves like a Left Arrow i.e. nothing is deleted, only cursor shifts left.

Note: <replaceobstructlist> : {Left, Right, Up, Down, PgUp, PgDown, Home, End, Esc}

Let's now analyse few test cases for Replace Mode. Assume empty file. Also, assume all the operations mentioned in Test case are done in succession. The underlined shows the cursor position

Chapter 6: System Testing and Integration

Testing Strategy

The following testing strategies have been followed by the author in order to stress-test the CoVim system:

  1. Functional Testing: The focus of testing has been to check whether the implemented features work according to the stated documentation of VIM rather than to check the non-functional requirements like Security, Scalability of the CoVIM application. The author has laid emphasis on testing the various commands offered by VIM, the operators and motions recognised in Vim and the modes available in Vim.
  2. Dynamic Testing: A variety of test cases have been adopted to counter all exceptions. For e.g., the implementation of backspace is an exceptional case in designing Replace Mode. Then there needs to be a separate handling for Enter key while implementing Normal replace command 'r'. The author has had test cases for all exceptions.
  3. Integration testing: The whole CoVim application was broken down into its various consisting modules and each module has been tested individually first and then after integration with the whole system. The break-test-consolidate approach has been used for testing i.e. break into sub-modules, test and consolidate the sub-modules. For e.g., initially only the Insert Mode was tested and implemented. Thereafter, various commands of Normal Mode like J (join), r(replace), u(undo) etc were implemented and tested individually. Then it was tested whether integrating them together makes a stable system. One such test case (Test Case 9) which exposed the flaw while integrating Insert and Undo command is listed in Section 6.4
  4. Grey Box Testing: The author had the access to implementation of the code to design appropriate test cases to validate the system against the specifications of VIM in its documented manual.
  5. System Testing: Once the entire system has been integrated together, test cases were run to see if the system is behaving as the same way as desired i.e. whether the document is consistent on both Local and remote side and also whether the behaviour of CoVIm replicates VIM. For e.g., test case 10 and 11 of Section 6.4 elucidate that even though the local instance of CoVim is behaving as desired, but sometimes the remote instance fail to adapt the new changes thereby leading to inconsistency of document at different instances of the shared application.

Now let's look at the various test cases on Mode by Mode basis.

Testing Insert Mode

The Insert Mode of Vim is like a common text editor mode e.g Notepad. Thus checking for Insert Mode is basically checking if entering all keys on local side propagates them to remote side as well.

Let's see what makes an exhaustive set of test case in Insert Mode:

  1. Test all the possible printable keys: They should be inserted at the specific cursor position.
  2. Test meta keys in conjugation with printable keys like Ctrl-U etc. These are called Special Keys and they have been listed in the Vim documentation: They should insert the character corresponding to them at the cursor position.
  3. Test conjugation of meta keys with non-printable keys like Shift-Del:

Unfortunately, meta-keys have not been handled till the time of printing of this report and that's the reason for discrepancy between actual and expected result:

In a scenario, where the operation only takes place on the Local side and does not propagate on to the remote side, one can use the following command to force sync all the instances of the application:

:CoVim sync

But, this command induces an extra NewLine character on the remote side which leads to error propagation because of Inconsistency in 2 instances of the shared application. Look at the following example:

On the Local side (see left), we just have one string of text, while on the remote side (see right), after execution of the sync command, we have text string plus a newline. Now this newline is not understood by the local side. So if the user types something in the newline space of right instance, it would be appended on the left instance of the application without the newline character in the buffer. See the above figure.

Testing Operator-pending Mode

The common syntax of commands in Operator-pending mode is as follows:




Where count=count1 x count2

Operator = c, d, y, > etc

Motion = j, k, l, aw etc

Now following cases make exhaustive test cases:

  1. Checking whether all operators are implemented or not (Test case 1 and 4)
  2. Checking whether commands with count1 and count2 behave as if there was 1 count input equivalent to their product (Test Case 2)
  3. Checking which all motions have been correctly accounted for (Test case 3)

Assume that the test file contains

"Testing for Operation-pending Mode"

Some of the test cases are listed below (Assume commands to be independent of each other):

Testing Normal Mode

The fact that VIM has a Normal Mode apart from just Insert Mode makes the editor special. Normal mode is basically used for executing various commands on the text like cut, copy, paste etc. Let's test the various commands available in Normal Mode in CoVim. To stress-test various commands, one should pay attention to operators, motion, count and undo commands

Now lets see what makes an exhaustive test case for Normal Mode:

  1. Command: To test whether all the commands are executing as expected. For e.g, D should delete the entire line.
  2. Count: To test whether the command is executed number of times. For e.g, if the user presses d3w, 3 words should be deleted. Also to check what happens if is greater than possible. For eg, in a text with 2 lines, what happens if the user pressed 3D.
  3. Motion: To test whether the intended characters are modified or not. For e.g, $ should affect the text content between cursor position and EOL.
  4. Change of Mode: To test the commands which exit the Normal Mode after the execution. For e.g., 'c' command ends in Insert Mode.

Assume the following text written in the workspace and all commands to be independent of each other:

This text, would be edited by Normal Mode commands

Example 1

"This text, would be edited by Normal Mode commands"

On the above text, execute this command: qs3rtq4l@s

  1. qs: Starts recording macro to register 's'
  2. 3rt: Replaces 3 characters by t. "This text, would be edited by tttmal Mode commands"
  3. q: Stores 3rt to register 's' and stops recording further macro
  4. 5l: Moves cursor to right 5 times. "This text, would be edited by tttmal Mode commands"
  5. @s: Executes the macro stored in 's' i.e. executes 3rt at cursor position. "This text, would be edited by tttmal ttte commands"

Example 2

"This text, would be edited by Normal Mode commands

Testing the Join command"

On the above text, if the user executes this command: 2J, the 2 lines will be joined as:

"This text, would be edited by Normal Mode commands Testing the Join command"

So, the <NL> is replaced by a <Space> and the cursor shifts to beginning of the newly joined line.

Example 3

"This text, would be edited by Normal Mode commands"

On the above text, execute this command: ma0d`a

  1. ma: Sets the mark at the cursor position i.e. N and calls this mark as 'a'.
  2. 0: takes the cursor to Home.
  3. d: Starts deleting from Home until the next motion
  4. `a: The motion till the mark 'a' i.e. till N.
  5. Result: "Normal Mode commands"

Case 3: Test operator commands with motion

In Section 6.3, the operator commands were tested. Let's test the various motions provided in Vim. Assume the operator command to be used be "d".

"This text, would be edited by Normal Mode commands text"

Testing Visual and Select Modes

More often than not, it is not easy to decide which command will move over the text that the user would want to change. In such a scenario, Visual mode comes in handy. It starts highlighting the text as the user is typing the required command.

For example, to delete from halfway one word to halfway another word:

This is an examination sample of visual mode



This is an example of visual mode

While doing this, the user doesn't really have to count how many to press "l" to end up in the right position. He can see what text will be deleted (in this case: ination sam) because it would be highlighted on screen.

Thus, it is observed that Visual mode is a visual interpretation of the normal mode commands wherein an operator is needed. So, no special test cases are required to test the Visual mode. The operator commands working in Normal mode would work in Visual Mode as well.

Select Mode, on the other hand, is the visual representation of the Insert/Replace Mode. The user can select the text using mouse or keyboard and the new key entered would replace the existing text. Again, no special test cases are required for Select Mode. The only difference between replace and Select mode is that a lot of text can be selected and replaced while in replace mode, it is one at a time overwriting of text.

Chapter 7: The Last Words


The project was initiated in order to extend the implementations in the CoVIM so that it can be ready for release. As such, it was to be ensured that CoVIM undergoes a lot of testing from a user's point of view. Thus, in this project, the author has been successfully able to integrate the Replace Mode to CoVIM and also has been able to test the current implementations of mappings in other modes. The test results have helped CoVIM come a long way in understanding and adapting to the erratic inputs of the user.


Nothing in the world is fool-proof and there is always a scope for improvement. A lot has been done till date to prepare CoVIM for its official release. A lot of improvements are still on-going. A detailed study of behaviour of Vim is required to analyse the working of all its different modes. A good understanding of the User manual will be the first step towards further advancement as it lists various exceptions in VIM's behaviour. Following are some key issues that can be taken into consideration to further make CoVIM mimic VIM-like behaviour:

  1. Interception of Meta-keys like Shift, Control, Windows, F2, F3 etc
  2. Interception of Mouse events to alter the buffer
  3. Providing option to Redo the change after Undo.
  4. Implementation of Repeat command i.e. "." DOT command
  5. Providing implementation for Indentation commands i.e. '>' and '<'
  6. Handling abbreviations
  7. Providing options for Insert Mode completion of text (Ctrl+P)
  8. Providing implementations for various motions for Operator-Pending Mode
  9. Providing implementations for all key mappings for Select and Visual Modes
  10. Implementing Command-line and Ex Modes


Appendix A - Vi vs Vim

There have been numerous improvements in Vim over Vi. Given below is the summary of few such improvements:

  1. Multi-level undo: Allows you to set the number of times you can undo your changes in a file buffer. You can also redo an undone change.
  2. Multiple windows and buffers: Each file can be displayed in its own window. You can move easily from one window to another. Each file opened during a Vim session also has an associated buffer and you can easily jump from one to the other.
  3. Repeat a series of commands: Vim has a facility which allows you to record a sequence of typed characters and repeat them any number of times.
  4. Flexible insert mode: Vim allows you to use the arrow keys while in insert mode to move around in the file. No more hitting <Esc>, moving around, then hitting `i' or `a'.
  5. Visual mode: You can highlight sections of text and execute operations on this section of text only.
  6. Block operators: Allow selection and highlighting of rectangular blocks of text in order do execute specific operations on them.
  7. Online help system: You can easily find help on any aspect of using Vim. Help is displayed in its own window.
  8. Command-line editing and history: History allows you to use the arrow keys to repeat or search for a command that has already been typed. Allows you to match the beginning of a command with the beginning of another similar command in the history buffer. You can also edit a command to correct typos or change a few values.
  9. Command line completion: Using the <Tab> key, you can complete commands, options, filenames, etc. as needed.
  10. Horizontal scrolling: Long lines can be scrolled horizontally (with or without the GUI).
  11. Text formatting: With two keystrokes, you can format large sections of text, without the use of external programs.
  12. Edit-compile-edit speedup: You can compile within Vim and automatically jump to the location of errors in the source code.
  13. Improved indenting for C programs: Vim gives you more control over how your C programs appear on screen.
  14. Searching for words in include files Vim allows you to search for a match of the word under the cursor in the current and included files.
  15. Word completion in Insert mode: Vim can complete words while you are typing, by matching the current word with other similar words in the file.
  16. Automatic commands: Commands automatically executed when reading or writing a file, jumping to another buffer, etc.
  17. Viminfo: Allows storing of the command line history, marks and registers in a file to be read on startup.
  18. Mouse support: The mouse is supported in an xterm and for MS-DOS. It can be used to position the cursor, select the visual area, paste a register, etc.
  19. Graphical User Interface (GUI) (Motif and Athena) : You can use the GUI and have access to a menu bar, scrollbar, etc. You can also define your own menus as well as do many operations with the mouse instead of the keyboard.

Appendix B - Source Codes

Replace method for <count>r<character>

Appendix C - Operators and Motions

The motion commands can be used after an operator command, to have the command operate on the text that was moved over. That is the text between the cursor position before and after the motion. Operators are generally used to delete or change text. The following operators are available:

c change
d delete
y yank into register (does not change the text)
~ swap case (only if 'tildeop' is set)
g~ swap case
gu make lowercase
gU make uppercase
! filter through an external program
= filter through 'equalprg' or C-indenting if empty
gq text formatting
g? ROT13 encoding
> shift right
< shift left
zf define a fold

The motions that can be used are:

aw a word (with white space)
iw inner word
aW a WORD (with white space)
iW inner WORD
as a sentence (with white space)
is inner sentence
ap a paragraph (with white space)
ip inner paragraph
ab a () block (with parenthesis)
ib inner () block
aB a {} block (with braces)
iB inner {} block
a< a <> block (with <>)
i< inner <> block
a[ a [] block (with [])
i[ inner [] block