1+ /*
2+ THIS IS A GENERATED/BUNDLED FILE BY ROLLUP
3+ if you want to view the source visit the plugins github repository
4+ */
5+
6+ 'use strict' ;
7+
8+ var obsidian = require ( 'obsidian' ) ;
9+
10+ /*! *****************************************************************************
11+ Copyright (c) Microsoft Corporation.
12+
13+ Permission to use, copy, modify, and/or distribute this software for any
14+ purpose with or without fee is hereby granted.
15+
16+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
17+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
19+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
20+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
21+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22+ PERFORMANCE OF THIS SOFTWARE.
23+ ***************************************************************************** */
24+
25+ function __awaiter ( thisArg , _arguments , P , generator ) {
26+ function adopt ( value ) { return value instanceof P ? value : new P ( function ( resolve ) { resolve ( value ) ; } ) ; }
27+ return new ( P || ( P = Promise ) ) ( function ( resolve , reject ) {
28+ function fulfilled ( value ) { try { step ( generator . next ( value ) ) ; } catch ( e ) { reject ( e ) ; } }
29+ function rejected ( value ) { try { step ( generator [ "throw" ] ( value ) ) ; } catch ( e ) { reject ( e ) ; } }
30+ function step ( result ) { result . done ? resolve ( result . value ) : adopt ( result . value ) . then ( fulfilled , rejected ) ; }
31+ step ( ( generator = generator . apply ( thisArg , _arguments || [ ] ) ) . next ( ) ) ;
32+ } ) ;
33+ }
34+
35+ const DEFAULT_SETTINGS = {
36+ findText : '' ,
37+ replaceText : '' ,
38+ useRegEx : true ,
39+ selOnly : false ,
40+ caseInsensitive : false ,
41+ processLineBreak : false ,
42+ processTab : false ,
43+ prefillFind : false
44+ } ;
45+ // logThreshold: 0 ... only error messages
46+ // 9 ... verbose output
47+ const logThreshold = 9 ;
48+ const logger = ( logString , logLevel = 0 ) => { if ( logLevel <= logThreshold )
49+ console . log ( 'RegexFiRe: ' + logString ) ; } ;
50+ class RegexFindReplacePlugin extends obsidian . Plugin {
51+ onload ( ) {
52+ return __awaiter ( this , void 0 , void 0 , function * ( ) {
53+ logger ( 'Loading Plugin...' , 9 ) ;
54+ yield this . loadSettings ( ) ;
55+ this . addSettingTab ( new RegexFindReplaceSettingTab ( this . app , this ) ) ;
56+ this . addCommand ( {
57+ id : 'obsidian-regex-replace' ,
58+ name : 'Find and Replace using regular expressions' ,
59+ editorCallback : ( editor ) => {
60+ new FindAndReplaceModal ( this . app , editor , this . settings , this ) . open ( ) ;
61+ } ,
62+ } ) ;
63+ } ) ;
64+ }
65+ onunload ( ) {
66+ logger ( 'Bye!' , 9 ) ;
67+ }
68+ loadSettings ( ) {
69+ return __awaiter ( this , void 0 , void 0 , function * ( ) {
70+ logger ( 'Loading Settings...' , 6 ) ;
71+ this . settings = Object . assign ( { } , DEFAULT_SETTINGS , yield this . loadData ( ) ) ;
72+ logger ( ' findVal: ' + this . settings . findText , 6 ) ;
73+ logger ( ' replaceText: ' + this . settings . replaceText , 6 ) ;
74+ logger ( ' caseInsensitive: ' + this . settings . caseInsensitive , 6 ) ;
75+ logger ( ' processLineBreak: ' + this . settings . processLineBreak , 6 ) ;
76+ } ) ;
77+ }
78+ saveSettings ( ) {
79+ return __awaiter ( this , void 0 , void 0 , function * ( ) {
80+ yield this . saveData ( this . settings ) ;
81+ } ) ;
82+ }
83+ }
84+ class FindAndReplaceModal extends obsidian . Modal {
85+ constructor ( app , editor , settings , plugin ) {
86+ super ( app ) ;
87+ this . editor = editor ;
88+ this . settings = settings ;
89+ this . plugin = plugin ;
90+ }
91+ onOpen ( ) {
92+ const { contentEl, titleEl, editor, modalEl } = this ;
93+ modalEl . addClass ( 'find-replace-modal' ) ;
94+ titleEl . setText ( 'Regex Find/Replace' ) ;
95+ const rowClass = 'row' ;
96+ const divClass = 'div' ;
97+ const noSelection = editor . getSelection ( ) === '' ;
98+ let regexFlags = 'gm' ;
99+ if ( this . settings . caseInsensitive )
100+ regexFlags = regexFlags . concat ( 'i' ) ;
101+ logger ( 'No text selected?: ' + noSelection , 9 ) ;
102+ const addTextComponent = ( label , placeholder , postfix = '' ) => {
103+ const containerEl = document . createElement ( divClass ) ;
104+ containerEl . addClass ( rowClass ) ;
105+ const targetEl = document . createElement ( divClass ) ;
106+ targetEl . addClass ( 'input-wrapper' ) ;
107+ const labelEl = document . createElement ( divClass ) ;
108+ labelEl . addClass ( 'input-label' ) ;
109+ labelEl . setText ( label ) ;
110+ const labelEl2 = document . createElement ( divClass ) ;
111+ labelEl2 . addClass ( 'postfix-label' ) ;
112+ labelEl2 . setText ( postfix ) ;
113+ containerEl . appendChild ( labelEl ) ;
114+ containerEl . appendChild ( targetEl ) ;
115+ containerEl . appendChild ( labelEl2 ) ;
116+ const component = new obsidian . TextComponent ( targetEl ) ;
117+ component . setPlaceholder ( placeholder ) ;
118+ contentEl . append ( containerEl ) ;
119+ return [ component , labelEl2 ] ;
120+ } ;
121+ const addToggleComponent = ( label , tooltip , hide = false ) => {
122+ const containerEl = document . createElement ( divClass ) ;
123+ containerEl . addClass ( rowClass ) ;
124+ const targetEl = document . createElement ( divClass ) ;
125+ targetEl . addClass ( rowClass ) ;
126+ const component = new obsidian . ToggleComponent ( targetEl ) ;
127+ component . setTooltip ( tooltip ) ;
128+ const labelEl = document . createElement ( divClass ) ;
129+ labelEl . addClass ( 'check-label' ) ;
130+ labelEl . setText ( label ) ;
131+ containerEl . appendChild ( labelEl ) ;
132+ containerEl . appendChild ( targetEl ) ;
133+ if ( ! hide )
134+ contentEl . appendChild ( containerEl ) ;
135+ return component ;
136+ } ;
137+ // Create input fields
138+ const findRow = addTextComponent ( 'Find:' , 'e.g. (.*)' , '/' + regexFlags ) ;
139+ const findInputComponent = findRow [ 0 ] ;
140+ const findRegexFlags = findRow [ 1 ] ;
141+ const replaceRow = addTextComponent ( 'Replace:' , 'e.g. $1' , this . settings . processLineBreak ? '\\n=LF' : '' ) ;
142+ const replaceWithInputComponent = replaceRow [ 0 ] ;
143+ // Create and show regular expression toggle switch
144+ const regToggleComponent = addToggleComponent ( 'Use regular expressions' , 'If enabled, regular expressions in the find field are processed as such, and regex groups might be addressed in the replace field' ) ;
145+ // Update regex-flags label if regular expressions are enabled or disabled
146+ regToggleComponent . onChange ( regNew => {
147+ if ( regNew ) {
148+ findRegexFlags . setText ( '/' + regexFlags ) ;
149+ }
150+ else {
151+ findRegexFlags . setText ( '' ) ;
152+ }
153+ } ) ;
154+ // Create and show selection toggle switch only if any text is selected
155+ const selToggleComponent = addToggleComponent ( 'Replace only in selection' , 'If enabled, replaces only occurances in the currently selected text' , noSelection ) ;
156+ // Create Buttons
157+ const buttonContainerEl = document . createElement ( divClass ) ;
158+ buttonContainerEl . addClass ( rowClass ) ;
159+ const submitButtonTarget = document . createElement ( divClass ) ;
160+ submitButtonTarget . addClass ( 'button-wrapper' ) ;
161+ submitButtonTarget . addClass ( rowClass ) ;
162+ const cancelButtonTarget = document . createElement ( divClass ) ;
163+ cancelButtonTarget . addClass ( 'button-wrapper' ) ;
164+ cancelButtonTarget . addClass ( rowClass ) ;
165+ const submitButtonComponent = new obsidian . ButtonComponent ( submitButtonTarget ) ;
166+ const cancelButtonComponent = new obsidian . ButtonComponent ( cancelButtonTarget ) ;
167+ cancelButtonComponent . setButtonText ( 'Cancel' ) ;
168+ cancelButtonComponent . onClick ( ( ) => {
169+ logger ( 'Action cancelled.' , 8 ) ;
170+ this . close ( ) ;
171+ } ) ;
172+ submitButtonComponent . setButtonText ( 'Replace All' ) ;
173+ submitButtonComponent . setCta ( ) ;
174+ submitButtonComponent . onClick ( ( ) => {
175+ let resultString = 'No match' ;
176+ let scope = '' ;
177+ const searchString = findInputComponent . getValue ( ) ;
178+ let replaceString = replaceWithInputComponent . getValue ( ) ;
179+ const selectedText = editor . getSelection ( ) ;
180+ if ( searchString === '' ) {
181+ new obsidian . Notice ( 'Nothing to search for!' ) ;
182+ return ;
183+ }
184+ // Replace line breaks in find-field if option is enabled
185+ if ( this . settings . processLineBreak ) {
186+ logger ( 'Replacing linebreaks in replace-field' , 9 ) ;
187+ logger ( ' old: ' + replaceString , 9 ) ;
188+ replaceString = replaceString . replace ( / \\ n / gm, '\n' ) ;
189+ logger ( ' new: ' + replaceString , 9 ) ;
190+ }
191+ // Replace line breaks in find-field if option is enabled
192+ if ( this . settings . processTab ) {
193+ logger ( 'Replacing tabs in replace-field' , 9 ) ;
194+ logger ( ' old: ' + replaceString , 9 ) ;
195+ replaceString = replaceString . replace ( / \\ t / gm, '\t' ) ;
196+ logger ( ' new: ' + replaceString , 9 ) ;
197+ }
198+ // Check if regular expressions should be used
199+ if ( regToggleComponent . getValue ( ) ) {
200+ logger ( 'USING regex with flags: ' + regexFlags , 8 ) ;
201+ const searchRegex = new RegExp ( searchString , regexFlags ) ;
202+ if ( ! selToggleComponent . getValue ( ) ) {
203+ logger ( ' SCOPE: Full document' , 9 ) ;
204+ const documentText = editor . getValue ( ) ;
205+ const rresult = documentText . match ( searchRegex ) ;
206+ if ( rresult ) {
207+ editor . setValue ( documentText . replace ( searchRegex , replaceString ) ) ;
208+ resultString = `Made ${ rresult . length } replacement(s) in document` ;
209+ }
210+ }
211+ else {
212+ logger ( ' SCOPE: Selection' , 9 ) ;
213+ const rresult = selectedText . match ( searchRegex ) ;
214+ if ( rresult ) {
215+ editor . replaceSelection ( selectedText . replace ( searchRegex , replaceString ) ) ;
216+ resultString = `Made ${ rresult . length } replacement(s) in selection` ;
217+ }
218+ }
219+ }
220+ else {
221+ logger ( 'NOT using regex' , 8 ) ;
222+ let nrOfHits = 0 ;
223+ if ( ! selToggleComponent . getValue ( ) ) {
224+ logger ( ' SCOPE: Full document' , 9 ) ;
225+ scope = 'selection' ;
226+ const documentText = editor . getValue ( ) ;
227+ const documentSplit = documentText . split ( searchString ) ;
228+ nrOfHits = documentSplit . length - 1 ;
229+ editor . setValue ( documentSplit . join ( replaceString ) ) ;
230+ }
231+ else {
232+ logger ( ' SCOPE: Selection' , 9 ) ;
233+ scope = 'document' ;
234+ const selectedSplit = selectedText . split ( searchString ) ;
235+ nrOfHits = selectedSplit . length - 1 ;
236+ editor . replaceSelection ( selectedSplit . join ( replaceString ) ) ;
237+ }
238+ resultString = `Made ${ nrOfHits } replacement(s) in ${ scope } ` ;
239+ }
240+ // Saving settings (find/replace text and toggle switch states)
241+ this . settings . findText = searchString ;
242+ this . settings . replaceText = replaceString ;
243+ this . settings . useRegEx = regToggleComponent . getValue ( ) ;
244+ this . settings . selOnly = selToggleComponent . getValue ( ) ;
245+ this . plugin . saveData ( this . settings ) ;
246+ this . close ( ) ;
247+ new obsidian . Notice ( resultString ) ;
248+ } ) ;
249+ // Apply settings
250+ regToggleComponent . setValue ( this . settings . useRegEx ) ;
251+ selToggleComponent . setValue ( this . settings . selOnly ) ;
252+ replaceWithInputComponent . setValue ( this . settings . replaceText ) ;
253+ // Check if the prefill find option is enabled and the selection does not contain linebreaks
254+ if ( this . settings . prefillFind && editor . getSelection ( ) . indexOf ( '\n' ) < 0 && ! noSelection ) {
255+ logger ( 'Found selection without linebreaks and option is enabled -> fill' , 9 ) ;
256+ findInputComponent . setValue ( editor . getSelection ( ) ) ;
257+ selToggleComponent . setValue ( false ) ;
258+ }
259+ else {
260+ logger ( 'Restore find text' , 9 ) ;
261+ findInputComponent . setValue ( this . settings . findText ) ;
262+ }
263+ // Add button row to dialog
264+ buttonContainerEl . appendChild ( submitButtonTarget ) ;
265+ buttonContainerEl . appendChild ( cancelButtonTarget ) ;
266+ contentEl . appendChild ( buttonContainerEl ) ;
267+ // If no text is selected, disable selection-toggle-switch
268+ if ( noSelection )
269+ selToggleComponent . setValue ( false ) ;
270+ }
271+ onClose ( ) {
272+ const { contentEl } = this ;
273+ contentEl . empty ( ) ;
274+ }
275+ }
276+ class RegexFindReplaceSettingTab extends obsidian . PluginSettingTab {
277+ constructor ( app , plugin ) {
278+ super ( app , plugin ) ;
279+ this . plugin = plugin ;
280+ }
281+ display ( ) {
282+ const { containerEl } = this ;
283+ containerEl . empty ( ) ;
284+ containerEl . createEl ( 'h4' , { text : 'Regular Expression Settings' } ) ;
285+ new obsidian . Setting ( containerEl )
286+ . setName ( 'Case Insensitive' )
287+ . setDesc ( 'When using regular expressions, apply the \'/i\' modifier for case insensitive search)' )
288+ . addToggle ( toggle => toggle
289+ . setValue ( this . plugin . settings . caseInsensitive )
290+ . onChange ( ( value ) => __awaiter ( this , void 0 , void 0 , function * ( ) {
291+ logger ( 'Settings update: caseInsensitive: ' + value ) ;
292+ this . plugin . settings . caseInsensitive = value ;
293+ yield this . plugin . saveSettings ( ) ;
294+ } ) ) ) ;
295+ containerEl . createEl ( 'h4' , { text : 'General Settings' } ) ;
296+ new obsidian . Setting ( containerEl )
297+ . setName ( 'Process \\n as line break' )
298+ . setDesc ( 'When \'\\n\' is used in the replace field, a \'line break\' will be inserted accordingly' )
299+ . addToggle ( toggle => toggle
300+ . setValue ( this . plugin . settings . processLineBreak )
301+ . onChange ( ( value ) => __awaiter ( this , void 0 , void 0 , function * ( ) {
302+ logger ( 'Settings update: processLineBreak: ' + value ) ;
303+ this . plugin . settings . processLineBreak = value ;
304+ yield this . plugin . saveSettings ( ) ;
305+ } ) ) ) ;
306+ new obsidian . Setting ( containerEl )
307+ . setName ( 'Prefill Find Field' )
308+ . setDesc ( 'Copy the currently selected text (if any) into the \'Find\' text field. This setting is only applied if the selection does not contain linebreaks' )
309+ . addToggle ( toggle => toggle
310+ . setValue ( this . plugin . settings . prefillFind )
311+ . onChange ( ( value ) => __awaiter ( this , void 0 , void 0 , function * ( ) {
312+ logger ( 'Settings update: prefillFind: ' + value ) ;
313+ this . plugin . settings . prefillFind = value ;
314+ yield this . plugin . saveSettings ( ) ;
315+ } ) ) ) ;
316+ }
317+ }
318+
319+ module . exports = RegexFindReplacePlugin ;
320+
321+
322+ /* nosourcemap */
0 commit comments