Search in sources :

Example 1 with Mark

use of com.maddyhome.idea.vim.common.Mark in project ideavim by JetBrains.

the class MarkGroup method readData.

public void readData(@NotNull Element element) {
    // We need to keep the filename for now and create the virtual file later. Any attempt to call
    // LocalFileSystem.getInstance().findFileByPath() results in the following error:
    // Read access is allowed from event dispatch thread or inside read-action only
    // (see com.intellij.openapi.application.Application.runReadAction())
    Element marksElem = element.getChild("globalmarks");
    if (marksElem != null) {
        List markList = marksElem.getChildren("mark");
        for (Object aMarkList : markList) {
            Element markElem = (Element) aMarkList;
            Mark mark = new Mark(markElem.getAttributeValue("key").charAt(0), Integer.parseInt(markElem.getAttributeValue("line")), Integer.parseInt(markElem.getAttributeValue("column")), markElem.getAttributeValue("filename"));
            globalMarks.put(mark.getKey(), mark);
            HashMap<Character, Mark> fmarks = getFileMarks(mark.getFilename());
            fmarks.put(mark.getKey(), mark);
        }
    }
    if (logger.isDebugEnabled()) {
        logger.debug("globalMarks=" + globalMarks);
    }
    Element fileMarksElem = element.getChild("filemarks");
    if (fileMarksElem != null) {
        List fileList = fileMarksElem.getChildren("file");
        for (Object aFileList : fileList) {
            Element fileElem = (Element) aFileList;
            String filename = fileElem.getAttributeValue("name");
            Date timestamp = new Date();
            try {
                long date = Long.parseLong(fileElem.getAttributeValue("timestamp"));
                timestamp.setTime(date);
            } catch (NumberFormatException e) {
            // ignore
            }
            FileMarks<Character, Mark> fmarks = getFileMarks(filename);
            List markList = fileElem.getChildren("mark");
            for (Object aMarkList : markList) {
                Element markElem = (Element) aMarkList;
                Mark mark = new Mark(markElem.getAttributeValue("key").charAt(0), Integer.parseInt(markElem.getAttributeValue("line")), Integer.parseInt(markElem.getAttributeValue("column")), filename);
                fmarks.put(mark.getKey(), mark);
            }
            fmarks.setTimestamp(timestamp);
        }
    }
    if (logger.isDebugEnabled()) {
        logger.debug("fileMarks=" + fileMarks);
    }
    jumps.clear();
    Element jumpsElem = element.getChild("jumps");
    if (jumpsElem != null) {
        List jumpList = jumpsElem.getChildren("jump");
        for (Object aJumpList : jumpList) {
            Element jumpElem = (Element) aJumpList;
            Jump jump = new Jump(Integer.parseInt(jumpElem.getAttributeValue("line")), Integer.parseInt(jumpElem.getAttributeValue("column")), jumpElem.getAttributeValue("filename"));
            jumps.add(jump);
        }
    }
    if (logger.isDebugEnabled()) {
        logger.debug("jumps=" + jumps);
    }
}
Also used : Element(org.jdom.Element) Mark(com.maddyhome.idea.vim.common.Mark) Jump(com.maddyhome.idea.vim.common.Jump)

Example 2 with Mark

use of com.maddyhome.idea.vim.common.Mark in project ideavim by JetBrains.

the class MarkGroup method updateMarkFromInsert.

/**
   * This updates all the marks for a file whenever text is inserted into the file. If the line that contains a mark
   * that is after the start of the insertion point, shift the mark by the number of new lines added.
   *
   * @param editor      The editor that was updated
   * @param marks       The editor's marks
   * @param insStartOff The insertion point
   * @param insLength   The length of the insertion
   */
public static void updateMarkFromInsert(@Nullable Editor editor, @Nullable HashMap<Character, Mark> marks, int insStartOff, int insLength) {
    if (marks != null && marks.size() > 0 && editor != null) {
        int insEndOff = insStartOff + insLength;
        LogicalPosition insStart = editor.offsetToLogicalPosition(insStartOff);
        LogicalPosition insEnd = editor.offsetToLogicalPosition(insEndOff);
        if (logger.isDebugEnabled())
            logger.debug("mark insert. insStart = " + insStart + ", insEnd = " + insEnd);
        int lines = insEnd.line - insStart.line;
        if (lines == 0)
            return;
        for (Mark mark : marks.values()) {
            if (logger.isDebugEnabled())
                logger.debug("mark = " + mark);
            // Shift the mark if the insertion began on a line prior to the marked line.
            if (insStart.line < mark.getLogicalLine()) {
                mark.setLogicalLine(mark.getLogicalLine() + lines);
                if (logger.isDebugEnabled())
                    logger.debug("Shifting mark by " + lines + " lines");
            }
        }
    }
}
Also used : LogicalPosition(com.intellij.openapi.editor.LogicalPosition) Mark(com.maddyhome.idea.vim.common.Mark)

