Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Chris White committed Apr 6, 2018
0 parents commit f5c0609
Show file tree
Hide file tree
Showing 7 changed files with 528 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*~
~*
*.swp
*.bak
62 changes: 62 additions & 0 deletions Install VimWord.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
@echo off
:: Install-VimWord.bat: Install VimWord.
:: Copyright (c) 2012--2018 Chris White
:: This file is licensed CC-BY-SA 3.0.
:: 2012/11/05 cwhite Initial version
:: 2012/11/13 cwhite Created from Update-and-respawn
:: 2015/07/08 chrisw Changed to VimWord
:: 2015/07/22 chrisw Added "echo d" just in case
:: 2016/10/14 chrisw Added PATH setting because a user needed it!
:: 2017/01/16 chrisw Added ZIP install check

cls
:: Wipe "Can't run from UNC path" message so users don't get confused
:: Thanks to http://stackoverflow.com/a/9018466/2877364 by
:: http://stackoverflow.com/users/2441/aphoria

path %PATH%;c:\windows\system32
:: ^^^ Because a user had a situation where we needed this!

echo Installer of 2017/01/16

set whereami=%~dp0
:: The path of this bat file, ending with a backslash.
:: We assume the dotm is in the same directory.
:: Thanks to http://stackoverflow.com/a/26564834/2877364 by
:: http://stackoverflow.com/users/2475211/jayro-greybeard

:: TODO update - this fails if whereami includes an ampersand - everything
:: at and after the ampersand is not part of %whereami%

set src="%whereami%VimWord.dotm"
echo Installing from %src%...
if not exist %src% goto :nosource

echo d | xcopy %src% "%appdata%\Microsoft\Word\Startup" /v /f /y
if errorlevel 1 goto error

:: success ::

echo Installed successfully!
goto end

:: failure ::

:error
echo An error occurred
goto end

:: Source file not found ::

:nosource
echo.
echo Could not find %src%.
echo.
echo If you are running this from within the ZIP file, please
echo unzip to a folder, then try again from the folder.
goto end

:end
pause

:: vi: set ts=2 sts=2 sw=2 expandtab ai: ::
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# VimWord

Word VBA add-in permitting you to use a subset of normal-mode editing commands
in Word.

## Installation

- Exit Word
- Run `Install VimWord.bat`
- Alternatively put `VimWord.dotm` in `...\Word\Startup` or load
through `Add-Ins | Manage: Word Add-ins`.
- Map a key to `VimDoCommand` (I use `Ctrl`+`;` because it's easy to type on
my keyboard.)

## Usage

- Hit the key you mapped, then enter a normal-mode command (e.g.,
`diw`). Currently only the `d` and `y` operators are supported,
plus `;` or `'` (not in Vim) to just go there. For example, `;10l`
will move 10 characters right.

## Limitations

- Counts are only supported on `h` and `l`
- Vertical motion is not yet supported
- Numerous others! :)

## License

CC-BY-NC-SA 4.0 or, at your option, any later version.

Binary file added VimWord.dotm
Binary file not shown.
207 changes: 207 additions & 0 deletions frmGrabKeys.frm
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
VERSION 5.00
Begin {C62A69F0-16DC-11CE-9E98-00AA00574A4F} frmGrabKeys
Caption = "Run Vim command"
ClientHeight = 3015
ClientLeft = 120
ClientTop = 465
ClientWidth = 4560
OleObjectBlob = "frmGrabKeys.frx":0000
StartUpPosition = 1 'CenterOwner
End
Attribute VB_Name = "frmGrabKeys"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False

' frmGrabKeys: collect keypresses.
' Copyright (c) 2018 Chris White. All rights reserved.
' 2018-04-06 chrisw Initial version

Option Explicit
Option Base 0

' Vim support
Public Enum VimOperator
vcUndef
vcChange ' c
vcDelete ' d
vcYank ' y
vcGo ' ' - NOT IN VIM. To use motions as cursor motions.
End Enum 'VimOperator

Public Enum VimMotion
vmUndef
'vmWholeLine ' for dd, yy, cc.
vmLeft ' h
vmRight ' l
vmUp ' k
vmDown ' j
vmStartOfLine ' ^ ' TODO
vmStartOfParagraph ' 0 ' TODO this gets mixed in with the count
vmEOL ' $ ' TODO
vmLine ' G
vmCharForward ' f
vmCharBackward ' F
vmTilForward ' t
vmTilBackward ' T
vmWordForward ' w
vmEOWordForward ' e
vmWordBackward ' b
vmNonblankForward ' W
vmEONonblankForward ' E
vmNonblankBackward ' B
vmSentenceForward ' )
vmSentenceBackward ' (
vmParaForward ' }
vmParaBackward ' {

