Skip to content

Commit

Permalink
Added textobj "B" for blank-line-delimited texts
Browse files Browse the repository at this point in the history
In Vim, objects B, {, and } are equivalent.  This commit
repurposes B (Block).  B now selects an area delimited by empty
paragraphs.  aB includes the trailing empty paragraph; iB excludes it.
  • Loading branch information
Chris White committed Jun 21, 2019
1 parent 63cadfe commit 9e9b3aa
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 16 deletions.
Binary file modified VimWord.dotm
Binary file not shown.
22 changes: 13 additions & 9 deletions frmGrabKeys.frm
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
' frmGrabKeys: collect keypresses and parse Vim commands
' Copyright (c) 2018 Chris White. All rights reserved.
' Copyright (c) 2018--2019 Chris White. All rights reserved.
' See changelog in mVimWord for other changes
' 2018-04-06 chrisw Initial version
' 2018-04-20 chrisw Major expansion/rewrite
Expand All @@ -32,6 +32,7 @@ Attribute VB_Exposed = False
' 2018-07-16 chrisw Added VHas*Count to support G (vmLine)
' 2018-08-18 chrisw Removed VimRegister enum; added register regex and VRegister
' 2018-09-19 chrisw Added vmMSWordSelection
' 2019-06-21 chrisw Added vm[AI]LineDelimBlock

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

Expand Down Expand Up @@ -207,8 +208,10 @@ Public Enum VimMotion ' Motions/objects/direct objects of transitive operators
vmISentence ' is
vmAPara ' ap (includes Chr(13))
vmIPara ' ip (not Chr(13))
vmALineDelimBlock ' aB (not in Vim)
vmILineDelimBlock ' iB (not in Vim)
' ab/ib () Not yet implemented
' aB/iB {} "
' a{/i{ {} "
' at/it " <tag></tag>
' a</i< <> "
' a[/i[ [] "
Expand Down Expand Up @@ -361,18 +364,16 @@ Private Sub UserForm_Initialize()
Dim RE_PAT As String

' === Build up the regex ===
' The following code is from the output of `re2vba.pl --nodim vim-regex.txt`.
' The following code is from the output of `re2vba.pl vim-regex.txt`.
' DO NOT MODIFY HERE. If you need to change it, modify vim-regex.txt
' and re-run re2vba.pl.