Example 3 with Mark

use of com.maddyhome.idea.vim.common.Mark in project ideavim by JetBrains.

the class MarkGroup method updateMarkFromDelete.

/**
   * This updates all the marks for a file whenever text is deleted from the file. If the line that contains a mark
   * is completely deleted then the mark is deleted too. If the deleted text is before the marked line, the mark is
   * moved up by the number of deleted lines.
   *
   * @param editor      The modified editor
   * @param marks       The editor's marks to update
   * @param delStartOff The offset within the editor where the deletion occurred
   * @param delLength   The length of the deleted text
   */
public static void updateMarkFromDelete(@Nullable Editor editor, @Nullable HashMap<Character, Mark> marks, int delStartOff, int delLength) {
    // Skip all this work if there are no marks
    if (marks != null && marks.size() > 0 && editor != null) {
        // Calculate the logical position of the start and end of the deleted text
        int delEndOff = delStartOff + delLength - 1;
        LogicalPosition delStart = editor.offsetToLogicalPosition(delStartOff);
        LogicalPosition delEnd = editor.offsetToLogicalPosition(delEndOff + 1);
        if (logger.isDebugEnabled())
            logger.debug("mark delete. delStart = " + delStart + ", delEnd = " + delEnd);
        // Now analyze each mark to determine if it needs to be updated or removed
        for (Character ch : marks.keySet()) {
            Mark mark = marks.get(ch);
            if (logger.isDebugEnabled())
                logger.debug("mark = " + mark);
            // proper number of lines.
            if (delEnd.line < mark.getLogicalLine()) {
                int lines = delEnd.line - delStart.line;
                if (logger.isDebugEnabled())
                    logger.debug("Shifting mark by " + lines + " lines");
                mark.setLogicalLine(mark.getLogicalLine() - lines);
            } else // If the deleted text begins before the mark and ends after the mark then it may be shifted or deleted
            if (delStart.line <= mark.getLogicalLine() && delEnd.line >= mark.getLogicalLine()) {
                int markLineStartOff = EditorHelper.getLineStartOffset(editor, mark.getLogicalLine());
                int markLineEndOff = EditorHelper.getLineEndOffset(editor, mark.getLogicalLine(), true);
                Command command = CommandState.getInstance(editor).getCommand();
                // If text is being changed from the start of the mark line (a special case for mark deletion)
                boolean changeFromMarkLineStart = command != null && command.getType() == Command.Type.CHANGE && delStartOff == markLineStartOff;
                // If the marked line is completely within the deleted text, remove the mark (except the special case)
                if (delStartOff <= markLineStartOff && delEndOff >= markLineEndOff && !changeFromMarkLineStart) {
                    VimPlugin.getMark().removeMark(ch, mark);
                    logger.debug("Removed mark");
                } else // on a line prior to the marked line (which means the deletion must end on the marked line).
                if (delStart.line < mark.getLogicalLine()) {
                    // shift mark
                    mark.setLogicalLine(delStart.line);
                    if (logger.isDebugEnabled())
                        logger.debug("Shifting mark to line " + delStart.line);
                }
            }
        }
    }
}
Also used : LogicalPosition(com.intellij.openapi.editor.LogicalPosition) Command(com.maddyhome.idea.vim.command.Command) Mark(com.maddyhome.idea.vim.common.Mark)

Example 4 with Mark

use of com.maddyhome.idea.vim.common.Mark in project ideavim by JetBrains.

the class MarkGroup method saveData.

