Skip to content

Commit

Permalink
Added <Space> option; bugfixes.
Browse files Browse the repository at this point in the history
<Space> before a command will now add inline whitespace at the end of
the motion to the range operated on.

Full export.
  • Loading branch information
Chris White committed Jun 7, 2018
1 parent 89433dc commit 8eb0d70
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 40 deletions.
Binary file modified VimWord.dotm
Binary file not shown.
74 changes: 45 additions & 29 deletions frmGrabKeys.frm
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ Attribute VB_Exposed = False
' 2018-05-02 chrisw Refactored motion code into ProcessMotion_
' 2018-05-07 chrisw Added ninja-feet; refactored regex
' 2018-05-12 chrisw Added x X .
' 2018-06-07 chrisw Added VSpace. Also, changed IsEmpty checks to
' Len>0 checks. I had a situation in which a non-match
' returned "" rather than Empty.
' Added special-case code for 0 after nonempty count2.

' NOTE: the consolidated reference is in :help normal-index

Expand Down Expand Up @@ -299,14 +303,17 @@ Public VOperatorCount As Long
Public VMotionCount As Long
Public VArg As String
Public VNinja As VimNinja
Public VSpace As Boolean

Private DotCount_ As Long ' Count on a `.`

' Regexp
Private RE_ACT As VBScript_RegExp_55.RegExp

' Submatch numbers - see vim-regex.txt
Private RESM_SPACEONE As Long
Private RESM_COUNT1 As Long
Private RESM_SPACETWO As Long
Private RESM_IVERB As Long
Private RESM_IMOTION As Long
Private RESM_ITEXT As Long
Expand All @@ -331,7 +338,8 @@ Private Sub UserForm_Initialize()
VMotionCount = 1
VArg = ""
VNinja = vnUndef

VSpace = False

DotCount_ = 1

Dim RE_PAT As String
Expand All @@ -341,25 +349,26 @@ Private Sub UserForm_Initialize()
' DO NOT MODIFY HERE. If you need to change it, modify vim-regex.txt
' and re-run re2vba.pl.


RE_PAT = _
"^(([1-9][0-9]*)?((([HMLGhjklwbWB\x28\x29\x7b\x7d]|g?[eE0\^\$" & _
"]|[fFtT](.))|(gW)?g?[\*#]|g?[pP])|([cdyv])([1-9][0-9]*)?(([\" & _
"[\]])?([ai])([wWsp])|[fFtT](.)|[HMLGhjklwbWB\x28\x29\x7b\x7d" & _
"]|g?[eE0\^\$])|([xX\.])))$" & _
"^(([ ]?)([1-9][0-9]*)?(([ ]?)(([HMLGhjklwbWB\x28\x29\x7b\x7d" & _
"]|g?[eE0\^\$]|[fFtT](.))|(gW)?g?[\*#]|g?[pP])|([cdyv])([1-9]" & _
"[0-9]*)?(([\[\]])?([ai])([wWsp])|[fFtT](.)|[HMLGhjklwbWB\x28" & _
"\x29\x7b\x7d]|g?[eE0\^\$])|([xX\.])))$" & _
""
RESM_COUNT1 = 1
RESM_IVERB = 3
RESM_IMOTION = 4
RESM_ITEXT = 5
RESM_TVERB = 7
RESM_COUNT2 = 8
RESM_TARGET = 9
RESM_NINJA = 10
RESM_TOBJ_RANGE = 11
RESM_OBJTYPE = 12
RESM_TTEXT = 13
RESM_TVERBABBR = 14
RESM_SPACEONE = 1
RESM_COUNT1 = 2
RESM_SPACETWO = 4
RESM_IVERB = 5
RESM_IMOTION = 6
RESM_ITEXT = 7
RESM_TVERB = 9
RESM_COUNT2 = 10
RESM_TARGET = 11
RESM_NINJA = 12
RESM_TOBJ_RANGE = 13
RESM_OBJTYPE = 14
RESM_TTEXT = 15
RESM_TVERBABBR = 16

' === End of generated code ===

Expand Down Expand Up @@ -451,7 +460,8 @@ Private Function ProcessHit_(hit As VBScript_RegExp_55.Match) As Boolean
VMotionCount = 1
VArg = ""
VNinja = vnUndef

VSpace = False

' Don't change DotCount_, which is set by Update()

' Internal variables so we can alias, e.g., `x` to `dl`
Expand All @@ -461,11 +471,17 @@ Private Function ProcessHit_(hit As VBScript_RegExp_55.Match) As Boolean
' Special-case "0" in code so that I don't have to special-case it in the
' regex. A non-empty count preceding a "0" command means that the "0"
' should actually be part of the count, so wait for more keys.
If (Not IsEmpty(hit.SubMatches(RESM_COUNT1))) And _
(hit.SubMatches(RESM_IMOTION) = "0") _
If ((Len(hit.SubMatches(RESM_COUNT1)) > 0) And (hit.SubMatches(RESM_IMOTION) = "0")) Or _
((Len(hit.SubMatches(RESM_COUNT2)) > 0) And (hit.SubMatches(RESM_TARGET) = "0")) _
Then ' ^ Empty decays to ""
Exit Function
End If

