mirror of
https://github.com/chylex/IntelliJ-IdeaVim.git
synced 2025-02-25 02:46:01 +01:00
Move more MotionGroup methods to its base class
This commit is contained in:
parent
618a010c15
commit
7652b16ca6
src/main/java/com/maddyhome/idea/vim
vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api
@ -22,9 +22,12 @@ import com.intellij.openapi.fileEditor.impl.EditorsSplitters;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectManager;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import com.intellij.openapi.vfs.VirtualFileSystem;
|
||||
import com.intellij.psi.search.FilenameIndex;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.ProjectScope;
|
||||
@ -44,6 +47,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
import static com.maddyhome.idea.vim.api.VimInjectorKt.injector;
|
||||
@ -445,4 +449,28 @@ public class FileGroup extends VimFileBase {
|
||||
LastTabService.getInstance(event.getManager().getProject()).setLastTab(event.getOldFile());
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public VimEditor selectEditor(@NotNull String projectId, @NotNull String documentPath, @Nullable String protocol) {
|
||||
VirtualFileSystem fileSystem = VirtualFileManager.getInstance().getFileSystem(protocol);
|
||||
if (fileSystem == null) return null;
|
||||
VirtualFile virtualFile = fileSystem.findFileByPath(documentPath);
|
||||
if (virtualFile == null) return null;
|
||||
|
||||
Project project = Arrays.stream(ProjectManager.getInstance().getOpenProjects())
|
||||
.filter(p -> injector.getFile().getProjectId(p).equals(projectId))
|
||||
.findFirst().orElseThrow();
|
||||
|
||||
Editor editor = selectEditor(project, virtualFile);
|
||||
if (editor == null) return null;
|
||||
return new IjVimEditor(editor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getProjectId(@NotNull Object project) {
|
||||
if (!(project instanceof Project)) throw new IllegalArgumentException();
|
||||
return ((Project) project).getName();
|
||||
}
|
||||
}
|
||||
|
@ -11,35 +11,22 @@ import com.intellij.openapi.actionSystem.DataContext
|
||||
import com.intellij.openapi.components.Service
|
||||
import com.intellij.openapi.editor.Caret
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.editor.LogicalPosition
|
||||
import com.intellij.openapi.editor.VisualPosition
|
||||
import com.intellij.openapi.fileEditor.FileEditorManagerEvent
|
||||
import com.intellij.openapi.fileEditor.TextEditor
|
||||
import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx
|
||||
import com.intellij.openapi.fileEditor.impl.EditorWindow
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.vfs.LocalFileSystem
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.openapi.vfs.VirtualFileManager
|
||||
import com.intellij.openapi.vfs.VirtualFileSystem
|
||||
import com.maddyhome.idea.vim.KeyHandler
|
||||
import com.maddyhome.idea.vim.VimPlugin
|
||||
import com.maddyhome.idea.vim.api.BufferPosition
|
||||
import com.maddyhome.idea.vim.api.ExecutionContext
|
||||
import com.maddyhome.idea.vim.api.ImmutableVimCaret
|
||||
import com.maddyhome.idea.vim.api.VimCaret
|
||||
import com.maddyhome.idea.vim.api.VimChangeGroupBase
|
||||
import com.maddyhome.idea.vim.api.VimEditor
|
||||
import com.maddyhome.idea.vim.api.VimMotionGroupBase
|
||||
import com.maddyhome.idea.vim.api.addJump
|
||||
import com.maddyhome.idea.vim.api.anyNonWhitespace
|
||||
import com.maddyhome.idea.vim.api.getJump
|
||||
import com.maddyhome.idea.vim.api.getJumpSpot
|
||||
import com.maddyhome.idea.vim.api.getLeadingCharacterOffset
|
||||
import com.maddyhome.idea.vim.api.getVisualLineCount
|
||||
import com.maddyhome.idea.vim.api.injector
|
||||
import com.maddyhome.idea.vim.api.lineLength
|
||||
import com.maddyhome.idea.vim.api.normalizeOffset
|
||||
import com.maddyhome.idea.vim.api.normalizeVisualColumn
|
||||
import com.maddyhome.idea.vim.api.normalizeVisualLine
|
||||
import com.maddyhome.idea.vim.api.visualLineToBufferLine
|
||||
@ -52,7 +39,6 @@ import com.maddyhome.idea.vim.handler.Motion
|
||||
import com.maddyhome.idea.vim.handler.Motion.AbsoluteOffset
|
||||
import com.maddyhome.idea.vim.handler.MotionActionHandler
|
||||
import com.maddyhome.idea.vim.handler.TextObjectActionHandler
|
||||
import com.maddyhome.idea.vim.handler.toMotionOrError
|
||||
import com.maddyhome.idea.vim.helper.EditorHelper
|
||||
import com.maddyhome.idea.vim.helper.exitVisualMode
|
||||
import com.maddyhome.idea.vim.helper.fileSize
|
||||
@ -61,17 +47,13 @@ import com.maddyhome.idea.vim.helper.getNormalizedSideScrollOffset
|
||||
import com.maddyhome.idea.vim.helper.isEndAllowed
|
||||
import com.maddyhome.idea.vim.helper.vimLastColumn
|
||||
import com.maddyhome.idea.vim.listener.AppCodeTemplates
|
||||
import com.maddyhome.idea.vim.mark.Mark
|
||||
import com.maddyhome.idea.vim.newapi.IjEditorExecutionContext
|
||||
import com.maddyhome.idea.vim.newapi.IjVimCaret
|
||||
import com.maddyhome.idea.vim.newapi.IjVimEditor
|
||||
import com.maddyhome.idea.vim.newapi.ij
|
||||
import com.maddyhome.idea.vim.newapi.vim
|
||||
import com.maddyhome.idea.vim.state.VimStateMachine
|
||||
import com.maddyhome.idea.vim.state.mode.Mode
|
||||
import com.maddyhome.idea.vim.ui.ex.ExEntryPanel
|
||||
import org.jetbrains.annotations.Range
|
||||
import java.io.File
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
|
||||
@ -84,20 +66,6 @@ internal class MotionGroup : VimMotionGroupBase() {
|
||||
AppCodeTemplates.onMovement(editor.ij, caret.ij, oldOffset < offset)
|
||||
}
|
||||
|
||||
private fun selectEditor(project: Project, mark: Mark): Editor? {
|
||||
val virtualFile = markToVirtualFile(mark) ?: return null
|
||||
return selectEditor(project, virtualFile)
|
||||
}
|
||||
|
||||
private fun markToVirtualFile(mark: Mark): VirtualFile? {
|
||||
val protocol = mark.protocol
|
||||
val fileSystem: VirtualFileSystem? = VirtualFileManager.getInstance().getFileSystem(protocol)
|
||||
return fileSystem?.findFileByPath(mark.filepath)
|
||||
}
|
||||
|
||||
private fun selectEditor(project: Project?, file: VirtualFile) =
|
||||
VimPlugin.getFile().selectEditor(project, file)
|
||||
|
||||
override fun moveCaretToFirstDisplayLine(
|
||||
editor: VimEditor,
|
||||
caret: ImmutableVimCaret,
|
||||
@ -120,68 +88,6 @@ internal class MotionGroup : VimMotionGroupBase() {
|
||||
return moveCaretToScreenLocation(editor.ij, caret.ij, ScreenLocation.MIDDLE, 0, false)
|
||||
}
|
||||
|
||||
override fun moveCaretToMark(caret: ImmutableVimCaret, ch: Char, toLineStart: Boolean): Motion {
|
||||
val markService = injector.markService
|
||||
val mark = markService.getMark(caret, ch) ?: return Motion.Error
|
||||
|
||||
val caretEditor = caret.editor
|
||||
val caretVirtualFile = EditorHelper.getVirtualFile((caretEditor as IjVimEditor).editor)
|
||||
|
||||
val line = mark.line
|
||||
|
||||
if (caretVirtualFile!!.path == mark.filepath) {
|
||||
val offset = if (toLineStart) {
|
||||
moveCaretToLineStartSkipLeading(caretEditor, line)
|
||||
} else {
|
||||
caretEditor.bufferPositionToOffset(BufferPosition(line, mark.col, false))
|
||||
}
|
||||
return offset.toMotionOrError()
|
||||
}
|
||||
|
||||
val project = caretEditor.editor.project
|
||||
val markEditor = selectEditor(project!!, mark)
|
||||
if (markEditor != null) {
|
||||
// todo should we move all the carets or only one?
|
||||
for (carett in markEditor.caretModel.allCarets) {
|
||||
val offset = if (toLineStart) {
|
||||
moveCaretToLineStartSkipLeading(IjVimEditor(markEditor), line)
|
||||
} else {
|
||||
// todo should it be the same as getting offset above?
|
||||
markEditor.logicalPositionToOffset(LogicalPosition(line, mark.col))
|
||||
}
|
||||
IjVimCaret(carett!!).moveToOffset(offset)
|
||||
}
|
||||
}
|
||||
return Motion.Error
|
||||
}
|
||||
|
||||
override fun moveCaretToJump(editor: VimEditor, caret: ImmutableVimCaret, count: Int): Motion {
|
||||
val jumpService = injector.jumpService
|
||||
val spot = jumpService.getJumpSpot(editor)
|
||||
val (line, col, fileName) = jumpService.getJump(editor, count) ?: return Motion.Error
|
||||
val vf = EditorHelper.getVirtualFile(editor.ij) ?: return Motion.Error
|
||||
val lp = BufferPosition(line, col, false)
|
||||
val lpNative = LogicalPosition(line, col, false)
|
||||
return if (vf.path != fileName) {
|
||||
val newFile = LocalFileSystem.getInstance().findFileByPath(fileName.replace(File.separatorChar, '/'))
|
||||
?: return Motion.Error
|
||||
selectEditor(editor.ij.project, newFile)?.let { newEditor ->
|
||||
if (spot == -1) {
|
||||
jumpService.addJump(editor, false)
|
||||
}
|
||||
newEditor.vim.let {
|
||||
it.currentCaret().moveToOffset(it.normalizeOffset(newEditor.logicalPositionToOffset(lpNative), false))
|
||||
}
|
||||
}
|
||||
Motion.Error
|
||||
} else {
|
||||
if (spot == -1) {
|
||||
jumpService.addJump(editor, false)
|
||||
}
|
||||
editor.bufferPositionToOffset(lp).toMotionOrError()
|
||||
}
|
||||
}
|
||||
|
||||
override fun moveCaretToCurrentDisplayLineMiddle(editor: VimEditor, caret: ImmutableVimCaret): Motion {
|
||||
val width = EditorHelper.getApproximateScreenWidth(editor.ij) / 2
|
||||
val len = editor.lineLength(editor.currentCaret().getBufferPosition().line)
|
||||
|
@ -35,6 +35,7 @@ import com.maddyhome.idea.vim.api.VimScrollingModel
|
||||
import com.maddyhome.idea.vim.api.VimSelectionModel
|
||||
import com.maddyhome.idea.vim.api.VimVisualPosition
|
||||
import com.maddyhome.idea.vim.api.VirtualFile
|
||||
import com.maddyhome.idea.vim.api.injector
|
||||
import com.maddyhome.idea.vim.command.OperatorArguments
|
||||
import com.maddyhome.idea.vim.common.EditorLine
|
||||
import com.maddyhome.idea.vim.common.IndentConfig
|
||||
@ -358,7 +359,7 @@ internal class IjVimEditor(editor: Editor) : MutableLinearEditor() {
|
||||
return EditorHelper.getVirtualFile(editor)?.getUrl()?.let { VirtualFileManager.extractProtocol(it) }
|
||||
}
|
||||
|
||||
override val projectId = editor.project?.basePath ?: DEFAULT_PROJECT_ID
|
||||
override val projectId = editor.project?.let { injector.file.getProjectId(it) } ?: DEFAULT_PROJECT_ID
|
||||
|
||||
override fun visualPositionToOffset(position: VimVisualPosition): Offset {
|
||||
return editor.visualPositionToOffset(VisualPosition(position.line, position.column, position.leansRight)).offset
|
||||
|
@ -20,4 +20,11 @@ public interface VimFile {
|
||||
public fun selectFile(count: Int, context: ExecutionContext): Boolean
|
||||
public fun selectNextFile(count: Int, context: ExecutionContext)
|
||||
public fun openFile(filename: String, context: ExecutionContext): Boolean
|
||||
|
||||
public fun getProjectId(project: Any): String
|
||||
|
||||
/**
|
||||
* Focuses or opens a new VimEditor by [documentPath]
|
||||
*/
|
||||
public fun selectEditor(projectId: String, documentPath: String, protocol: String?): VimEditor?
|
||||
}
|
||||
|
@ -260,6 +260,64 @@ public abstract class VimMotionGroupBase : VimMotionGroup {
|
||||
return moveCaretToLineStartSkipLeading(editor, line)
|
||||
}
|
||||
|
||||
override fun moveCaretToMark(caret: ImmutableVimCaret, ch: Char, toLineStart: Boolean): Motion {
|
||||
val markService = injector.markService
|
||||
val mark = markService.getMark(caret, ch) ?: return Motion.Error
|
||||
|
||||
val editor = caret.editor
|
||||
|
||||
val line = mark.line
|
||||
|
||||
if (editor.getPath() == mark.filepath) {
|
||||
val offset = if (toLineStart) {
|
||||
moveCaretToLineStartSkipLeading(editor, line)
|
||||
} else {
|
||||
editor.bufferPositionToOffset(BufferPosition(line, mark.col, false))
|
||||
}
|
||||
return offset.toMotionOrError()
|
||||
}
|
||||
|
||||
// TODO [vakhitov] It is super super super wrong.
|
||||
// TODO [vakhitov] We should remove all of the secondary carets and return an offset of the primary one
|
||||
val markEditor = injector.file.selectEditor(editor.projectId, mark.filepath, mark.protocol) ?: return Motion.Error
|
||||
// todo should we move all the carets or only one?
|
||||
for (carett in markEditor.carets()) {
|
||||
val offset = if (toLineStart) {
|
||||
moveCaretToLineStartSkipLeading(markEditor, line)
|
||||
} else {
|
||||
// todo should it be the same as getting offset above?
|
||||
markEditor.bufferPositionToOffset(BufferPosition(line, mark.col))
|
||||
}
|
||||
carett.moveToOffset(offset)
|
||||
}
|
||||
// TODO remove secondary carets and return result for primary caret
|
||||
return Motion.Error
|
||||
}
|
||||
|
||||
override fun moveCaretToJump(editor: VimEditor, caret: ImmutableVimCaret, count: Int): Motion {
|
||||
val jumpService = injector.jumpService
|
||||
val spot = jumpService.getJumpSpot(editor)
|
||||
val (line, col, fileName) = jumpService.getJump(editor, count) ?: return Motion.Error
|
||||
val lp = BufferPosition(line, col, false)
|
||||
return if (editor.getPath() != fileName) {
|
||||
// TODO [vakhitov] come up with a more gentle way to handle protocol
|
||||
injector.file.selectEditor(editor.projectId, fileName, "file")?.let { newEditor ->
|
||||
if (spot == -1) {
|
||||
jumpService.addJump(editor, false)
|
||||
}
|
||||
newEditor.let {
|
||||
it.currentCaret().moveToOffset(it.normalizeOffset(newEditor.bufferPositionToOffset(lp), false))
|
||||
}
|
||||
}
|
||||
Motion.Error
|
||||
} else {
|
||||
if (spot == -1) {
|
||||
jumpService.addJump(editor, false)
|
||||
}
|
||||
editor.bufferPositionToOffset(lp).toMotionOrError()
|
||||
}
|
||||
}
|
||||
|
||||
override fun getMotionRange(
|
||||
editor: VimEditor,
|
||||
caret: ImmutableVimCaret,
|
||||
|
Loading…
Reference in New Issue
Block a user