Note: this code should be placed in a workbook module.
' VIxcel
' ======
' A VBA extension to Microsoft Excel, implementing
' key mappings and functions similar to those of the
' VI (specifically VIM) text editors.
'
' Version 0.0.1 25 June 2002. Pre-alpha.
'
' Author: osfameron (osfameron@abelgratis.co.uk / hakim@earthling.net)
' Copyright (c) osfameron 2002
'
' This program may be freely distributed under:
' the GNU GPL
' OR the Perl Artistic license
'
' No fitness for absolutely any purpose is implied, and
' no liability for absolutely anything is admitted.
'
' For an overview, please look at the DOC page of the workbook
Option Explicit
Private m_Count As String
Private m_Command As String
Private m_Mode As Integer
Private m_LastLifeSign As Long
Private m_Head As Range
Private m_Range As Range
Private m_ExpectCallback As String
Const VI_TimeoutTime As Integer = 5 ' seconds
Const VI_Normal As Integer = 1
Const VI_ExpectDirection As Integer = 2
Const VI_VisualCell As Integer = 3
Const VI_VisualLine As Integer = 4
Sub Auto_Open()
Dim char As Variant, char2$
For char = Asc("a") To Asc("z")
VI_Bind Chr(char)
Next
For char = Asc("A") To Asc("Z")
VI_Bind Chr(char), Chr(char) & "_CAP"
Next
For char = Asc("0") To Asc("9")
VI_Bind Chr(char)
Next
For Each char In Array("HOME", "INSERT", "END", "ESC")
char2$ = char
VI_Bind "{" & char2$ & "}", char2$
Next
End Sub
Sub VI_Bind(char As String, Optional alt_name As String = "")
Dim bind_name As String
If alt_name <> "" Then bind_name = alt_name Else bind_name = char
Application.OnKey char, "VI_Key_" & bind_name
Debug.Print "Sub VI_Key_" & bind_name
Debug.Print vbTab & "VI_Key """ & bind_name & """"
Debug.Print vbTab & "VI_Error ""Command not implemented: '" & bind_name & "'"""
Debug.Print vbTab & "VI_Cancel_Command"
Debug.Print "End Sub"
End Sub
Sub VI_Error(errstring As String)
MsgBox errstring, vbCritical, "VI-like extension: error"
End
End Sub
Function VI_Count() As Integer
If m_Count = "" Then VI_Count = 1 Else VI_Count = m_Count
Debug.Print VI_Count
End Function
Sub VI_Cancel_Command()
m_Command = ""
m_Count = ""
Set m_Head = Nothing
m_Mode = VI_Normal
m_ExpectCallback = ""
Application.StatusBar = "Cancelled"
ActiveCell.Select
End Sub
Sub VI_TimeOut_Command()
If Timer - m_LastLifeSign >= VI_TimeoutTime - 1 Then
VI_Cancel_Command
Else
Application.StatusBar = "Not cancelled: " & Timer & "," & m_LastLifeSign
End If
End Sub
Sub VI_StatusBar()
Application.StatusBar = m_Count & " " & m_Command
End Sub
Sub VI_Set_TimeOut()
m_LastLifeSign = Timer
Application.OnTime Now + TimeValue("00:00:" & VI_TimeoutTime), "VI_TimeOut_Command"
End Sub
Sub VI_Jump_Command_End()
If m_Mode = VI_ExpectDirection Then
Application.OnTime Now, m_ExpectCallback
Debug.Print "Callback: " & m_ExpectCallback
ElseIf m_Mode = VI_VisualCell Then
VI_VisualCell_Callback
m_Count = ""
ElseIf m_Mode = VI_VisualLine Then
VI_VisualLine_Callback
m_Count = ""
Else
VI_Cancel_Command
End If
End Sub
Sub VI_VisualCell_Callback()
Dim tail As Range
Set tail = ActiveCell
Range(m_Head, tail).Select
tail.Activate
End Sub
Sub VI_VisualLine_Callback()
Dim tail As Range
Set tail = ActiveCell
Dim t As Integer, b As Integer, l As Integer, r As Integer
l = m_Range.Column
r = m_Range.Column + m_Range.Columns.count - 1
If tail.Row < m_Head.Row Then
t = tail.Row
b = m_Head.Row
Else
b = tail.Row
t = m_Head.Row
End If
Range(Cells(t, l), Cells(b, r)).Select
tail.Activate
End Sub
Sub VI_Key(char As String)
m_Command = m_Command & char
VI_StatusBar
VI_Set_TimeOut
End Sub
Sub VI_Key_Count(char As String)
m_Count = m_Count & char
VI_StatusBar
VI_Set_TimeOut
End Sub
Sub VI_Key_a()
VI_Key "a"
Application.SendKeys "{F2}"
VI_Cancel_Command
End Sub
Sub VI_Key_b()
VI_Key "b"
VI_Error "Command not implemented: 'b'"
VI_Cancel_Command
End Sub
Sub VI_Key_c()
VI_Key "c"
SendKeys "r"
End Sub
Sub VI_Key_d()
VI_Key "d"
If m_Mode = VI_ExpectDirection Then
Dim count As Integer
count = VI_Count
VI_Cancel_Command
Application.SendKeys "V" & count - 1 & "jd"
ElseIf m_Mode = VI_VisualCell Then
m_Head.Activate
Application.Dialogs(xlDialogEditDelete).Show
VI_Cancel_Command
ElseIf m_Mode = VI_VisualLine Then
m_Head.Activate
Selection.Delete (xlShiftUp)
VI_Cancel_Command
Else
m_Mode = VI_ExpectDirection
Set m_Head = ActiveCell
m_ExpectCallback = "VI_Key_d_callback"
Debug.Print "Setting: " & m_ExpectCallback
End If
End Sub
Sub VI_Key_d_callback()
If m_Mode = VI_ExpectDirection Then
Dim tail As Range
Set tail = ActiveCell
Range(m_Head, tail).Select
m_Head.Activate
Application.Dialogs(xlDialogEditDelete).Show
ActiveCell.Select
End If
VI_Cancel_Command
End Sub
Sub VI_Key_e()
VI_Key "e"
VI_Error "Command not implemented: 'e'"
VI_Cancel_Command
End Sub
Sub VI_Key_f()
VI_Key "f"
VI_Error "Command not implemented: 'f'"
VI_Cancel_Command
End Sub
Sub VI_Key_g()
VI_Key "g"
VI_Error "Command not implemented: 'g'"
VI_Cancel_Command
End Sub
Sub VI_Key_h()
VI_Key "h"
On Error GoTo VI_Error
ActiveCell.Offset(0, -VI_Count).Activate
VI_Jump_Command_End
Exit Sub
VI_Error:
VI_Cancel_Command
Cells(ActiveCell.Row, 1).Activate
Beep
End Sub
Sub VI_Key_i()
VI_Key "i"
Application.SendKeys "{F2}{HOME}"
VI_Cancel_Command
End Sub
Sub VI_Key_j()
VI_Key "j"
On Error GoTo VI_Error
ActiveCell.Offset(VI_Count, 0).Activate
VI_Jump_Command_End
Exit Sub
VI_Error:
VI_Cancel_Command
Cells(65536, ActiveCell.Column).Activate
Beep
End Sub
Sub VI_Key_k()
VI_Key "k"
On Error GoTo VI_Error
ActiveCell.Offset(-VI_Count, 0).Activate
VI_Jump_Command_End
Exit Sub
VI_Error:
VI_Cancel_Command
Cells(1, ActiveCell.Column).Activate
Beep
End Sub
Sub VI_Key_l()
VI_Key "l"
On Error GoTo VI_Error
ActiveCell.Offset(0, VI_Count).Activate
VI_Jump_Command_End
Exit Sub
VI_Error:
VI_Cancel_Command
Cells(ActiveCell.Row, 256).Activate
Beep
End Sub
Sub VI_Key_m()
VI_Key "m"
VI_Error "Command not implemented: 'm'"
VI_Cancel_Command
End Sub
Sub VI_Key_n()
VI_Key "n"
VI_Error "Command not implemented: 'n'"
VI_Cancel_Command
End Sub
Sub VI_Key_o()
VI_Key "o"
If m_Mode = VI_VisualCell Or m_Mode = VI_VisualLine Then
Dim temp As Range
Set temp = m_Head
Set m_Head = ActiveCell
temp.Activate
Else
Set m_Head = ActiveCell
Set m_Range = m_Head.CurrentRegion
VI_VisualLine_Callback
Dim i As Integer
For i = 1 To VI_Count
Selection.Offset(1, 0).Insert xlShiftDown
Next
VI_Cancel_Command
End If
End Sub
Sub VI_Key_p()
VI_Key "p"
VI_Error "Command not implemented: 'p'"
VI_Cancel_Command
End Sub
Sub VI_Key_q()
VI_Key "q"
VI_Error "Command not implemented: 'q'"
VI_Cancel_Command
End Sub
Sub VI_Key_r()
VI_Key "r"
Application.SendKeys "{F2}+{HOME}"
VI_Cancel_Command
End Sub
Sub VI_Key_s()
VI_Key "s"
VI_Error "Command not implemented: 's'"
VI_Cancel_Command
End Sub
Sub VI_Key_t()
VI_Key "t"
VI_Error "Command not implemented: 't'"
VI_Cancel_Command
End Sub
Sub VI_Key_u()
VI_Key "u"
Application.Undo
VI_Cancel_Command
End Sub
Sub VI_Key_v()
VI_Key "v"
If m_Mode = VI_VisualCell Then
m_Mode = VI_Normal
ActiveCell.Select
Else
m_Mode = VI_VisualCell
Set m_Head = ActiveCell
End If
End Sub
Sub VI_Key_w()
VI_Key "w"
VI_Error "Command not implemented: 'w'"
VI_Cancel_Command
End Sub
Sub VI_Key_x()
VI_Key "x"
VI_Error "Command not implemented: 'x'"
VI_Cancel_Command
End Sub
Sub VI_Key_y()
VI_Key "y"
VI_Error "Command not implemented: 'y'"
VI_Cancel_Command
End Sub
Sub VI_Key_z()
VI_Key "z"
VI_Error "Command not implemented: 'z'"
VI_Cancel_Command
End Sub
Sub VI_Key_A_CAP()
VI_Key "A_CAP"
VI_Error "Command not implemented: 'A_CAP'"
VI_Cancel_Command
End Sub
Sub VI_Key_B_CAP()
VI_Key "B_CAP"
VI_Error "Command not implemented: 'B_CAP'"
VI_Cancel_Command
End Sub
Sub VI_Key_C_CAP()
VI_Key "C_CAP"
VI_Error "Command not implemented: 'C_CAP'"
VI_Cancel_Command
End Sub
Sub VI_Key_D_CAP()
VI_Key "D_CAP"
VI_Error "Command not implemented: 'D_CAP'"
VI_Cancel_Command
End Sub
Sub VI_Key_E_CAP()
VI_Key "E_CAP"
VI_Error "Command not implemented: 'E_CAP'"
VI_Cancel_Command
End Sub
Sub VI_Key_F_CAP()
VI_Key "F_CAP"
VI_Error "Command not implemented: 'F_CAP'"
VI_Cancel_Command
End Sub
Sub VI_Key_G_CAP()
VI_Key "G_CAP"
VI_Error "Command not implemented: 'G_CAP'"
VI_Cancel_Command
End Sub
Sub VI_Key_H_CAP()
VI_Key "H_CAP"
VI_Error "Command not implemented: 'H_CAP'"
VI_Cancel_Command
End Sub
Sub VI_Key_I_CAP()
VI_Key "I_CAP"
VI_Error "Command not implemented: 'I_CAP'"
VI_Cancel_Command
End Sub
Sub VI_Key_J_CAP()
VI_Key "J_CAP"
VI_Error "Command not implemented: 'J_CAP'"
VI_Cancel_Command
End Sub
Sub VI_Key_K_CAP()
VI_Key "K_CAP"
VI_Error "Command not implemented: 'K_CAP'"
VI_Cancel_Command
End Sub
Sub VI_Key_L_CAP()
VI_Key "L_CAP"
VI_Error "Command not implemented: 'L_CAP'"
VI_Cancel_Command
End Sub
Sub VI_Key_M_CAP()
VI_Key "M_CAP"
VI_Error "Command not implemented: 'M_CAP'"
VI_Cancel_Command
End Sub
Sub VI_Key_N_CAP()
VI_Key "N_CAP"
VI_Error "Command not implemented: 'N_CAP'"
VI_Cancel_Command
End Sub
Sub VI_Key_O_CAP()
VI_Key "O_CAP"
VI_Error "Command not implemented: 'O_CAP'"
VI_Cancel_Command
End Sub
Sub VI_Key_P_CAP()
VI_Key "P_CAP"
VI_Error "Command not implemented: 'P_CAP'"
VI_Cancel_Command
End Sub
Sub VI_Key_Q_CAP()
VI_Key "Q_CAP"
VI_Error "Command not implemented: 'Q_CAP'"
VI_Cancel_Command
End Sub
Sub VI_Key_R_CAP()
VI_Key "R_CAP"
VI_Error "Command not implemented: 'R_CAP'"
VI_Cancel_Command
End Sub
Sub VI_Key_S_CAP()
VI_Key "S_CAP"
VI_Error "Command not implemented: 'S_CAP'"
VI_Cancel_Command
End Sub
Sub VI_Key_T_CAP()
VI_Key "T_CAP"
VI_Error "Command not implemented: 'T_CAP'"
VI_Cancel_Command
End Sub
Sub VI_Key_U_CAP()
VI_Key "U_CAP"
VI_Error "Command not implemented: 'U_CAP'"
VI_Cancel_Command
End Sub
Sub VI_Key_V_CAP()
VI_Key "V"
If m_Mode = VI_VisualLine Then
m_Mode = VI_Normal
ActiveCell.Select
Else
m_Mode = VI_VisualLine
Set m_Head = ActiveCell
Set m_Range = ActiveCell.CurrentRegion
VI_VisualLine_Callback
End If
End Sub
Sub VI_Key_W_CAP()
VI_Key "W_CAP"
VI_Error "Command not implemented: 'W_CAP'"
VI_Cancel_Command
End Sub
Sub VI_Key_X_CAP()
VI_Key "X_CAP"
VI_Error "Command not implemented: 'X_CAP'"
VI_Cancel_Command
End Sub
Sub VI_Key_Y_CAP()
VI_Key "Y_CAP"
VI_Error "Command not implemented: 'Y_CAP'"
VI_Cancel_Command
End Sub
Sub VI_Key_Z_CAP()
VI_Key "Z_CAP"
End Sub
Sub VI_Key_0()
VI_Key_Count "0"
End Sub
Sub VI_Key_1()
VI_Key_Count "1"
End Sub
Sub VI_Key_2()
VI_Key_Count "2"
End Sub
Sub VI_Key_3()
VI_Key_Count "3"
End Sub
Sub VI_Key_4()
VI_Key_Count "4"
End Sub
Sub VI_Key_5()
VI_Key_Count "5"
End Sub
Sub VI_Key_6()
VI_Key_Count "6"
End Sub
Sub VI_Key_7()
VI_Key_Count "7"
End Sub
Sub VI_Key_8()
VI_Key_Count "8"
End Sub
Sub VI_Key_9()
VI_Key_Count "9"
End Sub
Sub VI_Key_HOME()
VI_Key "HOME"
VI_Error "Command not implemented: 'HOME'"
VI_Cancel_Command
End Sub
Sub VI_Key_INSERT()
VI_Key "INSERT"
VI_Error "Command not implemented: 'INSERT'"
VI_Cancel_Command
End Sub
Sub VI_Key_END()
VI_Key "END"
VI_Error "Command not implemented: 'END'"
VI_Cancel_Command
End Sub
Sub VI_Key_ESC()
VI_Key "ESC"
ActiveCell.Select
VI_Cancel_Command
End Sub