' Check for <Space> indicators
If (Len(hit.SubMatches(RESM_SPACEONE)) > 0) Or _
(Len(hit.SubMatches(RESM_SPACETWO)) > 0) Then
VSpace = True
End If

' Count before the command, if any
If Len(hit.SubMatches(RESM_COUNT1)) = 0 Then
Expand All @@ -475,7 +491,7 @@ Private Function ProcessHit_(hit As VBScript_RegExp_55.Match) As Boolean
VOperatorCount = CLng(hit.SubMatches(RESM_COUNT1))
End If

If Not IsEmpty(hit.SubMatches(RESM_TVERBABBR)) Then ' transitive, abbreviated
If Len(hit.SubMatches(RESM_TVERBABBR)) > 0 Then ' transitive, abbreviated
Select Case hit.SubMatches(RESM_TVERBABBR)
' `.`: succeed early - VCommand and VOperatorCount are the only things that matter
Case ".":
Expand All @@ -498,12 +514,12 @@ Private Function ProcessHit_(hit As VBScript_RegExp_55.Match) As Boolean
VOperatorCount = VOperatorCount * DotCount_
DotCount_ = 1

If Not IsEmpty(hit.SubMatches(RESM_IVERB)) Then ' intransitive
If Len(hit.SubMatches(RESM_IVERB)) > 0 Then ' intransitive

Debug.Print "Intransit.", IIf(IsEmpty(hit.SubMatches(RESM_IMOTION)), "-", hit.SubMatches(RESM_IMOTION)), _
Debug.Print "Intransit.", IIf(Len(hit.SubMatches(RESM_IMOTION)) = 0, "-", hit.SubMatches(RESM_IMOTION)), _
hit.SubMatches(RESM_IVERB), hit.SubMatches(RESM_ITEXT)

If Not IsEmpty(hit.SubMatches(RESM_IMOTION)) Then
If Len(hit.SubMatches(RESM_IMOTION)) > 0 Then
If ProcessMotion_(hit.SubMatches(RESM_IMOTION)) Then
VOperator = voGo
Else
Expand Down Expand Up @@ -540,7 +556,7 @@ Private Function ProcessHit_(hit As VBScript_RegExp_55.Match) As Boolean
End Select
End If 'a motion else

ElseIf Not IsEmpty(tverb) Then ' transitive
ElseIf Len(tverb) > 0 Then ' transitive

Debug.Print "Transitive", tverb, hit.SubMatches(RESM_COUNT2), Left(target, 1), hit.SubMatches(RESM_OBJTYPE), hit.SubMatches(RESM_TTEXT)

Expand All @@ -564,7 +580,7 @@ Private Function ProcessHit_(hit As VBScript_RegExp_55.Match) As Boolean
If ProcessMotion_(CStr(target)) Then ' Motion without argument
' Nothing more to do

ElseIf Not IsEmpty(hit.SubMatches(RESM_TOBJ_RANGE)) Then ' Text object
ElseIf Len(hit.SubMatches(RESM_TOBJ_RANGE)) > 0 Then ' Text object
Select Case hit.SubMatches(RESM_TOBJ_RANGE)
Case "a":
Select Case hit.SubMatches(RESM_OBJTYPE)
Expand All @@ -587,7 +603,7 @@ Private Function ProcessHit_(hit As VBScript_RegExp_55.Match) As Boolean
Case Else: Exit Function
End Select

If Not IsEmpty(hit.SubMatches(RESM_NINJA)) Then
If Len(hit.SubMatches(RESM_NINJA)) > 0 Then
VNinja = IIf(hit.SubMatches(RESM_NINJA) = "[", vnLeft, vnRight)
End If

Expand Down Expand Up @@ -617,7 +633,7 @@ Private Sub Update()
Dim done As Boolean: done = False
Dim times_through As Long: times_through = 0 'deadman

lblKeys.Caption = Keys
lblKeys.Caption = Replace(Keys, " ", ChrW(&H2423)) ' Make spaces visible

' parse Vim commands to see if one is done
Dim matches As VBScript_RegExp_55.MatchCollection
Expand Down
Binary file modified frmGrabKeys.frx
Binary file not shown.
44 changes: 34 additions & 10 deletions mVimWord.bas
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Attribute VB_Name = "mVimWord"
' 2018-05-04 chrisw Changed paste behaviour per Word
' 2018-05-07 chrisw gp/gP now paste unformatted text; added ninja-feet
' 2018-05-10 chrisw Fixed whitespace classes used for text objects
' 2018-06-07 chrisw Hack in voDelete/voChange for strange Word behaviour.

' General comment: Word puts the cursor between characters; Vim puts the
' cursor on characters. This makes quite a difference. I may need
Expand All @@ -26,7 +27,7 @@ Public VimLastCommand_ As String
'

