Add "Unescape replacement string" option (#592)

This commit is contained in:
1024jp 2016-09-14 22:20:35 +09:00
parent e67dfa6c3b
commit b964cc0e2f
8 changed files with 67 additions and 20 deletions

View File

@ -5,6 +5,11 @@ Change Log
develop
--------------------------
### Improvements
- [beta] Add option “Unescape replacement string” to find panel (On by default).
### Known issues
- Some window states are not restored.

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11201" systemVersion="16A320" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="10117"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11201"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="NSViewController">
@ -12,11 +12,11 @@
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customView horizontalCompressionResistancePriority="249" id="n0x-rs-gOH">
<rect key="frame" x="0.0" y="0.0" width="230" height="271"/>
<rect key="frame" x="0.0" y="0.0" width="230" height="289"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<textField horizontalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="ZxT-dv-zkd">
<rect key="frame" x="18" y="244" width="194" height="17"/>
<rect key="frame" x="18" y="262" width="194" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Advanced Find Options" id="Dl6-kv-hhz">
<font key="font" metaFont="systemBold"/>
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
@ -24,7 +24,7 @@
</textFieldCell>
</textField>
<button toolTip="Allow . to match any character, including newline characters (singleline)." translatesAutoresizingMaskIntoConstraints="NO" id="c11-J5-UXF">
<rect key="frame" x="17" y="53" width="170" height="18"/>
<rect key="frame" x="17" y="71" width="170" height="18"/>
<buttonCell key="cell" type="check" title="Dot matches line separators" bezelStyle="regularSquare" imagePosition="left" controlSize="small" inset="2" id="nqr-AM-oJQ">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="smallSystem"/>
@ -34,7 +34,7 @@
</connections>
</button>
<button toolTip="Use Unicode TR#29 to specify word boundaries" translatesAutoresizingMaskIntoConstraints="NO" id="VMh-Tq-bq0">
<rect key="frame" x="17" y="17" width="180" height="18"/>
<rect key="frame" x="17" y="35" width="180" height="18"/>
<buttonCell key="cell" type="check" title="Use Unicode word boundaries" bezelStyle="regularSquare" imagePosition="left" controlSize="small" inset="2" id="5oj-ch-YiX">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="smallSystem"/>
@ -44,7 +44,7 @@
</connections>
</button>
<button toolTip="Exact character-by-character equivalence." translatesAutoresizingMaskIntoConstraints="NO" id="KG4-LQ-sen">
<rect key="frame" x="17" y="137" width="179" height="18"/>
<rect key="frame" x="17" y="155" width="179" height="18"/>
<buttonCell key="cell" type="check" title="Distinguish characters strictly" bezelStyle="regularSquare" imagePosition="left" controlSize="small" inset="2" id="mY4-am-wla">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="smallSystem"/>
@ -54,7 +54,7 @@
</connections>
</button>
<button toolTip="Search ignores width differences in character forms (ex. = a)." translatesAutoresizingMaskIntoConstraints="NO" id="A5O-jt-o7T">
<rect key="frame" x="17" y="101" width="150" height="18"/>
<rect key="frame" x="17" y="119" width="150" height="18"/>
<buttonCell key="cell" type="check" title="Ignore width differences" bezelStyle="regularSquare" imagePosition="left" controlSize="small" inset="2" id="Jug-Dk-JMZ">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="smallSystem"/>
@ -64,7 +64,7 @@
</connections>
</button>
<button toolTip="Allow ^ and $ to match the start and end of lines (multiline)." translatesAutoresizingMaskIntoConstraints="NO" id="Lhw-9C-lgB">
<rect key="frame" x="17" y="35" width="129" height="18"/>
<rect key="frame" x="17" y="53" width="129" height="18"/>
<buttonCell key="cell" type="check" title="Anchors match lines" bezelStyle="regularSquare" imagePosition="left" controlSize="small" state="on" inset="2" id="YXU-NA-BZb">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="smallSystem"/>
@ -74,7 +74,7 @@
</connections>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="fev-mC-rKB">
<rect key="frame" x="18" y="76" width="112" height="14"/>
<rect key="frame" x="18" y="94" width="112" height="14"/>
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Regular Expression" id="Xa9-i4-ELR">
<font key="font" metaFont="smallSystemBold"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@ -82,7 +82,7 @@
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="s9v-U5-5ZM">
<rect key="frame" x="18" y="160" width="87" height="14"/>
<rect key="frame" x="18" y="178" width="87" height="14"/>
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Textual Search" id="d1L-6X-N8c">
<font key="font" metaFont="smallSystemBold"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@ -90,7 +90,7 @@
</textFieldCell>
</textField>
<button translatesAutoresizingMaskIntoConstraints="NO" id="rmT-GL-9fJ">
<rect key="frame" x="17" y="185" width="164" height="18"/>
<rect key="frame" x="17" y="203" width="164" height="18"/>
<buttonCell key="cell" type="check" title="Auto-close progress dialog" bezelStyle="regularSquare" imagePosition="left" controlSize="small" inset="2" id="KBq-zH-H2M">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="smallSystem"/>
@ -100,7 +100,7 @@
</connections>
</button>
<button translatesAutoresizingMaskIntoConstraints="NO" id="B9b-MW-hnQ">
<rect key="frame" x="17" y="221" width="128" height="18"/>
<rect key="frame" x="17" y="239" width="128" height="18"/>
<buttonCell key="cell" type="check" title="Wrap search around" bezelStyle="regularSquare" imagePosition="left" controlSize="small" state="on" inset="2" id="o7S-uI-urg">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="smallSystem"/>
@ -110,7 +110,7 @@
</connections>
</button>
<button translatesAutoresizingMaskIntoConstraints="NO" id="vSw-Kt-7km">
<rect key="frame" x="17" y="203" width="187" height="18"/>
<rect key="frame" x="17" y="221" width="187" height="18"/>
<buttonCell key="cell" type="check" title="Select next match after replace" bezelStyle="regularSquare" imagePosition="left" controlSize="small" state="on" inset="2" id="XBp-LE-3Ry">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="smallSystem"/>
@ -120,7 +120,7 @@
</connections>
</button>
<button toolTip="Search ignores diacritic marks (ex. ö = o)." translatesAutoresizingMaskIntoConstraints="NO" id="YYY-qb-T00">
<rect key="frame" x="17" y="119" width="136" height="18"/>
<rect key="frame" x="17" y="137" width="136" height="18"/>
<buttonCell key="cell" type="check" title="Ignore diacritic marks" bezelStyle="regularSquare" imagePosition="left" controlSize="small" inset="2" id="OUc-5d-N7I">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="smallSystem"/>
@ -129,8 +129,19 @@
<binding destination="hNo-st-CW5" name="value" keyPath="values.findTextIgnoresDiacriticMarks" id="BLc-dO-pM2"/>
</connections>
</button>
<button toolTip="Unescape special characters with backslash in replacement string." translatesAutoresizingMaskIntoConstraints="NO" id="PLV-vr-cdI">
<rect key="frame" x="17" y="17" width="177" height="18"/>
<buttonCell key="cell" type="check" title="Unescape replacement string" bezelStyle="regularSquare" imagePosition="left" controlSize="small" inset="2" id="rTR-zE-Wff">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="smallSystem"/>
</buttonCell>
<connections>
<binding destination="hNo-st-CW5" name="value" keyPath="values.regexUnescapesReplacementString" id="urL-VK-LKH"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstAttribute="bottom" secondItem="PLV-vr-cdI" secondAttribute="bottom" constant="20" symbolic="YES" id="3MK-Fl-QFp"/>
<constraint firstItem="rmT-GL-9fJ" firstAttribute="leading" secondItem="n0x-rs-gOH" secondAttribute="leading" constant="20" symbolic="YES" id="4ff-on-TgQ"/>
<constraint firstItem="B9b-MW-hnQ" firstAttribute="leading" secondItem="n0x-rs-gOH" secondAttribute="leading" constant="20" symbolic="YES" id="6Uy-sY-FEu"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="KG4-LQ-sen" secondAttribute="trailing" constant="20" symbolic="YES" id="7Dv-5E-qlo"/>
@ -158,16 +169,18 @@
<constraint firstItem="s9v-U5-5ZM" firstAttribute="top" secondItem="rmT-GL-9fJ" secondAttribute="bottom" constant="14" id="aBe-mJ-w9p"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="vSw-Kt-7km" secondAttribute="trailing" constant="20" symbolic="YES" id="c1d-6J-L4f"/>
<constraint firstItem="c11-J5-UXF" firstAttribute="leading" secondItem="n0x-rs-gOH" secondAttribute="leading" constant="20" symbolic="YES" id="dR2-ul-Ob0"/>
<constraint firstItem="PLV-vr-cdI" firstAttribute="leading" secondItem="n0x-rs-gOH" secondAttribute="leading" constant="20" symbolic="YES" id="efM-dE-PSa"/>
<constraint firstItem="KG4-LQ-sen" firstAttribute="leading" secondItem="n0x-rs-gOH" secondAttribute="leading" constant="20" symbolic="YES" id="hdv-AA-XLr"/>
<constraint firstAttribute="bottom" secondItem="VMh-Tq-bq0" secondAttribute="bottom" constant="20" symbolic="YES" id="kbm-Mr-4OS"/>
<constraint firstItem="Lhw-9C-lgB" firstAttribute="top" secondItem="c11-J5-UXF" secondAttribute="bottom" constant="6" symbolic="YES" id="kfl-4t-EtN"/>
<constraint firstItem="A5O-jt-o7T" firstAttribute="leading" secondItem="n0x-rs-gOH" secondAttribute="leading" constant="20" symbolic="YES" id="mJB-47-Okl"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="PLV-vr-cdI" secondAttribute="trailing" constant="20" symbolic="YES" id="nsd-6s-Fri"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="rmT-GL-9fJ" secondAttribute="trailing" constant="20" symbolic="YES" id="pIx-sM-esg"/>
<constraint firstItem="VMh-Tq-bq0" firstAttribute="top" secondItem="Lhw-9C-lgB" secondAttribute="bottom" constant="6" symbolic="YES" id="pjs-G0-r7g"/>
<constraint firstItem="VMh-Tq-bq0" firstAttribute="leading" secondItem="n0x-rs-gOH" secondAttribute="leading" constant="20" symbolic="YES" id="u5s-Z1-TgX"/>
<constraint firstItem="A5O-jt-o7T" firstAttribute="top" secondItem="YYY-qb-T00" secondAttribute="bottom" constant="6" symbolic="YES" id="veC-N4-O6u"/>
<constraint firstItem="PLV-vr-cdI" firstAttribute="top" secondItem="VMh-Tq-bq0" secondAttribute="bottom" constant="6" symbolic="YES" id="xeF-Gs-9fp"/>
</constraints>
<point key="canvasLocation" x="157" y="415.5"/>
<point key="canvasLocation" x="157" y="432"/>
</customView>
<userDefaultsController representsSharedInstance="YES" id="hNo-st-CW5"/>
</objects>

View File

@ -257,6 +257,7 @@ extension DefaultKeys {
static let findRegexIsSingleline = DefaultKey<Bool>("findRegexIsSingleline")
static let findRegexIsMultiline = DefaultKey<Bool>("findRegexIsMultiline")
static let findRegexUsesUnicodeBoundaries = DefaultKey<Bool>("regexUsesUnicodeBoundaries")
static let findRegexUnescapesReplacementString = DefaultKey<Bool>("regexUnescapesReplacementString")
// settings that are not in preferences
static let colorCodeType = DefaultKey<Int>("colorCodeType")

View File

@ -149,6 +149,7 @@ let DefaultSettings: [DefaultKeys: Any] = [
.findRegexIsSingleline: false,
.findRegexIsMultiline: true,
.findRegexUsesUnicodeBoundaries: false,
.findRegexUnescapesReplacementString: true,
// ------ settings not in preferences window ------
.colorCodeType: 1,

View File

@ -59,6 +59,7 @@ private protocol TextFinderSettingsProvider {
var inSelection: Bool { get }
var textualOptions: NSString.CompareOptions { get }
var regexOptions: NSRegularExpression.Options { get }
var unescapesReplacementString: Bool { get }
var closesIndicatorWhenDone: Bool { get }
var sharesFindString: Bool { get }
@ -487,7 +488,9 @@ final class TextFinder: NSResponder, TextFinderSettingsProvider {
let string = textView.string else { return }
let integerFormatter = self.integerFormatter
let replacementString = self.replacementString
let replacementString = (self.usesRegularExpression && self.unescapesReplacementString)
? self.replacementString.unescaped
: self.replacementString
let scopeRanges = self.scopeRanges
let inSelection = self.inSelection
@ -727,8 +730,10 @@ final class TextFinder: NSResponder, TextFinderSettingsProvider {
let regex = self.regex()!
guard let match = regex.firstMatch(in: string, range: textView.selectedRange) else { return false }
let tempalte = self.unescapesReplacementString ? self.replacementString.unescaped : self.replacementString
matchedRange = match.range
replacedString = regex.replacementString(for: match, in: string, offset: 0, template: self.replacementString)
replacedString = regex.replacementString(for: match, in: string, offset: 0, template: tempalte)
} else {
matchedRange = (string as NSString).range(of: self.sanitizedFindString, options: self.textualOptions, range: textView.selectedRange)
@ -937,6 +942,13 @@ final class TextFinder: NSResponder, TextFinderSettingsProvider {
}
/// return value from user defaults
fileprivate var unescapesReplacementString: Bool {
return Defaults[.findRegexUnescapesReplacementString]
}
/// return value from user defaults
fileprivate var closesIndicatorWhenDone: Bool {

View File

@ -77,3 +77,8 @@
"5oj-ch-YiX.title" = "Unicode-Wortgrenzen verwenden";
/* Class = "NSButton"; ibShadowedToolTip = "Use Unicode TR#29 to specify word boundaries"; ObjectID = "VMh-Tq-bq0"; */
"VMh-Tq-bq0.ibShadowedToolTip" = "Unicode TR#29 verwenden, um Wortgrenzen zu spezifizieren.";
/* Class = "NSButtonCell"; title = "Unescape replacement string"; ObjectID = "rTR-zE-Wff"; */
"rTR-zE-Wff.title" = "Ersetzungstext maskieren";
/* Class = "NSButton"; ibShadowedToolTip = "Unescape special characters with backslash in replacement string."; ObjectID = "PLV-vr-cdI"; */
"PLV-vr-cdI.ibShadowedToolTip" = "Backslash im Ersetzungstext als Maskierungszeichen interpretieren.";

View File

@ -78,3 +78,8 @@
"5oj-ch-YiX.title" = "Unicode 単語境界を使用";
/* Class = "NSButton"; ibShadowedToolTip = "Use Unicode TR#29 to specify word boundaries"; ObjectID = "VMh-Tq-bq0"; */
"VMh-Tq-bq0.ibShadowedToolTip" = "単語の区切りに Unicode TR#29 定義を使用";
/* Class = "NSButtonCell"; title = "Unescape replacement string"; ObjectID = "rTR-zE-Wff"; */
"rTR-zE-Wff.title" = "置換文字列のエスケープ文字を解釈";
/* Class = "NSButton"; ibShadowedToolTip = "Unescape special characters with backslash in replacement string."; ObjectID = "PLV-vr-cdI"; */
"PLV-vr-cdI.ibShadowedToolTip" = "置換文字列のバックスラッシュをエスケープ文字として解釈";

View File

@ -78,3 +78,8 @@
"5oj-ch-YiX.title" = "使用 Unicode 字词边界";
/* Class = "NSButton"; ibShadowedToolTip = "Use Unicode TR#29 to specify word boundaries"; ObjectID = "VMh-Tq-bq0"; */
"VMh-Tq-bq0.ibShadowedToolTip" = "使用 Unicode TR#29 指定字词边界";
/* Class = "NSButtonCell"; title = "Unescape replacement string"; ObjectID = "rTR-zE-Wff"; */
"rTR-zE-Wff.title" = "Unescape replacement string"; // FIXME: added
/* Class = "NSButton"; ibShadowedToolTip = "Unescape special characters with backslash in replacement string."; ObjectID = "PLV-vr-cdI"; */
"PLV-vr-cdI.ibShadowedToolTip" = "Unescape special characters with backslash in replacement string."; // FIXME: added