artempyanykh / marksman

Write Markdown with code assist and intelligence in the comfort of your favourite editor.
MIT License
2.05k stars 35 forks source link

Support titles in YAML front matter #112

Open gour opened 1 year ago

gour commented 1 year ago

Hello,

I've problem running Marksman under SublimeText, iow. auto-completion for [[Wikilink]] does not work and here is the output in the ST's log panel:

:: --> marksman initialize(1): {'rootUri': 'file:///home/gour/tpnote', 'workspaceFolders': [{'uri': 'file:///home/gour/tpnote', 'name': 'tpnote'}], 'processId': 20550, 'rootPath': '/home/gour/tpnote', 'clientInfo': {'version': '1.20.0', 'name': 'Sublime Text LSP'}, 'initializationOptions': {}, 'capabilities': {'workspace': {'workspaceEdit': {'failureHandling': 'abort', 'documentChanges': True}, 'didChangeConfiguration': {'dynamicRegistration': True}, 'codeLens': {'refreshSupport': True}, 'semanticTokens': {'refreshSupport': True}, 'inlayHint': {'refreshSupport': True}, 'workspaceFolders': True, 'executeCommand': {}, 'applyEdit': True, 'configuration': True, 'symbol': {'symbolKind': {'valueSet': [10, 11, 24, 9, 3, 5, 15, 21, 1, 18, 17, 19, 6, 2, 14, 7, 25, 20, 4, 16, 12, 23, 26, 8, 13, 22]}, 'dynamicRegistration': True, 'tagSupport': {'valueSet': [1]}}}, 'textDocument': {'completion': {'dynamicRegistration': True, 'completionItemKind': {'valueSet': [13, 14, 8, 23, 4, 7, 12, 5, 1, 17, 15, 2, 9, 21, 11, 10, 24, 19, 3, 22, 25, 6, 18, 16, 20]}, 'completionItem': {'snippetSupport': True, 'insertTextModeSupport': {'valueSet': [2]}, 'resolveSupport': {'properties': ['detail', 'documentation', 'additionalTextEdits']}, 'labelDetailsSupport': True, 'documentationFormat': ['markdown', 'plaintext'], 'deprecatedSupport': True, 'insertReplaceSupport': True, 'tagSupport': {'valueSet': [1]}}, 'insertTextMode': 2}, 'formatting': {'dynamicRegistration': True}, 'documentHighlight': {'dynamicRegistration': True}, 'synchronization': {'dynamicRegistration': True, 'willSave': True, 'willSaveWaitUntil': True, 'didSave': True}, 'colorProvider': {'dynamicRegistration': True}, 'semanticTokens': {'formats': ['relative'], 'multilineTokenSupport': True, 'tokenTypes': ['enumMember', 'enum', 'type', 'interface', 'event', 'namespace', 'class', 'string', 'parameter', 'method', 'property', 'operator', 'comment', 'keyword', 'number', 'modifier', 'regexp', 'function', 'struct', 'typeParameter', 'variable', 'macro', 'decorator'], 'dynamicRegistration': True, 'augmentsSyntaxTokens': True, 'overlappingTokenSupport': False, 'tokenModifiers': ['abstract', 'definition', 'readonly', 'deprecated', 'modification', 'defaultLibrary', 'declaration', 'documentation', 'async', 'static'], 'requests': {'range': True, 'full': {'delta': True}}}, 'typeDefinition': {'dynamicRegistration': True, 'linkSupport': True}, 'implementation': {'dynamicRegistration': True, 'linkSupport': True}, 'documentSymbol': {'symbolKind': {'valueSet': [10, 11, 24, 9, 3, 5, 15, 21, 1, 18, 17, 19, 6, 2, 14, 7, 25, 20, 4, 16, 12, 23, 26, 8, 13, 22]}, 'dynamicRegistration': True, 'hierarchicalDocumentSymbolSupport': True, 'tagSupport': {'valueSet': [1]}}, 'codeLens': {'dynamicRegistration': True}, 'inlayHint': {'dynamicRegistration': True, 'resolveSupport': {'properties': ['textEdits', 'label.command']}}, 'rangeFormatting': {'dynamicRegistration': True}, 'signatureHelp': {'signatureInformation': {'parameterInformation': {'labelOffsetSupport': True}, 'activeParameterSupport': True, 'documentationFormat': ['markdown', 'plaintext']}, 'dynamicRegistration': True, 'contextSupport': True}, 'definition': {'dynamicRegistration': True, 'linkSupport': True}, 'codeAction': {'dataSupport': True, 'codeActionLiteralSupport': {'codeActionKind': {'valueSet': ['quickfix', 'refactor', 'refactor.extract', 'refactor.inline', 'refactor.rewrite', 'source.fixAll', 'source.organizeImports']}}, 'dynamicRegistration': True, 'isPreferredSupport': True, 'resolveSupport': {'properties': ['edit']}, 'disabledSupport': True}, 'rename': {'prepareSupport': True, 'dynamicRegistration': True}, 'hover': {'dynamicRegistration': True, 'contentFormat': ['markdown', 'plaintext']}, 'documentLink': {'dynamicRegistration': True, 'tooltipSupport': True}, 'selectionRange': {'dynamicRegistration': True}, 'publishDiagnostics': {'dataSupport': True, 'relatedInformation': True, 'codeDescriptionSupport': True, 'versionSupport': True, 'tagSupport': {'valueSet': [2, 1]}}, 'references': {'dynamicRegistration': True}, 'declaration': {'dynamicRegistration': True, 'linkSupport': True}}, 'general': {'markdown': {'version': '3.2.2', 'parser': 'Python-Markdown'}, 'regularExpressions': {'engine': 'ECMAScript'}}, 'window': {'workDoneProgress': True, 'showDocument': {'support': True}, 'showMessage': {'messageActionItem': {'additionalPropertiesSupport': True}}}}}
marksman: [11:31:36 INF] <LSP Entry> Starting Marksman LSP server: {}
:: <<< marksman 1: {'capabilities': {'renameProvider': {'prepareProvider': True}, 'hoverProvider': True, 'referencesProvider': True, 'documentSymbolProvider': True, 'completionProvider': {'triggerCharacters': ['[', '#', '(']}, 'workspace': {'fileOperations': {'didDelete': {'filters': [{'pattern': {'glob': '**/*.md', 'options': {'ignoreCase': True}, 'matches': 'file'}}]}, 'didCreate': {'filters': [{'pattern': {'glob': '**/*.md', 'options': {'ignoreCase': True}, 'matches': 'file'}}]}}, 'workspaceFolders': {'changeNotifications': True, 'supported': True}}, 'textDocumentSync': {'change': {'syncKind': 2}, 'didClose': {}, 'didOpen': {}}, 'codeActionProvider': {'resolveProvider': False}, 'definitionProvider': True, 'semanticTokensProvider': {'legend': {'tokenTypes': ['property', 'variable'], 'tokenModifiers': []}, 'range': True, 'full': {'delta': False}}, 'workspaceSymbolProvider': True}}
::  -> marksman initialized: {}
::  -> marksman textDocument/didOpen: {'textDocument': {'version': 15, 'uri': 'file:///home/gour/tpnote/first.md', 'languageId': 'markdown', 'text': '---\ntitle: "First Note"\ntags: ["test"]\n---\n\nThis is a first note with a link to the 2nd one: \n'}}
:: --> marksman textDocument/hover(2): {'position': {'character': 49, 'line': 5}, 'textDocument': {'uri': 'file:///home/gour/tpnote/first.md'}}
:: --> marksman textDocument/codeAction(3): {'context': {'diagnostics': [], 'triggerKind': 2}, 'textDocument': {'uri': 'file:///home/gour/tpnote/first.md'}, 'range': {'end': {'character': 49, 'line': 5}, 'start': {'character': 49, 'line': 5}}}
:: <<< marksman 2: None
:: <<< marksman 3: []
::  -> marksman textDocument/didChange: {'contentChanges': [{'text': '[]', 'range': {'end': {'character': 49, 'line': 5}, 'start': {'character': 49, 'line': 5}}, 'rangeLength': 0}], 'textDocument': {'version': 16, 'uri': 'file:///home/gour/tpnote/first.md'}}
::  -> marksman textDocument/didChange: {'contentChanges': [{'text': '[]', 'range': {'end': {'character': 50, 'line': 5}, 'start': {'character': 50, 'line': 5}}, 'rangeLength': 0}], 'textDocument': {'version': 17, 'uri': 'file:///home/gour/tpnote/first.md'}}
:: <-  marksman textDocument/publishDiagnostics: {'diagnostics': [{'message': "Link to non-existent document with the title ''", 'code': '2', 'range': {'end': {'character': 53, 'line': 5}, 'start': {'character': 49, 'line': 5}}, 'severity': 1, 'source': 'Marksman'}], 'uri': 'file:///home/gour/tpnote/first.md'}
:: --> marksman textDocument/codeAction(4): {'context': {'diagnostics': [{'message': "Link to non-existent document with the title ''", 'code': '2', 'range': {'end': {'character': 53, 'line': 5}, 'start': {'character': 49, 'line': 5}}, 'severity': 1, 'source': 'Marksman'}], 'triggerKind': 2}, 'textDocument': {'uri': 'file:///home/gour/tpnote/first.md'}, 'range': {'end': {'character': 53, 'line': 5}, 'start': {'character': 49, 'line': 5}}}
:: <<< marksman 4: []
::  -> marksman textDocument/didChange: {'contentChanges': [{'text': 's', 'range': {'end': {'character': 51, 'line': 5}, 'start': {'character': 51, 'line': 5}}, 'rangeLength': 0}], 'textDocument': {'version': 18, 'uri': 'file:///home/gour/tpnote/first.md'}}
:: <-  marksman textDocument/publishDiagnostics: {'diagnostics': [{'message': "Link to non-existent document with the title 's'", 'code': '2', 'range': {'end': {'character': 54, 'line': 5}, 'start': {'character': 49, 'line': 5}}, 'severity': 1, 'source': 'Marksman'}], 'uri': 'file:///home/gour/tpnote/first.md'}
:: --> marksman textDocument/codeAction(5): {'context': {'diagnostics': [{'message': "Link to non-existent document with the title 's'", 'code': '2', 'range': {'end': {'character': 54, 'line': 5}, 'start': {'character': 49, 'line': 5}}, 'severity': 1, 'source': 'Marksman'}], 'triggerKind': 2}, 'textDocument': {'uri': 'file:///home/gour/tpnote/first.md'}, 'range': {'end': {'character': 54, 'line': 5}, 'start': {'character': 49, 'line': 5}}}
:: <<< marksman 5: []
::  -> marksman textDocument/didChange: {'contentChanges': [{'text': 'e', 'range': {'end': {'character': 52, 'line': 5}, 'start': {'character': 52, 'line': 5}}, 'rangeLength': 0}], 'textDocument': {'version': 19, 'uri': 'file:///home/gour/tpnote/first.md'}}
:: <-  marksman textDocument/publishDiagnostics: {'diagnostics': [{'message': "Link to non-existent document with the title 'se'", 'code': '2', 'range': {'end': {'character': 55, 'line': 5}, 'start': {'character': 49, 'line': 5}}, 'severity': 1, 'source': 'Marksman'}], 'uri': 'file:///home/gour/tpnote/first.md'}
:: --> marksman textDocument/codeAction(6): {'context': {'diagnostics': [{'message': "Link to non-existent document with the title 'se'", 'code': '2', 'range': {'end': {'character': 55, 'line': 5}, 'start': {'character': 49, 'line': 5}}, 'severity': 1, 'source': 'Marksman'}], 'triggerKind': 2}, 'textDocument': {'uri': 'file:///home/gour/tpnote/first.md'}, 'range': {'end': {'character': 55, 'line': 5}, 'start': {'character': 49, 'line': 5}}}
:: <<< marksman 6: []
::  -> marksman textDocument/didChange: {'contentChanges': [{'text': 'c', 'range': {'end': {'character': 53, 'line': 5}, 'start': {'character': 53, 'line': 5}}, 'rangeLength': 0}], 'textDocument': {'version': 20, 'uri': 'file:///home/gour/tpnote/first.md'}}
:: <-  marksman textDocument/publishDiagnostics: {'diagnostics': [{'message': "Link to non-existent document with the title 'sec'", 'code': '2', 'range': {'end': {'character': 56, 'line': 5}, 'start': {'character': 49, 'line': 5}}, 'severity': 1, 'source': 'Marksman'}], 'uri': 'file:///home/gour/tpnote/first.md'}
:: --> marksman textDocument/codeAction(7): {'context': {'diagnostics': [{'message': "Link to non-existent document with the title 'sec'", 'code': '2', 'range': {'end': {'character': 56, 'line': 5}, 'start': {'character': 49, 'line': 5}}, 'severity': 1, 'source': 'Marksman'}], 'triggerKind': 2}, 'textDocument': {'uri': 'file:///home/gour/tpnote/first.md'}, 'range': {'end': {'character': 56, 'line': 5}, 'start': {'character': 49, 'line': 5}}}
:: <<< marksman 7: []
:: --> marksman textDocument/codeAction(8): {'context': {'diagnostics': [{'message': "Link to non-existent document with the title 'sec'", 'code': '2', 'range': {'end': {'character': 56, 'line': 5}, 'start': {'character': 49, 'line': 5}}, 'severity': 1, 'source': 'Marksman'}], 'triggerKind': 2}, 'textDocument': {'uri': 'file:///home/gour/tpnote/first.md'}, 'range': {'end': {'character': 0, 'line': 6}, 'start': {'character': 0, 'line': 0}}}
:: <<< marksman 8: []