Public Sub VimDoCommand_About()
MsgBox "VimWord version 0.2.11, 2018-05-12. Copyright (c) 2018 Christopher White. " & _
MsgBox "VimWord version 0.2.12, 2018-06-07. Copyright (c) 2018 Christopher White. " & _
"All Rights Reserved. Licensed CC-BY-NC-SA 4.0 (or later).", _
vbOKOnly + vbInformation, "About VimWord"
End Sub 'VimDoCommand_About
Expand Down Expand Up @@ -73,7 +74,8 @@ Private Sub VDCInternal(LoopIt As Boolean)
Dim cmdstr As String: cmdstr = ""
Dim arg As String: arg = ""
Dim ninja As VimNinja: ninja = vnUndef

Dim space As Boolean: space = False

If Not frm.WasCancelled Then
cmdstr = frm.Keys
oper = frm.VOperator
Expand All @@ -83,13 +85,14 @@ Private Sub VDCInternal(LoopIt As Boolean)
motionc = frm.VMotionCount
arg = frm.VArg
ninja = frm.VNinja
space = frm.VSpace
End If

Unload frm
Set frm = Nothing
If (cmd <> vcUndef) Or (oper <> voUndef And motion <> vmUndef) Then
vimRunCommand doc, proczone, coll, atStart, oper, cmd, motion, _
operc, motionc, cmdstr, arg, ninja
operc, motionc, cmdstr, arg, ninja, space
Application.ScreenRefresh
End If

Expand All @@ -111,7 +114,8 @@ Private Sub vimRunCommand( _
motionc As Long, _
cmdstr As String, _
arg As String, _
ninja As VimNinja _
ninja As VimNinja, _
space As Boolean _
)
Dim TITLE As String: TITLE = "Do Vim command"

Expand Down Expand Up @@ -388,7 +392,14 @@ Private Sub vimRunCommand( _
Case vnRight
proczone.Start = origpzstart
End Select


' Extra whitespace. Takes effect after ninja-feet.
If space And (colldir = wdCollapseEnd) Then
proczone.MoveEndWhile CSET_WS_ONELINE, wdForward
ElseIf space And (colldir = wdCollapseStart) Then
proczone.MoveStartWhile CSET_WS_ONELINE, wdBackward
End If

' === Operator/Command ==================================================

' Process it. We have either an operator or a command.
Expand All @@ -400,13 +411,26 @@ Private Sub vimRunCommand( _
If proczone.Start <> proczone.End Then proczone.Copy
GoTo VRC_Finally

Case voDelete:
If proczone.Start <> proczone.End Then proczone.Cut
Case voDelete, voChange:
If proczone.Start <> proczone.End Then
' Word doesn't always delete the whole selection!
Dim endr As Range
Set endr = proczone.Duplicate
endr.Collapse wdCollapseEnd
endr.MoveEnd wdCharacter, 1

proczone.Cut

If endr.Characters.count > 1 Then ' something strange happened
If endr.Characters.First = ChrW(13) Then
endr.End = endr.Start + 1
endr.Delete
End If
End If

End If
GoTo VRC_Finally

Case voChange:
If proczone.Start <> proczone.End Then proczone.Cut

' voGo, voSelect handled below
End Select 'operator

Expand Down
4 changes: 4 additions & 0 deletions re2vba.pl
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,10 @@ =head1 OPTIONS
If given on the command line, do not print the C<Dim> statements.
=item --private
If given, use C<Private> instead of C<Dim>.
=item -q, --quiet
Do not print the diagnostic messages while running
Expand Down
14 changes: 13 additions & 1 deletion vim-regex.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,28 @@
# Useful command line:
# ./re2vba.pl --nodim vim-regex.txt |tee >(putclip)

# Available normal-mode commands: at least Q (no Ex mode), U (Word doesn't
# save undo information per line).

# Main pattern
main ^( (?# Note: registers not yet implemented)
(?<spaceone>[ ]?)
(?<count1>[1-9][0-9]*)?
(?:
(?<spacetwo>[ ]?)
(?<=intrans)
|(?<=trans)
|(?<=trans-abbr)
)
)$

# <Space> in <space-one> or <space-two> (or both; no cumulative
# effect) applied with an operator that will cause the motion to
# extend to include any further inline whitespace. E.g., <Space>df,
# will delete to the following comma, and delete any spaces or tabs
# after that comma. Likewise, <Space>db will delete one word
# backwards, and any inline whitespace before that word.

# Motions that don't take arguments (although they may take counts).
# A motion of "0" is special-cased in the parsing code to keep the regex
# clean. This regex, after backtracking, matches "10" as a count of "1"
Expand Down Expand Up @@ -56,7 +68,7 @@ trans (?<tverb>[cdyv]) (?# TVERB: what to do)
(?<=noarg-motion)
)

# Transitive abbreviations: x, ., ... . These are the end of the entry ---
# Transitive abbreviations: x, ., ... . These are the end of the entry ---
# nothing comes after them.
trans-abbr (?<tverbabbr>[xX\.])

Expand Down

0 comments on commit 8eb0d70

Please sign in to comment.