vmAWord ' aw
vmIWord ' iw
vmANonblank ' aW
vmINonblank ' iW
vmASentence ' as
vmISentence ' is
vmAPara ' ap (includes Chr(13))
vmIPara ' ip (not Chr(13))
End Enum 'VimMotion
'

Public WasCancelled As Boolean
Public Keys As String
Public VCommand As VimOperator
Public VMotion As VimMotion
Public VCommandCount As Long
Public VMotionCount As Long
Public VArg As String

Private RE_EXCMD As VBScript_RegExp_55.RegExp

Private Sub Update()
Dim done As Boolean: done = False
lblKeys.Caption = Keys

' parse Vim commands to see if one is done
Dim matches As VBScript_RegExp_55.MatchCollection
Dim hit As VBScript_RegExp_55.Match

Set matches = RE_EXCMD.Execute(Keys)
If matches.count > 0 Then
Set hit = matches.Item(0)
On Error GoTo BadParse

If Len(hit.submatches(0)) = 0 Then
VCommandCount = 1
Else
VCommandCount = CLng(hit.submatches(0))
End If

If Len(hit.submatches(2)) = 0 Then
VMotionCount = 1
Else
VMotionCount = CLng(hit.submatches(2))
End If

VArg = "" ' empty unless assigned below (fFtT)

Select Case hit.submatches(1)
Case "c": VCommand = vcChange
Case "d": VCommand = vcDelete
Case "y": VCommand = vcYank
Case "'", ";": VCommand = vcGo
Case Else: Err.Raise vbObjectError
End Select

Select Case Left(hit.submatches(3), 1)
Case "h": VMotion = vmLeft
Case "l": VMotion = vmRight
Case "k": VMotion = vmUp
Case "j": VMotion = vmDown
Case "^": VMotion = vmStartOfLine
Case "0": VMotion = vmStartOfParagraph
Case "$": VMotion = vmEOL
Case "G": VMotion = vmLine

Case "w": VMotion = vmWordForward
Case "e": VMotion = vmEOWordForward
Case "b": VMotion = vmWordBackward
Case "W": VMotion = vmNonblankForward
Case "E": VMotion = vmEONonblankForward
Case "B": VMotion = vmNonblankBackward
Case ")": VMotion = vmSentenceForward
Case "(": VMotion = vmSentenceBackward
Case "}": VMotion = vmParaForward
Case "{": VMotion = vmParaBackward

Case "f", "F", "t", "T":
VArg = Mid(hit.submatches(3), 2, 1)
Select Case Left(hit.submatches(3), 1)
Case "f": VMotion = vmCharForward
Case "F": VMotion = vmCharBackward
Case "t": VMotion = vmTilForward
Case "T": VMotion = vmTilBackward
End Select

Case "a", "i":
Select Case hit.submatches(3)
Case "aw": VMotion = vmAWord
Case "iw": VMotion = vmIWord
Case "aW": VMotion = vmANonblank
Case "iW": VMotion = vmINonblank
Case "as": VMotion = vmASentence
Case "is": VMotion = vmISentence
Case "ap": VMotion = vmAPara
Case "ip": VMotion = vmIPara
End Select

Case Else: Err.Raise vbObjectError
End Select

done = True ' If we made it here, the parse was successful
End If

Update_Finally:
On Error Resume Next
If done Then
Me.Hide
End If
Exit Sub
BadParse:
done = False
Resume Update_Finally
End Sub

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Private Sub UserForm_Initialize()
WasCancelled = False
Keys = ""
VCommand = vcUndef
VMotion = vmUndef
VCommandCount = 1
VMotionCount = 1
VArg = ""

Set RE_EXCMD = New VBScript_RegExp_55.RegExp
RE_EXCMD.pattern = "^([0-9]*)([dcy;'])([0-9]*)([ai][wWsp]|[fFtT].|[hjklGwebWEB\)\(\}\{])$"
' TODO figure out ^0$
End Sub

Private Sub btnCancel_Click()
WasCancelled = True
Me.Hide
End Sub

Private Sub UserForm_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
If KeyAscii = vbKeyReturn Then
Me.Hide
ElseIf KeyAscii = vbKeyBack Then
If Len(Keys) > 0 Then
Keys = Left(Keys, Len(Keys) - 1)
Update
End If
ElseIf KeyAscii >= 32 And KeyAscii <= 127 Then
Keys = Keys & Chr(KeyAscii)
Update
End If
End Sub
Binary file added frmGrabKeys.frx
Binary file not shown.
Loading

0 comments on commit f5c0609

Please sign in to comment.