Below are my two test files...

first.md second.md

Any hint?

gour commented 1 year ago

It looks it is the problem with SublimeText's LSP-marksman package since the same test performs well with Helix editor.

artempyanykh commented 1 year ago

Thanks for reporting this @gour! As a quick sanity-check: do you have .marksman.toml or a git repo at the root folder with your notes? (I'm referring to the "Workspace folders, project roots, and single-file mode" section of the README)

gour commented 1 year ago

Thanks for reporting this @gour! As a quick sanity-check: do you have .marksman.toml or a git repo at the root folder with your notes? (I'm referring to the "Workspace folders, project roots, and single-file mode" section of the README)

No, I haven't, but added it now.

What is supposed to be the content of .marksman.toml ?

artempyanykh commented 1 year ago

@gour .marksman.toml marks the project root when your project is not under version control. It can also have project-specific configuration. You can leave it empty.

Do you get wiki links completion now that you've added the file? (server restart is required)

If you still don't get the completion you may want to try doing 'git init'. The idea is that since things work in helix but doesn't work in ST it can be a difference in workspace folders/projects setup.

gour commented 1 year ago

@gour .marksman.toml marks the project root when your project is not under version control. It can also have project-specific configuration. You can leave it empty.

OK.

Do you get wiki links completion now that you've added the file? (server restart is required)

I can say that even without I get it, but both Helix & ST4 have problem if the note does not contain 1st-level # header. Is it expected to be so?

artempyanykh commented 1 year ago

Yes, it's expected. Currently, the title is taken from 1st level heading.

I checked your documents: you define title inside frontmatter. I'd like to support this use-case too as it's very common in static site generators.

Let's repurpose this ticket as a feature request for taking a title from a frontmatter.

gour commented 1 year ago

@gour .marksman.toml marks the project root when your project is not under version control.

For personal projects I use Fossil, so wonder if it also qualifies as "version control" or it is Git-only?

gour commented 1 year ago

Yes, it's expected. Currently, the title is taken from 1st level heading.

OK, thanks.

I checked your documents: you define title inside frontmatter. I'd like to support this use-case too as it's very common in static site generators.

I'd also like to be able to use Zettlr and currently have problem interoperating with the links created by LSP-marksman...

Let's repurpose this ticket as a feature request for taking a title from a frontmatter.

Great. Thanks a lot for your work on Marksman! It greatly changes the Markdown's ecosystem. :smiley:

artempyanykh commented 1 year ago

Thanks for the kind words @gour! ❤️ I've retitled the issue as a feature request now.

fisher-j commented 1 year ago

I also would like to be able to link to titles in front matter.

silverhook commented 1 year ago

Perhaps it’s a bit of a big ask, but could we also interpret Tag(s): and Keyword(s): tags in the YAML front matter as Zettlekasten tags?

artempyanykh commented 1 year ago

@silverhook could you elaborate on the use-case? Currently, if you insert #blah in the document it'll be treated as a tag and will participate in tag completion; you don't need to define tags beforehand. Do you want to specifically put tags in the frontmatter? Or do you want to be able to drop the leading # before the tag name? Or something else?

fisher-j commented 1 year ago

I think it would be nice to put tags in the yaml front matter. In either a tags or categories key (the latter is used by the quarto site generator for R for blog posts). This would allow tags to be defined with spaces and without quotes using either yaml inline, or multi-line arrays:

title: Eureka
tags:
  - blog idea
  - uncategorized

Or

title: Eureka
tags: [blog idea, uncategorized]

On Sun, Jul 23, 2023, 3:27 PM Artem Pianykh @.***> wrote:

@silverhook https://github.com/silverhook could you elaborate on the use-case? Currently, if you insert #blah in the document it'll be treated as a tag and will participate in tag completion; you don't need to define tags beforehand. Do you want to specifically put tags in the frontmatter? Or do you want to be able to drop the leading # before the tag name? Or something else?

— Reply to this email directly, view it on GitHub https://github.com/artempyanykh/marksman/issues/112#issuecomment-1646975284, or unsubscribe https://github.com/notifications/unsubscribe-auth/APBWHQMV4LERZNYYEPDG7LDXRWQLFANCNFSM6AAAAAASELAT6E . You are receiving this because you commented.Message ID: @.***>

silverhook commented 1 year ago

@artempyanykh , I think @fisher-j described it well.

The thing is that several note/doc/blog systems using MarkDown – Pandoc and Pelican to name just two – already use tags: and keywords: in the YAML front matter. In Pandoc’s example, if you generate a PDF (through e.g. LaTeX), it will store the keywords into PDF metadata.

So, if we’re already re-using YAML front matter, re-using the tags may make sense too.

For inspiration perhaps see how Pandoc handles the YAML metadata block.