提交 ebf5f769 编写于 作者: R Rob Lourens

Allow editing multiple lines of text in the search view - fix #62304

上级 af821e29
......@@ -11,7 +11,6 @@
.monaco-findInput .monaco-inputbox {
font-size: 13px;
width: 100%;
height: 25px;
}
.monaco-findInput > .controls {
......
......@@ -23,6 +23,7 @@ export interface IFindInputOptions extends IFindInputStyles {
readonly width?: number;
readonly validation?: IInputValidator;
readonly label: string;
readonly flexibleHeight?: boolean;
readonly appendCaseSensitiveLabel?: string;
readonly appendWholeWordsLabel?: string;
......@@ -118,7 +119,7 @@ export class FindInput extends Widget {
this.domNode = null;
this.inputBox = null;
this.buildDomNode(options.appendCaseSensitiveLabel || '', options.appendWholeWordsLabel || '', options.appendRegexLabel || '', options.history);
this.buildDomNode(options.appendCaseSensitiveLabel || '', options.appendWholeWordsLabel || '', options.appendRegexLabel || '', options.history, options.flexibleHeight);
if (Boolean(parent)) {
parent.appendChild(this.domNode);
......@@ -287,7 +288,7 @@ export class FindInput extends Widget {
this.inputBox.width = w;
}
private buildDomNode(appendCaseSensitiveLabel: string, appendWholeWordsLabel: string, appendRegexLabel: string, history: string[]): void {
private buildDomNode(appendCaseSensitiveLabel: string, appendWholeWordsLabel: string, appendRegexLabel: string, history: string[], flexibleHeight: boolean): void {
this.domNode = document.createElement('div');
this.domNode.style.width = this.width + 'px';
dom.addClass(this.domNode, 'monaco-findInput');
......@@ -310,7 +311,8 @@ export class FindInput extends Widget {
inputValidationErrorBackground: this.inputValidationErrorBackground,
inputValidationErrorForeground: this.inputValidationErrorForeground,
inputValidationErrorBorder: this.inputValidationErrorBorder,
history
history,
flexibleHeight
}));
this.regex = this._register(new RegexCheckbox({
......
......@@ -291,6 +291,9 @@ export class InputBox extends Widget {
public set width(width: number) {
this.input.style.width = width + 'px';
if (this.mirror) {
this.mirror.style.width = width + 'px';
}
}
public showMessage(message: IMessage, force?: boolean): void {
......
......@@ -29,9 +29,21 @@
margin-left: 17px;
}
.search-view .search-widget .input-box,
.search-view .search-widget .input-box .monaco-inputbox {
height: 25px;
.search-view .search-widget .monaco-inputbox > .wrapper {
height: 100%;
}
.search-view .search-widget .monaco-inputbox > .wrapper > .mirror {
max-height: 134px;
}
.search-view .monaco-inputbox > .wrapper > textarea.input {
overflow: initial;
height: 26px; /* set initial height before measure */
}
.search-view .monaco-inputbox > .wrapper > textarea.input::-webkit-scrollbar {
display: none;
}
.search-view .search-widget .monaco-findInput {
......@@ -39,6 +51,10 @@
vertical-align: middle;
}
.search-view .search-widget .monaco-findInput > .controls {
top: 4px; /* Adjust controls, search view input box is slighty taller than find widget due to measurement */
}
.search-view .search-widget .replace-container {
margin-top: 6px;
position: relative;
......
......@@ -281,7 +281,8 @@ export class SearchWidget extends Widget {
appendCaseSensitiveLabel: appendKeyBindingLabel('', this.keyBindingService.lookupKeybinding(Constants.ToggleCaseSensitiveCommandId), this.keyBindingService),
appendWholeWordsLabel: appendKeyBindingLabel('', this.keyBindingService.lookupKeybinding(Constants.ToggleWholeWordCommandId), this.keyBindingService),
appendRegexLabel: appendKeyBindingLabel('', this.keyBindingService.lookupKeybinding(Constants.ToggleRegexCommandId), this.keyBindingService),
history: options.searchHistory
history: options.searchHistory,
flexibleHeight: true
};
let searchInputContainer = dom.append(parent, dom.$('.search-container.input-box'));
......@@ -329,7 +330,8 @@ export class SearchWidget extends Widget {
this.replaceInput = this._register(new ContextScopedHistoryInputBox(replaceBox, this.contextViewService, {
ariaLabel: nls.localize('label.Replace', 'Replace: Type replace term and press Enter to preview or Escape to cancel'),
placeholder: nls.localize('search.replace.placeHolder', "Replace"),
history: options.replaceHistory || []
history: options.replaceHistory || [],
flexibleHeight: true
}, this.contextKeyService));
this._register(attachInputBoxStyler(this.replaceInput, this.themeService));
this.onkeydown(this.replaceInput.inputElement, (keyboardEvent) => this.onReplaceInputKeyDown(keyboardEvent));
......@@ -376,6 +378,7 @@ export class SearchWidget extends Widget {
if (currentState !== newState) {
this.replaceActive.set(newState);
this._onReplaceStateChange.fire(newState);
this.replaceInput.layout();
}
}
......@@ -429,6 +432,20 @@ export class SearchWidget extends Widget {
}
keyboardEvent.preventDefault();
}
else if (keyboardEvent.equals(KeyCode.UpArrow)) {
const ta = this.searchInput.domNode.querySelector('textarea');
if (ta && ta.selectionStart > 0) {
keyboardEvent.stopPropagation();
}
}
else if (keyboardEvent.equals(KeyCode.DownArrow)) {
const ta = this.searchInput.domNode.querySelector('textarea');
if (ta && ta.selectionEnd < ta.value.length) {
keyboardEvent.stopPropagation();
}
}
}
private onCaseSensitiveKeyDown(keyboardEvent: IKeyboardEvent) {
......@@ -466,6 +483,20 @@ export class SearchWidget extends Widget {
this.searchInput.focus();
keyboardEvent.preventDefault();
}
else if (keyboardEvent.equals(KeyCode.UpArrow)) {
const ta = this.searchInput.domNode.querySelector('textarea');
if (ta && ta.selectionStart > 0) {
keyboardEvent.stopPropagation();
}
}
else if (keyboardEvent.equals(KeyCode.DownArrow)) {
const ta = this.searchInput.domNode.querySelector('textarea');
if (ta && ta.selectionEnd < ta.value.length) {
keyboardEvent.stopPropagation();
}
}
}
private onReplaceActionbarKeyDown(keyboardEvent: IKeyboardEvent) {
......
......@@ -67,10 +67,8 @@ export class QueryBuilder {
) { }
text(contentPattern: IPatternInfo, folderResources?: uri[], options: ITextQueryBuilderOptions = {}): ITextQuery {
contentPattern.isCaseSensitive = this.isCaseSensitive(contentPattern);
contentPattern.isMultiline = this.isMultiline(contentPattern);
contentPattern = this.getContentPattern(contentPattern);
const searchConfig = this.configurationService.getValue<ISearchConfiguration>();
contentPattern.wordSeparators = searchConfig.editor.wordSeparators;
const fallbackToPCRE = folderResources && folderResources.some(folder => {
const folderConfig = this.configurationService.getValue<ISearchConfiguration>({ resource: folder });
......@@ -91,6 +89,28 @@ export class QueryBuilder {
};
}
/**
* Adjusts input pattern for config
*/
private getContentPattern(inputPattern: IPatternInfo): IPatternInfo {
const searchConfig = this.configurationService.getValue<ISearchConfiguration>();
const newPattern = {
...inputPattern,
wordSeparators: searchConfig.editor.wordSeparators
};
if (this.isCaseSensitive(inputPattern)) {
newPattern.isCaseSensitive = true;
}
if (this.isMultiline(inputPattern)) {
newPattern.isMultiline = true;
}
return newPattern;
}
file(folderResources: uri[] | undefined, options: IFileQueryBuilderOptions = {}): IFileQuery {
const commonQuery = this.commonQuery(folderResources, options);
return <IFileQuery>{
......@@ -165,6 +185,10 @@ export class QueryBuilder {
return true;
}
if (contentPattern.pattern.indexOf('\n') >= 0) {
return true;
}
return false;
}
......
......@@ -7,7 +7,7 @@ import * as cp from 'child_process';
import { EventEmitter } from 'events';
import * as path from 'path';
import { NodeStringDecoder, StringDecoder } from 'string_decoder';
import { createRegExp, startsWith, startsWithUTF8BOM, stripUTF8BOM } from 'vs/base/common/strings';
import { createRegExp, startsWith, startsWithUTF8BOM, stripUTF8BOM, escapeRegExpCharacters } from 'vs/base/common/strings';
import { URI } from 'vs/base/common/uri';
import { IExtendedExtensionSearchOptions, SearchError, SearchErrorCode, serializeSearchError } from 'vs/platform/search/common/search';
import * as vscode from 'vscode';
......@@ -343,6 +343,11 @@ function getRgArgs(query: vscode.TextSearchQuery, options: vscode.TextSearchOpti
pattern = '\\-\\-';
}
if (query.isMultiline && !query.isRegExp) {
query.pattern = escapeRegExpCharacters(query.pattern);
query.isRegExp = true;
}
if ((<IExtendedExtensionSearchOptions>options).usePCRE2) {
args.push('--pcre2');
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册