github.com/aretext/aretext@v1.3.0/state/mode.go (about)

     1  package state
     2  
     3  import (
     4  	"github.com/aretext/aretext/selection"
     5  )
     6  
     7  // InputMode controls how the editor interprets input events.
     8  type InputMode int
     9  
    10  const (
    11  	InputModeNormal = InputMode(iota)
    12  	InputModeInsert
    13  	InputModeMenu
    14  	InputModeSearch
    15  	InputModeVisual
    16  	InputModeTask
    17  	InputModeTextField
    18  )
    19  
    20  func (im InputMode) String() string {
    21  	switch im {
    22  	case InputModeNormal:
    23  		return "normal"
    24  	case InputModeInsert:
    25  		return "insert"
    26  	case InputModeMenu:
    27  		return "menu"
    28  	case InputModeSearch:
    29  		return "search"
    30  	case InputModeVisual:
    31  		return "visual"
    32  	case InputModeTask:
    33  		return "task"
    34  	case InputModeTextField:
    35  		return "textfield"
    36  	default:
    37  		panic("invalid input mode")
    38  	}
    39  }
    40  
    41  // EnterNormalMode sets the editor to normal mode.
    42  func EnterNormalMode(state *EditorState) {
    43  	setInputMode(state, InputModeNormal)
    44  }
    45  
    46  // EnterInsertMode sets the editor to insert mode.
    47  func EnterInsertMode(state *EditorState) {
    48  	setInputMode(state, InputModeInsert)
    49  }
    50  
    51  func setInputMode(state *EditorState, mode InputMode) {
    52  	if state.inputMode == InputModeVisual && (mode == InputModeNormal || mode == InputModeInsert) {
    53  		// Clear selection when exiting visual mode.
    54  		state.documentBuffer.selector.Clear()
    55  	}
    56  
    57  	state.inputMode = mode
    58  }
    59  
    60  // ToggleVisualMode transitions to/from visual selection mode.
    61  func ToggleVisualMode(state *EditorState, selectionMode selection.Mode) {
    62  	buffer := state.documentBuffer
    63  
    64  	// If we're not already in visual mode, enter visual mode and start a new selection.
    65  	if state.inputMode != InputModeVisual {
    66  		setInputMode(state, InputModeVisual)
    67  		buffer.selector.Start(selectionMode, buffer.cursor.position)
    68  		return
    69  	}
    70  
    71  	// If we're in visual mode but not in the same selection mode,
    72  	// stay in visual mode and change the selection mode
    73  	// (for example, switch from selecting charwise to selecting linewise)
    74  	if buffer.selector.Mode() != selectionMode {
    75  		buffer.selector.SetMode(selectionMode)
    76  		return
    77  	}
    78  
    79  	// If we're already in visual mode and the requested selection mode,
    80  	// toggle back to normal mode.  This will also clear the selection.
    81  	setInputMode(state, InputModeNormal)
    82  }