1
0
mirror of https://github.com/chylex/IntelliJ-IdeaVim.git synced 2025-08-13 06:16:58 +02:00

Fix(VIM-3485): Stay in the same split when using (Back) or (Forward)

This commit is contained in:
filipp
2024-06-21 17:44:25 +03:00
parent 0765118ce2
commit 948520f90a
10 changed files with 36 additions and 23 deletions
src/main/java/com/maddyhome/idea/vim
vim-engine/src/main/kotlin/com/maddyhome/idea/vim

@@ -53,6 +53,7 @@ internal class VimJumpServiceImpl : VimJumpServiceBase(), PersistentStateCompone
jumpElem.setAttribute("line", jump.line.toString())
jumpElem.setAttribute("column", jump.col.toString())
jumpElem.setAttribute("filename", StringUtil.notNullize(jump.filepath))
jumpElem.setAttribute("protocol", StringUtil.notNullize(jump.protocol))
projectElement.addContent(jumpElem)
if (logger.isDebug()) {
logger.debug("saved jump = $jump")
@@ -73,6 +74,7 @@ internal class VimJumpServiceImpl : VimJumpServiceBase(), PersistentStateCompone
Integer.parseInt(jumpElement.getAttributeValue("line")),
Integer.parseInt(jumpElement.getAttributeValue("column")),
jumpElement.getAttributeValue("filename"),
jumpElement.getAttributeValue("protocol", "file"),
)
jumps.add(jump)
}
@@ -120,6 +122,6 @@ internal class JumpsListener(val project: Project) : RecentPlacesListener {
val path = place.file.path
return Jump(line, col, path)
return Jump(line, col, path, place.file.fileSystem.protocol)
}
}

