diff --git a/fcore/normal-mode/normal-mode.sml b/fcore/normal-mode/normal-mode.sml index af212dd..4b12ff2 100644 --- a/fcore/normal-mode/normal-mode.sml +++ b/fcore/normal-mode/normal-mode.sml @@ -307,6 +307,18 @@ struct | #">" => NormalYank.yankInsideChrClose (app, chr) | _ => NormalFinish.clearMode app + fun parseYankAround (app, chr) = + case chr of + #"(" => NormalYank.yankAroundChrOpen (app, chr) + | #"[" => NormalYank.yankAroundChrOpen (app, chr) + | #"{" => NormalYank.yankAroundChrOpen (app, chr) + | #"<" => NormalYank.yankAroundChrOpen (app, chr) + | #")" => NormalYank.yankAroundChrClose (app, chr) + | #"]" => NormalYank.yankAroundChrClose (app, chr) + | #"}" => NormalYank.yankAroundChrClose (app, chr) + | #">" => NormalYank.yankAroundChrClose (app, chr) + | _ => NormalFinish.clearMode app + fun parseYank (strPos, str, count, app, chrCmd, time) = if strPos = String.size str - 1 then parseYankTerminal (str, count, app, chrCmd, time) @@ -320,8 +332,8 @@ struct NormalYank.yankToChr (app, count, Cursor.toPrevChr, op-, chrCmd) | #"g" => parseYankGo (count, app, chrCmd) | #"i" => parseYankInside (app, chrCmd) + | #"a" => parseYankAround (app, chrCmd) (* todo: implement "yankaround" and "yankDelete" - | #"a" => | #"d" => *) | _ => NormalFinish.clearMode app diff --git a/fcore/normal-mode/normal-yank.sml b/fcore/normal-mode/normal-yank.sml index fd69097..268a0bb 100644 --- a/fcore/normal-mode/normal-yank.sml +++ b/fcore/normal-mode/normal-yank.sml @@ -317,12 +317,45 @@ struct val buffer = LineGap.goToIdx (low, buffer) val high = Cursor.matchPair (buffer, low) val buffer = LineGap.goToIdx (high, buffer) + val low = low + 1 in if low = high then NormalFinish.clearMode app - else finishAfterYankInside (app, low + 1, high, buffer) + else finishAfterYankInside (app, low, high, buffer) end fun yankInsideChrClose (app: app_type, chr) = + let + val {cursorIdx, buffer, ...} = app + + val start = Int.max (cursorIdx - 1, 0) + val buffer = LineGap.goToIdx (start, buffer) + + val high = Cursor.toNextChr (buffer, start, chr) + val buffer = LineGap.goToIdx (high, buffer) + val low = Cursor.matchPair (buffer, high) + 1 + in + if low = high then NormalFinish.clearMode app + else finishAfterYankInside (app, low, high, buffer) + end + + fun yankAroundChrOpen (app: app_type, chr) = + let + val {cursorIdx, buffer, ...} = app + + val start = cursorIdx + 1 + val buffer = LineGap.goToIdx (start, buffer) + + val low = Cursor.toPrevChr (buffer, start, chr) + val buffer = LineGap.goToIdx (low, buffer) + val high = Cursor.matchPair (buffer, low) + 1 + val buffer = LineGap.goToIdx (high, buffer) + val low = low + in + if low = high then NormalFinish.clearMode app + else finishAfterYankInside (app, low, high, buffer) + end + + fun yankAroundChrClose (app: app_type, chr) = let val {cursorIdx, buffer, ...} = app @@ -332,6 +365,7 @@ struct val high = Cursor.toNextChr (buffer, start, chr) val buffer = LineGap.goToIdx (high, buffer) val low = Cursor.matchPair (buffer, high) + val high = high + 1 in if low = high then NormalFinish.clearMode app else finishAfterYankInside (app, low, high, buffer)