mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-19 04:51:24 +07:00
IDEA-110607 Double clicking space/tab characters should select all space/tab characters until it encounters another type of character
Better word unselect GitOrigin-RevId: 5519cf57e79052e7472d554631865263531cf7d6
This commit is contained in:
committed by
intellij-monorepo-bot
parent
dd712b6535
commit
92ac1b6044
@@ -1,7 +1,7 @@
|
||||
class C {
|
||||
private void foo() {
|
||||
<selection>{
|
||||
<caret>
|
||||
}</selection>
|
||||
{
|
||||
<selection> <caret>
|
||||
</selection> }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
class C {
|
||||
private void foo() {
|
||||
<selection> {
|
||||
<selection>{
|
||||
<caret>
|
||||
}
|
||||
</selection> }
|
||||
}
|
||||
}</selection>
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
class C {
|
||||
private void foo() <selection>{
|
||||
{
|
||||
private void foo() {
|
||||
<selection> {
|
||||
<caret>
|
||||
}
|
||||
}</selection>
|
||||
}
|
||||
</selection> }
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
class C {
|
||||
private void foo() <selection>{
|
||||
{
|
||||
<caret>
|
||||
}
|
||||
}</selection>
|
||||
}
|
||||
@@ -857,6 +857,7 @@ advanced.setting.editor.normalize.splits=Equalize proportions in nested splits
|
||||
advanced.setting.editor.normalize.splits.description=Adjust splitters to keep space equally distributed after split/unsplit.
|
||||
advanced.setting.editor.open.inactive.splitter=When navigating to a file, prefer selecting existing tab in inactive split pane
|
||||
advanced.setting.editor.keep.pinned.tabs.on.left=Keep pinned tabs on the left
|
||||
advanced.setting.editor.selection.expand-whitespaces=Select whitespace characters with 'Extend Selection'
|
||||
advanced.setting.terminal.buffer.max.lines.count=Terminal scrollback buffer size
|
||||
advanced.setting.terminal.buffer.max.lines.count.trailingLabel=lines
|
||||
advanced.setting.terminal.escape.moves.focus.to.editor=Move focus to the editor with Escape
|
||||
|
||||
@@ -127,7 +127,7 @@ public class SelectWordHandler extends EditorActionHandler.ForEachCaret {
|
||||
}
|
||||
}
|
||||
|
||||
if (!(element instanceof PsiWhiteSpace && SelectWordUtil.canWhiteSpaceBeExpanded((PsiWhiteSpace) element, caretOffset, caret))) {
|
||||
if (!(element instanceof PsiWhiteSpace && SelectWordUtil.canWhiteSpaceBeExpanded((PsiWhiteSpace) element, caretOffset, caret, caret.getEditor()))) {
|
||||
while (element instanceof PsiWhiteSpace || element != null && StringUtil.isEmptyOrSpaces(element.getText())) {
|
||||
while (element.getNextSibling() == null) {
|
||||
if (element instanceof PsiFile) return null;
|
||||
|
||||
@@ -8,8 +8,10 @@ import com.intellij.lexer.Lexer;
|
||||
import com.intellij.openapi.editor.Caret;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.actions.EditorActionUtil;
|
||||
import com.intellij.openapi.options.advanced.AdvancedSettings;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.IndexNotReadyException;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.util.Processor;
|
||||
@@ -270,16 +272,24 @@ public final class SelectWordUtil {
|
||||
* Returns if there is any expandable whitespace belonging to the given psiWhiteSpace
|
||||
* by any side of a caret at specified cursorPosition
|
||||
*/
|
||||
public static boolean canWhiteSpaceBeExpanded(PsiWhiteSpace psiWhiteSpace, int cursorPosition, Caret caret) {
|
||||
if (caret.hasSelection() && psiWhiteSpace.getTextRange().contains(caret.getSelectionRange())) return false;
|
||||
public static boolean canWhiteSpaceBeExpanded(@NotNull PsiWhiteSpace psiWhiteSpace, int cursorPosition, @Nullable Caret caret, @NotNull Editor editor) {
|
||||
if (!AdvancedSettings.getBoolean("editor.selection.expand-whitespaces")) return false;
|
||||
|
||||
int beforeOffset = caret.hasSelection()? caret.getSelectionStart() : cursorPosition;
|
||||
Character charBeforeCursor = getCharBeforeCursorInPsiElement(psiWhiteSpace, beforeOffset);
|
||||
if (charBeforeCursor != null && isExpandableWhiteSpace(charBeforeCursor)) return true;
|
||||
TextRange selectionRange = caret != null && caret.hasSelection() ? caret.getSelectionRange() : null;
|
||||
if (selectionRange != null && !psiWhiteSpace.getTextRange().contains(selectionRange)) return false;
|
||||
|
||||
int startOffset = selectionRange == null ? cursorPosition : selectionRange.getStartOffset();
|
||||
Character charBeforeStartOffset = getCharBeforeCursorInPsiElement(psiWhiteSpace, startOffset);
|
||||
if (charBeforeStartOffset != null && isExpandableWhiteSpace(charBeforeStartOffset)) return true;
|
||||
|
||||
int afterOffset = caret.hasSelection()? caret.getSelectionEnd() : cursorPosition;
|
||||
Character charAfterCursor = getCharAfterCursorInPsiElement(psiWhiteSpace, afterOffset);
|
||||
if (charAfterCursor != null && isExpandableWhiteSpace(charAfterCursor)) return true;
|
||||
int endOffset = selectionRange == null ? cursorPosition : selectionRange.getEndOffset();
|
||||
Character charBeforeEndOffset = getCharBeforeCursorInPsiElement(psiWhiteSpace, endOffset);
|
||||
Character charAfterEndOffset = getCharAfterCursorInPsiElement(psiWhiteSpace, endOffset);
|
||||
if (charAfterEndOffset != null && isExpandableWhiteSpace(charAfterEndOffset)) return true;
|
||||
if (charBeforeEndOffset != null && isExpandableWhiteSpace(charBeforeEndOffset)
|
||||
&& charAfterEndOffset != null && Character.isWhitespace(charAfterEndOffset)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiWhiteSpace;
|
||||
import com.intellij.util.Processor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class UnSelectWordHandler extends EditorActionHandler.ForEachCaret {
|
||||
private final EditorActionHandler myOriginalHandler;
|
||||
@@ -85,54 +86,23 @@ public class UnSelectWordHandler extends EditorActionHandler.ForEachCaret {
|
||||
}
|
||||
}
|
||||
|
||||
final TextRange selectionRange = new TextRange(editor.getSelectionModel().getSelectionStart(), editor.getSelectionModel().getSelectionEnd());
|
||||
MaxRangeProcessor rangeProcessor = new MaxRangeProcessor(selectionRange, editor, cursorOffset);
|
||||
if (element instanceof PsiWhiteSpace) {
|
||||
PsiElement nextSibling = element.getNextSibling();
|
||||
if (nextSibling == null) {
|
||||
element = element.getParent();
|
||||
if (element == null || element instanceof PsiFile) {
|
||||
return;
|
||||
}
|
||||
nextSibling = element.getNextSibling();
|
||||
if (nextSibling == null) {
|
||||
return;
|
||||
}
|
||||
if (SelectWordUtil.canWhiteSpaceBeExpanded((PsiWhiteSpace) element, cursorOffset, null, editor)) {
|
||||
SelectWordUtil.processRanges(element, text, cursorOffset, editor, rangeProcessor);
|
||||
}
|
||||
element = nextSibling;
|
||||
cursorOffset = element.getTextRange().getStartOffset();
|
||||
PsiElement sibling = findNextSibling(element);
|
||||
if (sibling != null) {
|
||||
int siblingOffset = sibling.getTextRange().getStartOffset();
|
||||
rangeProcessor.setCursorOffset(siblingOffset);
|
||||
SelectWordUtil.processRanges(sibling, text, siblingOffset, editor, rangeProcessor);
|
||||
}
|
||||
} else {
|
||||
SelectWordUtil.processRanges(element, text, cursorOffset, editor, rangeProcessor);
|
||||
}
|
||||
|
||||
final TextRange selectionRange = new TextRange(editor.getSelectionModel().getSelectionStart(), editor.getSelectionModel().getSelectionEnd());
|
||||
|
||||
final Ref<TextRange> maximumRange = new Ref<>();
|
||||
|
||||
final int finalCursorOffset = cursorOffset;
|
||||
SelectWordUtil.processRanges(element, text, cursorOffset, editor, new Processor<>() {
|
||||
@Override
|
||||
public boolean process(TextRange range) {
|
||||
range = expandToFoldingBoundaries(range);
|
||||
if (selectionRange.contains(range) && !range.equals(selectionRange) &&
|
||||
(range.contains(finalCursorOffset) || finalCursorOffset == range.getEndOffset())) {
|
||||
if (maximumRange.get() == null || range.contains(maximumRange.get())) {
|
||||
maximumRange.set(range);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private TextRange expandToFoldingBoundaries(TextRange range) {
|
||||
int startOffset = range.getStartOffset();
|
||||
FoldRegion region = editor.getFoldingModel().getCollapsedRegionAtOffset(startOffset);
|
||||
if (region != null) startOffset = region.getStartOffset();
|
||||
int endOffset = range.getEndOffset();
|
||||
region = editor.getFoldingModel().getCollapsedRegionAtOffset(endOffset);
|
||||
if (region != null && endOffset > region.getStartOffset()) endOffset = region.getEndOffset();
|
||||
return new TextRange(startOffset, endOffset);
|
||||
}
|
||||
});
|
||||
|
||||
TextRange range = maximumRange.get();
|
||||
|
||||
TextRange range = rangeProcessor.getMaximumRange();
|
||||
if (range == null) {
|
||||
editor.getSelectionModel().setSelection(cursorOffset, cursorOffset);
|
||||
}
|
||||
@@ -140,4 +110,63 @@ public class UnSelectWordHandler extends EditorActionHandler.ForEachCaret {
|
||||
editor.getSelectionModel().setSelection(range.getStartOffset(), range.getEndOffset());
|
||||
}
|
||||
}
|
||||
|
||||
private static @Nullable PsiElement findNextSibling(PsiElement element) {
|
||||
PsiElement nextSibling = element.getNextSibling();
|
||||
if (nextSibling == null) {
|
||||
element = element.getParent();
|
||||
if (element == null || element instanceof PsiFile) {
|
||||
return null;
|
||||
}
|
||||
nextSibling = element.getNextSibling();
|
||||
if (nextSibling == null) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return nextSibling;
|
||||
}
|
||||
|
||||
private static class MaxRangeProcessor implements Processor<TextRange> {
|
||||
private final Ref<TextRange> maximumRange;
|
||||
private final TextRange selectionRange;
|
||||
private final Editor editor;
|
||||
private int cursorOffset;
|
||||
|
||||
private void setCursorOffset(int cursorOffset) {
|
||||
this.cursorOffset = cursorOffset;
|
||||
}
|
||||
|
||||
private MaxRangeProcessor(TextRange selectionRange, Editor editor, int cursorOffset) {
|
||||
this.maximumRange = new Ref<>();
|
||||
this.selectionRange = selectionRange;
|
||||
this.editor = editor;
|
||||
this.cursorOffset = cursorOffset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean process(TextRange range) {
|
||||
range = expandToFoldingBoundaries(range);
|
||||
if (selectionRange.contains(range) && !range.equals(selectionRange) &&
|
||||
(range.contains(cursorOffset) || cursorOffset == range.getEndOffset())) {
|
||||
if (maximumRange.get() == null || range.contains(maximumRange.get())) {
|
||||
maximumRange.set(range);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private TextRange expandToFoldingBoundaries(TextRange range) {
|
||||
int startOffset = range.getStartOffset();
|
||||
FoldRegion region = editor.getFoldingModel().getCollapsedRegionAtOffset(startOffset);
|
||||
if (region != null) startOffset = region.getStartOffset();
|
||||
int endOffset = range.getEndOffset();
|
||||
region = editor.getFoldingModel().getCollapsedRegionAtOffset(endOffset);
|
||||
if (region != null && endOffset > region.getStartOffset()) endOffset = region.getEndOffset();
|
||||
return new TextRange(startOffset, endOffset);
|
||||
}
|
||||
|
||||
private TextRange getMaximumRange() {
|
||||
return maximumRange.get();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1385,6 +1385,7 @@
|
||||
<advancedSetting id="editor.tab.painting" enumClass="com.intellij.openapi.editor.impl.TabCharacterPaintMode" default="HORIZONTAL_LINE" groupKey="group.advanced.settings.editor"/>
|
||||
<advancedSetting id="editor.distraction.free.margin" default="-1" groupKey="group.advanced.settings.editor"/>
|
||||
<advancedSetting id="editor.soft.wrap.force.limit" default="100000" groupKey="group.advanced.settings.editor"/>
|
||||
<advancedSetting id="editor.selection.expand-whitespaces" default="true" groupKey="group.advanced.settings.editor"/>
|
||||
<advancedSetting id="editor.open.inactive.splitter" default="true" groupKey="group.advanced.settings.editor.tabs"/>
|
||||
<advancedSetting id="editor.reuse.not.modified.tabs" default="false" groupKey="group.advanced.settings.editor.tabs" service="com.intellij.ide.ui.UISettings" property="reuseNotModifiedTabs"/>
|
||||
<advancedSetting id="editor.open.tabs.in.main.window" default="false" groupKey="group.advanced.settings.editor.tabs" service="com.intellij.ide.ui.UISettings" property="openTabsInMainWindow"/>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
class SimpleClass <selection>{
|
||||
<caret>
|
||||
}</selection>
|
||||
class SimpleClass {
|
||||
<selection> <caret>
|
||||
</selection>}
|
||||
@@ -1,3 +1,3 @@
|
||||
<selection>class SimpleClass {
|
||||
class SimpleClass <selection>{
|
||||
<caret>
|
||||
}</selection>
|
||||
Reference in New Issue
Block a user