@@ -12,7 +12,6 @@ import com.intellij.ide.bookmark.BookmarkType
import com.intellij.ide.bookmark.BookmarksManager
import com.intellij.ide.bookmark.LineBookmark
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFileManager
import java.lang.ref.WeakReference
internal class IntellijMark(bookmark: LineBookmark, override val col: Int, project: Project?) : Mark {
@@ -24,8 +23,8 @@ internal class IntellijMark(bookmark: LineBookmark, override val col: Int, proje
get() = getMark()?.line ?: 0
override val filepath: String
get() = getMark()?.file?.path ?: ""
override val protocol: String?
get() = getMark()?.file?.let { VirtualFileManager.extractProtocol(it.url) } ?: ""
override val protocol: String
get() = getMark()?.file?.fileSystem?.protocol ?: ""
fun clear() {
val mark = getMark() ?: return

@@ -260,7 +260,8 @@ internal class IjVimEditor(editor: Editor) : MutableLinearEditor() {
val vf = EditorHelper.getVirtualFile(editor)
return vf?.let {
object : VirtualFile {
override val path = vf.path
override val path: String = vf.path
override val protocol: String = vf.fileSystem.protocol
}
}
}

@@ -46,9 +46,11 @@ public interface VimJumpService {
}
public fun VimJumpService.addJump(editor: VimEditor, reset: Boolean) {
val path = editor.getPath() ?: return
val virtualFile = editor.getVirtualFile() ?: return
val path = virtualFile.path
val protocol = virtualFile.protocol
val position = editor.offsetToBufferPosition(editor.currentCaret().offset)
val jump = Jump(position.line, position.column, path)
val jump = Jump(position.line, position.column, path, protocol)
addJump(editor, jump, reset)
}

@@ -182,7 +182,7 @@ public abstract class VimMarkServiceBase : VimMarkService {
markChar.isLocalMark() -> {
if (caret.isPrimary) {
if (mark.key == BEFORE_JUMP_MARK) {
val jump = Jump(mark.line, mark.col, mark.filepath)
val jump = Jump(mark.line, mark.col, mark.filepath, mark.protocol)
injector.jumpService.addJump(editor, jump, true)
}
getLocalMarks(mark.filepath)[markChar] = mark
@@ -206,8 +206,9 @@ public abstract class VimMarkServiceBase : VimMarkService {
if (!markChar.isGlobalMark()) return null
if (!markChar.isOperationValidOnMark(VimMarkService.Operation.SET, editor.primaryCaret())) return null
val position = editor.offsetToBufferPosition(offset)
val path = editor.getPath() ?: return null
return VimMark(markChar, position.line, position.column, path, editor.extractProtocol())
val virtualFile = editor.getVirtualFile() ?: return null
val path = virtualFile.path
return VimMark(markChar, position.line, position.column, path, virtualFile.protocol)
}
override fun setGlobalMark(editor: VimEditor, char: Char, offset: Int): Boolean {
@@ -484,7 +485,8 @@ public abstract class VimMarkServiceBase : VimMarkService {
}
private fun getParagraphMark(editor: VimEditor, caret: ImmutableVimCaret, char: Char): VimMark? {
val path = editor.getPath() ?: return null
val virtualFile = editor.getVirtualFile() ?: return null
val path = virtualFile.path
val count = when (char) {
PARAGRAPH_START_MARK -> -1
PARAGRAPH_END_MARK -> 1
@@ -497,11 +499,13 @@ public abstract class VimMarkServiceBase : VimMarkService {
}
offset = editor.normalizeOffset(offset, false)
val lp = editor.offsetToBufferPosition(offset)
return VimMark(char, lp.line, lp.column, path, editor.extractProtocol())
val protocol = virtualFile.protocol
return VimMark(char, lp.line, lp.column, path, protocol)
}
private fun getSentenceMark(editor: VimEditor, caret: ImmutableVimCaret, char: Char): VimMark? {
val path = editor.getPath() ?: return null
val virtualFile = editor.getVirtualFile() ?: return null
val path = virtualFile.path
val count = when (char) {
SENTENCE_START_MARK -> -1
SENTENCE_END_MARK -> 1
@@ -510,7 +514,8 @@ public abstract class VimMarkServiceBase : VimMarkService {
var offset = injector.searchHelper.findNextSentenceStart(editor, caret, count, countCurrent = false, requireAll = true) ?: return null
offset = editor.normalizeOffset(offset, false)
val lp = editor.offsetToBufferPosition(offset)
return VimMark(char, lp.line, lp.column, path, editor.extractProtocol())
val protocol = virtualFile.protocol
return VimMark(char, lp.line, lp.column, path, protocol)
}
protected fun createSelectionStartMark(caret: ImmutableVimCaret): Mark? {
@@ -559,8 +564,9 @@ public abstract class VimMarkServiceBase : VimMarkService {
private fun createMark(caret: ImmutableVimCaret, char: Char, offset: Int): Mark? {
val editor = caret.editor
val virtualFile = editor.getVirtualFile() ?: return null
val position = editor.offsetToBufferPosition(offset)
return VimMark(char, position.line, position.column, editor.getPath() ?: return null, editor.extractProtocol())
return VimMark(char, position.line, position.column, virtualFile.path, virtualFile.protocol)
}
protected fun Char.normalizeMarkChar(): Char = if (this == '`') '\'' else this

@@ -282,11 +282,11 @@ public abstract class VimMotionGroupBase : VimMotionGroup {
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 (line, col, fileName, protocol) = 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 ->
injector.file.selectEditor(editor.projectId, fileName, protocol)?.let { newEditor ->
if (spot == -1) {
jumpService.addJump(editor, false)
}

@@ -10,4 +10,5 @@ package com.maddyhome.idea.vim.api
public interface VirtualFile {
public val path: String
public val protocol: String
}

@@ -8,4 +8,5 @@
package com.maddyhome.idea.vim.mark
public data class Jump(var line: Int, val col: Int, var filepath: String) // Todo maybe we should use something like IDE's RangeMarker here?
// Todo maybe we should use something like IDE's RangeMarker here?
public data class Jump(var line: Int, val col: Int, var filepath: String, val protocol: String)

@@ -17,7 +17,7 @@ public interface Mark {
public val line: Int // 0-based
public val col: Int // 0-based
public val filepath: String
public val protocol: String?
public val protocol: String
public fun offset(editor: VimEditor): Int = editor.bufferPositionToOffset(BufferPosition(line, col))
@@ -36,7 +36,7 @@ public data class VimMark(
override var line: Int,
override val col: Int,
override val filepath: String,
override val protocol: String?,
override val protocol: String,
) : Mark {
public companion object {
@JvmStatic

@@ -117,9 +117,10 @@ public data class MoveTextCommand(val range: Range, val argument: String) : Comm
}
private fun shiftLocalMark(caret: VimCaret, mark: Mark, shift: Int) {
val editor = caret.editor
val path = editor.getPath() ?: return
val mark = VimMark(mark.key, mark.line + shift, mark.col, path, editor.extractProtocol())
val virtualFile = caret.editor.getVirtualFile() ?: return
val path = virtualFile.path
val protocol = virtualFile.protocol
val mark = VimMark(mark.key, mark.line + shift, mark.col, path, protocol)
injector.markService.setMark(caret, mark)
}