RE_PAT = _
"^((\""([0-9a-z]))?([ ]?)([1-9][0-9]*)?(([ ]?)(([HMLGhjklwbWB" & _
"\x28\x29\x7b\x7d]|g?[eE0\^\$]|\x0d|[fFtT](.))|(gW)?g?[\*#]|g" & _
"?[pP])|([cdyvX])([1-9][0-9]*)?(([\[\]])?([ai])([wWsp])|[fFtT" & _
"](.)|[HMLGhjklwbWB\x28\x29\x7b\x7d]|g?[eE0\^\$]|\x0d)|([x\.]" & _
")))$" & _
"?[pP])|([cdyvX])([1-9][0-9]*)?(([\[\]])?([ai])([wWspB])|[fFt" & _
"T](.)|[HMLGhjklwbWB\x28\x29\x7b\x7d]|g?[eE0\^\$]|\x0d)|([x\." & _
"])))$" & _
""
RESM_REGISTER = 2
RESM_SPACEONE = 3
Expand All @@ -390,7 +391,8 @@ Private Sub UserForm_Initialize()
RESM_TTEXT = 17
RESM_TVERBABBR = 18

' === End of generated code ===
' End of generated code
' =============================

Set RE_ACT = New VBScript_RegExp_55.RegExp
RE_ACT.IgnoreCase = False
Expand Down Expand Up @@ -616,6 +618,7 @@ Private Function ProcessHit_(hit As VBScript_RegExp_55.Match) As Boolean
Case "W": VMotion = vmANonblank
Case "s": VMotion = vmASentence
Case "p": VMotion = vmAPara
Case "B": VMotion = vmALineDelimBlock
Case Else: Exit Function
End Select

Expand All @@ -625,6 +628,7 @@ Private Function ProcessHit_(hit As VBScript_RegExp_55.Match) As Boolean
Case "W": VMotion = vmINonblank
Case "s": VMotion = vmISentence
Case "p": VMotion = vmIPara
Case "B": VMotion = vmILineDelimBlock
Case Else: Exit Function
End Select

Expand Down
Binary file modified frmGrabKeys.frx
Binary file not shown.
48 changes: 44 additions & 4 deletions mVimWord.bas
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Attribute VB_Name = "mVimWord"
' 2019-02-19 chrisw Fixed logic for vmEOWordBackward (ge) and vmEONonblankBackward (gE).
' Be more selective about ViewNormal_ calls.
' 2019-03-05 chrisw Implemented H, M, L: added HandleHML_ material
' 2019-06-21 chrisw Implemented vm[AI]LineDelimBlock

' General comment: Word puts the cursor between characters; Vim puts the
' cursor on characters. This makes quite a difference. I may need
Expand All @@ -36,8 +37,8 @@ Option Explicit
Option Base 0

' Version info
Private Const VIMWORD_VERSION = "0.3.5-pre.1"
Private Const VIMWORD_DATE = "2019-04-29"
Private Const VIMWORD_VERSION = "0.3.5-pre.2"
Private Const VIMWORD_DATE = "2019-06-21"

' Scratchpad filename, lower case for comparison
Private Const SCRATCHPAD_FN_LC = "vimwordscratchpad.dotm"
Expand Down Expand Up @@ -500,6 +501,9 @@ Private Sub vimRunCommand( _
proczone.MoveEndWhile Chr(13), -1 ' Only the last Chr(13)
coll = (motion = vmEOParagraph)

Case vmALineDelimBlock, vmILineDelimBlock: ' B - delimited by ^p^p
Set proczone = FindLineDelimBlock_(proczone, motion)

Case vmMSWordSelection
If proczone.Start = proczone.End Then GoTo VRC_Finally
' If nothing is selected, don't try to take action.
Expand Down Expand Up @@ -922,7 +926,7 @@ Private Sub SaveRangeToRegister_(proczone As Range, reg As String)
Dim dest As Range
Set dest = GetRegister_(reg)

If source.Characters.last = Chr(13) Then
If source.Characters.Last = Chr(13) Then
' Remember that the proczone ended with a Chr(13) since we can't
' store the Chr(13) directly in the single paragraph the register
' is allocated.
Expand All @@ -944,7 +948,7 @@ Private Sub ReplaceRangeFromRegister_(proczone As Range, reg As String, formatte

Dim need_para As Boolean: need_para = False

If source.Characters.last = ChrW(U_PU1) Then ' The register ends with a paragraph mark
If source.Characters.Last = ChrW(U_PU1) Then ' The register ends with a paragraph mark
need_para = True
source.MoveEnd wdCharacter, -1 ' TODO check this for robustness in tables
End If
Expand Down Expand Up @@ -1015,3 +1019,39 @@ Private Function HandleHML_(motion As VimMotion, doc As Document) As Range
Set HandleHML_ = proczone
End Function 'HandleHML_
'

Private Function FindLineDelimBlock_(proczone As Range, motion As VimMotion) As Range
Dim retval As Range
Set retval = proczone.Duplicate
retval.Expand wdParagraph

' Look for the beginning
Do While retval.Start > 0
retval.MoveStart wdParagraph, -1
If retval.Paragraphs(1).Range.Characters.count = 1 Then
If retval.Start > 0 Then
retval.MoveStart wdParagraph, 1 ' Don't keep the empty one at the start
End If
Exit Do ' One-character para => only ^p, so now we have found ^p^p
End If
Loop ' While not at beginning

' Look for the end
Dim endrange As Range
Set endrange = proczone.Duplicate
endrange.Expand wdStory

Do While retval.End < endrange.End
retval.MoveEnd wdParagraph, 1
If retval.Paragraphs.Last.Range.Characters.count = 1 Then
' Found it. Don't keep the trailing blank line if it's an I motion.
If (retval.End < endrange.End) And (motion = vmILineDelimBlock) Then
retval.MoveEnd wdParagraph, -1
End If
Exit Do
End If
Loop ' while not at end

Set FindLineDelimBlock_ = retval
End Function 'FindLineDelimBlock_
'
9 changes: 6 additions & 3 deletions vim-regex.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
# vim normal-mode regex, in re2vba.pl input format.
# Copyright (c) Chris White 2018.
# Copyright (c) Chris White 2018--2019.
# CC-BY-NC-SA 4.0, or any later version, at your option.
# 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
# Note: normal-mode commands defined by Vim but available to be
# repurposed by VimWord: at least Q (no Ex mode), U (Word doesn't
# save undo information per line).

# Main pattern
Expand Down Expand Up @@ -57,10 +58,12 @@ intrans (?<iverb>
# ITEXT: character to jump to

# Text-object selection ([ai][something])
# Difference from Vim: B (block) is delimited by ^p^p. `{` and `}` are still
# available for brace-delimited blocks.
textobj (?<ninja>[\[\]])? (?# Ninja-feet marker)
# https://github.com/tommcdo/vim-ninja-feet
(?<tobj_range>[ai]) (?# Introducer)
(?<objtype>[wWsp]) (?# Type of text object)
(?<objtype>[wWspB]) (?# Type of text object)

# Transitive: verb, count, object, object type, text
trans (?<tverb>[cdyvX]) (?# TVERB: what to do)
Expand Down

0 comments on commit 9e9b3aa

Please sign in to comment.