Source code for fortrace.utility.console_applications.text_editor.vim

import os
from enum import Enum, auto, unique

from pexpect import replwrap

from fortrace.utility.console_applications.console_application import KeyCodes
from fortrace.utility.console_applications.text_editor.text_editor import (
    GenericConsoleTextEditor,
)


[docs] @unique class VIMMode(Enum): NORMAL = auto() INSERT = auto() VISUAL = auto() VISUAL_LINE = auto() VISUAL_BLOCK = auto()
[docs] class VIM(GenericConsoleTextEditor): """VIM text editor.""" def __init__(self, pty: replwrap.REPLWrapper): super().__init__(pty, "VIM") self._mode = VIMMode.NORMAL
[docs] def replace(self, old: str, new: str, count: int = -1): raise NotImplementedError
[docs] def go_to_line(self, line_num: int): """Go to a specific line. VIM's line indices start at 1. Place the cursor at the first column. Args: line_num: line to set cursor to. If -1 set cursor at the end of the file. If line_num is larger than the real number of lines of a file, VIM will set the cursor to the last line as well. """ prev_mode = self._mode self.change_mode(VIMMode.NORMAL) if line_num == -1: self._virsh.send("G") else: self._virsh.send(line_num) self._virsh.send("G") self.change_mode(prev_mode)
[docs] def delete_current_line(self): self.send_command("dd") self._virsh.readline()
[docs] def close(self): self.send_command(":q!") self._virsh.expect_exact(self._pty.prompt)
# TODO: readlines until prompt is reached?
[docs] def save_file(self): self.send_command(":w") self._document_saved = True
[docs] def send_command(self, command: str): """Enter a specified command in VIM's normal mode. Enters VIM's normal mode and enters the specified command. If possible use change_mode, since some commands do not work with a RET appended, and this will be done automatically. Notes: VIM will stay in normal mode after this method. Args: command: command to be entered """ self.change_mode(VIMMode.NORMAL) self._virsh.send(command) self.send_key_combination(KeyCodes.RET)
[docs] def change_mode(self, mode: VIMMode): """Change VIM to the specified mode. Args: mode: target mode """ # TODO: refactor this, since it looks awfully if mode is VIMMode.NORMAL: self.send_key_combination(KeyCodes.ESC) elif mode is VIMMode.INSERT: self.send_key_combination(KeyCodes.ESC) self._virsh.sendline("i") elif mode is VIMMode.VISUAL: self.send_key_combination(KeyCodes.ESC) self._virsh.sendline("v") elif mode is VIMMode.VISUAL_LINE: self.send_key_combination(KeyCodes.ESC) self._virsh.sendline("V") elif mode is VIMMode.VISUAL_BLOCK: self.send_key_combination(KeyCodes.ESC) self._virsh.sendcontrol("v") else: raise ValueError(f"Unknown mode {mode} provided") self._mode = mode
[docs] def send_file(self, path: os.PathLike): self.change_mode(VIMMode.INSERT) super().send_file(path) self.change_mode(VIMMode.NORMAL)
@property def mode(self): return self._mode