public void saveData(@NotNull Element element) {
    Element marksElem = new Element("globalmarks");
    for (Mark mark : globalMarks.values()) {
        if (!mark.isClear()) {
            Element markElem = new Element("mark");
            markElem.setAttribute("key", Character.toString(mark.getKey()));
            markElem.setAttribute("line", Integer.toString(mark.getLogicalLine()));
            markElem.setAttribute("column", Integer.toString(mark.getCol()));
            markElem.setAttribute("filename", StringUtil.notNullize(mark.getFilename()));
            marksElem.addContent(markElem);
            if (logger.isDebugEnabled()) {
                logger.debug("saved mark = " + mark);
            }
        }
    }
    element.addContent(marksElem);
    Element fileMarksElem = new Element("filemarks");
    List<FileMarks<Character, Mark>> files = new ArrayList<FileMarks<Character, Mark>>(fileMarks.values());
    Collections.sort(files, new Comparator<FileMarks<Character, Mark>>() {

        public int compare(@NotNull FileMarks<Character, Mark> o1, @NotNull FileMarks<Character, Mark> o2) {
            return o1.timestamp.compareTo(o2.timestamp);
        }
    });
    if (files.size() > SAVE_MARK_COUNT) {
        files = files.subList(files.size() - SAVE_MARK_COUNT, files.size());
    }
    for (String file : fileMarks.keySet()) {
        FileMarks<Character, Mark> marks = fileMarks.get(file);
        if (!files.contains(marks)) {
            continue;
        }
        if (marks.size() > 0) {
            Element fileMarkElem = new Element("file");
            fileMarkElem.setAttribute("name", file);
            fileMarkElem.setAttribute("timestamp", Long.toString(marks.timestamp.getTime()));
            for (Mark mark : marks.values()) {
                if (!mark.isClear() && !Character.isUpperCase(mark.getKey()) && SAVE_FILE_MARKS.indexOf(mark.getKey()) >= 0) {
                    Element markElem = new Element("mark");
                    markElem.setAttribute("key", Character.toString(mark.getKey()));
                    markElem.setAttribute("line", Integer.toString(mark.getLogicalLine()));
                    markElem.setAttribute("column", Integer.toString(mark.getCol()));
                    fileMarkElem.addContent(markElem);
                }
            }
            fileMarksElem.addContent(fileMarkElem);
        }
    }
    element.addContent(fileMarksElem);
    Element jumpsElem = new Element("jumps");
    for (Jump jump : jumps) {
        if (!jump.isClear()) {
            Element jumpElem = new Element("jump");
            jumpElem.setAttribute("line", Integer.toString(jump.getLogicalLine()));
            jumpElem.setAttribute("column", Integer.toString(jump.getCol()));
            jumpElem.setAttribute("filename", StringUtil.notNullize(jump.getFilename()));
            jumpsElem.addContent(jumpElem);
            if (logger.isDebugEnabled()) {
                logger.debug("saved jump = " + jump);
            }
        }
    }
    element.addContent(jumpsElem);
}
Also used : Element(org.jdom.Element) Mark(com.maddyhome.idea.vim.common.Mark) Jump(com.maddyhome.idea.vim.common.Jump)

Example 5 with Mark

use of com.maddyhome.idea.vim.common.Mark in project ideavim by JetBrains.

the class MarkGroup method getAllFileMarks.

@Nullable
private HashMap<Character, Mark> getAllFileMarks(@NotNull final Document doc) {
    VirtualFile vf = FileDocumentManager.getInstance().getFile(doc);
    if (vf == null) {
        return null;
    }
    HashMap<Character, Mark> res = new HashMap<Character, Mark>();
    FileMarks<Character, Mark> fileMarks = getFileMarks(doc);
    if (fileMarks != null) {
        res.putAll(fileMarks);
    }
    for (Character ch : globalMarks.keySet()) {
        Mark mark = globalMarks.get(ch);
        if (vf.getPath().equals(mark.getFilename())) {
            res.put(ch, mark);
        }
    }
    return res;
}
Also used : VirtualFile(com.intellij.openapi.vfs.VirtualFile) Mark(com.maddyhome.idea.vim.common.Mark) Nullable(org.jetbrains.annotations.Nullable)

Aggregations

Mark (com.maddyhome.idea.vim.common.Mark)21 VirtualFile (com.intellij.openapi.vfs.VirtualFile)6 LogicalPosition (com.intellij.openapi.editor.LogicalPosition)4 Nullable (org.jetbrains.annotations.Nullable)4 FileEditor (com.intellij.openapi.fileEditor.FileEditor)2 TextEditor (com.intellij.openapi.fileEditor.TextEditor)2 Jump (com.maddyhome.idea.vim.common.Jump)2 Element (org.jdom.Element)2 Command (com.maddyhome.idea.vim.command.Command)1 TextRange (com.maddyhome.idea.vim.common.TextRange)1