5333 lines · 172.8 KB · Rust
RawDownload
use editor::{    Anchor, Bias, BufferOffset, DisplayPoint, Editor, MultiBufferOffset, RowExt, ToOffset,    display_map::{DisplayRow, DisplaySnapshot, FoldPoint, ToDisplayPoint},    movement::{        self, FindRange, TextLayoutDetails, find_boundary, find_preceding_boundary_display_point,    },};use gpui::{Action, Context, Window, actions, px};use language::{CharKind, Point, Selection, SelectionGoal};use multi_buffer::MultiBufferRow;use schemars::JsonSchema;use serde::Deserialize;use std::{f64, ops::Range};use workspace::searchable::Direction; use crate::{    Vim,    normal::mark,    state::{Mode, Operator},    surrounds::SurroundsType,}; #[derive(Clone, Copy, Debug, PartialEq, Eq)]pub(crate) enum MotionKind {    Linewise,    Exclusive,    Inclusive,} impl MotionKind {    pub(crate) fn for_mode(mode: Mode) -> Self {        match mode {            Mode::VisualLine => MotionKind::Linewise,            _ => MotionKind::Exclusive,        }    }     pub(crate) fn linewise(&self) -> bool {        matches!(self, MotionKind::Linewise)    }} #[derive(Clone, Debug, PartialEq, Eq)]pub enum Motion {    Left,    WrappingLeft,    Down {        display_lines: bool,    },    Up {        display_lines: bool,    },    Right,    WrappingRight,    NextWordStart {        ignore_punctuation: bool,    },    NextWordEnd {        ignore_punctuation: bool,    },    PreviousWordStart {        ignore_punctuation: bool,    },    PreviousWordEnd {        ignore_punctuation: bool,    },    NextSubwordStart {        ignore_punctuation: bool,    },    NextSubwordEnd {        ignore_punctuation: bool,    },    PreviousSubwordStart {        ignore_punctuation: bool,    },    PreviousSubwordEnd {        ignore_punctuation: bool,    },    FirstNonWhitespace {        display_lines: bool,    },    CurrentLine,    StartOfLine {        display_lines: bool,    },    MiddleOfLine {        display_lines: bool,    },    EndOfLine {        display_lines: bool,    },    SentenceBackward,    SentenceForward,    StartOfParagraph,    EndOfParagraph,    StartOfDocument,    EndOfDocument,    Matching {        match_quotes: bool,    },    GoToPercentage,    UnmatchedForward {        char: char,    },    UnmatchedBackward {        char: char,    },    FindForward {        before: bool,        char: char,        mode: FindRange,        smartcase: bool,    },    FindBackward {        after: bool,        char: char,        mode: FindRange,        smartcase: bool,    },    Sneak {        first_char: char,        second_char: char,        smartcase: bool,    },    SneakBackward {        first_char: char,        second_char: char,        smartcase: bool,    },    RepeatFind {        last_find: Box<Motion>,    },    RepeatFindReversed {        last_find: Box<Motion>,    },    NextLineStart,    PreviousLineStart,    StartOfLineDownward,    EndOfLineDownward,    GoToColumn,    WindowTop,    WindowMiddle,    WindowBottom,    NextSectionStart,    NextSectionEnd,    PreviousSectionStart,    PreviousSectionEnd,    NextMethodStart,    NextMethodEnd,    PreviousMethodStart,    PreviousMethodEnd,    NextComment,    PreviousComment,    PreviousLesserIndent,    PreviousGreaterIndent,    PreviousSameIndent,    NextLesserIndent,    NextGreaterIndent,    NextSameIndent,     // we don't have a good way to run a search synchronously, so    // we handle search motions by running the search async and then    // calling back into motion with this    ZedSearchResult {        prior_selections: Vec<Range<Anchor>>,        new_selections: Vec<Range<Anchor>>,    },    Jump {        anchor: Anchor,        line: bool,    },} #[derive(Clone, Copy)]enum IndentType {    Lesser,    Greater,    Same,} /// Moves to the start of the next word.#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]#[action(namespace = vim)]#[serde(deny_unknown_fields)]struct NextWordStart {    #[serde(default)]    ignore_punctuation: bool,} /// Moves to the end of the next word.#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]#[action(namespace = vim)]#[serde(deny_unknown_fields)]struct NextWordEnd {    #[serde(default)]    ignore_punctuation: bool,} /// Moves to the start of the previous word.#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]#[action(namespace = vim)]#[serde(deny_unknown_fields)]struct PreviousWordStart {    #[serde(default)]    ignore_punctuation: bool,} /// Moves to the end of the previous word.#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]#[action(namespace = vim)]#[serde(deny_unknown_fields)]struct PreviousWordEnd {    #[serde(default)]    ignore_punctuation: bool,} /// Moves to the start of the next subword.#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]#[action(namespace = vim)]#[serde(deny_unknown_fields)]pub(crate) struct NextSubwordStart {    #[serde(default)]    pub(crate) ignore_punctuation: bool,} /// Moves to the end of the next subword.#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]#[action(namespace = vim)]#[serde(deny_unknown_fields)]pub(crate) struct NextSubwordEnd {    #[serde(default)]    pub(crate) ignore_punctuation: bool,} /// Moves to the start of the previous subword.#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]#[action(namespace = vim)]#[serde(deny_unknown_fields)]pub(crate) struct PreviousSubwordStart {    #[serde(default)]    pub(crate) ignore_punctuation: bool,} /// Moves to the end of the previous subword.#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]#[action(namespace = vim)]#[serde(deny_unknown_fields)]pub(crate) struct PreviousSubwordEnd {    #[serde(default)]    pub(crate) ignore_punctuation: bool,} /// Moves cursor up by the specified number of lines.#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]#[action(namespace = vim)]#[serde(deny_unknown_fields)]pub(crate) struct Up {    #[serde(default)]    pub(crate) display_lines: bool,} /// Moves cursor down by the specified number of lines.#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]#[action(namespace = vim)]#[serde(deny_unknown_fields)]pub(crate) struct Down {    #[serde(default)]    pub(crate) display_lines: bool,} /// Moves to the first non-whitespace character on the current line.#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]#[action(namespace = vim)]#[serde(deny_unknown_fields)]struct FirstNonWhitespace {    #[serde(default)]    display_lines: bool,} /// Moves to the matching bracket or delimiter.#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]#[action(namespace = vim)]#[serde(deny_unknown_fields)]struct Matching {    #[serde(default)]    /// Whether to include quote characters (`'`, `"`, `` ` ``) when searching    /// for matching pairs. When `false`, only brackets and parentheses are    /// matched, which aligns with Neovim's default `%` behavior.    match_quotes: bool,} /// Moves to the end of the current line.#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]#[action(namespace = vim)]#[serde(deny_unknown_fields)]struct EndOfLine {    #[serde(default)]    display_lines: bool,} /// Moves to the start of the current line.#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]#[action(namespace = vim)]#[serde(deny_unknown_fields)]pub struct StartOfLine {    #[serde(default)]    pub(crate) display_lines: bool,} /// Moves to the middle of the current line.#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]#[action(namespace = vim)]#[serde(deny_unknown_fields)]struct MiddleOfLine {    #[serde(default)]    display_lines: bool,} /// Finds the next unmatched bracket or delimiter.#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]#[action(namespace = vim)]#[serde(deny_unknown_fields)]struct UnmatchedForward {    #[serde(default)]    char: char,} /// Finds the previous unmatched bracket or delimiter.#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]#[action(namespace = vim)]#[serde(deny_unknown_fields)]struct UnmatchedBackward {    #[serde(default)]    char: char,} actions!(    vim,    [        /// Moves cursor left one character.        Left,        /// Moves cursor left one character, wrapping to previous line.        #[action(deprecated_aliases = ["vim::Backspace"])]        WrappingLeft,        /// Moves cursor right one character.        Right,        /// Moves cursor right one character, wrapping to next line.        #[action(deprecated_aliases = ["vim::Space"])]        WrappingRight,        /// Selects the current line.        CurrentLine,        /// Moves to the start of the next sentence.        SentenceForward,        /// Moves to the start of the previous sentence.        SentenceBackward,        /// Moves to the start of the paragraph.        StartOfParagraph,        /// Moves to the end of the paragraph.        EndOfParagraph,        /// Moves to the start of the document.        StartOfDocument,        /// Moves to the end of the document.        EndOfDocument,        /// Goes to a percentage position in the file.        GoToPercentage,        /// Moves to the start of the next line.        NextLineStart,        /// Moves to the start of the previous line.        PreviousLineStart,        /// Moves to the start of a line downward.        StartOfLineDownward,        /// Moves to the end of a line downward.        EndOfLineDownward,        /// Goes to a specific column number.        GoToColumn,        /// Repeats the last character find.        RepeatFind,        /// Repeats the last character find in reverse.        RepeatFindReversed,        /// Moves to the top of the window.        WindowTop,        /// Moves to the middle of the window.        WindowMiddle,        /// Moves to the bottom of the window.        WindowBottom,        /// Moves to the start of the next section.        NextSectionStart,        /// Moves to the end of the next section.        NextSectionEnd,        /// Moves to the start of the previous section.        PreviousSectionStart,        /// Moves to the end of the previous section.        PreviousSectionEnd,        /// Moves to the start of the next method.        NextMethodStart,        /// Moves to the end of the next method.        NextMethodEnd,        /// Moves to the start of the previous method.        PreviousMethodStart,        /// Moves to the end of the previous method.        PreviousMethodEnd,        /// Moves to the next comment.        NextComment,        /// Moves to the previous comment.        PreviousComment,        /// Moves to the previous line with lesser indentation.        PreviousLesserIndent,        /// Moves to the previous line with greater indentation.        PreviousGreaterIndent,        /// Moves to the previous line with the same indentation.        PreviousSameIndent,        /// Moves to the next line with lesser indentation.        NextLesserIndent,        /// Moves to the next line with greater indentation.        NextGreaterIndent,        /// Moves to the next line with the same indentation.        NextSameIndent,    ]); pub fn register(editor: &mut Editor, cx: &mut Context<Vim>) {    Vim::action(editor, cx, |vim, _: &Left, window, cx| {        vim.motion(Motion::Left, window, cx)    });    Vim::action(editor, cx, |vim, _: &WrappingLeft, window, cx| {        vim.motion(Motion::WrappingLeft, window, cx)    });    Vim::action(editor, cx, |vim, action: &Down, window, cx| {        vim.motion(            Motion::Down {                display_lines: action.display_lines,            },            window,            cx,        )    });    Vim::action(editor, cx, |vim, action: &Up, window, cx| {        vim.motion(            Motion::Up {                display_lines: action.display_lines,            },            window,            cx,        )    });    Vim::action(editor, cx, |vim, _: &Right, window, cx| {        vim.motion(Motion::Right, window, cx)    });    Vim::action(editor, cx, |vim, _: &WrappingRight, window, cx| {        vim.motion(Motion::WrappingRight, window, cx)    });    Vim::action(        editor,        cx,        |vim, action: &FirstNonWhitespace, window, cx| {            vim.motion(                Motion::FirstNonWhitespace {                    display_lines: action.display_lines,                },                window,                cx,            )        },    );    Vim::action(editor, cx, |vim, action: &StartOfLine, window, cx| {        vim.motion(            Motion::StartOfLine {                display_lines: action.display_lines,            },            window,            cx,        )    });    Vim::action(editor, cx, |vim, action: &MiddleOfLine, window, cx| {        vim.motion(            Motion::MiddleOfLine {                display_lines: action.display_lines,            },            window,            cx,        )    });    Vim::action(editor, cx, |vim, action: &EndOfLine, window, cx| {        vim.motion(            Motion::EndOfLine {                display_lines: action.display_lines,            },            window,            cx,        )    });    Vim::action(editor, cx, |vim, _: &CurrentLine, window, cx| {        vim.motion(Motion::CurrentLine, window, cx)    });    Vim::action(editor, cx, |vim, _: &StartOfParagraph, window, cx| {        vim.motion(Motion::StartOfParagraph, window, cx)    });    Vim::action(editor, cx, |vim, _: &EndOfParagraph, window, cx| {        vim.motion(Motion::EndOfParagraph, window, cx)    });

Lines 1–500 of 5333.