2020-06-13 14:06:35 +08:00
|
|
|
# ============================================================================
|
|
|
|
# FILE: __init__.py
|
|
|
|
# AUTHOR: Shougo Matsushita <Shougo.Matsu at gmail.com>
|
|
|
|
# License: MIT license
|
|
|
|
# ============================================================================
|
|
|
|
|
|
|
|
from enum import auto, IntFlag
|
|
|
|
import typing
|
|
|
|
|
|
|
|
from defx.context import Context
|
|
|
|
from defx.defx import Defx
|
|
|
|
from defx.view import View
|
|
|
|
|
|
|
|
|
|
|
|
class ActionAttr(IntFlag):
|
|
|
|
REDRAW = auto()
|
|
|
|
MARK = auto()
|
|
|
|
NO_TAGETS = auto()
|
|
|
|
CURSOR_TARGET = auto()
|
|
|
|
TREE = auto()
|
|
|
|
NONE = 0
|
|
|
|
|
|
|
|
|
|
|
|
class ActionTable(typing.NamedTuple):
|
|
|
|
func: typing.Callable[[View, Defx, Context], None]
|
|
|
|
attr: ActionAttr = ActionAttr.NONE
|
|
|
|
|
|
|
|
|
|
|
|
def do_action(view: View, defx: Defx,
|
|
|
|
action_name: str, context: Context) -> bool:
|
|
|
|
"""
|
|
|
|
Do "action_name" action.
|
|
|
|
"""
|
2020-10-31 15:58:52 +08:00
|
|
|
if not defx._source:
|
|
|
|
return True
|
|
|
|
|
2020-06-13 14:06:35 +08:00
|
|
|
actions: typing.Dict[str, ActionTable] = defx._source.kind.get_actions()
|
|
|
|
|
|
|
|
if action_name not in actions:
|
|
|
|
return True
|
|
|
|
|
|
|
|
action = actions[action_name]
|
|
|
|
|
|
|
|
selected_candidates = [x for x in view._candidates if x['is_selected']]
|
|
|
|
if (selected_candidates and
|
|
|
|
ActionAttr.NO_TAGETS not in action.attr and
|
|
|
|
ActionAttr.TREE not in action.attr):
|
|
|
|
# Clear marks
|
|
|
|
for candidate in selected_candidates:
|
|
|
|
candidate['is_selected'] = False
|
|
|
|
view.redraw()
|
|
|
|
|
|
|
|
if ActionAttr.CURSOR_TARGET in action.attr:
|
|
|
|
# Use cursor candidate only
|
|
|
|
cursor_candidate = view.get_cursor_candidate(context.cursor)
|
|
|
|
if not cursor_candidate:
|
|
|
|
return True
|
|
|
|
context = context._replace(
|
|
|
|
targets=[cursor_candidate],
|
|
|
|
)
|
|
|
|
|
|
|
|
action.func(view, defx, context)
|
|
|
|
|
|
|
|
if action_name != 'repeat':
|
|
|
|
view._prev_action = action_name
|
|
|
|
|
|
|
|
if ActionAttr.MARK in action.attr:
|
|
|
|
# Update marks
|
|
|
|
view.update_candidates()
|
|
|
|
view.redraw()
|
|
|
|
elif ActionAttr.TREE in action.attr:
|
|
|
|
view.update_candidates()
|
|
|
|
view.redraw()
|
|
|
|
elif ActionAttr.REDRAW in action.attr:
|
|
|
|
# Redraw
|
|
|
|
view.redraw(True)
|
|
|
|
return False
|