import { App , EditorSuggest , EditorSuggestContext , EditorSuggestTriggerInfo , EditorPosition , Editor , MarkdownView , TFile , } from "obsidian" ; import TemplaterPlugin from "main" ; import { is_function_documentation , is_module_name , ModuleName , TpSuggestDocumentation , Documentation } from "./TpDocumentation" ; export class Autocomplete extends EditorSuggest < TpSuggestDocumentation > { private tp_keyword_regex = /tp\.(?<module>[a-z]*)?(?<fn_trigger>\.(?<fn>[a-z_]*)?)?$/ ; private documentation : Documentation ; private latest_trigger_info : EditorSuggestTriggerInfo ; private module_name : ModuleName | string ; private function_trigger : boolean ; private function_name : string ; constructor ( private app , private plugin ) { super ( app ) ; this . documentation = new Documentation ( this . app ) ; } onTrigger ( cursor , editor , file ) { const range = editor . getRange ( { line : cursor . line , ch : 0 } , { line : cursor . line , ch : cursor . ch } ) ; const match = this . tp_keyword_regex . exec ( range ) ; if ( ! match ) { return null ; } let query ; const module_name = match . groups [ "module" ] || "" ; this . module_name = module_name ; if ( match . groups [ "fn_trigger" ] ) { if ( module_name == "" || ! is_module_name ( module_name ) ) { return ; } this . function_trigger = true ; this . function_name = match . groups [ "fn" ] || "" ; query = this . function_name ; } else { this . function_trigger = false ; query = this . module_name ; } const trigger_info = { start : { line : cursor . line , ch : cursor . ch - query . length } , end : { line : cursor . line , ch : cursor . ch } , query : query , } ; this . latest_trigger_info = trigger_info ; return trigger_info ; } getSuggestions ( context ) { let suggestions ; if ( this . module_name && this . function_trigger ) { suggestions = this . documentation . get_all_functions_documentation ( this . module_name as ModuleName ) ; } else { suggestions = this . documentation . get_all_modules_documentation ( ) ; } if ( ! suggestions ) { return [ ] ; } return suggestions . filter ( s => s . name . startsWith ( context . query ) ) ; } renderSuggestion ( value , el ) { el . createEl ( "b" , { text : value . name } ) ; el . createEl ( "br" ) ; if ( this . function_trigger && is_function_documentation ( value ) ) { el . createEl ( "code" , { text : value . definition } ) ; } if ( value . description ) { el . createEl ( "div" , { text : value . description } ) ; } } selectSuggestion ( value , evt ) { const active_view = this . app . workspace . getActiveViewOfType ( MarkdownView ) ; if ( ! active_view ) { return ; } active_view . editor . replaceRange ( value . name , this . latest_trigger_info . start , this . latest_trigger_info . end ) ; if ( this . latest_trigger_info . start . ch == this . latest_trigger_info . end . ch ) { const cursor_pos = this . latest_trigger_info . end ; cursor_pos . ch += value . name . length ; active_view . editor . setCursor ( cursor_pos ) ; } } }