1- import { EditorPosition , ListItemCache , Plugin , SectionCache } from "obsidian" ;
1+ import {
2+ Editor ,
3+ EditorPosition ,
4+ HeadingCache ,
5+ ListItemCache ,
6+ MarkdownView ,
7+ Plugin ,
8+ SectionCache ,
9+ TFile ,
10+ } from "obsidian" ;
211
312function generateId ( ) : string {
413 return Math . random ( ) . toString ( 36 ) . substr ( 2 , 6 ) ;
@@ -20,85 +29,23 @@ export default class MyPlugin extends Plugin {
2029 async onload ( ) {
2130 this . registerEvent (
2231 this . app . workspace . on ( "editor-menu" , ( menu , editor , view ) => {
23- const cursor = editor . getCursor ( "to" ) ;
24- const fileCache = this . app . metadataCache . getFileCache ( view . file ) ;
25-
26- let blockCache : ListItemCache | SectionCache = (
27- fileCache ?. sections || [ ]
28- ) . find ( ( section ) => {
29- return (
30- section . position . start . line <= cursor . line &&
31- section . position . end . line >= cursor . line
32- ) ;
33- } ) ;
34-
35- if ( ! blockCache ) return ;
32+ const block = this . getBlock ( editor , view . file ) ;
3633
37- if ( blockCache . type === "list" ) {
38- blockCache = ( fileCache ?. listItems || [ ] ) . find ( ( item ) => {
39- return (
40- item . position . start . line <= cursor . line &&
41- item . position . end . line >= cursor . line
42- ) ;
43- } ) ;
44- }
34+ if ( ! block ) return ;
4535
46- const isHeading = ( blockCache as any ) . type === " heading" ;
36+ const isHeading = ! ! ( block as any ) . heading ;
4737
4838 const onClick = ( isEmbed : boolean ) => {
49- // Copy heading
5039 if ( isHeading ) {
51- const heading = fileCache . headings . find ( ( heading ) => {
52- return (
53- heading . position . start . line === blockCache . position . start . line
54- ) ;
55- } ) ;
56-
57- return (
58- heading &&
59- navigator . clipboard . writeText (
60- `${
61- isEmbed ? "!" : ""
62- } ${ this . app . fileManager . generateMarkdownLink (
63- view . file ,
64- "" ,
65- "#" + heading . heading
66- ) } `
67- )
68- ) ;
69- }
70-
71- const blockId = blockCache . id ;
72-
73- // Copy existing block id
74- if ( blockId ) {
75- return navigator . clipboard . writeText (
76- `${ isEmbed ? "!" : "" } ${ this . app . fileManager . generateMarkdownLink (
77- view . file ,
78- "" ,
79- "#^" + blockId
80- ) } `
40+ this . handleHeading ( view . file , block as HeadingCache , isEmbed ) ;
41+ } else {
42+ this . handleBlock (
43+ view . file ,
44+ editor ,
45+ block as SectionCache | ListItemCache ,
46+ isEmbed
8147 ) ;
8248 }
83-
84- // Add a block id
85- const sectionEnd = blockCache . position . end ;
86- const end : EditorPosition = {
87- ch : sectionEnd . col ,
88- line : sectionEnd . line ,
89- } ;
90-
91- const id = generateId ( ) ;
92- const spacer = shouldInsertAfter ( blockCache ) ? "\n\n" : " " ;
93-
94- editor . replaceRange ( `${ spacer } ^${ id } ` , end ) ;
95- navigator . clipboard . writeText (
96- `${ isEmbed ? "!" : "" } ${ this . app . fileManager . generateMarkdownLink (
97- view . file ,
98- "" ,
99- "#^" + id
100- ) } `
101- ) ;
10249 } ;
10350
10451 menu . addItem ( ( item ) => {
@@ -116,5 +63,122 @@ export default class MyPlugin extends Plugin {
11663 } ) ;
11764 } )
11865 ) ;
66+
67+ this . addCommand ( {
68+ id : 'copy-link-to-block' ,
69+ name : "Copy link to current block or heading" ,
70+ editorCheckCallback : ( isChecking , editor , view ) => {
71+ return this . handleCommand ( isChecking , editor , view , false )
72+ } ,
73+ } )
74+
75+ this . addCommand ( {
76+ id : 'copy-embed-to-block' ,
77+ name : "Copy embed to current block or heading" ,
78+ editorCheckCallback : ( isChecking , editor , view ) => {
79+ return this . handleCommand ( isChecking , editor , view , true )
80+ } ,
81+ } )
82+ }
83+
84+ handleCommand ( isChecking : boolean , editor : Editor , view : MarkdownView , isEmbed : boolean ) {
85+ if ( isChecking ) {
86+ return ! ! this . getBlock ( editor , view . file ) ;
87+ }
88+
89+ const block = this . getBlock ( editor , view . file ) ;
90+
91+ if ( ! block ) return ;
92+
93+ const isHeading = ! ! ( block as any ) . heading ;
94+
95+ if ( isHeading ) {
96+ this . handleHeading ( view . file , block as HeadingCache , isEmbed ) ;
97+ } else {
98+ this . handleBlock (
99+ view . file ,
100+ editor ,
101+ block as SectionCache | ListItemCache ,
102+ isEmbed
103+ ) ;
104+ }
105+ }
106+
107+ getBlock ( editor : Editor , file : TFile ) {
108+ const cursor = editor . getCursor ( "to" ) ;
109+ const fileCache = this . app . metadataCache . getFileCache ( file ) ;
110+
111+ let block : ListItemCache | HeadingCache | SectionCache = (
112+ fileCache ?. sections || [ ]
113+ ) . find ( ( section ) => {
114+ return (
115+ section . position . start . line <= cursor . line &&
116+ section . position . end . line >= cursor . line
117+ ) ;
118+ } ) ;
119+
120+ if ( block ?. type === "list" ) {
121+ block = ( fileCache ?. listItems || [ ] ) . find ( ( item ) => {
122+ return (
123+ item . position . start . line <= cursor . line &&
124+ item . position . end . line >= cursor . line
125+ ) ;
126+ } ) ;
127+ } else if ( block ?. type === "heading" ) {
128+ block = fileCache . headings . find ( ( heading ) => {
129+ return heading . position . start . line === block . position . start . line ;
130+ } ) ;
131+ }
132+
133+ return block
134+ }
135+
136+ handleHeading ( file : TFile , block : HeadingCache , isEmbed : boolean ) {
137+ navigator . clipboard . writeText (
138+ `${ isEmbed ? "!" : "" } ${ this . app . fileManager . generateMarkdownLink (
139+ file ,
140+ "" ,
141+ "#" + block . heading
142+ ) } `
143+ ) ;
144+ }
145+
146+ handleBlock (
147+ file : TFile ,
148+ editor : Editor ,
149+ block : ListItemCache | SectionCache ,
150+ isEmbed : boolean
151+ ) {
152+ const blockId = block . id ;
153+
154+ // Copy existing block id
155+ if ( blockId ) {
156+ return navigator . clipboard . writeText (
157+ `${ isEmbed ? "!" : "" } ${ this . app . fileManager . generateMarkdownLink (
158+ file ,
159+ "" ,
160+ "#^" + blockId
161+ ) } `
162+ ) ;
163+ }
164+
165+ // Add a block id
166+ const sectionEnd = block . position . end ;
167+ const end : EditorPosition = {
168+ ch : sectionEnd . col ,
169+ line : sectionEnd . line ,
170+ } ;
171+
172+ const id = generateId ( ) ;
173+ const spacer = shouldInsertAfter ( block ) ? "\n\n" : " " ;
174+
175+ editor . replaceRange ( `${ spacer } ^${ id } ` , end ) ;
176+ navigator . clipboard . writeText (
177+ `${ isEmbed ? "!" : "" } ${ this . app . fileManager . generateMarkdownLink (
178+ file ,
179+ "" ,
180+ "#^" + id
181+ ) } `
182+ ) ;
119183 }
120184}
0 commit comments