1
- import { App , Editor , EditorPosition , EditorSuggest , EditorSuggestTriggerInfo , Notice , Plugin , PluginSettingTab , Setting , debounce } from 'obsidian' ;
1
+ import { App , Editor , EditorPosition , EditorSuggest , EditorSuggestTriggerInfo , Notice , Plugin , PluginSettingTab , Setting } from 'obsidian' ;
2
2
3
3
interface AnchorDisplaySuggestion {
4
4
displayText : string ;
@@ -40,12 +40,14 @@ export default class AnchorDisplayText extends Plugin {
40
40
const cursor = editor . getCursor ( ) ;
41
41
const currentLine = editor . getLine ( cursor . line ) ;
42
42
43
- const lastChar = currentLine [ cursor . ch - 1 ] ;
44
- if ( lastChar !== ']' ) return ;
43
+ const lastChars = currentLine . slice ( cursor . ch - 2 , cursor . ch ) ;
44
+ if ( lastChars !== ']]' ) {
45
+ return
46
+ }
45
47
46
48
// match anchor links WITHOUT an already defined display text
47
49
const headerLinkPattern = / \[ \[ ( [ ^ \] ] + # [ ^ | \n \r \] ] + ) \] \] / ;
48
- const match = currentLine . slice ( 0 , cursor . ch ) . match ( headerLinkPattern ) ;
50
+ const match = currentLine . slice ( 0 , cursor . ch + 2 ) . match ( headerLinkPattern ) ;
49
51
if ( match ) {
50
52
// handle multiple subheadings
51
53
const headings = match [ 1 ] . split ( '#' )
@@ -98,6 +100,7 @@ export default class AnchorDisplayText extends Plugin {
98
100
99
101
class AnchorDisplaySuggest extends EditorSuggest < AnchorDisplaySuggestion > {
100
102
private plugin : AnchorDisplayText ;
103
+ private suggestionSelected : EditorPosition | null = null ;
101
104
102
105
constructor ( plugin : AnchorDisplayText ) {
103
106
super ( plugin . app ) ;
@@ -107,17 +110,23 @@ class AnchorDisplaySuggest extends EditorSuggest<AnchorDisplaySuggestion> {
107
110
onTrigger ( cursor : EditorPosition , editor : Editor ) : EditorSuggestTriggerInfo | null {
108
111
// turns off suggestions if the setting is disabled but the app hasn't been reloaded
109
112
if ( ! this . plugin . settings . suggest ) return null ;
113
+ if ( this . suggestionSelected ) {
114
+ if ( this . suggestionSelected . ch === cursor . ch
115
+ && this . suggestionSelected . line === cursor . line ) return null ;
116
+ this . suggestionSelected = null ;
117
+ return null ;
118
+ }
110
119
111
120
const currentLine = editor . getLine ( cursor . line ) ;
112
- const lastChar = currentLine [ cursor . ch - 1 ] ;
113
- if ( lastChar !== ']' ) return null ;
121
+ const lastChars = currentLine . slice ( cursor . ch - 2 , cursor . ch ) ;
122
+ if ( lastChars !== '] ]' ) return null ;
114
123
115
124
// match anchor links, even if they already have a display text
116
125
const headerLinkPattern = / ( \[ \[ ( [ ^ \] ] + # [ ^ \n \r \] ] + ) \] \] ) $ / ;
117
126
// only when cursor is immediately after the link
118
127
const match = currentLine . slice ( 0 , cursor . ch ) . match ( headerLinkPattern ) ;
119
128
120
- if ( ! match ) return null ;
129
+ if ( ! match ) return null ;
121
130
122
131
return {
123
132
start : {
@@ -191,17 +200,13 @@ class AnchorDisplaySuggest extends EditorSuggest<AnchorDisplaySuggestion> {
191
200
this . context ! . start . ch = this . context ! . start . ch - match [ 0 ] . length ;
192
201
}
193
202
editor . replaceRange ( `|${ value . displayText } ` , this . context ! . start , this . context ! . end , 'headerDisplayText' ) ;
203
+ this . suggestionSelected = this . context ! . end ;
194
204
} ;
195
205
}
196
206
197
207
class AnchorDisplayTextSettingTab extends PluginSettingTab {
198
208
plugin : AnchorDisplayText ;
199
-
200
- private showSepNotice = debounce (
201
- ( ) => new Notice ( `Separators cannot contain any of the following characters: []#^|` ) ,
202
- 1000 ,
203
- true
204
- ) ;
209
+ private sepWarning : Notice | null = null ;
205
210
206
211
constructor ( app : App , plugin : AnchorDisplayText ) {
207
212
super ( app , plugin ) ;
@@ -210,13 +215,21 @@ class AnchorDisplayTextSettingTab extends PluginSettingTab {
210
215
211
216
validateSep ( value : string ) : string {
212
217
let validValue : string = value ;
218
+
213
219
for ( const c of value ) {
214
220
if ( '[]#^|' . includes ( c ) ) {
215
221
validValue = validValue . replace ( c , '' ) ;
216
222
}
217
223
}
218
224
if ( validValue != value ) {
219
- this . showSepNotice ( ) ;
225
+ if ( ! this . sepWarning ) {
226
+ this . sepWarning = new Notice ( `Separators cannot contain any of the following characters: []#^|` , 0 ) ;
227
+ }
228
+ } else {
229
+ if ( this . sepWarning ) {
230
+ this . sepWarning ! . hide ( ) ;
231
+ this . sepWarning = null ;
232
+ }
220
233
}
221
234
return validValue ;
222
235
}
0 commit comments